Remotely access IP Camera behind OpenWrt router

I've been experiencing this problem for almost 2 days, I really don't know what to do, have just tinkering with OpenWrt a week ago. Please don't hesitate to ask if you need any logs/output.

So I have IP Camera accessible via RTSP stream, this Camera is connected to my OpenWrt router and have address of 192.168.16.92. I have established a connection between the router and my vps using wireguard tunnel, so if my device connected to OpenWrt router, I get my vps ip when typing whats my ip on google.

You might ask why do I include vps in this conversation ? Well I want to be able to view the IP Cam rtsp stream using the vps public IP Address without having to connected to wireguard tunnel, e.g. both of below should achieve same thing.

While connected to OpenWrt router.

rtsp://192.168.16.92:8544/main

Not connected to both OpenWrt router and wireguard. (9544 is forwarded to 8544)

rtsp://(my_vps_ip):9544/main

I have followed this guide → https://pulakk.github.io/blog/remote-camera/accessing-camera-remotely to no avail, I always get rtsp://(my_vps_ip):9554/main: Invalid data found when processing input when playing via ffplay.

The router is locked behind CGNAT and no way to pull normal port forwarding/ddns strategies with it. Any help will be appreciated, I've been pulling my hair.

First you should have symmetric routing between the VPS and your home router through the tunnel. This means the home router is not NATing into the tunnel, thus it won't be necessary to port-forward back through NAT at home. You should be able to ping the camera directly from the CLI of the VPS.

Then within the VPS, forward an external port to the camera.

In general it's a bad idea to expose IP cameras directly to the Internet, it would be better to set up an additional VPN tunnel from whatever device is viewing the camera to the VPS.

How would I do "symmetric routing between the VPS and your home router through the tunnel" ? Can you give me any leads where to start ? I really appreciate your response !

Please stop right here, reset your router to defaults, set new root passwords and PSKs - and forget about that howto, it's dangerously insecure to accept everything from wan.

Once you're back to start, you have to make a conscious policy decision. Do you really want to expose the camera stream on wan, to everyone on the whole world wide web - and can you trust the camera firmware enough to rely on its updating an security status (imho a strong no on both accounts).

If you don't, a much better strategy would be to set up a wireguard road-warrior style VPN, which would allow you (and maybe your family) to access the camera over the VPN tunnel.

3 Likes

The thing is, I have connected to the vpn tunnel and was able to access the luci page, I'm unable to access the IP Camera though.

I don't want to use the official camera app, I want to access the camera by using IP as in I'm on the same network with the camera.

Yes that guide tells you to make settings that are completely insecure, unnecessary, and to top it off it also won't work.

So if you ever did set wan input=ACCEPT and/or allow general wan->lan forwarding, consider your router compromised and reset it completely, including re-keying the VPN.

As a general good practice, instead of connecting them to the LAN, make a separate network for cameras and other Internet Things and do not allow that network to forward to your LAN or access anything in your routers other than DHCP and DNS. If the camera ever contains malicious software (and some do from the factory), it won't be usable to attack your LAN machines.

So how would I go about this ? What do you mean by creating separate network ? That setup sounds great and I would like to do that in my setup, but is there any step by step how to or keywords I should search on the net ?

If your camera uses wifi, you can follow this guide for a guest network:
https://openwrt.org/docs/guide-user/network/wifi/guestwifi/configuration_webinterface

If it is ethernet connected, you can make a minor modification to the recipe in that guide to setup an ethernet port on your router for this new network.

1 Like

Thanks, my camera uses WiFi, so this guide would totally help me. But I wanted to ask the original question though, how would I access the IP Camera without being connected to same network with OpenWrt ? I can access LuCi page but not the camera

In general, you'll add a firewall rule that allows initiating a connection from lan > guest (or whatever you call the new network), but not the other way around (the camera will still be able to reply).

Then, for the remote access, that depends on how the camera works -- if it is cloud connected, you can use that to handle the access. If not, the recommended method is via a VPN. I'd recommend Wireguard for that.

1 Like

If I setup wireguard tunnel between my vps and the router, will the vps able to stream the IP Camera ? I'm looking to restream it using mediamtx

Assuming the streaming will work across subnets, it should work across a VPN without any issues. If you're asking about the VPS actually re-streaming (i.e. receiving a stream and creating a new one), that's a different question and out of scope for these forums. If you're referring to the idea that you could connect to your VPS and initiate a connection to your camera -- that should work provided everything is properly configured.

1 Like

Thanks for your help ! I will try the suggestion here, the restream is easy as long the vps could access the camera.

I will report anything back if I found trouble, many thanks to you all :smiley:

Hello @psherman, I have successfully created a guest wifi, the client in this guest wifi cannot access luci page and they are isolated (cannot talk to other client in same network), it's looking great. Thanks for your advice.

You said that I have to add firewall rule so I can access IP Camera within wireguard tunnel, the thing is-- I'm not really sure how to do that, does below configuration looks right to you ?


Should the IP Camera given an IP Address by wireguard ? This is my PC IP Address the one I use to type this question, it is assigned by wireguard (I'm connected to wireguard).

5: liso: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state UNKNOWN group default qlen 1000
    link/none 
    inet 10.7.0.2/24 brd 10.7.0.255 scope global noprefixroute liso

The router is on 10.7.0.4, I can access it without being on same network—in the other hand, IP Camera is still given normal dhcp IP from router (currently 192.168.20.106). How would me (outside network but still in wireguard tunnel) access IP Camera ?

no, that doesn't look right.

Let's see your config:

Please connect to your OpenWrt device using ssh and copy the output of the following commands and post it 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
cat /etc/config/network
cat /etc/config/wireless
cat /etc/config/dhcp
cat /etc/config/firewall

Do yourself a favor and save your configuration before you change anything; each time.

It is easier to go back to a saved config than it is to try to remember what all you changed.

1 Like

ubus call system board

{
        "kernel": "5.10.176",
        "hostname": "OpenWrt",
        "system": "MediaTek MT7620N ver:2 eco:6",
        "model": "D-Link DWR-116 A1/A2",
        "board_name": "dlink,dwr-116-a1",
        "rootfs_type": "squashfs",
        "release": {
                "distribution": "OpenWrt",
                "version": "22.03.5",
                "revision": "r20134-5f15225c1e",
                "target": "ramips/mt7620",
                "description": "OpenWrt 22.03.5 r20134-5f15225c1e"
        }
}

cat /etc/config/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 '(redacted)'

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

config device
        option name 'eth0.1'
        option macaddr '(redacted)'

config interface 'lan'
        option device 'br-lan'
        option proto 'static'
        option netmask '255.255.255.0'
        option ip6assign '60'
        option ipaddr '192.168.16.1'
        option delegate '0'

config device
        option name 'eth0.2'
        option macaddr '(redacted)'

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

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

config switch_vlan
        option device 'switch0'
        option vlan '1'
        option ports '0 1 2 3 6t'

config switch_vlan
        option device 'switch0'
        option vlan '2'
        option ports '4 6t'

config interface 'wwan'
        option proto 'dhcp'

config interface 'WG0'
        option proto 'wireguard'
        option private_key '(redacted)'
        list addresses '10.7.0.4/24'
        option delegate '0'

config wireguard_WG0
        option description 'WGConnect'
        option public_key '(redacted)'
        option preshared_key '(redacted)'
        option route_allowed_ips '1'
        option endpoint_host '103.x.x.x'
        option endpoint_port '8920'
        option persistent_keepalive '25'
        list allowed_ips '10.7.0.0/24'

config interface 'cctv'
        option proto 'static'
        option ipaddr '192.168.20.1'
        option netmask '255.255.255.0'
        list dns '8.8.8.8'
        list dns '1.1.1.1'

cat /etc/config/wireless

config wifi-device 'radio0'
        option type 'mac80211'
        option path 'platform/10180000.wmac'
        option band '2g'
        option htmode 'HT20'
        option cell_density '0'
        option country 'ID'
        option channel '1'

config wifi-iface 'wifinet1'
        option device 'radio0'
        option mode 'sta'
        option network 'wwan'
        option ssid 'hiber1'
        option encryption 'psk2'
        option key '(redacted)'
        option disabled '1'

config wifi-iface 'wifinet3'
        option device 'radio0'
        option mode 'ap'
        option ssid 'hiber-tv'
        option isolate '1'
        option encryption 'psk2'
        option key '(redacted)'
        option network 'cctv'

cat /etc/config/dhcp

config dnsmasq
        option domainneeded '1'
        option localise_queries '1'
        option rebind_protection '1'
        option rebind_localhost '1'
        option local '/lan/'
        option domain 'lan'
        option expandhosts '1'
        option authoritative '1'
        option readethers '1'
        option leasefile '/tmp/dhcp.leases'
        option resolvfile '/tmp/resolv.conf.d/resolv.conf.auto'
        option localservice '1'
        option ednspacket_max '1232'

config dhcp 'lan'
        option interface 'lan'
        option start '100'
        option limit '150'
        option leasetime '12h'
        option dhcpv4 'server'
        option dhcpv6 'server'
        option ra 'server'
        list ra_flags 'managed-config'
        list ra_flags 'other-config'

config dhcp 'wan'
        option interface 'wan'
        option ignore '1'

config odhcpd 'odhcpd'
        option maindhcp '0'
        option leasefile '/tmp/hosts/odhcpd'
        option leasetrigger '/usr/sbin/odhcpd-update'
        option loglevel '4'

config dhcp 'cctv'
        option interface 'cctv'
        option start '100'
        option leasetime '12h'
        option limit '15'

config host
        option name 'dgiot'
        option ip '192.168.20.106'
        option mac '(redacted)'
        option leasetime 'infinite'

cat /etc/config/firewall

config defaults
        option syn_flood '1'
        option input 'ACCEPT'
        option output 'ACCEPT'
        option forward 'REJECT'

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

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

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 rule
        option name 'Allow-WG-Luci'
        list proto 'tcp'
        option src 'wan'
        option target 'ACCEPT'
        list src_ip '10.7.0.0/24'
        list dest_ip '10.7.0.4'
        option dest_port '80 443 9525'

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

config forwarding
        option src 'cctv'
        option dest 'wan'

config rule
        option name 'cctv-dhcp'
        list proto 'udp'
        option src 'cctv'
        option target 'ACCEPT'
        option dest_port '67'

config rule
        option name 'cctv-dns'
        option src 'cctv'
        option dest_port '53'
        option target 'ACCEPT'

config rule
        option name 'cctv-block-all'
        option src 'cctv'
        option target 'DROP'

Is your wireguard connection fully trusted? Currently you have it associated with the wan firewall zone, which would certainly be appropriate for a commercial VPN provider connection. However, if this is your own VPS and is trusted, you can put it in its own zone and it can then be more permissive (making the firewall config more straightforward).

If it is not fully trusted, the wan (or another zone that is similarly restricted) makes sense.

Yes it is hosted in my own vps, so that means I can put the interface on its own zones ? I have added new zone by Network > Interfaces > Edit WG0 > Firewall Settings > custom

I set the name of new zone to "wireguard", after this changes I should replace the existing firewall rules to match new zone right ?

Here it is new info after putting wireguard on its own zone.

cat /etc/config/firewall


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

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

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

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 rule
	option name 'Allow-WG-Luci'
	list proto 'tcp'
	option target 'ACCEPT'
	list src_ip '10.7.0.0/24'
	list dest_ip '10.7.0.4'
	option dest_port '80 443 9525'
	option src 'wireguard'

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

config forwarding
	option src 'cctv'
	option dest 'wan'

config rule
	option name 'cctv-dhcp'
	list proto 'udp'
	option src 'cctv'
	option target 'ACCEPT'
	option dest_port '67'

config rule
	option name 'cctv-dns'
	option src 'cctv'
	option dest_port '53'
	option target 'ACCEPT'

config rule
	option name 'cctv-block-all'
	option src 'cctv'
	option target 'DROP'

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

This rule is no longer necessary:

You appear to be allowing the camera to access the internet -- is that intended?

What is this rule for?

To allow the wireguard network to reach the CCTV network, just add this:

config forwarding
	option src 'wireguard'
	option dest 'cctv'

(and also make sure that the remote peer has 192.168.20.0/24 in its allowed IPs (if the remote peer has 0.0.0.0/0 or 192.168.0.0/16, you're already covered).