Overview
Whether your web application server is behind a hardware firewall or not, an internal firewall should also be used to further protect the server. Your web server should not be able to communicate with any other servers, unless communication is required by your application. And even then, only the ports, protocols, and packet directions needed should be allowed. All other incoming and outgoing communications should be blocked. Fencing your server off in this manner prevents attackers from using it as a gateway into other servers in your environment. It also lessens the risk of your server sending unsolicited communications from ports and protocols not defined in your policy. In this lab I will guide you through creating a baseline firewall policy using IPtables for a web server.
Lab Configuration
The lab will consist of the following server configurations:
Name | OS | Role | Network Interface |
---|---|---|---|
WEBAPP01 | Ubuntu 13.10 | Web Application Server | ETH0 – 172.30.0.50 |
WEBDB01 | Ubuntu 13.10 | MySQL Database Server | ETH0 – 172.16.0.22 |
And the following networks exist in the environment.
Network | Purpose |
---|---|
172.30.0.0/24 | DMZ |
172.16.0.0/24 | Internal Production Servers |
172.20.0.0/24 | Internal network for IT |
Firewall Policy
Always define a firewall policy for your publicly accessable servers and enforce it. Your company or web application may have different requirements, however, as an example, the following policy will be applied to our firewall on our web server and its database server.
- All incoming and outgoing connections are to be dropped by default.
- Only allow incoming SSH connections from internal network.
- Only allow tcp connections on port 3306 between Webapp01 and Webdb01.
Disabled UFW
UFW is a basic frontend for Iptables on Ubuntu computers. Since we’re going to use IPtables directory to allow for more custom rules, we need to ensure UFW isn’t enabled.
- Check to see if UFW is enabled.
sudo ufw status
- If UFW is enabled, disable it.
sudo ufw disable
Create a Base Policy Script
- Create a new file named iptables-policy.sh
- Add the following lines to the file:
# Drop all packets by default iptables -P INPUT DROP iptables -P FORWARD DROP iptables -P OUTPUT DROP # Drop invalid packets iptables -A INPUT -m state --state INVALID -j DROP iptables -A FORWARD -m state --state INVALID -j DROP iptables -A OUTPUT -m state --state INVALID -j DROP iptables -A INPUT -p TCP -m tcp --tcp-flags SYN,FIN SYN,FIN -j DROP iptables -A INPUT -p TCP -m tcp --tcp-flags SYN,RST SYN,RST -j DROP # Allow remote ssh connections from internal network only. iptables -A INPUT -i eth0 -s 172.20.0.0/24 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT iptables -A OUTPUT -o eth0 -d 172.20.0.0/24 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT # Allow MySQL queries to and responses from our database server, WEBDB01, only. iptables -A OUTPUT -o eth0 -d 172.16.0.22 -p tcp --dport 1306 -m state --state NEW,ESTABLISHED -j ACCEPT iptables -A INPUT -i eth0 -s 172.16.0.22 -p tcp --sport 1306 -m state --state ESTABLISHED -j ACCEPT # Allow HTTP traffic in iptables -A INPUT -i eth0 -p TCP --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT iptables -A OUTPUT -o eth0 -p TCP --sport 80 -m state --state ESTABLISHED -j ACCEPT # Save and apply policy /sbin/service iptables save
- Save changes to the script file and exit the text editor.
- Ensure the script can be executed by you.
sudo chmod u+x ./iptables-policy.sh
- Run the script to apply the new policy.
./iptables-policy.sh
Allow Installs from Ubuntu Repositories
You’re eventually going to need to install system updates or new applications from the Ubuntu repository. Our base policy blocks all new outgoing HTTP connections. To allow these connections, we need to add a few extra lines to our policy script.
- Open iptables-policy.sh into a text editor.
- Above the iptables save command, add the following lines:
# Allow HTTP traffic out iptables -A OUTPUT -o eth0 -p TCP --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT iptables -A INPUT -i eth0 -p TCP --sport 80 -m state --state ESTABLISHED -j ACCEPT
- Save changes and exit the text editor.
- This will allow HTTP connections out, but without DNS you won’t be able to do name resolution. To allow DNS lookups, see Allow DNS Lookups below.
Allow DNS Lookups
Unless you allow DNS related connections out, you will need to connect to everything via an IP address. To allow queries to a DNS server, we need to add another rule.
- Open iptables-policy.sh into a text editor.
- Above the iptables save command, add the following lines:
# Allow DNS lookups iptables -A OUTPUT -o eth0 -p UDP --dport 53 -m state --state NEW,ESTABLISHED -j ACCEPT iptables -A INPUT -i eth0 -p UDP --sport 53 -m state --state ESTABLISHED -j ACCEPT
- Save your changes and exit the text editor.
- Execute the iptables-policy.sh script to apply our new rules.