Blank page on Chromium and macOS app, Android app "cannot connect"

Summary
Hosting Mattermost (via GitLab Omnibus) on my private server works fine using multiple clients and operating systems but doesn’t work at all for some clients (Chromium, Android app, macOS App) by just showing a blank/white page or by simply stating “Cannot connect to server”.

Steps to reproduce
Ubuntu Server 22.04 with Mattermost installed via GitLab Omnibus v16.8.1.

Relevant config from gitlab.rb:

mattermost_external_url 'https://REDACTED.de:444'
mattermost['home'] = '/home/mattermost'
mattermost['gitlab_enable'] = true
mattermost['gitlab_id'] = "REDACTED"
mattermost['gitlab_secret'] = "REDACTED"
mattermost['gitlab_auth_endpoint'] = "https://REDACTED.de/gitlab/oauth/authorize"
mattermost['gitlab_token_endpoint'] = "https://REDACTED.de/gitlab/oauth/token"
mattermost['gitlab_user_api_endpoint'] = "https://REDACTED.de/gitlab/api/v4/user"
mattermost['file_directory'] = "/home/mattermost/data"
mattermost_nginx['enable'] = true
mattermost_nginx['listen_port'] = 82
mattermost_nginx['listen_https'] = false

The nginx SSL reverse proxy config for mattermost:

upstream backend {
   server 127.0.0.1:82;
   keepalive 32;
}

proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=mattermost_cache:10m max_size=3g inactive=120m use_temp_path=off;

server {
    listen 444 ssl http2;
    server_name REDACTED.de;

    http2_push_preload on; # Enable HTTP/2 Server Push

    ssl_certificate /etc/letsencrypt/live/REDACTED.de/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/REDACTED.de/privkey.pem;
    
    server_tokens off;
    ssl_protocols TLSv1.2 TLSv1.3;

    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305;

    ssl_prefer_server_ciphers on;

    ssl_session_tickets off;
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:10m;

    ssl_buffer_size 8k;

    ssl_stapling on;
    ssl_stapling_verify on;

    add_header X-Content-Type-Options nosniff;
    add_header Content-Security-Policy "object-src 'none'; base-uri 'none'; require-trusted-types-for 'script'; frame-ancestors 'self';";
    add_header Content-Security-Policy "frame-ancestors 'self';";
    add_header Strict-Transport-Security "max-age=31536000; includeSubdomains; preload";

    ssl_dhparam /etc/ssl/certs/dh4096.pem;

    location ~ /api/v[0-9]+/(users/)?websocket$ {
       proxy_set_header Upgrade $http_upgrade;
       proxy_set_header Connection "upgrade";
       client_max_body_size 50M;
       proxy_set_header Host $http_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_set_header X-Frame-Options SAMEORIGIN;
       proxy_buffers 256 16k;
       proxy_buffer_size 16k;
       client_body_timeout 60;
       send_timeout 300;
       lingering_timeout 5;
       proxy_connect_timeout 90;
       proxy_send_timeout 300;
       proxy_read_timeout 90s;
       proxy_http_version 1.1;
       proxy_pass http://backend;
    }

    location / {
       client_max_body_size 50M;
       proxy_set_header Connection "";
       proxy_set_header Host $http_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_set_header X-Frame-Options SAMEORIGIN;
       proxy_buffers 256 16k;
       proxy_buffer_size 16k;
       proxy_read_timeout 600s;
       proxy_cache mattermost_cache;
       proxy_cache_revalidate on;
       proxy_cache_min_uses 2;
       proxy_cache_use_stale timeout;
       proxy_cache_lock on;
       proxy_http_version 1.1;
       proxy_pass http://backend;
    }
}

It’s really just the recommended nginx config (Configure NGINX as a proxy for Mattermost server — Mattermost documentation) with the SSL settings from here (Secure Your Nginx Server in 2024: Achieving an A+ Rating on Qualys SSL Labs).

Expected behavior
I’d expect this to work with all clients instead of just some.

Observed behavior
I’m getting a blank screen with Chromium (macOS, Android) and the macOS app after connecting to the server (before the user login). When looking into the Chromium developer consol, I can see this structure:

Using the Android app, I cannot even connect to the server as the app will just show “Cannot connect to server”.

It works absolutely fine with Firefox 122 (macOS, Android, iOS), Safari (macOS, iOS) and the iOS app.

There were a lot of similar threads and issues but nothing did exactly fit what I’m experiencing.

Fixed most broken clients (macOS app, Chromium on macOS and Android) by disabling the CSP headers in the nginx SSL reverse proxy:

    #add_header Content-Security-Policy "object-src 'none'; base-uri 'none'; require-trusted-types-for 'script'; frame-ancestors 'self';";
    #add_header Content-Security-Policy "frame-ancestors 'self';";

However, the Android app v2.12.1 (Build 6000505) is still unable to connect to my server when entering https://REDACTED.de:444 as Server-URL. I can access Mattermost from the affected phone just fine using Firefox or Chromium. When the app tries to connect to the server, this is the only line printed to the log:

127.0.0.1 - - [01/Feb/2024:23:26:12 +0100] "GET / HTTP/1.1" 200 1253 "" "okhttp/4.12.0" 2.83

The Android app also cannot connect via http:// without encryption using port 82. I’ve tested this on two Android phones (Google Pixel 6 Pro and Pixel 6a).

Has the Android app been tested with non-standard ports? Is there any way to get more info from the app why it cannot connect?

We have fixed a bug related to this and the fix will be available for download in a day or two (Mobile v2.12.2 dot release).

2 Likes

I’ve installed the Android Mattermost Beta app v2.12.2 (Build 50603) via F-Droid (since it’s still unavailable via Google Play) but I the connection issue with the server persists.

Btw., my server is now on GitLab Omnibus v16.8.2 with Mattermost v9.3.0.

Both, Mattermost Beta v2.12.2 (Build 50603) from F-Droird and Mattermost v2.12.2 (Build 6000506) from Google Play cannot connect to my server. Did the release of the fix get delayed or should it work with that version?

Got it, the issue sounded similar to what was fixed in v2.12.2, but it sounds like it was unrelated to this.

What can I do to find out what the problem is with the Android app?

Is anyone successfully using the Mattermost Android app with a non-standard port on the Mattermost server?

What are my options for finding out why only the Android app cannot connect to the server?

The issue with the Android app not connecting to the server is a known issue: Android app can't connect if server isn't listening on IPv6 · Issue #24703 · mattermost/mattermost · GitHub

It’s also likely to happen to a lot of people since the recommended nginx configuration only supports IPv4:

server {
   listen 443 ssl http2;

Since the Android app cannot connect to IPv4 and needs IPv6, you need to enable IPv6 support in your nginx config like this:

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

That change applied to my nginx config made the Android app connect to my mattermost server!