SSH внутри HTTP/HTTPS

    В последнее время правила становятся все жёстче, провайдеры лютуют, режут трафик.  Вот и столкнулся на днях с ситуацией когда, админ зарезал исходящий трафик оставив только веб. Замена ssh порта с 22 на 443 на удаленном сервере не помогла, видимо стоит какой DPI-фильтр. 

    В такой ситуации нам поможет websocat. Интересная приблуда, судя по описанию это: "Netcat, curl and socat for WebSockets."  Можно собрать с исходников, есть готовые сборки под разные системы ссылка.

    В большинстве случаев нам подойдет websocat.x86_64-unknown-linux-musl

    Рассмотрим ситуацию когда у нас есть сервер А который находится за жёстким фаерволом корпоративной сети (доступен только исходящий веб-трафик), и на него нужно получить доступ из вне по SSH c сервера B где-то в интернете. 
    Первоначально нам нужно получить websocat и поднять на сервере B nginx c простейшей конфигурацией.

    mkdir -p ~/commands && cd ~/commands
    wget https://github.com/vi/websocat/releases/download/v1.10.0/websocat.x86_64-unknown-linux-musl
    mv ./websocat.x86_64-unknown-linux-musl ./websocat
    dnf install nginx -y

    server {
      listen 123.123.123.123:80;
      server_name 123.123.123.123;
    location /wstunnel/ {
          proxy_pass http://127.0.0.1:33333;
          proxy_http_version 1.1;
          proxy_set_header Upgrade $http_upgrade;
          proxy_set_header Connection "Upgrade";
        }
    }

    Где 123.123.123.123 - это внешний IP-адрес сервера B (который будет принимать http/https соединения)

    Далее поднимаем websocat в фоне, либо можно в screen-е.

    $HOME/commands/websocat -E --binary ws-l:127.0.0.1:33333 tcp:127.0.0.1:22 &

    Переходим к настройке на стороне сервера А.  Таким же образом получаем на сервер websock и запускаем туннель.

    ssh -f -N -R 2233:127.0.0.1:22 -o ProxyCommand='~/commands/websocat --binary ws://123.123.123.123/wstunnel/' root@123.123.123.123

    Что тут происходит: сервер А  через http сокет подключается на web-сервер B (123.123.123.123), где Nginx принимает входное соединение и проксирует его на websocat, который в свою очередь соединяет c SSH сервером. Далее организовывается туннель, на сервере B поднимается порт 127.0.0.1:2233, при подключении на который мы выходим на SSH на сервере A.

    Если необходим туннель по HTTPS, то потребуется реальный домен, чтоб поднять сертификаты (certbot в помощь), и в соединении меняем ws на wss

    Copyright © 2022Powered by Bludit