Я наконец-то завёл себе сервер. На нем разместил сайт своей «компании», а пососедству решил поднять 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 юзерами.
Автор: kacang