Nie jesteś zalogowany.
Jeśli nie posiadasz konta, zarejestruj je już teraz! Pozwoli Ci ono w pełni korzystać z naszego serwisu. Spamerom dziękujemy!
Prosimy o pomoc dla małej Julki — przekaż 1% podatku na Fundacji Dzieciom zdazyć z Pomocą.
Więcej informacji na dug.net.pl/pomagamy/.
Witam
Planuję uruchomić stronę www na Apache i Debianie z dostępem przez ssh. Napisałem prosty firewall w oparciu o iptables. Chciałbym poznać Wasze opinie oraz czy coś powinienem ewentualnie poprawić.
#!/bin/sh IPTABLES=/sbin/iptables $IPTABLES -F $IPTABLES -P INPUT DROP $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P FORWARD DROP $IPTABLES -A INPUT -m state –state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -o eth0 -m state --state ESTABLISHED,RELATED -j ACCEP $IPTABLES -A INPUT -p tcp -i eth0 --dport 22 --sport 1024:65535 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -p tcp -i eth0 --dport 80 --sport 1024:65535 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -p tcp -i eth0 --dport 443 --sport 1024:65535 -m state --state NEW -j ACCEPT
Offline
Ogólnie jak na początek całkiem ładny, jednak pare małych uwag:
1. Koniecznie, koniecznie zmień port na którym działa SSH na jakiś inny. Najlepiej coś powyżej 20000
2. Literówka w nazwie skoku w łańcuchu OUTPUT (ACCEP zamiast ACCEPT)
3. Poczytaj o modułach iptables o nazwie recent i limit. Przydałoby się zrobić jakieś limity jednoczesnych połączeń per IP, albo ilość pakietów TCP z flagą SYN na początek (takie drobne utrudnienie na drodze zrobienia kuku maszynie)
4. Wpuść pakiet ICMP typu 8, czyli ping request. Miło gdy serwer odpowiada na pingi.
5. Dorób limitowanie tych pakietów, żebyś nie dostał ich 40 tysięcy w sekundę :P
6. Jeżeli masz możliwość (tzn jest to maszyna fizyczna, albo pełna wirtualizacja, nie kulawy OpenVZ) zainteresuj się tym co kryje się w paczkach xtables-addons i ipset.
7. Wpuszczenie ruchu na interfejsie loopback (lo) by nie zaszkodziło, niekiedy rzeczy lubią się sypać gdy tego nie ma.
8. Poczekaj na Jacekalex'a, ten Pan ma zawsze miliony pomysłów ;)
Offline
Dorzuć sobie jeszcze to:
/sbin/iptables -A INPUT -p tcp -j REJECT --reject-with tcp-reset /sbin/iptables -A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable /sbin/iptables -A INPUT -j REJECT --reject-with icmp-proto-unreachable
Jeszcze się nie zagłębiałem w iptables i nie wiem po co to, ale w każdym fw to dodają. xD
Offline
morfik napisał(-a):
Dorzuć sobie jeszcze to:
Kod:
/sbin/iptables -A INPUT -p tcp -j REJECT --reject-with tcp-reset /sbin/iptables -A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable /sbin/iptables -A INPUT -j REJECT --reject-with icmp-proto-unreachableJeszcze się nie zagłębiałem w iptables i nie wiem po co to, ale w każdym fw to dodają. xD
Gratuluję fachowej ekspertyzy... :D
Te regułki mają inaczej odrzucać połączenia, odsyłając pakiet ICMP z odpowiednią informacją, przeważnie w ten sposób ukrywa się usługi albo istnienie serwera.
Przy serwerze www niezbyt sensowne i niezbyt potrzebne, skoro i tak z portu 80 można się dowiedzieć dokładnie co to za system i jaki serwer, przy pomocy np nikto.
Ja bym wywalił ssh na jakiś losowy port i dał na nim limity połączeń, bardzo scisłe przy pomocy hashlimit.
np coś w ten deseń:
iptables -I INPUT -m hashlimit -m tcp -p tcp --dport {port_ssh} --hashlimit 1/min --hashlimit-mode srcip --hashlimit-name ssh -m state –state NEW -j ACCEPT
Sznurek:
http://blog.serverbuddies.com/using-hashlimit-in-iptables/
Identycznie bym obciął przy pomocy hashlimit i connlimit inne usługi, dopasowując limity połączeń i nowych połączeń do oczekiwanych i akceptowalnych dla serwera www i innych usług.
Np tak kiedyś robiłem do malutkiego serwera pocztowego z Qmailem na pokładzie, usługa SMTP:
iptables -N SMTP # osobny łancuch dla uslugi. iptables -A SMTP ! -i lo -m state --state NEW -m set --match-set spamhaus src -j STEAL iptables -A SMTP ! -i lo -m state --state NEW -m set --match-set sblamdrop src -j STEAL iptables -A SMTP ! -i lo -m connlimit --connlimit-upto 10 --connlimit-mask 0 --connlimit-saddr -m hashlimit --hashlimit-upto 1/min --hashlimit-burst 1 --hashlimit-mode srcip --hashlimit-name smtp -j ACCEPT iptables -A INPUT ! -i lo -p tcp -m multiport --dports 25,465,587 -j SMTP
A tutaj Ejabberd server2server:
iptables -A INPUT ! -i lo -p tcp --dport 5269 -m connlimit --connlimit-upto 10 --connlimit-mask 0 --connlimit-saddr -m hashlimit --hashlimit 5/min --hashlimit-burst 5 --hashlimit-mode srcip --hashlimit-name xmpp -j ACCEPT
Wszystkie reguły i konfiguracje najpierw testuj w domu, żeby jakiegoś przypału nie było, jeśli serwer stoi np na księżycu, albo jeszcze dalej. :D
Sznurki:
http://pl.wikibooks.org/wiki/Sieci_w_Linuksie/Netfilter
http://jacekalex.sh.dug.net.pl/Iptables-packet-flow.png
Pozdro
;-)
Ostatnio edytowany przez Jacekalex (2013-06-25 17:26:21)
Online
ICMP jest ważne dla wielu protokołów diagnostycznych, dlatego też nie zalecałbym jego pełnego wyłączenia. Wg mnie powinny być przynajmniej puszczone typy unreach(3), echoreq(8) oraz już nie w pełni konieczne timex(11)
Offline
jak zwykle @jacek świetnie wyjaśnił. Podłączę się do pytania, bo jest troszkę zbliżone. Jak przetestować swoje ustawienia? czy jest jakiś skaner który zasymulował by mi tyle skanów czy ataków na SSH i inne porty ?
Jest coś takiego?
Offline
Dziękuje za informację, stworzyłem następną wersję, do zabezpiecznia ssh planuje portsentry "zatrudnić"
#!/bin/sh IPTABLES=/sbin/$IPTABLES $IPTABLES -F $IPTABLES -P INPUT DROP $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P FORWARD DROP $IPTABLES -A INPUT -m state –state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -o eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A INPUT -p tcp -i eth0 --dport 20002 --sport 1024:65535 -m state --state NEW -j ACCEPT $IPTABLES -I INPUT -m hashlimit -m tcp -p tcp –dport 20002 –hashlimit 1/min –hashlimit-mode srcip –hashlimit-name ssh -m state –state NEW -j ACCEP $IPTABLES -A INPUT -p tcp -i eth0 --dport 80 --sport 1024:65535 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -p tcp -i eth0 --dport 443 --sport 1024:65535 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT –p tcp --dport 80 --syn –m limit --limit 1/s –m state --state NEW –j ACCEPT $IPTABLES -A INPUT -p icmp --icmp-type 8 -m limit --limit 1/s -j ACCEPT $IPTABLES -A OUTPUT -p icmp --icmp-type 8 -m limit --limit 1/s -j ACCEPT # zezwolenie na ruch dla interfejsow petli zwrotnej $IPTABLES -I INPUT -i lo -j ACCEPT $IPTABLES -I OUTPUT -o lo -j ACCEPT $IPTABLES -I INPUT -s 127.0.0.0/8 -d 127.0.0.0/8 -j ACCEPT $IPTABLES -I OUTPUT -s 127.0.0.0/8 -d 127.0.0.0/8 -j ACCEPT $IPTABLES -I INPUT -i lo -m state --state ESTABLISHED,RELATED -j ACCEPT
Ostatnio edytowany przez czater (2013-06-25 10:29:02)
Offline
No i wygląda całkiem ślicznie :>
Tylko skoro masz politykę dla OUTPUT domyślnie na ACCEPT nie ma sensu dodawać regułek loopbacka do tego łańcucha.
I ten jeden pakiet SYN na sekundę... A co jeżeli na stronę będzie chciało wejść kilku mieszkańców bloku którzy wszyscy siedzą za NAT'em i dzielą ten sam adres zewnętrzny? Ustaw ze 3,5. Wielka krzywda się nie stanie.
A co do pilnowania ssh: prawdopodobieństwo że jakiś automat wyczai Ci ssh na tym porcie jest nikłe. Do tego masz tam hashlimit 1 połączenie na minutę. Więc bruteforcowanie tego przez automaty trwałoby wieki. Jedyny sens zakładania jakiegoś daemona pilnującego tego portu to sytuacja gdy boisz sie że ktoś umyślnie będzie chciał zrobić Ci kuku. Wtedy jak coś polecałbym fail2ban (oprócz ssh potrafi pilnować proftpd, vsftp, apacha, etc) albo darmowego HIDS'a OSSEC (całkiem sympatyczne, ma szerooooooookie możliwości).
IMHO jakby ktoś chciał Ci robić kuku szybciej by znalazł jakąś podatność na stronie i przy jej użyciu się dostał do środka.
Ostatnio edytowany przez enether (2013-06-25 10:50:28)
Offline
Ok, a więc rozumiem że tak powinien wyglądać
$IPTABLES -P INPUT DROP $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P FORWARD DROP $IPTABLES -A INPUT -m state –state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -o eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A INPUT -p tcp -i eth0 --dport 20002 --sport 1024:65535 -m state --state NEW -j ACCEPT $IPTABLES -I INPUT -m hashlimit -m tcp -p tcp –dport 20002 –hashlimit 1/min –hashlimit-mode srcip –hashlimit-name ssh -m state –state NEW -j ACCEP $IPTABLES -A INPUT -p tcp -i eth0 --dport 80 --sport 1024:65535 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -p tcp -i eth0 --dport 443 --sport 1024:65535 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT –p tcp --dport 80 --syn –m limit --limit 1/s –m state --state NEW –j ACCEPT $IPTABLES -A INPUT -p icmp --icmp-type 8 -m limit --limit 1/s -j ACCEPT # zezwolenie na ruch dla interfejsow petli zwrotnej $IPTABLES -I INPUT -i lo -j ACCEPT $IPTABLES -I INPUT -s 127.0.0.0/8 -d 127.0.0.0/8 -j ACCEPT $IPTABLES -I INPUT -i lo -m state --state ESTABLISHED,RELATED -j ACCEPT
Offline
czater napisał(-a):
Ok, a więc rozumiem że tak powinien wyglądać
Kod:
$IPTABLES -P INPUT DROP $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P FORWARD DROP $IPTABLES -A INPUT -m state –state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -o eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A INPUT -p tcp -i eth0 --dport 20002 --sport 1024:65535 -m state --state NEW -j ACCEPT $IPTABLES -I INPUT -m hashlimit -m tcp -p tcp –dport 20002 –hashlimit 1/min –hashlimit-mode srcip –hashlimit-name ssh -m state –state NEW -j ACCEP $IPTABLES -A INPUT -p tcp -i eth0 --dport 80 --sport 1024:65535 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -p tcp -i eth0 --dport 443 --sport 1024:65535 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT –p tcp --dport 80 --syn –m limit --limit 1/s –m state --state NEW –j ACCEPT $IPTABLES -A INPUT -p icmp --icmp-type 8 -m limit --limit 1/s -j ACCEPT # zezwolenie na ruch dla interfejsow petli zwrotnej $IPTABLES -I INPUT -i lo -j ACCEPT $IPTABLES -I INPUT -s 127.0.0.0/8 -d 127.0.0.0/8 -j ACCEPT $IPTABLES -I INPUT -i lo -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A OUTPUT -o eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT
Jako że polityka OUTPUT jest na ACCEPT ta linijka nie robi nic.
$IPTABLES -I INPUT -s 127.0.0.0/8 -d 127.0.0.0/8 -j ACCEPT $IPTABLES -I INPUT -i lo -m state --state ESTABLISHED,RELATED -j ACCEPT
Jako że przed nimi masz "-i lo -j ACCEPT" to te wpisy nie mają żadnego znaczenia. Reguły w netfilterze przegladane są od góry w dół. Czyli jeżeli pakiet pasuje do regułki "pochodzi z interfejsu lo - zaakceptuj" wtedy nie jest już testowany na pochodzenie bądź miejsce docelowe czy stan.
$IPTABLES -A INPUT -p tcp -i eth0 --dport 20002 --sport 1024:65535 -m state --state NEW -j ACCEPT $IPTABLES -I INPUT -m hashlimit -m tcp -p tcp –dport 20002 –hashlimit 1/min –hashlimit-mode srcip –hashlimit-name ssh -m state –state NEW -j ACCEPT
Podobnie. Najpierw pakiet zostanie sprawdzony pod kątem regułki powyższej i zatwierdzony, w związku z tym nigdy nie będzie testowany pod kątem ilości połączeń na minutę. Górną usuń.
$IPTABLES -A INPUT -p tcp -i eth0 --dport 80 --sport 1024:65535 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT -p tcp -i eth0 --dport 443 --sport 1024:65535 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT –p tcp --dport 80 --syn –m limit --limit 1/s –m state --state NEW –j ACCEPT $IPTABLES -A INPUT -p icmp --icmp-type 8 -m limit --limit 1/s -j ACCEPT
To samo. Górna para jest zbędna skoro masz poniżej wpis dotyczacy portu 80 z modułem limit zastosowanym. Dorób taki sam wpis dla portu 443 (HTTPS) i ustaw limit na nieco większy. 5/s myślę, w ICMP też.
Dodatkowo staraj się nie mieszać appendów (-A) z insertami (-I) bo potem regułki wychodzą w dzikiej kolejności i pierwotny zamysł przy ich pisaniu może nie podziałać. Zdecydowanie lepiej w pliku umieszczać -A w odpowiedniej kolejności.
Ostatnio edytowany przez enether (2013-06-25 14:07:47)
Offline
redelek napisał(-a):
jak zwykle @jacek świetnie wyjaśnił. Podłączę się do pytania, bo jest troszkę zbliżone. Jak przetestować swoje ustawienia? czy jest jakiś skaner który zasymulował by mi tyle skanów czy ataków na SSH i inne porty ?
Jest coś takiego?
Można np przez localhosta:
iptables -S | grep 127 -A INPUT -d 127.0.2.1/32 -i lo -p udp -j REJECT --reject-with icmp-host-unreachable -A INPUT -d 127.0.2.1/32 -i lo -p tcp -j REJECT --reject-with tcp-reset -A INPUT -d 127.0.2.4/32 -i lo -j STEAL -A INPUT -d 127.0.2.5/32 -i lo -p tcp -j DELUDE -A INPUT -d 127.0.2.6/32 -i lo -j DROP -A INPUT -d 127.0.2.7/32 -i lo -p tcp -j TARPIT --tarpit -A INPUT -d 127.0.2.8/32 -i lo -p tcp -j TARPIT --honeypot -A INPUT -d 127.0.2.9/32 -i lo -p tcp -j TARPIT --reset -A INPUT ! -d 127.0.2.0/24 -i lo -j ACCEPT
do tego z podanych wyżej reguł (kila postów wyżej) usunąć wyłączenie interfesju lo, i wszystko testujesz na localhoście.
Albo virtualbox czy kvm - tam interfejs vboxnet0 lub tap, i z maszyny wirtualnej testujesz gospodarza, albo odwrotnie.
Bułka z masłem jednym słowem ;)
Online
Dziękuje za wskazówki, pozmieniałem trochę i publikuję kolejną wersję. Może przyda się komuś.
#!/bin/sh IPTABLES=/sbin/iptables $IPTABLES -F $IPTABLES -P INPUT DROP $IPTABLES -P OUTPUT ACCEPT $IPTABLES -P FORWARD DROP # zezwolenie na ruch dla interfejsow petli zwrotnej $IPTABLES -I INPUT -i lo -j ACCEPT $IPTABLES -A INPUT -m state –state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A INPUT -p tcp -i eth0 --dport 20002 --sport 1024:65535 -m state --state NEW -j ACCEPT $IPTABLES -A INPUT –p tcp --dport 80 --syn –m limit --limit 5/s –m state --state NEW –j ACCEPT $IPTABLES -A INPUT –p tcp --dport 443 --syn –m limit --limit 5/s –m state --state NEW –j ACCEPT $IPTABLES -A INPUT -p icmp --icmp-type 8 -m limit --limit 5/s -j ACCEPT $IPTABLES -A OUTPUT -p icmp --icmp-type 8 -m limit --limit 5/s -j ACCEPT $IPTABLES -A INPUT -m hashlimit -m tcp -p tcp –dport 20002 –hashlimit 1/min –hashlimit-mode srcip –hashlimit-name ssh -m state –state NEW -j ACCEPT
Ostatnio edytowany przez czater (2013-06-26 12:28:56)
Offline