Adding subnet to existing home network

I'd like to add some IP cams in my garden. They are some closed software devices and I assume they may be used by someone to get access to my home network. I thought I could create a subnet for them and prevent this subnet to reach my existing network thanks to firewall rules.
This is what I want to do (orange is existing, blue is planned):


Let's say, on lan, Openwrt router is dhcp server for the IP cams. It gives them 10.0.0.x IP. On the wan port, Openwrt is a dhcp client receiving 192.168.1.x address from the ISP modem/router.
Does this make sense?
What should I do in firewall config?

Sure, this would work in general, but you do have to think about how you access your cameras (or the NVR), and if the system requires internet access.

In the default configuration, the blue part of the network would be able to access your main network as well as the internet. But you would not be able to connect to the cameras/NVR from the main network (orange) by default. You can adjust the firewall to allow access from your main lan > cameras/NVR, and to prohibit access to from cameras/NVR > main network and/or the internet. There are a number of approaches that are entirely possible, but you'll need to put in some thought/research to figure out what the actual requirements/goals are.

1 Like

No NVR in this, each cam is a server.

I set all this up for testing with an old computer in place of the IP cam. Everything is as you said the old computer can ping PC1 and PC2 as well as anything on the internet. PC1 and 2 cannot ping old PC. This is the opposite of what I need! Plus, the IP cams need to be reachable from internet because I will use my smartphone to watch their video stream.

This is simpler if you make OpenWrt the main router, routing the two networks and the Internet. But it can also work the way you have drawn. The important thing is to remove the default general forward rule that allows lan->wan (in this case lan is the cameras and wan is everything else) to block the cameras from originating any connections to your house LAN and possibly the Internet. Then make exceptions for incoming connections.

You absolutely need some sort of VPN rather than exposing incoming camera ports directly to the Internet. The smartphone would run a VPN client which connects to the OpenWrt router and tunnels the camera LAN IP range from the phone to the cameras.

2 Likes

Unfortunately, the modem/router is mandatory. It is given by the ISP and is needed for the phone. There is very little configuration to be done with it. You can stop its dhcp server and set nat rules, but no "bridge mode" available.

I am going to work on the firewall setup first as this is new to me. If I am successfull, then, I will add the VPN layer! Thanks for the advice, anyway.

I don't understand much in firewall setting! The default config file is already too much for me. Can I start with something like this?

config rule
   option name 'Allow-watch-from-PCs'
   option src '192.168.0.10' # aka PC1
   option src '192.168.0.20' # aka PC2
   option dest '10.0.0.10' # aka cam1
   option dest '10.0.0.20' # aka cam2
   option target 'ACCEPT'

config rule
   option name 'parachute' # Only for test time
   option src 'any'
   option dest '192.168.0.100' # aka Openwrt
   option target 'ACCEPT'

Not with the default configuration, no. Masquerading on the WAN zone makes this impossible.

Taking a step back... does your main (ISP) router have support for adding static routes? If so, that will make the process significantly easier.

Well, as I need a starting point, I thought I would get rid of the default configuration and write only my two rules in /etc/config/firewall. I don't understand what masquerading does exept it's a kind of gateway for non-server machines. Sorry, this is my first attempt at networking :woozy_face:

The main router is not manageable at all. Only dhcp on/off and NAT.

Masquerading basically 'hides' an entire network (or even multiple networks) behind a single IP address. In the case of most masqueraded internet connections, a single IPv4 address is issued by the ISP -- the router takes this address. Behind the router is a complete private network. From the perspective of the world outside the private network, the IPv4 address held by the router is just that -- a single IP address and a single host. Everything appears to originate and/or terminate at the router -- the rest of the world does not know that there is a network behind it.

Beyond that, the rest of the world cannot directly access any hosts behind the router via the private IP addresses assigned to them in the router's network. Port forwarding is a mechanism by which this can be done, but this is distinctly different than directly accessing the host -- a port on the 'wan' side of a masquerading router can only be used to connect to one host... so if you have a 2 hosts with web servers on port 80 and/or 443, you could only map do 80 > 80 and 443 > 443 port mapping for one of them... for the other you'd have to use alternate ports (like 8080 > 80, 8443 > 443, etc, as an example). [note: in some cases, there are practical, but more complex solutions for handling this port mapping limitation, but it is limited to certain things and often requires stuff like reverse proxies and the like]. When this is done, the apparent IP address of the server is actually the IP address on the WAN of the router (i.e. the public IPv4 address from the ISP).

Setting static routes on your main router allows you to tell the main router the correct path to use to access the network behind the secondary router. Then you can turn off masquerading on the downstream router and traffic will flow. If you turn off masquerading without a corresponding static route, the main router will not know how to direct the return traffic, and it will simply get dropped.

In your case, considering that you must keep the ISP's router in place, the more practical solution may be to move your entire network behind the OpenWrt router. This means your entire network will be behind double-NAT (which is a problem in certain situations, but most protocols handle it without issue). From there, you can create two independent networks on the OpenWrt router that can then meet all of your requirements.

1 Like

First off, for any of this to work, the OpenWrt router wan side needs to have a fixed known IP on the home network (main router's LAN). The best way to do this is with a DHCP reservation in the main router. The other way is to configure it static on the OpenWrt WAN interface.

If you can enter static routes into the main router, enter the camera subnet (10.0.0.0/24) gatewayed via the OpenWrt router's wan IP on the main network. Then turn off masquerading on the OpenWrt router. For testing you can set a general firewall forward from wan to lan (but remove the default forward from lan to wan, since you don't want the cameras to initiate any connections). If you want to make it more restrictive you will need to remove the general rule and write a specific rule for each connection that you want to be allowed.

If you cannot enter static routes in the main router, the OpenWrt router needs to continue to masquerade its wan. In this case you'll need to forward and translate ports through OpenWrt to reach the cameras from the main lan. All of the cameras will appear to be at the OpenWrt router's IP, but with different port numbers.

Another approach is to go to a VPN where encapsulated and encrypted packets are sent to the OpenWrt router, where the tunnel opens with a non-masquerade route to the camera LAN. This will work from inside the home network as well as outside, if you forward a single port from the Internet through to the OpenWrt router.

I came to this solution. PC are on vlan1 and IPcams on vlan3. Now the network looks like this:

I am now dealing with firewall. I do not want any device on vlan3 to be able to access PC's or routers anywhere on the home network. So, I set up a firewall zone named IPcams for vlan3 and started with rejecting everything like this:

But there is something wrong. I can ping the modem, the router and the PC's on vlan1 from vlan3!

Please run the following commands (copy-paste the whole block) and paste the output here, using the "Preformatted text </> " button:
grafik
Remember to redact passwords, MAC addresses and any public IP addresses you may have

ubus call system board; \
uci export network; uci export firewall; \
head -n -0 /etc/firewall.user; \
iptables-save -c; ip6tables-save -c; nft list ruleset; \
ip -4 addr ; ip -4 ro li tab all ; ip -4 ru

The ISP modem's IP is 192.168.1.1 and openWRT has 192.168.1.25 on wan. The dhcp server on vlan1 gives 192.168.0.x and on vlan3 it gives 10.0.30.x IP's.

{
	"kernel": "5.10.146",
	"hostname": "OpenWrt",
	"system": "Broadcom BCM4712",
	"model": "Linksys WRT54G/GS/GL",
	"board_name": "0x0101:42",
	"rootfs_type": "squashfs",
	"release": {
		"distribution": "OpenWrt",
		"version": "22.03.2",
		"revision": "r19803-9a599fee93",
		"target": "bcm47xx/legacy",
		"description": "OpenWrt 22.03.2 r19803-9a599fee93"
	}
}
package network

config interface 'loopback'
	option device 'lo'
	option proto 'static'
	option ipaddr '127.0.0.1'
	option netmask '255.0.0.0'

config globals 'globals'
	option ula_prefix 'fdeb:55fb:0078::/48'

config device
	option name 'br-lan'
	option type 'bridge'
	list ports 'eth0.1'

config interface 'lan'
	option device 'br-lan'
	option proto 'static'
	option netmask '255.255.255.0'
	option ipaddr '192.168.0.100'

config interface 'wan'
	option device 'eth0.2'
	option proto 'dhcp'

config interface 'wan6'
	option device 'eth0.2'
	option proto 'dhcpv6'

config switch
	option name 'switch0'
	option reset '1'
	option enable_vlan '1'

config switch_vlan
	option device 'switch0'
	option vlan '1'
	option vid '1'
	option ports '1 2 5t'

config switch_vlan
	option device 'switch0'
	option vlan '2'
	option ports '0 5t'
	option vid '2'

config device
	option name 'eth0'

config device
	option name 'eth0.1'
	option type '8021q'
	option ifname 'eth0'
	option vid '1'

config device
	option name 'eth0.2'
	option type '8021q'
	option ifname 'eth0'
	option vid '2'

config switch_vlan
	option device 'switch0'
	option vlan '3'
	option ports '3 4 5t'
	option vid '3'

config device
	option name 'eth0.3'
	option type '8021q'
	option ifname 'eth0'
	option vid '3'

config device
	option name 'br-lan-cam'
	option type 'bridge'
	list ports 'eth0.3'

config interface 'LANCAM'
	option proto 'static'
	option device 'br-lan-cam'
	option ipaddr '10.0.30.1'
	option netmask '255.255.255.0'

package firewall

config defaults
	option input 'ACCEPT'
	option output 'ACCEPT'
	option synflood_protect '1'
	option forward 'ACCEPT'

config zone
	option name 'lan'
	option output 'ACCEPT'
	option forward 'REJECT'
	option input 'ACCEPT'
	list network 'lan'

config zone
	option name 'wan'
	option output 'ACCEPT'
	option masq '1'
	option mtu_fix '1'
	option forward 'ACCEPT'
	list network 'wan'
	list network 'wan6'
	option input 'REJECT'

config forwarding
	option src 'lan'
	option dest 'wan'

config rule
	option name 'Allow-DHCP-Renew'
	option src 'wan'
	option proto 'udp'
	option dest_port '68'
	option target 'ACCEPT'
	option family 'ipv4'

config rule
	option name 'Allow-Ping'
	option src 'wan'
	option proto 'icmp'
	option icmp_type 'echo-request'
	option family 'ipv4'
	option target 'ACCEPT'

config rule
	option name 'Allow-IGMP'
	option src 'wan'
	option proto 'igmp'
	option family 'ipv4'
	option target 'ACCEPT'

config rule
	option name 'Allow-DHCPv6'
	option src 'wan'
	option proto 'udp'
	option dest_port '546'
	option family 'ipv6'
	option target 'ACCEPT'

config rule
	option name 'Allow-MLD'
	option src 'wan'
	option proto 'icmp'
	option src_ip 'fe80::/10'
	list icmp_type '130/0'
	list icmp_type '131/0'
	list icmp_type '132/0'
	list icmp_type '143/0'
	option family 'ipv6'
	option target 'ACCEPT'

config rule
	option name 'Allow-ICMPv6-Input'
	option src 'wan'
	option proto 'icmp'
	list icmp_type 'echo-request'
	list icmp_type 'echo-reply'
	list icmp_type 'destination-unreachable'
	list icmp_type 'packet-too-big'
	list icmp_type 'time-exceeded'
	list icmp_type 'bad-header'
	list icmp_type 'unknown-header-type'
	list icmp_type 'router-solicitation'
	list icmp_type 'neighbour-solicitation'
	list icmp_type 'router-advertisement'
	list icmp_type 'neighbour-advertisement'
	option limit '1000/sec'
	option family 'ipv6'
	option target 'ACCEPT'

config rule
	option name 'Allow-ICMPv6-Forward'
	option src 'wan'
	option dest '*'
	option proto 'icmp'
	list icmp_type 'echo-request'
	list icmp_type 'echo-reply'
	list icmp_type 'destination-unreachable'
	list icmp_type 'packet-too-big'
	list icmp_type 'time-exceeded'
	list icmp_type 'bad-header'
	list icmp_type 'unknown-header-type'
	option limit '1000/sec'
	option family 'ipv6'
	option target 'ACCEPT'

config rule
	option name 'Allow-IPSec-ESP'
	option src 'wan'
	option dest 'lan'
	option proto 'esp'
	option target 'ACCEPT'

config rule
	option name 'Allow-ISAKMP'
	option src 'wan'
	option dest 'lan'
	option dest_port '500'
	option proto 'udp'
	option target 'ACCEPT'

config zone
	option name 'IPcams'
	option forward 'REJECT'
	list network 'LANCAM'
	option input 'REJECT'
	option output 'REJECT'

config forwarding
	option src 'lan'
	option dest 'IPcams'

config forwarding
	option src 'IPcams'
	option dest 'wan'

config rule
	option name 'IPcams DHCP and DNS'
	option src 'IPcams'
	option dest_port '53 67 68'
	option target 'ACCEPT'

config rule
	list proto 'tcp'
	option src 'lan'
	option dest 'wan'
	option dest_port '80 443'
	option target 'ACCEPT'
	option name 'allow modem web config'

head: /etc/firewall.user: No such file or directory
-ash: iptables-save: not found
-ash: ip6tables-save: not found
table inet fw4 {
	chain input {
		type filter hook input priority filter; policy accept;
		iifname "lo" accept comment "!fw4: Accept traffic from loopback"
		ct state established,related accept comment "!fw4: Allow inbound established and related flows"
		tcp flags syn / fin,syn,rst,ack jump syn_flood comment "!fw4: Rate limit TCP syn packets"
		iifname "br-lan" jump input_lan comment "!fw4: Handle lan IPv4/IPv6 input traffic"
		iifname "eth0.2" jump input_wan comment "!fw4: Handle wan IPv4/IPv6 input traffic"
		iifname "br-lan-cam" jump input_IPcams comment "!fw4: Handle IPcams IPv4/IPv6 input traffic"
	}

	chain forward {
		type filter hook forward priority filter; policy accept;
		ct state established,related accept comment "!fw4: Allow forwarded established and related flows"
		iifname "br-lan" jump forward_lan comment "!fw4: Handle lan IPv4/IPv6 forward traffic"
		iifname "eth0.2" jump forward_wan comment "!fw4: Handle wan IPv4/IPv6 forward traffic"
		iifname "br-lan-cam" jump forward_IPcams comment "!fw4: Handle IPcams IPv4/IPv6 forward traffic"
	}

	chain output {
		type filter hook output priority filter; policy accept;
		oifname "lo" accept comment "!fw4: Accept traffic towards loopback"
		ct state established,related accept comment "!fw4: Allow outbound established and related flows"
		oifname "br-lan" jump output_lan comment "!fw4: Handle lan IPv4/IPv6 output traffic"
		oifname "eth0.2" jump output_wan comment "!fw4: Handle wan IPv4/IPv6 output traffic"
		oifname "br-lan-cam" jump output_IPcams comment "!fw4: Handle IPcams IPv4/IPv6 output traffic"
	}

	chain prerouting {
		type filter hook prerouting priority filter; policy accept;
		iifname "br-lan" jump helper_lan comment "!fw4: Handle lan IPv4/IPv6 helper assignment"
		iifname "br-lan-cam" jump helper_IPcams comment "!fw4: Handle IPcams IPv4/IPv6 helper assignment"
	}

	chain handle_reject {
		meta l4proto tcp reject with tcp reset comment "!fw4: Reject TCP traffic"
		reject comment "!fw4: Reject any other traffic"
	}

	chain syn_flood {
		limit rate 25/second burst 50 packets return comment "!fw4: Accept SYN packets below rate-limit"
		drop comment "!fw4: Drop excess packets"
	}

	chain input_lan {
		jump accept_from_lan
	}

	chain output_lan {
		jump accept_to_lan
	}

	chain forward_lan {
		tcp dport { 80, 443 } counter packets 0 bytes 0 jump accept_to_wan comment "!fw4: allow modem web config"
		jump accept_to_wan comment "!fw4: Accept lan to wan forwarding"
		jump accept_to_IPcams comment "!fw4: Accept lan to IPcams forwarding"
		jump reject_to_lan
	}

	chain helper_lan {
	}

	chain accept_from_lan {
		iifname "br-lan" counter packets 0 bytes 0 accept comment "!fw4: accept lan IPv4/IPv6 traffic"
	}

	chain accept_to_lan {
		oifname "br-lan" counter packets 0 bytes 0 accept comment "!fw4: accept lan IPv4/IPv6 traffic"
	}

	chain reject_to_lan {
		oifname "br-lan" counter packets 0 bytes 0 jump handle_reject comment "!fw4: reject lan IPv4/IPv6 traffic"
	}

	chain input_wan {
		meta nfproto ipv4 udp dport 68 counter packets 0 bytes 0 accept comment "!fw4: Allow-DHCP-Renew"
		icmp type echo-request counter packets 0 bytes 0 accept comment "!fw4: Allow-Ping"
		meta nfproto ipv4 meta l4proto igmp counter packets 1 bytes 32 accept comment "!fw4: Allow-IGMP"
		meta nfproto ipv6 udp dport 546 counter packets 0 bytes 0 accept comment "!fw4: Allow-DHCPv6"
		ip6 saddr fe80::/10 icmpv6 type . icmpv6 code { mld-listener-query . no-route, mld-listener-report . no-route, mld-listener-done . no-route, mld2-listener-report . no-route } counter packets 0 bytes 0 accept comment "!fw4: Allow-MLD"
		icmpv6 type { destination-unreachable, time-exceeded, echo-request, echo-reply, nd-router-solicit, nd-router-advert } limit rate 1000/second counter packets 1 bytes 144 accept comment "!fw4: Allow-ICMPv6-Input"
		icmpv6 type . icmpv6 code { packet-too-big . no-route, parameter-problem . no-route, nd-neighbor-solicit . no-route, nd-neighbor-advert . no-route, parameter-problem . admin-prohibited } limit rate 1000/second counter packets 3 bytes 208 accept comment "!fw4: Allow-ICMPv6-Input"
		jump reject_from_wan
	}

	chain output_wan {
		jump accept_to_wan
	}

	chain forward_wan {
		icmpv6 type { destination-unreachable, time-exceeded, echo-request, echo-reply } limit rate 1000/second counter packets 0 bytes 0 accept comment "!fw4: Allow-ICMPv6-Forward"
		icmpv6 type . icmpv6 code { packet-too-big . no-route, parameter-problem . no-route, parameter-problem . admin-prohibited } limit rate 1000/second counter packets 0 bytes 0 accept comment "!fw4: Allow-ICMPv6-Forward"
		meta l4proto esp counter packets 0 bytes 0 jump accept_to_lan comment "!fw4: Allow-IPSec-ESP"
		udp dport 500 counter packets 0 bytes 0 jump accept_to_lan comment "!fw4: Allow-ISAKMP"
		jump accept_to_wan
	}

	chain accept_to_wan {
		oifname "eth0.2" counter packets 7 bytes 750 accept comment "!fw4: accept wan IPv4/IPv6 traffic"
	}

	chain reject_from_wan {
		iifname "eth0.2" counter packets 0 bytes 0 jump handle_reject comment "!fw4: reject wan IPv4/IPv6 traffic"
	}

	chain input_IPcams {
		tcp dport { 53, 67, 68 } counter packets 0 bytes 0 accept comment "!fw4: IPcams DHCP and DNS"
		udp dport { 53, 67, 68 } counter packets 0 bytes 0 accept comment "!fw4: IPcams DHCP and DNS"
		jump reject_from_IPcams
	}

	chain output_IPcams {
		jump reject_to_IPcams
	}

	chain forward_IPcams {
		jump accept_to_wan comment "!fw4: Accept IPcams to wan forwarding"
		jump reject_to_IPcams
	}

	chain helper_IPcams {
	}

	chain accept_to_IPcams {
		oifname "br-lan-cam" counter packets 0 bytes 0 accept comment "!fw4: accept IPcams IPv4/IPv6 traffic"
	}

	chain reject_from_IPcams {
		iifname "br-lan-cam" counter packets 0 bytes 0 jump handle_reject comment "!fw4: reject IPcams IPv4/IPv6 traffic"
	}

	chain reject_to_IPcams {
		oifname "br-lan-cam" counter packets 0 bytes 0 jump handle_reject comment "!fw4: reject IPcams IPv4/IPv6 traffic"
	}

	chain dstnat {
		type nat hook prerouting priority dstnat; policy accept;
	}

	chain srcnat {
		type nat hook postrouting priority srcnat; policy accept;
		oifname "eth0.2" jump srcnat_wan comment "!fw4: Handle wan IPv4/IPv6 srcnat traffic"
	}

	chain srcnat_wan {
		meta nfproto ipv4 masquerade comment "!fw4: Masquerade IPv4 wan traffic"
	}

	chain raw_prerouting {
		type filter hook prerouting priority raw; policy accept;
	}

	chain raw_output {
		type filter hook output priority raw; policy accept;
	}

	chain mangle_prerouting {
		type filter hook prerouting priority mangle; policy accept;
	}

	chain mangle_postrouting {
		type filter hook postrouting priority mangle; policy accept;
	}

	chain mangle_input {
		type filter hook input priority mangle; policy accept;
	}

	chain mangle_output {
		type route hook output priority mangle; policy accept;
	}

	chain mangle_forward {
		type filter hook forward priority mangle; policy accept;
		iifname "eth0.2" tcp flags syn tcp option maxseg size set rt mtu comment "!fw4: Zone wan IPv4/IPv6 ingress MTU fixing"
		oifname "eth0.2" tcp flags syn tcp option maxseg size set rt mtu comment "!fw4: Zone wan IPv4/IPv6 egress MTU fixing"
	}
}
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
5: br-lan: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP qlen 1000
    inet 192.168.0.100/24 brd 192.168.0.255 scope global br-lan
       valid_lft forever preferred_lft forever
7: eth0.2@eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP qlen 1000
    inet 192.168.1.25/24 brd 192.168.1.255 scope global eth0.2
       valid_lft forever preferred_lft forever
8: br-lan-cam: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP qlen 1000
    inet 10.0.30.1/24 brd 10.0.30.255 scope global br-lan-cam
       valid_lft forever preferred_lft forever
default via 192.168.1.1 dev eth0.2  src 192.168.1.25 
10.0.30.0/24 dev br-lan-cam scope link  src 10.0.30.1 
192.168.0.0/24 dev br-lan scope link  src 192.168.0.100 
192.168.1.0/24 dev eth0.2 scope link  src 192.168.1.25 
broadcast 10.0.30.0 dev br-lan-cam table local scope link  src 10.0.30.1 
local 10.0.30.1 dev br-lan-cam table local scope host  src 10.0.30.1 
broadcast 10.0.30.255 dev br-lan-cam table local scope link  src 10.0.30.1 
broadcast 127.0.0.0 dev lo table local scope link  src 127.0.0.1 
local 127.0.0.0/8 dev lo table local scope host  src 127.0.0.1 
local 127.0.0.1 dev lo table local scope host  src 127.0.0.1 
broadcast 127.255.255.255 dev lo table local scope link  src 127.0.0.1 
broadcast 192.168.0.0 dev br-lan table local scope link  src 192.168.0.100 
local 192.168.0.100 dev br-lan table local scope host  src 192.168.0.100 
broadcast 192.168.0.255 dev br-lan table local scope link  src 192.168.0.100 
broadcast 192.168.1.0 dev eth0.2 table local scope link  src 192.168.1.25 
local 192.168.1.25 dev eth0.2 table local scope host  src 192.168.1.25 
broadcast 192.168.1.255 dev eth0.2 table local scope link  src 192.168.1.25 
0:	from all lookup local 
32766:	from all lookup main 
32767:	from all lookup default 

One thing is to fix the default forward policy to REJECT. This is why camera zone works with lan.
The other thing is to switch the lancam zone output to accept. There is no security risk with that and it will be helpful when troubleshooting.

2 Likes

Thank you. With these settings vlan3 devices are unable to talk to vlan1.

How could vlan1 PC's access the IPcams on vlan3 so they can watch their stream?

That should work due to the forwarding allowed between lan and IPcam. The camera's IP address must be known in advance.
If you can access a camera's web page but not the video stream you may need to allow RTP packets from cam->lan. I'm not sure exactly how that works.

2 Likes

You are right, it works. The problem was I had not restarted all devices.

It seems the "Save and apply" button in LuCI does not really applies new settings.

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.