Problem with mobile web client showing - “The connection to the server was lost.”

Infos:

  • Used Zammad version: 6.3.1
  • Used Zammad installation type: (source, package, docker-compose, …): docker
  • Operating system: Ubuntu 24.04
  • Browser + version: Safari on iPhone

Expected behavior:

  • Access the mobile version of Zammad without giving “server connection lost error”

Actual behavior:

  • It shows a lost connection to server error when I use the mobile version on iPhone for a few seconds.

Steps to reproduce the behavior:

  • Accessing on the mobile version

I have read most of the other threads talking about this issue, however, I have not been able to solve this issue. It has something to do with the proxies, but I am unsure how to fix it.

The logs show

I, [2024-09-23T05:50:53.198826#16305-20552840]  INFO -- : Started GET "/cable" for 192.168.91.232 at 2024-09-23 05:50:53 +0000
I, [2024-09-23T05:50:53.205637#16305-20552840]  INFO -- : Started GET "/cable"[non-WebSocket] for 192.168.91.232 at 2024-09-23 05:50:53 +0000
E, [2024-09-23T05:50:53.205834#16305-20552840] ERROR -- : Failed to upgrade to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: close, HTTP_UPGRADE: )
I, [2024-09-23T05:50:53.211433#16305-20552840]  INFO -- : Finished "/cable"[non-WebSocket] for 192.168.91.232 at 2024-09-23 05:50:53 +0000

As you can see the issue is with the “non-websocket”

The etc/nginx/sites-enabled/zammad.conf file:

upstream zammad-railsserver {
  server 127.0.0.1:3000;
}

upstream zammad-websocket {
  server 127.0.0.1:6042;
}

server {
  listen 80;
  listen [::]:80;

  server_name help.myserver.nl;

  # security - prevent information disclosure about server version
  server_tokens off;

  access_log /var/log/nginx/zammad.access.log;
  error_log /var/log/nginx/zammad.error.log;

  location /.well-known/ {
    root /var/www/html;
  }

  return 301 https://$server_name$request_uri;

}


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

  server_name help.myserver.nl;

  # security - prevent information disclosure about server version
  server_tokens off;

  ssl_certificate /etc/letsencrypt/live/help.myserver.biz/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/help.myserver.biz/privkey.pem;


  ssl_protocols TLSv1.2;

  ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';

  ssl_dhparam /etc/nginx/ssl/dhparam.pem;

  ssl_prefer_server_ciphers on;

  ssl_session_cache shared:SSL:10m;
  ssl_session_timeout 180m;

  ssl_stapling on;
  ssl_stapling_verify on;

  ssl_trusted_certificate /etc/letsencrypt/live/help.myserver.biz/fullchain.pem;

  resolver 8.8.8.8 8.8.4.4;

  add_header Strict-Transport-Security "max-age=31536000" always;

  location = /robots.txt  {
    access_log off; log_not_found off;
  }

  location = /favicon.ico {
    access_log off; log_not_found off;
  }

  root /opt/zammad/public;

  access_log /var/log/nginx/zammad.access.log;
  error_log  /var/log/nginx/zammad.error.log;

  client_max_body_size 50M;

  location ~ ^/(assets/|robots.txt|humans.txt|favicon.ico|apple-touch-icon.png) {
    expires max;
  }

  # legacy web socket server
  location /ws {
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "Upgrade";
    proxy_set_header CLIENT_IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_read_timeout 86400;
    proxy_pass http://zammad-websocket;
  }

  # action cable
  location /cable {
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "Upgrade";

    proxy_set_header CLIENT_IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_read_timeout 86400;
    proxy_pass http://zammad-railsserver;
  }

  location / {
    proxy_set_header Host $http_host;
    proxy_set_header CLIENT_IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto  $scheme;

    # change this line in an SSO setup
    proxy_set_header X-Forwarded-User "";

    proxy_read_timeout 180;
    proxy_pass http://zammad-railsserver;

    gzip on;
    gzip_types text/plain text/xml text/css image/svg+xml application/javascript application/x-javascript application/json application/xml;
    gzip_proxied any;
  }
}

/etc/nginx/nginx.conf file:

user www-data;
worker_processes auto;
pid /run/nginx.pid;
error_log /var/log/nginx/error.log;
include /etc/nginx/modules-enabled/*.conf;

events {
        worker_connections 768;
        # multi_accept on;
}

http {

        ##
        # Basic Settings
        ##

        sendfile on;
        tcp_nopush on;
        types_hash_max_size 2048;
        # server_tokens off;

        # server_names_hash_bucket_size 64;
        # server_name_in_redirect off;

        include /etc/nginx/mime.types;
        default_type application/octet-stream;

        ##
        # SSL Settings
        ##

        ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
        ssl_prefer_server_ciphers on;

        ##
        # Logging Settings
        ##

        access_log /var/log/nginx/access.log;

        ##
        # Gzip Settings
        ##

        gzip on;

        # gzip_vary on;
        # gzip_proxied any;
        # gzip_comp_level 6;
        # gzip_buffers 16 8k;
        # gzip_http_version 1.1;
        # gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

        ##
        # Virtual Host Configs
        ##

        include /etc/nginx/conf.d/*.conf;
        include /etc/nginx/sites-enabled/*;
}


#mail {
#       # See sample authentication script at:
#       # http://wiki.nginx.org/ImapAuthenticateWithApachePhpScript
#
#       # auth_http localhost/auth.php;
#       # pop3_capabilities "TOP" "USER";
#       # imap_capabilities "IMAP4rev1" "UIDPLUS";
#
#       server {
#               listen     localhost:110;
#               protocol   pop3;
#               proxy      on;
#       }
#
#       server {
#               listen     localhost:143;
#               protocol   imap;
#               proxy      on;
#       }
#}

opt/zammad/contrib/nginx/zammad.conf file:

#
# this is the nginx config for zammad
#

upstream zammad-railsserver {
    server 127.0.0.1:3000;
}

upstream zammad-websocket {
    server 127.0.0.1:6042;
}

server {
    listen 80;
    listen [::]:80;

    # replace 'localhost' with your fqdn if you want to use zammad from remote
    server_name localhost;

    # security - prevent information disclosure about server version
    server_tokens off;

    root /opt/zammad/public;

    access_log /var/log/nginx/zammad.access.log;
    error_log  /var/log/nginx/zammad.error.log;

    client_max_body_size 50M;

    location ~ ^/(assets/|robots.txt|humans.txt|favicon.ico|apple-touch-icon.png) {
        expires max;
    }

    # legacy web socket server
    location /ws {
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_set_header CLIENT_IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_read_timeout 86400;
        proxy_pass http://zammad-websocket;
    }

    # action cable
    location /cable {
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_set_header CLIENT_IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_read_timeout 86400;
        proxy_pass http://zammad-railsserver;
    }

    location / {
        proxy_set_header Host $http_host;
        proxy_set_header CLIENT_IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        # Change this line in an SSO setup
        proxy_set_header X-Forwarded-User "";

        proxy_read_timeout 300;
        proxy_pass http://zammad-railsserver;

        gzip on;
        gzip_types text/plain text/xml text/css image/svg+xml application/javascript application/x-javascript application/json application/xml;
        gzip_proxied any;
    }
}

I’ve just seen that my nginx version is 1.24 but on the Zammad documentation the reverse proxies require 1.3+. So this may cause the issue, but since we got this package from Zammad itself it seems strange.

The proxy configuration itself looks okay. However, maybe the fqdn configuration is not. Zammad supports one subdomain / domain only and it has to reflect your nginx’s configuration or that what your user uses.

(See: Base — Zammad Admin Documentation documentation )

Also ensure that you’re not using application aware firewalls that eats your websocket connections.

I have the same problem, did you find a fix?