Pull to refresh

Как настроить Firewall для VPN-а на сервере с двумя IP

Reading time 6 min
Views 14K
image

Я наконец-то завёл себе сервер. На нем разместил сайт своей «компании», а по соседству решил поднять VPN. Для этого был заказан второй IP. На первом у меня будет web, mail, ssh а с второго будет ходить VPN трафик. Задумка простая, но хорошего описания такой конфигурации я так и не нашел. Под катом, я покажу как настроить Shorewall чтобы VPN трафик шел только в интернет, и не мог свободно проходить на соседний IP.

В этом посте я хочу сделать фокус не на установку всех программ, это было описано много раз в том числе и на хабре, а на настройку firewall-a для ситуации когда все сетевые интерфейсы у нас на одной карте. Для управления firewall-ом я буду использовать пакет Shorewall. На сайте у shorewall-a довольно много документации, но она описывает в основом конфигурации с разделными сетевыми картами, и подсетями лежащими за ними.

Давайте сперва посмотрим на ifconfig. Там мы видим два наших IP-шника, «1.1.1.1» и «2.2.2.2». Они оба идут напрямую в интернет. Сейчас они «близнецы», то есть если какой-нибудь сервис крутится на первом, он будет виден и на втором IP.

# ifconfig
eth0      Link encap:Ethernet  HWaddr хх:хх:хх:хх:хх:хх
          inet addr:1.1.1.1  Bcast:1.1.1.255  Mask:255.255.255.0
          inet6 addr: fe80::ххх:хххх:хххх:хххх/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:417428 errors:0 dropped:230 overruns:0 frame:0
          TX packets:17595 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:28249193 (28.2 MB)  TX bytes:4653027 (4.6 MB)

eth0:0    Link encap:Ethernet  HWaddr хх:хх:хх:хх:хх:хх
          inet addr:2.2.2.2  Bcast:2.2.2.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1

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:16436  Metric:1
          RX packets:507 errors:0 dropped:0 overruns:0 frame:0
          TX packets:507 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:44121 (44.1 KB)  TX bytes:44121 (44.1 KB)

Давайте это дело прикроем, так чтобы 1.1.1.1 пропускал на web, email, ssh, а 2.2.2.2 слушал vpn. Вот такая конфигурация:

# cat /etc/shorewall/interfaces
#ZONE   INTERFACE       BROADCAST       OPTIONS
net4    eth0            detect          tcpflags,logmartians,nosmurfs

# cat /etc/shorewall/zones
#ZONE   TYPE            OPTIONS         IN                      OUT
fw      firewall
net4    ipv4

# cat /etc/shorewall/policy
#SOURCE DEST    POLICY          LOG     LIMIT:          CONNLIMIT:
$FW     net4    ACCEPT
net4    $FW     DROP            info
net4    all     DROP            info
# The FOLLOWING POLICY MUST BE LAST
all     all     REJECT          info

# cat /etc/shorewall/rules
#ACTION         SOURCE          DEST            PROTO   DEST    SOURCE
SECTION NEW
# ------------------------- INTERNET --------------------------------
ACCEPT          net4            $FW:1.1.1.1      tcp     22
ACCEPT          net4            $FW:1.1.1.1      tcp     25
ACCEPT          net4            $FW:1.1.1.1      tcp     80
# ------------------------- VPN -------------------------------------
ACCEPT          net4            $FW:2.2.2.2      udp     1194

Это стандартная конфигурация, которая пропускает весь трафик с нашего VPS-a в интернет, а назад не пускает ничего, кроме того что прописано в rules. Под зоной $FW, подразумеваются оба IP, так как оба являются частью eth0 (не смотря на то что у 2.2.2.2 есть своё имя eth0:0). Для уточнения используются кострукции типа: $FW:[ip]. Вроде всё нормально. Тогда, запускаем VPN сервер, и смотрим ifconfig. Помимо того что там уже было, появился новый interface tun0:

tun0      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
          inet addr:10.8.0.1  P-t-P:10.1.0.2  Mask:255.255.255.255
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1500  Metric:1
          RX packets:3261 errors:0 dropped:0 overruns:0 frame:0
          TX packets:2624 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:100
          RX bytes:351155 (351.1 KB)  TX bytes:1043254 (1.0 MB)

заметьте, что интерфейс tun0 не является «близнецом» с eth0, а представляет из себя более полноценный интефейс. За этой подсетью будут сидеть VPN клиенты. Давайте подсоединимся прямо сеичас. На другом компе: проходим авторизацию, соеденение установлено, идем в терминал и пробуем подсоединится хотя бы нашему vpn gateway (10.8.0.1) чтобы почитать почту, можно пинговать если пинги принимаются (см. /etc/sysctl.conf).

$telnet 10.8.0.1 25
$sudo tail /var/log/syslog
... Shorewall:INPUT:REJECT:IN=tun0 OUT= MAC= SRC=10.8.0.6 DST=10.8.0.1 ... PROTO=TCP SPT=36879 DPT=25 ...

Наша попытка зайти на mail сервер была отвергнута, из за того что, не являсь «близнецом» eth0, tun0 не можем говорить с eth0 (и eth0:0) из за правила:

all     all     REJECT          info

в конце /etc/shorewall/policy. Пока все правильно. Тогда добавим tun0 в shorewall.
Новая конфигурация:

# cat /etc/shorewall/interfaces
#ZONE   INTERFACE       BROADCAST       OPTIONS
net4    eth0            detect          tcpflags,logmartians,nosmurfs
vpn4    tun0            detect          tcpflags,logmartians,nosmurfs              #NEW

# cat /etc/shorewall/zones
#ZONE   TYPE            OPTIONS         IN                      OUT
fw      firewall
net4    ipv4
vpn4    ipv4         #NEW

# cat /etc/shorewall/policy
#SOURCE DEST    POLICY          LOG     LIMIT:          CONNLIMIT:
$FW     net4    ACCEPT
vpn4    $FW     ACCEPT            #NEW
vpn4    net4     ACCEPT            #NEW
net4    $FW     DROP            info
net4    all     DROP            info
# The FOLLOWING POLICY MUST BE LAST
all     all     REJECT          info

# cat /etc/shorewall/rules
#ACTION         SOURCE          DEST            PROTO   DEST    SOURCE
SECTION NEW
# ------------------------- INTERNET --------------------------------
ACCEPT          net4            $FW:1.1.1.1      tcp     22
ACCEPT          net4            $FW:1.1.1.1      tcp     25
ACCEPT          net4            $FW:1.1.1.1      tcp     80
# ------------------------- VPN -------------------------------------
ACCEPT          net4            $FW:2.2.2.2      udp     1194

# SNAT, for access to internet -- NEW
# cat /etc/shorewall/masq
#INTERFACE              SOURCE          ADDRESS         PROTO   PORT(S) IPSEC   MARK
eth0                   10.8.0.0/24     2.2.2.2

Что изменилось? Мы создали зону под именем vpn4 которая соответствует интерфейсу tun0. Мы декларировали vpn4 как IPv4. Мы разрешили трафику из tun0 доходить до firewall-а, и до интернета (eth0/net4). Как ни странно, нельзя разрешить только до firewall-a, а дальше по существующему правилу $fw -> net4. Надо добавить обе строки. И последнее что нам надо для полноценного выхода в интернет, это SNAT (source address translation, когда подменяется адрес отправителя на адрес смотрящии в интернет, в нашем случае 2.2.2.2). Создаем файл masq и требуем там замены всех адресов 10.8.0.х на 2.2.2.2 при выходе из eth0 (и eth0:0).

Пробуем… Всё работает! Даже слишком… с адресом из 10.8.0.х можно заходить на 1.1.1.1:1194, чего мы никак не хотим. Мы хотели чтобы vpn трафик сперва выходил в интернет а потом бился назад через firewall. Вместо этого мы имеем vpn клиента который смотрит на наш сервер видом сзади. Почему? Потому что когда мы разрешили коммуникации типа:

# /etc/shorewall/policy:
vpn4    $FW     ACCEPT            #NEW

мы не уточнили на какой именно IP, так как под $FW их два (1.1.1.1 и 2.2.2.2). Ну ладно, давайте пропишем. Ан-нет, синтаксис типа: $FW:[ip] в файле policy не принемается. На этом моменте я перепробовал много всего и почти бросил затею и оставил как есть. Хотя до конца пути было очень мало. Итак, озарение: все что прописывается в policy можно точно также прописать в rules, а в rules мы можем указывать конкретные IP на firewall-e. Давайте перепишем, последняя конфигурация:

# cat /etc/shorewall/interfaces
#ZONE   INTERFACE       BROADCAST       OPTIONS
net4    eth0            detect          tcpflags,logmartians,nosmurfs
vpn4    tun0            detect          tcpflags,logmartians,nosmurfs

# cat /etc/shorewall/zones
#ZONE   TYPE            OPTIONS         IN                      OUT
fw      firewall
net4    ipv4
vpn4    ipv4

# cat /etc/shorewall/policy
#SOURCE DEST    POLICY          LOG     LIMIT:          CONNLIMIT:
$FW     net4    ACCEPT
#vpn4    $FW     ACCEPT            #NEW
#vpn4    net4     ACCEPT            #NEW
net4    $FW     DROP            info
net4    all     DROP            info
# The FOLLOWING POLICY MUST BE LAST
all     all     REJECT          info

# cat /etc/shorewall/rules
#ACTION         SOURCE          DEST            PROTO   DEST    SOURCE
SECTION NEW
# ------------------------- INTERNET --------------------------------
ACCEPT          net4            $FW:1.1.1.1      tcp     22
ACCEPT          net4            $FW:1.1.1.1      tcp     25
ACCEPT          net4            $FW:1.1.1.1      tcp     80
# ------------------------- VPN -------------------------------------
ACCEPT          net4            $FW:2.2.2.2      udp     1194
# ------------------------- NEW -------------------------------------
ACCEPT          vpn4            net4
ACCEPT          vpn4            $FW:1.1.1.1      tcp     22
ACCEPT          vpn4            $FW:1.1.1.1      tcp     25
ACCEPT          vpn4            $FW:1.1.1.1      tcp     80

# cat /etc/shorewall/masq
#INTERFACE              SOURCE          ADDRESS         PROTO   PORT(S) IPSEC   MARK
eth0                   10.8.0.0/24     2.2.2.2

Что мы сделали: убрали старые разрешения из policy, и добавили разрешения в rules. Мы разрешаем весь трафик из vpn в интернет, и выборочно разрешаем трафик непосредственно на 1.1.1.1. А через интернет заходы на 1.1.1.1 послать нельзя? Нет, как бы нам ни хотелось они будут идти внутри сервера, поетому лучшее что мы можем, это продублировать правила для интернета для трафика vpn -> 1.1.1.1. А как же трафик на 2.2.2.2? Этот трафик непосредвенно и есть vpn трафик, и он не может приходить изнутри (это обсепечивается route-ом на клиентской машине). В других словах, клиент vpn-a никогда не пришлет трафик по направлению 10.8.0.1(vpn4) -> 2.2.2.2($fw:2.2.2.2).

Ну вот в принципе и все. Теперь мы можем спокойно браузить с «рабочего» VPN-a без использования IP-шника ведущего на «компанейский» сайт, и не боятся за обход firewall-a обычными vpn юзерами.
Tags:
Hubs:
+3
Comments 4
Comments Comments 4

Articles