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

traefik reverse proxy, ssl and real time html - cannot connect to websocket #2369

Closed
dajuno opened this issue Aug 25, 2022 · 6 comments
Closed

Comments

@dajuno
Copy link

dajuno commented Aug 25, 2022

Hi,
I've spent some time trying to set up goaccess for a project. While real time html reports worked on localhost, I cannot get it to run on the server with SSL: Firefox can’t establish a connection to the server at wss://stats.example.com:7890/.

The setup is a docker-compose environment containing traefik as reverse proxy (providing tls certificates), a goaccess docker container and a nginx webserver serving the report. I am unsure how the websocket connection should be routed with the reverse proxy... if at all. maybe this is more a traefik question than a goaccess websocket question. (I'm quite new to the field so please indulge my lack of knowledge.)

excerpt of docker-compose.yml:

services:
  apache:
     [...]

  reverse-proxy:
    restart: always
    image: traefik:v2.8
    ports:
      - 443:443 # HTTPS port
      - 80:80 # HTTP port
      - 7890:7890 # goaccess websocket
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock # So that Traefik can listen to the Docker events
      - ./traefik/traefik.yml:/etc/traefik/traefik.yml:ro
      - traefik-letsencrypt:/letsencrypt # Persistent file for ACME Setup (Certificate Store)
      - traefik-log:/data/log # Persistent file for logging
    networks:
      - default
    labels:
      - traefik.http.routers.dashboard.rule=Host(`traefik.example.com`)
      - traefik.http.routers.dashboard.entrypoints=websecure
      - traefik.http.routers.dashboard.tls.certResolver=le
      - traefik.http.routers.dashboard.service=api@internal
      
  goaccess:
    image: allinurl/goaccess
    container_name: goaccess
    depends_on:
      - traefik-certs-dumper
    restart: always
    command:
      - '--log-file=/srv/log/access.log'
      - '--output=/srv/reports/index.html'
      - '--log-format=COMBINED'
      - '--real-time-html'
      - '--anonymize-ip'
      # - '--config-file=/etc/goaccess.conf'
      - '--geoip-database=/srv/geoip/GeoLite2-City.mmdb'
      - '--db-path=/srv/data'
      - '--ssl-cert=/letsencrypt/certs/certs/stats.example.com.crt'
      - '--ssl-key=/letsencrypt/certs/private/stats.example.com.key'
      # - '--restore'
      # - '--persist'
    expose:
      - 7890
    # ports:
    #   - 7890:7890
    networks:
      default:
        aliases:
         - goaccess.svc
    volumes:
      - apache_logs:/srv/log:ro
      - apache_reports:/srv/reports
      - goaccess_db:/srv/data
      # - ./goaccess/goaccess.conf:/etc/goaccess.conf
      - ./goaccess/GeoLite2-City.mmdb:/srv/geoip/GeoLite2-City.mmdb
      - traefik-letsencrypt:/letsencrypt:ro
    labels:
      - traefik.http.routers.goaccess.rule=Host(`stats.example.com`) # && PathPrefix(`/ws`)
      - traefik.http.routers.goaccess.entrypoints=wss
      - traefik.http.routers.goaccess.tls.certResolver=le
      - traefik.http.routers.goaccess.middlewares=sslheader
      - traefik.http.middlewares.sslheader.headers.customRequestHeaders.X-Forwarded-Proto=https
      - traefik.http.services.goaccess-portal-compose.loadbalancer.server.port=7890

  nginx:
    image: nginx
    container_name: nginx-goaccess
    depends_on:
      - goaccess
    volumes:
      - apache_reports:/usr/share/nginx/html
    labels:
      - traefik.http.routers.nginx.rule=Host(`stats.example.com`)
      - traefik.http.routers.nginx.entrypoints=websecure
      - traefik.http.routers.nginx.tls.certResolver=le

  # just a tool to convert traefik's acme.json to .crt and .key files for goaccess --ssl-crt and --ssl-key
  traefik-certs-dumper:
    image: ldez/traefik-certs-dumper:v2.8.1
    entrypoint: sh -c 'apk add jq ; while ! [ -e /data/acme.json ] || ! [ `jq ".[] | .Certificates | length" /data/acme.json` != 0 ]; do sleep 1 ; done && traefik-certs-dumper file --version v2 --watch --source /data/acme.json --dest /data/certs'
    volumes:
      - traefik-letsencrypt:/data

In addition, traefik is configured for entrypoints websecure (443), web (80, redirected to websecure) and "wss" (entrypoints.wss.address=7890). The config is a mix of bits and pieces I found online, probably messy and confusing.

The generated report is served at stats.example.com (obviously I replaced my domain by example.com everywhere), but only static. and real-time updates are not working.
The firefox console reports:
Firefox can’t establish a connection to the server at wss://stats.example.com:7890/.

Request Headers:

GET / undefined
Host: stats.example.com:7890
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Firefox/91.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Sec-WebSocket-Version: 13
Origin: https://stats.example.com
Sec-WebSocket-Extensions: permessage-deflate
Sec-WebSocket-Key: VXLNqRn6fy+s7+8feykgLQ==
Connection: keep-alive, Upgrade
Sec-Fetch-Dest: websocket
Sec-Fetch-Mode: websocket
Sec-Fetch-Site: same-site
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket

Stack trace:

setWebSocket
https://stats.example.com/:1:2654
initialize
https://stats.example.com/:1:1646
window.onload
https://stats.example.com/:1:42633
(Async: EventHandlerNonNull) <anonymous>
https://stats.example.com/:1:42595
<anonymous>
https://stats.example.com/:1:42839

Also, the connection attempt is marked as insecure.

I would much appreciate any help you can offer!

@allinurl
Copy link
Owner

Unfortunately I'm not familiar with traefik, but there have been some questions related to this, let me know if any of these help:

#2023 (comment)
#2333 (comment)
#969 (comment)

@dajuno
Copy link
Author

dajuno commented Aug 29, 2022

Thanks, also for this great tool. I've seen the links but couldn't manage to get it working. For now I opted for static reports via cronjobs, which does the job for me. Thanks!

@allinurl
Copy link
Owner

allinurl commented Sep 1, 2022

Just out of curiosity and something you could try, I know that in some proxies the following configuration has worked:

If GoAccess is running behind a proxy, you could set the client side
to connect to a different port by specifying the host followed by a
colon and the port. e.g.,

--ws-url=wss://stats.example.com:7891 --port=7890

Also, I'd try without TLS first and see if you get it to work that way.

@allinurl
Copy link
Owner

Any updates on this? Thanks

@dajuno
Copy link
Author

dajuno commented Oct 7, 2022

Hey, sorry! I haven't pursued this further, sticked with the static version and moved on to other projects. Sorry and thanks for your time!

@allinurl
Copy link
Owner

allinurl commented Oct 7, 2022

Closing this. Feel free to reopen it if needed.

@allinurl allinurl closed this as completed Oct 7, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants