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

Часто оказывается необходимым дать доступ из Интернета к каким-либо портам своего компьютера, расположенного за 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=:8080 -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.


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

© Geektimes