Univerzální řešení: pro každý paket se vyhodnocuje sada správcem definovaných pravidel:
"on $interface", "from/to", "tagged"
"-A", "-i/-o" "-s/-d" "--mark ?"
"pass/block", "nat-to/rdr-to", "keep state", "tag"
"-j", "--set ?"
pfctl(8), pfsync(4)
iptables(8), ip6tables(8), conntrack(8), ipset(8)
# emerge -av iptables conntrack-tools ipset
# pfctl -sr [-a název-anchoru] ## "show rules"
# iptables -nvL [název-chainu] ## "neresolvuj + verbose list"
pf.conf(5); pfctl -nf /etc/pf.conf == "jen otestuj, jestli to půjde" (většinou)# vi /etc/pf.conf (většinou)# pfctl [-a název-anchoru] -f /etc/pf.conf
záleží na distribuci; iptables-save(8), iptables-restore(8) (většinou)# <pokusy-na-živém-systému> (většinou)# /etc/init.d/ip[6]tables save
(keyword) | pass | block [return|drop] | match | anchor bez quick |
(chain name) | ACCEPT | REJECT, DROP | RETURN |
block return [quick] [parametry] block in ## spoiler!
## přidá na konec src-chainu # iptables -A <src-chain> [parametry] -j <dst-chain> # iptables -A INPUT -j DROP ## spoiler! ## vloží jako 42. pravidlo src-chainu # iptables -I <src-chain> 42 [parametry] -j <dst-chain>
## standardně, když nic neřeknete (žádné -a), je vše v kořenovém anchoru anchor "zvenku" in on egress { [pravidla] };
## musíte si vybrat minimálně z INPUT, OUTPUT, FORWARD # iptables -N chain_zvenku && iptables -A INPUT -i eth0 -j chain_zvenku
pass ## defaultně implikuje "keep state"
# iptables -P ACCEPT <jaký-chain?>
## novější # iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT ## nebo starší # iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPTVe skutečnosti je to složitější, než si dokážete představit. Zjednodušený pohled.
# vi /etc/pf.conf # pfctl -f /etc/pf.conf
# iptables -R # iptables -D # iptables --line-numbers
# pfctl -Fr ## "flush rules"
# iptables -F INPUT
# pfctl -z
# iptables -Z [chain [rule]]
pass in block out passneni stejne jako
# iptables -A INPUT -j ACCEPT # iptables -A OUTPUT -j DROP
pass out on ! em0 block in on egress ## implicitně vytvořená skupina: ifs s default routami pass in on vnitrni ## ifconfig em0 group vnitrni match on ct4 set skip on lo # lo je skupina všech interfaceů "lo0, lo1, ..."
# iptables -A OUTPUT ! -o eth0 -j ACCEPT # < netuším jak > # < netuším jak > # iptables -A FORWARD -{i,o} ct4 # < netuším jak elegantněji, než na správná místa dát -i/o lo -j ACCEPT a potom si jich nevšímat >
block on em0 inet6 pass in on em0 inet6 proto icmp6
# ip6tables -A INPUT -i em0 -j DROP # ip6tables -A INPUT -i em0 -p icmp6 -j ACCEPT
pass from 192.168.99.0/24 block proto tcp to ! 192.168.99.4 port smtp block proto tcp from os Windows to port smtp pass proto tcp to port >49151
# iptables -A mychain -s 192.168.99.0/24 -j ACCEPT # iptables -A mychain ! -d 192.168.99.4 -p tcp --dport 25 -j DROP # < netuším jak: filter osf > # iptables -A mychain -p tcp --dports 49151:
# expanduje se na všechny adresy pass in proto tcp to em0 port smtp # máte-li DHCP nebo měníte-li často konfiguraci, můžete nechat PF, aby se pokaždé podíval pass in to (em0) # self-explanatory pass in to em0:network # keyword "self" expanduje na všechny adresy přiřazené tomuto stroji; bývá jich hodně pass in to self pass from (self)
# expanduje se na block drop in on ! em0 inet from { em0:network } block drop in inet from em0Dejte si na to pozor, nechcete to vždy! (redundance, překrývající se ranky + rdomains, ...)
moje_sit="192.168.99.0/24" muj_interface="fxp0" muj_limit="keep state (pflow max-src-conn 50)" pass on $muj_interface from $moje_sit $muj_limit
moje_site="{ 192.168.99.0/24, 192.168.199.0/24 }" pass proto tcp to $moje_site port { smtp, domain, www }
match out inet on egress nat-to (egress)
# iptables -t nat -A POSTROUTING -o $ext -j MASQUERADE # iptables -t nat -A POSTROUTING -o $ext -j SNAT --to vaše.ip.adresa
match in proto tcp from <neplatici> to ! <banky> port www rdr-to 127.0.0.1 port 88
# iptables -t nat -A PREROUTING -j DNAT --to-destination 127.0.0.1 ## tohle umi presmerovat jen na lokalni stroj, na adresu iface, odkud to prislo # iptables -t nat -A PREROUTING -j REDIRECT --to-port 88
dmz="198.442.14.32/27" nouzovy_poskytovatel="32.16.8.4" pass out quick from $dmz nat-to $nouzovy_poskytovatel
table <tabulka> table <uvnitr> const { 192.168.77.0/24, 192.168.177.0/24, 192.168.199.0/24 } table <moje-tabulka> file "/etc/fw/moje_tabulka"
# ipset create tabulka <co-do-ní-chci-dávat> # iptables -A INPUT -m set --match-set tabulka (src|dst) -j ACCEPT
# pfctl -sT [-a anchor] ## na tabulky v anchorech pozor! # pfctl -t tabulka -T show [-a anchor] # pfctl -t tabulka -T add 10.16.16.16/28 # pfctl -t tabulka -T delete 10.16.16.16/28 # pfctl -f /etc/jeden/zaznam/na/radek -t tabulka -T add
pass in proto tcp to port ssh keep state (max-src-conn-rate 3/2) # můžeme specifikovat tabulku, do které se budou házet neposlušní pass in proto tcp to port ssh keep state (max-src-conn-rate 3/2 overload <bruteforce>)
pass keep state (no-sync)
set skip on $pfsync_parent_device pass quick on em0 proto carp keep state (no-sync) prio 7
sysctl net.inet.carp.preempt=1
# echo "vhid <vaše-NN> carpdev vic0 advskew 16 pass mekmitasdigoat" > /etc/hostname.carp0 # echo "inet vaše.ip.adresa" >> /etc/hostname.carp0 # sh /etc/netstart carp0 ## na obou strojích (na jednom vyšší advskew) # ifconfig pfsync0 create syncdev em0 syncpeer <jednoznačná adresa druhého stroje> up
# ifconfig -g carp carpdemote 42 # ifconfig -g carp -carpdemote 42
...ale uvědomělý admin si toho musí uvědomovat víc...
- "Knock, knock.
- Who's there?
- The Doctor.
- Doctor Who?"
TODO: Jak to co nejrychlejc nastavit, pravni pozadavky, ukazka one-click shortcutu na putty s predvyplnenym klicem/menem, co se po zavreni odpoji. Nezapomenout osetrit tu chranenou sluzbu (cache browseru, session IDs, problem dual-auth, revokace tiketu/sessions po ukonceni authpf spojeni, co s visejicima spojenima (prednastavit keepalive v putty), ukazat puttygen pri te prilezitosti)
echo "/advskew $OLD/s/advskew $OLD/advskew $NEW/\nw" | ed -s /etc/hostname.carpX