Easily generate 204 no content return code?

Amazon devices routinely ping http://tabletcaptiveportal.com/generate_204, http://firetvcaptiveportal.com/generate_204 and http://fireoscaptiveportal.com/generate_204 to check if the device is on public WiFi with a capture portal login page, or something of that nature.

With AdGuard I can easily just block this request or redirect it to whatever, but I was curious to know if there was any easy way to "locally generate" on the router a 204 code to return to that request. It doesn't seem that I would need a full-blown server to send such a simple aknowledgment, and I was wondering if anybody had ever toyed with this idea on their router.

Thanks!

I think best is play around with nginx here.

Since that gl firmware uses this by default....

I have had a quick glimpse and I think this can be accomplished...

go to /etc/nginx/conf.d and make a new conf file.

then as basic config put this and modify to your heart content:

server {
    listen 80;
    listen [::]:80;
    listen 443 ssl;
    listen [::]:443 ssl;
    server_name example.com, www.example.com;
    return 204;
}

I did not tested this so be carefull with this, my suspicion by fastly skimming the documentation.

You may can get away with something like...

server {
    listen 80;
    listen [::]:80;
    listen 443 ssl;
    listen [::]:443 ssl;
    server_name example.com, www.example.com;
    
    location /generate204 {
        return 204;
    }
}

But therefor I don't know if the location section is limitated or just works like a typical anonymous block as a adder to current code, that is just a wild assumption without checking the docs, you need to test this :face_savoring_food:

make sure that the dns points to the router and if that is still not enough you could point the dns domain to your router as forwarder.

Note that the server_name is really important, if you remove this line you may break the entire ui, you want it specific having it rule to a specific domain.

Thanks a lot for suggesting to use the nginx server, that's a great idea.

Ok, so I have the following:

cat /etc/nginx/conf.d/gl.conf 

contains

include /etc/nginx/gl-conf.d/*.conf;

so indeed I can have something like

cat /etc/nginx/gl-conf.d/test_204.conf 

giving

server {
    listen 80;
    listen [::]:80;
    listen 443 ssl;
    listen [::]:443 ssl;
    server_name example.com;
    
    location /generate_204 {
        return 204;
    }
}

but when I restart the server using

/etc/init.d/nginx restart

the whole UI becomes unaccessible. I undid those changes through SSH.

Once I make it work, I'll have to figure out 1. how to test that it works properly, 2. which rewrite rule I should implement in AdGuard. I'll investigate and report if I can find an answer.

Ok, so first element, the server directive is not correct:

nginx -t
nginx: [emerg] "server" directive is not allowed here in /etc/nginx/gl-conf.d/test_204.conf:1

Can you please do this in /etc/nginx/conf.d/ ?

It has more debug information and here server entry works.

Heres what I have tested so far:

server {
    listen 80;
    listen [::]:80;
    listen 443 ssl;
    listen [::]:443 ssl;
    ssl_certificate /etc/nginx/nginx.cer;
    ssl_certificate_key /etc/nginx/nginx.key;
    server_name example.com, www.example.com;
    root /var/www/examplesite;
    location / {
       try_files $uri $uri/ =204;
    }
    return 204;
}

The error was that I missed the ssl keys.

Second error was the bucket size, for this you need to edit nginx.conf and under http add this:

server_names_hash_bucket_size 64;

It seems you need to increase with the power by 2 if you gonna use more domains, in this case we went from 32 to 64.

But this then gave me a wildcard for all domains and not only the server name as directive I had to investigate this in nginx.conf.

So this let me assume you may have to add your own includes and bring back sites-available and sites-enabled because conf.d is already part by the http instance defined with gl things in nginx.conf that is where conf.d is included and that is probably why it does ignore the server_name as virtual host.

Hope this helps a bunch, I have had not the time to further expand this.

Ok, so apparently all I need is

  1. create a /etc/nginx/gl-conf.d/test_204.conf file containing

    location /generate_204 {
            return 204;
        }
    
  2. Restart the server using /etc/init.d/nginx restart

  3. Make sure the config file is valid using nginx -t

  4. Create the following rewrite rules from AdGuard (http://192.168.8.1:3000/#dns_rewrites):

I'll test some more but it seems to be working as intended.

1 Like

Hi! Thanks a lot for all the additional investigation -- what I have currently seems to be working, but I'll make sure to get back and have a look if I ever want to improve or refine further. Thanks again!

The rewrite rules are actually:

fireoscaptiveportal.com => 192.168.8.1
tabletcaptiveportal.com => 192.168.8.1
firetvcaptiveportal.com => 192.168.8.1

with 192.168.8.1 being the address of the router of course. This way, the /generate_204 requests get served locally ,it seems to be working flawlessly.

1 Like