Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to use behind proxy. #2

Open
therealeldaria opened this issue Feb 25, 2019 · 21 comments
Open

Unable to use behind proxy. #2

therealeldaria opened this issue Feb 25, 2019 · 21 comments

Comments

@therealeldaria
Copy link

I'm using the Docker-compose but modified so that the ports are not exposed, I did not want to expose the ports on the network unencrypted, so I set up a nginx proxy with letsencrypt.
On the proxy I send traffic from port 443 to http://dockername:4326
I can get to the admin page with no issues but it does not seem to want to connect to the socket.
I have a suspicion that the actual webbrowser attempts to connect instead of internal in the docker container. Is there a way to configure it to connect internally or do I need to expose the port outside the continer?

@itzg
Copy link
Owner

itzg commented Feb 25, 2019

When you add a new server in "Server Management" can you make sure in "Server Host" you are giving the docker-compose service name of the minecraft-server container? With my example compose file, the hostname minecraft is coming from here.

@therealeldaria
Copy link
Author

Problem is that I can't get to the Server Management Page, it just keeps loading, showing three dots, pulsating. I can see the menu by clicking the 3 lines at the left, and I see the sub-menus, Dashboard, Server Management, Widgets, etc. But none of them loads, except those that link here, and to paypal.

@itzg
Copy link
Owner

itzg commented Feb 26, 2019

Gotcha. I’ll try recreating that proxy setup too and see if I can debug it.

@therealeldaria
Copy link
Author

Docker-compose.yml:

  rcon:
     container_name: rcon
     image: itzg/rcon
     volumes:
       - "rcon:/opt/rcon-web-admin/db"
   nginx_proxy:
     container_name: nginx_proxy
     image: nginx
     ports:
       - "80:80"
       - "443:443"
     volumes:
       - "/home/user/mc/docker-nginx/html:/usr/share/nginx/html"
       - "/etc/letsencrypt:/etc/letsencrypt:ro"
       - "/home/user/mc/docker-nginx/default.conf:/etc/nginx/conf.d/default.conf"
 
 
 volumes:
   rcon

nginx configuration (default.conf)

server {
    listen 80;
    return 301 https://$host$request_uri;
}

upstream rcon {
    server rcon:4326;
    keepalive 32;
}

server {
    listen 443 ssl http2 default_server;
    server_name  minecraft.myserver.net;

    root /usr/share/www;
    index  index.html index.htm;

    client_max_body_size 0;

    ssl_certificate /etc/letsencrypt/live/minecraft.myserver.net/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/minecraft.myserver.net/privkey.pem;
    ssl_protocols TLSv1.1 TLSv1.2;
    ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";
    add_header Strict-Transport-Security "max-age=31536000; includeSubdomains";
    ssl_prefer_server_ciphers on;

    location / {
      proxy_pass http://rcon/;
      proxy_http_version 1.1;
      proxy_set_header Connection "upgrade";
      proxy_set_header Upgrade $http_upgrade;
    }
}

@emmett421
Copy link

Did you ever figure this out? I'm having the same exact issue except I'm using traefik as my proxy.

@itzg
Copy link
Owner

itzg commented Jun 25, 2019

I think I accidentally ran into the same kind of issue when I forgot to expose the websocket port. That led me to find this issue and solution description in the upstream:

https://github.com/brainfoolong/rcon-web-admin/issues/9

@zeigerpuppy
Copy link

did anyone solve this for the use of nginx?

@quodos
Copy link

quodos commented May 15, 2020

Unfortunately the link to the solution is down as the maintainer of the original rcon-web-admin repo changed.

I figure you have to set the RWA_WEBSOCKET_URL or RWA_WEBSOCKET_URL_SSL variable to a path and then proxy it to the port via nginx. Unfortunately setting RWA_WEBSOCKET_URL_SSL as environment variable seems to have no effect as the tool still tries to access the websocket via ws://...:4327.

@itzg
Copy link
Owner

itzg commented May 16, 2020

Thanks for pointing that out @quodos . Apparently I missed a couple of links that need to point at the new location.

itzg added a commit that referenced this issue May 16, 2020
@itzg
Copy link
Owner

itzg commented May 16, 2020

@quodos , I got the links fixed. As for the core issue you will need to contact the maintainers over there, but they are quite responsive now.

@fraserkyle
Copy link

fraserkyle commented Sep 5, 2020

I have resolve this by creating separate nginx configs. 1 for the WebUI and the other for WebSockets.

In my docker compose:
RWA_WEBSOCKET_URL_SSL: "wss://ws.{my rcon url}" RWA_WEBSOCKET_URL: "ws://ws.{my rcon url}"

/etc/nginx/conf.d/{my rcon url}.conf
`
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}

server {
server_name {my rcon url};

location / {
  proxy_set_header        Host $host;
  proxy_set_header        X-Real-IP $remote_addr;
  proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header        X-Forwarded-Proto $scheme;

  proxy_http_version 1.1;
  proxy_set_header Upgrade $http_upgrade;
  proxy_set_header Connection $connection_upgrade;
  proxy_set_header Host $host; 

  proxy_read_timeout  90;

  proxy_pass http://{my INTERNAL rcon url}:4326;
}

}
`

/etc/nginx/conf.d/ws.{my rcon url}.conf
`
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}

server {
server_name ws.{my rcon url};

location / {
  proxy_set_header        Host $host;
  proxy_set_header        X-Real-IP $remote_addr;
  proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header        X-Forwarded-Proto $scheme;

  proxy_http_version 1.1;
  proxy_set_header Upgrade $http_upgrade;
  proxy_set_header Connection $connection_upgrade;
  proxy_set_header Host $host; 

  proxy_read_timeout  90;

  proxy_pass http://{my INTERNAL rcon url}:4327;
}

}
`

you can then use certbot to generate your sll certificates

@jippi
Copy link

jippi commented Jan 2, 2021

I ended up with this nginx configuration to make it work

map $http_x_forwarded_proto $proxy_x_forwarded_proto {
  default $http_x_forwarded_proto;
  ''      $scheme;
}

map $http_upgrade $connection_upgrade {
  default upgrade;
  '' close;
}

server {
    listen              443 ssl http2;
    listen              [::]:443 ssl http2;

    server_name        __YOUR_HOSTNAME__;

    ssl_certificate     /etc/letsencrypt/live/__YOUR_HOSTNAME__/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/__YOUR_HOSTNAME__/privkey.pem;
    ssl_session_timeout 5m;
    ssl_protocols       TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
    ssl_ciphers         HIGH:MEDIUM:!SSLv2:!PSK:!SRP:!ADH:!AECDH;
    ssl_prefer_server_ciphers on;

    location /ws/ {
        proxy_pass http://127.0.0.1:4327/;
        gzip on;
        
        # Websocket support
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
        proxy_redirect     off;

        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto;
        proxy_set_header X-Frame-Options SAMEORIGIN;
        proxy_set_header X-Forwarded-Ssl on;
    }

    location / {
        proxy_pass http://127.0.0.1:4326;
        gzip on;

        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto;
        proxy_set_header X-Frame-Options SAMEORIGIN;
        proxy_set_header X-Forwarded-Ssl on;
    }
}

and my docker-compose (mostly from the tutorials)

services:
  minecraft:
    image: itzg/minecraft-server
    ports:
      - "25565:25565"
      - "28016:28016"
    volumes:
      - "/data/minecraft/data:/data"
    environment:
      EULA: "TRUE"
      ENABLE_RCON: "true"
      RCON_PASSWORD: "__REPLACE_THIS__"
      RCON_PORT: 28016
      # enable env variable replacement
      REPLACE_ENV_VARIABLES: "TRUE"
      # define an optional prefix for your env variables you want to replace
      ENV_VARIABLE_PREFIX: "CFG_"
      # and here are the actual variables
      CFG_DB_HOST: "http://localhost:3306"
      CFG_DB_NAME: "minecraft"
      CFG_DB_PASSWORD_FILE: "/run/secrets/db_password"
      WHITELIST: __REPLACE_THIS__
      OPS: __REPLACE_THIS__
      ANNOUNCE_PLAYER_ACHIEVEMENTS: "true"
    restart: always

  rcon:
    image: itzg/rcon
    environment:
      RWA_ENV: "true"
      RWA_USERNAME: "__REPLACE_THIS__"
      RWA_PASSWORD: "__REPLACE_THIS__"
      RWA_ADMIN: "true"
      RWA_RCON_HOST: "minecraft"
      RWA_RCON_PORT: "28016"
      RWA_WEB_RCON: "true"
      RWA_WEBSOCKET_URL_SSL: "wss://__YOUR_HOSTNAME__/ws"
      RWA_WEBSCOCKET_URL: "wss://__YOUR_HOSTNAME__/ws"
    links:
      - minecraft
    ports:
      - "4326:4326"
      - "4327:4327"
    volumes:
      - "/data/minecraft/rcon:/opt/rcon-web-admin/db"

secrets:
  db_password:
    file: ./db_password

@codestation
Copy link

codestation commented Jul 31, 2022

@elriti For traefik i used this:

  rcon:
    image: itzg/rcon
    volumes:
      - rcon_data:/opt/rcon-web-admin/db
    environment:
      RWA_ENV: "TRUE"
      RWA_USERNAME: admin
      RWA_PASSWORD: admin
      RWA_ADMIN: "TRUE"
      RWA_RCON_HOST: minecraft
      RWA_RCON_PORT: 28016
      RWA_WEBSOCKET_URL_SSL: "wss://rcon.example.com/ws"
      RWA_WEBSOCKET_URL: "ws://rcon.example.com/ws"
      # needs to match the password configured for the container, which is 'minecraft' by default
      RWA_RCON_PASSWORD: minecraft
    networks:
      - gateway
      - minecraft
    deploy:
      placement:
        constraints:
          - node.hostname == myhost
      labels:
        - traefik.enable=true
        - traefik.http.services.rcon-web.loadbalancer.server.port=4326
        - traefik.http.services.rcon-ws.loadbalancer.server.port=4327

        - traefik.http.routers.rcon-web.rule=Host(`rcon.example.com`)
        - traefik.http.routers.rcon-web.service=rcon-web
        - traefik.http.routers.rcon-web.entryPoints=https
        - traefik.http.routers.rcon-web.tls=true
        - traefik.http.routers.rcon-web.tls.certresolver=tls

        - traefik.http.routers.rcon-ws.rule=Host(`rcon.example.com`) && Path(`/ws`)
        - traefik.http.routers.rcon-ws.service=rcon-ws
        - traefik.http.routers.rcon-ws.entryPoints=https
        - traefik.http.routers.rcon-ws.tls=true
        - traefik.http.routers.rcon-ws.tls.certresolver=tls

Basically i created an alternate route so my host + /ws (exact path) goes to the port 4327 of my service. No need for an extra subdomain.

@DoTheEvo
Copy link

DoTheEvo commented Sep 1, 2022

For caddy reverse proxy

add env variables to the docker-compose.yml or to the .env file

RWA_WEBSOCKET_URL: "ws://rcon.example.com/ws"
RWA_WEBSOCKET_URL_SSL: "wss://rcon.example.com/ws"

and in Caddyfile add this,
minecraft-rcon is a pingable hostname of the docker container

rcon.example.com {
        reverse_proxy /ws minecraft-rcon:4327
        reverse_proxy minecraft-rcon:4326
}

@philipt4
Copy link

philipt4 commented Oct 9, 2022

@codestation Do you have two rcon containers running?
What is happening with the load balancing there isnt completely clear to me.

I'd appreciate any pointers here. Using Traefik wildcard ssl reverse proxy (the labels I use work with all other of my web apps) and unmodified/default minecraft server config which runs properly,

version: "3"

services:
  mc:
    image: itzg/minecraft-server:latest
    container_name: "mc"
    environment:
      EULA: TRUE
      VERSION: 1.19.2
      OVERRIDE_SERVER_PROPERTIES: TRUE
      ENABLE_RCON: TRUE
      RCON_PASSWORD: minecraft
    ports:
      - 25565:25565/tcp
    networks:
      - "proxy"
    # tty: true
    # stdin_open: true
    restart: unless-stopped
    volumes:
      - ./minecraft-data:/data

  mc-dash:
    image: itzg/rcon:latest
    container_name: "mc-dash"
    environment:
      RWA_ENV: TRUE
      RWA_WEB_RCON: TRUE
      RWA_USERNAME: admin
      RWA_PASSWORD: admin
      RWA_ADMIN: TRUE
      # is referring to the hostname of 'mc' compose service below
      RWA_RCON_HOST: minecraft
      # needs to match the password configured for the container, which is 'minecraft' by default
      RWA_RCON_PASSWORD: minecraft
      RWA_RCON_PORT: "25575"
      RWA_WEBSOCKET_URL_SSL: "wss://mc-dash.mydomain.com:4327"
    ports:
      - 4326:4326
      - 4327:4327
    restart: unless-stopped
    networks:
      - "proxy"
    volumes:
      - ./rcon_data:/opt/rcon-web-admin/db
    labels:
      traefik.enable: "true"
      traefik.http.services.mc-dash.loadbalancer.server.port: "4326"
      traefik.http.routers.mc-dash.entrypoints: "web"
      traefik.http.routers.mc-dash.rule: "Host(mc-dash.mydomain.com)"
      traefik.http.middlewares.mc-dash-https-redirect.redirectscheme.scheme: "https"
      traefik.http.routers.mc-dash.middlewares: "mc-dash-https-redirect"
      traefik.http.routers.mc-dash-secure.entrypoints: "websecure"
      traefik.http.routers.mc-dash-secure.rule: "Host(mc-dash.mydomain.com)"
      traefik.http.routers.mc-dash-secure.tls: "true"
      traefik.http.routers.mc-dash-secure.service: "mc-dash"
      traefik.docker.network: "proxy"

networks:
  proxy:
    external: true

mc-dash.mydomain.com is accessible, but is blank as seemingly the backend/ws isnt functioning. No 'mc-dash'/rcon web errors in console.

@codestation
Copy link

codestation commented Oct 12, 2022

Do you have two rcon containers running?

@philipt4 no, only one. The container uses a volume to store their data so i don't think that it can work with multiple replicas.

For your config, the rcon container expect the string TRUE instead of a boolean value, so make sure to quote the value (TRUE is different from 'TRUE' in yaml). Also the RWA_RCON_HOST value must match the service name (mc in your case). Also for some reason, if RWA_WEB_RCON is set then the rcon client won't connect (dunno why), so i had to remove it.

I grabbed your compose file and made rcon work with this config:

version: "3"

services:
  mc:
    image: itzg/minecraft-server:latest
    container_name: "mc"
    environment:
      EULA: TRUE
      VERSION: 1.19.2
      OVERRIDE_SERVER_PROPERTIES: TRUE
      ENABLE_RCON: TRUE
      RCON_PASSWORD: minecraft
    ports:
      - 25565:25565/tcp
    networks:
      - "proxy"
    # tty: true
    # stdin_open: true
    restart: unless-stopped
    volumes:
      - ./minecraft-data:/data

  mc-dash:
    image: itzg/rcon:latest
    container_name: "mc-dash"
    environment:
      RWA_ENV: 'TRUE'
      #RWA_WEB_RCON: 'TRUE'
      RWA_USERNAME: admin
      RWA_PASSWORD: admin
      RWA_ADMIN: 'TRUE'
      # is referring to the hostname of 'mc' compose service below
      RWA_RCON_HOST: mc
      # needs to match the password configured for the container, which is 'minecraft' by default
      RWA_RCON_PASSWORD: minecraft
      RWA_RCON_PORT: "25575"
      RWA_WEBSOCKET_URL_SSL: "wss://mc-dash.mydomain.com:4327"
    ports:
      - 4326:4326
      - 4327:4327
    restart: unless-stopped
    networks:
      - "proxy"
    volumes:
      - ./rcon_data:/opt/rcon-web-admin/db

networks:
  proxy:
    external: true

Didn't check your traefik config, just connected to http://localhost:4326/

@philipt4
Copy link

philipt4 commented Oct 17, 2022

@codestation I appreciate the response!
Your above compose file worked well for running on my localhost.
To allow the same config to go hand in hand with traefik, I had to add the additional fields:

For environment, I modified RWA_WEBSOCKET_URL_SSL and added RWA_WEBSOCKET_URL:

    environment:
      RWA_WEBSOCKET_URL_SSL: "wss://mc-dash.mydomain.com/ws"
      RWA_WEBSOCKET_URL: "ws://mc-dash.mydomain.com/ws"

For labels, I added:

    labels:
      traefik.enable: "true"
      traefik.http.services.mc-dash-web.loadbalancer.server.port: "4326"
      traefik.http.services.mc-dash-ws.loadbalancer.server.port: "4327"
      traefik.http.middlewares.mc-dash-https-redirect.redirectscheme.scheme: "https"

      traefik.http.routers.mc-dash-web.rule: "Host(`mc-dash.mydomain.com`)"
      traefik.http.routers.mc-dash-web.service: "mc-dash-web"
      traefik.http.routers.mc-dash-web.entrypoints: "websecure"
      traefik.http.routers.mc-dash-web.tls: "true"

      traefik.http.routers.mc-dash-ws.rule: "Host(`mc-dash.mydomain.com`) && Path(`/ws`)"
      traefik.http.routers.mc-dash-ws.service: "mc-dash-ws"
      traefik.http.routers.mc-dash-ws.entrypoints: "websecure"
      traefik.http.routers.mc-dash-ws.tls: "true"

      traefik.docker.network: "proxy"

For anyone that Is looking at this thread with the same issue, those were the only added fields added/modified on top of the config from codestation's most recent comment. Traefik + Wildcard cert on my end + docker rcon working here.
EDIT: some people use for their 'entrypoint' traefik label have it set to 'http' and 'https' (such as codestation in his first comment on this thread). I use 'web' and 'websecure'.

@toddejohnson
Copy link

It looks like merging the ports has been a PR since 2020 rcon-web-admin/rcon-web-admin#17

Is this upstream project dead upstream? No commits since 2020.

@itzg
Copy link
Owner

itzg commented May 25, 2024

Is this upstream project dead upstream? No commits since 2020.

Yes, it seems to be, which compromises my ability to maintain the image of it.

@aziran07
Copy link

aziran07 commented Jul 4, 2024

Do you have two rcon containers running?

@philipt4 no, only one. The container uses a volume to store their data so i don't think that it can work with multiple replicas.

For your config, the rcon container expect the string TRUE instead of a boolean value, so make sure to quote the value (TRUE is different from 'TRUE' in yaml). Also the RWA_RCON_HOST value must match the service name (mc in your case). Also for some reason, if RWA_WEB_RCON is set then the rcon client won't connect (dunno why), so i had to remove it.

Looking at rcon.js in the original repository (https://github.com/rcon-web-admin/rcon-web-admin/blob/4a8b04a0d4bfaf248b2c7259d2882c93794f5e7e/src/rcon.js#L123), processing when RWA_RCON_WEB is true and false is different. (This is probably to distinguish between games that support web rcon and games that do not.) This option is only applied when the image is first built, so it must be set to false when the image is first created - if you use this image for minecraft.

@coolcow
Copy link

coolcow commented Oct 16, 2024

This works fine for me (Proxy in front of the rcon container, that listens to a single port and splits the connections to the different ports depending on the connection type):


compose.yml

services:

  rcon-proxy:
    image: nginx:latest
    environment:
      - VIRTUAL_HOST=rcon.exemple.com # <=== the FQDN for the rcon access
    volumes:
      - ./rcon-proxy.conf:/etc/nginx/nginx.conf:ro
    depends_on:
      - rcon

  rcon:
    image: itzg/rcon
    environment:
      # ...
      - RWA_RCON_HOST=server # <=== same as the service name of the minecraft server
      - RWA_WEBSOCKET_URL=http://rcon.exemple.com # <=== the FQDN for the rcon access
      # ...
    depends_on:
      - server

  server:
    image: itzg/minecraft-server:latest
    # ...

networks:

  default:
    external: true
    name: main-proxy

rcon.proxy.conf (the upstream name has to match the rcon service name)


http {
    upstream http_backend {
        server rcon:4326; # <=== rcon upstream for normal http
    }

    upstream websocket_backend {
        server rcon:4327; # <=== rcon upstream for websocket
    }

    server {
        listen 80;

        location / {
            proxy_pass http://rcon:4326; # <=== rcon upstream for normal http

            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;

            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection $connection_upgrade;

            if ($http_upgrade = "websocket") {
                set $connection_upgrade 'upgrade';
                proxy_pass http://rcon:4327; # <=== rcon upstream for websocket
            }
        }
    }
}

main-proxy is the network where my jwilder/nginx-proxy container is doing its VIRTUAL_HOST reverse-proxy magic...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests