Домашний сервер с Debian — Firewall + NAT

Появилось сегодня настроение «покрутить за настройки» свой домашний сервер с Debian Lenny на борту 🙂 С чего бы это вдруг … даже не спрашивайте — чето захотелось срочно поадминить 😀 Ну чтоже настраивать то? Вроде и так все работает и даже кушать не просит! Однакоже, давно мне не давала покоя мысль что firewall у меня дома, ну вообще не по фэншую настроен. Чего только стоит default policy ACCEPT во всех цепочках 😀 Из умений нынешних стоит отметить лиш NAT — работает исправно, не ломался пока еще, и вообще проблем никаких. Вот так вот … на работе сижу вылизываю все, а дома когдато поднял по быстрячку, лиш бы работало — и сплю спокойно! Все как обычно — сапожник без сапог … но это поправимо! Вот, собственно, нашелся обьект «донастройки»? Вполне подойдет, подумалось мне, и взялся я за него основательней!

Итак, задача видется мне так:

1. Улучшить защиту домашнего сервера со стороны интернета

  • перейти на Default Policy — DROP в цепочках INPUT и FORWARD
  • дать доступ к серверу из интернета только на такие сервисы DNS, HTTP, SSH

2. Роздать интернет клиенту из внутрисети, имея настройки:

  • внешний фиксированный ipaddress сервера — 123.123.123.123
  • ipaddress/netmask внутреннего интерфейса — 192.168.0.1/24
  • ipaddress/netmask клиента — 192.168.0.3/24 (в последствии дал доспут по mac address чтобы не зависеть от ip)

3. Предоставить доступ клиенту из внутрисети ко всем доступным на сервере сервисам (samba, imap, ssh, smtp, http)

4. Пробросить порты tcp {4662} и udp {4672, 4665} из внешнего интерфейса сервера на клиента. Открываем «прямой» доступ из интернет для amule на клиенте, ато с low id много не накачаеш 😉

Ну чтож, вроде все вполне очевидно — клиент должен ходить везде (весь интернет + сервисы на домашнем сервере), а из интернета на сервер можно попасть только на порты ssh (мне же нужна админская ходка), на apache (лежит несколько сайтов) и на DNS (чтобы отрезолвить несколько моих и неочень зон).

Для того чтобы все это организовать, достаточно одной только программы — iptables. Нужно также знать, что iptables можно «поднимать» по разному. Можно запускать как сервис при старте системы, а можно только при поднятии интерфейсов скриптом. А если заморочиться … то по любому пришедшему в голову системному событию (параноидальная мысль) 🙂 Я выбрал вариант включения фаервола скриптом с нужными правилами при поднятии сетевых интерфейсов.
В этом случае, скриптик приведенный ниже, надо положить в /etc/network/if-pre-up/ Даже видно из названия директории в которую я его поместил, что он запустится перед поднятием сетевых интерфейсов. Название дал ему 00-snat, вы можете назвать как пожелаете. Главное чтобы у него был бит X — тоесть розрешен запуск. Итак, скрипт:

#!/bin/sh
### - Delete All Rules - ###
iptables -F
iptables -F -t nat
### - Rules For IP from INET - ###
iptables -N from_inet
iptables -A from_inet -p tcp -m conntrack --ctstate NEW,INVALID --tcp-flags SYN,ACK SYN,ACK -j REJECT --reject-with tcp-reset
iptables -A from_inet -p tcp -m multiport --dports 22,53,80 -j ACCEPT
iptables -A from_inet -p udp -m multiport --dports 53 -j ACCEPT
iptables -A from_inet -p icmp --icmp-type 8 -j ACCEPT
#iptables -N from_lan
#iptables -A from_lan -p tcp -m multiport --dports 22,53,80,139,445 -j ACCEPT
#iptables -A from_lan -p udp -m multiport --dports 53,137,138 -j ACCEPT
#iptables -A from_lan -p icmp -j ACCEPT
#iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -i eth0 -j from_inet
### - Rules For IP from LAN - ###
#iptables -A INPUT -i eth1 -j from_lan
iptables -A INPUT -i eth1 -j ACCEPT
### - FWD Rules - ###
iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -m mac --mac-source 00:CC:AA:FF:AA:FF -j ACCEPT
iptables -A FORWARD -p tcp -d 192.168.0.3 --dport 4662 -j ACCEPT
### - NAT - ###
iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -o eth0 -j SNAT --to-source 123.123.123.123
### - Default Policies - ###
iptables -P INPUT DROP
iptables -P OUTPUT ACCEPT
iptables -P FORWARD DROP
## - DNAT for AMule - ###
iptables -t nat -A PREROUTING -i eth0 -p tcp --destination-port 4662 -j DNAT --to-destination 192.168.0.3:4662
iptables -t nat -A PREROUTING -i eth0 -p udp --destination-port 4672 -j DNAT --to-destination 192.168.0.3:4672
iptables -t nat -A PREROUTING -i eth0 -p udp --destination-port 4665 -j DNAT --to-destination 192.168.0.3:4665

Даем права на запуск:

# chmod +x /etc/network/if-pre-up/00-snat

Вот такой скрипт 🙂 Ничего сложного и непонятного тут нету. Все предельно просто.

Как видите есть даже заготовка для случая с недоверенной локальной сетью. Если необходимо — просто розкомментируйте все что касается from_lan и закомментируйте правило:

#iptables -A INPUT -i eth1 -j ACCEPT

В результате все что придет на внутренний интерфейс сервера в цепочку INPUT будет направляться в цепочку from_lan и обрабатываться ее правилами, а уж что неполучит ACCEPT в цепочке from_lan, согласно default police для INPUT, будет молча игнорироваться — DROP! Тоесть мы получим еще и полный контроль над траффиком который приходит из внутрисети непосредственно на внутренний интерфейс сервера 🙂

Кроме того, я заморочился, и разрешил forwarding только для одного mac адреса — конечно, клиентского. Чегото захотелось выпендриться. Можете смело заменить на правило с ip, а то что с mac убрать 🙂

Тоесть, заменяем вот это правило с mac address:

iptables -A FORWARD -m mac --mac-source 00:CC:AA:FF:AA:FF -j ACCEPT

На правило с конкретным ip (если доступ нужно дать только одному клиенту) :

iptables -A FORWARD -s 192.168.0.3 -j ACCEPT

Или на приавило вида ip/mask (если доступ надо дать целой подсети):

iptables -A FORWARD -s 192.168.0.0/24 -j ACCEPT

Ну вот и все! Скажу лиш напоследок, что данный набор правил работает у меня дома вполне исправно уже несколько месяцев. К томуже, написан весьма прозрачно для дополнительных правок, поэтому легко можно модифицировать и под более сложные задачи 😉

Также замечу, что для еще большей безопасности, использую программку fail2ban которая очень эффективно защищает от атак называемых bruteforce. После нескольких неверных попыток авторизации или поиска у нас на сервере чегото непонятно чего (Error 404 в Apache) клиент блочится фаерволом на определенный промежуток времени. Все это достаточно тонко настраивается, может напишу в следующих заметках. Данная утилитка позволяет защищать сервер от какеров которые пытаются сломать ssh, apache, dovecot, разные ftp и много всего (правила для срабатывая блокировки описываются перловыми regexp-ами — это дает нам возможность защитить что угодно при условии наличия логов).

За сим все … всем удачи и супер-пупер безопасности! И чтобы спалось спокойно ….

    • Judest
    • Февраль 3rd, 2011 8:37пп

    Спасибо за статью. Надо будет как-нибудь и своим сервером заняться, да добавить в него функцию маршрутизатора.

    • admin
    • Февраль 4th, 2011 9:07дп

    Обязательно займитесь! Сервер … он как ребенок, когда уделяеш ему мало внимания — начинает капризничать 😀

    • Charlz_Klug
    • Март 14th, 2011 7:24пп

    imil@Adminassistant:~$ sudo ifconfig
    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:12 errors:0 dropped:0 overruns:0 frame:0
    TX packets:12 errors:0 dropped:0 overruns:0 carrier:0
    collisions:0 txqueuelen:0
    RX bytes:800 (800.0 B) TX bytes:800 (800.0 B)

    ppp0 Link encap:Point-to-Point Protocol
    inet addr:192.167.28.160 P-t-P:192.168.1.1 Mask:255.255.255.255
    UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1500 Metric:1
    RX packets:103 errors:1 dropped:0 overruns:0 frame:0
    TX packets:222 errors:0 dropped:0 overruns:0 carrier:0
    collisions:0 txqueuelen:3
    RX bytes:56638 (55.3 KiB) TX bytes:24267 (23.6 KiB)

    vbox0 Link encap:Ethernet HWaddr 00:ff:75:c8:a1:9b
    inet addr:192.168.0.2 Bcast:192.168.0.255 Mask:255.255.255.0
    inet6 addr: fe80::2ff:75ff:fec8:a19b/64 Scope:Link
    UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
    RX packets:184 errors:0 dropped:0 overruns:0 frame:0
    TX packets:119 errors:0 dropped:101 overruns:0 carrier:0
    collisions:0 txqueuelen:500
    RX bytes:37646 (36.7 KiB) TX bytes:17472 (17.0 KiB)

    Есть ещё в VirtualBox машина с Windows XP SP3. Хочу этой машине с Debian’а дать интернет. Настройки гостевой операционной системы:
    C:\Documents and Settings\root>ipconfig

    Настройка протокола IP для Windows

    Подключение по локальной сети 2 — Ethernet адаптер:

    DNS-суффикс этого подключения . . :
    IP-адрес . . . . . . . . . . . . : 192.168.0.1
    Маска подсети . . . . . . . . . . : 255.255.255.0
    Основной шлюз . . . . . . . . . . : 192.168.0.2

    C:\Documents and Settings\root>

    На Debian сделал следующее:
    imil@Adminassistant:~$ sudo iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -o ppp0 -j MASQUERADE
    imil@Adminassistant:~$

    Но:
    C:\Documents and Settings\root>ping ya.ru
    При проверке связи не удалось обнаружить узел ya.ru. Проверьте имя узла и повтор
    ите попытку.

    C:\Documents and Settings\root>

    В свойствах виртуальной машины указано подключение к Хост-интерфейсу. Подскажите, пожалуйста, что я делаю не так?

    • admin
    • Март 14th, 2011 9:46пп

    В настройках самого виртуалбокса сетевуха для WinXP стоит в режиме моста или ната?

    • Charlz_Klug
    • Март 15th, 2011 7:57дп

    Здесь скриншот: «http://s42.radikal.ru/i096/1103/7c/b568ebba0190.jpg». Я не уверен, но должно быть в режиме моста. VirtualBox версии 1.6.6. Может обновить?

    • admin
    • Март 16th, 2011 9:45дп

    Поставьте режим моста или NAT (смотря что вам нужно) и попробуйте. При этом ничего ненадо добавлять руками в правила iptables (VirtualBox все должен сделать сам)

    • Charlz_Klug
    • Март 24th, 2011 2:03пп

    Значит, так: Обновился с Lenny до Squeeze. Соответственно, обновил и VirtualBox. Теперь у меня он версии 3.2.10_OSE r66523. Не без бубна обошлось. Была проблема с сетью. Но и их решил. Далее, выставил в гостевой WinXP «Получать IP автоматически», то бишь с DHCP. А в настройках VirtualBox выставил NAT. Теперь всё работает! Спасибо Вам за подсказку.

  1. Трэкбэков пока нет.

Why ask?