Добрый день! История такова: сколько себя помню, всегда дома висел какой-нибудь сервер, который очень хотелось вывести во всеми нами любимый Интернет.
«Ну и что тут сложного? Практически любой провайдер предоставляет статический белый IP за небольшую плату!», – скажите Вы и будете абсолютно правы. Но это платно, да и вообще хотелось попробовать чего-нибудь более оригинального. Основная проблема доступа к моему серверу – NAT. Если вдруг кто не знает, что это, ниже оставил пояснение из Википедии.
Преобразование адреса методом NAT может производиться почти любым маршрутизирующим устройством — маршрутизатором, сервером доступа, межсетевым экраном. Наиболее популярным является SNAT, суть механизма которого состоит в замене адреса источника (англ. source) при прохождении пакета в одну сторону и обратной замене адреса назначения (англ. destination) в ответном пакете. Наряду с адресами источник/назначение могут также заменяться номера портов источника и назначения.
Принимая пакет от локального компьютера, роутер смотрит на IP-адрес назначения. Если это локальный адрес, то пакет пересылается другому локальному компьютеру. Если нет, то пакет надо переслать наружу в интернет. Но ведь обратным адресом в пакете указан локальный адрес компьютера, который из интернета будет недоступен. Поэтому роутер «на лету» транслирует (подменяет) обратный IP-адрес пакета на свой внешний (видимый из интернета) IP-адрес и меняет номер порта (чтобы различать ответные пакеты, адресованные разным локальным компьютерам). Комбинацию, нужную для обратной подстановки, роутер сохраняет у себя во временной таблице. Через некоторое время после того, как клиент и сервер закончат обмениваться пакетами, роутер сотрет у себя в таблице запись о n-ом порте за сроком давности.
Если своими словами, это внешний маршрутизатор, позволяющий Вам отправлять запросы в интернет, но не позволяющий Вам их получать. Ответ-то из Интернета Вы получаете, а значит уже не все потеряно. Мне вспомнилась старая программа LogMeIn Hamach, она же позволяла нам обмениваться пакетами данных при том, что ВСЕ клиенты были в закрытой NAT'ом сети. А что, если реализовать что-нибудь подобное:
Что здесь нарисовано? OPI – это моя Orange Pi PC, которая выполняет роль сервера, NAT – это, как несложно догадаться, маршрутизатор моего оператора (он может быть не один, но сути это не меняет), KVM – внешний сервер товарища, CLI – клиент. Возможно, у вас возник вопрос: «По какой причине ты не мог просто выкинуть все свои сервисы на сервер товарища?». Ответ прост: не хочу. В конце концов и дисковое пространство пришлось бы использовать чужое, а меня это не устраивает. Не говоря уже об усложнении администрирования и обслуживания сервера…
OPI подключается к KVM и между ними устанавливается VPN канал. А далее клиент подключается к KVM, и эта машина в свою очередь отправляет запрос через VPN к OPI.
Почему KVM? Сервер товарища – обычный
Настройка сервера
В теории это звучит все здорово, но теперь надо реализовывать на практике. Нужно выбрать протокол для VPN. Изначально, я был склонен к OpenVPN, но после череды проб, ошибок, неудач, пришел к выводу, что это не лучший протокол для таких действий. В конце концов он использует сложные алгоритмы шифрования, которые еще и будут неслабо грузить процессор OPI и внешнего сервера, поэтому мой выбор пал на протокол PPTP.
Первым делом надо установить сам PPTP демон на сервере:
apt install pptpd
Следующим шагом его надо настроить. Откроем его конфиг файл /etc/pptpd.conf и укажем IP адрес сервера и диапазон IP адресов клиентов:
localip 10.0.0.1
remoteip 10.0.0.100-200
Теперь нужно создать учетные записи VPN клиентов. Их список находится в файле /etc/ppp/chap-secrets
# client server secret IP addresses
orange pptpd pass123 10.0.0.100
Мы создали клиента orange с паролем pass123 и IP адресом 10.0.0.100. Если вместо IP адреса указать *, то клиент получит любой свободный IP адрес из диапазона, указанного в remoteip. Нам рандома явно не надо. Теперь еще пару штрихов с настройками PPTPD. Добавим DNS сервера в файле /etc/ppp/pptpd-options
ms-dns 8.8.8.8
ms-dns 8.8.4.4
И перезагрузим PPTPD:
service pptpd restart
Очень важный шаг – включение IP форвардинга. Это позволит Вам пересылать пакеты между публичным IP и приватными IP, которые Вы настроили при помощи PPTP. Редактируем файл /etc/sysctl.conf и раскомментируем строку:
net.ipv4.ip_forward = 1
Отлично, теперь можно начинать колдовать с ipatables.
Для начала узнаем название нашего сетевого интерфейса:
~$ ifconfig
ens3 Link encap:Ethernet HWaddr 52:54:00:f8:0c:4a
inet addr:31.148.99.234 Bcast:31.148.99.255 Mask:255.255.255.0
inet6 addr: fe80::5054:ff:fef8:c4a/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:8808733 errors:0 dropped:0 overruns:0 frame:0
TX packets:3300625 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:3511383831 (3.5 GB) TX bytes:3245380453 (3.2 GB)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:216 errors:0 dropped:0 overruns:0 frame:0
TX packets:216 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1
RX bytes:16618 (16.6 KB) TX bytes:16618 (16.6 KB)
У меня он называется ens3. Однако, чаще всего он называется eth0.
Создаем правило iptables:
iptables -t nat -A POSTROUTING -o ens3 -j MASQUERADE && iptables-save
Не забудьте заменить интерфейс на свой. Если вы планируете в будущем использовать VPN для своих нужд, можете прописать правила, чтобы клиенты VPN сети могли взаимодействовать:
iptables --table nat --append POSTROUTING --out-interface ppp0 -j MASQUERADE
iptables -I INPUT -s 10.0.0.0/8 -i ppp0 -j ACCEPT
iptables --append FORWARD --in-interface ens3 -j ACCEPT
ppp0 – виртуальный интерфейс сети.
Настройка локального сервера
Далее нужно подключить нашего первого клиента – Orange PI. На этом моменте я засел надолго, так как все инструкции в интернете говорили одно и то же, и все они не работали.
Первым делом на Orange PI установим PPTP клиент:
apt install pptp-linux
Создадим файл /etc/ppp/peers/pptpserver и впишем следующее:
pty "pptp 31.148.99.234 --nolaunchpppd"
name orange
password pass123
remotename PPTP
require-mppe-128
Не забудьте поменять IP адрес сервера и прочие данные на свои.
Далее закомментируем все строки в файле /etc/ppp/options вставкой символа #
Файл /etc/ppp/options.pptp нужно привести к следующему виду:
lock
noauth
nobsdcomp
nodeflate
defaultroute
replacedefaultroute
mtu 1400
persist
maxfail 0
lcp-echo-interval 20
lcp-echo-failure 3
И, наконец, пробуем подключиться:
pon pptpserver
Если все получилось, попробуем посмотреть на наш виртуальный интерфейс:
~$ ifconfig ppp0
ppp0 Link encap:Point-to-Point Protocol
inet addr:10.0.0.100 P-t-P:10.0.0.1 Mask:255.255.255.255
UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1496 Metric:1
RX packets:1075 errors:0 dropped:0 overruns:0 frame:0
TX packets:959 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:3
RX bytes:154176 (154.1 KB) TX bytes:194499 (194.4 KB)
Попробуем пропинговать Orange PI с внешнего сервера:
~$ ping 10.0.0.100
PING 10.0.0.100 (10.0.0.100) 56(84) bytes of data.
64 bytes from 10.0.0.100: icmp_seq=1 ttl=64 time=8.91 ms
64 bytes from 10.0.0.100: icmp_seq=2 ttl=64 time=8.80 ms
64 bytes from 10.0.0.100: icmp_seq=3 ttl=64 time=8.93 ms
64 bytes from 10.0.0.100: icmp_seq=4 ttl=64 time=9.00 ms
Работает!
Проброс портов
Теперь самая малость: перенаправление пакетов с сервера на Orange PI. Тут уже способы могут быть разными, но так как на этом сервере 80 и 443 порт не используются вообще, мы можем просто попросить сервер все пакеты для этих портов перенаправлять на OPI
iptables -t nat -A PREROUTING -p tcp -d 31.148.99.234 --dport 80 -j DNAT --to-destination 10.0.0.100:80
iptables -A FORWARD -i ppp0 -d 10.0.0.100 -p tcp --dport 80 -j ACCEPT
iptables -t nat -A PREROUTING -p tcp -d 31.148.99.234 --dport 443 -j DNAT --to-destination 10.0.0.100:443
iptables -A FORWARD -i ppp0 -d 10.0.0.100 -p tcp --dport 443 -j ACCEPT
На забудьте поменять IP адреса на свои. Проверим, что все работает:
Здорово! Цель достигнута!
Маленькие доработки
Но вдруг в здании, где располагается Orange PI выключается свет и… После перезагрузки никто опять не может получить доступ к нашему апельсину. Почему? Потому что сам по себе Orange PI к VPN не подключится. Напишем простой скрипт на bash, который будет вциклически выполняться, проверяя, установлено ли соединение:
#!/bin/sh
while [ 0 ]
do
if ifconfig ppp0>>/dev/null
then
sleep 7
else
pon pptpserver
if $?
then
echo $(date) Connected
else
echo $(date) Connection error
fi
fi
sleep 3
done
Теперь добавим его в автозагрузку. В файл /etc/rc.local впишем строку с расположением скрипта. В моем случае это:
/root/scripts/ppp.sh
Не забываем дать скрипту права на исполнение:
chmod +x /root/scripts/ppp.sh
Внимательный пользователь мог заметить, что в скрипте есть команды echo, но ведь им некуда делать вывод! Изначально, я планировал сделать в виде сервиса, чтобы вывод удобно капал туда, но в итоге банально поленился, работает же. Кстати, а работает ли? Перезагружаем наш апельсин и видим, что интерфейс ppp0 успешно поднялся, а наши сервисы доступны из интернета. Цель достигнута, господа!
Итог
Все это сделано исключительно в развлекательных и учебных целях. Практической пользы это почти не несет, так как нам все равно необходим внешний сервер, да и нагрузка не его сеть удваивается, ибо ему приходиться принимать пакеты и сразу же передавать их дальше. Однако, у этого метода есть преимущества, т.к. реальный IP нашего сервера будет скрыт, этот внешний сервер сможет лучше противостоять DDoS атакам, а также сможет выводить беспокойным пользователям страницу о технических работах, если Orange PI будет недоступен. Конечно же, для этого нужно будет еще серьезно постараться, но разве не в самом пути к цели все удовольствие, товарищи?
Ссылки на используемые ресурсы
1. Как настроить VPN с помощью PPTP
2. Проброс портов через NAT
Автор: Trofen