У меня есть сервер под управлением Linux Mint 12, который я хочу постоянно подключать к PPTP VPN. VPN-сервер довольно надежен, но иногда он падает, поэтому я просто хочу сделать так, чтобы вся интернет-активность была отключена, если VPN-соединение разорвано.
Я также хотел бы найти способ его автоматического перезапуска, но это не такая уж большая проблема, так как это происходит довольно редко.
Я также хочу всегда иметь возможность подключиться к приставке из моей локальной сети, независимо от того, работает VPN или нет.
Вот как выглядит мой ifconfig при правильном подключении VPN:
eth0 Link encap:Ethernet HWaddr 00:22:15:21:59:9a
inet addr:192.168.0.171 Bcast:192.168.0.255 Mask:255.255.255.0
inet6 addr: fe80::222:15ff:fe21:599a/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:37389 errors:0 dropped:0 overruns:0 frame:0
TX packets:29028 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:37781384 (37.7 MB) TX bytes:19281394 (19.2 MB)
Interrupt:41 Base address:0x8000
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:1446 errors:0 dropped:0 overruns:0 frame:0
TX packets:1446 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:472178 (472.1 KB) TX bytes:472178 (472.1 KB)
tun0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
inet addr:10.10.11.10 P-t-P:10.10.11.9 Mask:255.255.255.255
UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1500 Metric:1
RX packets:14 errors:0 dropped:0 overruns:0 frame:0
TX packets:23 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:100
RX bytes:1368 (1.3 KB) TX bytes:1812 (1.8 KB)
Вот сценарий iptables, который я нашел в другом месте, который, казалось, был связан с проблемой, которую я пытаюсь решить, но в итоге он заблокировал весь доступ, но я не уверен, что мне нужно изменить:
#!/bin/bash
#Set variables
IPT=/sbin/iptables
VPN=`ifconfig|perl -nE'/dr:(\S+)/&&say$1'|grep 10.`
LAN=192.168.0.0/24
#Flush rules
$IPT -F
$IPT -X
#Default policies and define chains
$IPT -P OUTPUT DROP
$IPT -P INPUT DROP
$IPT -P FORWARD DROP
#Allow input from LAN and tun0 ONLY
$IPT -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
$IPT -A INPUT -i lo -j ACCEPT
$IPT -A INPUT -i tun0 -m conntrack --ctstate NEW -j ACCEPT
$IPT -A INPUT -s $LAN -m conntrack --ctstate NEW -j ACCEPT
$IPT -A INPUT -j DROP
#Allow output from lo and tun0 ONLY
$IPT -A OUTPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
$IPT -A OUTPUT -o lo -j ACCEPT
$IPT -A OUTPUT -o tun0 -m conntrack --ctstate NEW -j ACCEPT
$IPT -A OUTPUT -d $VPN -m conntrack --ctstate NEW -j ACCEPT
$IPT -A OUTPUT -j DROP
exit 0
Спасибо за вашу помощь.
Эти правила iptables не разрешают трафик к серверу VPN, поэтому VPN не может быть установлен. Вам понадобятся следующие правила в OUTPUT
цепочка перед финалом DROP
правило, где 1.2.3.4 - IP-адрес VPN-сервера. Они позволяют TCP-подключения к порту 1723 (канал управления PPTP) и пакеты GRE (канал данных).
iptables --append OUTPUT --destination 1.2.3.4 --protocol tcp --dport 1723 --jump ACCEPT
iptables --append OUTPUT --destination 1.2.3.4 --protocol gre --jump ACCEPT
Есть два подхода к этому: на основе маршрутизации и на основе межсетевого экрана.
Типичная таблица маршрутизации машины, не подключенной к VPN, выглядит примерно так:
10.23.11.0/24 dev eth0
default via 10.23.11.1
Первый маршрут - к хостам в локальной сети, а второй маршрут отправляет все остальное на шлюз по умолчанию. При подключении к VPN таблица маршрутизации выглядит примерно так (где 1.2.3.4 - публичный IP-адрес VPN-сервера, а 10.8.0.1 - частный IP-адрес VPN-сервера):
10.23.11.0/24 dev eth0
1.2.3.4 via 10.23.11.1
default via 10.8.0.1
Первый маршрут такой же, а третий маршрут - это то, что отправляет все через VPN. Однако обратите внимание на второе правило: в нем говорится, что для доступа к VPN-серверу общедоступные IP-пакеты должны отправляться через шлюз по умолчанию. Это сделано для того, чтобы туннелированные пакеты, созданные клиентом VPN, действительно доходили до сервера; если этот маршрут отсутствует, пакеты, созданные клиентом VPN, будут снова отправлены через VPN и никогда не попадут на сервер.
Теперь, если третий маршрут будет удален, тогда пакеты, предназначенные для любого места в Интернете, кроме VPN-сервера, не будут иметь совпадающего маршрута, и поэтому хост никогда не будет их отправлять. Поэтому мы хотим, чтобы таблица маршрутизации выглядела так, когда VPN не подключен:
10.23.11.0/24 dev eth0
1.2.3.4 via 10.23.11.1
Хосты в локальной сети по-прежнему доступны, и сервер VPN по-прежнему доступен (поскольку нам нужно иметь возможность запустить VPN), но все остальное не будет маршрутизироваться. Однако получить эту настройку может быть немного сложно, особенно если вы используете DHCP. Статическая конфигурация в Debian включает в себя следующее: /etc/network/interfaces
тем не мение:
auto eth0
iface eth0 inet static
address 10.23.11.10
netmask 255.255.255.0
up ip route add 1.2.3.4 via 10.23.11.1
Обратите внимание, что нет gateway
оператор, так как это то, что устанавливает маршрут по умолчанию.
Обратной стороной этого подхода является то, что трафик, не связанный с VPN, к серверу VPN по-прежнему разрешается в незашифрованном виде. Если вы запускаете другие службы на VPN-сервере и вам нужно убедиться, что они защищены, вам придется использовать подход брандмауэра.
редактировать: @JamesRyan предполагает, что этот подход хрупок, потому что маршрут по умолчанию может быть добавлен автоматически или случайно. Другой подход - добавить маршрут черной дыры, который отправляет трафик куда-то, но не направляет его дальше. Однако это не будет работать с автоматически добавляемым маршрутом по умолчанию, потому что он уже использует метрику с наивысшим приоритетом 0. Маршрут по умолчанию все еще необходимо удалить, но затем можно добавить что-то вроде следующего.
default via 127.255.255.255
Идея здесь состоит в том, чтобы заблокировать весь исходящий трафик на физическом интерфейсе, кроме туннелированного трафика, созданного клиентом VPN, и трафика, предназначенного для локальной сети. Объем трафика для VPN зависит от используемого протокола. PPTP использует TCP-порт 1723 в качестве канала управления, и GRE как собственно туннель. OpenVPN использует порт UDP 1194. Правила брандмауэра будут выглядеть примерно так:
iptables --append OUTPUT --out-interface eth0 --destination 10.23.11.0/24 --jump ACCEPT
iptables --append OUTPUT --out-interface eth0 --destination 1.2.3.4 --protocol tcp --dport 1723 --jump ACCEPT
iptables --append OUTPUT --out-interface eth0 --destination 1.2.3.4 --protocol gre --jump ACCEPT
iptables --append OUTPUT --out-interface eth0 --jump REJECT
Первое правило принимает трафик для LAN. Второе и третье правила принимают VPN-трафик на VPN-сервер. Четвертое правило отклоняет весь другой трафик, покидающий физический интерфейс.
Еще одна вещь, которую вам может потребоваться принять, - это DNS, если вы используете DNS-сервер не в локальной сети, потому что клиенту VPN, вероятно, потребуется выполнить поиск DNS, чтобы найти сервер VPN. Следующее правило вставлено перед REJECT
разрешит трафик DNS к общедоступной службе DNS Google.
iptables --append OUTPUT --out-interface eth0 --destination 8.8.8.8 --protocol udp --dport 53 --jump ACCEPT
Добавьте еще один маршрут по умолчанию с более высокой метрикой, указывающий на нулевой интерфейс. Когда VPN недоступен, сработает второй маршрут и заблокирует трафик.
Это не квест iptables - для этого вам не нужны iptables.
Просто установите маршрут по умолчанию для прохождения через VPN, и все готово. Вы также можете добавить другой маршрут по умолчанию с худшей метрикой для использования, когда VPN не работает.
Ваша локальная сеть подключена напрямую, поэтому она имеет приоритет над шлюзом по умолчанию.