KVM behind a reverse proxy

Hi,

In order to integrate the KVM in my setup, I'd require to access the KVM web UI through a reverse proxy. Is there any recommended setup for Apache or Nginx on the proxy server?
I'd rather use a path to access the KVM using this type of url : https://my-proxy/kvm/
is there a way to do that?

You can try using FRP (Fast Reverse Proxy) for this.GitHub - fatedier/frp: A fast reverse proxy to help you expose a local server behind a NAT or firewall to the internet.

For video and audio streaming, if P2P is not available in the network, you’ll also need to set up a WebRTC TURN relay.

Here’s a demo we set up for customers using FRP + Nginx with reverse proxy:
:link: https://kvm-demo.gl-inet.cn

This is for reference only and may not fully match your specific requirements.

I don't have experience configuring nginx on servers. You might need an intranet penetration tool, as a simple reverse proxy only works when the KVM has a public IP address.

I tried using caddy on windows but could not get it to work. Only managed to get a white screen instead of any video.

could you please share your nginx & FRP config?

Here’s a reference configuration using Nginx and FRP:

Nginx (HTTPS Reverse Proxy):

server {
    listen 443 ssl;
    server_name your.domain;

    ssl_certificate xxxxxxx;
    ssl_certificate_key xxxxxxx;

    location / {
        proxy_pass https://127.0.0.1:10443;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_ssl_verify off;
        proxy_ssl_name $host;
        proxy_ssl_server_name on;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

FRP (frps.toml / frpc.toml):

# frps.toml
bindPort = 17000
vhostHTTPSPort = 10443
vhostHTTPPort = 1080
allowPorts = [{ single = 80 }, { single = 443 }, { single = 1080 }, { single = 10443 }]
maxPortsPerClient = 1

# frpc.toml
serverAddr = "you frp server IP"
serverPort = 17000

[[proxies]]
name = "kvm-demo"
type = "https"
localIP = "127.0.0.1"
localPort = 443
customDomains = ["your.domain"]

This setup is for reference only. In networks where P2P is unavailable, it may not work reliably. TURN server support is not yet available — it’s planned for v1.5 or later.

1 Like

I’ve run into something similar when trying to put a KVM web UI behind a reverse proxy. A straight HTTPS reverse proxy usually isn’t enough because the KVM uses some paths and connections that don’t always translate well.

What worked for me was combining Nginx with FRP (Fast Reverse Proxy):

In Nginx, I set up a simple HTTPS block pointing /kvm/ to the KVM’s web port.

In FRP, I forwarded the local KVM port through my server so it’s reachable even if the device is behind NAT.

Once that was in place, the interface loaded fine through my domain. You just need to make sure the paths line up (e.g., /kvm/ with the trailing slash) and that SSL is handled cleanly either at Nginx or on the KVM side.

One thing to watch out for: the video stream sometimes won’t load if the proxy isn’t passing upgrade headers or if there are absolute paths in the KVM UI. A quick tweak with Nginx headers or sub_filter usually fixes that.

If you don’t want to deal with FRP, tools like Caddy can also work, but I’ve seen people hit issues where the UI loads but the video stays blank.

Curious — does your setup fail at loading the page at all, or is it just the video/stream part that breaks?

Best Brazil Proxies

Hello, for some reasons, I’m stuck with Apache. Therefore I’m not able to go as far as you did in setting a reverse proxy for the KVM.

I have this working behind Apache via ssh:

1 Like

Thank you for your suggestion and the documentation.
Is there any reason you’re using an SSH tunnel, other than securing the communication? My Apache server and the KVM are in a trusted network, so I’d rather avoid using additional tools with no good reason for.

In my case, I need access from behind a NAT gateway. This builds a tunnel to my server and the server proxies it. It’s simple and works in almost every case.

1 Like

It also means that the device doesn't need to be exposed to the Internet, I use SSH tunnels to go between symmetric NATs all the time, I feel it's more secure than exposing a bunch of internal-only hosts directly.

2 Likes