# Simple iptables help (solved)

## Bigun

Here the rules I've setup so far:

```
 # iptables -L --line-numbers -v

Chain INPUT (policy ACCEPT 289 packets, 36828 bytes)

num   pkts bytes target     prot opt in     out     source               destination         

1        0     0 ACCEPT     all  --  lo     any     anywhere             anywhere            

2     1315 98748 ACCEPT     tcp  --  any    any     192.168.10.0/24      anywhere            tcp dpt:ssh 

3       51  3903 ACCEPT     tcp  --  any    any     anywhere             anywhere            tcp dpt:http 

4        0     0 ACCEPT     tcp  --  any    any     anywhere             anywhere            tcp dpt:submission 

5        0     0 ACCEPT     tcp  --  any    any     anywhere             anywhere            tcp dpt:imaps 

Chain FORWARD (policy DROP 0 packets, 0 bytes)

num   pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 107 packets, 28935 bytes)

num   pkts bytes target     prot opt in     out     source               destination         

1        0     0 ACCEPT     all  --  any    lo      anywhere             anywhere            
```

The server is sitting on my internal network.  As you can see the policy right now is to ACCEPT packets on the INPUT chain.  If I change the policy to DROP packets, this is what I get when I list the rules:

```
# iptables -L --line-numbers -v

Chain INPUT (policy DROP 0 packets, 0 bytes)

num   pkts bytes target     prot opt in     out     source               destination         

1        0     0 ACCEPT     all  --  lo     any     anywhere             anywhere            
```

It also doesn't return with a prompt, I have to ctrl+c out of it.  What rule(s) am I missing?

----------

## Hu

First, never use iptables --list to show your rules to others.  Always use iptables-save -c.  Second, please explain your problem.  You mention that no prompt is returned, but you never said what client program you are using or what protocol you expected to work.  Seeing the output of ip a on both systems would also be helpful.

As written, your rules in the first code block are not useful.  Either the packet is accepted because it matched a rule or it is accepted because it did not match any rule and hit the end of the chain.  Regardless, it is accepted.

----------

## Bigun

 *Quote:*   

> First, never use iptables --list to show your rules to others. Always use iptables-save -c.

 

Sorry:

```
# Generated by iptables-save v1.4.6 on Sun Sep  5 13:38:26 2010

*filter

:INPUT ACCEPT [154:21124]

:FORWARD DROP [0:0]

:OUTPUT ACCEPT [338:341108]

[0:0] -A INPUT -i lo -j ACCEPT 

[1445:107876] -A INPUT -s 192.168.10.0/24 -p tcp -m tcp --dport 22 -j ACCEPT 

[300:23457] -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT 

[0:0] -A INPUT -p tcp -m tcp --dport 587 -j ACCEPT 

[0:0] -A INPUT -p tcp -m tcp --dport 993 -j ACCEPT 

[0:0] -A OUTPUT -o lo -j ACCEPT 

COMMIT

# Completed on Sun Sep  5 13:38:26 2010
```

Every how-to I've read so far used iptables --list, I assumed it would be fine to post here.  Why is it so bad?

 *Quote:*   

> Second, please explain your problem.

 

I'm simply trying to enable a policy of dropping packets by default if no rule is matched.  Instead it seems it's blocking some essential service I'm not aware of.

 *Quote:*   

> You mention that no prompt is returned, but you never said what client program you are using or what protocol you expected to work. 

 

Take your pick, I'm on a local terminal on the machine or ssh'ed in, same result.  If you want a client name, it is bash.

 *Quote:*   

> Seeing the output of ip a on both systems would also be helpful. 

 

There's only one system involved.  Also I'm a bit embarrassed, but I don't seem to have any tool called "ip" installed, equery isn't giving me any clues as to what to install either.

 *Quote:*   

> As written, your rules in the first code block are not useful. Either the packet is accepted because it matched a rule or it is accepted because it did not match any rule and hit the end of the chain. Regardless, it is accepted.

 

Correct.  That's what I'm trying to fix.

----------

## maxime1986

try DROP as your default INPUT rule and :

```
iptables -L -n
```

man iptables :

 *Quote:*   

> -n, --numeric
> 
>               Numeric output.  IP addresses and port numbers will be printed in numeric format.  By default, the program will try to display them as host names, network names, or services (whenever applicable).

 

without "-n" option iptables can take a very long time to reverse dns, so much time that you can think it's freezed.

----------

## Hu

 *Bigun wrote:*   

> Every how-to I've read so far used iptables --list, I assumed it would be fine to post here.  Why is it so bad?

 The output provided by iptables --list is badly incomplete, which is why I have been telling people here for more than a year not to use it to report rules.  It is usable for system administration, but not good when you need someone else to see all your rules and be able to reproduce them.

 *Bigun wrote:*   

> I'm simply trying to enable a policy of dropping packets by default if no rule is matched.  Instead it seems it's blocking some essential service I'm not aware of.

 The output you showed in the last code block of your first post does exactly this.  Any traffic not matched by a rule is dropped.  Any traffic from the local machine matches and is accepted.  Everything else is not matched.  I assume you consider connectivity to other machines an essential service and would like to allow it?  :Wink: 

 *Bigun wrote:*   

> Take your pick, I'm on a local terminal on the machine or ssh'ed in, same result.  If you want a client name, it is bash.

 I am not quite sure what you mean.  I wanted to know what you consider an "essential service" that you expect to work, but which failed with the default-drop target.

 *Bigun wrote:*   

> There's only one system involved.  Also I'm a bit embarrassed, but I don't seem to have any tool called "ip" installed, equery isn't giving me any clues as to what to install either.

 Not having it is a frustratingly common problem.  It seems far too few people install sys-apps/iproute2.

 *Bigun wrote:*   

> Correct.  That's what I'm trying to fix.

 The final code block fixes it quite well.  It drops everything not from the local machine.  :Smile:   This provides excellent protection against almost all forms of attack, since it ensures, among other things, that your web browser cannot complete a handshake with foreign servers, thereby precluding it from downloading malicious content.  :Wink: 

To get started, you probably want a rule that matches established connections and allows their traffic: iptables -A INPUT -m conntrack --ctstate ESTABLISHED -j ACCEPT.  This will allow you to act as a client to other machines.  Most people with iptables questions are trying to expose some limited set of services to the outside world, which requires additional rules.  To determine the content of those rules, we need to know the name of those services (http, rsync, ssh, etc.).

----------

## bobspencer123

you can also have a look at this  script  someone posted in the how/to forums. I used this as a starting point for my simple firewall.

----------

## Bigun

```
# ip a

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN 

    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: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000

    link/ether 00:e0:18:1c:69:93 brd ff:ff:ff:ff:ff:ff

    inet 192.168.10.203/24 brd 192.168.10.255 scope global eth0

    inet6 fe80::2e0:18ff:fe1c:6993/64 scope link 

       valid_lft forever preferred_lft forever

3: sit0: <NOARP> mtu 1480 qdisc noop state DOWN 

    link/sit 0.0.0.0 brd 0.0.0.0
```

Also, I changed the default policy to DROP on my INPUT chain.  For some reason, iptables-save -c is able to display all the rules:

```
 # iptables-save -c

# Generated by iptables-save v1.4.6 on Mon Sep  6 06:25:15 2010

*filter

:INPUT DROP [0:0]

:FORWARD DROP [0:0]

:OUTPUT ACCEPT [4:496]

[0:0] -A INPUT -i lo -j ACCEPT 

[2353:164116] -A INPUT -s 192.168.10.0/24 -p tcp -m tcp --dport 22 -j ACCEPT 

[561:44845] -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT 

[0:0] -A INPUT -p tcp -m tcp --dport 587 -j ACCEPT 

[0:0] -A INPUT -p tcp -m tcp --dport 993 -j ACCEPT 

[0:0] -A OUTPUT -o lo -j ACCEPT 

COMMIT

# Completed on Mon Sep  6 06:25:15 2010
```

And iptables -L --line-numbers -v isn't freezing, looks like maxime1986 was right.  I waiting for about a minute and it finally listed everything.

Glad to know I didn't screw things up.

----------

## Hu

 *Bigun wrote:*   

> Also, I changed the default policy to DROP on my INPUT chain.  For some reason, iptables-save -c is able to display all the rules:

 Yes.  It does not do reverse lookups.  It turns out that you are not using the other chains, so iptables-save is a bit less critical here.  Very often, people ask for help with multi-table setups, and getting everything in a single view is much more valuable there.

The delay in listing was likely because you have not allowed DNS traffic, so reverse lookups had to time out.  The rules shown will allow this machine to serve ssh, http, mail submission, and imap.  They will not allow any outbound connections to work properly.  Is this intended?

----------

## Bigun

The OUTPUT chain has an ACCEPT policy with it, I've been testing it and it has been working.

edit:

That said, here are the rules I have now:

```
# iptables-save -c

# Generated by iptables-save v1.4.6 on Tue Sep  7 07:12:59 2010

*filter

:INPUT DROP [29944:2097968]

:FORWARD DROP [0:0]

:OUTPUT ACCEPT [0:0]

[96:8360] -A INPUT -i lo -j ACCEPT 

[7232:492424] -A INPUT -s 192.168.10.0/24 -p tcp -m tcp --dport 22 -j ACCEPT 

[727:58635] -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT 

[92:9428] -A INPUT -p tcp -m tcp --dport 587 -j ACCEPT 

[814:79649] -A INPUT -p tcp -m tcp --dport 993 -j ACCEPT 

[0:0] -A INPUT -s 127.0.0.1/32 -j ACCEPT 

[1025:115133] -A INPUT -i eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT 

[96:8360] -A OUTPUT -o lo -j ACCEPT 

[4431:723951] -A OUTPUT -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT 

COMMIT

# Completed on Tue Sep  7 07:12:59 2010
```

I walked away then realized I did have to put two rules in to make things work.

----------

## Hu

 *Bigun wrote:*   

> 
> 
> ```
> # iptables-save -c
> 
> ...

 This second rule is redundant.  Any traffic looped back from the local machine to itself will come over lo, so there is no need to handle 127.0.0.1/32.

 *Bigun wrote:*   

> I walked away then realized I did have to put two rules in to make things work.

 Right.  An ACCEPT on OUTPUT let traffic leave, but without a rule to allow the established responses, you could never finish a TCP handshake.

----------

## Bigun

I'll drop that second rule, I appreciate all the help Hu!

 :Smile: 

----------

