Каждый выход в интернет не только дает возможность подключаться к различным серверам и сайтам, но и создает потенциальную опасность проникновения на наш компьютер извне. Не стоит пренебрегать этой опасностью. Ситуация усугубляется оттого, что в некоторых (пока еще) широко распространенных операционных системах по умолчанию остаются открытыми многие порты, что позволяет подключаться из интернета к пользователю незаметно для последнего. Поэтому в основу любого фаервола должны быть заложены правила по закрытию и контролированию портов. В нашем случае действуют политики по умолчанию – всё закрыть, открыть извне только то что нам необходимо (“block everything, then open up holes as neccessary“), а также сам шлюз и компьютеры локальной сети могут открывать порты в обратную сторону самостоятельно.
Вот что у меня будет:
3G modem USB (ppp0) со статическим IP 123.456.789.012
Ethernet (eth0) IP 192.168.1.1
Wi-Fi USB (wlan0) IP 192.168.0.1
OpenVPN (tun0) IP 10.8.0.1
Замутил все это дело на вот такой штуке, если интересно Fujitsu-Siemens FUTRO A250
Вообще, это тонкий клиент 🙂 Но я поставил в него CF card 32GB и установил Debian 8.4
Не смотря на то, что ОЗУ всего 256мб, справляется он очень хорошо.
Приступим. Для того чтобы наш шлюз раздавал dns клиентам необходимо поствить dnsmasq, а также на всякий случай убедиться что пакет iptables установлен в системе (хотя я не помню ни одного случая чтобы он по-умолчанию в Debian не был установлен):
# apt-get install dnsmasq
Настраивать dnsmasq никак не надо – если у вас стоит какой-то другой кэшируюший dns-сервер то dnsmasq устанавливать нет необходимости.
Так же нам понадобится DHCP сервер (хотя можно и использовать dnsmasq)
# apt-get install isc-dhcp-server
По настройке isc-dhcp-server можно почитать отдельную статью на этом сайте.
В нашем случае вот примерно как будут выглядеть скрипт настройки iptables:
###################################################################################################
#!/bin/bash
# На всякий случай загрузим модули и включим форвардинг
echo "1" > /proc/sys/net/ipv4/ip_forward
echo "1" > /proc/sys/net/ipv4/ip_dynaddr
modprobe iptable_nat
modprobe ip_conntrack_ftp
modprobe ip_nat_ftp
# Пропишем переменные
export IPT="iptables"
export WAN=ppp0
export WAN_IP=123.456.789.012
export LAN=eth0
export LAN_IP_RANGE=192.168.1.0/24
export WLAN=wlan0
export WLAN_IP_RANGE=192.168.0.0/24
export VPN=tun0
export VPN_IP_RANGE=10.8.0.0/24
export WEBSRV=192.168.1.10
# Сбросим все правила
$IPT -F
$IPT -F -t nat
$IPT -F -t mangle
$IPT -X
$IPT -t nat -X
$IPT -t mangle -X
# Запрещаем ВСЁ
$IPT -P INPUT DROP
$IPT -P OUTPUT DROP
$IPT -P FORWARD DROP
# Разрешаем ВСЁ внутри сети
$IPT -A INPUT -i lo -j ACCEPT
$IPT -A INPUT -i $LAN -j ACCEPT
$IPT -A INPUT -i $WLAN -j ACCEPT
$IPT -A INPUT -i $VPN -j ACCEPT
$IPT -A OUTPUT -o lo -j ACCEPT
$IPT -A OUTPUT -o $LAN -j ACCEPT
$IPT -A OUTPUT -o $WLAN -j ACCEPT
$IPT -A OUTPUT -o $VPN -j ACCEPT
# Оставляем нужные ICMP
$IPT -A INPUT -p icmp -j DROP
$IPT -A INPUT -p icmp --icmp-type echo-reply -j ACCEPT
$IPT -A INPUT -p icmp --icmp-type destination-unreachable -j ACCEPT
$IPT -A INPUT -p icmp --icmp-type time-exceeded -j ACCEPT
$IPT -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
# Разрешаем соединения, которые установлены
$IPT -A INPUT -p all -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPT -A OUTPUT -p all -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
$IPT -A FORWARD -p all -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
# Включаем фрагментацию пакетов. Необходимо из за разных значений MTU
$IPT -I FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
# Отбрасывать все пакеты, которые не могут быть идентифицированы и поэтому не могут иметь определенного статуса.
$IPT -A INPUT -m state --state INVALID -j DROP
$IPT -A FORWARD -m state --state INVALID -j DROP
# Приводит к связыванию системных ресурсов, так что реальный обмен данными становится не возможным.
$IPT -A INPUT -p tcp ! --syn -m state --state NEW -j DROP
$IPT -A OUTPUT -p tcp ! --syn -m state --state NEW -j DROP
# Разрешаем форвардинг внутри сети
$IPT -A FORWARD -i $LAN -o $WAN -j ACCEPT
$IPT -A FORWARD -i $LAN -o $WLAN -j ACCEPT
$IPT -A FORWARD -i $LAN -o $VPN -j ACCEPT
$IPT -A FORWARD -i $WLAN -o $WAN -j ACCEPT
$IPT -A FORWARD -i $WLAN -o $LAN -j ACCEPT
$IPT -A FORWARD -i $WLAN -o $VPN -j ACCEPT
$IPT -A FORWARD -i $VPN -o $WAN -j ACCEPT
$IPT -A FORWARD -i $VPN -o $LAN -j ACCEPT
$IPT -A FORWARD -i $VPN -o $WLAN -j ACCEPT
# И наружу
$IPT -A FORWARD -i $WAN -o $LAN -j REJECT
$IPT -A FORWARD -i $WAN -o $WLAN -j REJECT
$IPT -A FORWARD -i $WAN -o $VPN -j REJECT
# Заворачиваем трафик
$IPT -t nat -A POSTROUTING -s $VPN_IP_RANGE -d $LAN_IP_RANGE -o $LAN -j MASQUERADE
$IPT -t nat -A POSTROUTING -s $VPN_IP_RANGE -d $WLAN_IP_RANGE -o $WLAN -j MASQUERADE
$IPT -t nat -A POSTROUTING -s $LAN_IP_RANGE -o $WAN -j MASQUERADE
$IPT -t nat -A POSTROUTING -s $WLAN_IP_RANGE -o $WAN -j MASQUERADE
$IPT -t nat -A POSTROUTING -s $VPN_IP_RANGE -o $WAN -j MASQUERADE
# Разрешаем порты
$IPT -A INPUT -i $WAN -p tcp --dport 22 -j ACCEPT
$IPT -A INPUT -i $WAN -p tcp --dport 80 -j ACCEPT
$IPT -A INPUT -i $WAN -p udp --dport 1194 -j ACCEPT
$IPT -A INPUT -i $LAN -p tcp --dport 53 -j ACCEPT
$IPT -A INPUT -i $LAN -p udp --dport 53 -j ACCEPT
$IPT -A INPUT -i $WLAN -p tcp --dport 53 -j ACCEPT
$IPT -A INPUT -i $WLAN -p udp --dport 53 -j ACCEPT
# И на десерт – проброс портов 🙂
$IPT -t nat -A PREROUTING -p tcp -d $WAN_IP --dport 8080 -j DNAT --to-destination $WEBSRV:80
$IPT -t nat -A POSTROUTING -p tcp --dst $WEBSRV --dport 8080 -j SNAT --to-source $WAN_IP
# Записываем в конфиг
iptables-save > /etc/iptables.conf
# Выводим все, что получилось
route -n
$IPT -L
$IPT -L -v -n
$IPT -L -v -n -t nat--
###################################################################################################
Теперь сделаем, чтобы правила загружались при запуске системы. Добавим в файл /etc/network/interfaces строчку
post-up iptables-restore < /etc/iptables.conf
Вот и всё. Наслаждаемся 🙂