Simple iptables Rules for Ubuntu/ Debian VPS

Simple iptables Rules for Ubuntu/ Debian VPS

Get Social!

The following iptables rules are are a starting point to add basic firewall security to a public facing server, such as a public VPS. The primary focus is to stop any inbound traffic other than SSH, which is required for shell access.

[the_ad id=”2698″]

The biggest issue with public VPS providers is that often some iptables features are disabled – many OpenVZ container providers don’t allow state checking in iptables, for example. If you’ve got one of these VPS’s you’ll likely see the following error:

iptables: No chain/target/match by that name.

These rules are engineered so that they will work with most VPS’s where iptables is installed.

The following rules will block all incoming connections except SSH, including PING requests. Outgoing is open for HTTP and HTTPS TCP requests and DNS UDP requests.

See the links at the bottom of the page for a more in depth look at iptables rules.

# Loopback
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT

# Inbound SSH
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A OUTPUT -p tcp --sport 22 -j ACCEPT

# Outbound HTTP/S
iptables -A OUTPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --sport 80 -j ACCEPT
iptables -A OUTPUT -p tcp --dport 443 -j ACCEPT
iptables -A INPUT -p tcp --sport 443 -j ACCEPT

# Outbound DNS
iptables -A OUTPUT -p udp --dport 53 -j ACCEPT
iptables -A INPUT -p udp --sport 53 -j ACCEPT

# default policy
iptables -P INPUT DROP
iptables -P FORWARD DROP

If you’re using Ubuntu, you can easily make the rules persist:

apt-get install iptables-persistent
service iptables save


Basic IPTable Rules

Category : How-to

Get Social!

Here are some basic IPTable rules to enable essential connectivity from the host. Outbound connectivity such as ping, DNS and HTTP are all enabled, along with inbound SSH.

All external sources are enabled for SSH so it’s advisable to restrict this further once you’re up and running. This IPTables script is intended to be a starting point and may need to be tailored for your security requirements.

Paste the below script in order to get started.

Optional, run iptables -F to clear existing rules.

iptables -F


# Loopback
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT

# Established
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -m conntrack --ctstate ESTABLISHED -j ACCEPT

# Drop invalid
iptables -A INPUT -m conntrack --ctstate INVALID -j DROP

# Incoming SSH
iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp --sport 22 -m conntrack --ctstate ESTABLISHED -j ACCEPT

# Outgoing HTTPS
iptables -A OUTPUT -o eth0 -p tcp --dport 443 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --sport 443 -m state --state ESTABLISHED -j ACCEPT

# Outgoing HTTP
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

# Outgoing DNS
iptables -A OUTPUT -p udp -o eth0 --dport 53 -j ACCEPT
iptables -A INPUT -p udp -i eth0 --sport 53 -j ACCEPT

# Outgoing Ping
iptables -A OUTPUT -p icmp --icmp-type echo-request -j ACCEPT
iptables -A INPUT -p icmp --icmp-type echo-reply -j ACCEPT

# Default chain
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT DROP

See the cheat sheet for more information.

Set up Linux PPTP Client from the Terminal

Get Social!

Linux penguinA Virtual Private Network, or VPN, allows the client computer to connect to a remote local network to use it’s resources such as printers and file shares. There are several types of VPN such as PPTP and LP2SEC with varying types of protection. PPTP is not the most secure type of VPN but its the easiest to set up.

PPTP has numerous security risks which means that the data you are transferring through your VPN can easily be unencrypted. L2TP/IPsec is becoming the standard VPN technology of choice. PPTP should not be used unless security of each end point and the data transferred is not required.

Take the quick VPN Poll to tell us what type of VPN you use.

This tutorial assumes you have a PPTP server already set up with the following details:

  • Hostname:
  • Username: pptpuser
  • Password: pptppassword

Open a Terminal and install the required PPTP client packages.

apt-get install pptp-linux network-manager-pptp

Create a credentials file with the username and password of the PPTP server:

vi /etc/ppp/chap-secrets

Add your entry using the below attributes

  • [USER] – user name to log in to the VPN server
  • [SERVER] – name of server to use, PPTP in our case.
  • [SECRET] – password of the above [USER].
  • [IP] – ip of the server, * means all IPs.
[USER]    [SERVER]    [SECRET]    [IP]


pptpuser    PPTP    pptppassword    *

Create a file which will be executed when the PPTP connection is started. This can contain additional commands to run when the connection is started such as adding new routes or firewall exceptions.

vi /etc/ppp/ip-up.d/route-traffic

The below examle script adds a route from the PPTP connection to any computers on the PPTP servers local network with IPs in the or ranges. This means that on the PPTP client, any machines on the above IP ranges will be accessible. This script may not be required for your environment and is simply used as an example. Note: a route should automatically be added to your VPN gateway.

route add -net ${NET1} dev ${IFACE}
route add -net ${NET2} dev ${IFACE}

Allow execution of the script:

chmod +x /etc/ppp/ip-up.d/route-traffic

Add the PPTP client connection pool and any additional settings which are required. The connection name,, can be changed to suite your connection. 

vi /etc/ppp/peers/

Add the details of the PPTP server. The below are the basic options required to connect to the server using mppe-128 encryption. Edit the below attributes to match your environment:

  • [USER] – user name to log in to the VPN server
  • [HOST] – host name or IP address of the PPTP server.
pty "pptp [HOST] --nolaunchpppd"
name [USER]
remotename PPTP
file /etc/ppp/options.pptp

You must add rules to your firewall to allow connections to and from this interface as well as through your existing public interface to make the PPTP connection.  The below rules open all traffic on the new pptp interface using iptables. You may need to change this once the connection has been tested to increase security.

iptables -A INPUT -i pptp -j ACCEPT
iptables -A OUTPUT -o pptp -j ACCEPT

Finally you will need to start your PPTP client connection. Use pon and poff to start and stop your PPTP client. Replace [CONNECTION] with the name you gave to the file in /etc/ppp/peers/.


See my script on automatically detecting a disconnect and restarting the PPTP client connection.

iptables cheat sheet

Get Social!

Here are a few handy commands for using iptables. They are tailored for an OpenVZ container with a venet network interface but can easily be adapted to use your interface by replacing venet0 with your network interface.

For setting up iptables in an openVZ this blog post.

iptables console

Remove existing rules

You can easily delete all existing rules in iptables. Be careful using this command, there is no going back unless you have backed up your rules.

iptables -F

Backup and restore

Backup to file

Rules can easily be saved to an external file for backups or outputting for version control. This will save the rules to /etc/iptables.rules.

iptables-save -c > /etc/iptables.rules

Restore from file

Saved settings can be restored with the following command:

iptables-restore > /etc/iptables.rules

Change the default policy

The default policy can be changed to specify what should happen to traffic which doesn’t have a rule to explicitly define what to do. You can specify to ACCEPT, REJECT or DROP for INPUT, FORWARD and OUTPUT.



Change INPUT to DROP

iptables -P INPUT DROP

Apply the catchall rule

You can add a rule to the bottom of the rule book to choose what to do with traffic which doesn’t match any other rule. A common use would be to add a DROP as the last rule to drop any traffic which isn’t explicitly allowed by an earlier rule. You can specify to ACCEPT, REJECT or DROP for INPUT, FORWARD and OUTPUT as well as an interface.

ACCEPT INPUT on interface lo

iptables -A INPUT -i lo -j ACCEPT

BLOCK INPUT on interface venet0

iptables -A INPUT -i venet0 -j DROP

List active rules

You can list the active rules with -L, and -v for information on packets affected.

iptables -L -v

Enable established connections rule

Already established connections will not be affected by adding this inbound rule. Traffic affected by other outbound rules will also be honoured. If you add this rule, you won’t likely need to specify inbound rules for many outbound rules.

iptables -A INPUT -i venet0 -m state --state RELATED,ESTABLISHED -j ACCEPT

Adding new rules

New rules can be added to control how traffic passes through an interface. If you have not used the Established connections rule then you will also need to add an outgoing rule. If you do use the Established connections rule then you will only need the top command in each of the below headings.

Add rule for port 80 – such as Apache

iptables -A INPUT -i venet0 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o venet0 -p tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT

Add rule for port 22 – SSH outbound connections

iptables -A OUTPUT -o venet0 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i venet0 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT

Add rule for 53 – DNS outbound

iptables -A OUTPUT -o venet0 -p udp -o eth0 --dport 53 -j ACCEPT
iptables -A INPUT -i venet0-p udp -i eth0 --sport 53 -j ACCEPT

Add rule for port 22 – SSH inbound connections

iptables -A INPUT -i venet0 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o venet0 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT

Add rule for outgoing http/ https

iptables -A OUTPUT -o venet0 -p tcp -m multiport --dport 80,443 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i venet0 -p tcp -m multiport --sports 80,443 -m state --state ESTABLISHED -j ACCEPT

Add rule for ping from remote to local

iptables -A INPUT -i venet0 -p icmp --icmp-type echo-request -j ACCEPT
iptables -A OUTPUT -o ventet -p icmp --icmp-type echo-reply -j ACCEPT

 Add rule for ping from local to remote

iptables -A OUTPUT -o venet0 -p icmp --icmp-type echo-request -j ACCEPT
iptables -A INPUT -i venet0 -p icmp --icmp-type echo-reply -j ACCEPT

Delete rule

The easiest way to remove a rule is to delete it by it’s rule position in the list. To find out the rules position run iptables -L with the line-number argument. The below command is to delete an INPUT command however you can easily change INPUT to OUTPUT as required.

iptables -L INPUT --line-numbers

Then run the delete command for the relevent direction. This will delete the 7th inbound rule.

iptables -D INPUT 7

Example deleting rule 1 for INPUT:

# iptables -L INPUT --line-numbers
Chain INPUT (policy DROP)
num  target     prot opt source               destination
1    ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:ssh state NEW,ESTABLISHED
2    ACCEPT     all  --  anywhere             anywhere             state RELATED,ESTABLISHED
3    ACCEPT     icmp --  anywhere             anywhere             icmp echo-reply
4    ACCEPT     icmp --  anywhere             anywhere             icmp echo-request

# iptables -D INPUT 1

# iptables -L INPUT --line-numbers
Chain INPUT (policy DROP)
num  target     prot opt source               destination
1    ACCEPT     all  --  anywhere             anywhere             state RELATED,ESTABLISHED
2    ACCEPT     icmp --  anywhere             anywhere             icmp echo-reply
3    ACCEPT     icmp --  anywhere             anywhere             icmp echo-request


Let me know in the comments if you think anything is missing.

iptables in a Ubuntu OpenVZ container

Get Social!

proxmox logo gradIf you need a software firewall to shield containers on a Proxmox stack, you should always use a firewall on the host to decide what traffic is allowed for each container. This brings some obvious benefits such as it’s centrally managed – one configuration location for all containers on the node, and security as a compromised container cannot change firewall settings.

However, in Proxmox 3.0+ you can use iptables in a container which also has it’s own benefits under certain circumstances. For example, you can test firewall rules for a new development container without risking other containers on the same host, and you don’t need to give people access to the host to modify the rules.

I have tried iptables using a Ubuntu 12.04 container template. It works as expected but requires some setup on both the guest container and the Proxmox host.


Proxmox – steps to perform on the Proxmox host

You will need to enable containers access to the required kernel modules. To do this, edit the vz config file:

vi /etc/vz/vz.conf

And edit the IPTABLES= line as below.

IPTABLES="ipt_REJECT ipt_tos ipt_limit ipt_multiport iptable_filter iptable_mangle ipt_TCPMSS ipt_tcpmss ipt_ttl ipt_length ipt_state"

Make sure the required modules are loaded by running the following in a console window as root:

modprobe xt_state
modprobe xt_tcpudp
modprobe ip_conntrack

 Container – steps to perform in the Ubuntu container

First, you need a console window in the host. Either use the GUI console window or use vzctl enter [VMID] to login to the container.

Install iptables using apt-get.

apt-get install iptables

Any changes you make to iptables, such as adding new rules, will be lost each time the service is restarted. This is obviously not ideal as all the rules will be lost every time the container reboots. To get round this we need to add a script to save the rules each time the network interface goes down, and one to load the rules when the interface starts up.

Create an iptables script to run when the network is started:

vi /etc/network/if-pre-up.d/iptables

And add the below script to load the rules into iptables:

iptables-restore < /etc/iptables.rules
exit 0

And when the network goes down:

vi /etc/network/if-post-down.d/iptables

To save the rules:

iptables-save -c > /etc/iptables.rules
exit 0

After your network is restarted, the current rules will be saved to /etc/iptables.rules. To add new rules, you can edit this file directly and load the settings or you can use the iptables commands to create the rules you require. More about that in my iptables cheat sheet.

Visit our advertisers

Quick Poll

What type of VPN protocol do you use?

Visit our advertisers