1. "Reverse IP tables"
The concept here is to perform the equivalent of port knocking, but instead of opening a firewall pinhole based on inbound connections, the pinhole is opened based on outbound connections. This technique is especially useful in binding together different apps or services which are running at the same time.
In this example, MySql is setting up database synchronization. The local master creates an outbound connection to the remote slave, but the remote slave also creates an inbound connection back to the local master. Normally, the local inbound MySql port is closed. IPtables will only open the inbound port after the master expresses its implicit trust in the remote slave by creating the outbound connection.
iptables -A OUTPUT -p tcp --dport 3306 -m recent --name dbout --rdest -j ACCEPT
iptables -A INPUT -p tcp --dport 3306 -m recent --name dbout --rcheck -j ACCEPT
The take-away here is that it's possible to make the iptables aware of the state of multiple connections both inbound and outbound.
2. "Log Clog"
When logging firewall events, keep in mind Ranum's Laws of Log Analysis:
Ranum's first law of Log Analysis:
- Never keep more than you can conceive of possibly looking at
Ranum's second law of Log Analysis:
- The number of times an uninteresting thing happens is an interesting thing
Ranum's third law of Log Analysis:
- Keep everything you possibly can except for where you come into conflict with the First Law
(Posted to firewall-wizards mailing list Oct 01,2004)
When using iptables, there isn't a lot of logging sophistication, which means that there's a relatively low limit on the First Law. Thankfully, there's a hack on the Second Law which expands that limit - reduce the logging on what is absolutely uninteresting. I recommend Windows broadcasts. (I actually recommend throwing away Windows, but that's a different blog post.)
Throwing away all instances would be an absolute violation of the Second (and Third) Laws. Therefore, the key is to throw away most of the instances. Log the first instance, then suppress the rest.
iptables -A INPUT -p udp --dport 138 -m recent --name udp-138 --rcheck --seconds 300 -j DROP
iptables -A INPUT -p udp --dport 138 -m recent --name udp-138 --set
iptables -A INPUT -j LOG --log-prefix “INPUT-drop”
- (optional)
iptables -A INPUT -j DROP
iptables -A INPUT -p udp --dport 138 -m recent --name udp-138 --rcheck --hitcount 100 -j DROP
The advantage is that every log event represents a known larger number of events, so logging statistics can can still detect differences in numbers of "uninteresting" events.
3. "Auth port"
So you have a service which, for reasons you'd rather not discuss, has no auth, but still needs to be used. With iptables, if you can create a wrapper around the client to do auth, you can use the recent table to make the primary port inherit the auth. It's highly imperfect - auth is tied to the IP address, so IP spoofing FTW - but it's better than leaving the port wide open.
The key to success here is to make the auth service iptables-aware - and it has to have a portion running as root. :-( Once the auth is successful, the "old" way is to insert a new iptables rule. The "new" way is to add the IP address to a recency table which is already referenced by a rule.
iptables -A INPUT -d [server] -p tcp --dport 443 -j ALLOW
iptables -A INPUT -d [server] -p tcp --dport 80 -m recent --name authok --rcheck -j ALLOW
/proc/net/xt_recent/[name]
. Therefore, once the auth happens, the service can simply # echo [IP] >> /proc/net/xt_recent/[name]
and the address will be added as though it were accepted by a rule.Take-away: recency tables can be read and written from user space, without having to modify the actual IPtables policy, or going anywhere near the iptables binary.
4. "Quick & Dirty IDS"
Doing a web search for "iptables -m recent" will return a result on the first page to do IP address blocking, probably something like this page:
iptables -A FORWARD -m recent --name noplacelike --rcheck --seconds 60 -j DROP
iptables -A FORWARD -i eth0 -d 127.0.0.0/8 -m recent --name noplacelike --set -j DROP
iptables -A FORWARD -m recent --name noplacelike --update --seconds 60 -j DROP
After identifying the attacker (in line b), using "--update" instead of "--rcheck" will both check and re-set the address in the recency table. As long as the attacker continues to connect to the target system, if the previous connection is within 60 seconds of the previous connection, the attacker's system will continue to be blacklisted.
That's it for the "sane" IPtables tricks with the "recent" match. Next blog entry: some of the crazy potential uses of iptables.
No comments:
Post a Comment