INN2 Restricted Access with iptables

Overview

This guide implements defense-in-depth security for INN2 servers using iptables firewall rules. The architecture restricts public access while maintaining Tor hidden service connectivity and whitelisted peer access.

Security Model: Zero-trust by default. All incoming connections blocked except explicitly whitelisted peers and localhost (for Tor).
Internet (Blocked) Tor Network ↓ ↓ ✗ Tor Daemon ↓ ↓ [iptables DROP] 127.0.0.1:119 ↓ Whitelisted Peers → [iptables ACCEPT] → INN2 Server (Explicit IPs) (port 119)

Architecture Goals

Prerequisites

# Ensure iptables is installed
sudo apt install iptables iptables-persistent -y

# Verify INN is running
sudo systemctl status innd

# Verify Tor is configured (if using hidden service)
sudo systemctl status tor

iptables Configuration

Step 1: Flush Existing Rules

# Clear all existing rules (CAREFUL: may disconnect SSH)
sudo iptables -F
sudo iptables -X
sudo iptables -Z
SSH Warning: If managing server remotely, ensure SSH rule is in place before flushing:
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT

Step 2: Set Default Policies

# Default DROP for incoming, ACCEPT for outgoing
sudo iptables -P INPUT DROP
sudo iptables -P FORWARD DROP
sudo iptables -P OUTPUT ACCEPT

Step 3: Allow Localhost (Critical for Tor)

# Allow all localhost traffic (required for Tor)
sudo iptables -A INPUT -i lo -j ACCEPT
sudo iptables -A OUTPUT -o lo -j ACCEPT
Why Localhost Matters: Tor daemon connects to INN via 127.0.0.1:119. Without this rule, Tor hidden service will fail to reach INN.

Step 4: Allow Established Connections

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

Step 5: Whitelist Peer Servers

# Add your trusted peer IPs (replace with actual IPs)
sudo iptables -A INPUT -p tcp -s 203.0.113.10 --dport 119 -j ACCEPT
sudo iptables -A INPUT -p tcp -s 198.51.100.20 --dport 119 -j ACCEPT
sudo iptables -A INPUT -p tcp -s 192.0.2.30 --dport 119 -j ACCEPT

# Allow entire subnet (if needed)
sudo iptables -A INPUT -p tcp -s 203.0.113.0/24 --dport 119 -j ACCEPT

Step 6: Allow Essential Services

# Allow SSH (if managing remotely)
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT

# Allow HTTP/HTTPS (if running web server)
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT

Step 7: Log Dropped Connections (Optional)

# Log dropped NNTP attempts (before final DROP)
sudo iptables -A INPUT -p tcp --dport 119 -m limit --limit 5/min -j LOG --log-prefix "NNTP-DROP: " --log-level 4

# Final DROP (implicit due to default policy, but explicit for clarity)
sudo iptables -A INPUT -j DROP

Complete iptables Script

Create a persistent firewall configuration:

sudo nano /etc/iptables/rules.v4
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]

# Localhost (CRITICAL for Tor)
-A INPUT -i lo -j ACCEPT

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

# SSH (adjust port if non-standard)
-A INPUT -p tcp --dport 22 -j ACCEPT

# HTTP/HTTPS (if web server)
-A INPUT -p tcp --dport 80 -j ACCEPT
-A INPUT -p tcp --dport 443 -j ACCEPT

# Whitelisted NNTP peers
-A INPUT -p tcp -s 203.0.113.10 --dport 119 -j ACCEPT
-A INPUT -p tcp -s 198.51.100.20 --dport 119 -j ACCEPT
-A INPUT -p tcp -s 192.0.2.30 --dport 119 -j ACCEPT

# Log dropped NNTP attempts
-A INPUT -p tcp --dport 119 -m limit --limit 5/min -j LOG --log-prefix "NNTP-DROP: " --log-level 4

COMMIT

Apply Rules

# Load rules
sudo iptables-restore < /etc/iptables/rules.v4

# Make persistent across reboots
sudo netfilter-persistent save

Verification

Test Localhost Access (Tor)

# Should succeed (Tor uses localhost)
telnet 127.0.0.1 119

Test Public Access (Should Fail)

# From external machine, should timeout/refuse
telnet YOUR_PUBLIC_IP 119

Test Whitelisted Peer

# From whitelisted IP, should succeed
telnet YOUR_SERVER_IP 119

View Active Rules

# List all rules
sudo iptables -L -n -v

# Check specific chain
sudo iptables -L INPUT -n -v --line-numbers

Monitor Dropped Connections

# View firewall logs
sudo tail -f /var/log/syslog | grep NNTP-DROP

# Count dropped attempts
sudo grep "NNTP-DROP" /var/log/syslog | wc -l

INN Configuration Alignment

Ensure INN readers.conf matches firewall policy:

sudo nano /etc/news/readers.conf
# Localhost (for Tor)
auth "localhost" {
    hosts: "localhost, 127.0.0.1, ::1"
    default: "<localhost>"
}

access "localhost" {
    users: "<localhost>"
    newsgroups: "*"
    access: RPA
}

# Whitelisted peers only
auth "peers" {
    hosts: "203.0.113.10, 198.51.100.20, 192.0.2.30"
    default: "<peer>"
}

access "peers" {
    users: "<peer>"
    newsgroups: "*"
    access: RPA
}
Defense in Depth: Both iptables AND readers.conf restrict access. If firewall is bypassed, INN still enforces access control.

Managing Peer Whitelist

Add New Peer

# Add iptables rule
sudo iptables -I INPUT 6 -p tcp -s NEW_PEER_IP --dport 119 -j ACCEPT

# Save changes
sudo netfilter-persistent save

# Add to readers.conf
sudo nano /etc/news/readers.conf
# Add NEW_PEER_IP to hosts: line

# Reload INN
sudo systemctl reload innd

Remove Peer

# Find rule number
sudo iptables -L INPUT -n -v --line-numbers

# Delete rule (replace X with line number)
sudo iptables -D INPUT X

# Save changes
sudo netfilter-persistent save

IPv6 Configuration

Apply same rules for IPv6:

sudo nano /etc/iptables/rules.v6
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]

# Localhost
-A INPUT -i lo -j ACCEPT

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

# SSH
-A INPUT -p tcp --dport 22 -j ACCEPT

# Whitelisted peers (IPv6)
-A INPUT -p tcp -s 2001:db8::10 --dport 119 -j ACCEPT

COMMIT
sudo ip6tables-restore < /etc/iptables/rules.v6
sudo netfilter-persistent save

Troubleshooting

Tor Can't Connect to INN

# Verify localhost rule exists
sudo iptables -L INPUT -n -v | grep "127.0.0.1"

# Test directly
telnet 127.0.0.1 119

# Check Tor logs
sudo journalctl -u tor -f

Legitimate Peer Blocked

# Verify peer IP is whitelisted
sudo iptables -L INPUT -n -v | grep PEER_IP

# Check if IP changed (dynamic IP issue)
dig +short peer.example.net

# Temporarily allow for testing
sudo iptables -I INPUT 1 -p tcp -s PEER_IP --dport 119 -j ACCEPT

Reset Firewall (Emergency)

# ACCEPT all (removes restrictions)
sudo iptables -P INPUT ACCEPT
sudo iptables -P FORWARD ACCEPT
sudo iptables -P OUTPUT ACCEPT
sudo iptables -F
Emergency Reset: Only use if locked out. Server becomes unprotected until rules are reapplied.

Automated Peer Management Script

sudo nano /usr/local/bin/inn-peer-manager.sh
#!/bin/bash
# INN Peer Whitelist Manager

ACTION=$1
PEER_IP=$2

case "$ACTION" in
  add)
    echo "Adding peer: $PEER_IP"
    iptables -I INPUT 6 -p tcp -s $PEER_IP --dport 119 -j ACCEPT
    netfilter-persistent save
    echo "Peer $PEER_IP added. Update readers.conf manually."
    ;;
  remove)
    echo "Removing peer: $PEER_IP"
    RULE_NUM=$(iptables -L INPUT -n --line-numbers | grep "$PEER_IP" | grep "dpt:119" | awk '{print $1}')
    if [ -n "$RULE_NUM" ]; then
      iptables -D INPUT $RULE_NUM
      netfilter-persistent save
      echo "Peer $PEER_IP removed."
    else
      echo "Peer $PEER_IP not found."
    fi
    ;;
  list)
    echo "Current NNTP peers:"
    iptables -L INPUT -n -v | grep "dpt:119"
    ;;
  *)
    echo "Usage: $0 {add|remove|list} [PEER_IP]"
    exit 1
    ;;
esac
sudo chmod +x /usr/local/bin/inn-peer-manager.sh

# Usage
sudo /usr/local/bin/inn-peer-manager.sh add 203.0.113.50
sudo /usr/local/bin/inn-peer-manager.sh list
sudo /usr/local/bin/inn-peer-manager.sh remove 203.0.113.50

Security Best Practices

Next Steps