?
Solved

IPTABLES router with traffic accounting

Posted on 2009-02-16
12
Medium Priority
?
1,864 Views
Last Modified: 2013-11-16
Hi everyone, I'm trying to build up a complete, stable, and working as expected router/firewall for my network.  I've searched extensively and now I'm kinda stuck, as I think I understand how it works and I'm not sure if I do really, so here I am.  The actual code running at system statup is included below.  I'm running on the most recent debian release I installed not so long ago (linux-2.6.18-6-686) which includes iptables 1.3.6.  I didn't recompile the kernel or anything.  What I'm asking for is a simple check of my current scripts, and what must be changed, what should be changed, etc.  I want a simple firewall behavior, nothing complicated, as you can see below, only a couple port forwardings, that's it.  When this is done there is the accounting part, the goal is to know how much bandwidth which IPs used during a certain period of time (dumping values with iptables -L -v -n -x, this part of the accounting I can work on myself, I'm just asking for iptables related stuff), so the possibilities are, authorized MAC/IP combinations, traffic aimed at the firewall itself, and unknown traffic.  I want to know exactly of much data pass through eth0, at all times, I don't want to skip unknown/dropped traffic as it passed through my modem and I'm billed for it.  That's where I'm lost, when I forward ports with DNAT, do they still go through INPUT or they go through FORWARD as they should?  I couldn't find any information on this anywhere.

Thanks for the help!
modprobe ip_conntrack
modprobe ip_conntrack_ftp
modprobe ip_conntrack_irc
modprobe ip_nat_ftp
modprobe ip_nat_irc
 
iptables -F
iptables -t nat -F
iptables -t mangle -F
iptables -t raw -F
iptables -X
iptables -t nat -X
iptables -t mangle -X
iptables -t raw -X
 
# Disable traffic while making rules
iptables -A INPUT -j DROP
iptables -A FORWARD -j DROP
iptables -A OUTPUT -j DROP
 
echo "1" > /proc/sys/net/ipv4/ip_forward
echo "1" > /proc/sys/net/ipv4/conf/all/rp_filter
echo "1" > /proc/sys/net/ipv4/ip_dynaddr
 
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 25 -m state --state NEW,RELATED,ESTABLISHED -j DNAT --to-destination 10.25.50.50
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -m state --state NEW,RELATED,ESTABLISHED -j DNAT --to-destination 10.25.50.50
iptables -t nat -A PREROUTING -i eth0 -p 47 -m state --state NEW,RELATED,ESTABLISHED -j DNAT --to-destination 10.25.50.50
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 1723 -m state --state NEW,RELATED,ESTABLISHED -j DNAT --to-destination 10.25.50.50
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 4422 -m state --state NEW,RELATED,ESTABLISHED -j DNAT --to-destination 10.25.50.75
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 8880:8889 -m state --state NEW,RELATED,ESTABLISHED -j DNAT --to-destination 10.25.50.75
iptables -t nat -A PREROUTING -i eth0 -p udp --dport 9990:9999 -m state --state NEW,RELATED,ESTABLISHED -j DNAT --to-destination 10.25.50.75
 
iptables -A FORWARD -o eth0 -m mac --mac-source XX:XX:XX:XX:XX:XX -s 10.25.50.75 -j ACCEPT
iptables -A FORWARD -o eth0 -m mac --mac-source XX:XX:XX:XX:XX:XX -s 10.25.50.50 -j ACCEPT
iptables -A FORWARD -i eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i eth0 -d 10.25.50.50 -p tcp --dport 25 -m state --state NEW -j ACCEPT
iptables -A FORWARD -i eth0 -d 10.25.50.50 -p tcp --dport 80 -m state --state NEW -j ACCEPT
iptables -A FORWARD -i eth0 -d 10.25.50.50 -p 47 -m state --state NEW -j ACCEPT
iptables -A FORWARD -i eth0 -d 10.25.50.50 -p tcp --dport 1723 -m state --state NEW -j ACCEPT
iptables -A FORWARD -i eth0 -d 10.25.50.75 -p tcp --dport 4422 -m state --state NEW -j ACCEPT
iptables -A FORWARD -i eth0 -d 10.25.50.75 -p tcp --dport 8880:8889 -m state --state NEW -j ACCEPT
iptables -A FORWARD -i eth0 -d 10.25.50.75 -p udp --dport 9990:9999 -m state --state NEW -j ACCEPT
iptables -A FORWARD -j DROP
 
iptables -A INPUT -i eth0 -m state --state INVALID,NEW -j DROP
 
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
 
# Accounting
iptables -I FORWARD 2 -s 10.25.50.50 
iptables -I FORWARD 2 -d 10.25.50.50
iptables -I FORWARD 2 -s 10.25.50.75
iptables -I FORWARD 2 -d 10.25.50.75
iptables -I INPUT 2 -i eth0
iptables -I OUTPUT 2 -o eth0
 
# Enable traffic
iptables -D INPUT 1
iptables -D FORWARD 1
iptables -D OUTPUT 1

Open in new window

0
Comment
Question by:dprovencher
  • 7
  • 5
12 Comments
 
LVL 51

Accepted Solution

by:
ahoffmann earned 1500 total points
ID: 23657512
> .. when I forward ports with DNAT, do they still go through INPUT or they go through FORWARD as they should?
if you do DNAT in the PREROUTING chain (as you did), then the package is passed to the FORWARD chain (unless you defined you own IP, which is useless, somehow), INPUT and OUTPUT chain is not used for these packages
0
 
LVL 1

Author Comment

by:dprovencher
ID: 23661537
Thank you very much for this information, that clears up that part of my problem.  Can you comment on the script itself, anything I should add, any options not activated in the system variables that would add security or protect against attacks?  I don't want any traffic getting to the firewall itself except responses to packets sent by it (dns queries, ISP's DHCP, etc)

Thanks!

And sorry for the amount of points, a related question of mine did not get any answers, I requested a deletion yesterday, I will increase points in this one to 500 when it is deleted, which takes 4 days apparently.
0
 
LVL 51

Expert Comment

by:ahoffmann
ID: 23662764
I'm just wondering why you delete some rules at the end
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 1

Author Comment

by:dprovencher
ID: 23662972
I delete the first rule of each chain, that I added at the top of the script to stop all traffic.

Here's the code I speak of at the top and at the end.
# Disable traffic while making rules
iptables -A INPUT -j DROP
iptables -A FORWARD -j DROP
iptables -A OUTPUT -j DROP
 
# Enable traffic
iptables -D INPUT 1
iptables -D FORWARD 1
iptables -D OUTPUT 1

Open in new window

0
 
LVL 51

Expert Comment

by:ahoffmann
ID: 23663030
hmm, the script then depends on the current configuration to work proper
To make it behave the same all times I'd change the DROP rules like:

iptables -I INPUT 1 -j DROP

depending on the usage of that script, for example as rc-script, I'd add a default policy for each chain at the beginning like:

iptables -P INPUT DROP
0
 
LVL 1

Author Comment

by:dprovencher
ID: 23664808
Thanks for the help I'll replace those lines with a policy oriented approach, can you provide insight on the rest of the scripts?  Would it be working as expected, secure, etc?
0
 
LVL 51

Expert Comment

by:ahoffmann
ID: 23665027
> ... secure, etc?
hmm secure is a wide definition ...
What I see so far:
* if you trust all you clients, then MASQUERADE is ok, otherwise you open the door from inside to outside
* also I can't speak about the other open/DNATted ports
* if port 80 means a web server, HTTP protocol, then your network is wide, wide open unless you take addition care there
0
 
LVL 1

Author Comment

by:dprovencher
ID: 23665114
80 is a web server, IIS 6.  Do you mean my forwarded port 80 is wide open on the destination internal host?  If so, well that's what I want, I mean the outside being able to reach my web server.  If you mean that the linux box is wide open can you give me some directions as to what is open and how?

Thanks!
0
 
LVL 51

Expert Comment

by:ahoffmann
ID: 23665292
I meant that most attack are against web servers today
a packetfilter won't detect much there
So my comment about port 80 might or might not be serious:)
0
 
LVL 1

Author Comment

by:dprovencher
ID: 23665683
Ok yeah I know that, I even closed my FTP and SQL ports because I don't really need them, they were steadily brute-forced.  I had no worries my passwords are strong but it was generating very unwanted traffic and clogging my old router sometimes.

Anyway, since nobody sees security risks in my script or things I could improve I guess I got it mostly right :)

Thanks for the help, I'll reward you 500 points in a few days for your first answer concerning DNAT going through INPUT or not as this was my big question.
0
 
LVL 1

Author Comment

by:dprovencher
ID: 23723868
Ok I updated the points, I'll post my complete solution for others to use when I get some spare time in some days.
0
 
LVL 1

Author Comment

by:dprovencher
ID: 23775484
So here are my scripts, the first is the firewall script, that you load at startup, and the second is the accounting data dumping (on a MSSQL server, I use isql for this) that you can run with cron, I run it every minute.  I didn't comment the code cause I'm lazy but I'm sure you can figure it out as I'm myself a beginner with iptables.  My lastest addition is the interface "lo" lines in the stop script cause at shutdown bind would hang for like 2 minutes.

Enjoy!
#! /bin/sh
 
case "$1" in
  start)
    echo "Starting firewall"
 
    iptables -P INPUT DROP
    iptables -P FORWARD DROP
    iptables -P OUTPUT DROP
 
    iptables -F
    iptables -t nat -F
    iptables -t mangle -F
    iptables -t raw -F
    iptables -X
    iptables -t nat -X
    iptables -t mangle -X
    iptables -t raw -X
 
    modprobe ip_conntrack
    modprobe ip_conntrack_ftp
    modprobe ip_conntrack_irc
    modprobe ip_nat_ftp
    modprobe ip_nat_irc
 
    echo "1" > /proc/sys/net/ipv4/conf/all/rp_filter
    echo "1" > /proc/sys/net/ipv4/ip_dynaddr
 
    iptables -N ACCOUNTING
    iptables -A ACCOUNTING -d 10.25.50.50 -j RETURN
    iptables -A ACCOUNTING -s 10.25.50.50 -j RETURN
    iptables -A ACCOUNTING -d 10.25.50.75 -j RETURN
    iptables -A ACCOUNTING -s 10.25.50.75 -j RETURN
    iptables -A ACCOUNTING -d 10.25.50.225 -j RETURN
    iptables -A ACCOUNTING -s 10.25.50.225 -j RETURN
    iptables -A ACCOUNTING -d 10.25.50.226 -j RETURN
    iptables -A ACCOUNTING -s 10.25.50.226 -j RETURN
    iptables -A ACCOUNTING -d 10.25.50.227 -j RETURN
    iptables -A ACCOUNTING -s 10.25.50.227 -j RETURN
    iptables -A ACCOUNTING -i eth0 -j RETURN
    iptables -A ACCOUNTING -o eth0 -j RETURN
 
    iptables -A FORWARD -j ACCOUNTING
    iptables -A OUTPUT -o eth0 -j ACCOUNTING
    iptables -A INPUT -i eth0 -j ACCOUNTING
 
    iptables -A OUTPUT -j ACCEPT
    iptables -A INPUT -i ! eth0 -j ACCEPT
    iptables -A INPUT -i eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
 
    iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 25 -m state --state NEW,RELATED,ESTABLISHED -j DNAT --to-destination 10.25.50.50
    iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -m state --state NEW,RELATED,ESTABLISHED -j DNAT --to-destination 10.25.50.50
 
    iptables -A FORWARD -o eth0 -m mac --mac-source 00:11:22:33:44:55 -s 10.25.50.50 -j ACCEPT
    iptables -A FORWARD -o eth0 -m mac --mac-source 00:11:22:33:44:55 -s 10.25.50.75 -j ACCEPT
    iptables -A FORWARD -o eth0 -m mac --mac-source 00:11:22:33:44:55 -s 10.25.50.225 -j ACCEPT
    iptables -A FORWARD -o eth0 -m mac --mac-source 00:11:22:33:44:55 -s 10.25.50.226 -j ACCEPT
    iptables -A FORWARD -o eth0 -m mac --mac-source 00:11:22:33:44:55 -s 10.25.50.227 -j ACCEPT
    iptables -A FORWARD -i eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
    iptables -A FORWARD -i eth0 -d 10.25.50.50 -p tcp --dport 25 -m state --state NEW -j ACCEPT
    iptables -A FORWARD -i eth0 -d 10.25.50.50 -p tcp --dport 80 -m state --state NEW -j ACCEPT
 
    iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
 
    echo "1" > /proc/sys/net/ipv4/ip_forward
 
    echo "Done"
    ;;
  stop)
    echo "Stopping firewall"
 
    echo "0" > /proc/sys/net/ipv4/ip_forward
 
    iptables -F
    iptables -t nat -F
    iptables -t mangle -F
    iptables -t raw -F
    iptables -X
    iptables -t nat -X
    iptables -t mangle -X
    iptables -t raw -X
 
    iptables -A INPUT -i lo -j ACCEPT
    iptables -A OUTPUT -o lo -j ACCEPT
 
    echo "Done"
    ;;
  reload|restart|force-reload)
    /etc/init.d/firewall stop
    /etc/init.d/firewall start
    ;;
  *)
    echo "Usage: /etc/init.d/firewall {start|stop|reload|restart|force-reload}"
    exit 1
    ;;
esac
 
exit 0
 
------------------------------------------------------------------------
 
#! /bin/sh
 
RAWDATA=`iptables -Z -x -v -n -L ACCOUNTING`
 
WHILEI=0
WHILERECORDI=0
 
SQLQUERIES=$(
  echo "$RAWDATA" |
  {
    while read WHILECURRENTLINE; do
      ((WHILEI++));
      if [ "$WHILEI" -gt 2 ]; then
        if [ "$WHILERECORDI" -eq 0 ]; then
          CURRENTDOWNBYTES=`echo "$WHILECURRENTLINE" | egrep -o "[0-9]{1,}" | head -n 2 | tail -n 1`;
          CURRENTIP=`echo "$WHILECURRENTLINE" | egrep -o "[0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}" | tail -n 1`;
          WHILERECORDI=1;
        else
          CURRENTUPBYTES=`echo "$WHILECURRENTLINE" | egrep -o "[0-9]{1,}" | head -n 2 | tail -n 1`;
          if [ "$CURRENTUPBYTES" -gt 0 ] || [ "$CURRENTDOWNBYTES" -gt 0 ]; then
            WHILESQLQUERIES=`echo "INSERT INTO tbl_data (ip, databytesup, databytesdown) VALUES ('$CURRENTIP', $CURRENTUPBYTES, $CURRENTDOWNBYTES)\r\n"$WHILESQLQUERIES`;
          fi;
          WHILERECORDI=0;
        fi;
      fi;
    done
    echo -e "$WHILESQLQUERIES"
  }
)
 
INSERTRETURN=`echo "$SQLQUERIES" | isql SERVER_CONNECTION username password -b | grep -c -m 1 "1"`
 
if [ "$INSERTRETURN" != "1" ]; then
  echo -e "`date +"%F %T"` SQL INSERT ERROR\r" > /dev/tty1;
fi
 
exit 0

Open in new window

0

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

​Being a Managed Services Provider (MSP) has presented you  with challenges in the past— and by meeting those challenges you’ve reaped the rewards of success.  In 2014, challenges and rewards remain; but as the Internet and business environment evol…
BIND is the most widely used Name Server. A Name Server is the one that translates a site name to it's IP address. There is a new bug in BIND (https://kb.isc.org/article/AA-01272), affecting all versions of BIND 9 from BIND 9.1.0 (inclusive) thro…
If you're a developer or IT admin, you’re probably tasked with managing multiple websites, servers, applications, and levels of security on a daily basis. While this can be extremely time consuming, it can also be frustrating when systems aren't wor…
When cloud platforms entered the scene, users and companies jumped on board to take advantage of the many benefits, like the ability to work and connect with company information from various locations. What many didn't foresee was the increased risk…
Suggested Courses
Course of the Month17 days, 8 hours left to enroll

831 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question