Posts Tagged ‘iptables’

Limit bandwidth utilization using iptables.

I used the following in an attempt to the limit bandwidth utilization of the few IP address on my network. Used this on a CentOS6 firewall. I will see how it works over time. It seems to work fine, but I need to do more testing. I used the limit numbers I did based on the total amount of bandwidth available, and how much I wanted to limit it. I basically tested different settings to get the numbers right. Now, I just need to see how it impacts the usage. In other words, is it usable as a solution for a small network?

Create the chain:
iptables -N MYCHAIN

Send traffic I want to the chain:

iptables -I INPUT -s IPSorSUBNET -j MYCHAIN
iptables -I FORWARD -s IPSorSUBNET -j MYCHAIN

Configure the limit module to limit bandwidth in the chain:
iptables -A MYCHAIN -m limit –limit 5/second –limit-burst 10 -j ACCEPT

Drop any traffic that exceeds the limit:
iptables -A MYCHAIN -j DROP

Update: I found using a different limit-burst unusable. However, keeping the limit and the limit-burst equal seems to actually be working well thus far. I have found that having the limit and limit-burst equal to 10 per second on my 1.3Mb/s connection works well.

Finally had to cave in – DNS ACLs.

Platform: CentOS 6 x86_64

I knew when I implemented my split DNS solution years ago that I wanted to try to keep one recursive and open to use for queries. I wanted this more for my convenience (testing, and I could remember my address) when working on issues outside my own network. I knew at the time that I was taking a risk. It seemed like it was more about resources than security. I have two DNSs, but only the one was open to queries without restriction. Well, after probably about 10 years running like this, I finally had a need to add some ACLs and close up my convenient access. I was hit by several very long flurries of requests for isc.org. Because I have such limited bandwidth, it was quickly pretty obvious that something was wrong.

Initially, I looked to my gateway server. And this stumped me for a while, because I detected nothing wrong or any unusual traffic volume. However, a quick trace and look at the DNS logs on my secondary server revealed the requests. They would go on for hours and hours, but they would stop once in a while for a few hours before starting up again.

My initial approach was to block the IP address the queries were coming from, and hope to preserve my convenient access to my own recursive lookup server. I also found this interesting solution using iptables to block any requests to isc.org:

iptables -A INPUT -p udp -m string --hex-string "|03697363036f726700|" --algo bm --to 65535 -j DROP

But this does not seem practical to somebody who uses services provided by the Internet Systems Consortium, and does actually find myself on the site once in a while. While this solution does not really work for me in this case, it certainly enlightened me to adding this to my arsenal for some other situations. All you need to do is convert the URL to hex and create your iptables statement.

After watching the requests continue to come in despite being dropped at my firewall, I decided that it finally come to an end. I gave in an have added the ACLs to my external DNS servers.

In the /var/named/chroot/etc/named.conf:
...
acl "AllowToQuery" {
// Add subnets I trust to use my DNS for queries.
aaa.bbb.ccc.ddd/xx;
eee.fff.ggg.hhh/yy;
iii.jjj.kkk.lll/zz;
localhost;
};
...
// Added the ACL after DDOS attacked - repeated queries for isc.org.
allow-query { AllowToQuery; };
...

The allow-query statement was added to my external view, since I am running a split DNS. Having the ACLs setup this way eventually caused the request to stop.

How to NAT a Linux virtual interface.

I was able to use the following iptables configuration to NAT from a linux virtual interface (eth1:1) to an email/web server on my LAN (192.168.0.x). virt_ip_addr is the IP address I assigned to eth1:1, and 192.168.0.6 is the IP address of the server on my LAN. This works with both INPUT and FORWARD chains set to DROP.

This may not be the best solution, but it took quite a while to figure out how get something in place that works.

######################
# nat PREROUTING Chain Rules
######################

-A PREROUTING -d virt_ip_addr -p tcp –dport 25 -j DNAT –to 192.168.0.6:25
-A PREROUTING -d virt_ip_addr -p tcp –dport 80 -j DNAT –to 192.168.0.6:80

######################
# nat POSTROUTING Chain Rules
######################

-A POSTROUTING -o eth1 -j SNAT –to-source virt_ip_addr

######################
# filter FORWARD Chain Rules
######################

-A FORWARD -p tcp -i eth0 -o eth1 -s 192.168.0.6 -m multiport –sports 25 -j ACCEPT
-A FORWARD -p tcp -i eth1 -o eth0 -d 192.168.0.6 -m multiport –dports 25 -m state –state NEW -j ACCEPT
-A FORWARD -p tcp -i eth1 -o eth0 -d 192.168.0.6 -m multiport –dports 25 -j ACCEPT

-A FORWARD -p tcp -i eth0 -o eth1 -s 192.168.0.6 -m multiport –sports 80 -j ACCEPT
-A FORWARD -p tcp -i eth1 -o eth0 -d 192.168.0.6 -m multiport –dports 80 -m state –state NEW -j ACCEPT
-A FORWARD -p tcp -i eth1 -o eth0 -d 192.168.0.6 -m multiport –dports 80 -j ACCEPT

Return top

INFORMATION