1

I am trying to block the entire Internet on all ports, but allow a multiple ranges to connect on specific ports. I want this ruleset to apply to outbound connections as well (using REJECT instead of DROP) as to prevent identification attacks.

*filter

# Allow all loopback (lo0) traffic and drop all traffic to 127/8 that doesn't use lo0
-A INPUT -i lo -j ACCEPT
-A INPUT -d 127.0.0.0/8 -j REJECT

# Accept all established inbound connections
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# Allow all network traffic
-A INPUT -s 192.168.0.0/24 -j ACCEPT
-A INPUT -d 192.168.0.0/24 -j ACCEPT

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


# Permitted web connections
-A INPUT -s 8.4.0.0/24 -p tcp --dport http  -j ACCEPT
-A INPUT -s 8.8.0.0/24 -p tcp --dport http  -j ACCEPT
-A INPUT -s 8.4.0.0/24 -p tcp --dport https -j ACCEPT
-A INPUT -s 8.8.0.0/24 -p tcp --dport https -j ACCEPT

-A OUTPUT -s 8.4.0.0/24 -p tcp --dport http  -j ACCEPT
-A OUTPUT -s 8.8.0.0/24 -p tcp --dport http  -j ACCEPT
-A OUTPUT -s 8.4.0.0/24 -p tcp --dport https -j ACCEPT
-A OUTPUT -s 8.8.0.0/24 -p tcp --dport https -j ACCEPT

# Reject all web not to or from a safe server
-A INPUT  -p tcp --dport http  -j DROP
-A INPUT  -p tcp --dport https -j DROP
-A OUTPUT -p tcp --dport http  -j REJECT
-A OUTPUT -p tcp --dport https -j REJECT


# Drop all other inbound - default deny unless explicitly allowed
-A INPUT   -j DROP
-A FORWARD -j DROP

COMMIT

The drawback with my very strict policy is the verbosity of adding an additional range. Each range takes four lines of policy to work. Inbound/HTTP, Inbound/HTTPS, Outbound/HTTP, Outbound/HTTP. It's a huge pain to keep straight.

What I would like it something like this:

# Pseucode
*group webservers
8.8.0.0/24
8.4.0.0/24

*filter
-A INPUT -s webservers -p tcp --dport http  -j ACCEPT
-A INPUT -s webservers -p tcp --dport http  -j ACCEPT
-A OUTPUT -s webservers -p tcp --dport http  -j ACCEPT
-A OUTPUT -s webservers -p tcp --dport http  -j ACCEPT

Is there an easy way to accomplish this?

Josh
  • 155
  • 8

2 Answers2

2

You might want to try using ipsets

If you want to

  • store multiple IP addresses or port numbers and match against the collection by iptables at one swoop;
  • dynamically update iptables rules against IP addresses or ports without performance penalty;
  • express complex IP address and ports based rulesets with one single iptables rule and benefit from the speed of IP sets

then ipset may be the proper tool for you.

Worth noting that:

IP sets are a framework inside the Linux kernel, which can be administered by the ipset utility

And yes, the website looks like it hasn't been updated since 1996. For some reason computer security news sources and low-level software / firmware project webpages look like that a lot.

Parthian Shot
  • 1,165
  • 4
  • 16
  • 32
1

You can also try sending all the traffic from certain ranges to a custom chain, then each port-related accept becomes a single line:

iptables -N CUSTOM

iptables -I INPUT 1 -s 8.4.0.0/24 -j CUSTOM
iptables -I INPUT 2 -s 8.8.0.0/24 -j CUSTOM
etc.

iptables -A CUSTOM - p tcp --dport 80 -j ACCEPT
iptables -A CUSTOM - p tcp --dport 443 -j ACCEPT
etc.

Packets from the source range(s) sent to the CUSTOM chain that don't match an ACCEPT there will come back to the INPUT chain for handling (ie, DROPping) with all the rest of the unwanted traffic.

MadHatter
  • 79,770
  • 20
  • 184
  • 232