Привет, лор!
Прочитав работу «Techniques and Countermeasures of TCP-IP OS Fingerprinting on Linux Systems» и мануал Block and Slow Nmap with Firewalls, решил, что нужно разработать шаблон iptables для защиты своих vps-ок. Цель – по возможности скрыть пассивные отпечатки OS, а также фильтрация нежелательных подключений. Работа таблиц тестировалась в том числе и на реликтовом 2.6 ядре.
#!/bin/bash
# 1
iptables -P INPUT DROP
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT
ip6tables -P INPUT DROP
ip6tables -P OUTPUT ACCEPT
ip6tables -P FORWARD ACCEPT
# 2
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X
iptables -N NMAP
iptables -N SSH
# 3
iptables -A INPUT -m state --state ESTABLISHED -j ACCEPT
# 4
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT ! -i lo -s 127.0.0.0/8 -j DROP
iptables -A INPUT -m state --state UNTRACKED,INVALID -j DROP
iptables -t nat -A POSTROUTING -s XX.XX.XX.XX/24 -j SNAT --to-source XX.XX.XX.XX --persistent
iptables -A INPUT -i tun+ ! -s XX.XX.XX.XX/32 -p tcp --dport XXXXX -j REJECT --reject-with tcp-reset
iptables -A INPUT -i tun+ -j ACCEPT
# 5
iptables -A INPUT -p udp --dport XXXXX ! --sport 0 -m state --state NEW ! -f -m u32 --u32 "0>>22&0x3C@5&0xFF=0x38 && 0>>22&0x3C@34=0x3F3" -j ACCEPT
# 6
iptables -A INPUT -m recent --update --seconds 604800 --reap --name nmap -j DROP
# 7
iptables -A INPUT -p tcp -m multiport --dports XXXXX,XXXXX -m tcpmss --mss YYYY -m state --state NEW -j SSH
iptables -A SSH -m recent --update --seconds 604800 --reap --name ssh
iptables -A SSH -m recent --set --name ssh
iptables -A SSH -m limit --limit 1/minute --limit-burst 1 -j ACCEPT
iptables -A SSH -j DROP
# 8
iptables -A INPUT -p icmp --icmp-type 8 -m length --length XXXX -m limit --limit 1/second --limit-burst 1 -j ACCEPT
iptables -A INPUT -p icmp -m limit --limit 1/second --limit-burst 1 -j REJECT --reject-with icmp-host-unreachable
# 9
iptables -A INPUT -p tcp --sport 0 -j NMAP
iptables -A INPUT -p udp --sport 0 -j NMAP
iptables -A INPUT -m state --state NEW -f -j NMAP
iptables -A INPUT -p tcp -m osf --genre NMAP -j NMAP
iptables -A INPUT -p udp -m length --length 20:28 -j NMAP
iptables -A INPUT -p tcp ! --tcp-flags ALL SYN -m state --state NEW -j NMAP
iptables -A INPUT -p tcp --tcp-flags SYN SYN -m state ! --state NEW -j NMAP
iptables -A NMAP -m recent --set --name nmap -j DROP
# 10
iptables -t mangle -A OUTPUT -p tcp -j ECN --ecn-tcp-remove
iptables -t mangle -A OUTPUT -p tcp -j DSCP --set-dscp-class XX
iptables -t mangle -A OUTPUT -p tcp --syn -j TCPMSS --set-mss XXXX
iptables -t mangle -A OUTPUT -p tcp -j TTL --ttl-set 128
iptables -t mangle -A OUTPUT -p udp -j TTL --ttl-set 32
iptables -t mangle -A OUTPUT -p icmp -j TTL --ttl-set 128
# 11
# XXXXX service
iptables -A INPUT -p tcp --dport XXXXX -m state --state NEW -j ACCEPT
iptables -A INPUT -p udp --dport XXXXX -m state --state NEW -j ACCEPT
exit 0
#1 Настройка политик по умолчанию. ipv6 обычно отключена, но
ip6tables -P INPUT DROP
оставляю на случай, если забуду v6 выключить.#2 Очистка таблиц перед настройкой правил.
#3 Подтверждённые соединения больше не фильтруются. Без RELATED всё замечательно работает.
#4 Внутренний трафик должен приходить только с устройства
lo
.-j SNAT
для vpn.! -s XX.XX.XX.XX/32
на некоторые порты доступ закрыт в том числе друзьям внутри виртуальной сети. Остальной трафик внутри vpn-i tun+
принимается без фильтраций.#5 Мне нужен стабильный доступ к vpn даже тогда, когда мой ip-шник занесён в список блокировки (во время тестов такое случается частенько). Есть подключение по vpn – доступ к ssh гарантирован. Так как этот порт не прикрыт чёрным списком, ему назначены дополнительные проверки: первый пакет не должен быть сегментирован, например. Модуль
u32
– это нечто! Оооочень доступный мануал от Bill Stearn здесь. Меня напрягало, что OpenVPN отвечает на обе доступные пробыnmap -sV
. Благо, первый openvpn udp пакет обладает уникальными для каждой конфигурации признаками в зависимости от сгенерированнного Diffie–Hellman ключа.0>>22&0x3C@5&0xFF=0x38
матчится байт-маркер OpenVPN,0>>22&0x3C@34=0x3F3
– бред, чтобы не копировали: здесь правило будет у всех разное, можно только его оставить. Ищется просто с помощью tcpdump, wireshark и т. д. В результате vps-ка больше не отвечает ни на какие пробы запущенной на порту службы.#6 Чёрный список со сроком жизни каждой записи в одну неделю.
#7 К сожалению, первый пакет tcp соединения (ssh) невозможно фильтровать модулем
u32
– пакет обычно пустой, а провайдер режет бит TOS. Поэтому придумал помечать SYN пакеты выставлением--mss
(принимает значения до 1460 включительно). Выбрал нестандартное значение и voil