Use egress filtering to mitigate attacks and information leaks coming from your network.
By now you should be familiar with the concept of firewalling as it applies to blocking traffic coming into your network. But have you considered the benefits of filtering traffic that leaves your network? For instance, what would happen if someone compromised a host on your network and used it as a platform to attack other networks? What if a worm somehow made it onto your network and tried to infect hosts across the Internet? At the very least, you would probably receive some angry phone calls and emails.
Luckily, filtering your outbound traffic—otherwise known as egress filtering—can help to contain such malicious behavior. Egress filtering not only can protect others from attacks originating from your network, but also can be used to enforce network usage policies and make sure information doesn’t leak out of your network onto the wider Internet. In many situations, egress filtering is just as important as filtering inbound traffic.
The general guideline when crafting egress-filtering rules is the same as when constructing any inbound-filtering rule: devices should be allowed to do only what they were meant to do. That is, a mail server should be allowed to serve and relay mail only, a web server should be allowed to serve web content only, a DNS server should service DNS requests only, and so on. By ensuring that this policy is implemented, you can better contain the threats mentioned earlier.
It might also be a good idea to force users to use internal services rather than Internet services wherever possible. For example, if you are using your own DNS servers, clients shouldn’t be able to connect to external DNS servers to resolve hostnames. If clients are allowed to do this, you risk the chance that they will reveal intranet hostnames to outside parties when they attempt to resolve internal hostnames through an external DNS server.
This restriction can be accomplished in OpenBSD with a rule like this:
rdr on $INT_IF
inet proto { tcp, udp } from $INT_IF
:network to any port 53 -> $DNS_SERVER
port 53
Of course, you’ll need to set INT_IF
to the interface facing your internal network and set DNS_SERVER
to the IP address of your internal DNS server.
If you’re using Netfilter [Hack #44], you’ll have to use four rules to accomplish the same goal:
#iptables -t nat -A PREROUTING -p tcp -i
$INT_IF
--dport 53 -j DNAT \
--to-destination
$DNS_SERVER
:53
#iptables -t nat -A PREROUTING -p udp -i
$INT_IF
--dport 53 -j DNAT \
--to-destination
$DNS_SERVER
:53
#iptables -t nat -A POSTROUTING -p tcp -o
$EXT_IF
--sport 53 -j SNAT \
--to-source
#
$SNAT_IP
iptables -t nat -A POSTROUTING -p udp -o
$EXT_IF
--sport 53 -j SNAT \
--to-source
$SNAT_IP
The first two rules specify that the destination address of any incoming packet destined for TCP or UDP port 53 should be rewritten to DNS_SERVER
. However, this will cause any response to the rewritten packet to be sent to the host that initiated the connection. If the server to which the host originally intended to connect is not DNS_SERVER
, the response from DNS_SERVER
will be silently dropped.
The next two rules fix this by performing address translation on the source address of the packet before it is sent out. That sends DNS_SERVER
’s response back to the host running Netfilter, and the host then translates the destination address back to the host that initiated the connection. You should set SNAT_IP
to the IP address on the machine running Netfilter that is visible to DNS_SERVER
.
Similarly, if you’re running an internal mail server and want to monitor email that exits your enterprise, you’ll need to prevent your users from sending email through external mail servers. In OpenBSD, can do this by using a similar rule to force all SMTP traffic to be redirected to your own SMTP server:
rdr on $INT_IF
inet proto tcp from $INT_IF
:network to any port 25 -> $SMTP_HOST
port 25
For Netfilter, the same result can be accomplished with these two rules:
#iptables -t nat -A PREROUTING -p tcp -i
$INT_IF
--dport 25 -j DNAT \
--to-destination
$SMTP_HOST
:25
#iptables -t nat -A POSTROUTING -p tcp -i
$EXT_IF
--sport 25 -j SNAT \
--to-source
$SNAT_IP
Egress filtering can also prevent IP spoofing. By filtering on your external interface at the border of your network, you can verify that packets leaving your network have source addresses that match your address space. By filtering all other traffic, you can ensure that any IP spoofing attack performed from your network or routed through it will be dropped before the packets are able to leave.