W moim skrypcie iptables eksperymentowałem z pisaniem tak precyzyjnych reguł, jak to tylko możliwe. Ograniczam, którzy użytkownicy mogą korzystać z których usług, częściowo ze względów bezpieczeństwa, a częściowo jako ćwiczenie edukacyjne.
Używanie iptables v1.4.16.2 na Debianie 6.0.6 z uruchomionym jądrem 3.6.2.
Jednak natrafiłem na problem, którego jeszcze nie rozumiem ...
porty wychodzące dla wszystkich użytkowników
Działa to doskonale. Nie mam żadnych ogólnych reguł śledzenia stanu.
## Port wychodzący 81 $ IPTABLES -A WYJŚCIE -p tcp --port 81 -m conntrack --ctstate NOWOŚĆ, USTANOWIONO -j AKCEPTUJ $ IPTABLES -A WEJŚCIE -p tcp --sport 81 -s $ MYIP -m conntrack --ctstate USTANOWIONO -j AKCEPTUJ
porty wychodzące z dopasowaniem użytkownika
## port wychodzący 80 dla konta użytkownika $ IPTABLES -A WYJŚCIE - właściciel dopasowania - konto-właściciel konto użytkownika -p tcp --port 80 -m conntrack --ctstate NOWOŚĆ, USTALONY --sport 1024: 65535 -j AKCEPTUJ $ IPTABLES -A WEJŚCIE -p tcp --sport 80 --port 1024: 65535 -d $ MYIP -m conntrack --ctstate USTANOWIONO -j AKCEPTUJ
Pozwala to na port 80 tylko dla konta „konto użytkownika”, ale takie reguły dla ruchu TCP mają problemy.
## Domyślny dziennik wychodzący + reguły blokowania $ IPTABLES -A WYJŚCIE -j LOG - log-prefiks „BAD OUTGOING” --log-ip-options --log-tcp-options --log-uid $ IPTABLES -A WYJŚCIE -j DROP
Problem
Powyższe działa, użytkownik „konto użytkownika” może uzyskać pliki doskonale. Żaden inny użytkownik w systemie nie może nawiązywać połączeń wychodzących z portem 80.
useraccount @ host: $ wget http://cachefly.cachefly.net/10mb.test
Ale powyższy wget pozostawia x7 porzucone wpisy w moim syslog:
18 października 02:00:35 xxxx jądro: BAD OUTGOING IN = OUT = eth0 SRC = xx.xx.xx.xx DST = 205.234.175.175 LEN = 40 TOS = 0x00 PREC = 0x00 TTL = 64 ID = 12170 DF PROTO = TCP SPT = 37792 DPT = 80 SEQ = 164520678 ACK = 3997126942 WINDOW = 979 RES = 0x00 ACK URGP = 0
Nie dostaję tych kropli dla podobnych reguł dla ruchu UDP. Mam już zasady, które ograniczają użytkowników, którzy mogą wysyłać żądania DNS.
Porzucone wychodzące pakiety ACK wydają się pochodzić z konta głównego (URGP = 0), czego nie rozumiem. Nawet kiedy zamieniam konto użytkownika na root.
Uważam, że pakiety ACK są klasyfikowane jako nowe, ponieważ conntrack rozpoczyna śledzenie połączeń po 3 kroku uzgadniania w 3 kierunkach, ale dlaczego są one odrzucane?
Czy te krople można bezpiecznie zignorować?
Edytować
Często więc widzę takie zasady, które działają dla mnie dobrze:
$ IPTABLES -A WYJŚCIE -s $ MYIP -p tcp -m tcp --port 80 -m stan - stan NOWY, USTANOWIONY -j AKCEPTUJ $ IPTABLES -A WEJŚCIE -p tcp -m tcp --sport 80 -d $ MYIP -m stan - stan USTANOWIONO -j AKCEPTUJ
Zamieniłem „-m state --state” na „-m conntrack --ctstate”, ponieważ dopasowanie stanu jest najwyraźniej nieaktualne.
Czy najlepszą praktyką jest stosowanie ogólnych reguł śledzenia stanu? Czy powyższe zasady nie są uważane za prawidłowe?
Czy dla lepszej kontroli połączeń wychodzących użytkowników byłoby coś takiego?
$ IPTABLES -A WEJŚCIE -m conntrack --ctstate USTANOWIONO -j AKCEPTUJ $ IPTABLES -A WYJŚCIE -m conntrack --ctstate USTANOWIONO -j AKCEPTUJ $ IPTABLES -A WYJŚCIE -p tcp --port 80 -s $ SERVER_IP_TUNNEL -m conntrack --ctstate NOWOŚĆ -m właściciel - rachunek-właściciela konto użytkownika -j AKCEPTUJ $ IPTABLES -A WYJŚCIE -p tcp --port 80 -s $ SERVER_IP_TUNNEL -m conntrack --ctstate NOWOŚĆ -m właściciel --uid-właściciel inne konto -j AKCEPTUJ