Captive portals - how to trigger them manually

Recently i fought again with login in captive portals in some hotels. It is a known problem that the automatic detection is somewhat buggy, at least on xfce. So i had to find a manual way to trigger the portal (there is an elemental package in the repos - did not work for me). For this, there are 2 approaches:

  1. Trigger the portal as designed through dns request. The problem with this is, it requires a http website, and in 2026 i realized there are virtually none of those anymore. So i made a nice collection (now is the moment to hit Save as… for this topic to have it for offline usage when you need it being behind a portal :wink:):

Some of them might work, some might not, try your luck, just paste one of those in your browser when you are behind a captive portal.

  1. The second approach is to actively scan the network for the portal, which might not be your network gateway. In this endevour i found a nice package - snortal. It is also available as an aur package.

After running it, it shows for example the following:

[teo@teo-lenovo-v15 ~]$ snortal
Captive portal URLs detected:
────────────────────────────────────────────────────────────
  70  http://ping.manjaro.org/check_network_status.txt  [nm-connectivity-conf]
  60  http://spot.cwifi.de/status                    [gateway-probe: 172.31.0.1]
────────────────────────────────────────────────────────────

For some unknown reason it always shows the manjaro ping, even when not behind a portal, but if there is indeed one, it is shown on the second line. Ctrl click the link and voila. This approach is also very useful if you have a timed ticket and have to check the remaining time, or if you have a ticket for a single device and want to deactivate one to use another. In such case you will need the main page of the portal even if you are activated and currently having internet, and the urls above do not work in this scenario.

4 Likes

Reading the github page it does this because it is reading the configured NM listed check, which for us is http://ping.manjaro.org/check

Mod edit: fixed a typo in the URL

1 Like

I have been using Firefox and it auto detects a captive portal, easy breezy.

I will test it next time since i am using chromium (which also has autodetection as well as the network manager itself, but sometimes they fail).
According to some reddit posts for firefox there might be one more trick - typing a nonexistent address, like 5-6 random letters and hitting enter. Have not tested yet.

I don’t know the setup behind the ping.manjaro.org service.

What I do know is that the reason why the connectivity check must be http is that https is used for captive portals.

What I also know is that a former team member worked very hard to implement hidden telemetry using various innocent services and I have internally called the member out on it.

One of the attempts involved using the Network Manager’s connectivity check.

I am thinking that your issues with the captive portals is due to the default Manjaro Linux connectivity check using ping.manjaro.org but not returning the required response.

       response
           If set, controls what body content NetworkManager checks for
           when requesting the URI for connectivity checking. Note that
           this only compares that the HTTP response starts with the
           specified text, it does not compare the exact string. This
           behavior might change in the future, so avoid relying on it. If
           missing, the response defaults to "NetworkManager is online". If
           set to empty, the HTTP server is expected to answer with status
           code 204 or send no data.

– NetworkManager.conf(5) β€” Arch manual pages

My investigation lead me to setup my own ping check using the Arch Linux recipe

Please, only use this service as a testing option - do not rely on it - as it may disappear without warning.

 $ cat /etc/NetworkManager/conf.d/20-connectivity.conf 
[connectivity]
uri=http://ping.nix.dk/nm-check.txt

My version of the service in running on nginx using this configuration

server {
    # We don't redirect to HTTPS because a redirect is considered a captive portal.
    listen       80;
    listen       443 ssl;
    server_name  ping.nix.dk;
    http2 on;

    default_type text/plain;

    location = / {
        return 200 'This domain is used for connectivity checking (captive portal detection).\n';
    }

    # https://man.archlinux.org/man/NetworkManager.conf.5#CONNECTIVITY_SECTION
    location = /nm-check.txt {
        access_log off;
        add_header Cache-Control "max-age=0, must-revalidate";
        return 200 'NetworkManager is online\n';
    }

    location = /check_network_status.txt {
        access_log off;
        add_header Cache-Control "max-age=0, must-revalidate";
        return 200 'NetworkManager is online\n';
    }

    location / {
        access_log off;
        return 404;
    }

    ssl_certificate /etc/letsencrypt/live/ping.nix.dk/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/ping.nix.dk/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}
1 Like