[solved] Permission problem with nginx

The issue I am facing:

I'm getting the following error when I try to change the adlist through the web interface on a box running Debian Bookworm.

Error, something went wrong!
While executing: attempt to write a readonly database
Added 0 out of 1 adlists

I followed these instructions and can confirm that www-data is a member of the group pihole:

pihole:x:1001:www-data

I can also confirm the correct ownership of gravity.db

$ ls -l /etc/pihole/gravity.db
-rw-rw-r-- 1 pihole pihole 12603392 Jun 18 17:39 /etc/pihole/gravity.db

Details about my system:

It is a NUC with 8GB RAM.

What I have changed since installing Pi-hole:

Configured pi-hole to use nginx instead of lighttpd.

Just to make sure:

What are the permissions and ownership for the /etc/pihole directory (ls -ld /etc/pihole)?

Validate nginx is actually runnin under the www-date user with:

ps -C nginx -o uid,user,gid,group,pid,cmd

/etc/pihole seems fine:

$ ls -ld /etc/pihole
drwxrwxr-x 3 pihole pihole 4096 Jun 19 13:37 /etc/pihole

but some of its contents are owned by root. Happy to make it all owned by pihole but I don't want to break anything.

$ ls -ld /etc/pihole/*
-rw-r--r-- 1 root   root         65 Jun 18 16:36 /etc/pihole/adlists.list.old
-rw-r--r-- 1 root   root          0 Jun 18 17:39 /etc/pihole/custom.list
-rw-r--r-- 1 pihole pihole        0 Jun 18 17:39 /etc/pihole/dhcp.leases
-rw-r--r-- 1 root   root        651 Jun 18 17:39 /etc/pihole/dns-servers.conf
-rw-rw-r-- 1 pihole pihole 12603392 Jun 18 17:39 /etc/pihole/gravity.db
-rw-rw-r-- 1 pihole pihole    94208 Jun 18 17:39 /etc/pihole/gravity_old.db
-rw-r--r-- 1 root   root        874 Jun 18 17:39 /etc/pihole/install.log
-rw-r--r-- 1 root   root    4580794 Jun 18 17:39 /etc/pihole/list.1.raw.githubusercontent.com.domains
-rw-r--r-- 1 root   root         95 Jun 18 17:39 /etc/pihole/list.1.raw.githubusercontent.com.domains.sha1
-rw-r--r-- 1 root   root         65 Jun 18 17:39 /etc/pihole/local.list
-rw-r--r-- 1 root   root        241 Jun 18 17:39 /etc/pihole/logrotate
-rw-r--r-- 1 pihole pihole  3096576 Jun 18 17:39 /etc/pihole/macvendor.db
drwxr-xr-x 2 root   root       4096 Jun 18 17:39 /etc/pihole/migration_backup
-rw-rw-r-- 1 pihole root        146 Jun 18 18:46 /etc/pihole/pihole-FTL.conf
-rw-rw-r-- 1 pihole pihole   139264 Jun 19 13:38 /etc/pihole/pihole-FTL.db
-rw-r--r-- 1 root   root        385 Jun 18 18:46 /etc/pihole/setupVars.conf
-rw-r--r-- 1 root   root        296 Jun 18 18:26 /etc/pihole/versions

The main process is running under root:

$ ps -C nginx -o uid,user,gid,group,pid,cmd
  UID USER       GID GROUP        PID CMD
    0 root         0 root       70680 nginx: master process /usr/sbin/nginx -g 
   33 www-data    33 www-data   70681 nginx: worker process
   33 www-data    33 www-data   70682 nginx: worker process
   33 www-data    33 www-data   70683 nginx: worker process
   33 www-data    33 www-data   70684 nginx: worker process

Could you post output for below pls?
Easier to read :wink:

stat -c "%U %G %a %n" /etc/pihole/{,*} | column -t

EDIT: changed it a bit

$ stat -c "%U %G %a %n" /etc/pihole/* | column -t
root    root    644  /etc/pihole/adlists.list.old
root    root    644  /etc/pihole/custom.list
pihole  pihole  644  /etc/pihole/dhcp.leases
root    root    644  /etc/pihole/dns-servers.conf
pihole  pihole  664  /etc/pihole/gravity.db
pihole  pihole  664  /etc/pihole/gravity_old.db
root    root    644  /etc/pihole/install.log
root    root    644  /etc/pihole/list.1.raw.githubusercontent.com.domains
root    root    644  /etc/pihole/list.1.raw.githubusercontent.com.domains.sha1
root    root    644  /etc/pihole/local.list
root    root    644  /etc/pihole/logrotate
pihole  pihole  644  /etc/pihole/macvendor.db
root    root    755  /etc/pihole/migration_backup
pihole  root    664  /etc/pihole/pihole-FTL.conf
pihole  pihole  664  /etc/pihole/pihole-FTL.db
root    root    644  /etc/pihole/setupVars.conf
root    root    644  /etc/pihole/versions

Use the </> button instead of quote when pasting code output here pls?
I changed your last reply so it looks way more pleasant :wink:

Could you repeat that but with below instead:

$ stat -c "%U %G %a %n" /etc/pihole/{,*} | column -t
pihole  pihole  775  /etc/pihole/
root    root    644  /etc/pihole/adlists.list.old
root    root    644  /etc/pihole/custom.list
pihole  pihole  644  /etc/pihole/dhcp.leases
root    root    644  /etc/pihole/dns-servers.conf
pihole  pihole  664  /etc/pihole/gravity.db
pihole  pihole  664  /etc/pihole/gravity_old.db
root    root    644  /etc/pihole/install.log
root    root    644  /etc/pihole/list.1.raw.githubusercontent.com.domains
root    root    644  /etc/pihole/list.1.raw.githubusercontent.com.domains.sha1
root    root    644  /etc/pihole/local.list
root    root    644  /etc/pihole/logrotate
pihole  pihole  644  /etc/pihole/macvendor.db
root    root    755  /etc/pihole/migration_backup
pihole  root    664  /etc/pihole/pihole-FTL.conf
pihole  pihole  664  /etc/pihole/pihole-FTL.db
root    root    644  /etc/pihole/setupVars.conf
root    root    644  /etc/pihole/versions

Looks same as mine.

groups www-data

?

$ groups www-data
www-data : www-data pihole

OK I have no clue.
I dont run nginx so better wait for someone else with experience to reply.

I also don't use nginx.

I'm not sure if there are some PHP error messages to help us here. When Pi-hole runs using lighttpd the debug log shows PHP error messages, but nginx logs are not collected.

Do you see any errors on your PHP logs or web server logs?

1 Like

Do you run php-fpm.service ?

systemctl is-active php-fpm.service

If so, have a look at below:

Since version 7.4 php-fpm is hardened by default and revokes read/write access on /usr (and sub-directories).

Create an drop-in file for php-fpm with the following content:

From searching here:

Yes, it is active:

$ systemctl is-active php8.2-fpm.service
active

The archwiki solution seems like it might work but Debian's implementation of php-fpm has pretty different file locations.

A slightly different question. How do I change the block list from the command line? Either editing a config file or using the pihole command would be fine? (If preferred, I can post the question in a new topic.)

I should have supplied you with below instead :wink:

systemctl list-units "*php*"

Yeah I cant help you much with that as the default Pi-hole install uses a different PHP interpreter:

pi@ph5a:~ $ cat /etc/lighttpd/conf-enabled/15-fastcgi-php.conf
# -*- depends: fastcgi -*-
# /usr/share/doc/lighttpd/fastcgi.txt.gz
# http://redmine.lighttpd.net/projects/lighttpd/wiki/Docs:ConfigurationOptions#mod_fastcgi-fastcgi

## Start an FastCGI server for php (needs the php5-cgi package)
fastcgi.server += ( ".php" =>
        ((
                "bin-path" => "/usr/bin/php-cgi",
[..]

I dont know what exactly needs to be done for that as Pi-hole stores those in a dbase and are linked to "groups":

pi@ph5a:~ $ pihole-FTL sqlite3 /etc/pihole/gravity.db ".databases"
main: /etc/pihole/gravity.db r/o
pi@ph5a:~ $ pihole-FTL sqlite3 /etc/pihole/gravity.db ".tables"
adlist               domainlist_by_group  vw_gravity
adlist_by_group      gravity              vw_regex_blacklist
client               group                vw_regex_whitelist
client_by_group      info                 vw_whitelist
domain_audit         vw_adlist
domainlist           vw_blacklist
pi@ph5a:~ $ pihole-FTL sqlite3 /etc/pihole/gravity.db ".schema adlist"
CREATE TABLE adlist
(
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        address TEXT UNIQUE NOT NULL,
        enabled BOOLEAN NOT NULL DEFAULT 1,
        date_added INTEGER NOT NULL DEFAULT (cast(strftime('%s', 'now') as int)),
        date_modified INTEGER NOT NULL DEFAULT (cast(strftime('%s', 'now') as int)),
        comment TEXT,
        date_updated INTEGER,
        number INTEGER NOT NULL DEFAULT 0,
        invalid_domains INTEGER NOT NULL DEFAULT 0,
        status INTEGER NOT NULL DEFAULT 0
);
CREATE TRIGGER tr_adlist_update AFTER UPDATE OF address,enabled,comment ON adlist
    BEGIN
      UPDATE adlist SET date_modified = (cast(strftime('%s', 'now') as int)) WHERE id = NEW.id;
    END;
CREATE TRIGGER tr_adlist_delete AFTER DELETE ON adlist
    BEGIN
      DELETE FROM adlist_by_group WHERE adlist_id = OLD.id;
    END;
CREATE TRIGGER tr_adlist_add AFTER INSERT ON adlist
    BEGIN
      INSERT INTO adlist_by_group (adlist_id, group_id) VALUES (NEW.id, 0);
    END;
pi@ph5a:~ $ pihole-FTL sqlite3 /etc/pihole/gravity.db --header --column "SELECT * FROM adlist"
id  address                                                                enabled  date_added  date_modified  comment          date_updated  number  invalid_domains  status
--  ---------------------------------------------------------------------  -------  ----------  -------------  ---------------  ------------  ------  ---------------  ------
1   https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts       1        1616080363  1624707951     Pi-hole default  1687053987    193746  1                1
3   https://dehakkelaar.nl/lists/cryptojacking_campaign.list.txt           1        1616084339  1624707968     Crypto Jacking   1681672096    853     0                2
4   https://gitlab.com/ZeroDot1/CoinBlockerLists/raw/master/list.txt       1        1616084339  1624707972     Crypto Jacking   1687054020    288104  212              1

I can show you how to delete and add an URL but am not sure if thats all you have to do as Pi-hole also works with "groups" which complicates a bit":

pi@ph5a:~ $ pihole-FTL sqlite3 /etc/pihole/gravity.db --header --column "SELECT * FROM adlist_by_group"
adlist_id  group_id
---------  --------
4          0
1          0
3          0

Better get the webGUI up and running :wink:

Ok, this is very weird but all of a sudden, it's working. I had added the drop-in file from the Arch wiki and it looked like it was going to be a lot of work to get it working so I eventually deleted it. Then, after your last post, I thought, let's give the gui another try and lo and behold, it works! Clearly a reboot or something was needed -- I'm pretty sure I made no substantive changes.

In any case, thank you for the many suggestions!

1 Like

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