[SOLVED] Securing php PDO mysql credentials for Humo-Gen

Problem Description
I have installed a Humo-Gen genealogy LAMP webserver, which uses php and mysql/mariadb.
I installed mariadb, php-pdo, and php-gd2 and unzipped the installation zipfile to /var/www/htmll/humogen then ran the setup from a browser. Everything works fine. I uploaded a GEDCOM file with around 9,000 people and the Olimex HK-Pioneer is handling the server load just fine.

Now that everything’s working, I would like to secure the webserver.
The Humo-Gen manual suggests moving a file “db_login.php” which contains
mysql credentials (hostname, user, password, dbname):

define("DATABASE_HOST",     'localhost');
define("DATABASE_USERNAME", 'username');
define("DATABASE_PASSWORD", 'password');
define("DATABASE_NAME",     'dbname');

The manual suggests moving the file outside the webroot and then
replacing it with a new file like:

<?php require_once(''/root/mydomain/db_login.inc.php");?>

Expected Results
After making the change, I should still be able to access the login screen.

Actual results
Just get a blank screen.
I’ve set ownership/permissions to www-data.www-data for the directory and file holding the sql connection credentials.
My best guess is that FreedomBox’s apache2 configuration files don’t allow this.

I’ve taken a look around /etc/apache2/apache.conf and /etc/apache2/conf-available/
but I would appreciate any help on getting this to work.

There’s a lot online about various ways of securing mysql connections in php, but simply putting the credentials in a file outside the webroot is probably the simplest.

Some other methods involve apache loading global php environment variables, then moving them to local memory and basically rewriting the code. I’d prefer to leave the upstream code alone, so I can keep the genealogy program upgraded easily.

Hi okno, thanks for the detailed description of your issue.

I would guess that you’re in the right track and it might be an issue with permissions to access the moved file outside the content root. Could you check the following:

  • Do you see any log messages from Apache? They should be in /var/log/apache2.
  • What are the permissions of the folder structure /root/mydomain and the file itself? For the apache user to be able to ‘see’ that file, the directories would need the ‘+x’ flag, so maybe you just need a sudo chmod +x /root && sudo chmod +x /root/mydomain and then reload apache with sudo systemctl reload apache2? Alternatively - if you do not want to use the /root folder at all - you could place the db_login.inc.php file somewhere else like a new folder /etc/humogen and set the proper permissions there.

Cheers & HTH,
Axel

1 Like
root@freedombox:~# ls -ldn /etc/DOMAIN 
drwxr-xr-x 1 33 33 56 Feb  5 06:07 /etc/DOMAIN
root@freedombox:~# ls -l /etc|grep DOMAIN
drwxr-xr-x 1 www-data www-data    56 Feb  5 06:07 DOMAIN
root@freedombox:~# ls -lr /etc/DOMAIN/
total 8
-rw-r--r-- 1 www-data www-data   61 Feb  4 13:32 db_login.php
-rw-r--r-- 1 www-data www-data 2339 Feb  4 07:53 db_login.inc.php
root@freedombox:~# vi cd /var/www/html/humogen/include/
2 files to edit
root@freedombox:~# cd /var/www/html/humogen/include/
root@freedombox:/var/www/html/humogen/include# vi db_login.php 
root@freedombox:/var/www/html/humogen/include# cp /etc/DOMAIN/db_login.php .
root@freedombox:/var/www/html/humogen/include# vi db_login.php 
root@freedombox:/var/www/html/humogen/include# ls -l db_login.php 
-rw-r--r-- 1 www-data www-data 60 Feb  5 13:44 db_login.php
root@freedombox:/var/www/html/humogen/include# systemctl restart apache2; systemctl restart php7.4-fpm

And I still get a blank screen/
I also tried /var/www/DOMAIN and /usr/share/DOMAIN
because /etc/apache2/apache2.conf has these directives:

# Sets the default security model of the Apache2 HTTPD server. It does
# not allow access to the root filesystem outside of /usr/share and /var/www.
# The former is used by web applications packaged in Debian,
# the latter may be used for local directories served by the web server. If
# your system is serving content from a sub-directory in /srv you must allow
# access here, or in any related virtual host.

<Directory /usr/share>
	AllowOverride None
	Require all granted
</Directory>

<Directory /var/www/>
	Options Indexes FollowSymLinks
	AllowOverride None
	Require all granted
</Directory>

But I still get a blank screen.

My unchanged /etc/apache2/sites-enabled/freedombox-default.conf :

# Keep this in sync with apache default 000-default.conf
<VirtualHost *:80>
    ServerAdmin webmaster@localhost
    DocumentRoot /var/www/html
</VirtualHost>

# Keep this in sync with apache default default-ssl.conf
<IfModule mod_ssl.c>
    <VirtualHost _default_:443>
        ServerAdmin webmaster@localhost
        DocumentRoot /var/www/html

        SSLEngine on
        SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem
        SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
        <FilesMatch "\.(?:cgi|shtml|phtml|php)$">
            SSLOptions +StdEnvVars
        </FilesMatch>
        <Directory /usr/lib/cgi-bin>
            SSLOptions +StdEnvVars
        </Directory>
    </VirtualHost>
</IfModule>

And my virtual DOMAIN’s configuration file as automatically created by FreedomBox:

Use FreedomBoxTLSSiteMacro www.DOMAIN

My Humo-Gen website is in a subfolder of the webroot and is accessed at http://freedombox.local/humogen or https://www.DOMAIN/humogen

/var/www/html/humogen

I zero’d out my /var/log/apache2 logfiles, then browsed to humogen, got blank screen, but nothing at all written to any apache2 logfiles.

OK, I found that if I just make db_login.php a symlink to the sql credentials outside the DOCROOT, then this works. But is that then no different than just keeping the sql credentials inside the DOCROOT ? Don’t want everyone on the internet to just GET db_login.php and take a look at my SQL connection credentials.

I fully agree with your concern, but I do not know PHP well enough to understand which permissions are necessary for require_once() to work properly. And the section in humogen’s manual do not say anything about file system permissions and only points out multiple locations where you need to change the code.

Did you have any luck checking Apache’s error log files when not using the symlink? If it says something like ‘permission denied’ we can at least be sure that it tries to access the proper (moved) files.

Thanks for the help kopfkind

I figured it out.
[SOLVED]

I turned on php logging by adding these lines to /etc/php/7.4/fpm/php.ini

    error_reporting = E_ALL & ~E_NOTICE
    error_reporting = E_ALL & ~E_NOTICE | E_STRICT
    error_reporting = E_COMPILE_ERROR|E_RECOVERABLE_ERROR|E_ER… _ERROR
    error_reporting = E_ALL & ~E_NOTICE

Then added some lines to db_login.php

<?php 
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
require_once("/etc/DOMAIN/db_login.inc.php");
;require_once("/var/www/DOMAIN/db_login.inc.php");
?>

And for good measure restarted everything:
systemctl restart php7.4-fpm ; systemctl restart apache2

Turns out when I cut-n-pasted from the Humo-Gen manual I somehow got mismatched parenthesis
which resulted in a php parse error:

<?php require_once(``/etc/DOMAIN/db_login.inc.php"); ?>

2 Likes

I’m happy to hear that you’ve found the issue. Happy genealogy-ing! :nerd_face:

And just for completeness, in case any other FreedomBox users run into something similar,

I also had to enable displaying errors in /etc/php/7.4/fpm/php.ini
by setting display_errors = On

; Default Value: On
; Development Value: On
; Production Value: Off
; http://php.net/display-errors
display_errors = Off
2 Likes

Note: The Debian 12 “Bookworm” upgrade changes the file relevant to @okno’s explanation from /etc/php/7.4/fpm/php.ini to /etc/php/8.2/fpm/php.ini. If a future PHP upgrade occurs, changes to this file might cause the upgrade process to require manual approval of the changes. Therefore, I recommend making a backup of the php.ini file so that you can revert it during an upgrade, or at least know which changes you need to reapply.