Xray по сути является целым фреймворком, который поддерживает просто огромное количество различных протоколов и алгоритмов шифрования.
В этой статье рассмотрим настройку в качестве маршрутизатора, где xray будет отправлять весь трафик через vps в Германии, а трафик chatgpt через офис в Казахстане.
Инфо по установке xray тут. Документация тут.
Настройка NGINX-DPI
Тут просто указываем адрес и порт xray-router:
local proxy_addr = "127.0.0.1";
local proxy_port = 1082;
Настройка XRAY-ROUTER
Чтобы было проще читать конфиг распишу что к чему. В секции routing описываем правила по типу если domain такой-то, то отправляем трафик на такой-то сервер по тегу (outboundTag).
В секции inbounds (входящие) указываем какой адрес и порт должен слушать xray.
В секции outbounds (исходящие) указываем сервера и с помощью тегов задаем им имена по которым и обращаемся к серверам в секции routing.
{
"log": {
"access": "/var/log/xray/access.log",
"error": "/var/log/xray/error.log",
"loglevel": "debug"
},
"routing": {
"domainStrategy": "AsIs",
"domainMatcher": "hybrid",
"rules": [
{
"type": "field",
"network": "tcp",
"protocol": [
"http",
"tls"
],
"domain": [
"ip.me",
"chat.openai.com",
"auth0.openai.com",
"lawinsider.com",
"instagram.com"
],
"outboundTag": "kz"
},
{
"type": "field",
"network": "tcp",
"protocol": [
"http",
"tls"
],
"domain": [
"ifconfig.me",
"geoip:!ru"
],
"outboundTag": "de"
},
{
"type": "field",
"domain": [
"geoip:ru"
],
"outboundTag": "direct"
}
]
},
"inbounds": [
{
"listen": "127.0.0.1",
"port": 1082,
"protocol": "socks",
"settings": {
"udp": false,
"ip": "127.0.0.1"
},
"sniffing": {
"enabled": true,
"destOverride": [
"http",
"tls"
]
}
}
],
"outbounds": [
{
"protocol": "vless",
"settings": {
"vnext": [
{
"address": "<server_name>",
"port": <server_port>,
"users": [
{
# id генерируется командой /usr/local/bin/xray uuid
"id": "<id>",
"encryption": "none",
"flow": "xtls-rprx-vision"
}
]
}
]
},
"streamSettings": {
"network": "tcp",
"security": "tls",
"tlsSettings": {
"serverName": "xray",
"allowInsecure": true,
"fingerprint": "randomized"
}
},
"tag": "de"
},
{
"protocol": "vless",
"settings": {
"vnext": [
{
"address": "<server_name>",
"port": <server_port>,
"users": [
{
# id генерируется командой /usr/local/bin/xray uuid
"id": "<id>",
"encryption": "none",
"flow": "xtls-rprx-vision"
}
]
}
]
},
"streamSettings": {
"network": "tcp",
"security": "tls",
"tlsSettings": {
"serverName": "xray",
"allowInsecure": true,
"fingerprint": "randomized"
}
},
"tag": "kz"
},
{
"protocol": "freedom",
"tag": "direct"
}
]
}
Замените <server_ip> и <server_port> на свои и постарайтесь на запутаться. Также замените <id> на свои в секции users (считайте это логин и пароль по которому сервер идентифицирует клиента).
НАСТРОЙКА XRAY-SERVER
Приведу конфиг только для одного сервера поскольку они отличаются только портом и id.
{
"log": {
"access": "/var/log/xray/access.log",
"error": "/var/log/xray/error.log",
"loglevel": "error"
},
"inbounds": [
{
"listen": "0.0.0.0",
"port": <server_port>,
"protocol": "vless",
"settings": {
"clients": [
{
"id": "<id>",
"flow": "xtls-rprx-vision"
}
],
"decryption": "none"
},
"streamSettings": {
"network": "tcp",
"security": "tls",
"tlsSettings": {
"allowInsecure": true,
"rejectUnknownSni": false,
"minVersion": "1.2",
"certificates": [
{
"ocspStapling": 3600,
"certificateFile": "/etc/ssl/hysteria-server.crt",
"keyFile": "/etc/ssl/hysteria-server.key"
}
]
}
},
"sniffing": {
"enabled": true,
"destOverride": [
"http",
"tls"
]
}
}
],
"outbounds": [
{
"protocol": "freedom",
"tag": "direct"
},
{
"protocol": "blackhole",
"tag": "block"
}
],
"policy": {
"levels": {
"0": {
"handshake": 2,
"connIdle": 120
}
}
}
}
В качестве ssl сертификата использовали самоподписный сертификат, который использовался для hysteria, но если есть сертификат от letsencrypt, то так даже лучше будет.
НАСТРОЙКА NGINX
В секцию http прописываем следующие директивы:
map $proxy_protocol_addr $proxy_forwarded_elem {
~^[0-9.]+$ "for=$proxy_protocol_addr";
~^[0-9A-Fa-f:.]+$ "for=\"[$proxy_protocol_addr]\"";
default "for=unknown";
}
map $http_forwarded $proxy_add_forwarded {
"~^(,[ \\t]*)*([!#$%&'*+.^_`|~0-9A-Za-z-]+=([!#$%&'*+.^_`|~0-9A-Za-z-]+|\"([\\t \\x21\\x23-\\x5B\\x5D-\\x7E\\x80-\\xFF]|\\\\[\\t \\x21-\\x7E\\x80-\\xFF])*\"))?(;([!#$%&'*+.^_`|~0-9A-Za-z-]+=([!#$%&'*+.^_`|~0-9A-Za-z-]+|\"([\\t \\x21\\x23-\\x5B\\x5D-\\x7E\\x80-\\xFF]|\\\\[\\t \\x21-\\x7E\\x80-\\xFF])*\"))?)*([ \\t]*,([ \\t]*([!#$%&'*+.^_`|~0-9A-Za-z-]+=([!#$%&'*+.^_`|~0-9A-Za-z-]+|\"([\\t \\x21\\x23-\\x5B\\x5D-\\x7E\\x80-\\xFF]|\\\\[\\t \\x21-\\x7E\\x80-\\xFF])*\"))?(;([!#$%&'*+.^_`|~0-9A-Za-z-]+=([!#$%&'*+.^_`|~0-9A-Za-z-]+|\"([\\t \\x21\\x23-\\x5B\\x5D-\\x7E\\x80-\\xFF]|\\\\[\\t \\x21-\\x7E\\x80-\\xFF])*\"))?)*)?)*$" "$http_forwarded, $proxy_forwarded_elem";
default "$proxy_forwarded_elem";
}
Теперь в каждом виртуальном хосте в секции server прописываем вместо listen:
listen 127.0.0.1:8001 proxy_protocol;
listen 127.0.0.1:8002 http2 proxy_protocol;
set_real_ip_from 127.0.0.1;
real_ip_header proxy_protocol;
real_ip_recursive on;
...
Также, если ваш сайт в корне имеет редирект, то надо добавить директиву "port_in_redirect off;", чтобы порт в ссылку не дописывался при редиректе. А еще, если браузер блокирует загрузку статики с ошибкой "blocked:mixed-content", то добавьте директиву "add_header 'Content-Security-Policy' 'upgrade-insecure-requests';".
ТЕСТИРУЕМ
Прописываем в nginx-dpi ip.me и ifconfig.me.
local force_domains = {
"ip.me",
"ifconfig.me",
"openai.com",
"lawinsider.com",
"instagram.com",
"cloudflare.com",
"cloudflare.net"
}
Теперь если зайти в ip.me, то определится казахский ip-адрес, а если зайти в ifconfig.me, то немецкий.
Единственное неудобство это то, что придется вести два списка доменов, но с другой стороны таких жестких блокировок как в openai не много.
Спасибо @feel за конфигурации.
UPD 09.06.23: ПРЯЧЕМ OPENVPN
Вообщем появились нехорошие новости о возможной блокировке vpn протоколов. Решили подстраховаться и спрятать трафик openvpn site to site внутри xray на примере pfsense.
Предположим, что у сервера локальный адрес a.a.a.a, а у клиента b.b.b.b. Сперва настроим сервер openvpn.
vpn->openvpn->servers->выбираем конфигурацию сервера->protocol: TCP->interface: LAN
Теперь настроим клиент.
vpn->openvpn->clients->выбираем конфигурацию клиента->protocol: TCP->interface: LAN->server host: a.a.a.a
# далее переходим в секцию custom options и прописываем следующее
socks-proxy <xray-router-ip> <xray-router-port>;
socks-proxy-retry;
Теперь настроим xray-router. Добавим в секцию rules новое правило.
{
"type": "field",
"network": "tcp",
"ip": [
"a.a.a.a"
],
"outboundTag": "kz"
},
Таким образом мы говорим xray, что если в запросе присутствует ip a.a.a.a, то трафик идет в казахский офис и далее openvpn клиент подключается к серверу по локальному ip-адресу по протоколу tcp.