m1k1o / neko

A self hosted virtual browser that runs in docker and uses WebRTC.
https://neko.m1k1o.net/
Apache License 2.0
7.78k stars 572 forks source link

Reversed Proxy with Apache unable to connect externally #410

Closed Togtja closed 1 month ago

Togtja commented 3 months ago

I am trying to use the neko server behind a reverse proxy, but I am having some issues with the websocket connection. I am able to connect to the server, but it gives peer failed when I try to login. It works perfectly when I connect to the domain on the local network where the domain and the server are hosted.

Note that the domain is hosted on a different server than the neko server. Hence the private IP address in the configuration instead of localhost.

My apache2 configuration for a reverse proxy:

<IfModule mod_ssl.c>
<VirtualHost *:443>
    ServerName neko.domain.com

    ErrorLog ${APACHE_LOG_DIR}/neko_error.log
    CustomLog ${APACHE_LOG_DIR}/neko_access.log combined

    LoadModule proxy_module /usr/lib/apache2/modules/mod_proxy.so
    LoadModule proxy_http_module /usr/lib/apache2/modules/mod_proxy_http.so
    LoadModule proxy_wstunnel_module /usr/lib/apache2/modules/mod_proxy_wstunnel.so

    SSLEngine on
    SSLProxyEngine on
    SSLProxyVerify none
    SSLProxyCheckPeerCN off
    SSLProxyCheckPeerName off

    ProxyRequests Off
    ProxyPass / http://192.168.1.183:8080/
    ProxyPassReverse / http://192.168.1.183:8080/
    RewriteEngine on
    RewriteCond %{HTTP:Upgrade} websocket [NC]
    RewriteCond %{HTTP:Connection} upgrade [NC]
    RewriteRule ^/?(.*) "ws://192.168.1.183:8080/$1" [P,L]

    Include /etc/letsencrypt/options-ssl-apache.conf
    SSLCertificateFile /etc/letsencrypt/live/neko.domain.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/neko.domain.com/privkey.pem
</VirtualHost>
</IfModule>

My neko configuration:


services:
  neko:
    image: "m1k1o/neko:vlc"
    restart: "unless-stopped"
    shm_size: "2gb"
    ports:
      - "8080:8080"
      - "52000-52100:52000-52100/udp"
    environment:
      NEKO_SCREEN: 1920x1080@30
      NEKO_PASSWORD: password
      NEKO_PASSWORD_ADMIN: admin_password
      NEKO_EPR: 52000-52100
      NEKO_ICELITE: 1
      NEKO_NAT1TO1: 192.168.1.183

    labels:
      - "traefik.enable=true"
      - "traefik.http.services.neko-frontend.loadbalancer.server.port=8080"
      - "traefik.http.routers.neko.rule=Host(`neko.domain.com`)"
      - "traefik.http.routers.neko.entrypoints=web-secure"
      - "traefik.http.routers.neko.tls.certresolver=letsencrypt"

When an external ip connect the docker output WRN or higher I see is:

neko-1  | 8:45AM WRN negotiation is needed module=webrtc
neko-1  | 8:45AM ERR creating offer failed error="InvalidModificationError: invalid proposed signaling state transition: have-local-offer->SetLocal(offer)->have-local-offer" module=webrtc
neko-1  | 8:45AM WRN read message error error="websocket: close 1005 (no status)" module=websocket
neko-1  | 8:45AM WRN Failed to discover mDNS candidate c5bdabf4-7e3d-4b0f-af83-47c6b9c0edae.local: mDNS: connection is closed module=webrtc submodule=pion subsystem=ice
neko-1  | 8:45AM WRN Failed to start manager: connecting canceled by caller module=webrtc submodule=pion subsystem=pc
neko-1  | 8:45AM WRN Failed to start SCTP: DTLS not established module=webrtc submodule=pion subsystem=pc
neko-1  | 8:45AM WRN undeclaredMediaProcessor failed to open SrtcpSession: the DTLS transport has not started yet module=webrtc submodule=pion subsystem=pc
neko-1  | 8:45AM WRN undeclaredMediaProcessor failed to open SrtpSession: the DTLS transport has not started yet module=webrtc submodule=pion subsystem=pc

In the firefox browser trying to connect I get a peer failed error

Any clue as to what might be wrong, or if anything in my configurations is off?

m1k1o commented 3 months ago

It says your client to connect to your local ip address and if they cannot reach it (from outside) then they cannot connect.

Currently only one Ip can be used, its a limitation. So if you expect to connect from outside use public ip in nat1to1 and ensure nat hairpinning works to have local access as well.

Togtja commented 3 months ago

Thank you for your quick respone m1k1o! I appropriate it a lot!

I changed NEKO_NAT1TO1 to my public IP, then I could not access is on host, LAN nor external. I checked that my router supports NAT loopback/hairpinning, and it did, if the forum posts are to be trusted. I then decided to portforward the UDP port 52000-52100, then it finally worked everywhere (Host, LAN, external). I also tried with the mux configuration (also had to Port Forward the mux port), and that too worked. (Separate question, but is there a performance difference between mux and epr?)

But I'm not certain why I have to port forward these ports when using the revere proxy. And for host localhost:8080 and LAN connections (<private_ip>:8080) I should not need to port forward at all, so I assume it has to do with #47? Which is the one IP connection limitation right.

Just as a slight side-note and clarification, though I assume it's the NAT loopback on my router that does this. I am able to connect using <private_ip>:8080 from other devices on the network, despite setting NEKO_NAT1TO1 to my public IP. However, if NEKO_NAT1TO1 is my public IP address then I also have to portforward, otherwise I get the peer failed error

m1k1o commented 3 months ago

is there a performance difference between mux and epr?

Probably there is some difference, but absolutely minimal. If using EPR the multiplexing is happening on the network level (separate UDP ports) and if using MUX the multiplexing is happening in the neko.

But I'm not certain why I have to port forward these ports when using the revere proxy. And for host localhost:8080 and LAN connections (:8080) I should not need to port forward at all, so I assume it has to do with https://github.com/m1k1o/neko/issues/47? Which is the one IP connection limitation right.

Exactly, even the LAN hosts get the Public IP and try to connect there. The value of NEKO_NAT1TO1 is not used by backend, but by the client. And they need to be able to reach that IP/ports.

Just as a slight side-note and clarification, though I assume it's the NAT loopback on my router that does this. I am able to connect using <private_ip>:8080 from other devices on the network, despite setting NEKO_NAT1TO1 to my public IP. However, ifNEKO_NAT1TO1 is my public IP address then I also have to portforward, otherwise I get the peer failed error

The ports needs to be forwarded to outside even for LAN clients because they are connecting to the NEKO_NAT1TO1 what is the public IP.