How to securely watch IP cameras without VPN?

Hello all, I’m struggling with this puzzle/goal/want. I want to check via web browser from work my Reolink IP camera setup. Because its work:

  • Cannot VPN from work laptop, I need to stay on work network.

I do not want to port forward the Reolink NVR, way too insecure.

Middle ground a work buddy proposed is port forward the NVR, but firewall/block all IPs outside of my work’s IP(s). Maybe go a step further and put the NVR in a DMZ as well. But I would like to go further than this and use this as an opportunity to learn some new things.

I have started looking in bastion hosting, but the google results are all gunked up with AWS and Azure tutorials and advertising, I haven’t found a tutorial using an OS/VM I can support and setup at home.

I like the idea of a bastion host as I can lockout all but one port, firewall so only the work IP(s) can access that exposed port, and (if linux) even use google 2FA for this remoting in. Another pro with the 2FA is to mitigate if some ass-hat watching Forcepoint innerview logs w/ keylogging (work is pretty secure) they cannot play with ethics and log into my bastion host.

Any advice on proceeding on with this goal? I’m a looking in the right direction? Any good websites/tutorials LVL1 peeps have to recommend?

Set up an inbound HTTPS proxy and only permit work’s IP addresses on it.

OR

Set up inbound SSH on whatever port and use an SSH tunnel to forward connections from your local machine on port X to the remote machine on port Y.

SSH may be the easiest way, assuming work permits outbound connections to whatever port you run SSH on.

It will be relatively easy to set up - you just need a machine on your network that exposes SSH to the world. The SSH option you’re looking for in the man-page is -L.

If you do use SSH, make sure you’re using public key authentication.

if you’re not, you really should be. Disable password auth for any SSH exposed to the internet (and really, if you do key based auth properly its not a hassle to use internally either).

If you’re unfamiliar with using ssh with keys, i can give you a quick overview if you need it.

edit:
e.g., this sets up a connection from my local machine on port 5555 to pop out onto the remote SSH host’s (10.51.65.13 is a remote linux box) network to the ip 10.3.1.12 on port 80 (a web server the linux box can reach).

jrose@RMBP13 ~ % ssh [email protected] -L 127.0.0.1:5555:10.3.1.12:80

so i can use a web browser to http://127.0.0.1:5555 to access port 80 on a machine 10.3.1.12 on the remote network, via the machine i’ve ssh’d to.

It’s basically set up a 1:1 mapping of local port 5555 to remote port 80 using the SSH box as a tunnel.

If you have a home router that runs SSH you’re already most of the way there.

5 Likes

+1 to ssh and +100 to this. Yes it can be more annoying to setup, but it’s definitely more secure

1 Like

It’s actually not that bad when you get your head around it - but for mortals who just want to know enough to connect - the documentation sucks.

For those who aren’t aware, the basic premise is

  • on the machine you are going to log in to other machines from run ssh-keygen and follow the prompts. It will generate 2 files for you in ~/.ssh - id_rsa and id_rsa.pub
  • i rename my id_rsa.pub file to be something like “macbook_id_rsa.pub” (for the one on my macbook for example) so i know which machine it was from.
  • the id_rsa file (or “identity”) is PRIVATE and stays in your home folder on the machine you generated it on. You don’t move this file from machine to machine, you generate a new id_rsa/id_rsa.pub file on EACH machine you are going to connect to other boxes from.
  • copy your id_rsa.pub file (your PUBLIC key) to the remote machine(s) and add it to the file ~/.ssh/authorized_keys. i’m pretty sure you can also put comments in the file to describe which key is which but can’t remember.

Can’t stress enough - the private part of the key (the file without .pub on it) - that shouldn’t leave your machine, and should be kept secure. Don’t copy it around, use a new private key for each machine. Makes it easier to remove the proper key(s) if you have a key compromise or get rid of a machine.

Give your .pub file to anyone you like. Thats how they will identify your login. That can be disclosed to anyone, posted on the internet, whatever. Hence “public” key.

if the remote machine is set up for public key auth, your private key on your client machine will then authenticate to the remote machine using your stored (on the other end) public key

You can then disable password auth. If password auth is disabled, doesn’t matter how many brute force attempts someone does, without your private key, they aint getting in. Because instead of a password (which even a good one may only have a hundred or so bits of entropy), you’re authenticating with a several thousand bit key file.

1 Like

Are these your home cameras you’re trying to secure to be able to access from work, or work cameras?

IP based security, … is not really considered security (by many people).

An inbound (reverse) https proxy + basic authentication is secure enough technically speaking. Basic auth with username/password in plain text is secure enough to pass any kind of us federal government audit, but for 1 or 2 people working it’s at least easy to set up. If you’ve ever setup a webserver - this is childs play. (so not that hard at all).

The question is, is your reolink setup proxyable in that way, ie. does it load any third party resources? You can check with ctrl+shift+j in chrome and reload while looking at the network tab, … or you could install umatrix chrome extension and see what it tells you.

Also, I don’t know how you authenticate to the nvr. Does it have a login screen that gives your browser a cookie? Or does your browser ask for user/pass (https reverse proxy can work with either, just needs a bit of setup for the specific case).

If this sounds feasible to you read on:


… first thing you need is a domain name from a provider you can reasonably trust (alternative, if you don’t trust the domain name is that you’d need client side certificates and that’s just a pain in the ass to install on all devices you use and maintain). For home / small office use e.g. www.duckdns.org is probably trust worthy enough, and in that case you only need server side certs and some basic auth.

… second thing you need, and speaking of server side - you need something like a raspberry pi, or a small VM if you already have some VM setup. or perhaps you can set this up in a container (if you don’t know how, don’t and do it on a raspberry pi to start with … duct tape it to the nvr). What you’d do would be to forward a port from your router to this Raspberry pi (or a vm on prem, or a cloud vm, or to a container or whatever). This port would run nginx, and would terminate the https session, and authenticate you, and forward requests to the less secure nvr. It’d have to have a static ip internally (for router to port forward to). On this raspberry pi, you can have 1 cron that updates your domain name so that it points to your public IP.
And another cron to refresh the cert from letsencrypt and reload nginx, such that it loads a new cert every time it refreshes it (I use acme.sh - other solutions I tried are more work, or used to be back when I tried them)

Your nginx setup would be really simple,

example that works easily with debian that keeps a separate config per domain:

/etc/nginx/sites-available/<DOMAIN>
server {
        # this is for certificate renewal, and https redirect ...
        # ... I run standard ports 80/443 and a separate subdomain for
        # ... each of the services I proxy ...
        # ... I'm not sure how acme webroot challenge would work from a
        # ... non standard port. There's probably options for that too.
        listen 80;
        listen [::]:80;  # ipv6

        server_name <DOMAIN>; # <-- fill in ext domain

        # directory that acme.sh uses to answer a challenge ...
        # ... when renewing let's encrypt certs, -w flag of acme.sh
        location /.well-known/acme-challenge/ {
                allow all;
                root /home/<USER>/.acme.sh/webroot/;  # <-- fill in user
                default_type "text/plain";
        }
        location / { return 301 https://$host$request_uri; }
}
server {
        listen 443 ssl;
        listen [::]:443;

        server_name <DOMAIN>; # <-- fill in ext domain

        ssl_certificate /home/<USER>/.acme.sh/<DOMAIN>/fullchain.cer; # <-- fill in user and domain
        ssl_certificate_key /home/<USER>/.acme.sh/<DOMAIN>/<DOMAIN>.key; # <-- fill in user and domain

        auth_basic      "Restricted";
        # format for file below, very easy, but password not encrypted.
        # user:{PLAIN}password:comment
        # user2:{PLAIN}password2:comment2
        # ...
        # it's possible to store passwords as salted hashes too,...
        # ... but this requires a tool to compute and store and edit.
        # ... many other non-file based auths or non-basic auths
        # ... are also possible, but more complex to set up.
        auth_basic_user_file    /etc/nginx/htpasswd;

        location / {
                proxy_pass http://<ENDPOINT_IP_OR_HOST>:<PORT>; # <-- fill in the endpoint behind your firewall
        }
}

Now that I look at it, it’s a bit fiddly, (it felt easier when I was setting it up, honestly). there’s the acme.sh certificate renewal tool, and there’s directory permissions, and machine wide nginx settings. Those aren’t hard either solvable. How you manage your passwords, for home/small office, that htpasswd file is good enough, but it’s definitely not best practice. (it’s still better than ip based security thanks to https).

Let me know if want more detail/help on these other aspects, … if this reverse https proxy situation sounds useful to you.

1 Like

^^ yeah… but an SSH tunnel is a lot less work, and if you already have a router running ssh… its already there, basically :smiley:

a lot depends on what’s already there. Even with ssh if you have openwrt/ddwrt/pfsense or whatever then it’s there, but probably not if it’s an off the shelf router.

buying a $50 router to put behind an existing one, and port forwarding what’s needed for a split tunnel VPN might actually be easier.

@thro … there’s plenty of options, @Token needs to clarify their use case. (are cameras at home or at work, are they webui or do they need a horrible non-browser app, do they care to have access from a phone, do they have any budget/ability with linux, or not).

1 Like

I will try to clarify use-case.

Home cameras, reolinks nvr that uses text credentials and only works with IE over port 9000

Work: have to get temp admin password to make most changes, and some GPOs I have no way of getting around such as adding x509 CAs

Home router is pfSense, my reolinks (cams and nvr) are on a vlan.

So I need the ability to use IE on my work computer to browse my home cameras/nvr.

Insecure “easy” method, port forward and pray reolink creds are good enough.

I would like to add a layer, some proxy or bastion host that adds a layer of authentication but again will have limits on my work laptops permissions to add certs or additional software.

Hmm, maybe you have the option of setting up a zerotier from your company network?

Catch traffic from cameras, transfer it to some server / pc there, set zerotier to external server (UDP hole punching) and connect your pc to this network.
Encryption, and your pc will be as if it were locally in lan with cameras.

No need to expose ports to the world. No need to add rules on FW for foreign IP for inbound traffic. From both sides, the traffic will only go to an external server that will hook both ends and will act as a hub.
zero

Or put a machine / VM containing IE at home and expose the port to the world(only allow IP’s from work in the firewall). From work, connect to your home machine with x2go and watch cameras on it … but it will be slow and extremely low fps.

1 Like

@risk and @thro and others, I will try to process your responses today, work and life has been hectic, in fact I just got back in town from work travel.

I forgot to mention two more details, my home IP is static (pretty cool) and I have a domain I can leverage. So far only port 8123 is being used for home assistant. I would like to reserve 443 for a website.

Personally, I would try to avoid exposing these cameras directly to the world. If for some reason you are unable to implement zerotier and you want to avoid opening ports to the world then maybe chrome remote desktop if you trust google of course :wink:

In your place, I would simply invest in an additional machine or put a VM specifically for these cameras and connect to this machine remotely. Zerotier and CRD do not require theoretically exposing the service to the world and thus you do not need to add rules to FW.
However, if you choose the path with something like x2go then all you need to do is on your home FW add rules incoming for IP’s from work on a specific port on which remote sessions will listen. In general, I would avoid DMZ and exposing these cameras directly, it is better to do it through a local machine in lan.

Googling it now.

This shows how little I know as I do not even know how to effectively ask.

Also more important details I should have included- I have an always on type 1 hypervisor home lab environment so spinning up VMs are not an issue, in fact is desired as its an excuse to practice.

Also, work is pretty tight on web traffic, I will be rolling the dice (but expect it to be fine) if lets encrypt certs are not filtered.

zerotier looks amazing.

I almost want the excuse to have to build out a VM, setup lets encrypt, leverage Google 2FA, leverage my domain name, and find a way to route IE from work traffic through this VM and to the Reolink NVR UI. But I’m likely to fail on so many levels. Zerotier looks like a silver bullet unless my work’s security effectively blocks it.

I wouldn’t hold my breath for your admin letting your machine go onto arbitrary VPNs and bypassing whatever network security infrastructure you have at work.

If you can access your home assistant instance on 8123 from work, you can definitely port forward another port or two - 80 and 443, for your http/https “frontend”. You can then reuse that frontend for more than one thing at your home simply by using multiple domain names or subdomains for different services as you wish (steer to different backends based on domain name).

As you have a 24/7 hypervisor at home already, I’d consider spinning up Alpine Linux and nginx on it (alpine is very very lightweight making it easy to maintain and thus well suited for the role).

2 Likes

This is exciting, it’s going to be a learning experience.

It all depends on how the corporate network works. If everything is blocked and goes through some central authorization point, you won’t do much. Are you able to simply use TCP on ports 80 and 8080 without any additional authorization?

If you have normal unrestricted output then you can work … The easiest way would be to simply set up ssh sessions.

If you can easily exit with TCP traffic on port 80, let’s do it.

At home on your firewall, add the allow rule for IP / IP’s from work and port 80.
At home on your firewall, add port forwarding 80 to 22.
In your home firewall, add a rule to block all IPs on port 80
On the server at home, run some OS in VM.
At home on VM, run sshd and add an account. Optionally, you can even add 2fa.
Ensure that the VM has traffic to the cameras and the firewall.

On a laptop, start IE and set the proxy server as 127.0.0.1 on port 8090 (only socks nothing else!)
Run putty and set your host / server (your home public ip) with port 80 and Tunnel as D8090.
Set ssh sessions / log in.
Go to IE and enter your home local camera IP and port. (Make sure the proxy does not bypass for local addressing!)

It should work … All the traffic that generates IE is intercepted by the ssh tunnel and goes to your VM from which it directly goes to your lan from local addressing touches the cameras.

1 Like

I did a test run of just the following:

  • my pfsense, ssh enabled, firewall rule (WAN) set to allow my work’s IP to ssh into any WAN side address
  • Tried to putty into my pfsense from work

Received: Error, network error: Software caused connection abort.

Opened firewall up to any source, Set phone to hotspot, logged into that hotspot with personal laptop, putty, was able to ssh into my pfsense box. Deleted that firewall rule.

I’m assuming my work is filtering out-bound 22. If I setup the tunnel to go over 80 I’m fairly sure without SSL it will still be blocked/dropped.

I have been working on a nginx+letsencrypt container on another project that might help in this department. By “working” I mean its a fantastic container at github.com/linuxserver/docker-letsencrypt, but I’m noob, opposite of 1337 so its been a learning experience installing and setting it up vs. other people would have it done in a few minutes.

I’ve gotten as far as being able to get to the nginx default page from work, so:

  • domain A record is good
  • domain DNS entry for subdomain is good
  • Not stuck at http, SSL is not self-singed so work filters let it through

Just test on 80 or 443 does not make sense to speculate. I am not sure if it will be blocked at 80. If it blocks 80 or 443 then it is not a simple firewall but a thorough packet analysis. In other words, your admin is doing the job …

You are slowly starting to hunt a mosquito with an atomic warhead. :slight_smile:
Another method is the docker + headless web browser which you display to the world / work and then, like a regular https connection, you shoot at it. The problem is that there is probably no IE for docker. :wink: But FF is probably still available.

In this case, the scenario is quite simple … A simple https connection from work to a web server at home that serves the headless browser via webgui and with it you can watch cameras. But IE …:slight_smile:

https://hub.docker.com/r/jlesage/firefox

Another option is to run VM in the home network, start the browser, set the cameras and let the video display. Then on this OS with the help of OBS or something similar catch the image and start saving it to a file or stream to even youtube if you do not worry about privacy just set a private link. :wink:
Or make your own video player that will be fed through your web server and OBS will send stream to it.

Makes sense, will work this hopefully soon.

The company is big, they pay good money to have things like (redacted) brand firewalls with layer7 filtering.

Oh, so you know me? haha

I tried that earlier on a box at home wanting to unrestrict myself from IE, no go. I even tried two separate IP camera plugins- no go (which surprised me, Reolinks support the fairly universal RTSP). Maybe its my fault, the documentation to get the plugins working were zero.

I’m going to keep going at this as its not a critical ‘needs to be done now’ and I’m learning a lot- especially via this thread.

Again thanks to everyone in the thread contributing!!

I know this fairy tale about the corporate network too well. :wink:
If you can’t do it and admin won’t help, you have to come to terms with it. There is no point in doing anything by force, because you can still create problems for yourself at work. :wink:

If they care so much about safety and analyze high layers then you won’t do much. But I’m still encouraging you to do the ssh test on port 80. If you can’t connect, we’ll have to come up with something more corporate-friendly. :wink:

Do you have normal access to websites from work? Youtube and similar work? Is access to your own server at home with https?
If so, then let’s think about video streaming :wink: Do you only want to watch these cameras passively or does it have to be interaction and sending commands? Passive watching will not be a problem. It may be worse if you need to send data to cameras.

I don’t know what cameras you have and what type of signal they generate / protocol. If they are not intelligent IP cameras and can be used only from the browser level, as I wrote earlier. In LAN a computer or vm that will act as a viewing center and on it the image will be captured and sent to a web server either local or remote. More or less in a way you can do it like teampgp or use vlc. By doing this, you eliminate all problems on the corporate network side, because there you will simply go to some website over https and watch the video stream. Of course, this makes sense when talking about passive watching… And the authorization and encryption will do for us the web server.

https://www.leaseweb.com/labs/2013/11/streaming-video-demand-nginx-rtmp-module/

1 Like