Xray + прозрачный доступ к onion/i2p ресурсам

Необходимости сохранять анонимность при доступе в даркнет нету. Просто хочется настроить прозрачный доступ чтобы было.

На сервере крутится xray + tor, имеется такое правило маршрутизации

{
                "type": "field",
                "outboundTag": "TOR",
                "domain": [
                    "domain:onion"
                ]
            },

имеем такой outbound

        {
            "tag": "TOR",
            "protocol": "socks",
            "settings": {
                "servers": [
                    {
                        "address": "127.0.0.1",
                        "port": 9050
                    }
                ]
            }
        },

В режиме socks5-прокси например с компа сайт http://flibustaongezhld6dibs2dps6vm4nvqg2kp7vgowbu76tzopgnhazqd.onion/ открывается но не с первого раза, при этом в логах на сервере в /var/log/xray/error.log имеем строки вида

2023/11/18 06:58:46 [Warning] [2410852795] app/proxyman/outbound: failed to process outbound traffic > proxy/socks: failed to establish connection to server > read tcp 127.0.0.1:12456->127.0.0.1:9050: i/o timeout

в документации к xray не нашел способа увеличить таймут для этого outbound.

Ну а на мобильном не всем браузерам подсунешь socks5 прокси. А в режиме tun - это вооще не работает…

Я так понимаю что должен быть какой-то “локальный” dns-сервер на xray-сервере который будет выдавать уникальные фейковые ip-адреса (наверное AAAA записи из какого-нибудь волшебного CIDR) для onion, весь dns клиента завернуть на xray чтобы он прозрачно получал ipv6 до onion и потом уже работал с ним…

Может кто-то уже делал что-то подобное?

С i2p аналогично, сейчас пока разбираюсь с onion…

    "policy": {
        "levels": {
            "0": {
                "handshake": 10
            }
        }
    },

не помогает?

вот еще нашел конфиг для sing-box Regarding nonIPQuery · XTLS/Xray-core · Discussion #2298 · GitHub

Помогло!

Касательно DNS пошел путем linux-way. В torrc добавил строки:

DNSPort 127.0.0.2:53
AutomapHostsOnResolve 1
AutomapHostsSuffixes .onion

Потом склеил все с помощью dnsmasq добился такого поведения на стороне VDS

root@v2136098:/opt/real# nslookup flibustaongezhld6dibs2dps6vm4nvqg2kp7vgowbu76tzopgnhazqd.onion
Server:         127.0.0.1
Address:        127.0.0.1#53

Non-authoritative answer:
Name:   flibustaongezhld6dibs2dps6vm4nvqg2kp7vgowbu76tzopgnhazqd.onion
Address: 127.230.9.54
Name:   flibustaongezhld6dibs2dps6vm4nvqg2kp7vgowbu76tzopgnhazqd.onion
Address: fe80:2f39:b9c6:12ab:10cf:1857:51ca:c510

root@v2136098:/opt/real# nslookup flibusta.lib
Server:         127.0.0.1
Address:        127.0.0.1#53

Non-authoritative answer:
Name:   flibusta.lib
Address: 179.43.150.83

В server-config.json поставил единственный сервер в dns

"dns": {
        "servers": [
            "tcp+local:\/\/127.0.0.1"
        ]
    }

В режиме socks заработала lib (потому как в настройках dnsmasq указал серверы OpenNIC) но в режиме tun на клиенте не работает: не ресолвится

Клиент - свежий v2rayNG…

в v2rayng прописан remote dns 127.0.0.1?

пробовал - вообще никакие страницы не находит, есть мысли но пока воюю на стороне VDS, прикрутил i2pd, все оказалось проще

В dnsmasq прибил гвоздями 1 адрес и для onion и i2p:

address=/i2p/127.254.0.1
address=/onion/127.254.0.1

повесил на http-порту привокси:

listen-address 127.254.0.1:80
forward-socks5t   .onion     127.0.0.1:9050 .
forward           .i2p   127.0.0.1:4444

итого wget на vds выдает и onion и i2p

Теперь вот думаю понравится ли ip адрес 127.254.0.1 клиенту, не попробует ли он сделать bypass lan

Не в курсе можно ли создать фиктивный адрес типа 195.1.1.1 который будет действовать в рамках VDS на который можно будет повесить привокси?

Установите какой-то локальный адрес на интерфейс lo, его и пропишите в конфигурационных файлах. При этом слушать (bind’ится) только на этом интерфейсе не нужно.

root@v2136098:~# ip address show dev lo
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet 195.195.195.195/32 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever

root@v2136098:~# nslookup stats.i2p 195.195.195.195
Server:         195.195.195.195
Address:        195.195.195.195#53

Name:   stats.i2p
Address: 195.195.195.195

root@v2136098:~# nslookup ya.ru 195.195.195.195
Server:         195.195.195.195
Address:        195.195.195.195#53

Non-authoritative answer:
Name:   ya.ru
Address: 5.255.255.242
Name:   ya.ru
Address: 77.88.55.242
Name:   ya.ru
Address: 2a02:6b8::2:242

root@v2136098:~# nslookup rutor.lib 195.195.195.195
Server:         195.195.195.195
Address:        195.195.195.195#53

Non-authoritative answer:
Name:   rutor.lib
Address: 193.46.255.25



ya.ru - работает!
rutor.lib - не ресолвит!

Вот такая фигня. Может scope поменять попробовать у 195.195.195.195 ?

ЗЫ. Прописал в v2rayng левые dns - при соединении проверка средствами v2rayng говорит что сбой а браузер работает как ни в чем не бывало, ip vps на 2ip.ru показывает

ЗЫ2. Включил галочку fakedns в клиенте, заработало. Но это я так понимаю костыль на стороне клиента, и мой внутренний перфекционист грызет меня со страшной силой.

Заработало.

При включенной галочке на виртуальном адресе 26.26.26.2:53 поднимается UDP-only который редиректит dns-запросы на удаленный ресолвер xray

Смысл опций “удаленная / внутреняя dns” пока не ясен

@ValdikSS получилось, вот инструкция может кому пригодится

  1. Обычный DNS рулим на VDS стандартными средствами, ресолвер вешаем на 127.0.0.1:53, помним про /etc/resolve.conf

  2. Сломался outbound protocol=“wireguard” , пришлось запускать 2-й экземпляр XRay и лазить в него из основного через socks:

{
    "log": {
        "loglevel": "warning",
        "access": "\/var\/log\/xray\/wg-access.log",
        "error": "\/var\/log\/xray\/wg-error.log",
        "dnsLog": false
    },
    "dns": {
        "servers": [
            "tcp+local:1.1.1.1",
            "tcp+local:1.0.0.1"
        ]
    },
    "inbounds": [
        {
            "port": "1081",
            "listen": "127.0.0.1",
            "tag": "wireproxy",
            "protocol": "socks",
            "settings": {
                "auth": "noauth",
                "udp": true
            }
        }
    ],
    "outbounds": [
        {
            "tag": "WARP",
            "protocol": "wireguard",
            "settings": {
                "secretKey": "...",
                "address": [
                    "172.16.0.2\/32",
                    "2606:4700:110:8de1:4b29:ef08:2482:535d\/128"
                ],
                "peers": [
                    {
                        "endpoint": "engage.cloudflareclient.com:2408",
                        "publicKey": "bmXOC+F1FxEMF9dyiK2H5\/1SUtzH0JuVo51h2wPfgyo="
                    }
                ],
                "mtu": 1280
            }
        }
    ],
    "routing": {
        "domainStrategy": "IPOnDemand",
        "rules": []
    }
}
  1. Ставим привокси:
listen-address 127.0.0.1:8118
accept-intercepted-requests 1

user-manual /usr/share/doc/privoxy/user-manual
confdir /etc/privoxy
logdir /var/log/privoxy

forward-socks5t   .onion     127.0.0.1:9050 .
forward           .i2p   127.0.0.1:4444

logfile logfile
toggle  0
enable-remote-toggle  0
enable-remote-http-toggle  0
enable-edit-actions 0
enforce-blocks 0
buffer-limit 4096
enable-proxy-authentication-forwarding 0
forwarded-connect-retries  0
allow-cgi-request-crunching 0
split-large-forms 0
keep-alive-timeout 5
tolerate-pipelining 1
socket-timeout 300

  1. xray
{

"dns": {
        "tag": "dns_inbound",
        "servers": [
            "localhost"
        ],
        "hosts": {
            "domain:onion": "155.155.155.155",
            "domain:i2p": "155.155.155.155"
        }
    },
    "inbounds": [
        {
            "listen": "127.0.0.4",
            "port": 53,
            "protocol": "dokodemo-door",
            "network": "tcp,udp",
            "settings": {
                "address": "127.0.0.1",
                "port": 53,
                "network": "tcp,udp"
            },
            "tag": "dns-in"
        },
.....
],
    "outbounds": [
        {
            "protocol": "freedom",
            "domainStrategy": "AsIs",
            "tag": "freedom",
            "settings": {}
        },
        {
            "protocol": "freedom",
            "domainStrategy": "AsIs",
            "tag": "privoxy",
            "redirect": "127.0.0.1:8118",
            "userLevel": 5,
            "settings": {}
        },
        {
            "protocol": "dns",
            "address": "9.9.9.9",
            "port": 53,
            "settings": {
                "nonIPQuery": "drop"
            },
            "tag": "dns-out"
        },
        {
            "tag": "WARP",
            "protocol": "socks",
            "settings": {
                "servers": [
                    {
                        "address": "127.0.0.1",
                        "port": 1081
                    }
                ],
            }
        },
        {
            "tag": "TOR",
            "protocol": "socks",
            "settings": {
                "servers": [
                    {
                        "address": "127.0.0.1",
                        "port": 9050,
                        "users": [
                            {
                                "user": "tor-user",
                                "pass": "tor-pass",
                                "level": 5
                            }
                        ]
                    }
                ]
            }
        },
        {
            "tag": "i2p",
            "protocol": "socks",
            "settings": {
                "servers": [
                    {
                        "address": "127.0.0.1",
                        "port": 4447,
                        "users": [
                            {
                                "user": "i2p-user",
                                "pass": "i2p-pass",
                                "level": 5
                            }
                        ]
                    }
                ]
            }
        },
        {
            "protocol": "blackhole",
            "tag": "block"
        }
    ],
    "routing": {
        "domainStrategy": "IPIfNonMatch",
        "rules": [
            {
                "type": "field",
                "inboundTag": [
                    "dns_inbound"
                ],
                "outboundTag": "freedom",
                "network": "tcp,udp"
            },
            {
                "type": "field",
                "port": "53",
                "outboundTag": "dns-out",
                "network": "tcp,udp"
            },
            {
                "type": "field",
                "outboundTag": "TOR",
                "domain": [
                    "domain:onion"
                ]
            },
            {
                "type": "field",
                "outboundTag": "i2p",
                "domain": [
                    "domain:i2p"
                ]
            },
            {
                "type": "field",
                "ip": [
                    "155.155.155.15"
                ],
                "outboundTag": "privoxy",
                "network": "tcp"
            },
            {
                "type": "field",
                "ip": [
                    "geoip:private"
                ],
                "outboundTag": "block"
            },
            {
                "type": "field",
                "port": "25, 587, 465, 2525",
                "network": "tcp",
                "outboundTag": "block"
            },
            {
                "type": "field",
                "outboundTag": "block",
                "domain": [
                    "geosite:category-ads-all"
                ]
            },
            {
                "type": "field",
                "user": [
                    "rl_0_Dmitry"
                ],
                "outboundTag": "WARP"
            },
            {
                "type": "field",
                "protocol": [
                    "bittorrent"
                ],
                "outboundTag": "block"
            }
        ]
    },
    "policy": {
        "levels": {
            "0": {
                "handshake": 5,
                "connIdle": 120
            },
            "5": {
                "handshake": 120,
                "connIdle": 300
            }
        }
    }
}
  1. Настрока v2rayng
    включаем эту галочку

а тут забавнее. Явно тыкаем на удаленная DNS и очищаем значение. При этом в UI все равно будет отображаться 1.1.1.1 Поэтому тыкаем и убеждаемся что в окошке редактирования поле пустое

Касательно “Внутренная DNS” наоборот - открывам и явно прописываем 223.5.5.5 (тыкаем и убеждаемся что в окошке редактирования поле НЕ пустое)