Приветики. Надеюсь, все отошли от новогодних, и можно писать и читать дальше. Как хозяин умного дома, я состою в чатике по Home Assistant, там прекрасное отзывчивое комьюнити,
но периодически задаётся вопрос по тому, как собственно выставить свой веб сервис в интернет. И оказывается, что в двух словах тут не ответишь, а вменяемой инструкции на которую можно дать ссылку - нет. Так что теперь она будет здесь.

Рокет сайнса здесь не встретите, и в целом все эти вещи справедливы и работают уже минимум лет 10, просто не так тривиально понять, какой именно запрос нужно задать в гугл, и что делать.

Мы рассмотрим здесь несколько сценариев - статический белый айпи, динамический белый айпи, и серый. Для серого рассмотрим варианты с готовыми сервисами, с помощью Keenetic и с помощью ssh туннеля. Погнали!

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

1. Белый статический айпи

Если вы являетесь счастливым обладателем статического внешнего айпи адреса, то и делать-то особо ничего не надо. Просто настраиваем свой сервер или роутер как веб сервер, максимум - пробрасываем с роутера порты.

Минусы такого варианта - нужно озаботиться безопасностью сервера, закрыть все лишние порты, а ещё вы оказываетесь прибиты гвоздями к этому физическому месту и своему провайдеру.

Если у вас нет белого статического айпи - переходим к пункту 2.

2. Белый динамический айпи

Кажется, это уже экзотика, но встречается до сих пор. Проще всего настроиться через KeenDNS, который есть на роутерах Keenetic, DynDNS, DuckDNS или любой другой аналогичный сервис. Минусы такого решения те же, что со статическим адресом.

Если у вас нет белого динамического айпи - переходим к пункту 3. Он подойдёт для любой ситуации.

3. Серый айпи или закрытые порты на доступ извне

Первые два варианта я упомянул скорее для формальности, потому что большая часть пользователей находится именно на серых айпи адресах, и без каких-то нестандартных финтов ушами опубликовать себя в интернет не сможет. Что же делать? Тут есть несколько вариантов.

3.1 Используем возможности роутера

Как я уже упомянул ранее, у Keenetic есть сервис KeenDNS. И у него есть два режима работы. Direct - это собственно обычный DNS сервис, который поможет, если у вас публичный айпи адрес. И Cloud, который на самом деле не имеет никакого отношения к DNS, а просто прокидывает туннель к вашей локальной сети через облако Keenetic.

Вот вариант с облаком нам поможет в этой ситуации - парой галок можно получить свой облачный домен для сервиса, прокинуть порт от устройства в локальной сети наружу, сделать там Basic Auth, и ещё и SSL сертификат на него навесить. Просто сказка!

Лет 8 им пользовался, ни единого разрыва. Однако, минусы тоже есть:

  • По умолчанию не прокидывается заголовок хоста. Поэтому я все эти годы мучался и вешал сервисы на разные порты. Прямо перед написанием статьи я всё же смог нагуглить решение и прокинуть заголовок - но это прям неочевидно.

  • А вот Referer и Origin прокинуть так и не удаётся. Хотя в реальной жизни я на это наступил ровно один раз, когда Authentik отказался пропускать мои запросы, защитившись от них при помощи CSRF. Пришлось руками прописать то, что должно быть в заголовках. Это, конечно, сводит защиту CSRF на ноль, но... Защита без токенов всё равно такое себе.

  • Ничто не вечно под луной, и в какой-то момент сервис может прилечь или прекратить работу, и тогда весь ваш веб станет резко недоступен

  • Паранойя может помешать вам гонять личный трафик через облако вендора роутера

  • Вы не сможете поменять роутер на роутер другой фирмы, и получите вендор лок

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

Ну и основная проблема при использовании такого решения - у вас может быть роутер другой фирмы. Не знаю, есть ли у них аналогичные сервисы, не встречал, может кто в комментариях поделится. Но если нету - идём дальше по списку решений!

3.2 Используем сторонний сервис

Есть немало сервисов, которые бесплатно или за символические деньги заниматся тем же, что KeenDNS - прокидывают вам туннель наружу.

Навскидку могу перечислить:

  • pinggy.io

  • localtonet.com

  • cloudflare tunnel

  • cloudflare zero trust

  • zrok кажется тоже умеет при self hosted установке, но я не осилил найти инструкцию

  • вроде у google тоже есть какое-то туннелирование

  • ngrok может за деньги дать вам кастомный домен, или бесплатно - постоянный, но случайно сгенерированный.

В общем, вариантов много, можно найти что понравится. Минусы примерно те же самые, что у KeenDNS, за исключением отвязки от вендора вашего роутера.

Не нравится? Ну что же, для упоротых упорных есть уровень хардкора!

3.3 Используем собственное облако и SSH туннель

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

Для данного решения вам потребуется:

  • Сервер на внешнем хостинге с белым айпи на Linux

  • Домашний сервер на Linux

  • Домен, в котором вы управляете зонами и можете наклепать себе удобных поддоменов

  • Базовое знание Linux

А кто говорил, что будет легко.

3.3.1 Настраиваем доступ по сертификату на свой сервер

Для начала нам понадобится настроить доступ по SSH с помощью сертификата. Под это есть много инструкций, больших и подробных, под любой дистрибутив - так что я не буду здесь пытаться их переплюнуть. Просто загуглите.

На выходе у вас должна с домашнего сервера отрабатывать команда ssh user_login@mydomain.com -i /home/path_to_home_dir/.ssh/private_key и по ней вы должны оказываться на своём сервере.

3.3.2 Прокидываем порт

Теперь мы воспользуемся особой серверной магией - при помощи ssh прокинем локальный порт на удалённый сервер.

ssh -R 8080:localhost:9000 user_login@mydomain.com -i /home/path_to_home_dir/.ssh/private_key -N

В этом примере порт 8080 нашей локальной машины прокидывается на 9000 порт удалённого сервера.

Подставьте вместо 8080 порт вашего приложения, а вместо 9000 - какой-нибудь свободный порт удалённого сервера. Тогда после выполнения команды ваш сервис должен стать доступен через ваш удалённый сервер по указанному порту.

Если не получилось - выставьте AllowTcpForwarding yes и GatewayPorts yes в sshd_config удалённого сервера и перезапустите ssh там.

Если всё ещё не получилось - временно выключите там фаервол или добавьте новый порт в его исключения.

Если всё ещё не получилось - stack overflow вам в помощь, задача супер стандартная.

3.3.2 Проксируем туннель через nginx

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

Предположим, что локальный сервис у вас крутится на порту 8123. Тогда конфиг сайта локального nginx будет примерно такой:

upstream some_service {
       server 127.0.0.1:8123;
}

server {
    listen 8080;
    server_name subdomain.mydomain.com;
    access_log /var/log/nginx/service-access-remote.log main;
    error_log /var/log/nginx/service-error-remote.log;

location / {
    proxy_pass http://some_service;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "Upgrade";
    proxy_set_header Host $host;

    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Real-IP $remote_addr;
    }
}

То есть, все запросы, которые придут через туннель на порт 8080, будут проверены на домен, и в случае, если домен равен subdomain.mydomain.com - будут переданы на порт 8123.

Так же нам потребуется настроить удалённый nginx:

upstream tunnel {
       server 127.0.0.1:9000;
}

server {
    listen 80;
    server_name subdomain.mydomain.com;
    access_log /var/log/nginx/service-access.log main;
    error_log /var/log/nginx/service-error.log;

location / {
    proxy_pass http://tunnel;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "Upgrade";
    proxy_set_header Host $host;

    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Real-IP $remote_addr;
    }
}

Теперь у нас есть полная цепочка:

  1. Запрос приходит на 80 порт удалённого сервера с указанием домена subdomain.mydomain.com

  2. Nginx на удалённом сервере слушает порт, видит домен, пишет логи доступа и отправляет запрос в туннель на порту 9000

  3. Туннель "выныривает" на вашем локальном сервере на порту 8080 и попадает в локальный Nginx

  4. Локальный nginx опять же видит домен и на его основании пересылает запрос уже в конечное приложение на порту 8123

Звучит на первый взгляд сложно, зато позволяет через один туннель гонять сколько угодно запросов к различным сайтам сервера.

3.3.3 Ни единого разрыва!

Всё готово? Как бы не так! SSH туннель может упасть при обрыве коннекта, и вместо доступного извне сервера у вас окажется тыква.

Чтобы этого не случилось, можно воспользоваться пакетом autossh из штатного репозитория - он обеспечит автоматическое переподнятие туннеля.

Ставим пакет, и запускаем его примерно так:
autossh -NR 8080:localhost:9000 -M 0 -o "ServerAliveInterval 10" -o "ServerAliveCountMax 3" user_login@mydomain.com -i /home/path_to_home_dir/.ssh/private_key

Теперь туннель не умрёт. Но... Подождите, что же будет при ребуте локального сервера?

3.3.4 Переживший ребут

Можно добавить команду в @reboot от cron, но мне кажется более правильным добавить новый системный сервис.

Добавляем настройку демона, например, в такой файл - /etc/systemd/system/autossh.service:

[Unit]
Description=AutoSSH to My Server
After=network.target

[Service]
Environment="AUTOSSH_GATETIME=0"
Environment="AUTOSSH_LOGFILE=/var/log/autossh"
ExecStart=autossh -NR  8080:localhost:9000 -M 0 -o "ExitOnForwardFailure=yes" -o "ServerAliveInterval=180" -o "ServerAliveCountMax=3" -o "PubkeyAuthentication=yes" -o "PasswordAuthentication=no" -i /home/path_to_home_dir/.ssh/private_key user_login@mydomain.com -p 22
Restart=always

[Install]
WantedBy=multi-user.target

После этого выполняем systemctl daemon-reload и systemctl enable --now autossh, проверяем логи в /var/log/autossh, и радуемся, что нам больше не страшны ребуты.

3.3.5 Нет пределов совершенству

Если вы думаете, что на этом всё - совсем нет! По хорошему, стоит так же защитить ваш сайт при помощи SSL - например, через Lets Encrypt, а если он приватный (например, управление умным домом) - то закрыть снаружи дополнительной авторизацией вроде Authentik.

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

В итоге у вас может получиться какой-то такой конфиг внешнего nginx:


upstream tunnel {
       server 127.0.0.1:9000;
}

server {
    server_name subdomain.mydomain.com;
    access_log /var/log/nginx/tun-access.log main;
    error_log /var/log/nginx/tun-error.log;
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/subdomain.mydomain.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/subdomain.mydomain.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot


location / {
    proxy_pass http://tunnel;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "Upgrade";
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Real-IP $remote_addr;
    ##############################
    # authentik-specific config
    ##############################
    auth_request     /outpost.goauthentik.io/auth/nginx;
    error_page       401 = @goauthentik_proxy_signin;
    auth_request_set $auth_cookie $upstream_http_set_cookie;
    add_header       Set-Cookie $auth_cookie;

    # translate headers from the outposts back to the actual upstream
    auth_request_set $authentik_username $upstream_http_x_authentik_username;
    auth_request_set $authentik_groups $upstream_http_x_authentik_groups;
    auth_request_set $authentik_email $upstream_http_x_authentik_email;
    auth_request_set $authentik_name $upstream_http_x_authentik_name;
    auth_request_set $authentik_uid $upstream_http_x_authentik_uid;

    proxy_set_header X-authentik-username $authentik_username;
    proxy_set_header X-authentik-groups $authentik_groups;
    proxy_set_header X-authentik-email $authentik_email;
    proxy_set_header X-authentik-name $authentik_name;
    proxy_set_header X-authentik-uid $authentik_uid;
    
}
# all requests to /outpost.goauthentik.io must be accessible without authentication
location /outpost.goauthentik.io {
    proxy_pass              https://127.0.0.1:7443/outpost.goauthentik.io;
    # ensure the host of this vserver matches your external URL you've configured
    # in authentik
    proxy_set_header        Host $host;
    proxy_set_header        X-Original-URL $scheme://$http_host$request_uri;
    add_header              Set-Cookie $auth_cookie;
    auth_request_set        $auth_cookie $upstream_http_set_cookie;
    proxy_pass_request_body off;
    proxy_set_header        Content-Length "";
}

# Special location for when the /auth endpoint returns a 401,
# redirect to the /start URL which initiates SSO
location @goauthentik_proxy_signin {
    internal;
    add_header Set-Cookie $auth_cookie;
    return 302 /outpost.goauthentik.io/start?rd=$request_uri;
    # For domain level, use the below error_page to redirect to your authentik server with the full redirect path
    # return 302 https://authentik.company/outpost.goauthentik.io/start?rd=$scheme://$http_host$request_uri;
}

Вот теперь вы действительно великолепны.

3.3.6 Плюсы и минусы решения с туннелем

Плюсы:

  • Вы сегодня много узнали

  • Вам не страшна замена роутера или падение внешнего сервиса

  • Никто не ограничит вас по скорости

  • Никто не слушает ваш трафик, но это не точно

  • Вы можете прокидывать любые заголовки, как только пожелаете

  • Вы можете поселиться на острове, запитывать сервер от бешеных белок, получать интернет через сотовую связь и спутник - и туннель продолжит работать, у него нет никакой привязки.

Минусы:

  • Вы сегодня много узнали

  • Первичная настройка занимает некоторое время

  • Придётся платить за облачный сервер и домен

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

Наверняка я описал не все варианты и способы, докидывайте в комментариях. Напоследок - несколько ссылок, которые мне помогли разобраться:

Ссылочки

SSH туннели

Обсуждения

Апдейт по мотивам комментариев

  1. Можно ещё воспользоваться специализированными сервисами для конкретно вашего кейса - например, для Home Assistant есть Dataplicity и Nabu Casa

  2. Вместо SSH туннеля можно использовать VPN к внешнему серверу и опять же прокидывать порты через Nginx. На первый взгляд кажется, что равнозначное ssh решение, в том числе по трудоёмкости.

  3. А можно использовать VPN и не прокидывать его наружу через nginx. Тогда ваш сервис будет доступен снаружи откуда угодно - но только через VPN соединение. Что в некоторых случаях имеет смысл.

  4. Говорят, что ещё одна альтернатива SSH и VPN - это zerotier. Не слышал про этого зверя, но кажется про него есть на хабре хорошая статья.

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


  1. belokobylskiy
    09.01.2024 18:02
    +2

    Для задачи "выставить HA в интернет" отлично подходит компонент Dataplicity от @AlexxIT https://github.com/AlexxIT/Dataplicity

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


    1. jehy Автор
      09.01.2024 18:02

      Ну вот Dataplicity и Nabu Casa подходят для Home Assistant, но хочется же ещё кучу всего выставить :)


  1. aborouhin
    09.01.2024 18:02
    +4

    Зачем Вам два nginx'а-то? Что мешает прокинуть на удалённый сервер непосредственно тот порт, который слушает локальное приложение?

    Ну и VPN протоколов есть много хороших и разных, SSH для постоянного использования не лучший выбор. Тут последнее время про VPN разной стойкости к блокировкам статей достаточно :)


    1. jehy Автор
      09.01.2024 18:02

      Как написал в статье - два nginx для того, чтобы использовать один туннель на несколько приложений, которые слушают разные порты. Если этого не надо - да, можно вообще без nginx обойтись.


      1. aborouhin
        09.01.2024 18:02
        +2

        IMHO, проще или сделать по туннелю на каждый порт, или всё-таки перейти с SSH на полноценный VPN. К слову, если приложения не для широкой публики, а для личного/корпоративного использования, то доступ к ним лучше бы тоже через VPN открывать, а не по белому IP. И в простом сценарии это может быть один и тот же VPN, два зайца одним выстрелом (и можно обойтись без проброса портов, да и без nginx, если последний не нужен ради SSL).


        1. jehy Автор
          09.01.2024 18:02

          если приложения не для широкой публики, а для личного/корпоративного использования, то доступ к ним лучше бы тоже через VPN открывать

          Здесь я про всякий self hosted, и тут есть нюанс в том, что у него бывают интеграции с внешними облачными сервисами, например, УДЯ с прямым подключением (https://docs.yaha-cloud.ru/v0.6.x/install/integration/). Поэтому за VPN не спрячешь.

          или всё-таки перейти с SSH на полноценный VPN

          Уже добавил к статье, что можно для прокидывания наружу использовать VPN вместо SSH, но кажется прям равнозначным решением. И там и там постоянное шифрованное соединение, просто протоколы разные.

          IMHO, проще или сделать по туннелю на каждый порт

          Запутаться легко... Да и лично мне удобно, когда у меня нгинкс отдельно по каждому приложению логи доступа и ошибок пишет. Да и в целом единая точка входа это хорошо. Ну и без nginx на внешнем сервере не получится Authentik подрубить.


          1. aborouhin
            09.01.2024 18:02

            Здесь я про всякий self hosted, и тут есть нюанс в том, что у него бывают интеграции с внешними облачными сервисами, например, УДЯ с прямым подключением (https://docs.yaha-cloud.ru/v0.6.x/install/integration/). Поэтому за VPN не спрячешь.

            Я бы в этой ситуации открыл в фаерволе доступ к 443 порту снаружи только для IP того самого облачного сервиса, а сам бы к вебморде ходил всё же через VPN. Хотя, возможно, я параноик :)


            1. jehy Автор
              09.01.2024 18:02

              IP у облачного сервиса часто случайный, к сожалению.
              Но я тоже паранок, поэтому у меня весь веб, в том числе имеющий свою авторизацию, дополнительно закрыт за authentik reverse proxy - с нужными исключениями на конкретные адреса.


      1. Kononvaler
        09.01.2024 18:02

        У вас два линукса по обеим сторонам, есть socat


        1. jehy Автор
          09.01.2024 18:02

          Спасибо, не знал. А чем он лучше ssh? Синтаксически выглядит почти так же. Под капотом что-то лучшее происходит?


          1. Kononvaler
            09.01.2024 18:02

            Через socat Вы просто перенаправите порт, без второго энжиникс и туннеля на ssh
            Вообще у кинетик есть поддержка wireguard, легко настраивается и отлично работает. На внешнем VDS сервере ставите так-же WG , соединяете с вашим кинетиком и потом легко и непринужденно в роутере пробрасываете нужные порты к определенным устройствам в локальной сети.
            Ну и хотелось бы предостеречь от всяких динднс, установите fail2ban, активируйте динднс и поразитесь в логах количеству сразу появившихся куче ботов, пытающихся подобрать пароль к вашему серверу.


            1. jehy Автор
              09.01.2024 18:02

              Так вроде выглядит как те же яйца, вид сбоку.
              Чем socat лучше SSH для прокидывания тоннеля?
              А nginx там для случая дифференциации сайтов по домену и внешнего ssl.


            1. mayorovp
              09.01.2024 18:02

              Последнее время боты лезут и без всяких динамических днс. Мне кажется, они открыли для себя технологию Certificate Transparency и узнают про домены в момент выпуска сертификата для этого домена.


              1. jehy Автор
                09.01.2024 18:02

                Думаю, здесь @Kononvaler имеет в виду, что боты полезут сразу по всем доступным портам.
                В том время как при использовании VPN туннеля ты можешь выставить один конкретный, в котором ты уверен.


                1. mayorovp
                  09.01.2024 18:02

                  Странный вывод. Во-первых, dns - это просто назначение имён IP-адресам, от использования его динамической разновидности новый IP-адрес не появится и лишние порты на нём никак не откроются.

                  Во-вторых, от использования туннеля общее количество открытых портов не уменьшается, а увеличивается на 1.


                  1. jehy Автор
                    09.01.2024 18:02

                    Опять же не уверен, что я толкую корректно за автора комментария, но полагаю, что боты веселее лезут на те айпишники, к которым привязаны доменные имена. Конкретно у меня в практике был случай, когда хакеры сканировали поддомены и при появлении новых сразу туда набегали. Так-то понятно, что айпишники уже есть в интернете, привязаны там домены или нет. И security via obscurity - так себе подход для обеспечения безопасности :)

                    Насчёт количества открытых портов - я бы сказал, что нормально через dynamic dns выкидывать в интернет роутер и на нём открывать конкретный порт и прокидывать его на локальную тачку. В роутере по умолчанию всё лишнее закрыто. А вот выкидывать в сеть целиком какой-то домашний сервер - стрёмно, там может быть не настроенный фаервол или какие-то сервисы, о которых вы не подумали - всякие там СУБД, веб морды и прочее.


  1. markoni
    09.01.2024 18:02
    +3

    просто не так тривиально понять, какой именно запрос нужно задать в гугл

    Совсем не тривиально, 4 слова все-таки - "homeassistant nginx reverse proxy" :)


    1. jehy Автор
      09.01.2024 18:02

      Если вы про эту статью - там описано, как поставить Home Assistant за nginx. Но это не приведёт волшебным образом к появлению доступа через интернет :)
      Если про другую ссылку - закиньте сюда, пожалуйста.


  1. select26
    09.01.2024 18:02
    +16

    А вы были так близки: у Cloudflair есть такая штука zerotrust. Просто запускаешь один бинарник на хосте (x86 или ARM) и автоматом становится доступным хост через прокси Cloudflair. Со всеми из защитам, бесплатной авторизацией (SIC!) и т.п. Неважно белый IP или нет. Двойной NAT или тройной. Дешево (даром с рядом ограничений), надежно и доступно.
    Я лучше решения не знаю.


    1. jehy Автор
      09.01.2024 18:02

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


    1. cry_san
      09.01.2024 18:02

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

      Спасибо!


    1. enamchuk
      09.01.2024 18:02
      +1

      Cloudflare’s Zero Trust даже в бесплатной версии требует указать номер действительной банковской карты и карты банков РФ на данный момент не принимаются.


  1. mayorovp
    09.01.2024 18:02

    По умолчанию не прокидывается заголовок хоста. Поэтому я все эти годы мучался и вешал сервисы на разные порты. Прямо перед написанием статьи я всё же смог нагуглить решение и прокинуть заголовок - но это прям неочевидно.

    Вам же прямо там дали правильное решение - не использовать http proxy на стороне роутера, а пробросить порт. Порт пробрасывать не обязательно на конкретный сайт, его можно пробросить и на промежуточный сервер, который правильно всё разрулит.

    Да вы сами дальше по тексту предлагаете использовать nginx для этих целей, только в паре с ssh туннелем. Но ssh туннель тут не обязателен, этот вариант универсален и применим для любого из пунктов - 1, 2, 3.1, 3.2, 3.3

    Однако, лично я рекомендую traefik, его конечно не очень просто ставить, зато уже поставленный настраивается он довольно просто; и главное у него из коробки есть всё что нужно для работы в режиме входного прокси http-запросов - не будет никаких проблем ни с веб-сокетами, ни с http2, ни с http3, и даже tls сертификаты от lets encrypt он вам сам соорудит.


    1. jehy Автор
      09.01.2024 18:02

      Порт пробрасывать не обязательно на конкретный сайт, его можно пробросить и на промежуточный сервер, который правильно всё разрулит.

      Непонятно, как промежуточный сервер это разрулит, если ему не пришёл хост. Чисто по портам? Держать один набор портов для конечных приложений, второй для домашнего сервера как входящие, и третий на удалённом сервере как исходящие? Это прям гарантированно запутаться можно. Гораздо проще оперировать именами хостов. Точно такие же метаданные, но легко интерпритируемые. А проблема не прокидываемого хоста на кинетике, как оказалось, решается.

      Но ssh туннель тут не обязателен

      И каким образом на одном голом nginx запрос уйдёт в домашний сервер за серым айпи?

      Однако, лично я рекомендую traefik

      Да, вроде хорошая штука. Но пока не щупал, привык за последние лет 15 к nginx, да и проблем с веб сокетами и http2 у него давно нет. А сертификаты легко certbot закидывает.


      1. mayorovp
        09.01.2024 18:02
        +1

        Непонятно, как промежуточный сервер это разрулит, если ему не пришёл хост.

        Непонятно, что помешает прийти имени хоста в заголовке при использовании проброса порта.

        А проблема не прокидываемого хоста на кинетике, как оказалось, решается.

        Зато проблема с Origin как оказалось, средствами кинетика не решается (согласно вашим же словам). Предложенный же способ решает проблемы с любыми заголовками.

        И каким образом на одном голом nginx запрос уйдёт в домашний сервер за серым айпи?

        Я же написал - см. ваши же пункты 1, 2, 3.1 и 3.2

        да и проблем с веб сокетами и http2 у него давно нет.

        Год назад мне оказалось проще поставить traefik, чем разбираться как оно правильно пробрасывается в nginx (притом, что изначально я немного знал nginx и совсем не знал traefik).

        Ну и немного цифр: новый сайт в nginx настраивается 18 строками конфига, новый же сайт в traefik настраивается в 5 строк.


        1. jehy Автор
          09.01.2024 18:02

          Я же написал - см. ваши же пункты 1, 2, 3.1 и 3.2

          Ну так при этих пунктах и nginx не нужен :) Если внимательно прочитаете - ssh туннель у меня только для того случая, когда у нас нет белого айпи и мы не хотим использовать внешние сервисы.

          Зато проблема с Origin как оказалось, средствами кинетика не решается (согласно вашим же словам). Предложенный же способ решает проблемы с любыми заголовками.

          Предложенный способ, то есть - проброс порта? Я пока так и не понял, как вы предлагаете это сделать не средствами роутера, без ssh, белого айпи и сторонних сервисов.


          1. mayorovp
            09.01.2024 18:02
            -2

            Ну так при этих пунктах и nginx не нужен :)

            Нужен, и нужен он ровно для тех же целей, что и в пункте 3.3 - чтобы держать несколько сайтов на одном (внешнем) ip адресе и порту.

            Я пока так и не понял, как вы предлагаете это сделать не средствами роутера, без ssh, белого айпи и сторонних сервисов.

            Извините, но вы идиот или как? Я вам уже два раза писал, что предложенное решение работает совместно с вашими же пунктами 1, 2, 3.1 и 3.2, а вовсе не вместо них.


  1. ddruganov
    09.01.2024 18:02

    Спасибо большое, как раз скоро понадобится)


  1. SlavikF
    09.01.2024 18:02
    +2

    Я пользовался rinetd вместо nginx:

    https://github.com/samhocevar/rinetd

    Плюс в том, что он работает на более низком уровне - что-то типа L2, и прокидывает данные, как есть. Nginx как-то слишком уж много вмешивается в заголовки, буфферизирует и т.д...

    И да, вместо SSH лучше бы VPN.


    1. jehy Автор
      09.01.2024 18:02

      Я пользовался rinetd вместо nginx

      Не знаю его, но на первый взгляд кажется, что это аналог туннеля, то есть, потенциально может заменить ssh туннель, но не nginx. Nginx у меня используется для раскидывания запросов по сервисам на основании домена, и, если это не нужно - он тоже не нужен.

      И да, вместо SSH лучше бы VPN.

      Так, вы второй человек, который говорит, что лучше VPN. А чем с вашей точки зрения? Мне просто кажется, что равнозначные решения в данном контексте. И там и там подключение по ассиметричномному ключу, постоянный коннект, шифрование трафика...


      1. askharitonov
        09.01.2024 18:02

        Так, вы второй человек, который говорит, что лучше VPN. А чем с вашей точки зрения?

        В случае использования OpenVPN не нужно создавать свой сервис, запускающий соединение по ssh. Хотя в принципе нельзя сказать, что инструкция становится проще, потому что настройка OpenVPN может требовать несколько больших усилий. Но всё же OpenVPN - это типовое решение, и общее решение вида "соединяемся с сервером по OpenVPN, пробрасываем порты 80 и 443 сервера на IP-адрес локального сервера внутри VPN" запоминается проще.


    1. jehy Автор
      09.01.2024 18:02

      UPD. Посидел подумал, чем VPN может быть лучше.
      С одной стороны, в нём появляется смысл, если появляется третий узел, который нужно связать.
      С другой стороны, для self hosted такое событие маловероятно, но хочется, чтобы сервера не имели доступа к произвольным портам друг друга, а только к тому\тем, по которым внешний трафик гоняют. Кажется, SSH тут лучше подходит.


      1. Barnaby
        09.01.2024 18:02
        +1

        Не нужно второй nginx городить, у ssh низкая производительность (сильно проц грузит), к VPN удобно цепляться, чтобы получить доступ ко всей локалке. Ну и VPN нам так и так нужен :)


        1. jehy Автор
          09.01.2024 18:02

          Вообще кажется, что ssh как раз быстрее, чем vpn. А в локалку я бы с внешнего сервера наоборот не пускал. Но тут нам не о чём спорить, у всех юз кейсы разные :)


      1. SlavikF
        09.01.2024 18:02
        +1

        Для прокидывания трафика SSH работает значительно медленнее VPN, потому что SSH работает по TCP и внутри него идёт TCP трафик. Получается TCP-over-TCP, что значительно медленнее чем просто TCP. Ещё это называют TCP metldown.

        Именно поэтому VPN чаще используют UDP.

        https://openvpn.net/faq/what-is-tcp-meltdown/

        rinetd вместо ssh использоваться не может, потому что он не достанет компьютер за NAT. Даже не знаю, если можно запустить rinetd на компьютере за NAT, и прокинуть его на VPS, - вроде бы так невозможно с rinetd...


        1. jehy Автор
          09.01.2024 18:02
          +2

          Ну вот по ссылке выше и тут пишут наоборот - что SSH не затрагивает содержимое TCP, тупо перекидывания его, и TCP-over-TCP не получается. Конечно, SA и его соседи - не самые надёжные источники, но никто не опровергает, да и на диаграмме IBM кажется нет двойной упаковки.

          Но вообще кажется, что это не принципиальный вопрос, поскольку мы сейчас рассматриваем применение для домашних серверов. А для большой серьёзной среды с кучей серверов ясно что вариант через SSH не катит :)


        1. dsoastro
          09.01.2024 18:02
          +4

          Здесь нет tcp over tcp. SSH читает из сокета на одном сервере, передает данные по основному соединению, и пишет в сокет на другом сервере. Чтобы делать tcp over tcp нужно создавать интерфейс типа tun (как vpn делает) и в него маршрутизировать трафик. ssh -R никаких интерфейсов не создает


        1. Antra
          09.01.2024 18:02
          +1

          UDP часто используют еще по не совсем очевидной причине.

          Представьте, что пришел пакет на сервер А, ssh по TCP его послал, но пакет потерялся. В это время пришел пакет на сервер B. Так вот он будет ждать пока через стандартные механизмы организуется retransmit для потерянного пакета, предназначавшегося для A...

          В случае же UDP потери пакетов и прочее отрабатывается на уровне приложений. Разные сессии друг друга не тормозят. И чем больше одновременных сессий, тем актуальнее это становится.


  1. INSTE
    09.01.2024 18:02
    +3

    >> А вот Referer и Origin прокинуть так и не удаётся.

    Думаю, с этим можно помочь. Просто запросов не было раньше, а на форуме тему упустил видимо. Напишите-ка в официальную поддержку, указав что от меня.

    PS: Глянул по истории: сброс referer обязателен для проксирования некоторых веб-морд от хуавейных модемов, иначе они не авторизуют; а сброс origin был сделан для работы websocket. Итого думаю можно сделать команды для отключения этих сбросов, так как они по сути в вашей ситуации не важны.


    1. jehy Автор
      09.01.2024 18:02

      Спасибо! Если что, кинетик - до сих пор лучшее, что со мной случалось в мире роутеров :)
      Заявка в поддержку - https://support.keenetic.com/hc/requests/11600


      1. NihilPersonalis
        09.01.2024 18:02
        +1

        Лучшее, что случалось в мире роутеров это mikrotik. После этого нафиг не сдался ни keenetic, ни что либо подобное.


      1. jehy Автор
        09.01.2024 18:02

        Галя, у нас отмена. Нужно было писать в русскую поддержку, а не европейскую. Корректный тикет - 170730194


  1. buldo
    09.01.2024 18:02
    +1

    А не страшно HA выставлять в паблик?

    Мой внутренний параноик решил, что vpn до домашней сети как-то не так страшно.


    1. Barnaby
      09.01.2024 18:02

      А VPN нестрашно? Можно 2FA подключить.


      1. buldo
        09.01.2024 18:02

        VPN менее страшно. Поверхность для взлома меньше. Плюс vpn сложнее перебирать - подключение по ключу


    1. jehy Автор
      09.01.2024 18:02

      спрятав за внешнюю авторизационную проксю Authentik - не страшно. Вряд ли ломанут разом обе авторизации.

      Но если бы у меня там была какая-то потенциально опасная автоматика вроде котлов и замков - я бы не стал выставлять. Сделал бы второй инстанс для таких вещей. А лучше - отдельный микроконтроллер :)


      1. buldo
        09.01.2024 18:02

        Мне бы какой-нибудь WAF...


        1. jehy Автор
          09.01.2024 18:02

          Почему нет? ModSecurity был, есть и будет. Или можно посмотреть, например, что такое nemesida waf. Вдруг работает...


          1. buldo
            09.01.2024 18:02

            Я знаю, что они есть. Но как подумаю о настройке, сразу вломы становится


            1. jehy Автор
              09.01.2024 18:02

              Ну, простейший вариант - докер контейнер с нгинкс прокси с mod security. Ставится за минуты.

              Но если серьёзно, то надо думать про модель угроз. В моём случае, самое страшное, что может сделать хакер - открыть ворота. Ну, я знаю, что у них и так есть уязвимость. А ещё что можно перелезть забор и открыть их при помощи отвертки. Так что не очень страшно.

              Страшнее для меня что геккона в террариуме можно и поджарить при помощи умного дома. Поэтому у него отдельный микроконтроллер, который в сеть выдаёт только статистику.


    1. markoni
      09.01.2024 18:02

      Я болтаюсь по разным странам, как та субстанция в проруби, vpn-ов в телефоне - как собак нерезаных, а весточку от дома возле Минска хочется получать всегда. Поэтому выставлен через прокси наружу, и.... - никому за 5 лет не был нужен, кроме меня :)


  1. Barnaby
    09.01.2024 18:02

    Del.


  1. spiritedflow
    09.01.2024 18:02
    +2

    Для home assistant, приватной файлопомойки и всего подобного все же лучше поднять VPN сервер, и организовать постоянное подключение своих телефонов и ноутбуков к этому VPN. Рано или поздно захочется поставить всякие клиенты на телефон, вроде автоматической синхронизации снятых фотографии в файлопомойку или homeassistant клиент, который будет звонить когда кто-то звонит в вашу дверь, и все эти промежуточные nginx-ы с промежуточными аутентификациями будут только мешать. Да даже файлопомойка может быть и не нужна будет, вы сможете закинуть файлы по SMB прямо на свой комп.

    Для сайтов, которые должны быть доступны неограниченному кругу лиц (визитка, общедоступная файлопомойка и прочее) нужна DMZ и выделенная железка/виртуалка в этой DMZ с которой не будет доступа в локалку. К сожалению, многие думают "да кому я нужен", не понимая, как сейчас действуют хакеры. У тех сейчас просто тонна средств автоматизации, которые не пропустят никого. Там скрипт через поисковики вроде шодана найдет все уязвимые сайты с уязвимой версией софта, включая ваш, а потом бот заражения автоматически разберется со всеми вашими локальными компами в режиме "домашняя сеть", серверами с http протоколом (я же дома, от кого шифроваться?) и абсолютно незащищенными IoT устройствами, которые не обновляются ... никогда? И всё, вся ваша локалка в ботнете, включая холодильник, а файлопомойка забита троянами и шифровальщиками.


    1. jehy Автор
      09.01.2024 18:02

      Спасибо, вы первый, кто таки расписал, почему VPN может подойти лучше.

      Подозреваю, у меня,как у веб разработчика, немного профдеформация - мне хочется всё что есть - выставить в виде веба. Даже веб морда для определения состояния HDD есть.

      В общем, не отрицаю ваш вариант с впн, но напишу, как у меня решаются описанные вами задачи:

      вроде автоматической синхронизации снятых фотографии в файлопомойку

      Фотографии у меня уходят в гугловое облако, а для прочих файликов есть яндекс диск, который есть на телефонах, компах и на сервере в виде демона. Помимо задачи собственно синхронизации файлов он ещё даёт дополнительную точку резервирования. Хотя ясно, что этого не достаточно, так что помимо этого меня есть холодные бекапы на диске, который не подключен к сети и лежит в шкафу.

      или homeassistant клиент, который будет звонить когда кто-то звонит в вашу дверь

      Для этого у меня используются нотификации в телеграмм и звонки на телефон, тут впн не обязателен, всё спокойно изнутри решается.

      Там скрипт через поисковики вроде шодана найдет все уязвимые сайты с уязвимой версией софта

      Поисковик найдёт сайты и упрётся там в Authentik, который я несколько раз упомянул. Если там вдруг найдётся zero day, то после этого нужно будет найти ещё zero day внутри авторизации сервиса под ним. А после этого нужно будет выйти как-то в хост из непривилегированного докер контейнера, поскольку все сервисы крутятся в отдельных контейнерах. Если взломан внешний сервер, а не прокинутый локальный, то после этого надо повторить приседания с локальным и обеспечить себе интерфейс для работы внутрь сети, в том время как у тебя есть только порт, который на nginx уходит... Риск этого довольно мал.

      А к слову насчёт всякого ioT - он у меня потихоньку на Zigbee уползает. Здесь прям нетривиально что-то сделать, максимум можно попытаться перепрошить ESP микроконтроллеры, на которых кастомный ioT крутится.. Но для этого надо взломать контейнер, в котором лежат ключи доступа к устройствам и в целом разбираться в этом. Автоматика не осилит, а если осилит человек - я по этому потом продаваемый остросюжетный детектив в стиле киберпанк написать смогу :)

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


  1. haga777
    09.01.2024 18:02

    Товарищи, как бы вы соединили всё сети, у которых нет белого адреса? Я предполагаю, что можно сделать ( я так и сделал) с обоих сторон прошитые роутеры на опенврт и установлен zerotier. Настроено site to site подключение и в принципе всё нормально, но иногда на одной из сторон туннель зависает. У меня так частенько на микротик рб5009 случается, что интерфейс вкл и запущено соединение, но оно в подвешенном состоянии. Либо перезагрузка микротика, либо передернуть интерфейс нужно.

    Сейчас мне бы разобраться, как без таких вот ухищрений спокойно соединить две сети на опенврт, например, при наличии ВПС с белым адресом?

    Ещё есть ли возможность поставить cloudflare туннель на опенврт?


    1. DaemonGloom
      09.01.2024 18:02
      +1

      Если есть VPS - туда ставится дистрибутив по вашему выбору (хоть тот же openwrt) и на нём поднимается VPN сервер, а все остальные к нему подключаются как клиенты. Главное - разрешить маршрутизацию из VPN в локальную сеть на роутерах (если адреса разные). С одинаковыми адресами (типа 192.168.1.x в каждой сети) нужно будет ещё дополнительно настраивать NAT поверх для преобразования адресов.


      1. haga777
        09.01.2024 18:02

        Извини, не мог бы подробнее как сам это видишь? ВПС есть арендовал за 80руб в России, с очень низким пингом, 50мбит

        Знаю, что есть разные готовые сервисы, тот же zerotier.

        Мне очень зашёл tailsckale, но он заблокирован для России, верхнее его можно легко поставить на смартфон. На убунту или винду можно установить только полный инсталлятор, а не веб установщик. Тогда ставиться и работает отлично. Но по инструкции с опенврт не получается, так как он скачивается во время выполнения установки и не может, так как заблокирован для России)

        Пока, предполагаю, поставить ros chr на ВПС и подключать клиентов по вг.


        1. DaemonGloom
          09.01.2024 18:02
          +2

          Если у вас уже есть VPS - поднимаете там любой классический VPN сервер (L2TP, SSTP, IPSEC/IKEv2, WG, да хоть openvpn) и подключаете клиентов через него. Можно и через RouterOS, так тоже вполне будет работать. Документация у них неплохая.


        1. Aelliari
          09.01.2024 18:02

          Кроме ZeroTier и tailscale есть различие аналогии, не все из них имеют собственный публичный координирующий сервер (но все позволяют развернуть свой на vps). Например netbird, netmaker


  1. APh
    09.01.2024 18:02

    Первые вводные абзацы с ошибками в грамматике не единичными отбивают желание вчитываться в тело, хотя тема интересна.

    Ну, почему нельзя в бесплатном инструменте проверить грамматику перед публикацией, если сам не из того теста?

    Какой бог заставляет вас делать это и становиться в ряд с прочими "запупыркиными" --- блогерами-миллионниками?


    1. jehy Автор
      09.01.2024 18:02

      Хмм. Удивился, пошёл проверил через гугл доки. На первых пять абзацов есть одна опечатка, на весь остальной текст ещё три. Опечатки, а не грамматические ошибки. Если такая частота опечаток отбивает у вас желание читать - не представляю, как вы в интернет заходите :) Но поправил.


  1. Timertatar
    09.01.2024 18:02
    +2

    У меня vds за 100 руб/мес с белым ip. Настроил там wireguard и реверспрокси. И все сервера домашние и рабочие туда подключены. А там уже что захочешь, можно и пробросить порты в iptables, либо реверспрокси на апаче. У меня начальный уровень в линукс, все настроил используя гугл/яру. Метод пробы и ошибок всегда дает результаты. Из сервисов: два нексклоуда (рабочий и личный), вебсервер с тремя сайтами, домашний НА, backup server и несколько всяких серверов на линукс для экспериментов и обучении. Все хосты на proxmox и находяться на разных местах (на работе, дома,на даче). Интернет главное был, вне зависимости какой, белый или серый, безразница. Нет привязки к месности, роутеру. Да и виртуальные сервера можно перемещать по хостам за пару кликов.


    1. jehy Автор
      09.01.2024 18:02

      То есть, тоже VPN используете. А веб у вас наружу торчит, или всё за VPN закрыто?


      1. Timertatar
        09.01.2024 18:02
        +2

        Конечно. Сайты наружу торчат. Да и НА тоже. А сами хосты proxmox нет. Для обслуживание я на ноуте впн соединяю и все под рукой оказываеться.


  1. blib
    09.01.2024 18:02

    есть еще простой способ ngrok
    без плясок с бубнами, просто, и кондово...

    ngrok config add-authtoken <TOKEN>
    ngrok http http://localhost:8080


    1. jehy Автор
      09.01.2024 18:02

      Да, этот вариант у меня упомянут.


  1. Roffild
    09.01.2024 18:02

    SSH vs VPN: тут интересная ситуация с портами.

    В случае SSH пробрасывается конкретный порт. В firewall можно на процесс sshd разрешить все порты, чтобы через конфиг SSH контролировать.

    Для VPN нужно отключить gateway, если не хотим трафик Ютуба для клиента гнать через свой сервер. Порты можно контролировать только через firewall.

    Выбор из количества необходимых портов, блокировки (урезания скорости) для протокола на уровне провайдера и т.д.


  1. treppilk
    09.01.2024 18:02

    Пользуюсь https://expose.dev/, как альтернативой ngrok. Для разработки телеграм ботов очень облегчает жизнь


  1. HSerg
    09.01.2024 18:02

    Если есть свой vds, то самый простой способ - FRP, https://github.com/fatedier/frp.


  1. Art_VN
    09.01.2024 18:02

    ipv6 туннель от tunnelbroker:
    +: не нужно облако, бесплатно, /64 подсеть, free DNS ...
    -: не вижу
    поправьте меня, если ошибаюсь


    1. slonopotamus
      09.01.2024 18:02

      Для этого нужен белый IPv4-адрес, хотя бы один. Про "не нужно облако" вы читерите, потому что облаком выступает собсна tunnelbroker. Ещё из минусов проблемы с тем что не вся IoT готова к IPv6. Например, Micropython в него не умеет.


      1. Aelliari
        09.01.2024 18:02
        +2

        Я ещё больше считерю, route64 имеет опцию в виде wireguard и для этого туннельного брокера не нужен «белый» ipv4


        1. slonopotamus
          09.01.2024 18:02

          Ух ты. Не знал про route64, спасибо. Ну и как вам плюс в карму поставить, не влезает больше. Так-то я всяко за IPv6.


      1. Art_VN
        09.01.2024 18:02

        Как уже было сказано на текущий момент брокеров много, предлагающие различные способы приобщения к ipv6. А если уж есть белый статический ipv4 то пощупать ipv6 можно вообще без брокеров, через ретрансляторы 6to4
        upd: нашел статью, прочитав которую узнал про такие фишки (оказывается, ей более 10 лет). И вот выдержка из нее про 6to4
        "Звучит довольно просто, использовать подход еще проще. Ты поднимаешь 6to4-интерфейс и настраиваешь адрес в формате «2002:xxyy:zztt», где «xx.yy.zz.tt» — это IPv4-адрес, записанный в шестнадцатеричном виде, а маршрутизацию настраиваешь так, чтобы все исходящие пакеты «уходили» на 192.88.99.1. Вот и вся настройка. Плюс 6to4 в том, что связь между двумя пользователями 6to4 осуществляется не через туннельный сервер, а напрямую, с нулевой дополнительной задержкой, при этом самый близкий шлюз выбирается автоматически."


    1. jehy Автор
      09.01.2024 18:02

      Видимо, вы по диагонали читали. Да, есть много разных сервисов, через сервера которых можно себе туннель наружу пробить, я перечислил часть, но их очень много. У них есть минусы, которые тоже упомянуты, но в большинстве случае совершенно не критичны.


  1. merced2001
    09.01.2024 18:02

    Для второго случая (белый динамический айпи) и роутеров Асус можно обойтись и без сторонних сервисов. Скрипты, которые сами обновляют DNS записи у регистратора, можно найти тут


  1. LuigiVampa
    09.01.2024 18:02
    +1

    Спасибо за интересную статью! Как сторонник селфхостинга ресурсов под свои нужды - горячо одобряю, особенно с учётом подорожания стоимости аренды серверов.

    В комментариях уже многие высказались за использование VPNа на VPS сервере с белым адресом вместо ssh-туннеля, и я, пожалуй, тоже присоединюсь к этому. Я достаточно много пользовался ssh-туннелями, и пользуюсь ими до сих пор для доступа к каким-то приватным ресурсам, веб-мордам админок и т.д. - всего того что не должно торчать в сеть ни при каких обстоятельствах, но с ssh-туннелями также имел крайне негативный опыт с обрывами соединения и их стабильностью. Самый неприятный момент в том, что соединение может оборваться, а вот процесс ssh отвечающий за поддержание туннеля не завершится, и приходится самостоятельно руками его прибивать и стартовать новый. Да, autossh вроде как решает проблему, но сам по себе является костылём, использования которого хотелось бы избежать.

    Небольшой оффтоп. У меня получилось достичь приемлемой, почти полностью беспроблемной стабильности ssh-туннелей с помощью добавления TCP-keepalive. Это генерирует небольшой постоянный трафик, но в нынешние времена это не должно быть проблемой. Для включения keepalive необходимо в конфигурацию подключения на стороне клиента, которая описывается в файле ~/.ssh/config внести соответствующие параметры. У меня типичная конфигурация подключения выглядит примерно так:

    Host SSH_ALIAS
    HostName 123.45.67.89
    User user
    Port 12345
    IdentityFile ~/.ssh/id_ed25519_key_for_certain_server
    IdentitiesOnly yes
    TCPKeepAlive yes
    ServerAliveInterval 15
    ServerAliveCountMax 4
    StrictHostKeyChecking yes

    Также обязательно на стороне сервера в конфигурацию openssh в файле /etc/ssh/sshd_config добавить:

    TCPKeepAlive yes

    Не уверен что это будет работать с минималистичными реализациями вроде dropbear, но на полноценных компьютерах почти все пользуются openssh, так что думаю что проблем не возникнет.

    Выскажу свои аргументы за схему с VPN на VPSке вместо туннелей:

    • Хорошо настроенный wireguard, с правильно выставленными значениями MTU на стороне клиента и сервера позволяет прокачивать трафик от VPS почти без потери скорости и всё буквально ограничится пропускной способностью вашего домашнего интернета. В своё время я экспериментировал с синхронизацией большого количества данных через rsync over ssh, и там у меня скорость резалась очень серьёзно. С wireguard таких проблем вообще не встретил. Допускаю что это мои руки не из плеч.

    • Если не обязательно использовать 80 и 443 порты, то можно полностью избежать использования nginx, и, соответственно, лишнего расхода ресурсов совсем сделав на стороне VPS порт форвардинг прямо на iptables. Трафик будет заворачиваться получателю в нужный tun-интерфейс напрямую правилами фаервола. Обрывы не страшны, т.к. даже если клиент отвалился, он переподключится, на VPS ничего специально делать не нужно, следить за восстановлением маршрутов тоже. Если у вас только один сервер за VPS и нет необходимости ничего крутить на ней самой, то можно и 80 и 443 порты полностью завернуть на ваш домашний сервер, и уже на нём, на стороне nginx, раскидывать подключения через mod_stream, ssl_preload по виртуалкам или контейнерам. Таким образом у вас будут и все ваши ресурсы, хоть их будет несколько десятков, на официальном 443 порту, и на все можно получить бесплатные сертификаты от letsencrypt или zerossl. При этом нагрузка на VPS и её ответственность будут абсолютно минимальны: прокидывать туда-сюда трафик и быть "лицом с белым адресом".

    С ssh-туннелями всё это тоже сделать можно, но получается чуть больше потенциальных проблем, необходимости контроля и нагрузки на обе стороны


    1. jehy Автор
      09.01.2024 18:02
      +1

      Спасибо за развёрнутый комментарий! Практически со всем согласен, я собственно нигде не утверждал, что способ с ssh и двумя nginx - единственный или самый лучший. У меня просто есть некоторое количество предпосылок именно для такой настройки соединения. Они просто не очень интересные, поэтому не расписывал. А в целом - у всех потребности немного отличаются, поэтому подходят разные решения, это нормально.

      Разве что чуть поспорю с костыльностью autossh. Это просто обычный демон с кипэлайвом и реконнектами, при этом из официального репозитория. В целом, ничем не отличается от любого другого механизма установления постоянного соединения.


  1. Expany
    09.01.2024 18:02

    Static IP

    Domain

    Basic HTTP Auth

    ???

    Profit

    Статик от прова, домен у любого регистратора, проброс портов и дело в шляпе.

    На это целой статьи вроде не надо, или я ошибаюсь?


    1. jehy Автор
      09.01.2024 18:02

      Чукча - не читатель?


  1. boojum
    09.01.2024 18:02

    А статические IPv6 адреса провайдеры еще не раздают?


    1. Aelliari
      09.01.2024 18:02

      В нормальной ситуации - и не должны, они должны давать статический префикс /64 на оконечное устройство. Если это не оконченое устройство (например роутер) - префикс, по идее должен быть ещё короче


      1. boojum
        09.01.2024 18:02

        Не понял вашу мысль. "статический префикс /64" - это разве не то о чём я спросил?


        1. Aelliari
          09.01.2024 18:02

          Вы спросили о «адресах», нет, провайдер не должен давать адреса (хотя DHCPv6 тоже существует). Он должен давать префикс, а адреса выбирают оконечные устройства самостоятельно с учётом полученного префикса

          И естественно, устройство реализующее IPv6 Privacy Extension будет регулярно менять эти самые адреса, если ему явно не сказали «сохранить» какой-то адрес активным (менять оно продолжит, просто указанный адрес - тоже останется)


          1. boojum
            09.01.2024 18:02
            -1

            Это всё замечательно. Я рад что вы знаете столько умных терминов.
            Жаль лишь, что ваши ответы не имеют отношения к сути моего вопроса.


            1. belokobylskiy
              09.01.2024 18:02
              +2

              Стандарты в ipv6 и ipv4 отличаются. В v4 провайдер выдаёт вам один адрес для роутера (статический/динамический, серый/белый), а если у вас за роутером ещё устройства - это вы сами решаете что делать, обычно через NAT с серыми адресами. А в ipv6 провайдер должен выдавать подсеть адресов /56, чтобы роутер дальше раздал по подсети /64 для каждого отдельного устройства.

              Касаемо вашего вопроса: да, некоторые провайдеры выдают нормальные ipv6 адреса, зависит от региона и провайдера.


  1. andreybold
    09.01.2024 18:02
    +1

    Год или два назад тоже задался этим вопросом и тоже для Home Assistant. Первое моё решение (после долгих поисков и гугления) — clouflare. Но пару месяцев назад узнал про роутеры keenetic (нужно было строить mesh сеть) и узнал что у них есть функция KeenDNS. Недавно купил его, настроил и доволен как слон. Эту бы статью года два назад, сэкономил бы кучу времени и сил. Но всё равно огромное спасибо за статью. И спасибо за наводку про заголовок хоста. Пока не пригодилось, но думаю будет полезно в будущем.