Did the login URL handling change?

Hi.

I'm trying to figure out whether the handling for the login page has changed with an impact when using an external reverse proxy. I've had a look through the last few releases of change history but can't see anything.

Until recently I hadn't updated the pi-hole images in a while (full setup below) so they were running a release from back in May/June. They're now running the latest version (pi-hole 5.14.2, web 5.18) and I'm seeing some odd behaviour in an environment that has multiple pi-hole instances.

So, the useful information...

Setup
I'm running multiple Pi-Hole docker instances across a number of Raspberry Pis - one per pi.

These are fronted by a separate nginx container (pihole still retains it's standard web server in the container - that's untouched) that acts as the access point for a whole bunch of stuff across the pis (and dealing with https/certs where the back end service is http only). There are a number of URLs configured here:

  • dns.mydomain.com - This resolves to the first pihole instance but ultimately is just a simple access route for management and then relying on syncing across the nodes for any changes.
  • dns.mydomain.com/pihole1 - This specifically routes to the first instance
  • dns.mydomain.com/pihole2 - This specifically routes to the second instance.

The nginx config is:

        proxy_buffering off;

        location / {
                proxy_pass http://pihole1_obot/admin/;
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
        location /pihole1/ {
                proxy_pass http://pihole1_obot/admin/;
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
        location /pihole2/ {
                proxy_pass http://pihole2_obot/admin/;
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }

Previous (expected) Behaviour
Until the container update, I could go to any of the URLs above and login without any issues. So if I went to the URL for pihole2, I login there and go to the dashboard for pihole2.

Current (unexpected) Behaviour
Since the update, the URL takes me to the login page but when I login it attempts to pass me back to the base URL of dns.mydomain.com.

So if I login to pihole2, it bounces me to the dashboard for pihole1 after. Interestingly it appears to have completed the login and stashed the relevant session information with the browser because if I go back to the pihole2 URL I get the right dashboard.

Hope someone can help with this one.

Thank you!

Have you reviewed this?

Funnily enough, I was reading that one this morning - as far as I can tell though that's for API integration. It did help me fix something with homeassistant but I didn't see anything there that related to the web page or login.

From what I can tell this is more to do with how the login page works out the URL to redirect you to after a successful login than API tokens.

I started looking at the updates on github and can see quite a few changes around login setup and how the authentication is done/stored but unfortunately my PHP and JS knowledge is pretty basic so it's painful going.

So I think the short answer is yes, the behaviour for redirection after login has changed.

Looks like a change in August re-writing the login page re-did this and added code specifically looking for /admin/login.php to identify where to redirect to.

In my case (assuming my reading is right - as I mentioned, my PHP and JS is minimal at best) that check fails as it will see (for example) /pihole2/admin/login.php and it falls out through worst case code where it treats it as login failure but without the niceties of "retry your password". Not sure the code is fully controlled in that case.

Should I log an issue on github here?

You updated from an older version.

These changes happened around 6 months ago.

Previously, after a successful login, PHP redirected to index.php.
The new code only changes the destination page if you tried to access a different page, but wasn't already logged in.

Example:

  • You try to access http://pi.hole/admin/settings.php, but you're not logged in;
  • You will be redirected to the login page;
  • After a successful login, you will be finally redirected to http://pi.hole/admin/settings.php (the intended original page).

I'm not sure what is causing this behavior, but I don't think this is an issue on PHP code. Maybe there is something wrong with the forwarded address.

Thanks for the background on the changes rdwebdesign . And thank you for your time on Pi-Hole in general.

I'm not disputing the time frame for the changes and things moving on - I wanted to provide context on the environment and specifically call out that gap in case it was an easy answer like the API endpoint changes. My initial thought was something had changed and either (a) I'd missed a bit of config needed now or (b) that's just how it works now - some apps have a constraint on base URL when it comes to proxy setups, limiting to domain name while others let you configure it. As you can see from the thread title, I'm asking did something change - certainly no allegations of bugs! I can see a number of changes over the last 6 months that improve security and that's only ever a good thing.

The behaviour I'm seeing is a subtle variation of what you describe:

  • Attempt to access mydomain.com/pihole2/admin
  • Redirected to login page on pihole2 - mydomain.com/pihole2/admin/login.php
  • After successful login, redirected to mydomain.com/admin (which breaks on rendering because the target for mydomain.com doesn't recognise the session but that's to be expected and reasonable).

I wondered if it was parsing the original URL incorrectly or shortening it before storing to use after successful login - an assumption that the full URL would only ever be domain/admin for example.

I'll carry on poking around and see what I can find - I have a spare instance running that I can tinker with and make code/config changes to experiment whether that be the nginx config or the pi-hole code.

PHP redirects depending on the information received from the web server REQUEST_URI here.

This value is used on login.php to define the destination page.

You can see what is passed to the variable, adding this code to login.php, after require 'scripts/pi-hole/php/header.php';:

echo "<pre>";
var_dump($_SESSION['prev_url']);
echo "</pre>";

This will print the values on the Login page.

1 Like

Sorry, wanted to correct my last post:

  • On the browser, attempt to access mydomain.com/pihole2
  • nginx (based on the above config) redirects to pihole2_obot/admin (for 100% transparency, pihole2_obot in nginx is an upstream declaration that, as a LAN declared hostname, resolves at the router upstream of pi-hole). The browser sees this as mydomain.com/pihole2/login.php
  • After successful login, browser is redirected to mydomain.com/admin.

There's definitely something mixed up between the browser, nginx and pi-hole - technically the pi-hole re-direct to /admin is correct as it only sees pihole2_obot/admin - only it's being applied against mydomain.com to become mydomain.com/admin.

Perfect - the pi-hole equivalent of random printf/echo debug statements. I can work with that :grin:

Yeah...
If you just want to print the content as a string, you can replace the var_dump($_SESSION['prev_url']); with echo $_SESSION['prev_url'];.

var_dump() will also print the type and structure (it can be used on arrays and objects).

So, after a bit more digging on code versions and experimenting I can confirm the re-write of the login page is definitely the cause of the behaviour I'm seeing.

The old password.php behaviour always re-directed to index.php from the current position. For vanilla setups, this took you to host/admin/index.php and on my setup it took me to mydomain.com/pihole2/index.php - nginx then translating that to pihole2host/admin/index.php.

With the new behaviour, the attempt to redirect with based on the calling URL (/admin) tells the browser to head to /admin on the current site - hence the redirect to mydomain.com/admin.

Interestingly, the behaviour of this page if the session is authenticated remains the same - a redirect to index.php rather than any attempt to redirect to whatever the original URL was. Not sure if that is deliberate or not.

Given the browser has no knowledge of the redirect and pihole has no knowledge of the original URL called, I can't see a way to fix this outside of a pi-hole code change. The alternative would be re-configuring the proxy to a different domain for each pi-hole instance.

I have written a small patch to password.php that uses a new, optional, setup variable to swapout /admin from the redirect if set. This allows me to configure each instance in a proxy friendly way. Behaviour for the redirect now becomes:

  • If adminRoot is set and the redirect is heading to /admin/*, the redirect is amended based on adminRoot.
  • As an example, if adminRoot was set to /pihole2, a redirect for /admin/ becomes /pihole2/ or a redirect of /admin/dns_records.php becomes a redirect to /pihole2/dns_records.php.
  • If adminRoot is not set the redirect remains as per original behaviour.

Of course if Pi-Hole ever deviates from the entire web portal being under /admin then there's a problem!

Presumably I'd need to pick this discussion up on github under the AdminLTE project if I wanted it considered for inclusion? (Or am I likely to just get a flat no for the answer?)

This is the most common scenario. Users usually use a domain (or subdomain) for each website.

Presumably I'd need to pick this discussion up on github under the AdminLTE project if I wanted it considered for inclusion? (Or am I likely to just get a flat no for the answer?)

You can open an issue or a pull request on Github. We don't bite (unless provoked :grin:).

I can't tell if your idea will be accepted or refused, but you can try it.

Ticket 2488 raised - here's hoping it doesn't hurt! :grin:

This topic was automatically closed 21 days after the last reply. New replies are no longer allowed.