Вынос локального сервера в сеть с помощью другого внешнего сервера

в 12:21, , рубрики: iptables, linux, nat, Orange Pi, PPTP, vpn, Настройка Linux, Серверное администрирование, Сетевые технологии

Добрый день! История такова: сколько себя помню, всегда дома висел какой-нибудь сервер, который очень хотелось вывести во всеми нами любимый Интернет.
«Ну и что тут сложного? Практически любой провайдер предоставляет статический белый IP за небольшую плату!», – скажите Вы и будете абсолютно правы. Но это платно, да и вообще хотелось попробовать чего-нибудь более оригинального. Основная проблема доступа к моему серверу – NAT. Если вдруг кто не знает, что это, ниже оставил пояснение из Википедии.

NAT

NAT (от англ. Network Address Translation — «преобразование сетевых адресов») — это механизм в сетях TCP/IP, позволяющий преобразовывать IP-адреса транзитных пакетов. Также имеет названия IP Masquerading, Network Masquerading и Native Address Translation.
Преобразование адреса методом NAT может производиться почти любым маршрутизирующим устройством — маршрутизатором, сервером доступа, межсетевым экраном. Наиболее популярным является SNAT, суть механизма которого состоит в замене адреса источника (англ. source) при прохождении пакета в одну сторону и обратной замене адреса назначения (англ. destination) в ответном пакете. Наряду с адресами источник/назначение могут также заменяться номера портов источника и назначения.

Принимая пакет от локального компьютера, роутер смотрит на IP-адрес назначения. Если это локальный адрес, то пакет пересылается другому локальному компьютеру. Если нет, то пакет надо переслать наружу в интернет. Но ведь обратным адресом в пакете указан локальный адрес компьютера, который из интернета будет недоступен. Поэтому роутер «на лету» транслирует (подменяет) обратный IP-адрес пакета на свой внешний (видимый из интернета) IP-адрес и меняет номер порта (чтобы различать ответные пакеты, адресованные разным локальным компьютерам). Комбинацию, нужную для обратной подстановки, роутер сохраняет у себя во временной таблице. Через некоторое время после того, как клиент и сервер закончат обмениваться пакетами, роутер сотрет у себя в таблице запись о n-ом порте за сроком давности.

Если своими словами, это внешний маршрутизатор, позволяющий Вам отправлять запросы в интернет, но не позволяющий Вам их получать. Ответ-то из Интернета Вы получаете, а значит уже не все потеряно. Мне вспомнилась старая программа LogMeIn Hamach, она же позволяла нам обмениваться пакетами данных при том, что ВСЕ клиенты были в закрытой NAT'ом сети. А что, если реализовать что-нибудь подобное:

Вынос локального сервера в сеть с помощью другого внешнего сервера - 1

Что здесь нарисовано? OPI – это моя Orange Pi PC, которая выполняет роль сервера, NAT – это, как несложно догадаться, маршрутизатор моего оператора (он может быть не один, но сути это не меняет), KVM – внешний сервер товарища, CLI – клиент. Возможно, у вас возник вопрос: «По какой причине ты не мог просто выкинуть все свои сервисы на сервер товарища?». Ответ прост: не хочу. В конце концов и дисковое пространство пришлось бы использовать чужое, а меня это не устраивает. Не говоря уже об усложнении администрирования и обслуживания сервера…

OPI подключается к KVM и между ними устанавливается VPN канал. А далее клиент подключается к KVM, и эта машина в свою очередь отправляет запрос через VPN к OPI.
Почему KVM? Сервер товарища – обычный VDS(Virtual Dedicated Server). Обычно это либо KVM (Kernel-based Virtual Machine), либо OVZ (OpenVZ). OVZ в нашем случае не подходит, так как iptables там работают как-то не так, да и вообще штука очень странная.

Настройка сервера

В теории это звучит все здорово, но теперь надо реализовывать на практике. Нужно выбрать протокол для 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 адреса на свои. Проверим, что все работает:

Вынос локального сервера в сеть с помощью другого внешнего сервера - 2

Здорово! Цель достигнута!

Маленькие доработки

Но вдруг в здании, где располагается 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

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js