######################################################################## ######################################################################## # First, let define filter table. Use "iptables -nvxL" to see counters. ######################################################################## ######################################################################## *filter :INPUT DROP [0:0] :FORWARD DROP [0:0] :OUTPUT DROP [0:0] ######################################################################## # First, let define a nice small helper chain for logging things in # filter table. If you want to log something, just jump to it from # wherever. -N LOG_INP -N LOG_OUT -N LOG_FWD # Uncomment if you get too many broadcasts logged on some of your # interfaces. Change interface name as needed. Windows machines # would usually generate tons of these. Thanks Bill for wasting our # network bandwith. If you don't want to log anything else, just add # additional lines for that stuff and call RETURN target before you # hit the lines that call LOG target. # -A LOG_INP -i eth0 -m pkttype --pkt-type broadcast -j RETURN -A LOG_INP -j LOG --log-prefix "INPUT " -A LOG_OUT -j LOG --log-prefix "OUTPUT " -A LOG_FWD -j LOG --log-prefix "FORWARD " -A LOG_INP -j RETURN -A LOG_OUT -j RETURN -A LOG_FWD -j RETURN ######################################################################## # You want to have this as the very first rules in INPUT, OUTPUT and # FORWARD chains for performance reasons. They allow packets that # belong to already established connections to pass through. The wast # majority of packets going through the firewall will be matched # against those first three lines bellow. Some people blindly allow # all related connections too (by using only the first three lines and # changing "ESTABLISHED" to "ESTABLISHED,RELATED"), but I'd rather be # a bit more peaky about it. On firewall, you want to accept almost # all related ICMP messages. You can be a bit more restrictive here # and allow only ICMP types actually needed for networking to work # stable and fast. But even this setup is more restrictive than most # people use. It's your choice what you'll actually use here. -A INPUT -m state --state ESTABLISHED -j ACCEPT -A OUTPUT -m state --state ESTABLISHED -j ACCEPT -A FORWARD -m state --state ESTABLISHED -j ACCEPT -A INPUT -p icmp -m state --state RELATED -j ACCEPT -A OUTPUT -p icmp -m state --state RELATED -j ACCEPT -A FORWARD -p icmp -m state --state RELATED -j ACCEPT ######################################################################## # OK, now the rest is total overkill for this simple config (and will # burn more CPU cycles). However, as this file grows in size and # complexity, this will actually make things more managable and will # consume less CPU cycles since Netfilter's kernel modules don't need # to check packets against all your 10,000 rules. For each service # we'll define custom chain to do filtering in. In INPUT, OUTPUT and # FORWARD chains will insert only the rules to call custom chain for # each of the service that we want to accept. Make sure each custom # chain ends up with either RETURN or DROP targets. If you fall off # the end of custom chain, what happens is not usually what you # intended to happen. I find using the RETURN target to be more # flexible option, since it allows for a packet to be accepted by some # other custom chain (not used in this particular file). ######################################################################## # First let do SSH. We'll allow it from everywhere so you don't end # up locked out. Tighten it up. If you also wanted to allow your # firewall to forward SSH connections, you'd create new custom chain # SSH_FWD similar to SSH_INP. # Create new chain and insert the rule to call it -N SSH_INP -A INPUT -p tcp --syn --sport 1024: --dport 22 -m state --state NEW -j SSH_INP # Put your SSH rules here. You probably want to be more restrictive # than allowing access from anywhere. -A SSH_INP -j ACCEPT # And this should be last thing at the end of all your custom chains -A SSH_INP -j RETURN ######################################################################## # OK, now let do the HTTP stuff. Same as for SSH. Let say you also # want to allow HTTPS. # define it -N HTTP_INP -A INPUT -p tcp --syn --sport 1024: --dport 80 -m state --state NEW -j HTTP_INP -A INPUT -p tcp --syn --sport 1024: --dport 443 -m state --state NEW -j HTTP_INP # rules -A HTTP_INP -j ACCEPT # go back -A HTTP_INP -j RETURN ######################################################################## # VNC stuff # define it -N VNC_FWD -A FORWARD -p tcp --syn --sport 1024: --dport 5900 -m state --state NEW -j VNC_FWD # rules -A VNC_FWD -s 192.168.192.24 -d 10.10.60.4 -j ACCEPT # go back -A VNC_FWD -j RETURN ######################################################################## # And your 8000 port thingie. I'll put some dummy addresses here. # Change them to what you need. Here you see advantage of using # custom chains. If packet is destined for port 10000, you check it # only once (the FORWARD rule), instead of checking it four times # (once for each src-dst combo you allow). # define it -N P8000_FWD -A FORWARD -p tcp --syn --sport 1024: --dport 8000 -m state --state NEW -j P8000_FWD # rules -A P8000_FWD -s 1.2.3.4 -d 10.10.60.123 -j ACCEPT -A P8000_FWD -s 1.2.3.5 -d 10.10.60.123 -j ACCEPT -A P8000_FWD -s 1.2.3.6 -d 10.10.60.123 -j ACCEPT -A P8000_FWD -s 1.2.3.7 -d 10.10.60.123 -j ACCEPT # go back -A P8000_FWD -j RETURN ######################################################################## # OK, this stuff should be at the end of filter table. If you want to # log things that firewall blocked, just call our nice logging chains. -A INPUT -j LOG_INP -A OUTPUT -j LOG_OUT -A FORWARD -j LOG_FWD ######################################################################## # Commit line must be the last line in table definition. It commits # the above rules into the kernel. COMMIT ######################################################################## ######################################################################## # Next, we define the nat table. You'd implement stuff such as SNAT # or DNAT here. Use "iptables -t nat -nvxL" to see counters. ######################################################################## ######################################################################## *nat :PREROUTING ACCEPT [0:0] :POSTROUTING ACCEPT [0:0] :OUTPUT ACCEPT [0:0] ######################################################################## # So, you said you want that fancy port forwarding of port 8000. I'll # put a dummy address here, change it to what you actually need. The # rules in filter's INPUT and FORWARD chains will see this IP address, # not the original destination address. You just do DNAT here, access # is controlled from the filter table (above). -A PREROUTING -p tcp --dport 8000 -j DNAT --to-destination 10.10.60.123 ######################################################################## # And again, COMMIT is the last thing in table's definition. COMMIT ######################################################################## ######################################################################## # Here comes the mangle table. Not used for anything in this # particular simplicit setup. We'll just define it and leave it # empty. Use "iptables -t mangle -nvxL" to see counters. ######################################################################## ######################################################################## *mangle :PREROUTING ACCEPT [0:0] :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0] :POSTROUTING ACCEPT [0:0] COMMIT