poweradmin / poweradmin

A web-based control panel for PowerDNS
http://www.poweradmin.org
GNU General Public License v3.0
652 stars 260 forks source link

"Authentication Failed!" on a fresh installation (Poweradmin 3.8.1, MariaDB 10.5, PHP-FPM 8.3.12, nginx, Rocky 9.4) #587

Closed ChristopherW closed 1 month ago

ChristopherW commented 1 month ago

I've been attempting to deploy Poweradmin 3.8.1 tonight on a Rocky Linux 9.4 system, running nginx and PHP-FPM 8.3.12 (fpm-cfgi) with a fresh install of PowerDNS and MariaDB 10.5.

PowerDNS is running correctly daemonised, verified with systemctl status pdns.

After some initial frustrations with php-fpm (assumptions that you're installing for apache not nginx) and setting up an nginx server listener on a custom port, I embarked on the install process using the web install script. The poweradmin folder is chowned to the nginx running user and group.

I ran through the install process... In Step 3 supplying the powerdns DB account, password and DB name and a Poweradmin administrator password. In Step 4, I supplied a new username, password and other optional details In Step 5 I copy-pasted the two SQL lines verbatim into a MariaDB root console, granting the Step 4 user account the required privileges on the PowerDNS database. I created the config file accordingly in Step 6, then tidied up at the end of Step 7 before going to the main login page.

However, whatever I try, I cannot log in, it always shows a red "Authentication Failed!" banner and I'm brought back to the login page.

if I enable syslog logging in the config file, the only thing logged is "Failed authentication attempt from [my:ip:addr:ess] for user 'step4-username'."

I've duplicated the sample config.inc.php and incorporated the install-specific variables to create a complete override of the defaults, so I can test things in one place. I've tried changing from bcrypt to MD5, no change. Nothing I've tried works, and no nginx or PHP-FPM errors are logged (I have a fairly high loglevel).

This seems like a failure to launch, but I can't determine why. I've run through the web install procedure half a dozen times or so, each time with no success.

Also, why does poweradmin create and want to use an SQL account accessible from any host? I prefer SQL user accounts to be scoped to localhost and do not typically run MariaDB servers bound to anything except localhost (and firewalled accordingly).

ChristopherW commented 1 month ago

install this I put the necessary dlls in the archive

Is this a hacked account / spam / phishing attempt? This is totally irrelevant to the reported issue.

edmondas commented 1 month ago

install this I put the necessary dlls in the archive

Is this a hacked account / spam / phishing attempt? This is totally irrelevant to the reported issue.

This is not the first time that a fake Github account has offered help in the form of malware files. I have removed the related post and the link to it from the comments.

edmondas commented 1 month ago

@ChristopherW First check if these extensions are installed on your machine (phpinfo or similar): intl, gettext, openssl, filter, tokenizer, pdo and pdo-mysql (or pdo-pgsql, pdo-sqlite depending on the db type).

Second, try disabling login token validation in the inc/config.inc.php file.

$login_token_validation = false

Add these debugging lines at the top of the main index.php file

ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

The last option would be to write to me directly (you can find my email in my profile) and let's find out a way to debug it somehow by giving me some access.

ChristopherW commented 1 month ago

@ChristopherW First check if these extensions are installed on your machine (phpinfo or similar): intl, gettext, openssl, filter, tokenizer, pdo and pdo-mysql (or pdo-pgsql, pdo-sqlite depending on the db type).

Yep, all installed.

Second, try disabling login token validation in the inc/config.inc.php file.

$login_token_validation = false

No change.

Add these debugging lines at the top of the main index.php file

ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

Nothing shown when submitting the login. It seems to just fail silently :) Are there any options for more verbose logging on the poweradmin side?

The last option would be to write to me directly (you can find my email in my profile) and let's find out a way to debug it somehow by giving me some access.

Happy to give you access to this server if you want to investigate, it's a non-production server running a handful of things for personal projects and testing before deploying things 'for real' at work.

edmondas commented 1 month ago

There's no way to enable additional logging in this case. Implementing that could be a good thing to consider, but at the moment I'm busy with another rework. So I don't see any other way to debug the problem without touching any code on your machine, of course you can try to do it yourself by adding some echo statements.

One idea that just occurred to me is to enable SQL debug with $db_debug = true, but not sure how much that would help in your case.

The problem itself sounds a bit mystical, but it would be good to find the root cause.

edmondas commented 1 month ago

@ChristopherW Could you temporarily replace the existing lib/LegacyAuthenticateSession.php with the attached file, it has additional error logging to syslog, so it might help to trace your problem without me trying to access your machine.

LegacyAuthenticateSession.php.txt

glnengineer commented 1 month ago

Same issue here using Rocky/RHEL 9.

I use PostgreSQL 15/16/17 instead of MariaDB (tested both DB) with same "Authentication Failed!" issue. I also open out pg_hba for all and switch to MD5, Listen on 0.0.0.0. No difference. Applied all the above steps incl replacing "LegacyAuthenticateSession.php" with no additional error/debug message. Only thing left to see what the codes are doing is stepping thru in local VSCode.

ChristopherW commented 1 month ago

@ChristopherW Could you temporarily replace the existing lib/LegacyAuthenticateSession.php with the attached file, it has additional error logging to syslog, so it might help to trace your problem without me trying to access your machine.

LegacyAuthenticateSession.php.txt

Hi, I looked for this file in the poweradmin /lib folder but it's not present. I obtained the files via git clone https://github.com/poweradmin/poweradmin.git. The only files containing function authenticate(): void are

lib/Application/Service/LdapAuthenticator.php
lib/Application/Service/SqlAuthenticator.php
lib/Infrastructure/Service/SessionAuthenticator.php

Do I just need to add that file to the /lib directory and it will be used, or is that for a version of poweradmin different from the one I have?

edmondas commented 1 month ago

@ChristopherW Oh, that file was intended for v3.8.1, but I see you've moved to the master branch, which may not be as stable, and of course I've made some changes there, so you have separate files. I recently introduced these to decouple the functionality and have better control.

The funny thing is that I tried to install it myself on Rocky Linux 9 and it works fine, maybe I'm doing something different.

I can create custom lib/Application/Service/SqlAuthenticator.php and lib/Infrastructure/Service/SessionAuthenticator.php files for you, just give me some time

In any case, after they are replaced all trace messages should go to /var/log/php-fpm/www-error.log

edmondas commented 1 month ago

@glnengineer Have you found anything interesting by going through the code with vscode?

edmondas commented 1 month ago

@ChristopherW I updated the master branch and added additional logging. To enable this you should add this line to your inc/config.inc.php file

$logger_type = 'native';
$logger_level = 'debug';

It will log messages through the native error_log handler, which depending on your system configuration may go to /var/log/php-fpm/www-error.log, or in my case I see them in Docker logs:


2024-10-05 10:25:17 NOTICE: PHP message: 2024-10-05T07:25:17+00:00 [DEBUG]: [SessionAuthenticator] Starting authentication process
2024-10-05 10:25:17 NOTICE: PHP message: 2024-10-05T07:25:17+00:00 [DEBUG]: [SessionAuthenticator] User admin attempting to authenticate
2024-10-05 10:25:17 NOTICE: PHP message: 2024-10-05T07:25:17+00:00 [DEBUG]: [SessionAuthenticator] Password encrypted for user admin
2024-10-05 10:25:17 NOTICE: PHP message: 2024-10-05T07:25:17+00:00 [DEBUG]: [SessionAuthenticator] User login set for user admin
2024-10-05 10:25:17 NOTICE: PHP message: 2024-10-05T07:25:17+00:00 [DEBUG]: [SessionAuthenticator] User language set for user admin
2024-10-05 10:25:17 NOTICE: PHP message: 2024-10-05T07:25:17+00:00 [INFO]: [SessionAuthenticator] User admin authenticated
2024-10-05 10:25:17 NOTICE: PHP message: 2024-10-05T07:25:17+00:00 [DEBUG]: [SessionAuthenticator] Session timestamp updated for user admin
2024-10-05 10:25:17 NOTICE: PHP message: 2024-10-05T07:25:17+00:00 [INFO]: [SessionAuthenticator] User admin uses SQL for authentication
2024-10-05 10:25:17 NOTICE: PHP message: 2024-10-05T07:25:17+00:00 [INFO]: [SqlAuthenticator] Starting authentication process.
2024-10-05 10:25:18 NOTICE: PHP message: 2024-10-05T07:25:18+00:00 [INFO]: [SqlAuthenticator] Session ID regenerated for user: admin
2024-10-05 10:25:18 NOTICE: PHP message: 2024-10-05T07:25:18+00:00 [INFO]: [SqlAuthenticator] CSRF token generated for user: admin
2024-10-05 10:25:18 NOTICE: PHP message: 2024-10-05T07:25:18+00:00 [DEBUG]: [SessionAuthenticator] Starting authentication process
2024-10-05 10:25:18 NOTICE: PHP message: 2024-10-05T07:25:18+00:00 [DEBUG]: [SessionAuthenticator] Session timestamp updated for user admin
2024-10-05 10:25:18 NOTICE: PHP message: 2024-10-05T07:25:18+00:00 [INFO]: [SessionAuthenticator] User admin uses SQL for authentication
2024-10-05 10:25:18 NOTICE: PHP message: 2024-10-05T07:25:18+00:00 [INFO]: [SqlAuthenticator] Starting authentication process.
2024-10-05 10:25:18 NOTICE: PHP message: 2024-10-05T07:25:18+00:00 [INFO]: [SqlAuthenticator] Session ID regenerated for user: admin
2024-10-05 10:25:18 NOTICE: PHP message: 2024-10-05T07:25:18+00:00 [INFO]: [SqlAuthenticator] Authentication process completed successfully for user: admin
2024-10-05 10:25:18 NOTICE: PHP message: 2024-10-05T07:25:18+00:00 [DEBUG]: [SessionAuthenticator] Authentication process completed for user admin```
glnengineer commented 1 month ago

Below is last 100 lines of debug terminal output from VSCode when step thru lastest git clone ( downloaded 5 mins ago).

Error: Authentication failed!

Debug: index.php

Lines (func) appear: Line 45

try { $router->process(); } catch (Exception $e) { error_log($e->getMessage()); echo 'An error occurred while processing the request.';

Last 100 lines of debug console output:

-> stackTraceRequest { command: 'stackTrace', arguments: { threadId: 2, startFrame: 0, levels: 20 }, type: 'request', seq: 122 } xd(2) <- stack_get -i 55 xd(2) -> <?xml version="1.0" encoding="iso-8859-1"?> <- stackTraceResponse Response { seq: 0, type: 'response', request_seq: 122, command: 'stackTrace', success: true, body: { totalFrames: 1, stackFrames: [ { id: 31, name: '{main}', source: { name: 'index.php', path: '/usr/share/nginx/gln.local/dnsadmin/index.php' }, line: 46, column: 1 } ] } } -> scopesRequest { command: 'scopes', arguments: { frameId: 30 }, type: 'request', seq: 123 } xd(2) <- context_names -i 56 -d 0 xd(2) -> <?xml version="1.0" encoding="iso-8859-1"?> <- scopesResponse Response { seq: 0, type: 'response', request_seq: 123, command: 'scopes', success: true, body: { scopes: [ Scope { name: 'Locals', variablesReference: 77, expensive: false }, Scope { name: 'Superglobals', variablesReference: 78, expensive: false }, Scope { name: 'User defined constants', variablesReference: 79, expensive: false } ] } } -> variablesRequest { command: 'variables', arguments: { variablesReference: 77 }, type: 'request', seq: 124 } xd(2) <- context_get -i 57 -d 0 -c 0 xd(2) -> <?xml version="1.0" encoding="iso-8859-1"?><![CDATA[1]]><![CDATA[1]]><![CDATA[1]]><![CDATA[1]]><![CDATA[1]]><![CDATA[1]]><![CDATA[1]]><![CDATA[1]]><![CDATA[1]]><![CDATA[1]]><![CDATA[aW5kZXg=]]><![CDATA[1]]> <- variablesResponse Response { seq: 0, type: 'response', request_seq: 124, command: 'variables', success: true, body: { variables: [ { name: '$composer_autoload_files', value: 'array(10)', type: 'array', variablesReference: 80, presentationHint: {}, evaluateName: '$composer_autoload_files', indexedVariables: 10 }, { name: '$e', value: 'uninitialized', type: 'uninitialized', variablesReference: 0, presentationHint: {}, evaluateName: '$e', indexedVariables: undefined }, { name: '$err', value: 'uninitialized', type: 'uninitialized', variablesReference: 0, presentationHint: {}, evaluateName: '$err', indexedVariables: undefined }, { name: '$router', value: 'Poweradmin\Application\Routing\BasicRouter', type: 'object', variablesReference: 81, presentationHint: {}, evaluateName: '$router', indexedVariables: 3 }, { name: '$secure', value: 'true', type: 'bool', variablesReference: 0, presentationHint: {}, evaluateName: '$secure', indexedVariables: undefined } ] } } -> nextRequest { command: 'next', arguments: { threadId: 2 }, type: 'request', seq: 125 } <- nextResponse Response { seq: 0, type: 'response', request_seq: 125, command: 'next', success: true } xd(2) <- step_over -i 58 xd(2) -> <?xml version="1.0" encoding="iso-8859-1"?> xd(2) <- stop -i 59 xd(2) -> <?xml version="1.0" encoding="iso-8859-1"?> <- threadEvent ThreadEvent { seq: 0, type: 'event', event: 'thread', body: { reason: 'exited', threadId: 2 } }

glnengineer commented 1 month ago

Addit info:

Credential passed thru codes.

Test accounrt username/password

Line 40: $router = new BasicRouter($_REQUEST);

_token = "GeqrR2OMJ2Wku7iYB0q_qg-un1GKPZaQj1g17gQ9" query_string = "page=login&time=1728326026" username = "username" password = "password" userlang = "en_EN" authenticate = " Go "

glnengineer commented 1 month ago

Lab server info:

Operating System: Rocky Linux 9.4 (Blue Onyx)
CPE OS Name: cpe:/o:rocky:rocky:9::baseos Kernel: Linux 5.14.0-427.37.1.el9_4.x86_64 Architecture: x86-64 Hardware Vendor: VMware, Inc.

MariaDB: 10.5.22 NGINX: 1.20.1-16 PHP: 8.2.13 PowerDNS: 4.8.4-1

edmondas commented 1 month ago

@glnengineer It's really hard for me to say anything from the information you've provided. Could you share the nginx configuration, maybe it's a bit different than I expect. You can exclude server_name just for safety, but in other settings like location and so on.

In my case everything works with such config.

server {
    listen 80;
    server_name REDACTED;
    root /var/www/poweradmin;
    index index.php index.html index.htm;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        fastcgi_pass unix:/var/run/php-fpm/www.sock;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }
}
glnengineer commented 1 month ago

I use your nginx.conf with same AUTH Error result.

Here is my non-SSL version.

server {

Basic settings.

listen       80;
server_name  XXXXXXXX;
root         /usr/share/nginx/XXXX/poweradmin;
index index.php;

# Index settings.
location / {
    proxy_read_timeout 600;
    proxy_connect_timeout 600;
    proxy_send_timeout 600;
    try_files $uri $uri/ /index.php?$args;
}

# PHP-FPM setting.
location ~ \.php$ {
    fastcgi_index index.php;
    include /etc/nginx/fastcgi_params;
    fastcgi_pass unix:/run/php-fpm/www.sock;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}

}

glnengineer commented 1 month ago

MariaDB (MySQL): account build and granted permission to PowerDNS DB.

mysql -u username -ppassword -e "STATUS;mysql -u username -ppassword -e "STATUS; \

SHOW DATABASES; \ SHOW GRANTS FOR username@localhost;"

mysql Ver 15.1 Distrib 10.5.22-MariaDB, for Linux (x86_64) using EditLine wrapper

Connection id: 7 Current database: Current user: username@localhost SSL: Not in use Current pager: stdout Using outfile: '' Using delimiter: ; Server: MariaDB Server version: 10.5.22-MariaDB MariaDB Server Protocol version: 10 Connection: Localhost via UNIX socket Server characterset: latin1 Db characterset: latin1 Client characterset: utf8 Conn. characterset: utf8 UNIX socket: /var/lib/mysql/mysql.sock Uptime: 3 min 5 sec

Threads: 1 Questions: 11 Slow queries: 0 Opens: 21 Open tables: 14 Queries per second avg: 0.059

+--------------------+ | Database | +--------------------+ | information_schema | | pdns | +--------------------+ +-----------------------------------------------------------------------------------------------------------------+ | Grants for username@localhost | +-----------------------------------------------------------------------------------------------------------------+ | GRANT USAGE ON . TO username@localhost IDENTIFIED BY PASSWORD '2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19' | | GRANT SELECT, INSERT, UPDATE, DELETE ON pdns. TO username@localhost | +-----------------------------------------------------------------------------------------------------------------+

glnengineer commented 1 month ago

One more thing. I enabled general query log in MariaDB to see what login communicate with MariaDB.

tail -f /var/lib/mysql/general.log

241007 17:59:02 19 Connect username@localhost on pdns using TCP/IP 19 Prepare SELECT id, fullname, password, active FROM users WHERE username=? AND use_ldap=0 19 Execute SELECT id, fullname, password, active FROM users WHERE username='user1' AND use_ldap=0 19 Close stmt 19 Quit ^C

edmondas commented 1 month ago

The error message: Authentication failed! can only occur in two cases:

  1. No user found with the specified username
  2. Password verification failed for user

For the first case, try to check whether SQL returns data

SELECT id, fullname, password, active FROM users WHERE username="admin" AND use_ldap=0

Please note that the default username is admin

The second is much harder to check, as you need to calculate your password hash and compare it with the one stored in the database

glnengineer commented 1 month ago

OK. I figure out my issue. I cannot speak for the OP.

The issue is due to none of the INSTALL steps tell you which user to use to log into the portal.

I tried the 2 users asked during step 3 and step 4. These are referencing user from 'mysql.user" table.

I ran the SQL cmd and yield no result.

For the first case, try to check whether SQL returns data

mysql -u username -ppassword powerdns

Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A

Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 130 Server version: 10.5.22-MariaDB MariaDB Server

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [powerdns]> SELECT id, fullname, password, active FROM users WHERE username='user1' AND use_ldap=0; Empty set (0.001 sec) <-- HERE!


Step 3: Configuring Database Connection

Username The username to use to connect to the database, make sure the username has sufficient rights to perform administrative task to the PowerDNS database (the installer wants to drop, create and fill tables to the database).

Poweradmin administrator password The password of the Poweradmin administrator. This administrator has full rights to Poweradmin using the web interface.

Step 4: Setup of account and name servers Username The username for Poweradmin. This new user will have limited rights only.

Step 7: Installation complete Now we have finished the configuration.

You should (must!) remove the directory "install/" from the Poweradmin root directory. You will not be able to use Poweradmin if it exists. Do it now.

After you have removed the directory, you can login to Poweradmin.

User created in Step 4 is added to 'mysql.user" table.

MariaDB [powerdns]> SELECT user,host,password,Grant_priv FROM mysql.user; +-------------+-----------+-------------------------------------------+------------+ | User | Host | Password | Grant_priv | +-------------+-----------+-------------------------------------------+------------+ | mariadb.sys | localhost | | N | | root | localhost | invalid | Y | | mysql | localhost | invalid | Y | | poweradmin | localhost | 0176F31B29E0DA4E3EF73FBAB5E467717DDDA444 | N | | username | localhost | 2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19 | N | +-------------+-----------+-------------------------------------------+------------+

I lookup the "users" table in my PowerDNS DB and it only shows username "admin'.

MariaDB [powerdns]> SELECT username,password,fullname from users; +----------+--------------------------------------------------------------+---------------+ | username | password | fullname | +----------+--------------------------------------------------------------+---------------+ | admin | $2y$12$FYFJfsPdNfmbiBMhBkAHreDNn84TJ4v6e11qOxDd25ED1Oed0OX2W | Administrator | +----------+--------------------------------------------------------------+---------------+

This usernname is not mentioned in any of the INSTALL steps.

So I tested the password assigned in Step 3 (Poweradmin administrator password) and it works.

So recap for anyone running into this issue. use username 'admin" and password set in step 3 (Poweradmin administrator password) to log in.

Please update this in Install description in step 7 (last step) on what credential to use to log into the portal.

Thanks.

edmondas commented 1 month ago

@glnengineer Great success! I have added an extra message to the last step as per your request.

Screenshot 2024-10-08 at 18 01 01
edmondas commented 1 month ago

@ChristopherW Have you tried to use the 'admin' user to log in?

edmondas commented 1 month ago

if I enable syslog logging in the config file, the only thing logged is "Failed authentication attempt from [my:ip:addr:ess] for user 'step4-username'."

After carefully reviewing your message, I noticed that this username is used solely for the database connection. I'll update the message to clarify this.

image

Also, why does poweradmin create and want to use an SQL account accessible from any host? I prefer SQL user accounts to be scoped to localhost and do not typically run MariaDB servers bound to anything except localhost (and firewalled accordingly).

The deployment model can vary, as different users utilize our software in various ways. Currently, the installation provides two options when using MySQL or MariaDB:

image

For you, it will be localhost. I'm using Docker, so it suggests a mysql host.

ChristopherW commented 1 month ago

@ChristopherW Have you tried to use the 'admin' user to log in?

Hello, I've been busy for the last few days but noticed the ticket updates. I'm going to look at the additional steps as discussed and will report back with my success or failure! Do you recommend me doing a fresh git clone from master, or should I specify a branch to also get any changes?