What's new

Control LAN Access via iptables

  • SNBForums Code of Conduct

    SNBForums is a community for everyone, no matter what their level of experience.

    Please be tolerant and patient of others, especially newcomers. We are all here to share and learn!

    The rules are simple: Be patient, be nice, be helpful or be gone!

johhnyu

Occasional Visitor
Is it possible to control LAN access via iptables? I have a bunch of IOT devices that I want to access the internet and (and this is the kicker) accept incoming connections from specific hosts inside my LAN, but not create their own connections to hosts in my LAN.

It looks like iptables rules are completely ignored for the LAN. Is it just that the switch is not exposed to the kernel, so I'm pretty much out of luck?
 
Is it possible to control LAN access via iptables? I have a bunch of IOT devices that I want to access the internet and (and this is the kicker) accept incoming connections from specific hosts inside my LAN, but not create their own connections to hosts in my LAN.

It looks like iptables rules are completely ignored for the LAN. Is it just that the switch is not exposed to the kernel, so I'm pretty much out of luck?

Iptable rules are not ignored for LAN, you just have to watch out at what position you place the rules.

In iptables -vL format
Code:
Chain FORWARD (policy DROP 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
   0     0 ACCEPT     all  --  any    any     anywhere             anywhere             state RELATED,ESTABLISHED
-------- ** Accepts existing connections
   0     0 other2wan  all  --  !br0   eth0    anywhere             anywhere
-------- ** Chain dealing with outgoing traffic not originating from LAN   ( Used to DROP any non Tunneled/Local --> WAN traffic)
   0     0 DROP       all  --  any    any     anywhere             anywhere             state INVALID
-------- ** Drops any invalid packets
   0     0 ACCEPT     all  --  br0    br0     anywhere             anywhere
-------- **Accepts LAN to LAN traffic
   0     0 NSFW       all  --  any    any     anywhere             anywhere
-------- ** Chain dealing with outgoing LAN -> WAN traffic ( Used to DROP user defined traffic in WebUI Net Service Filter)
   0     0 ACCEPT     all  --  any    any     anywhere             anywhere             ctstate DNAT
-------- ** Accept traffic resulting from a Port Forward
   0     0 OVPN       all  --  any    any     anywhere             anywhere             state NEW
-------- ** Chain used for OpenVPN tunnel interfaces
   0     0 ACCEPT     all  --  br0    any     anywhere             anywhere
-------- ** Accept outgoing traffic originating from LAN

In human readable / input format.

Code:
-A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
-A FORWARD ! -i br0 -o eth0 -j other2wan
-A FORWARD -m state --state INVALID -j DROP
-A FORWARD -i br0 -o br0 -j ACCEPT
-A FORWARD -j NSFW
-A FORWARD -m conntrack --ctstate DNAT -j ACCEPT
-A FORWARD -m state --state NEW -j OVPN
-A FORWARD -i br0 -j ACCEPT

Each packet is consulted via this filter from top to bottom, until it hits an ACCEPT/DROP/END OF THE LIST.

Eg.

Existing connections (not already dropped on first packet) will hit ESTABLISHED ACCEPT
LAN2LAN communications will hit br0 --> br0 ACCEPT
New connections will be consulted against NSFW
Port forwards Connections will hit ctstate DNAT ACCEPT
Else outgoing connections will hit the br0 --> any ACCEPT

For your LAN filtering rule, you have to insert the rule the filtering rules above the br0 --> br0 ACCEPT rule (-A FORWARD -i br0 -o br0 -j ACCEPT)
 
Last edited:
That is filtering by interface, what I was trying to do is at the IP level like the below. Is it only possible at the interface level?

I did also try similar FORWARD rules as I always confuse them. Just predicting what you're gonna say. :)

I didn't do any connection tracking; didn't get that far as nothing seemed to block LAN connections at all.

Code:
### Google Home (30) & Amazon Echo Dots (39,40)
# ALLOW to Shield TVs (175,176)
/usr/sbin/iptables -I INPUT --src 192.168.1.30,192.168.1.39,192.168.1.40 -m iprange --dst-range 192.168.1.175-192.168.1.176 -j ALLOW
# ALLOW to Harmony Hubs (192,193) and Sonos (194-196)
/usr/sbin/iptables -I INPUT --src 192.168.1.30,192.168.1.39,192.168.1.40 -m iprange --dst-range 192.168.1.192-192.168.1.196 -j ALLOW
# REJECT LAN for the rest
/usr/sbin/iptables -I INPUT --src 192.168.1.30,192.168.1.39,192.168.1.40 --dst 192.168.1.0/24 -j REJECT
 
INPUT is only traffic destined towards router itself.

Local Device --> Local Device traffic will NOT appear at INPUT.

WAN --> Local Device will hit FORWARD.
Local Device --> WAN will hit FORWARD.

LAN/WAN Device --> Process on Router will hit INPUT.
Process on Router --> LAN/WAN will hit OUTPUT.

Once again, within the forward chain, your custom rules have has to be placed above the following rule or they will not work.

Code:
-A FORWARD -i br0 -o br0 -j ACCEPT


This is because this rule will accept any Local Device --> Local Device traffic prior to having your custom rule evaluated. (eg. top -> bottom evaluation)

---

This should help you understand how traffic passes through the chains.

Code:
    As a router (pass through traffic)
        PREROUTING -> FORWARD -> POSTROUTING
    As a client (incomming traffic)
        PREROUTING -> INPUT
    As a client (outgoing traffic)
        OUTPUT ->POSTROUTING
 
Last edited:
OK, I just ran a very simple forward rule, trying to block connections from .202 to .200, and that did not work. Had a ping running the whole time. I also confirmed it shows up at the very top of the "iptables -L FORWARD" rule list. As it should, because I used the insert flag rather than append.

I actually thought I had it figured out, because iptables -L showed .200 as the source and .202 as the destination as I had messed it up, but reversing it didn't work either. Was a real eureka moment. Briefly.

Code:
/usr/sbin/iptables -I FORWARD --src 192.168.1.202 --dst 192.168.1.200 -j REJECT
 
Last edited:
Just when I thought I was getting the hang of iptables, son of a !@#$!

Could it be since they are on the same switch, it connection bypassing any routing and going directly between the devices entirely??
 
Yeah, that's what I suspected in the OP. :(

Can’t you just put all the IoT devices on a guest network?

Guest network isolation works because the kernel creates virtual interfaces and then makes use of ebtables (one layer lower) for access control as opposed to iptables.
 
Unfortunately not, I need several of the IOT devices to access selected hosts on my intranet. The Harmony hubs controls some devices over IP, the alexas/google homes need to connect to my Sonos speakers, etc.

I guess the real solution is to setup tagging and VLANs, but unfortunately AsusWRT/Merlin isn't really suited to that. In the end, I may find myself building a PFsense router and just use my RT-AC68u as a wifi AP. Was trying to avoid that if possible.

Ultimately as IOT devices get more popular, I expect a lot of people would find similar functionality very useful. It's crazy, I live alone in a 1BR apartment and I have over 30 devices on my LAN! Hopefully manufacturers like Asus, Cisco, TP-link, etc, will start building it into their devices.

I imagine a utopia where the router automatically sets up an untrusted VLAN, interrogates all your devices with something like nmap, and puts the IOT and non-discoverable devices on the untrusted VLAN. That would be a killer feature indeed.
 
Can you run iptables -nvL, does that rule actually catch any packets?

BTW, there is a way on newer kernels to use netfilter with bridge interfaces, but it’s not on by default. http://ebtables.netfilter.org/documentation/bridge-nf.html

Sure thing. I found some hits!

Code:
Jun 21 23:53:05 kernel: IN=br0 OUT=br0 SRC=192.168.2.74 DST=192.168.2.74 LEN=132 TOS=0x00 PREC=0x00 TTL=127 ID=6483 PROTO=UDP SPT=6880 DPT=6880 LEN=112 MARK=0x1
Jun 21 23:53:05 kernel: IN=br0 OUT=br0 SRC=192.168.2.74 DST=192.168.2.74 LEN=337 TOS=0x00 PREC=0x00 TTL=127 ID=25713 PROTO=UDP SPT=6880 DPT=6880 LEN=317 MARK=0x1

I am lost for words how in the hell the above packet was even routed!

It's a packet originating from my computer and then destined back towards my computer?!?
Port 6880 is my torrent port.

I have the my client running in the background but without any active torrents. Only DHT should be active.
 
Last edited:
My guess is your torrent client is checking to ensure that port 6880 is actually open somehow.

So is there any way to use the ebtables functionality inside AsusWRT/Merlin to do selective LAN filtering?
 
I have a bunch of IOT devices that I want to access the internet and accept incoming connections from specific hosts inside my LAN, but not create their own connections to hosts in my LAN.

Unfortunately not, I need several of the IOT devices to access selected hosts on my intranet. The Harmony hubs controls some devices over IP, the alexas/google homes need to connect to my Sonos speakers, etc.

Do you want IoT -> LAN access or no? I’m confused by your comments since I interpret ‘access’ with initiating connection.

Regardless, you should be able to do what you want with Guest networks. Most likely not out of the box on Asuswrt/Merlin, YazFi script should get you a bit more control (development is still ongoing and some upcoming features is close to what you want), and you can certainly achieve the access control you want with custom iptables rules.

https://www.snbforums.com/threads/yazfi-enhanced-asuswrt-merlin-guest-wifi-networks.45924/
 
Code:
Jun 21 23:53:05 kernel: IN=br0 OUT=br0 SRC=192.168.2.74 DST=192.168.2.74 LEN=132 TOS=0x00 PREC=0x00 TTL=127 ID=6483 PROTO=UDP SPT=6880 DPT=6880 LEN=112 MARK=0x1
Jun 21 23:53:05 kernel: IN=br0 OUT=br0 SRC=192.168.2.74 DST=192.168.2.74 LEN=337 TOS=0x00 PREC=0x00 TTL=127 ID=25713 PROTO=UDP SPT=6880 DPT=6880 LEN=317 MARK=0x1

I am lost for words how in the hell the above packet was even routed!
It took me a while to realise what's going on here. The only time that rule is invoked that I can think of is when NAT loopback is being used.

So in the example above there would have been a port forwarding rule on the WAN interface that pointed to 192.168.2.74:6880. A LAN device sending traffic to the WAN IP address for that port would un-bridge the traffic. The router will then DNAT the IP address to 192.168.2.74 and send it back to the bridge interface.
 
I want to selectively allow some IOT devices to access some hosts on my LAN, then reject all others.

YazFi looks promising, but it lists LAN access as an upcoming feature, so not available yet. Also it looks like when that feature is added, it will work just like the "allow intranet" switch in current guest wifi settings, which is not what I want. I want to selectively allow access from specific hosts to specific hosts.
 

Latest threads

Sign Up For SNBForums Daily Digest

Get an update of what's new every day delivered to your mailbox. Sign up here!
Top