Nginx или Haproxy реализуют HTTPS-туннели, туннели HTTP/2 over HTTPS, туннели WebSocket over HTTP/2 over HTTPS, туннели gRPC over HTTP/2 over HTTPS, а также туннели gRPC over HTTP/2 over HTTPS с двусторонней аутентификацией по самозаверяющему сертификату.
Создание HTTPS-туннеля с помощью Nginx на стороне клиента и сервера для скрытия отпечатков
Сетевая структура:
xray_client ---tcp--- nginx_client ---HTTPS--- nginx_sever ---tcp--- xray_server
Компиляция nginx с поддержкой --with-stream
Выполните компиляцию как на клиенте, так и на сервере.
curl -O -L http://nginx.org/download/nginx-1.22.1.tar.gz
tar -zxvf nginx-1.22.1.tar.gz
cd nginx-1.22.1
apt install gcc make
// Для компиляции требуются gcc и make
./configure --prefix=/usr/local/nginx --with-http_ssl_module --with-http_v2_module --with-stream --with-stream_ssl_module
// На этом шаге могут потребоваться дополнительные библиотеки, установите их в соответствии с сообщениями об ошибках.
make && make install
После компиляции папка nginx будет находиться в /usr/local/nginx
.
Настройка nginx
Отредактируйте конфигурационный файл nginx.conf.
vim /usr/local/nginx/conf/nginx.conf
Добавьте следующую конфигурацию на стороне сервера.
Получение сертификата для сервера не рассматривается в данном руководстве. Обратитесь к документации.
stream {
server {
listen 443 ssl;
listen [::]:443 ssl;
ssl_protocols TLSv1.3;
ssl_certificate /path/to/cert/domain.crt; # Путь к файлу crt
ssl_certificate_key /path/to/cert/domain.key; # Путь к файлу key
proxy_pass unix:/dev/shm/vless.sock; # Использование доменного сокета
}
}
Внимание
Раздел stream находится на одном уровне с модулем http. Клиент может удалить раздел http, а сервер может удалить его или настроить веб-сайт для маскировки.
Добавьте следующую конфигурацию на стороне клиента.
stream {
server {
listen 6666;
listen [::]:6666;
proxy_ssl on;
proxy_ssl_protocols TLSv1.3;
proxy_ssl_server_name on;
proxy_ssl_name yourdomain.domain; # Доменное имя сервера
proxy_pass ip:443; # IP-адрес сервера, например, proxy_pass 6.6.6.6:443; или proxy_pass [2401:0:0::1]:443;
}
}
Создайте файл nginx.service
в папке /etc/systemd/system
.
vim /etc/systemd/system/nginx.service
Добавьте следующий текст:
[Unit]
Description=The NGINX HTTP and reverse proxy server
After=syslog.target network-online.target remote-fs.target nss-lookup.target
After=xray.service
[Service]
Type=forking
ExecStartPre=/usr/local/nginx/sbin/nginx -t
ExecStart=/usr/local/nginx/sbin/nginx
ExecReload=/usr/local/nginx/sbin/nginx -s reload
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true
[Install]
WantedBy=multi-user.target
Добавьте автоматический запуск при загрузке системы.
systemctl enable nginx
Настройка Xray
Конфигурация Xray на стороне сервера:
{
"log": {
"loglevel": "none"
},
"inbounds": [
{
"listen": "/dev/shm/vless.sock,0666",
"protocol": "vless",
"settings": {
"clients": [
{
"id": "uuid"
}
],
"decryption": "none"
},
"streamSettings": {
"network": "tcp"
},
"sniffing": {
"enabled": true,
"destOverride": [
"http",
"tls"
]
}
}
],
"outbounds": [
{
"protocol": "freedom"
}
]
}
Конфигурация Xray на стороне клиента (в данном примере используется прозрачное проксирование пограничного маршрутизатора):
{
"log": {
"loglevel": "none"
},
"dns": {
"servers": [
"1.1.1.1",
{
"address": "119.29.29.29",
"domains": [
"geosite:cn"
],
"expectIP": [
"geoip:cn"
]
}
],
"disableFallback": true,
"disableFallbackIfMatch": true
},
"inbounds": [
{
"tag": "tproxy-in",
"port": 12345,
"protocol": "dokodemo-door",
"settings": {
"network": "tcp,udp",
"followRedirect": true
},
"sniffing": {
"enabled": true,
"destOverride": [
"http",
"tls"
]
},
"streamSettings": {
"sockopt": {
"tproxy": "tproxy",
"mark": 255
}
}
},
{
"tag": "http",
"port": 10808,
"listen": "127.0.0.1",
"protocol": "http",
"sniffing": {
"enabled": true,
"destOverride": [
"http",
"tls"
]
}
}
],
"outbounds": [
{
"tag": "nginxtls",
"protocol": "vless",
"settings": {
"vnext": [
{
"address": "127.0.0.1",
"port": 6666,
"users": [
{
"id": "uuid",
"encryption": "none"
}
]
}
]
},
"streamSettings": {
"sockopt": {
"mark": 255
},
"network": "tcp"
}
},
{
"tag": "direct",
"protocol": "freedom",
"streamSettings": {
"sockopt": {
"mark": 255
}
}
},
{
"tag": "block",
"protocol": "blackhole",
"settings": {
"response": {
"type": "http"
}
}
}
],
"routing": {
"domainMatcher": "mph",
"domainStrategy": "AsIs",
"rules": [
{
"type": "field",
"domain": [
"geosite:category-ads-all"
],
"outboundTag": "block"
},
{
"type": "field",
"port": 123,
"network": "udp",
"outboundTag": "direct"
},
{
"type": "field",
"ip": [
"1.1.1.1"
],
"outboundTag": "proxy"
},
{
"type": "field",
"domain": [
"geosite:cn"
],
"outboundTag": "direct"
},
{
"type": "field",
"protocol": [
"bittorrent"
],
"outboundTag": "direct"
},
{
"type": "field",
"ip": [
"geoip:private"
],
"outboundTag": "direct"
},
{
"type": "field",
"inboundTag": [
"tproxy-in"
],
"outboundTag": "nginxtls"
}
]
}
}
При использовании прозрачного проксирования необходимо добавить следующие правила в конфигурацию iptables или ip6tables:
# Настройка маршрутизации по политике для IPv4
ip rule add fwmark 1 table 100
ip route add local 0.0.0.0/0 dev lo table 100
# Настройка маршрутизации по политике для IPv6
ip -6 rule add fwmark 1 table 106
ip -6 route add local ::/0 dev lo table 106
# Прямое подключение для IP-адреса VPS
iptables -t mangle -A XRAY_MASK -d VSP_IPv4/32 -j RETURN
ip6tables -t mangle -A XRAY6_MASK -d VPS_IPv6/128 -j RETURN
Запуск сервисов на клиенте и сервере
systemctl restart xray
systemctl restart nginx
Завершение
Создание HTTPS-туннеля с помощью Haproxy на стороне клиента и сервера для скрытия отпечатков
Установка Haproxy:
pacman -Su haproxy
или apt install haproxy
Haproxy требует OpenSSL для обработки SSL. Проверьте версию OpenSSL и при необходимости установите или обновите ее.
HTTPS-туннель
Haproxy может легко реализовать HTTPS-туннель, как и описанный выше Nginx.
Сетевая структура:
xray_client ---tcp--- haproxy_client ---HTTPS--- haproxy_sever ---tcp--- xray_server
Конфигурация haproxy_client (удалите комментарии перед запуском):
global
log /dev/log local0 alert
log /dev/log local1 alert
stats socket /dev/shm/admin.sock mode 660 level admin expose-fd listeners
stats timeout 30s
user root
group root
daemon
# Принудительное использование TLS 1.3 для туннеля
ssl-default-server-options ssl-min-ver TLSv1.3
defaults
log global
mode tcp
timeout connect 5s
timeout client 300s
timeout server 300s
frontend xray
bind 127.0.0.1:6666 # Прослушивание порта 6666 на локальном хосте
default_backend tunnel
backend tunnel
server tunnel www.example.com:443 ssl verify none sni req.hdr(host) alpn h2,http/1.1
# Можно использовать доменное имя или IP-адрес. При использовании доменного имени рекомендуется указать IP-адрес в файле hosts, чтобы сократить время разрешения имени.
# alpn используется для согласования с сервером. Если на стороне сервера установлено alpn h2,http1.1, то клиент может указать h2 для подключения по HTTP/2 или http1.1 для подключения по HTTP.
# Рекомендуется указывать h2 в обоих случаях.
Конфигурация haproxy_server (удалите комментарии перед запуском):
global
log /dev/log local0 alert
log /dev/log local1 alert
stats socket /dev/shm/admin.sock mode 660 level admin expose-fd listeners
stats timeout 30s
user root
group root
daemon
# Указание наборов шифров и минимальной версии SSL 1.2 для повышения безопасности
ssl-default-bind-ciphers ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256
ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
ssl-default-bind-options ssl-min-ver TLSv1.2
defaults
log global
mode tcp
timeout connect 5s
timeout client 300s
timeout server 300s
frontend tls-in
bind :::443 ssl crt /path/to/pem alpn h2,http/1.1 # Haproxy использует pem для расшифровки SSL. Файл pem можно получить с помощью команды cat www.example.com.crt www.example.com.key > www.example.com.pem
default_backend xray
tcp-request inspect-delay 5s
tcp-request content accept if HTTP
use_backend web if HTTP
backend xray
server xray /dev/shm/vless.sock # Поддерживаются абстрактные сокеты: "abns@vless.sock" и loopback: 127.0.0.1:6666
backend web
server web /dev/shm/h1h2c.sock # Перенаправление на веб-сайт
Настройка Xray
Аналогично разделу Nginx: простейшая конфигурация TCP, совместимая с любым протоколом. Рекомендуется использовать VLESS+TCP без дополнительного шифрования. Обратитесь к документации или другим примерам.
WebSocket over HTTP/2
Haproxy поддерживает h2c как для входящих, так и для исходящих подключений HTTP/2.
Однако в документации Xray по HTTP/2 говорится:
“В соответствии с рекомендациями по HTTP/2, клиент и сервер должны одновременно включать TLS для корректной работы этого метода передачи... В текущей версии HTTP/2 для входящих подключений (сервер) не требуется настройка TLS.”
То есть для входящих подключений можно использовать h2c, но для исходящих подключений h2c не поддерживается. Поэтому невозможно использовать схему xray_client ---h2c--- haproxy_client ---HTTP/2+TLS--- haproxy_sever ---h2c--- xray_server.
Однако можно обойти это ограничение, используя WebSocket. Haproxy поддерживает ws over HTTP/2.
Тогда сетевая структура будет выглядеть следующим образом: xray_client ---ws--- haproxy_client ---ws over HTTP/2 over HTTPS--- haproxy_sever ---ws--- xray_server.
Конфигурация haproxy_client:
global
log /dev/log local0 alert
log /dev/log local1 alert
stats socket /dev/shm/admin.sock mode 660 level admin expose-fd listeners
stats timeout 30s
user root
group root
daemon
# Настройка производительности HTTP/2. Эти параметры можно изменять при возникновении проблем с производительностью HTTP/2.
# Дополнительные настройки см. в разделе tune.h2 документации Haproxy: https://docs.haproxy.org/2.7/configuration.html
tune.h2.initial-window-size 536870912 # Начальный размер окна, рекомендуется настроить, значение по умолчанию - 65536 байт.
# При резком увеличении трафика может потребоваться время на загрузку, рекомендуется настраивать в зависимости от скорости интернета.
tune.h2.max-concurrent-streams 512 # Количество одновременных потоков, можно настроить при необходимости, значение по умолчанию - 100.
# Обычно не требуется изменять (не рекомендуется официальной документацией).
ssl-default-server-options ssl-min-ver TLSv1.3
defaults
log global
mode http
timeout connect 5s
timeout client 300s
timeout server 300s
frontend xray
bind 127.0.0.1:6666
default_backend tunnel
backend tunnel
server tunnel www.example.com:443 ssl verify none sni req.hdr(host) ws h2 alpn h2
# ws over HTTP/2
Конфигурация haproxy_server:
global
log /dev/log local0 alert
log /dev/log local1 alert
stats socket /dev/shm/admin.sock mode 660 level admin expose-fd listeners
stats timeout 30s
user root
group root
daemon
# Настройка производительности HTTP/2 (необязательно, но рекомендуется).
tune.h2.initial-window-size 536870912
tune.h2.max-concurrent-streams 512
ssl-default-bind-ciphers ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256
ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
ssl-default-bind-options ssl-min-ver TLSv1.2
defaults
log global
mode http
timeout connect 5s
timeout client 300s
timeout server 300s
frontend tls-in
bind :::443 ssl crt /path/to/pem alpn h2,http/1.1
use_backend xray if { ssl_fc_alpn -i h2 } { path_beg /tunnel }
use_backend server1 if { ssl_fc_alpn -i h2 } { path_beg /path1 }
use_backend server2 if { ssl_fc_alpn -i h2 } { path_beg /path2 }
use_backend server3 if { ssl_fc_alpn -i h2 } { path_beg /path3 }
default_backend web
# Haproxy в режиме http может разделять трафик на основе пути.
backend xray
server xray abns@vless.sock ws h1
backend server1
server server1 abns@server1.sock ws h1
backend server2
server server2 abns@server2.sock ws h1
backend server3
server server3 abns@server3.sock ws h1
backend web
server web /dev/shm/h1h2c.sock
Настройка Xray
Простая конфигурация WebSocket, TLS не требуется. Пример конфигурации см. в документации Xray. Параметр "path" можно использовать для разделения трафика на стороне сервера Haproxy (клиент также может разделять трафик с помощью Haproxy, принцип аналогичен, см. конфигурацию разделения трафика на стороне сервера).
gRPC over HTTP/2
Хотя двусторонний h2c невозможен, gRPC не требует обязательного использования TLS.
Сетевая структура: xray_client ---gRPC h2c--- haproxy_client ---gRPC over HTTP/2 over HTTPS--- haproxy_sever ---gRPC h2c--- xray_server
Конфигурация haproxy_client:
global
log /dev/log local0 alert
log /dev/log local1 alert
stats socket /dev/shm/admin.sock mode 660 level admin expose-fd listeners
stats timeout 30s
user root
group root
daemon
tune.h2.initial-window-size 536870912
tune.h2.max-concurrent-streams 512
ssl-default-server-options ssl-min-ver TLSv1.3
defaults
log global
mode http
timeout connect 5s
timeout client 300s
timeout server 300s
frontend xray
bind 127.0.0.1:6666 proto h2 # Укажите proto h2 для использования h2c
default_backend tunnel
backend tunnel
server tunnel www.example.com:443 ssl verify none sni req.hdr(host) alpn h2
Конфигурация haproxy_server:
global
log /dev/log local0 alert
log /dev/log local1 alert
stats socket /dev/shm/admin.sock mode 660 level admin expose-fd listeners
stats timeout 30s
user root
group root
daemon
tune.h2.initial-window-size 536870912
tune.h2.max-concurrent-streams 512
ssl-default-bind-ciphers ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256
ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
ssl-default-bind-options ssl-min-ver TLSv1.2
defaults
log global
mode http
timeout connect 5s
timeout client 300s
timeout server 300s
frontend tls-in
bind :::443 ssl crt /path/to/pem alpn h2,http/1.1
use_backend xray if { ssl_fc_alpn -i h2 } { path_beg /tunnel } # "serviceName", настроенное в gRPC Xray, можно использовать для разделения трафика в Haproxy с помощью пути.
# Для удобства использования "multiMode" используйте параметр path_beg для сопоставления пути.
use_backend server1 if { ssl_fc_alpn -i h2 } { path_beg /path1 }
use_backend server2 if { ssl_fc_alpn -i h2 } { path_beg /path2 }
use_backend server3 if { ssl_fc_alpn -i h2 } { path_beg /path3 }
default_backend web
backend xray
server xray abns@vless.sock proto h2
backend server1
server server1 abns@server1.sock proto h2
backend server2
server server2 abns@server2.sock proto h2
backend server3
server server3 abns@server3.sock proto h2
backend web
server web /dev/shm/h1h2c.sock
Настройка Xray
Простая конфигурация gRPC, TLS не требуется. Конфигурация см. в документации. Параметр serviceName можно использовать для разделения трафика.
Двусторонняя аутентификация Haproxy с использованием самозаверяющего сертификата (пример gRPC)
Здесь используется двусторонняя аутентификация по самозаверяющему сертификату для повышения безопасности туннеля (это немного увеличивает задержку, но с gRPC это не так заметно). Сервер обрабатывает как доверенные, так и самозаверяющие сертификаты и разделяет трафик на поддельный веб-сайт и туннель.
www.example.com - доменное имя поддельного веб-сайта с доверенным сертификатом (например, сертификат, полученный в соответствии с документацией).
tunnel.example.com - доменное имя с самозаверяющим сертификатом. Самозаверяющий сертификат можно создать, например, с помощью инструкции https://learn.microsoft.com/ru-ru/azure/application-gateway/self-signed-certificates.
Корневой сертификат: ca.crt, сертификат сервера: server.crt, ключ сервера: server.key.
Необходимо создать как минимум файл server.pem, который клиент может использовать для двусторонней аутентификации. Также можно создать два сертификата - client и server - для двусторонней аутентификации.
Необходимо подготовить файл fullchain.crt для аутентификации (cat server.crt ca.crt > fullchain.crt) и server.pem (cat server.crt server.key ca.crt > server.pem) для расшифровки.
Конфигурация haproxy_client:
global
log /dev/log local0 alert
log /dev/log local1 alert
stats socket /dev/shm/admin.sock mode 660 level admin expose-fd listeners
stats timeout 30s
user root
group root
daemon
tune.h2.initial-window-size 536870912
tune.h2.max-concurrent-streams 512
ssl-default-server-options ssl-min-ver TLSv1.3
defaults
log global
mode http
timeout connect 5s
timeout client 300s
timeout server 300s
frontend xray
bind 127.0.0.1:6666 proto h2
default_backend tunnel
backend tunnel
server tunnel tunnel.example.com:443 tfo allow-0rtt ssl crt /path/to/client.pem verify required ca-file /path/to/fullchain.crt sni str(tunnel.example.com) alpn h2
# Доменное имя можно настроить произвольно, оно должно совпадать с самозаверяющим сертификатом.
# Укажите IP-адрес в файле hosts.
# Параметр str в sni устанавливает SNI, который используется сервером для идентификации.
Конфигурация haproxy_server:
global
log /dev/log local0 alert
log /dev/log local1 alert
stats socket /dev/shm/admin.sock mode 660 level admin expose-fd listeners
stats timeout 30s
user root
group root
daemon
tune.h2.initial-window-size 536870912
tune.h2.max-concurrent-streams 512
ssl-default-bind-ciphers ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256
ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
ssl-default-bind-options ssl-min-ver TLSv1.2
defaults
log global
mode http
timeout connect 5s
timeout client 300s
timeout server 300s
frontend tls-in
bind :::443 tfo allow-0rtt ssl crt /path/to/server.pem verify optional ca-file /path/to/fullchain.crt crt /path/to/www.example.com.pem alpn h2,http/1.1
use_backend xray if { ssl_fc_sni tunnel.example.com } { ssl_c_used } { ssl_fc_alpn -i h2 } { path_beg /tunnel }
use_backend server1 if { ssl_fc_sni atunnel.example.com } { ssl_c_used } { ssl_fc_alpn -i h2 } { path_beg /path2 }
use_backend server2 if { ssl_fc_sni btunnel.example.com } { ssl_c_used } { ssl_fc_alpn -i h2 } { path_beg /path3 }
use_backend server3 if { ssl_fc_sni ctunnel.example.com } { ssl_c_used } { ssl_fc_alpn -i h2 } { path_beg /path4 }
default_backend web
# Haproxy поддерживает несколько файлов pem для расшифровки.
# Разделение трафика можно выполнять на основе SNI или пути, доступны различные способы.
# Дополнительные сведения об ACL см. в документации Haproxy.
backend xray
server xray abns@vless.sock proto h2
backend server1
server server1 abns@server1.sock proto h2
backend server2
server server2 abns@server2.sock proto h2
backend server3
server server3 abns@server3.sock proto h2
backend web
server web /dev/shm/h1h2c.sock
Настройка Xray
Простая конфигурация gRPC, TLS не требуется. Конфигурация см. в документации. Параметр serviceName можно использовать для разделения трафика.