Введение

Так как я любитель selfhosted, у меня есть домашняя инфраструктура:

  • Orange Pi - медиасервер;

  • Synology - файлопомойка;

  • Neptune 4 - 3д принтер с веб интерфейсом и видео с камеры.

И хотелось бы иметь безопасный доступ к ней снаружи через телефон и ПК, но при этом иметь выход в интернет не в РФ.
Раньше для этих нужд я использовал OpenVPN, но теперь на него полагаться не стоит. Поэтому я начал изучать документацию к отличному инструменту от китайских товарищей - Xray!

Что понадобится:

  • Сервер с внешним IP с инфраструктурой. У меня - Orange Pi, далее - Bridge

  • Сервер, к которому хотим получить доступ - Server

  • Сервер вне РФ для выхода в интернет. Далее - Proxy

  • Клиент на ваш вкус. Далее - Client

  • Клиент и сервер на Linux - Xray-core, который можно поставить через официальный скрипт установки Xray

  • Клиент на андроид - v2rayNG

Еще клиенты можно найти в репозитории Xray-core

За базу берем файл конфигурации VLESS-TCP-XTLS-Vision-REALITY и начинаем читать документацию к Xray

Маршрутизация происходит на клиенте. Если клиент обращается к домену xray.com, например, то направляем траффик в Bridge, а для всех остальных соединений - в Proxy. Затем Bridge направляет траффик к Server, если клиент обращался к server.xray.com.
Выглядит так:

Файл конфигурации xray расположен в /usr/local/etc/xray/config.json и после каждого изменения этого файла необходимо перезапускать службу через systemctl restart xray.service

Установка

  1. Устанавливаем Xray на Bridge и Proxy:

bash -c "$(curl -L https://github.com/XTLS/Xray-install/raw/main/install-release.sh)" @ install
  1. Открываем порт 443 на Bridge и Proxy. Например, через ufw:

ufw allow 443
  1. Генерируем ключи серверов на Bridge или Proxy:

xray x25519

Приватный ключ заносится в файл конфигурации сервера xray, а публичный - конфиг клиента

  1. Генерируем UUID на каждого клиента и придумываем ему shortId:

xray uuid

UUID и shortId заносятся и в конфиги серверов, и клиентов
shortId должен быть HEX числом не длиннее 16 символов и кратно 2 символам, например a0, b1, ff

  1. Заносим приватный ключ, UUID, shortId, хостнейм сервера, по которому будем обращаться в файл конфигурации Bridge /usr/local/etc/xray/config.json:

`/usr/local/etc/xray/config.json`
 {
     "log": {
         "loglevel": "debug"
     },
     "inbounds": [Заносим в файл
         {
             "tag": "external",
             "port": 443,
             "protocol": "vless",
             "settings": {
                 "clients": [
                     {
                         "id": "client_uuid_0", // run `xray uuid` to generate
                         "flow": "xtls-rprx-vision"
                     },
                     {
                         "id": "client_uuid_1",
                         "flow": "xtls-rprx-vision"
                     }
                 ],
                 "decryption": "none"
             },
             "streamSettings": {
                 "network": "tcp",
                 "security": "reality",
                 "realitySettings": {
                     "dest": "google.com:443", // You can also use `1.1.1.1:443` as dest
                     "serverNames": [
                         "google.com" // If you use `1.1.1.1:443` as dest, then you can leave `serverNames` empty, it is a possible ways to bypass Iran's internet speed restrictions.
                     ],
                     "privateKey": "bridge_privateKey", // run `xray x25519` to generate. Public and private keys need to be corresponding.
                     "shortIds": [ // Required, list of shortIds available to clients, can be used to distinguish different clients
                         "client_shortId_0", // If this item exists, client shortId can be empty
                         "client_shortId_1",
                         "0123456789abcdef" // 0 to f, length is a multiple of 2, maximum length is 16
                     ]
                 }
             },
             "sniffing": {
                 "enabled": true,
                 "destOverride": [
                     "http",
                     "tls",
                     "quic"
                 ],
                 "routeOnly": true
             }
         }
     ],
     "outbounds": [
         {
             "tag": "out",
             "protocol": "freedom"
         },
         {
             "tag": "neptune4",
             "protocol": "freedom",
             "settings": {
                 "redirect": "server_lan_ip:0" // Forward all traffic to web server
             }
         }
     ],
     "routing": {
         "rules": [
             {
                 "type": "field",
                 "domain": [
                     "server.xray.com"
                 ],
                 "outboundTag": "server"
             }
         ]
     }
 }
  1. Для Proxy все попроще - заносим приватный ключ, UUID иshortId:

спойлер
  {
      "log": {
          "loglevel": "debug"
      },
      "inbounds": [
          {
              "tag": "proxy",
              "port": 443,
              "protocol": "vless",
              "settings": {
                  "clients": [
                      {
                          "ывфыid": "client_uuid_0", // run `xray uuid` to generate
                          "flow": "xtls-rprx-vision"
                      },
                      {
                          "id": "client_uuid_1",
                          "flow": "xtls-rprx-vision"
                      }
                  ],
                  "decryption": "none"
              },
              "streamSettings": {
                  "network": "tcp",
                  "security": "reality",
                  "realitySettings": {
                      "dest": "google.com:443", // You can also use `1.1.1.1:443` as dest
                      "serverNames": [
                          "google.com" // If you use `1.1.1.1:443` as dest, then you can leave `serverNames` empty, it is a possible ways to bypass Iran's internet speed restrictions.
                      ],
                      "privateKey": "proxy_privateKey", // run `xray x25519` to generate. Public and private keys need to be corresponding.
                      "shortIds": [ // Required, list of shortIds available to clients, can be used to distinguish different clients
                          "client_shortId_0", // If this item exists, client shortId can be empty
                          "client_shortId_1",
                          "0123456789abcdef" // 0 to f, length is a multiple of 2, maximum length is 16
                      ]
                  }
              },
              "sniffing": {
                  "enabled": true,
                  "destOverride": [
                      "http",
                      "tls",
                      "quic"
                  ],
                  "routeOnly": true
              }
          }
      ],
      "outbounds": [
          {Заносим в файл
              "protocol": "freedom",
              "tag": "direct"
          }
      ]
  }
  1. Перезапускаем службу xray на Bridge и Proxy:

systemctl restart xray.service

Подключение клиентом

Файл конфигурации общий для всех клиентов.
Заносим в файл конфигурации UUID, shortId, hostname или ip Proxy, Bridge, а также домен, по которому будем перенаправлять траффик:

спойлер
{
    "log": {
        "loglevel": "debug"
    },
    "routing": {
        "rules": [
            {
                "type": "field",
                "domain": [
                    "xray.com"
                ],
                "outboundTag": "bridge"
            }
        ]
    },
    "inbounds": [
        {
            "listen": "127.0.0.1",
            "port": 10808,
            "protocol": "socks",
            "settings": {
                "udp": true
            },
            "sniffing": {
                "enabled": true,
                "destOverride": [Заносим в файл
                    "http",
                    "tls",
                    "quic"
                ],
                "routeOnly": true
            }
        }
    ],
    "outbounds": [
        {
            "protocol": "vless",
            "settings": {
                "vnext": [
                    {
                        "address": "proxy_hostname_or_ip",
                        "port": 443,
                        "users": [
                            {
                                "id": "client_uuid_0", // Needs to match server side
                                "encryption": "none",
                                "flow": "xtls-rprx-vision"
                            }
                        ]
                    }
                ]
            },
            "streamSettings": {
                "network": "tcp",
                "security": "reality",
                "realitySettings": {
                    "fingerprint": "chrome",
                    "serverName": "google.com", // If your dest is `1.1.1.1:443`, then leave it empty
                    "publicKey": "proxy_publicKey", // run `xray x25519` to generate. Public and private keys need to be corresponding.
                    "spiderX": "", // If your dest is `1.1.1.1:443`, then you can fill it with `/dns-query/` or just leave it empty
                    "shortId": "client_shortId_0" // Required
                }
            },
            "tag": "proxy"
        },
        {
            "protocol": "vless",
            "settings": {
                "vnext": [
                    {
                        "address": "bridge_hostname_or_ip",
                        "port": 443,
                        "users": [
                            {
                                "id": "client_uuid_0", // Needs to match server side
                                "encryption": "none",
                                "flow": "xtls-rprx-vision"
                            }
                        ]
                    }
                ]
            },
            "streamSettings": {
                "network": "tcp",
                "security": "reality",
                "realitySettings": {
                    "fingerprint": "chrome",
                    "serverName": "google.com", // If your dest is `1.1.1.1:443`, then leave it empty
                    "publicKey": "bridge_publicKey", // run `xray x25519` to generate. Public and private keys need to be corresponding.
                    "spiderX": "", // If your dest is `1.1.1.1:443`, then you can fill it with `/dns-query/` or just leave it empty
                    "shortId": "client_shortId_0" // Required
                }
            },
            "tag": "bridge"
        }
    ]
}

Linux

  1. Устанавливаем Xray:

bash -c "$(curl -L https://github.com/XTLS/Xray-install/raw/main/install-release.sh)" @ install
  1. Записываем файл конфигурации в /usr/local/etc/xray/config.json

  2. Перезапускаем службу:

systemctl restart xray.service

Теперь на клиенте запущен локальный socks5, к которому можно подключиться через браузер, например, в Firefox Settings -> Network Settings -> Settings -> Manual proxy configuration:
Socks Host: 127.0.0.1 Port: 10808
Устанавливаем флаг SOCKS v5

Android

  1. Устанавливаем v2rayNG

  2. Загружаем файл конфигурации на телефон

  3. Добавляем файл конфигурации в приложении через Custom config -> Import custom config from locally

  4. Включаем

Выбрать, какие приложения пускать через xray, можно через Settings -> VPN Settings -> Per-app proxy

Заключение

Теперь у нас есть доступ к своей инфраструктуре по доменному имени и нормальный интернет.
Бонусом:
Можно подключаться к Server по ssh через xray. Одной строкой:

ssh root@server.xray.com -o "ProxyCommand=nc -X connect -x 127.0.0.1:10808 %h %p"

Или прописать в ~/.ssh/config:

Host server
    Hostname server.xray.com
    User root
    ProxyCommand nc -X 5 -x 127.0.0.1:10808 %h %p
    ServerAliveInterval 10

Комментарии (19)


  1. runetfreedom
    03.11.2024 14:57

    Во первых, Xray это не vpn, это прокси.

    Во вторых, vpn протоколы внутри РФ обычно не блокируются, так что к дому можно подключаться хоть через wireguard


    1. anwender95 Автор
      03.11.2024 14:57

      Да, Xray является прокси. Я успел где-то упомянуть, что он является VPN-ом?)

      Да, сейчас VPN-ны в РФ работают более стабильно, но я захотел сделать себе канал связи, который меньше зависит от хотелок РКН.

      Ну и самое главное - один конфиг для всего. Я не нашел легкого способа держать включенным xray и OpenVPN на телефоне. Еще думал про Cloak, но на андроиде не нашел возможности его юзать с OpenVPN.


      1. runetfreedom
        03.11.2024 14:57

        Да, Xray является прокси. Я успел где-то упомянуть, что он является VPN-ом?)

        Да, прямо в заголовке и тегах упомянули.


    1. maxzh83
      03.11.2024 14:57

      Wireguard вполне себе блокируют некоторые провайдеры, сам натыкался


    1. Allozorro
      03.11.2024 14:57

      Дом ру - не работает ни Wireguard, ни OpenVPN.


      1. runetfreedom
        03.11.2024 14:57

        Вы внутри РФ подключаетесь?


        1. Allozorro
          03.11.2024 14:57

          Да. WG отвалился в позапрошлый четверг.


          1. runetfreedom
            03.11.2024 14:57

            Вы можете попросить провайдера обратиться в ГРЧЦ и попросить внести сервер в белый список. Это, если что, сейчас очень распространенно.


            1. mba892
              03.11.2024 14:57

              Почему мы должны кланяться и просить? Я тоже выберу XRay (свободу).


            1. dartraiden
              03.11.2024 14:57

              Сдаётся мне, что быстрее перейти на другой протокол, чем теребить неповоротливую махину в виде домру или ростелекома.

              А потом у сервера поменяется IP-адрес (мне вот на днях пришлось по техническим причинам поменять) и придётся повторять всё заново (ну или тратиться на не особо нужное доменное имя, а бесплатные домены второго уровня сейчас никто уже не даёт).


            1. zqpqy
              03.11.2024 14:57

              "Такой возможности нет, но вы можете обратиться туда сами", сказал крупный провайдер.


              1. oller
                03.11.2024 14:57

                А можно ссылку, куда обращаться

                Мы бы и сами и через провайдера готовы


          1. ABATAPA
            03.11.2024 14:57

            Блокировка Wireguard "лечится" обфускацией IP.


            1. Allozorro
              03.11.2024 14:57

              Всем понятно как оно лечится и какие аналоги имеются. Суть в том, что провайдеры блочат эти протоколы.


          1. iserver
            03.11.2024 14:57

            А AmneziaWG проверяли ? У знакомых такой же пров. С Амнезией всё работает.


            1. Allozorro
              03.11.2024 14:57

              Да, с AWG всё ок. Завернул в неё дискорд и прочее нужное на Кинетике.


  1. rebug
    03.11.2024 14:57

    А вот как еще настроить чтобы к серверу подключаться по ssh не по 127.0.0.1, а по другому айпишнику? Выглядит так, будто может оказаться конфликт портов и будет выбираться локальный (у меня так было с shadowsocks v2ray). По видимому надо на сервере настроить, чтобы кроме 127.0.0.1 было еще ип например 128.0.0.1 или в хостс прописать помимо localhost другое название


    1. anwender95 Автор
      03.11.2024 14:57

      Я когда экспериментировал с этим столкнулся, но здесь у нас используются хостнеймы и они же хранятся в ~/.ssh/known_hosts
      Т.е. там будет server.xray.com, а не 127.0.0.1
      А локалхост - просто прокси в настройках соединения. В данном конфиге, локалхост у нас является интерфейсом к xray.


  1. seoevil
    03.11.2024 14:57

    Че то подумал про LADA по заголовку