1

I recently got and setup a small linux (Debian) router box. I'm adding it to an existing network to create a small subnet with specific properties, namely internet content filtering. I'm highjacking http/https (80/443) traffic and pushing it through filtering services running on the box with:

$IPT -t nat -A PREROUTING -i eth1 -p tcp --dport 80 -j REDIRECT --to-port 8080
$IPT -t nat -A PREROUTING -i eth1 -p tcp --dport 443 -j REDIRECT --to-port 8080

While this works properly (when the client machines know about the https proxy) I can't get non-browser applications to work, namely the Steam client. It is supposed to use a range of TCP and UDP ports. I've tried making ACCEPT rules for those ranges for both TCP and UDP and for both dport and sport connections with no success.

Am I misunderstanding something about routing? I assume that I don't have to port forward anything because I'm the client, consuming their ports. I thought I just had to permit traffic on ports and that it would then forward along to the server endpoint and come back. Does anyone know how to allow the Steam client (or all traffic on all ports) in iptables?

SECOND EDIT (different code):

Based on comments I decided to try and update my script, taking out different lines I was trying and just making it accept everything. However it still doesn't seem to work, at least for Steam. This is my raw code without me trying to clean it up for this site, maybe I missed something when I did that.

#!/bin/sh
IPT=/sbin/iptables

# Flush all chains, to start with a clean slate.
$IPT -F
$IPT -t nat -F

# Set filter Policies. By default, ACCEPT everything.
$IPT -P INPUT ACCEPT
$IPT -P OUTPUT ACCEPT
$IPT -P FORWARD ACCEPT

# Set server INPUT rules.
$IPT -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPT -A INPUT -i eth1 -j ACCEPT
$IPT -A INPUT -i lo -j ACCEPT
$IPT -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
$IPT -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
$IPT -A INPUT -p icmp -m icmp --icmp-type echo-request -j ACCEPT

# Attempt to blanket statement accept everything (all ports, essentially)
$IPT -A INPUT -p tcp -m tcp --dport 0:65000 -j ACCEPT
$IPT -A INPUT -p udp -m udp --dport 0:65000 -j ACCEPT
$IPT -A FORWARD -p tcp -m tcp --dport 0:65000 -j ACCEPT
$IPT -A FORWARD -p udp -m udp --dport 0:65000 -j ACCEPT
$IPT -A OUTPUT -p tcp -m tcp --dport 0:65000 -j ACCEPT
$IPT -A OUTPUT -p udp -m udp --dport 0:65000 -j ACCEPT

# Accept minecraft, this is working
$IPT -A INPUT -p tcp -m tcp --dport 25565 -j ACCEPT
$IPT -A OUTPUT -p tcp -m tcp --dport 25565 -j ACCEPT
$IPT -A FORWARD -p tcp -m tcp --dport 25565 -j ACCEPT

# Set router FORWARD rules.
$IPT -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPT -A FORWARD -i eth1 -o eth0 -j ACCEPT

# Masquerade outgoing LAN traffic.
$IPT -t nat -A POSTROUTING -s 172.16.1.0/24 -o eth0 -j MASQUERADE

$IPT -t nat -A PREROUTING -i eth1 -p tcp --dport 80 -j REDIRECT --to-port 8080
$IPT -t nat -A PREROUTING -i eth1 -p tcp --dport 443 -j REDIRECT --to-port 8080

# Port forward minecraft, simple enough
$IPT -t nat -A PREROUTING -i eth0 -p tcp --dport 25565 -j DNAT --to-destination 172.16.1.100
4
  • 1
    What do the routes on the clients look like, what other iptables rules do you have in place, what is the default policy for each chain?
    – tink
    Apr 30, 2013 at 22:54
  • @tink I posted more of my code in the question. The clients are windows machines and don't have any special routes. I've just told the browsers about the proxy. I don't use chains other than the default input/output/forward as you can see above. Thanks for any help you can offer!
    – BlargleMonster
    Apr 30, 2013 at 23:37
  • So ... what do the windows boxes uses as their default GW, and how does it relate to the debian box? If the debian machine IS ther default GW you shouldn't have to tell the browsers about the proxy as the rules you have in place are valid for a transparent proxy. And all other traffic than http(s) is getting dropped.
    – tink
    May 1, 2013 at 1:22
  • @tink Ah yes, I didn't think of that. It is the default GW for them. The reason they have to know about it is because it breaks https since it would be a man in the middle attack to intercept that transparently. If I change the three DROP statements in the beginning to ACCEPT should it work? May 1, 2013 at 1:47

2 Answers 2

0

I was able to whitelist all the IP addresses used by Steam. Chances are they won't apply in your area (everything around here goes through Level 3's pipes), but I'll show you how I did it.

First, I have a custom chain that gets called from the FORWARD chain:

# Create chain to filter IP addresses
iptables -N zone_lan_filter

# Filter TCP and UDP traffic
iptables -A FORWARD -p tcp -j zone_lan_filter
iptables -A FORWARD -p udp -j zone_lan_filter

# Reject everything else
iptables -A FORWARD -p tcp -j REJECT
iptables -A FORWARD -p udp -j REJECT

The custom chain is literally just an enormous range of IP addresses:

# When a packet is sent to this chain, accept it if it matches any of the rules below
#
# Addresses in these ranges are registered to Valve Corporation and are used by Steam
iptables -A zone_lan_filter -p tcp -m iprange --dst-range 208.64.200.0-208.64.203.255 -j ACCEPT
iptables -A zone_lan_filter -p udp -m iprange --dst-range 208.64.200.0-208.64.203.255 -j ACCEPT
iptables -A zone_lan_filter -p tcp -m iprange --dst-range 205.196.6.0-205.196.6.255 -j ACCEPT
iptables -A zone_lan_filter -p udp -m iprange --dst-range 205.196.6.0-205.196.6.255 -j ACCEPT

This first group is used by Steam while signing in. Eventually, we have another list of IP addresses that belong to CDNs used by Steam for downloading games and patches:

# Addresses in these ranges are registered to Highwinds Network Group and are used by Steam
iptables -A zone_lan_filter -p tcp -m iprange --dst-range 205.185.217.0-205.185.217.255 -j ACCEPT
iptables -A zone_lan_filter -p udp -m iprange --dst-range 205.185.217.0-205.185.217.255 -j ACCEPT
iptables -A zone_lan_filter -p tcp -m iprange --dst-range 205.185.201.0-205.185.201.255 -j ACCEPT
iptables -A zone_lan_filter -p udp -m iprange --dst-range 205.185.201.0-205.185.201.255 -j ACCEPT

Next, we get to a list of IP addresses that belong to the major ISPs in my area. These are bound to be different anywhere outside of Colorado:

# Addresses in these ranges are registered to Level 3 Communications and are used by Steam
iptables -A zone_lan_filter -p tcp -m iprange --dst-range 162.97.0.0-162.97.255.255 -j ACCEPT
iptables -A zone_lan_filter -p udp -m iprange --dst-range 162.97.0.0-162.97.255.255 -j ACCEPT
iptables -A zone_lan_filter -p tcp -m iprange --dst-range 204.245.0.0-204.245.63.255 -j ACCEPT
iptables -A zone_lan_filter -p udp -m iprange --dst-range 204.245.0.0-204.245.63.255 -j ACCEPT

Finally, anything that wasn't whitelisted gets returned:

# If none of the rules above matched, return to previous chain
iptables -A zone_lan_filter -j RETURN

So how did I come up with those IP addresses? By logging everything in netfilter:

iptables -I FORWARD -j LOG --log-prefix "iptables_log: "

These get put into the system log, which you can view like so:

dmesg | grep iptables_log

With a destination IP address from dmesg, you can use whois to get the CIDR in use by the organization the IP address is registerd to.

whois will also give you a link to a page on ARIN that lists a whole bunch of other IP addresses used by that organization. For instance, whois 208.64.200.0 prints the following information:

OrgName:        Valve Corporation
OrgId:          VC-2
Address:        10900 NE 4th St, Suite 500
City:           Bellevue
StateProv:      WA
PostalCode:     98004
Country:        US
RegDate:        2010-11-12
Updated:        2010-11-12
Ref:            http://whois.arin.net/rest/org/VC-2

Follow the link at the bottom to the ARIN page, then go to related networks. You can whitelist all of those network ranges.

0

Just to help anyone else who may run into this issue:

The problem was a bit silly. I hadn't enabled IP forwarding in the kernel. Since I wanted this to be permanent I just updated /etc/sysctl.conf changing the IPv4 forwarding line to be

net.ipv4.ip_forward = 1

and restarted the machine.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .