9

There is a server without any iptables defense: ACCEPT all..

There could be custom applications on this server.

If we should need to harden this server (so deny all, and only let what is needed by the applications) with strict iptables rules, we have to find out by hand that which app uses which dst/src port/protocol and then we have to write the iptables rules for them..

The question: are there any scripts that can help collecting these informations from a running machine? (from the logs?) - And automatically generating the iptables rules?

Like there is the audit2allow on SELinux. Just for iptables!

The machine cannot have any outage!

Ex.: the "MAGIC" script should run a week/month on the machine, collecting informations, then, after a week/month, the script will be able to produce an iptables rule file that we can use.

Many people could get in this situation (how to harden a server regarding iptables). And it would be great if there were a script/solution that can do this :\

5
  • Alternatively, block everything and only let what is needed through. You could find out what is needed with a tcpdump run over a week or so.
    – Lawrence
    Commented Jul 4, 2014 at 1:13
  • There cannot be any outage on this machine :) Commented Jul 4, 2014 at 10:23
  • 1
    What about fail2ban
    – totti
    Commented Jul 7, 2014 at 14:50
  • 1
    You can monitor traffic or check open ports, but you would probably miss seldom, but important outgoing traffic (special security updates, mails sent in rare cases, ...). As long as you only want to filter incoming traffic, monitoring could be an option.
    – jofel
    Commented Jul 7, 2014 at 17:08
  • This is quite possible to do, you can script a way to build a rule set from the running applications and exposed ports. But you really don't want to do this because 1) in most cases not all services need to be exposed to the network and 2) there could be services that you absolutely do not want to have exposed to the network. Instead do it by hand, once, setup a good rule set and go from there. One way to do it safely is to build the rule set with ESTABLISHED/RELATED and ACCEPT rules then check the relevant rules are matching the traffic. When you are happy, change the INPUT policy to drop.
    – Pedro
    Commented Feb 20, 2018 at 9:11

7 Answers 7

2

Do it manually

sudo ss -tuanp

or

sudo netstat -tuanp

Explanation:

-t - show tcp sockets
-u - show udp sockets
-a - show all sockets
-n - show numeric, don't resolve 
-p - show process name
1

Run tcpdump on the machine for a week or so to capture the average traffic. Then you can browse the traffic using wireshark later to see what ports are being used.

The command for this would be tcpdump -i <interface> -s 65535 -w <some-file>

You can then map this back using netstat -tuanp to see what PIDs/applications are using what ports.

Theoretically this could be scripted.

1

You can start with a very basic template like- https://gist.github.com/jirutka/3742890, which only allow ssh and ping, and add any thing else manually.

a quick script hack to generate iptables rules for your application listening on the public interface (0.0.0.0) /tcp

netstat -lnpt | egrep '0.0.0.0:[0-9]+' | awk '{print $4,$7}' | \
sed -E -e 's/0.0.0.0://g' -e 's|[0-9]+/||' | \
awk '{printf ("iptables -A INPUT -p tcp --dport %5d --syn -m conntrack --ctstate NEW -m comment %s \n", $1,$2) }'

you can also use the iptables -I INPUT <number> to inject the rules in a specific location, which you can list with iptables -nvL --line-numbers INPUT

1

Unfortunately there is no such script that I've ever seen that can run in a learning mode or passive mode logging all your network usage, taking its results and generating an actual firewall using iptables from its logs.

Your best bet is going to be to start simple and continuously keep adding the various pieces as you begin to fully understand what services your system is providing. You'll need to make use of tools such as netstat to see what ports are in use for the various services you host, as well as what IP addresses are accessing them.

$ sudo netstat -tlpn
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address               Foreign Address             State       PID/Program name   
tcp        0      0 0.0.0.0:25                  0.0.0.0:*                   LISTEN      26292/sendmail      
tcp        0      0 0.0.0.0:890                 0.0.0.0:*                   LISTEN      26149/ypbind        
tcp        0      0 0.0.0.0:445                 0.0.0.0:*                   LISTEN      26321/smbd          
tcp        0      0 127.0.0.1:2207              0.0.0.0:*                   LISTEN      26226/python        
tcp        0      0 127.0.0.1:2208              0.0.0.0:*                   LISTEN      26221/./hpiod       
tcp        0      0 127.0.0.1:199               0.0.0.0:*                   LISTEN      26237/snmpd         
tcp        0      0 0.0.0.0:809                 0.0.0.0:*                   LISTEN      26067/rpc.statd     
tcp        0      0 0.0.0.0:139                 0.0.0.0:*                   LISTEN      26321/smbd          
tcp        0      0 0.0.0.0:587                 0.0.0.0:*                   LISTEN      26292/sendmail      
tcp        0      0 0.0.0.0:111                 0.0.0.0:*                   LISTEN      26038/portmap       
tcp        0      0 0.0.0.0:35604               0.0.0.0:*                   LISTEN      -                   
tcp        0      0 0.0.0.0:22                  0.0.0.0:*                   LISTEN      26249/sshd          
tcp        0      0 0.0.0.0:631                 0.0.0.0:*                   LISTEN      26257/cupsd         
tcp        0      0 :::22                       :::*                        LISTEN      26249/sshd          
tcp        0      0 :::631                      :::*                        LISTEN      26257/cupsd         

NOTE: In the above you can see what services I have running on a server that are accepting TCP connections, i.e. they're "listening" for connections on various ports.

It's a no-brainier to start with things like SSH (port 22) and HTTP (port 80), if these are typical to your system, so I would do these types of services in mass all at once. For other services such as LDAP or NIS you may want to do these in a more controlled manner, making sure things do not break as you introduce them.

Tools such as FireHOL, Firewall Builder (fwbuilder), and eztables may be helpful as you attack this project, since they provide a nice layer of abstraction from having to build custom iptable rules by hand, which can be tricky.

FireHOL

FireHOL is a language (and a program to run it) which builds secure, stateful firewalls of any complexity from easy to understand, human-readable configurations.

example

transparent_squid 8080 "squid root" inface eth0

interface eth0 mylan
    policy accept

interface ppp+ internet
    server smtp accept
    server http accept
    server ftp  accept
    server ssh  accept src example.firehol.org

    client all  accept

router mylan2internet inface eth0 outface ppp+
    masquerade
    route all accept
fwbuilder

Fwbuilder is a unique graphical firewall tool that allows the user to create objects and then drag and drop those objects into firewalls, to build a powerful security system for a single PC or a network of PCs. Fwbuilder supports a wide range of firewalls (Cisco ASA/PIX, Linux iptables, FreeBSD's ipfilter, OpenBSD's pf, and more), so its rules can be deployed on multiple platforms. Let's take a look at using Fwbuilder on Linux, which might just become a life-long affair with a powerful security system.

example

   ss fwbuilder

eztables

Eztables allows you to quickly configure a firewall without ever touching iptables. The firewall rule syntax is designed to be easy to read and to apply.

This is how you allow the entire internet to access your webserver on TCP-port 80:

  allow_in any $eth0 any 80/tcp

Eztables is designed to be simple, yet powerful. It doesn't matter if you want to protect your laptop, are setting up a home router, or building a company firewall.

Using Fail2Ban

With a rudimentary iptables firewall in place you'll likely want to compliment it using a tool such as Fail2Ban.

excerpt

Fail2ban scans log files (e.g. /var/log/apache/error_log) and bans IPs that show the malicious signs -- too many password failures, seeking for exploits, etc. Generally Fail2Ban is then used to update firewall rules to reject the IP addresses for a specified amount of time, although any arbitrary other action (e.g. sending an email) could also be configured. Out of the box Fail2Ban comes with filters for various services (apache, courier, ssh, etc).

Using tools such as this will help limit the exposure that your system will have to endure as you continue to harden it. Even after you're fairly convinced that your system has been hardened, you may still want to continue using Fail2Ban as part of your security measures.

References

0

Use iptable rules to log the new connections, that will logs udp too .

iptables -I INPUT -m state --state NEW -j LOG --log-prefix "New inbound connection: "
iptables -I OUTPUT -m state --state NEW -j LOG --log-prefix "New outbound connection: "

You can specify different --log-level to have the logs in another file than /var/log/messages (you will have to configure the syslog daemon).

I think you should read the main application logs as some server have a very periodic activity like noon, end of week, end of month (quarter, year) so you will not miss an important network activity of the server.

As the server is critical, makes the network flow matrix of the server on a nice spreadsheet (ip source,ip dest,protocol,port,application) that will helps you to build the rules.

0

I know this is not a script and it's not an answer to OP's question but it's an idea of mine that I want to share with OP.

I got all listening ports with:

netstat -an | egrep 'tcp .*LISTEN' | awk -F" " '{print $4}' | awk -F":" '{print $NF}'

Maybe this can get you any closer to writing your own script. :)

0

You can start with something like this:

netstat -n -l -p | egrep "^(tcp|tcp6|udp)" | grep LISTEN | sed -r 's!^(tcp|tcp6|udp)\s.*:([0-9]+).*LISTEN\s+.*/(.*)!iptables -A INPUT -p \1 --dport \2 -j ACCEPT # \3!'

and then follow it up with

iptables -P INPUT DROP

or

iptables -A INPUT -j REJECT --reject-with icmp-host-prohibited

What the first line does is use netstat to list the listening processes and their ports. It will then generate "iptables" lines to allow for each of those incoming connections. The little sed regex substitution was customized for the netstat output on my server, so it might require some tweaking for you. When it works, you should end up with something looking like:

iptables -A INPUT -p tcp --dport 111 -j ACCEPT # rpcbind       
iptables -A INPUT -p tcp --dport 22 -j ACCEPT # sshd          
iptables -A INPUT -p tcp --dport 25 -j ACCEPT # master        
iptables -A INPUT -p tcp --dport 3306 -j ACCEPT # mysqld        
iptables -A INPUT -p tcp --dport 49476 -j ACCEPT # rpc.statd     
iptables -A INPUT -p tcp --dport 5432 -j ACCEPT # postgres.bin  
iptables -A INPUT -p tcp --dport 55371 -j ACCEPT # rpc.statd

Two important things to note:

1) These rules do nothing for you until you put a DROP or REJECT line at the end or make that the default policy for unmatched packets. These rules allow packets, which is moot, if the default policy is allow anything not matched.

2) These rules are ambivalent about the source IP. From your original post, it sounds like you want to allow all of your clients to use the server, then, examine the logs to obtain source IP's to go with the destination ports. I don't know of a tool to do that, so this script will only prevent people from making new services on your server which listen on other ports... which is something.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .