# [SOLVED] Basic Iptables setup for gentoo router

## xanas3712

Ok, I've read a lot of this and even found a way that works but only using extremely permissive rules (basically allow all).  The home router guide on the wiki doesn't work as described at all. The rules it sets cause the client machines to be unable to get to the internet at all.

Here's what I'm using right now from there..

```

First we flush our current rules

# iptables -F

# iptables -t nat -F

Setup default policies to handle unmatched traffic

# iptables -P INPUT ACCEPT

# iptables -P OUTPUT ACCEPT

# iptables -P FORWARD DROP

Copy and paste these examples ...

# export LAN=eth0

# export WAN=eth1

Then we lock our services so they only work from the LAN

# iptables -I INPUT 1 -i ${LAN} -j ACCEPT

# iptables -I INPUT 1 -i lo -j ACCEPT

# iptables -A INPUT -p UDP --dport bootps -i ! ${LAN} -j REJECT

# iptables -A INPUT -p UDP --dport domain -i ! ${LAN} -j REJECT

(Optional) Allow access to our ssh server from the WAN

# iptables -A INPUT -p TCP --dport ssh -i ${WAN} -j ACCEPT

Drop TCP / UDP packets to privileged ports

# iptables -A INPUT -p TCP -i ! ${LAN} -d 0/0 --dport 0:1023 -j DROP

# iptables -A INPUT -p UDP -i ! ${LAN} -d 0/0 --dport 0:1023 -j DROP

Finally we add the rules for NAT

# iptables -I FORWARD -i ${LAN} -d 192.168.0.0/255.255.255.0 -j DROP

# iptables -A FORWARD -i ${LAN} -s 192.168.0.0/255.255.255.0 -j ACCEPT

# iptables -A FORWARD -i ${WAN} -d 192.168.0.0/255.255.255.0 -j ACCEPT

# iptables -t nat -A POSTROUTING -o ${WAN} -j MASQUERADE

```

Note that I changed the 255.255.0.0 to 255.255.255.0 but this doesn't seem to really change anyting.  i am actually using 255.255.255.0 in my broadcast line so I think that's what I should be using here, honestly I don't understand subnet mask enough to know what the difference would mean anyway.

This is what I get out of iptables -L -v after doing this

```

Chain INPUT (policy ACCEPT 27244 packets, 6816K bytes)

 pkts bytes target     prot opt in     out     source               destination

  375 22728 ACCEPT     all  --  lo     any     anywhere             anywhere

    0     0 ACCEPT     all  --  eth0   any     anywhere             anywhere

    1   328 REJECT     udp  --  !eth0  any     anywhere             anywhere            udp dpt:bootps reject-with icmp-port-unreachable

  693 46947 REJECT     udp  --  !eth0  any     anywhere             anywhere            udp dpt:domain reject-with icmp-port-unreachable

    0     0 ACCEPT     tcp  --  eth1   any     anywhere             anywhere            tcp dpt:ssh

   23  1460 DROP       tcp  --  !eth0  any     anywhere             anywhere            tcp dpts:0:1023

  670 65895 DROP       udp  --  !eth0  any     anywhere             anywhere            udp dpts:0:1023

Chain FORWARD (policy DROP 620 packets, 48949 bytes)

 pkts bytes target     prot opt in     out     source               destination

    0     0 DROP       all  --  eth0   any     anywhere             192.168.0.0/24

    0     0 ACCEPT     all  --  eth0   any     192.168.0.0/24       anywhere

    0     0 ACCEPT     all  --  eth1   any     anywhere             192.168.0.0/24

Chain OUTPUT (policy ACCEPT 31199 packets, 12M bytes)

 pkts bytes target     prot opt in     out     source               destination

```

I don't really honestly understand what "OUTPUT" "INPUT" and "FORWARD" means in this context.  I can "kind of" guess, but I don't really understand what's being thrown at me here.  I also am not really sure what the difference is between DROP and REJECT.  

!eth0 I assume means "not eth0" I guess this means that the "drop" rule applies to everything except eth0 for ports 0-1023?Last edited by xanas3712 on Mon May 21, 2007 12:20 am; edited 1 time in total

----------

## xanas3712

experiments: 

1) reflushing

2) iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE

3) iptables -P FORWARD DROP (no connection to net)

4) iptables -P FORWARD ACCEPT (connection works)

this seems to be making sense.  And I note that the example does set forward to drop so it makes sense that the connection wouldn't work if that's all, but it looks like the forward rule for source 192.168.0.0 on eth0 is set to ACCEPT, which would be an exception to the general drop rule.. unsure why that doesn't create the intended effect..

This rule would seem correct but it doesn't work while -P FORWARD ACCEPT does

```

Chain FORWARD (policy DROP 224 packets, 17627 bytes)

 pkts bytes target     prot opt in     out     source               destination

    0     0 ACCEPT     all  --  eth0   eth1    192.168.0.0/24       anywhere

```

iptables -A FORWARD (or -I, not understanding really the differences between A & I too well) -i eth0 -o eth1 -s 192.168.0.0/24 (or 16) -j ACCEPT

also tried with not restricting output with -o and leaving it at out = any... changes nothing

...

ok this does work but is silly

```

Chain FORWARD (policy DROP 461 packets, 36804 bytes)

 pkts bytes target     prot opt in     out     source               destination

   27 17054 ACCEPT     all  --  any    any     anywhere             anywhere

```

iptables -I FORWARD -J ACCEPT

It's essentially the same as just doing the -P but at least it confirms that the rules "should" ideally somehow work the way I was thinking..

wait a sec.. I bet.. arg..

oh well, thought I had something, I had previously setup a bridged openvpn connection using br0, so I tried -i br0 but that didn't produce any results, thought maybe since even though eth0 wasn't the entire interface really it was the problem but apparently not, as this rule does not work..

iptables -I FORWARD -i br0 -J ACCEPT 

strange.. it does let some packets through while eth0 doesn't but it still doesn't seem to accomplish actually letting the clients connect to the internet.

EDIT: done for the night, since I am basically all I'm wanting is to understand this a little more and I'll test and test some more with different commands to figure out what rules are given but I really don't know the meanings of some basic terminology here I guess.  It seems like it should be working but it's not now and I don't know why.  All I really want is to have a basic external firewall (no access to internal ports except those I allow like ssh/http/etc) but that doesn't prevent any internal operations for clients including gaming.  It seems with the very permissive rules sets the particular game I was working on this for (C&C3) does work more reliably than it did when I was behind the d-link router, so I think this is what I need to do it's just I don't know exactly how to accomplish it without destroying all security.

----------

## Hu

What is your network topology?  The output of ip addr show; ip link show will reveal this.  You can edit out your external IP from that.  We just need to see which interface faces the intranet and which one faces the Internet.

If you already read the iptables manpage and it was not sufficiently clear, please say so and I will expand upon what it says.  Quoting from it saves me the trouble of retyping it if you have not seen these parts yet.  :Smile: 

INPUT / OUTPUT / FORWARD are chains in the filter table, which control the filtering of traffic.  To quote from man iptables:

```
              filter:

                  This  is  the default table (if no -t option is passed).  It

                  contains the built-in chains INPUT (for packets destined  to

                  local  sockets),  FORWARD  (for packets being routed through

                  the box), and OUTPUT (for locally-generated packets).

```

DROP and REJECT are terminating targets which specify how to handle the packet.  From man iptables:

```
       ACCEPT  means to let the packet through.  DROP means to drop the packet

       on the floor.
```

```
   REJECT

       This is used to send back an error packet in response  to  the  matched

       packet:  otherwise it is equivalent to DROP so it is a terminating TAR-

       GET, ending rule traversal.  This target is only valid  in  the  INPUT,

       FORWARD  and  OUTPUT  chains,  and  user-defined  chains which are only

       called from those chains.
```

Yes, !eth0 is "not eth0."  For the rule you posted, it requests: if (packet is NOT entering on eth0) and (packet is tcp) and (packet is from anywhere) and (packet is to anywhere) and (destination port is in the range [0:1023]), then DROP.  The following rule does the same, except for udp.

iptables -A ... appends the rule to the end of the specified chain.  iptables -I ... <number> ... inserts the rule at the specified position in the chain.  -A is useful when you are building up the chain in order and want new rules put at the end.  -I is useful when you are going back and inserting rules after the chain is already up.  You may want to do this to add a temporary ACCEPT target that you do not wish to leave permanently active, such as a rule to grant a game access through the firewall.  Such a target would be added only while you are playing, then removed later.  It would be wasteful to tear down and rebuild the entire firewall just to get the game rule(s) in, so you use -I to insert them as needed.

For a connection to traverse the box, you need:IP forwarding enabled in /proc/sys/net/ipv4/ip_forwarding

A FORWARD chain which permits the traffic to pass

For a NAT based setup, you also need the nat table to rewrite the addresses on the packet, so that a peer on the Internet does not receive traffic claiming to be from 192.168.0.x, since that peer will likely not be able to route the traffic to you, and will probably drop it on sight.

The goal of "does not prevent gaming" may prove to be elusive, depending on the game.  Some games do stupid things like sending the IP address and port of the internal socket as part of the game data.  With such a game, other players would try to connect to 192.168.0.2 even though your firewall correctly rewrote the IP headers.  Some games work fine.  You could theoretically write a fix to correct the game's data on its way through the firewall, but that is rarely a trivial task.

If you post a more detailed description of your topology and desired rules, someone should be able to help you write the right rules.  In the meantime, you may want to look at the non-terminating target LOG, which can be used to log characteristics of the packets it matches.  It can be helpful for determining why a packet is not matching the terminating target that you want to match.  However, if you use LOG on a production system, be careful to use the limit match, else an aggressive port scan could generate a large volume of log data very quickly.

----------

## xanas3712

Thanks for the response/info.  I tend to try searches/google/etc. (did a lot of them) before the manual.  The manual is a lot of information at once and I have difficulty absorbing that.  I just read through it a bit more and I basically comprehend what you are saying now but I'm still not sure about a few things.  I did however get something to work by...

1) I changed eth0 to br0 (due to me previously setting up openvpn on the router box with a bridged interface) this seemed to be the magic that made the default home router script on the wiki work.

2) restarted peerguardian

3) now it doesn't work  :Razz: 

4) stopped peerguardian

5) now it does work.

So I'm having a different problem now but I can probably live without it if I have to or figure out some other solution/why it doesn't work.

I notice it seems to "INSERT" a rule to change the output/input to "QUEUE" 

btw, the "man" command doesn't have any instructions on how to "search" etc that I can find.  I can't however get the iptables to come up in kde's help browser of unix man pages... which is odd, I guess that's something else that I have to make work ..

EDIT: ok I understand queue now, and I did seem to have the kernel options set correctly, though it labeled the option "OBSOLETE" I also have the new, "not obsolete" config option, though i'm assuming peerguardian still needs the old one since it's not been updated in awhile.

----------

## Hu

Traditionally, / is the search character in most Unix tools.  / works in /usr/bin/less, which is commonly used for paging a manpage.

Without knowing your network topology, and how you set up the bridge, I cannot explain why you need to specify br0 instead of eth0.

Peerguardian is most likely inserting additional rules.  If you post a sample of what it is generating, we may be able to identify why those rules cause problems.  Based on the manpage, it sounds like the QUEUE target is being used to route the traffic to userspace, possibly so that Peerguardian can do further processing on it.  I never use QUEUE, so I could be completely wrong about that.

----------

## xanas3712

yeah, I think that's what it does.  It just seems to be processing it wrongly for lan clients, but then it probably isn't that advanced.

Sorry for not giving that other info before, my fault, thought I had it fixed when I started the last post... until peerguardian..

```

1: lo: <LOOPBACK,UP,10000> mtu 16436 qdisc noqueue

    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

    inet 127.0.0.1/8 brd 127.255.255.255 scope host lo

    inet6 ::1/128 scope host

       valid_lft forever preferred_lft forever

2: sit0: <NOARP> mtu 1480 qdisc noop

    link/sit 0.0.0.0 brd 0.0.0.0

3: eth0: <BROADCAST,MULTICAST,PROMISC,UP,10000> mtu 1500 qdisc pfifo_fast qlen 1000

    link/ether 00:0f:ea:78:a5:6d brd ff:ff:ff:ff:ff:ff

    inet6 fe80::20f:eaff:fe78:a56d/64 scope link

       valid_lft forever preferred_lft forever

4: eth1: <BROADCAST,MULTICAST,UP,10000> mtu 1500 qdisc pfifo_fast qlen 1000

    link/ether 00:e0:4c:77:7f:2b brd ff:ff:ff:ff:ff:ff

    inet 24.155.xx.xxx/22 brd 24.155.xx.xxx scope global eth1

    inet6 fe80::2e0:4cff:fe77:7f2b/64 scope link

       valid_lft forever preferred_lft forever

5: tap0: <BROADCAST,MULTICAST,PROMISC,UP,10000> mtu 1500 qdisc noqueue qlen 100

    link/ether 96:34:64:75:f4:c2 brd ff:ff:ff:ff:ff:ff

    inet6 fe80::9434:64ff:fe75:f4c2/64 scope link

       valid_lft forever preferred_lft forever

8: br0: <BROADCAST,MULTICAST,UP,10000> mtu 1500 qdisc noqueue

    link/ether 00:0f:ea:78:a5:6d brd ff:ff:ff:ff:ff:ff

    inet 192.168.0.1/24 brd 192.168.0.255 scope global br0

    inet6 fe80::20f:eaff:fe78:a56d/64 scope link

       valid_lft forever preferred_lft forever

1: lo: <LOOPBACK,UP,10000> mtu 16436 qdisc noqueue

    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

2: sit0: <NOARP> mtu 1480 qdisc noop

    link/sit 0.0.0.0 brd 0.0.0.0

3: eth0: <BROADCAST,MULTICAST,PROMISC,UP,10000> mtu 1500 qdisc pfifo_fast qlen 1000

    link/ether 00:0f:ea:78:a5:6d brd ff:ff:ff:ff:ff:ff

4: eth1: <BROADCAST,MULTICAST,UP,10000> mtu 1500 qdisc pfifo_fast qlen 1000

    link/ether 00:e0:4c:77:7f:2b brd ff:ff:ff:ff:ff:ff

5: tap0: <BROADCAST,MULTICAST,PROMISC,UP,10000> mtu 1500 qdisc noqueue qlen 100

    link/ether 96:34:64:75:f4:c2 brd ff:ff:ff:ff:ff:ff

8: br0: <BROADCAST,MULTICAST,UP,10000> mtu 1500 qdisc noqueue

    link/ether 00:0f:ea:78:a5:6d brd ff:ff:ff:ff:ff:ff

```

Current working rules setup

```

zero-one xanas # iptables -L -v

Chain INPUT (policy ACCEPT 2957 packets, 1998K bytes)

 pkts bytes target     prot opt in     out     source               destination

   48  2016 ACCEPT     all  --  lo     any     anywhere             anywhere

  211 22630 ACCEPT     all  --  br0    any     anywhere             anywhere

    0     0 REJECT     udp  --  !br0   any     anywhere             anywhere            udp dpt:bootps reject-with icmp-port-unreachable

    4   288 REJECT     udp  --  !br0   any     anywhere             anywhere            udp dpt:domain reject-with icmp-port-unreachable

    0     0 ACCEPT     tcp  --  eth1   any     anywhere             anywhere            tcp dpt:ssh

    0     0 DROP       tcp  --  !br0   any     anywhere             anywhere            tcp dpts:0:1023

  767  285K DROP       udp  --  !br0   any     anywhere             anywhere            udp dpts:0:1023

Chain FORWARD (policy DROP 4 packets, 1326 bytes)

 pkts bytes target     prot opt in     out     source               destination

   43  5654 DROP       all  --  br0    any     anywhere             192.168.0.0/24

 5903  579K ACCEPT     all  --  br0    any     192.168.0.0/24       anywhere

 6034 3618K ACCEPT     all  --  eth1   any     anywhere             192.168.0.0/24

Chain OUTPUT (policy ACCEPT 2892 packets, 336K bytes)

 pkts bytes target     prot opt in     out     source               destination

```

----------

## Hu

That ruleset looks fairly open, particularly for the FORWARD chain.  I suggest making the following changes:

```
# Start over

iptables -F FORWARD

iptables -P FORWARD DROP

# Drop Internet traffic from private IP ranges

iptables -A FORWARD -i eth1 -s 10.0.0.0/8 -j DROP

iptables -A FORWARD -i eth1 -s 172.16.0.0/12 -j DROP

iptables -A FORWARD -i eth1 -s 192.168.0.0/16 -j DROP

# Drop traffic which should stay in the local network

iptables -A FORWARD -i br0 -d 192.168.0.0/16 -j DROP

# Drop traffic which is trying to leave the local network, but appears

# not to have originated locally

iptables -A FORWARD -i br0 -s ! 192.168.0.0/24 -j DROP

# Drop traffic which the kernel thinks is INVALID

iptables -A FORWARD -m state --state INVALID -j DROP

# Allow traffic for existing connections to pass

# Note: requires stateful match support in the kernel

iptables -A FORWARD -i eth1 -p tcp -m state --state ESTABLISHED -j ACCEPT

iptables -A FORWARD -i eth1 -p udp -m state --state RELATED,ESTABLISHED -j ACCEPT

# Allow internal hosts to use TCP and UDP freely

iptables -A FORWARD -i br0 -p tcp -j ACCEPT

iptables -A FORWARD -i br0 -p udp -j ACCEPT

```

Also, unless you have good reason to do otherwise, you may as well change the INPUT chain to DROP instead of REJECT the UDP requests.  Similarly, you should change the last two rules so that they drop TCP and UDP for all ports, rather than only privileged ones.  Note that this change will interfere with the ability to run servers locally, so you will need to identify the ports of those servers and create an ACCEPT rule to permit their traffic.

[Edit: fixed the example line that was supposed to reset the policy.  As originally written, it would not work.]Last edited by Hu on Mon May 21, 2007 4:15 am; edited 1 time in total

----------

## xanas3712

Just working through to make sure i understand your examples (thanks for providing!) 

```
# Start over

iptables -F FORWARD

iptables -P DROP

```

SO -P DROP works because it makes the assignment to all flushed "chains" ?  so therefore it doesn't require the -P FORWARD DROP?

```

# Drop Internet traffic from private IP ranges

iptables -A FORWARD -i eth1 -s 10.0.0.0/8 -j DROP

iptables -A FORWARD -i eth1 -s 172.16.0.0/12 -j DROP

iptables -A FORWARD -i eth1 -s 192.168.0.0/16 -j DROP

```

This would drop all traffic received from local ranges, meaning others who don't have their nat working correctly?  Or is there some kind of exploitative way of using local IP traffic?   This is cool because I now understand the subnet masks a bit better.  8 is the same as 255.0.0.0 and so the lower the number the more possible address space? Then by using 24 with 192.168.0.0 I'm restricting it to only 192.168.0.(0-254 )instead of 192.168.(0-254).(0-254) ? 

```

# Drop traffic which should stay in the local network

iptables -A FORWARD -i br0 -d 192.168.0.0/16 -j DROP

```

If a packet is directed towards an internal IP how would it end up getting forwarded?  Or is this just explicitly defining something that wouldn't happen normally?

```

# Drop traffic which is trying to leave the local network, but appears

# not to have originated locally

iptables -A FORWARD -i br0 -s ! 192.168.0.0/24 -j DROP

# Drop traffic which the kernel thinks is INVALID

iptables -A FORWARD -m state --state INVALID -j DROP

```

These both seem pretty clear, though I'm curious if the determinations are sometimes wrong on origination/invalid packets? Though I suppose I could make it more permissive if it doesn't work right.

```

# Allow traffic for existing connections to pass

# Note: requires stateful match support in the kernel

iptables -A FORWARD -i eth1 -p tcp -m state --state ESTABLISHED -j ACCEPT

iptables -A FORWARD -i eth1 -p udp -m state --state RELATED,ESTABLISHED -j ACCEPT

```

So "RELATED" is used because of the nature of UDP traffic(just a set of "disconnected" packets), I'm guessing you wouldn't ever have a "RELATED" tcp packet, right?  This is why they are 2 seperate rules, I guess RELATED would fail on tcp or might allow something unexpected?  

```

# Allow internal hosts to use TCP and UDP freely

iptables -A FORWARD -i br0 -p tcp -j ACCEPT

iptables -A FORWARD -i br0 -p udp -j ACCEPT

```

Makes sense, though I'll probably combine the rule.  I don't foresee that I'll have the need to restrict tcp/udp internal traffic at any point as this is just a home lan.

 *Quote:*   

> 
> 
> Also, unless you have good reason to do otherwise, you may as well change the INPUT chain to DROP instead of REJECT the UDP requests.  Similarly, you should change the last two rules so that they drop TCP and UDP for all ports, rather than only privileged ones.  Note that this change will interfere with the ability to run servers locally, so you will need to identify the ports of those servers and create an ACCEPT rule to permit their traffic.

 

If I change the main chain command to drop I wouldn't need to set the 2 rules to drop tcp/udp right?  It'd automatically do that unless I make an explicit allowance for the server port to be used?  This makes more sense to me also.  I kind of was wondering why the home router guide wasn't setup to do this myself, except perhaps that most of the automated services run on < 1024.

So I need to...

```

 iptables -F INPUT; iptables -I INPUT - i br0 -j ACCEPT; iptables -A INPUT -i eth1 --dport ssh -j ACCEPT; iptables -A INPUT -i eth1 --dport http -j ACCEPT 

```

EDIT doing this + doing what you suggested ended up not working quite right.  I'm not sure what was not working.  The server machine was stuck on looking up web pages, and other machines also couldn't browse the net, but somehow world of warcraft was still working just fine through this, so I have to think it's perhaps an issue related to me not being able to get DNS resolution?  But then, I was pinging on one of the internal machines and though I couldn't get a response from google or get the web page, it did resolve some kind of ip address.

Odd stuff...

EDIT2, I bet it was due to me diong iptables -P INPUT DROP, you said only to change the rejects to drop, don't ask me how I misread that, but I bet dropping all input probably screws up the communication a bit and probably prevented dns from working correctly.

----------

## xanas3712

this didn't work either..

```

zero-one xanas # iptables -P FORWARD DROP

zero-one xanas # iptables -A FORWARD -i br0 -j ACCEPT

zero-one xanas # iptables -A FORWARD -i eth1 -p tcp -m state --state ESTABLISHED -j ACCEPT

zero-one xanas # iptables -A FORWARD -i eth1 -p udp -m state --state ESTABLISHED,RELATED -j ACCEPT

zero-one xanas # iptables -I INPUT -i eth1 -p tcp --dport 0:65535 -j DROP

zero-one xanas # iptables -A INPUT -i eth1 -p udp --dport 0:65535 -j DROP

zero-one xanas # iptables -A INPUT -i eth1 -p tcp --dport ssh -j ACCEPT;

zero-one xanas # iptables -A INPUT -i eth1 -p tcp --dport ftp -j ACCEPT;

zero-one xanas # iptables -A INPUT -i eth1 -p tcp --dport http -j ACCEPT

zero-one xanas # iptables -L -v

Chain INPUT (policy ACCEPT 1820 packets, 1438K bytes)

 pkts bytes target     prot opt in     out     source               destination

   10  2688 DROP       tcp  --  eth1   any     anywhere             anywhere            tcp

    4  1508 DROP       udp  --  eth1   any     anywhere             anywhere            udp

    0     0 ACCEPT     tcp  --  eth1   any     anywhere             anywhere            tcp dpt:ssh

    0     0 ACCEPT     tcp  --  eth1   any     anywhere             anywhere            tcp dpt:ftp

    0     0 ACCEPT     tcp  --  eth1   any     anywhere             anywhere            tcp dpt:http

Chain FORWARD (policy DROP 51 packets, 6716 bytes)

 pkts bytes target     prot opt in     out     source               destination

 4135  229K ACCEPT     all  --  br0    any     anywhere             anywhere

 3742 1371K ACCEPT     tcp  --  eth1   any     anywhere             anywhere            state ESTABLISHED

    0     0 ACCEPT     udp  --  eth1   any     anywhere             anywhere            state RELATED,ESTABLISHED

Chain OUTPUT (policy ACCEPT 18200 packets, 2183K bytes)

 pkts bytes target     prot opt in     out     source               destination

```

To fix this one I had iptables -F INPUT hmm....

EDIT: Ok, this one seems to be a go so far anyhow

```

zero-one xanas # iptables -L -v

Chain INPUT (policy ACCEPT 81119 packets, 41M bytes)

 pkts bytes target     prot opt in     out     source               destination

 6675 3814K ACCEPT     all  --  eth1   any     anywhere             anywhere            state RELATED,ESTABLISHED

    0     0 ACCEPT     tcp  --  eth1   any     anywhere             anywhere            tcp dpt:ssh

    0     0 ACCEPT     tcp  --  eth1   any     anywhere             anywhere            tcp dpt:http

    0     0 ACCEPT     tcp  --  eth1   any     anywhere             anywhere            tcp dpt:ftp

   10   472 DROP       tcp  --  eth1   any     anywhere             anywhere            tcp

   18  6036 DROP       udp  --  eth1   any     anywhere             anywhere            udp

Chain FORWARD (policy DROP 51 packets, 6716 bytes)

 pkts bytes target     prot opt in     out     source               destination

14925  899K ACCEPT     all  --  br0    any     anywhere             anywhere

14382 4598K ACCEPT     tcp  --  eth1   any     anywhere             anywhere            state ESTABLISHED

    0     0 ACCEPT     udp  --  eth1   any     anywhere             anywhere            state RELATED,ESTABLISHED

Chain OUTPUT (policy ACCEPT 134K packets, 85M bytes)

 pkts bytes target     prot opt in     out     source               destination

```

I can probably go back and add the more complex forwarding rules now without issues, just wanted to get somewhere working first and decide if I though the source/dest checking/invalid state checking was all necessary.

WORKS, and with peerguardian, although it seems the guardian might eliminate with queue the actual ruleset after that.  Might be resolvable with a set of rules that re-arranges the order, but I'm fine without it and can use blocklists via some other programs directly anhow, marking solved..

----------

## Hu

No, that -P DROP was a mistake.  I have fixed it in the original post.  My intent was just to make sure that the chain was in a sane state by setting both its rules and its policy in my example.  Flushing the chain does not automatically change the policy.

Yes, that is intended to drop private range addresses coming off the Internet interface.  Although those could be an indication of a malfunctioning NAT, they are more likely an indication that someone is attempting to exploit IP address based trust.  For instance, if you have configured your sshd daemon to allow unauthenticated login from "your network," where that means 192.168.0.x, then an attacker could exploit that if he could make a connection claiming to be from 192.168.0.x.  To avoid that, we drop such traffic when it comes from the Internet interface.  Such a connection is non-trivial since it involves getting intervening systems to cooperate, but I have seen my ISP sending me datagrams from 10.x.x.x addresses before, so it is not out of the question.

Yes, /8 is a shorter notation for 255.0.0.0.  Yes, smaller numbers mean more addresses to match.  Yes, using /24 restricts it to 192.168.0.x.  Using /16 would have restricted it to 192.168.x.x.

 *xanas3712 wrote:*   

> 
> 
> ```
> # Drop traffic which should stay in the local network
> 
> ...

 

It should not be forwarded.  This is another case of explicitly refusing traffic which should not happen.

I have never experienced any problems relating to the use of the INVALID state match.  According to the chain counters, my firewall has matched several hundred packets with the INVALID state match.

No, RELATED is legal for TCP.  As I understand netfilter, RELATED applies in the case of multi-circuit protocols, such as FTP.  It should match traffic which is associated with a new circuit that is related to the existing circuit, such as a new data connection related to an existing control connection. I do not run an FTP server behind my firewall, so I cannot confirm whether it works as desired.  The rules are separate because there are more values than just tcp and udp.  By calling them out separately, I avoid letting either rule match any of the other protocols, such as icmp or the various lesser known protocols.

 *xanas3712 wrote:*   

> Makes sense, though I'll probably combine the rule. I don't foresee that I'll have the need to restrict tcp/udp internal traffic at any point as this is just a home lan.

 

Unless you need to grant access on the other protocols, I would suggest keeping the rules separate for the reason outlined in the prior paragraph.

 *xanas3712 wrote:*   

> If I change the main chain command to drop I wouldn't need to set the 2 rules to drop tcp/udp right? It'd automatically do that unless I make an explicit allowance for the server port to be used?

 

Correct.  Yes.

 *xanas3712 wrote:*   

> I kind of was wondering why the home router guide wasn't setup to do this myself, except perhaps that most of the automated services run on < 1024.

 

This may have been done on the assumption that the user would be running applications which bound non-privileged ports and expected free access, which is common in networked games.

 *xanas3712 wrote:*   

> EDIT2, I bet it was due to me diong iptables -P INPUT DROP, you said only to change the rejects to drop, don't ask me how I misread that, but I bet dropping all input probably screws up the communication a bit and probably prevented dns from working correctly.

 

That sounds likely.  I run with INPUT set to DROP, but my rules are much more complex than what you were using.

 *xanas3712 wrote:*   

> EDIT: Ok, this one seems to be a go so far anyhow

 

Good.  However, your INPUT chain is using a default-permit policy.  You are dropping disallowed TCP and UDP, but ICMP (among others) is not specified and therefore is falling off the end of the chain and being handled by the policy of ACCEPT.  One way to fix this would be to remove the last two rules and instead do:

```

# Allow traffic over loopback.  This is very important to avoid breaking

# applications running on the machine.

iptables -A INPUT -i lo -j ACCEPT

# Allow internal machines to connect to this host without restriction.

iptables -A INPUT -i br0 -j ACCEPT

# Drop anything not matched by other rules.

iptables -P INPUT DROP

```

Such a change would create a default-deny policy.  Best practices in security dictate that you should avoid trying to blacklist "bad" traffic, because you might miss something that can then get through.  Instead, you should whitelist "good" traffic and deny everything else.  When using a whitelist, a mistake manifests as a service not functioning correctly / at all.  When using a blacklist, a mistake manifests as an attacker being able to perform an action you meant to block.

----------

## xanas3712

Right, what you are saying makes complete sense to me.  My only issue at this point was I had to narrow the protocol usage a bit to get the game to work correctly in this case.  It seems that the game uses (probably ICMP) to get the latency, so if I don't allow it then it shows my latency as extremely high (since it's timing out).

I suppose I can just allow all ICMP, I can't think of anything that would go wrong with that particular protocol on my end.

BTW, out of curiosity what kind of applications are you running?  C&C 3 is a particularly picky game that constantly tells me I have "NAT problems."  With the D-link I basically couldn't play, with this I can play but it still gives me those messages every so often (particularly in automatch, custom matches where I join games I choose seem to work just fine).  I suppose that game is probably to blame, it doesn't work with my gigabit switch in LAN mode either for some odd reason (which doesn't affect any other game but their previous "C&C Generals")

----------

## xanas3712

Ok, this is my final result (I think) with the default drop policy/etc for all but output (I don't have any need to block that at this time, except perhaps invalid packets or something)

```

zero-one xanas # iptables -L -v

Chain INPUT (policy DROP 2231 packets, 329K bytes)

 pkts bytes target     prot opt in     out     source               destination

23136   13M ACCEPT     tcp  --  any    any     anywhere             anywhere            tcp dpts:6881:6999

  128 14666 ACCEPT     all  --  br0    any     anywhere             anywhere

  266 19540 ACCEPT     all  --  lo     any     anywhere             anywhere

  130 11255 ACCEPT     icmp --  any    any     anywhere             anywhere

    0     0 ACCEPT     udp  --  any    any     anywhere             anywhere            udp dpt:openvpn

    0     0 ACCEPT     tcp  --  any    any     anywhere             anywhere            tcp dpt:openvpn

    0     0 ACCEPT     tcp  --  any    any     anywhere             anywhere            tcp dpt:ftp

    0     0 ACCEPT     tcp  --  any    any     anywhere             anywhere            tcp dpt:http

    0     0 ACCEPT     tcp  --  any    any     anywhere             anywhere            tcp dpt:ssh

46126   29M ACCEPT     all  --  any    any     anywhere             anywhere            state RELATED,ESTABLISHED

Chain FORWARD (policy DROP 192 packets, 30991 bytes)

 pkts bytes target     prot opt in     out     source               destination

    0     0 DROP       all  --  eth1   any     192.168.0.0/16       anywhere

    0     0 DROP       all  --  eth1   any     172.16.0.0/12        anywhere

    0     0 DROP       all  --  eth1   any     10.0.0.0/8           anywhere

    0     0 DROP       all  --  br0    any     anywhere             192.168.0.0/16

    0     0 DROP       all  --  br0    any    !192.168.0.0/24       anywhere

    0     0 DROP       all  --  any    any     anywhere             anywhere            state INVALID

   18  3520 ACCEPT     all  --  eth1   any     anywhere             anywhere            state RELATED,ESTABLISHED

   20  7938 ACCEPT     all  --  br0    any     anywhere             anywhere

Chain OUTPUT (policy ACCEPT 2200K packets, 1531M bytes)

 pkts bytes target     prot opt in     out     source               destination

```

----------

## Hu

I mostly run "well behaved applications," i.e. ones that don't require special holes in the firewall to work correctly.  :Smile:   Games require special handling, but they are NAT-friendly.

From what I have read, there is a theoretical risk associated with a blanket ICMP allow, but as far as I know those are not likely to crop up in anything short of a targeted attack designed to break into your network (as opposed to the multitudes of port-scanning hosts out there just trying to find anyone and everyone who is open).

Those rules look good.  Depending on your usage pattern, you may want to create a script to add/remove rules based on what the box is supposed to be doing.  For example, when you want to play, run ~/bin/c-and-c.sh open to add rules to allow playing, then run ~/bin/c-and-c.sh close to close the ports when you are done.  However, I think your current setup is tight enough that there is no security-driven need to do so.  It would be more about minimizing the number of unnecessarily visible ports than about further protecting your system.

If you want to dig into why C&C warns about NAT problems, emerge net-analyzer/tcpdump and/or net-analyzer/wireshark.  You can use them to capture and review network traffic crossing the box, which may give you some insight into what C&C is doing that causes it to warn about NAT.  Both packages can do packet capturing, but I generally recommend that people use tcpdump to capture the data, then run Wireshark as an unprivileged user to review what was caught.  Wireshark provides a nice GUI that can make it easier to navigate the capture file, but it also has a long history of security vulnerabilities, so running it as root (which is necessary for capturing traffic) is frowned upon.  Analyzing the C&C traffic is a bit off-subject for this thread, but I suspect there are enough Gentoo users who run into issues with NAT and games that it would be within the forum's purpose to discuss it in a new thread on this site.  :Smile: 

----------

## xanas3712

Ok, I think I'll do that.

I really do appreciate your help with this.

----------

