СоХабр закрыт.

С 13.05.2019 изменения постов больше не отслеживаются, и новые посты не сохраняются.

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

Часто оказывается необходимым дать доступ из Интернета к каким-либо портам своего компьютера, расположенного за NAT провайдера. Но популярный ранее сервис ngrok стал IMHO фактически непригоден в бесплатной версии. Как же быть? Сделаем свой ngrok, разместив его на своей же VPS-ке (да, Ваш сервер в Интернете необходим, без него никак). Опишу, как это вышло у меня.

image

Итак, имеем VPS на Ubuntu Linux 14.04.1. Заходим в консоль через SSH и действуем по списку.
1. Ставим последние обновления для системы.

apt-get update
apt-get -y upgrade

2. Установим необходимые пакеты.

apt-get install build-essential mercurial git

система mercurial требуется для сборки ngrok

3. Устанавливаем последнюю (1.8.3) версию языка Go (Golang) — ngrok написан именно на нем.

apt-get golang — так делать не нужно, так как не гарантируется установка последней версии языка

wget https://storage.googleapis.com/golang/go1.8.3.linux-amd64.tar.gz
tar -xvf go1.8.3.linux-amd64.tar.gz
mv go /usr/local
export GOROOT=/usr/local/go
export GOPATH=/home/go
export PATH=$GOPATH/bin:$GOROOT/bin:$PATH

Примечание. Команды export окажут влияние только на текущую сессию.

Проверяем:

go version -> go version go1.8.3 linux/amd64


4. Клонируем исходный код ngrok.

git clone https://github.com/inconshreveable/ngrok.git ngrok
cd ngrok

5. Создаем требуемые поддомены для Вашей VPS — A-записи с именами ngrok, 1.ngrok, 2.ngrok и т.п., указывающие на IP-адрес VPS (1, 2 — желаемые субдомены). И да, просто ngrok тоже нужен!

6. Генерируем самоподписанный SSL-сертификат (необходим, так как ngrok создает туннель через TLS).

openssl genrsa -out rootCA.key 2048
openssl req -x509 -new -nodes -key rootCA.key -subj "/CN=ngrok.domain.com" -days 5000 -out rootCA.pem
openssl genrsa -out device.key 2048
openssl req -new -key device.key -subj "/CN=ngrok.domain.com" -out device.csr
openssl x509 -req -in device.csr -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out device.crt -days 5000

5000 — срок действия сертификата в днях (можно заменить, например, на 10000)
domain.com — домен Вашей VPS

Копируем нужные для компиляции файлы в директорию assets:

cp rootCA.pem assets/client/tls/ngrokroot.crt
cp device.crt assets/server/tls/snakeoil.crt 
cp device.key assets/server/tls/snakeoil.key

7. Компилируем сервер и клиент для Linux.

make release-server release-client

Копируем полученный файл сервера ngrokd из директории bin в нужную папку.

8. Компилируем сервер (на всякий случАй)) и клиент для 32-разрядной Windows.

make clean
GOOS=windows GOARCH=386 make release-server release-client

(для 64-битной версии меняем 386 на amd64).

Копируем файл клиента ngrok.exe с VPS из папки bin/windows_386 на клиентский (домашний) компьютер.

9. Копируем файлы device.key, device.crt, device.csr в директорию, куда мы скопировали исполнимый файл сервера ngrokd.

Устанавливаем требуемые атрибуты файла сервера:

chmod +x ngrokd

Запускаем сервер (например, через утилиту screen).

screen -S ngrok
./ngrokd -tlsKey=device.key -tlsCrt=device.crt -domain=ngrok.domain.com -httpAddr=:<b>8080</b> -httpsAddr=:8081

domain.com — домен Вашей VPS
8080 — порт для HTTP-запросов
8081 — порт для HTTPS-запросов
(порты, естественно, должны быть свободны)

Жмем CTRL+A+D для выхода из созданного «экрана».

10. Создаем на клиенте (домашнем компьютере) файл конфигурации ngrok.cfg в той же директории, куда мы скопировали ngrok.exe, с содержимым:

server_addr: ngrok.domain.com:4443
trust_host_root_certs: false

4443 — порт по умолчанию, на котором сервер ngrok слушает запросы (этот порт должен быть открыт на Вашей VPS)
domain.com — домен Вашей VPS
false — ведь сертификат самоподписанный

11. Ждем, пока изменения в DNS-записях достигнут Вашего провайдера (с DNS-серверами Google, например, будет быстрее), пингуя нужный адрес.

ping ngrok.domain.com

domain.com — домен Вашей VPS

12. Запускаем простейший Web-сервер на 80-м порту (HTTP) Вашего домашнего компьютера (например, на Ruby c WEBRick).

13. Запускаем на домашнем компьютере клиент ngrok с выводом протокола.

ngrok.exe -log=stdout -config=ngrok.cfg -subdomain=1 80

1 — желаемый субдомен для этого домашнего компьютера
80 — порт нашего Web-сервера, выставляемого в Интернет

14. Проверяем работу, заходя с другого компьютера на наш Web-сервер по адресу:

http://1.ngrok.domain.com:8080

8080 — заданный на шаге 9 порт для HTTP-запросов
domain.com — домен Вашей VPS

Если Web-сервер не будет запущен, получим сообщение:

Tunnel http://1.ngrok.domain.com:8080 unavailable
Unable to initiate connection to 127.0.0.1:80. A web server must be running on port 127.0.0.1:80 to complete the tunnel.

Вот такие дела! Надеюсь, кому-то пригодится.

комментарии (40)

+2
pwrlnd ,   * (был изменён)
SSH port forwarding не справится с такой задачей? Просто и из коробки. А если надо быстро и надёжно, то тогда уж OpenVPN можно поднять.
0
ed007 ,  
А разве надо хоть кому не быстро и не надежно?
+1
pwrlnd ,  
не быстро и не надежно

Скорость и стабильность — понятие относительные. Прокинуть порт WEB-сервера для демонстрации проекта или получить доступ к RDP во внутренней сети — будет вполне достаточно SSH. Если же речь идёт об одновременной работе десятков людей через это соединение, то лучше выбрать OpenVPN или что-то подобное.
0
ed007 ,  
Мне просто резанула глаза эта фраза, если так сказать на переговорах — клиент потерян. (По крайней мере в EU)
0
pwrlnd ,  
Зачем на переговорах клиенту объяснять технические детали вашей dev-среды? Уверен, что клиенту интересна релизная часть.
0
dbond ,  
OpenVPN не работает за провайдерским натом, например у ТТК.
0
pwrlnd ,   * (был изменён)
Какая связь? Если доступ в интернет есть, то OpenVPN точно будет работать — NAT ему не мешает. Либо не в ту сторону тоннель строите. Для тяжелых случаев даже есть режим TCP.
0
dbond ,  
У ТТК OpenVPN работает только на статическом айпишнике. По словам ТП это особенности их NAT.
+2
pwrlnd ,  
Если бы был такой особенный NAT, то клиенты завалили бы поддержку жалобами. Одни бы жаловались на торренты, другие на неработающий DNS от Google, а третьи бы не смогли играть в свою любимую игру онлайн.

Если уж предположить, что UDP специально был порезан, то OpenVPN в режиме TCP точно бы заработал, так как это соединение ничем не отличается от того, которое устанавливает браузер для загрузки сайта.
0
dbond ,  
Я жаловался ))) им как с гуся вода. У них помимо глюков впн за 2 последних недели 3 блэкаута было, причем один из них весь рабочий день. ТП молчит как рыба об лёд, отнекивается общими фразами. Причем и сервер и клиент у ТТК в одном городе. Сервер на статическом IP, клиент на динамическом. Не работает, пишет «TLS handshake failed.», но стоит у клиента воткнуть в роутер кабель от Ростелекома или Мегафона, все начинает работать как часики.
0
pwrlnd ,  
До сих пор присутствует такая проблема? У меня прямо спортивный интерес возник — посмотреть, что это ТТК там сделали, что так ювелирно вставляют палки в колеса.
0
dbond ,  
Сейчас поменял настройки с UDP на TCP. Порт 8080. Не работает! Пишет «TCP: connect to [AF_INET]XX.XX.XX.XX:8080 failed, will try again in 5 seconds.»
0
pwrlnd ,  
На сервере тоже надо изменять конфиг (в таком случае лучше иметь два конфига, чтобы старых клиентов не перенастраивать).
0
dbond ,  
Я создал ещё один экземпляр сервера. Через Мегафон работает. Через ТТК — нет.
0
pwrlnd ,  
тогда трафик надо с интерфейса снять и посмотреть что происходит
0
dbond ,  
Посмотрел вайршарком, уходят тсп пакеты с портов 49758 (при каждой попытке происходит инкремент номера порта) на адрес сервера порт 8080. На сервере tcpdump входящих пакетов не видит.
0
pwrlnd ,  
А на сервере сидите по ssh с этой же машины?
0
dbond ,  
со второго компа но через другого провайдера.
0
pwrlnd ,  
То есть вы через ТТК не можете подключиться по ssh к своему серверу?
0
dbond ,  
У меня ssh закрыт. pfSence рулится через веб-интерфейс.
0
pwrlnd ,  
Хорошо, через ТТК на веб-интерфейс вы можете зайти из дома?
0
dbond ,  
не пробовал, у меня все входящие закрыты кроме портов ВПН
0
pwrlnd ,  
Тогда стоит открыть и посмотреть. А на счёт OpenVPN — скорее всего, дело в настройках файерволла на сервере.
0
dbond ,  
Там все верно. от других провайдеров работает!
0
pwrlnd ,  
Не факт — ТТК может натить своих клиентов с адреса, который входит в подсеть, в которой находится сервер с его шлюзом. И правила на сервере могут быть для этой подсети указаны другие. Это как пример — комбинации могут быть другие.

PS: По факту у вас проблема только внутри сети ТТК, скорее всего. Если косяк не у вас, а у ТТК, то пробелма не в нате, а в маршрутизации.
0
dbond ,  
Не вижу я веб-интерфейс своего сервера именно из ТТК! Нда, сам не догадался очевидное проверить. Спасибо! Буду с ними бодаться.
0
dbond ,  
Попробую открыть, посмотрю.
0
dbond ,  
Андроид и ios клиенты тоже не коннектятся когда подключены к домашнему вайфаю.
0
dartraiden ,  
SoftEther VPN умеет пробивать NAT, если мне не изменяет память.
0
SolarW ,  
В наших краях у провайдеров предоставляющего доступ без реальных айпишек частенько не работает PPTP из-за того, что не NAT'ят GRE.

P.S. Да, я в курсе что PPTP древность которую надо заменять на другие способы. Но иногда его более чем хватает.
0
pwrlnd ,   * (был изменён)
Да, с GRE есть такая проблема. У меня даже есть подозрение, что dbond путает обычный VPN (PPTP или L2TP) с OpenVPN. Десять лет назад у меня было около 1500 клиентов, более половины использовало OpenVPN для доступа. Не было случаев, когда OpenVPN не работал: были случаи, когда у клиента был только прокси для доступа в интернет — даже в режиме работы через прокси OpenVPN показал себя отлично.
0
dbond ,  
Не путаю. Со стороны сервера pfsence. Там эта фича практически из коробки. И экспорт клиентов очень удобен. Даже бухи в состоянии дома запустить.
+5
gudvinr ,  

Это уже не "бесплатный туннель", если нужен VPS.


Какой смысл в ngrok (причём старой версии) в этом случае, если есть старый-добрый ssh forwarding, как выше сказали?
Проще скрипт написать, который будет делать тоже самое без лишних слоёв.


В качестве альтернативы можно использовать localtunnel.


ИМХО конечно, но и бесплатного плана для ngrok вполне достаточно для IoT проектов или чтобы потестировать что-либо на локальной машине за NAT. В остальных случаях так или иначе понадобится отдельный сервер с выделенным адресом.
Слабо могу представить, для чего нужны ресурсы сверх того, что предлагают в бесплатном плане, при таких юзкейсах.


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

+1
amarao ,  
ssh -CD 1080 ip-address

Появляется socks-proxy на порту 127.0.0.1:1080

всё остальное содержимое статьи — зачем?
0
redmanmale ,  

Или ssh -L 8080:127.0.0.1:8080 user@ip-address-vps -N.
Пробрасываем локальный порт (слева) на удалённый порт (справа).

+5
saboteur_kiev ,  
Слово «бесплатный» следует убрать из названия статьи.
–1
justhabrauser ,  
Чем бы дитя не тешилось — только бы руки на одеяле держало.
(а за make убивают вообще-то)
Но таки да — вариант.
+1
bigbrotherwatchingyou ,  
Статью можно назвать «Когда линуксоиду нечем заняться...» Таким в проктологи надо идти, а не админить и программить
0
ABATAPA ,  
OpenVPN c Pritunl на хостинге за 100 руб. поднимается буквально несколькими командами. Дальше несколько кликов — и вот уже есть конфиг, который «едят» 99% клиентов под все платформы.
+1
Anonym ,  

apt-get install ngrok-server уже не работает?