How to Block All Ports Except 1962, 999, and 12020 in Ubuntu Using iptables


2 views

When securing an Ubuntu server, one common task is restricting network access to only essential ports. In this case, we need to allow traffic on ports 1962 (SSH), 999, and 12020 while blocking everything else. This requires proper iptables configuration.

Your existing iptables rules show some basic setup but don't fully implement the desired port restrictions:


*filter
:INPUT ACCEPT [643490:136950781]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [645723:99904505]
-A INPUT -p tcp -m tcp --dport 1962 -j ACCEPT 
-A INPUT -p tcp -m tcp --dport 999 -j ACCEPT 
COMMIT

This configuration has two main issues:

  • It only blocks TCP ports (not UDP)
  • It's missing the 12020 port allowance

Here's a comprehensive iptables configuration that properly implements the required restrictions:


*filter
# Default policies
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]

# Allow localhost traffic
-A INPUT -i lo -j ACCEPT
-A OUTPUT -o lo -j ACCEPT

# Allow established connections
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# Allow specific ports
-A INPUT -p tcp --dport 1962 -j ACCEPT  # SSH
-A INPUT -p tcp --dport 999 -j ACCEPT    # Script port 1
-A INPUT -p tcp --dport 12020 -j ACCEPT  # Script port 2

# Allow ICMP (ping)
-A INPUT -p icmp -j ACCEPT

# Log dropped packets (optional)
-A INPUT -j LOG --log-prefix "IPTABLES DROP: "

COMMIT

To apply these rules:

  1. Save the configuration to a file (e.g., /etc/iptables.rules)
  2. Apply the rules: sudo iptables-restore < /etc/iptables.rules
  3. Make the rules persistent: sudo apt-get install iptables-persistent

For a more robust solution:

  • Consider rate limiting for SSH (port 1962) to prevent brute force attacks
  • Add UDP rules if your scripts use UDP protocols
  • Regularly monitor your iptables logs for suspicious activity

After applying the rules, verify them with:


sudo iptables -L -v

This will show you the current rules and packet counts, confirming your configuration is active.


When working with iptables in Ubuntu, it's crucial to understand that the default policy for all chains is typically ACCEPT. This means any incoming/outgoing traffic is allowed unless explicitly blocked. Your current configuration shows:


*filter
:INPUT ACCEPT [643490:136950781]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [645723:99904505]

This permissive setup isn't ideal for security. Let's implement a whitelist approach.

First, we'll set default policies to DROP all traffic, then selectively allow what we need:


sudo iptables -P INPUT DROP
sudo iptables -P FORWARD DROP
sudo iptables -P OUTPUT DROP

For your specific needs (SSH on 1962 and scripts on 999, 12020), we'll create explicit rules:


# Allow established/related connections
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

# Allow loopback interface
sudo iptables -A INPUT -i lo -j ACCEPT
sudo iptables -A OUTPUT -o lo -j ACCEPT

# Allow specific ports
sudo iptables -A INPUT -p tcp --dport 1962 -j ACCEPT   # SSH
sudo iptables -A INPUT -p tcp --dport 999 -j ACCEPT    # Script 1
sudo iptables -A INPUT -p tcp --dport 12020 -j ACCEPT  # Script 2

# Allow outgoing connections from these ports
sudo iptables -A OUTPUT -p tcp --sport 1962 -j ACCEPT
sudo iptables -A OUTPUT -p tcp --sport 999 -j ACCEPT
sudo iptables -A OUTPUT -p tcp --sport 12020 -j ACCEPT

Your scripts might need DNS resolution and some outbound connections:


# Allow DNS resolution
sudo iptables -A OUTPUT -p udp --dport 53 -j ACCEPT
sudo iptables -A OUTPUT -p tcp --dport 53 -j ACCEPT

# Allow outbound HTTP/HTTPS if needed
sudo iptables -A OUTPUT -p tcp --dport 80 -j ACCEPT
sudo iptables -A OUTPUT -p tcp --dport 443 -j ACCEPT

# Allow ICMP (ping)
sudo iptables -A INPUT -p icmp -j ACCEPT
sudo iptables -A OUTPUT -p icmp -j ACCEPT

To make changes persistent across reboots:


sudo apt install iptables-persistent
sudo netfilter-persistent save

Check your rules with:


sudo iptables -L -n -v

You should see output similar to:


Chain INPUT (policy DROP 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 ACCEPT     all  --  lo     *       0.0.0.0/0            0.0.0.0/0
 1234 98765 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:1962
  567 43210 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:999
  890 65432 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:12020

Chain OUTPUT (policy DROP 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 ACCEPT     all  --  *      lo      0.0.0.0/0            0.0.0.0/0
  123 45678 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp spt:1962
   45 67890 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp spt:999
   67 89012 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp spt:12020

For enhanced security:


# Rate limiting SSH connections
sudo iptables -A INPUT -p tcp --dport 1962 -m conntrack --ctstate NEW -m limit --limit 3/min --limit-burst 3 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 1962 -m conntrack --ctstate NEW -j DROP

# Log dropped packets (optional)
sudo iptables -N LOGGING
sudo iptables -A INPUT -j LOGGING
sudo iptables -A LOGGING -m limit --limit 2/min -j LOG --log-prefix "IPTables-Dropped: " --log-level 4
sudo iptables -A LOGGING -j DROP

For simpler management, you could use ufw instead:


sudo ufw default deny incoming
sudo ufw default deny outgoing
sudo ufw allow 1962/tcp
sudo ufw allow 999/tcp
sudo ufw allow 12020/tcp
sudo ufw allow out 53/udp  # DNS
sudo ufw allow out 80/tcp  # HTTP
sudo ufw allow out 443/tcp # HTTPS
sudo ufw enable