1

I am trying to configure a secondary network for my IOT stuff. I want to allow only a few device internet access and the rest should be "jailed" to that network. Also, all devices on the IOT network should be able to access my MQTT server that is on my main network.

My setup is as follows:

  • Firmware: DD-WRT v3.0-r34015M kongac (12/09/17) - More recent versions give me a lot of trouble with wireless connectivity. Wifi keeps dropping off after 10 minutes and the only way to fix it is to restart the router.
  • Hardware: Netgear R7000

My network is configured such that:

  • Under Wireless -> Basic Settings:

    • I've added a VAP
    • Network Config: Bridged
    • AP Isolation: Disable
  • Under Setup -> VLANs

    • Port 2 = VLAN15 (no bridge assignment)
  • Under Setup -> Networking

    • Added new bridge (br2)
    • Assigned wl02 and vlan15 to br2
    • Assigned 192.168.7.0/24 to br2
    • Added DHCP server for br2
  • Under Setup -> Advanced Routing

    • Added a route from 192.168.1.0/24 to 192.168.7.0/24 via br2

If I do not add any firewall rules, I am able to access devices on my IOT network from main network and, if I were to connect to my IOT network, I can browse the web.

After doing some searching, I added theses firewall rules (it seems like dd-wrt is always prepending the rules, so DROP needs to be entered first):

iptables -I FORWARD -i br2 -j DROP
iptables -I FORWARD -i br2 -o br0 -d 192.168.1.38 -p tcp --dport 1883 -m state --state NEW -j ACCEPT
iptables -I FORWARD -i br0 -o br2 -m state --state NEW -j ACCEPT

As a result,

  • IOT -> Internet = DENIED
  • Main -> IOT = DENIED
  • IOT -> 192.168.1.38:1883 = DENIED

I am sure that I am missing something with iptables, but not sure what.

Also, is it safe to assume that adding:

iptables -I FORWARD -i br2 -o br0 -s 192.168.7.5 -m state --state NEW -j ACCEPT

will allow 192.168.7.5 access the internet?

Any guidance is greatly appreciated.

Update: Output of requested commands (with redacted WAN IP):

root@DD-WRT:~# ip -br link
root@DD-WRT:~# ip -4 -br address
root@DD-WRT:~# ip route
default via 73.70.220.1 dev vlan2
X.X.X.X/23 dev vlan2  proto kernel  scope link  src X.X.X.X
127.0.0.0/8 dev lo  scope link
169.254.0.0/16 dev br0  proto kernel  scope link  src 169.254.255.1
172.16.0.0/24 via 172.16.0.1 dev vlan3
172.16.0.0/24 dev vlan3  proto kernel  scope link  src 172.16.0.3
192.168.1.0/24 via 192.168.1.1 dev br0  scope link
192.168.1.0/24 dev br0  proto kernel  scope link  src 192.168.1.1
192.168.7.0/24 via 192.168.7.1 dev br2  scope link
192.168.7.0/24 dev br2  proto kernel  scope link  src 192.168.7.1
192.168.15.0/24 dev br1  proto kernel  scope link  src 192.168.15.1
root@DD-WRT:~# ip rule
0:  from all lookup local
32766:  from all lookup main
32767:  from all lookup default
0

First thing: -I means insert at the head, ie prepend. Use -A to append at the end. -A might not actually work as expected if you don't also look at other iptables rules that might have been already put before. So let's keep using -I but with a incremented line number after to choose where to insert and have the rules in the usual order.

Your problem is about handling stateful rules. A conntrack flow is NEW with the first packet. Any reply packet won't be new, but will start the ESTABLISHED state. Your rules only allow NEW states so nothing can work correctly.

Not knowing all the other rules or network settings will lead to probable suboptimal/duplicate rules in this answer, but it should work anyway.

First add generic rules that will allow reply as well as related (eg: for udp errors with icmp or for helper modules like for ftp data) packets, one rule per direction. Those rules won't allow traffic alone because a new flow is always NEW (so not ESTABLISHED or RELATED) by definition. So you will only have to care about NEW states (-m conntrack --ctstate superseded -m state --state so you should rather use it if available, else juste replace all those strings back to -m state --state):

iptables -I FORWARD 1 -i br2 -o br0  -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
iptables -I FORWARD 2 -i br0 -o br2  -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

Now you can deal with (only) the new flows:
Note that the previous rule and the next rule could be combined in only one rule with all 3 states, or no state check at all since that will always be one of those 3 states (ok, beside INVALID)

iptables -I FORWARD 3 -i br0 -o br2 -m conntrack --ctstate NEW -j ACCEPT
iptables -I FORWARD 4 -i br2 -o br0 -d 192.168.1.38 -p tcp --dport 1883 -m conntrack --ctstate NEW -j ACCEPT
iptables -I FORWARD 5 -i br2 -j DROP

For your last question, I doubt what you wrote would allow Internet access, because internet might probably not be available on br0's interface. It would be available on the interface that has the public IP. This should work without knowing which interface it is, simply by not stating it (run after the previous commands, or reorder numbers accordingly. iptables-save and iptables-restore are your friends):

iptables -I FORWARD 5 -o br2 -d 192.168.7.5 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
iptables -I FORWARD 6 -i br2 -s 192.168.7.5 -m conntrack --ctstate NEW -j ACCEPT

But those missing informations added in the question would have helped for sure: ip -br link; ip -4 -br address; ip route; ip rule (and possibly iptables-save). Then rules could probably be made more generic still without lowering security.

UPDATE: mac match to match a MAC address.

It's possible to match a mac address instead of an IP. This information can only be used as source and makes sense only in the correct network. So -o br2 can't be used to match the MAC. Let's just replace the rule 5 above with a more generic one (which is still ok for security). Using -R to replace the rules 5 and 6 above, please adjust (again: iptables-save is handy):

iptables -R FORWARD 5 -o br2 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
iptables -R FORWARD 6 -i br2 -m mac --mac-source 02:03:04:05:06:07 -m conntrack --ctstate NEW -j ACCEPT

And in the end you get:

iptables -I FORWARD 1 -i br2 -o br0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
iptables -I FORWARD 2 -i br0 -o br2 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
iptables -I FORWARD 3 -i br0 -o br2 -m conntrack --ctstate NEW -j ACCEPT
iptables -I FORWARD 4 -d 192.168.1.38/32 -i br2 -o br0 -p tcp -m tcp --dport 1883 -m conntrack --ctstate NEW -j ACCEPT
iptables -I FORWARD 5 -o br2 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
iptables -I FORWARD 6 -i br2 -m mac --mac-source 02:03:04:05:06:07 -m conntrack --ctstate NEW -j ACCEPT
iptables -I FORWARD 7 -i br2 -j DROP

Fifth one is a superset of 2nd one only because there should probably be the WAN interface added in the rule but I don't know it.

  • Sorry for the delayed response and thank you for your detailed explanation on how this works. It makes a lot of sense now! I've tested the setup and it works like a charm! – dimaj Aug 15 '18 at 7:43
  • another question, if I may, is it possible to grant internet access to devices based on their MAC addresses instead of IP addresses? – dimaj Aug 15 '18 at 8:00
  • made an update in the answer accordingly – A.B Aug 15 '18 at 11:15
  • Thanks! So, based on your answer, I understand that I cannot use ip tables with mac address to filter incoming traffic. How do I know if I even need incoming traffic? For devices like Nest, do you know who is pinging who? Is Nest reaching out to a device or is device reaching out to Nest with "I'm alive" message? In other words, do I really care about --destination rules? Also, I've updated my original question with output of command you've mentioned earlier. Sorry I missed that before. – dimaj Aug 15 '18 at 16:52
  • You got it wrong: I just added an example with iptables doing fitering on incoming traffic based on MAC address. What made you think the opposite? For any other question, well ask an other question on this site or an other adequate site – A.B Aug 15 '18 at 17:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.