Начало

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

Но, благодаря этому, я, так же, вспомнил, как когда-то давно, я наткнулся на статью про ngrok. Ссылки на нее, к сожалению, я не сохранил и, благополучно забыл. Но теперь, с пылающей идеей в голове, я устремился на поиски самого ценного ресурса, для осуществления задуманного — информации.

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

Кстати, о железе. Мой сервер, это крохотный raspberry pi 4 c 8-ю гигами оперативной памяти под управлением 21 Ubuntu, на котором у меня постоянно крутятся мои разработки.

Установка ngrok

Для начала, регистрируемся на сайте и получаем токен.

Далее выполняем:

snap install ngrok

Далее нужно добавить полученный токен командой:

ngrok authtoken <ваш токен>

И все, установка завершена.

Туннель в небе

Теперь остается только открыть туннель для вашего ресурса. Это мог бы быть сайт, или еще какой проект, или, вообще, БД.
Мы же открываем удаленный доступ. Значит, ssh. Значит 22 порт по умолчанию.

ngrok tcp 22

На экране появится что-то вроде:

Процесс работы сервиса
Процесс работы сервиса

Туннель открыт. Главное здесь это поле Forwarding, которе имеет примерно такое содержимое: tcp://0.tcp.eu.ngrok.io:12345.
Теперь все запросы по этому адресу будут транслироваться на localhost:22 где их ожидает ssh.

Что бы подключиться удаленно выполним:

ssh 0.tcp.eu.ngrok.io -p 12345

Введя имя пользователя и пароль, попадаем на устройство. Готово! Поздравляю!

А если перезагрузится?

Ну, а правда, если по какой-то причине, сервер перезагрузится, туннель же закроется. Непорядок.
Но я уже работал с systemctl, так что эта проблема — вопрос нескольких минут.
Очень советую ознакомится с этой крутой штукой.

systemd — подсистема инициализации и управления службами в Linux, фактически вытеснившая в 2010-е годы традиционную подсистему init. Основная особенность — интенсивное распараллеливание запуска служб в процессе загрузки системы, что позволяет существенно ускорить запуск операционной системы. Основная единица управления — модуль, одним из типов модулей являются «службы» — аналог демонов — наборы процессов, запускаемые и управляемые средствами подсистемы и изолируемые контрольными группами.

Пишем файл ngrok.service и помещаем его в /etc/systemd/system/ (требуются рут права)

Содержимое файла:

[Unit]
Description=ngrok
After=network.target
After=syslog.target

[Service]
Type=simple
ExecStart=/snap/bin/ngrok tcp 22
Restart=always
RestartSec=1
WorkingDirectory=/home/vladimir/prog/python/projects/ngrok 
User=vladimir  
Group=vladimir
StartLimitBurst=99999
StartLimitInterval=999999

[Install]
WantedBy=multi-user.target

Активируем сервис:

sudo systemctl enable ngrok.service

И запускаем:

sudo systemctl start ngrok.service

Теперь, даже, если сервер перезагрузится, этот сервис запусится автоматически.

Ngrok API

При каждом открытии туннеля ngrok, адрес подключения будет разным.
Как тогда удаленно узнать новый адрес? Это несложно. У ngrok есть собстенный API
И есть там требуемый роут /tunnels.

Однако, для начала, нужно получить API токен. На сайте сервиса.

Подобный запрос:

curl --location --request GET 'https://api.ngrok.com/tunnels' --header 'Authorization: Bearer <ваш API токен>' --header 'Ngrok-Version: 2'

Даст такой результат, если не открыто ни одного туннеля:

{
    "tunnels": [],
    "uri": "https://api.ngrok.com/tunnels",
    "next_page_uri": null
}

И если есть:

{
    "tunnels": [
        {
            "id": "<privat>",
            "public_url": "tcp://0.tcp.eu.ngrok.io:12345",
            "started_at": "2099-06-15T10:46:13Z",
            "metadata": "",
            "proto": "tcp",
            "region": "eu",
            "tunnel_session": {
                "id": "<privat>",
                "uri": "https://api.ngrok.com/tunnel_sessions/<privat>
            },
            "endpoint": {
                "id": "<privat>",
                "uri": "https://api.ngrok.com/endpoints/<privat>"
            },
            "forwards_to": "localhost:22"
        }
    ],
    "uri": "https://api.ngrok.com/tunnels",
    "next_page_uri": null
}

Как видите, вся необходимая информация, для подключения есть в поле "public_url". Можно подключаться.

Еще немножко автоматизации

Как говорил один великий: "Я человек простой: вижу то, что можно автоматизировать — автоматизирую".

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

Пишем скрипт.

В баше я не особо силен, но написанного хватает с головой:

#!/bin/bash

res=$(curl --location --request GET 'https://api.ngrok.com/tunnels' \
--header 'Authorization: Bearer <ваш API токен>' \
--header 'Ngrok-Version: 2' | awk 'BEGIN { FS="\""; RS="," }; { if ($2 == "public_url") {print $4}}')

if [ -z "$res" ]  
then
    echo "No tunnels"
    exit
fi

ip_port=$(echo ${res:6})

arr=($(echo $ip_port | tr ":" "\n"))

ip=$(echo ${arr[0]})
port=$(echo ${arr[1]})

ssh $ip -p $port

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

Итоги

В этой статье был описан способ организации удаленного доступа по протоколу ssh к серверу под управлением Ubuntu.

Будте осторожны. Помните, вы открываете туннель не только для себя, но и для всего мира. Озаботьтесь безопасностью.

У меня управление туннелями выведено в свой telegram бот. И оповещения о попытках ssh подключении приходят туда же. Если кому будет интересно, расскажу, как это сделал, но уже в другой статье.

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


  1. litos
    29.06.2022 14:56
    +5

    Но ведь это коммерческое решение судя по сайту https://ngrok.com/pricing с «чужим» сервером?


  1. cepera_ang
    29.06.2022 15:06
    -1

    В стопятьсотмиллионный раз посоветую http://tailscale.com/ всем зашедшим на огонёк огранизации удалённого доступа (с белым айпи или нет — пофиг вообще). Перефразируя слова из статьи: можете не быть осторожны, помните, вы организуете совершенно безопасный доступ для себя и только для себя. И бонусом — требуется 0 конфигурации.


    1. litos
      29.06.2022 15:08
      +3

      Тоже что-то платное? https://tailscale.com/contact/sales/

      Что мешает купить свой VPS за 3 доллара в месяц и настроить VPN с клиентов и проброс портов через него?


      1. cepera_ang
        29.06.2022 15:11

        Нет, бесплатный вариант для домашнего или небольшого профессионального использования будет за глаза. А гитхаб план вообще 95% потребностей закроет даже для мелких компаний.


        Разница между покупкой VPS за 3 доллара и настройкой всяких портов и прочей вознёй и работающей просто из коробки всегда надёжно системой — гораздо больше чем может показаться на первый взгляд. Попробовав второе уже навсегда становится непонятно «зачем?» нужен первый вариант :)


        1. bepim
          29.06.2022 15:57
          +1

          Разница между покупкой VPS за 3 доллара и настройкой всяких портов и
          прочей вознёй и работающей просто из коробки всегда надёжно системой

          https://github.com/angristan/openvpn-install/

          всё ставится одной строчкой, работает годами


          1. cepera_ang
            29.06.2022 16:21

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


            1. bepim
              29.06.2022 16:39
              +1

              На телефон, планшет, малинку и виндовый комп ставится импортированием .ovpn файла, то есть в два клика. Сам файл создаётся одной строчкой.

              Проблем с NAT за годы использования в разных странах и у разных провайдеров/опсосов замечено не было, при смене сети переподключается автоматом средствами ОС (всякие ssh этого не замечают, а кроме него мне нигде бесшовная сессия не нужна).

              Пошарить машинку - одной строчкой даётся и отзывается доступ.

              По поводу ротации ключей/сертификатов и длины маршрутов предлагаю вам самому ознакомиться: я не шарю, просто пользуюсь в своё удовольствие, нареканий не имею.


        1. HackcatDev
          30.06.2022 15:06
          +3

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


          1. cepera_ang
            30.06.2022 15:20

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


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


            1. HackcatDev
              01.07.2022 15:04

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

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

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


  1. jstbot
    29.06.2022 15:57

    не для того что бы во внешний мир открыть какой то доступ, а получить доступ до любого устройства из многих своих(хоть с телефона), до сих пор использую ZeroTier


  1. idruzhitskiy
    29.06.2022 15:57
    +1

    Еще вариант - настроить ddns (например duckdns.org), обновление записи поставить по крону. И не придется ходить через сторонние серверы.


    1. turbidit
      29.06.2022 16:25

      Как ddns поможет с серым ip?


      1. idruzhitskiy
        29.06.2022 17:14

        Скрипт каждые n минут обновляет ip на ddns сервере. В итоге к машине можно подключаться через выбранный ddns адрес.


        1. turbidit
          29.06.2022 17:38
          +4

          Как вы подключитесь извне к серому адресу? Думаю, вы путаете серый и белый динамический.


          1. idruzhitskiy
            29.06.2022 18:07

            Да, вы правы, в случае с серым ip это не поможет.


  1. FSA
    30.06.2022 15:02
    +1

    Самый надёжный и простой вариант - дешёвый VPS с Wireguard. Минимум настроек. Прокинуть на клиентов можно что угодно. При желании можно использовать для починки сети из-за блокировок РКН.


    1. ABATAPA
      30.06.2022 15:33

      А если ещё кто успел взять за $6.6 в год... Да даже за $1 в месяц. Правда, сейчас единственный путь оплаты — криптовалюта. 8(


      1. FSA
        30.06.2022 22:11

        Никого не рекламирую, но за 3 евро в месяц через киви вполне возможно найти.


  1. geekfil
    01.07.2022 08:06

    Советую присмотреться к Cloudflare Tunnel.