# Allowing SSH on LAN with iptables

## alienjon

I have my iptables setup on a server to drop all packets by default.  I would like to allow unfettered access to SSH to this server so long as you are on the LAN (192.168.1.*).  Currently, I cannot SSH to the machine at all.  The following line allows access, except despite my specifying the LAN IPs, I can also access it from the Internet:

 *Quote:*   

> iptables -A INPUT -p tcp -s 192.168.1.0/24 --dport ssh -m state --state NEW,ESTABLISHED -j ACCEPT

 

I did some looking online to find the parameters for that command, but it still doesn't seem to be quite working.

----------

## Logicien

First I would verify that your machines are seen on your local network

```
nmap -sP 192.168.1.0/24
```

and ping the server address. Note that the ssh server configuration can prevent it's access in plus of the firewall.

This is how I configure Iptables for a local network. It's a step by step configuration who can be use in a script. Just replace wlan0 by the name of your interface and the asterix by the Ip address of your ssh server. I can locally ssh client to the ssh server and no services are seen on Internet even if all the local machines can access Internet. It's a setup to use Gentoo as an Internet gateway.

```
iptables -F -t filter

iptables -F -t mangle

iptables -F -t nat

iptables -F -t raw

iptables -F -t security

iptables -X -t filter

iptables -X -t mangle

iptables -X -t nat

iptables -X -t raw

iptables -X -t security

iptables -P FORWARD DROP -t filter

iptables -P INPUT DROP -t filter

iptables -P OUTPUT DROP -t filter

iptables -P FORWARD ACCEPT -t mangle

iptables -P INPUT ACCEPT -t mangle

iptables -P OUTPUT ACCEPT -t mangle

iptables -P POSTROUTING ACCEPT -t mangle

iptables -P PREROUTING ACCEPT -t mangle

iptables -P OUTPUT ACCEPT -t raw

iptables -P PREROUTING ACCEPT -t raw

iptables -P FORWARD ACCEPT -t security

iptables -P INPUT ACCEPT -t security

iptables -P OUTPUT ACCEPT -t security

iptables -A INPUT -j ACCEPT -i wlan0 -t filter

iptables -A OUTPUT -j ACCEPT -o wlan0 -t filter

iptables -A INPUT  -j ACCEPT -m conntrack --ctstate RELATED,ESTABLISHED -t filter

iptables -A OUTPUT -j ACCEPT -m conntrack --ctstate NEW,RELATED,ESTABLISHED -t filter

iptables -A FORWARD -d 192.168.1.*/24 -j ACCEPT

iptables -A FORWARD -j ACCEPT -s 192.168.1.*/24

iptables -A POSTROUTING -j MASQUERADE -s 192.168.1.*/24 -t nat

sysctl -w net.ipv4.ip_forward=1
```

----------

## alienjon

I can ping and access the server just fine without any iptables policies set.  The setup I currently have is actually a bit more than I mentioned in my OP, but I'm only referencing the relevent commands (by that I mean that without the line in the OP allowing ssh connections I am unable to connect because the default policy is to DROP, but when I add the line there seems to be universal access to the machine.

I had tested from my cell phone, actually, as I can connect via wifi with a local address or via the mobile data and connect via the cell connection with a non-local address.  The only thought which comes to mind is that my lan gets access to the internet through a router, which forwards all port 22 traffic to this server.  Is it possible that iptables is registering the router's address (which would be on the lan) instead of the wan address?

----------

## Logicien

If you don't want any service of your local network be available from Internet you can block them at your router level and/or at the Linux Netfilter level. Some routers have the option to act only as a modem. Linux is my only router, firewall and gateway to Internet for all my local networks, cabled, wireless, Bluetooth and virtual. My cable modem do not have any of these capabilities. According to GRC | ShieldsUP! — Internet Vulnerability Profiling no port is open and I am not seen from Internet.

----------

## NeddySeagoon

alienjon,

Your router will do NAT, so anything permitted from the outside world will appear to originate from the router on your LAN.

For NAT to work, the router must be doing  forwarding.

That means you need to drop packets that have your router as the source address.

That can be messy if you have several subnets in use. Depending on the setup, the other subnets may be NATed too, so you won't be able to connect from them.

The right place to drop internet packets you don't want is your router.

----------

## alienjon

 *Logicien wrote:*   

> If you don't want any service of your local network be available from Internet you can block them at your router level and/or at the Linux Netfilter level.

 

A good idea (And probably what I'll end up doing) though at the moment I was mostly wondering why the rule wasn't working (ie: what about the rule was causing it to be accepted in both LAN and WAN).  Similarly, I was thinking of closing down port forwarding on the router side except for VPN connections (I do have a server setup on the router) which I would include a separate rule for devices on the VPN subnet.

 *NeddySeagoon wrote:*   

> Your router will do NAT, so anything permitted from the outside world will appear to originate from the router on your LAN.
> 
> For NAT to work, the router must be doing forwarding.

 

At the moment the forwarding is done via the 'port forwarding' option in the router (not explicitly through IP tables, though 'port forwarding' was essentially a GUI version of adding those specific rules.  I guess this isn't the case or this method of forwarding doesn't quite work the same?

 *NeddySeagoon wrote:*   

> That means you need to drop packets that have your router as the source address.
> 
> That can be messy if you have several subnets in use. Depending on the setup, the other subnets may be NATed too, so you won't be able to connect from them.

 

This next bit doesn't feel like it should make any sense (ie: there are much better ways of doing it) but for the sake of learning let me throw this out.  Would you mean that I would get the desired effect with something like the following:

```
iptables -P INPUT DROP

iptables -A INPUT -p tcp -s 192.168.1.1 --dport ssh -j DROP

iptables -A INPUT -p tcp -s 192.168.1.0/24 --dport ssh -j ACCEPT
```

That feels like it's unnecessary work in practice, but for the sake of example this would fix the problem otherwise?

----------

## Hu

It is certainly possible that your router is NAT'ing Internet packets to appear to come from the router.  If that is happening, I would consider that to be an incorrect configuration of the router.  NAT should only be used when the intended recipient cannot cope with the true address.  When you connect from the LAN to the WAN, NAT is necessary because peers on the Internet have no way to route traffic to a 192.168.x.x source.  When the WAN peer connects to you, your normal routing could send the traffic back to them, so your router should not be configured to NAT WAN traffic.

Your shown iptables rules would likely achieve your goal, but I think you would be better served identifying why traffic from the Internet appears to originate from the LAN and change the configuration to prevent that.

----------

## alienjon

 *Hu wrote:*   

> It is certainly possible that your router is NAT'ing Internet packets to appear to come from the router.  If that is happening, I would consider that to be an incorrect configuration of the router.  NAT should only be used when the intended recipient cannot cope with the true address.  When you connect from the LAN to the WAN, NAT is necessary because peers on the Internet have no way to route traffic to a 192.168.x.x source.  When the WAN peer connects to you, your normal routing could send the traffic back to them, so your router should not be configured to NAT WAN traffic.

 

How might I test this?  When I run 'ss' I get the external IP, not the router's.

----------

## szatox

Login with ssh from the outside and type "who".

You should find your session together with the IP your server sees as your client's.

----------

## Hu

If ss shows the true IP, then that is also the IP that iptables should have seen, and the problems described earlier in the thread should not have happened.

----------

## alienjon

 *szatox wrote:*   

> Login with ssh from the outside and type "who".
> 
> You should find your session together with the IP your server sees as your client's.

 

```
alienjon pts/0          2017-02-12 11:24 (192.168.1.1)
```

It does, in fact, see the router and not the external address.  Not what I was expecting.  I take it that this means that the router then 'forwards' all incoming traffic after reassigning the IP to itself.  This particular router is flashed with DD-WRT, so I do have access to adding iptables commands.  Does this behavior seem to make sense or should I figure out the iptables filter to forward the actual ip for incoming traffic?

----------

## Hu

The default mode of routers is to preserve the source IP information.  Mangling it as you see is only done when NAT is used.  You should investigate the rules on the router to determine why it is NATing traffic in the wrong direction.  If it were a general purpose Linux system, I would say post the output of iptables-save -c.  I do not know if you can get that output from a DD-WRT system.

----------

## alienjon

 *Hu wrote:*   

> The default mode of routers is to preserve the source IP information.  Mangling it as you see is only done when NAT is used.  You should investigate the rules on the router to determine why it is NATing traffic in the wrong direction.  If it were a general purpose Linux system, I would say post the output of iptables-save -c.  I do not know if you can get that output from a DD-WRT system.

 iptables and iptables-restore is available, but not 'save'.  I'll try to look a bit into this and see what I can find.  There appears to be a number of rules to go through.

----------

## Hu

That is very strange.  iptables-restore is of limited value without iptables-save, so it is surprising that they shipped one and not the other.  Absent iptables-save, you can use iptables --list-rules on each table (nat, filter, etc.) in turn.  The nat table is the most likely to be interesting here.

----------

## alienjon

 *Hu wrote:*   

> That is very strange.  iptables-restore is of limited value without iptables-save, so it is surprising that they shipped one and not the other.  Absent iptables-save, you can use iptables --list-rules on each table (nat, filter, etc.) in turn.  The nat table is the most likely to be interesting here.

 Do you mean -L or --list?  --list-rules doesn't seem to be an option.

----------

## Hu

No, I mean --list-rules, which works for me with iptables version 1.4.21, and is mentioned and described in the manual page installed with it.  Perhaps your router ships an older, less capable, version of iptables which lacks this command.  If so, you will need to improvise, since --list has a nasty habit of obscuring important details.  If you are stuck using --list, add in --exact --line-numbers --verbose --numeric.

----------

## NeddySeagoon

alienjon

iptables -L -t <table_name>

----------

## alienjon

 *Hu wrote:*   

> No, I mean --list-rules, which works for me with iptables version 1.4.21, and is mentioned and described in the manual page installed with it.  Perhaps your router ships an older, less capable, version of iptables which lacks this command.  If so, you will need to improvise, since --list has a nasty habit of obscuring important details.  If you are stuck using --list, add in --exact --line-numbers --verbose --numeric.

 I think you may be correct.  The command works fine on my server, but not on the router...

 *NeddySeagoon wrote:*   

> alienjon
> 
> iptables -L -t <table_name>

 

Below is the output, except for lines that route {WAN IP} to a previously specified internal host (port forwarding I've otherwise setup).  The POSTROUTING chain appears to possibly be the culprit.

```
Chain PREROUTING (policy ACCEPT)

target     prot opt source               destination

DNAT       icmp --  0.0.0.0/0            {WAN IP}      to:{ROUTER IP}

TRIGGER    0    --  0.0.0.0/0            {WAN IP}      TRIGGER type:dnat match:0 relate:0

Chain INPUT (policy ACCEPT)

target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)

target     prot opt source               destination

Chain POSTROUTING (policy ACCEPT)

target     prot opt source               destination

SNAT       0    --  0.0.0.0/0            0.0.0.0/0           to: {ROUTER IP}

SNAT       0    --  0.0.0.0/0            0.0.0.0/0           to: {WAN IP}

SNAT       0    --  {ROUTER IP}/24       0.0.0.0/0           to: {WAN IP}
```

----------

## Hu

I concur with your analysis.  The first two rules in the POSTROUTING chain look bogus to me.  If there are no hidden qualifiers on those rules (you did not use --verbose, so some match qualifiers, such as interface, are hidden; iptables --list-rules or iptables --list --verbose would show these), then I am surprised your network works at all.  It looks like all traffic should match the first rule, causing your router's IP to be used for everything.  If your ISP is not performing another layer of NAT on your outbound traffic, you would be sending traffic to the world with your router's internal IP (assuming that is what {ROUTER IP} represents), which should not work.

I would use as the sole POSTROUTING rule -o $WAN_INTERFACE -j MASQUERADE.  Let traffic that is sent out $LAN_INTERFACE pass without modification.  Let the kernel determine the correct IP address to insert on NAT'd traffic.

----------

## alienjon

Yes, {ROUTER IP} being the subnet gateway address (*.*.*.1). With verbose:

```
Chain POSTROUTING (policy ACCEPT 340 packets, 59975 bytes)

 pkts bytes target     prot opt in     out     source               destination

  184 64977 SNAT       0    --  *      br0     0.0.0.0/0            0.0.0.0/0           to:{ROUTER IP}

33924 2842K SNAT       0    --  *      vlan2   0.0.0.0/0            0.0.0.0/0           to:{WAN IP}

    6  3937 SNAT       0    --  *      vlan2   {LAN SUBNET}.0/24       0.0.0.0/0           to:{WAN IP}

```

That first rule is attached to br0.  If I understand how this bridge is setup, it basically connects the wifi interfaces with the LAN, so this is basically saying that all traffic from br0 (or all LAN, including wifi and wired) is to be filtered through the router.  vlan2 appears to be the interface connected to the WAN:

```
vlan2     Link encap:Ethernet  HWaddr {HW ADDRESS}

          inet addr:{WAN IP}  Bcast:{WAN BROADCAST ADDRESS}  Mask:255.255.252.0

          inet6 addr: {WAN IPv6}/64 Scope:Link

          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1

          RX packets:67081869 errors:0 dropped:0 overruns:0 frame:0

          TX packets:23411333 errors:0 dropped:0 overruns:0 carrier:0

          collisions:0 txqueuelen:1000

          RX bytes:97150891900 (90.4 GiB)  TX bytes:3631034571 (3.3 GiB)
```

I would then deduce,then is that all POSTROUTING bridged traffic go to the router and all POSTROUTING router traffic goes to the WAN (though then I'm not sure what the effect of line 3 would be, as line 2 should catch anything that would otherwise go to line 3).  Might this be part of a larger security measure then?  Ie: if someone tried to do something to the network it would end up effecting the router instead of any devices in the subnet?

----------

## Hu

This is an anti-security measure.  By changing the source address of the traffic, you give it the appearance that it comes from the router, which may cause hosts that would otherwise distrust it to treat it as safe.  You should remove the first rule and the third rule.  Let traffic destined to your ISP be rewritten.  Let all other traffic pass with its true address.  These rewrites have no effect on where the traffic goes, so anyone attempting to attack a host would still hit the host he intended.  However, it would appear that the attack originated from the router, which would make forensics more difficult.  Hence, anti-security.

----------

## alienjon

That's a good point and well beyond concerning...  I'm tempted to clear out all the iptables rules and put in my own, though as this is the family router I'm also tempted to go with the "if it's not broke, don't fix it".  I am looking into a router upgrade at some point soon and might play around with it after that when there's less of a chance of downtime for the rest of the family.

----------

## Hu

I think you would not break anything by removing only the rules I cited.  I cannot comment on your proposed replacement.  I have never used it.

----------

