Upgrade through Dashboard fails if AGH service is run as non-root user #1104

Closed
opened 2026-03-04 01:04:16 -05:00 by deekerman · 24 comments
Owner

Originally created by @kinggrowler on GitHub (Nov 22, 2019).

Originally assigned to: @szolin on GitHub.

When an update for AdGuard Home is available, the dashboard displays a notice about the available upgrade along with an "Upgrade now" button.

Clicking the button does nearly everything correctly: the old binary is archived, the new one downloaded, the systemd service is restarted.

However, when the service is run as a non-root user, the "setcap" command must be manually executed again.

sudo setcap CAP_NET_BIND_SERVICE=+eip /opt/AdGuardHome/AdGuardHome

My question: is this expected behaviour, and if so, is there a better way I can handle this than manually logging in and running the command?

  • Version of AdGuard Home server:
    • 0.992 to 0.99.3
  • How did you setup DNS configuration:
    • AdGuard Home is configured as my network's nameserver through my router DHCP configuration.
  • Operating system and version:
    • Various Ubuntu and Debian-based LXC containers where AGH service is run as a non-root user.

Expected Behavior

Ideally, AGH would handle setting of the CAP_NET_BIND_SERVICE capability. Baring that, AGH should display a warning message before upgrading via Dashboard.

Actual Behavior

AGH fails to restart after upgrade due to inability to bind to a privileged port.

Screenshots

● AdGuardHome.service - AdGuard Home: Network-level blocker
   Loaded: loaded (/etc/systemd/system/AdGuardHome.service; enabled; vendor preset: enabled)
   Active: activating (auto-restart) (Result: exit-code) since Fri 2019-11-22 10:40:49 PST; 4s ago
  Process: 1068 ExecStart=/opt/AdGuardHome/AdGuardHome -s run (code=exited, status=1/FAILURE)
 Main PID: 1068 (code=exited, status=1/FAILURE)

Nov 22 10:40:49 adguard systemd[1]: AdGuardHome.service: Failed with result 'exit-code'.

aghome@adguard:~$ cd /opt/AdGuardHome/
aghome@adguard:~$ sudo setcap CAP_NET_BIND_SERVICE=+eip /opt/AdGuardHome/AdGuardHome

aghome@adguard:/opt/AdGuardHome$ sudo systemctl restart AdGuardHome.service
aghome@adguard:/opt/AdGuardHome$ sudo systemctl status AdGuardHome.service
● AdGuardHome.service - AdGuard Home: Network-level blocker
   Loaded: loaded (/etc/systemd/system/AdGuardHome.service; enabled; vendor preset: enabled)
   Active: active (running) since Fri 2019-11-22 10:43:01 PST; 4s ago
 Main PID: 1280 (AdGuardHome)
    Tasks: 13 (limit: 4915)
   CGroup: /system.slice/AdGuardHome.service
           └─1280 /opt/AdGuardHome/AdGuardHome -s run

Nov 22 10:43:03 adguard AdGuardHome[1280]: 2019/11/22 10:43:03 [info] Starting the DNS proxy server
Nov 22 10:43:03 adguard AdGuardHome[1280]: 2019/11/22 10:43:03 [info] Ratelimit is enabled and set to 20 rps
Nov 22 10:43:03 adguard AdGuardHome[1280]: 2019/11/22 10:43:03 [info] The server is configured to refuse ANY requests
Nov 22 10:43:03 adguard AdGuardHome[1280]: 2019/11/22 10:43:03 [info] DNS cache is enabled
Nov 22 10:43:03 adguard AdGuardHome[1280]: 2019/11/22 10:43:03 [info] Creating the UDP server socket
Nov 22 10:43:03 adguard AdGuardHome[1280]: 2019/11/22 10:43:03 [info] Listening to udp://[::]:53
Nov 22 10:43:03 adguard AdGuardHome[1280]: 2019/11/22 10:43:03 [info] Creating the TCP server socket
Nov 22 10:43:03 adguard AdGuardHome[1280]: 2019/11/22 10:43:03 [info] Listening to tcp://[::]:53
Nov 22 10:43:03 adguard AdGuardHome[1280]: 2019/11/22 10:43:03 [info] Entering the UDP listener loop on [::]:53
Nov 22 10:43:03 adguard AdGuardHome[1280]: 2019/11/22 10:43:03 [info] Entering the tcp listener loop on [::]:53

Additional Information

$ cat /etc/systemd/system/AdGuardHome.service

[Unit]
Description=AdGuard Home: Network-level blocker
ConditionFileIsExecutable=/opt/AdGuardHome/AdGuardHome
After=syslog.target network-online.target

[Service]
User=aghome
Group=aghome
StartLimitInterval=5
StartLimitBurst=10
ExecStart=/opt/AdGuardHome/AdGuardHome "-s" "run"

WorkingDirectory=/opt/AdGuardHome

Restart=always
RestartSec=10
EnvironmentFile=-/etc/sysconfig/AdGuardHome

[Install]
WantedBy=multi-user.target
Originally created by @kinggrowler on GitHub (Nov 22, 2019). Originally assigned to: @szolin on GitHub. When an update for AdGuard Home is available, the dashboard displays a notice about the available upgrade along with an "Upgrade now" button. Clicking the button does nearly everything correctly: the old binary is archived, the new one downloaded, the systemd service is restarted. However, when the service is run as a **non-root user**, the "setcap" command must be manually executed again. `sudo setcap CAP_NET_BIND_SERVICE=+eip /opt/AdGuardHome/AdGuardHome` **My question**: is this expected behaviour, and if so, is there a better way I can handle this than manually logging in and running the command? <!--- Please include all relevant details about the environment you experienced the bug in --> * **Version of AdGuard Home server:** * 0.992 to 0.99.3 * **How did you setup DNS configuration:** * AdGuard Home is configured as my network's nameserver through my router DHCP configuration. * **Operating system and version:** * Various Ubuntu and Debian-based LXC containers where AGH service is run as a non-root user. ### Expected Behavior Ideally, AGH would handle setting of the CAP_NET_BIND_SERVICE capability. Baring that, AGH should display a warning message before upgrading via Dashboard. ### Actual Behavior AGH fails to restart after upgrade due to inability to bind to a privileged port. ### Screenshots ```aghome@adguard:~$ sudo systemctl status AdGuardHome.service ● AdGuardHome.service - AdGuard Home: Network-level blocker Loaded: loaded (/etc/systemd/system/AdGuardHome.service; enabled; vendor preset: enabled) Active: activating (auto-restart) (Result: exit-code) since Fri 2019-11-22 10:40:49 PST; 4s ago Process: 1068 ExecStart=/opt/AdGuardHome/AdGuardHome -s run (code=exited, status=1/FAILURE) Main PID: 1068 (code=exited, status=1/FAILURE) Nov 22 10:40:49 adguard systemd[1]: AdGuardHome.service: Failed with result 'exit-code'. aghome@adguard:~$ cd /opt/AdGuardHome/ aghome@adguard:~$ sudo setcap CAP_NET_BIND_SERVICE=+eip /opt/AdGuardHome/AdGuardHome aghome@adguard:/opt/AdGuardHome$ sudo systemctl restart AdGuardHome.service aghome@adguard:/opt/AdGuardHome$ sudo systemctl status AdGuardHome.service ● AdGuardHome.service - AdGuard Home: Network-level blocker Loaded: loaded (/etc/systemd/system/AdGuardHome.service; enabled; vendor preset: enabled) Active: active (running) since Fri 2019-11-22 10:43:01 PST; 4s ago Main PID: 1280 (AdGuardHome) Tasks: 13 (limit: 4915) CGroup: /system.slice/AdGuardHome.service └─1280 /opt/AdGuardHome/AdGuardHome -s run Nov 22 10:43:03 adguard AdGuardHome[1280]: 2019/11/22 10:43:03 [info] Starting the DNS proxy server Nov 22 10:43:03 adguard AdGuardHome[1280]: 2019/11/22 10:43:03 [info] Ratelimit is enabled and set to 20 rps Nov 22 10:43:03 adguard AdGuardHome[1280]: 2019/11/22 10:43:03 [info] The server is configured to refuse ANY requests Nov 22 10:43:03 adguard AdGuardHome[1280]: 2019/11/22 10:43:03 [info] DNS cache is enabled Nov 22 10:43:03 adguard AdGuardHome[1280]: 2019/11/22 10:43:03 [info] Creating the UDP server socket Nov 22 10:43:03 adguard AdGuardHome[1280]: 2019/11/22 10:43:03 [info] Listening to udp://[::]:53 Nov 22 10:43:03 adguard AdGuardHome[1280]: 2019/11/22 10:43:03 [info] Creating the TCP server socket Nov 22 10:43:03 adguard AdGuardHome[1280]: 2019/11/22 10:43:03 [info] Listening to tcp://[::]:53 Nov 22 10:43:03 adguard AdGuardHome[1280]: 2019/11/22 10:43:03 [info] Entering the UDP listener loop on [::]:53 Nov 22 10:43:03 adguard AdGuardHome[1280]: 2019/11/22 10:43:03 [info] Entering the tcp listener loop on [::]:53 ``` ### Additional Information $ cat /etc/systemd/system/AdGuardHome.service ``` [Unit] Description=AdGuard Home: Network-level blocker ConditionFileIsExecutable=/opt/AdGuardHome/AdGuardHome After=syslog.target network-online.target [Service] User=aghome Group=aghome StartLimitInterval=5 StartLimitBurst=10 ExecStart=/opt/AdGuardHome/AdGuardHome "-s" "run" WorkingDirectory=/opt/AdGuardHome Restart=always RestartSec=10 EnvironmentFile=-/etc/sysconfig/AdGuardHome [Install] WantedBy=multi-user.target ```
deekerman 2026-03-04 01:04:16 -05:00
Author
Owner

@ameshkov commented on GitHub (Nov 25, 2019):

Ideally, AGH would handle setting of the CAP_NET_BIND_SERVICE capability. Baring that, AGH should display a warning message before upgrading via Dashboard.

I am not sure if we can handle this without root.

As an alternative solution, we can simply disable automatic updates, replace "Update now" with "Learn how to update" button and lead users to the update manual.

@ameshkov commented on GitHub (Nov 25, 2019): > Ideally, AGH would handle setting of the CAP_NET_BIND_SERVICE capability. Baring that, AGH should display a warning message before upgrading via Dashboard. I am not sure if we can handle this without root. As an alternative solution, we can simply disable automatic updates, replace "Update now" with "Learn how to update" button and lead users to the update manual.
Author
Owner

@kinggrowler commented on GitHub (Nov 25, 2019):

I have a workaround for this simply by changing slightly the systemd service file for AdGuardHome.service.

Adding the line:

ExecStartPre=+/sbin/setcap CAP_NET_BIND_SERVICE=+eip /opt/AdGuardHome/AdGuardHome

Will run the setcap command each time the service is bounced, and run only that command as root user. I have tested this a number of times upgrading from 0.99.2 to 0.99.3 and it works without issue. The downside is we run this command each time the service is restarted, but it certainly doesn't cause issue to do so (as far as I know).

See this note about systemd.service "Special executable prefixes:

Prefix Effect
"+" If the executable path is prefixed with "+" then the process is executed with full privileges. In this mode privilege restrictions configured with User=, Group=, CapabilityBoundingSet= or the various file system namespacing options (such as PrivateDevices=, PrivateTmp=) are not applied to the invoked command line (but still affect any other ExecStart=, ExecStop=, … lines).

( The "+" modifier was introduced in version 231.)

Attached is my complete systemd service file, which differs from the one in my orignal comment by only this line:

[Unit]
Description=AdGuard Home: Network-level blocker
ConditionFileIsExecutable=/opt/AdGuardHome/AdGuardHome
After=syslog.target network-online.target

[Service]
User=aghome
Group=aghome
StartLimitInterval=5
StartLimitBurst=10
ExecStartPre=+/sbin/setcap CAP_NET_BIND_SERVICE=+eip /opt/AdGuardHome/AdGuardHome
ExecStart=/opt/AdGuardHome/AdGuardHome "-s" "run"

WorkingDirectory=/opt/AdGuardHome

Restart=always
RestartSec=10
EnvironmentFile=-/etc/sysconfig/AdGuardHome

[Install]
WantedBy=multi-user.target
@kinggrowler commented on GitHub (Nov 25, 2019): I have a workaround for this simply by changing slightly the systemd service file for AdGuardHome.service. Adding the line: `ExecStartPre=+/sbin/setcap CAP_NET_BIND_SERVICE=+eip /opt/AdGuardHome/AdGuardHome` Will run the setcap command each time the service is bounced, and run only that command as root user. I have tested this a number of times upgrading from 0.99.2 to 0.99.3 and it works without issue. The downside is we run this command each time the service is restarted, but it certainly doesn't cause issue to do so (as far as I know). See this [note](https://www.freedesktop.org/software/systemd/man/systemd.service.html) about systemd.service "Special executable prefixes: > Prefix | Effect > -- | -- > "+" | If the executable path is prefixed with "+" then the process is executed with full privileges. In this mode privilege restrictions configured with User=, Group=, CapabilityBoundingSet= or the various file system namespacing options (such as PrivateDevices=, PrivateTmp=) are not applied to the invoked command line (but still affect any other ExecStart=, ExecStop=, … lines). ( The "+" modifier was introduced in version 231.) Attached is my complete systemd service file, which differs from the one in my orignal comment by only this line: ``` [Unit] Description=AdGuard Home: Network-level blocker ConditionFileIsExecutable=/opt/AdGuardHome/AdGuardHome After=syslog.target network-online.target [Service] User=aghome Group=aghome StartLimitInterval=5 StartLimitBurst=10 ExecStartPre=+/sbin/setcap CAP_NET_BIND_SERVICE=+eip /opt/AdGuardHome/AdGuardHome ExecStart=/opt/AdGuardHome/AdGuardHome "-s" "run" WorkingDirectory=/opt/AdGuardHome Restart=always RestartSec=10 EnvironmentFile=-/etc/sysconfig/AdGuardHome [Install] WantedBy=multi-user.target ```
Author
Owner

@ameshkov commented on GitHub (Nov 25, 2019):

Huh, interesting!

So it seems it would be enough to change the documentation on how to run AdGuard Home without root.

@ameshkov commented on GitHub (Nov 25, 2019): Huh, interesting! So it seems it would be enough to change the documentation on how to run AdGuard Home without root.
Author
Owner

@kinggrowler commented on GitHub (Nov 25, 2019):

Huh, interesting!

So it seems it would be enough to change the documentation on how to run AdGuard Home without root.

My workaround definitely works but I'm not an expert with systemd so I don't know if there is a better way. It certainly seems like a nice solution since there is no change to the AGH binary and only adding one line to the service file, and only for those users that wish to run as non-root user.

@kinggrowler commented on GitHub (Nov 25, 2019): > Huh, interesting! > > So it seems it would be enough to change the documentation on how to run AdGuard Home without root. My workaround definitely works but I'm not an expert with systemd so I don't know if there is a better way. It certainly seems like a nice solution since there is no change to the AGH binary and only adding one line to the service file, and only for those users that wish to run as non-root user.
Author
Owner

@OMICRON3069 commented on GitHub (Dec 25, 2019):

Maybe you can add this two line to your systemd services file

CapabilityBoundingSet=CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_NET_BIND_SERVICE

so it will be like

[Service]
Type=simple
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_NET_BIND_SERVICE
PermissionsStartOnly=true

ExecStart=/usr/local/bin/AdGuardHome -w /opt/dns
WorkingDirectory=/opt/dns

Restart=on-failure
RestartSec=3

User=omicron3069

KillMode=process
ProtectSystem=full
ProtectHome=read-only
PrivateTmp=true
PrivateDevices=true
NoNewPrivileges=true
@OMICRON3069 commented on GitHub (Dec 25, 2019): Maybe you can add this two line to your systemd services file ``` CapabilityBoundingSet=CAP_NET_BIND_SERVICE AmbientCapabilities=CAP_NET_BIND_SERVICE ``` so it will be like ``` [Service] Type=simple CapabilityBoundingSet=CAP_NET_BIND_SERVICE AmbientCapabilities=CAP_NET_BIND_SERVICE PermissionsStartOnly=true ExecStart=/usr/local/bin/AdGuardHome -w /opt/dns WorkingDirectory=/opt/dns Restart=on-failure RestartSec=3 User=omicron3069 KillMode=process ProtectSystem=full ProtectHome=read-only PrivateTmp=true PrivateDevices=true NoNewPrivileges=true ```
Author
Owner

@kinggrowler commented on GitHub (Dec 28, 2019):

@OMICRON3069 , can you explain a bit more about what these two lines do?

@kinggrowler commented on GitHub (Dec 28, 2019): @OMICRON3069 , can you explain a bit more about what these two lines do?
Author
Owner

@OMICRON3069 commented on GitHub (Dec 28, 2019):

No problem, and you can read systemd manual in detail at https://www.freedesktop.org/software/systemd/man/systemd.exec.html

CapabilityBoundingSet=

Controls which capabilities to include in the capability bounding set for the executed process. See capabilities(7) for details. Takes a whitespace-separated list of capability names, e.g. CAP_SYS_ADMIN, CAP_DAC_OVERRIDE, CAP_SYS_PTRACE. Capabilities listed will be included in the bounding set, all others are removed. If the list of capabilities is prefixed with "~", all but the listed capabilities will be included, the effect of the assignment inverted. Note that this option also affects the respective capabilities in the effective, permitted and inheritable capability sets. If this option is not used, the capability bounding set is not modified on process execution, hence no limits on the capabilities of the process are enforced. This option may appear more than once, in which case the bounding sets are merged by OR, or by AND if the lines are prefixed with "~" (see below). If the empty string is assigned to this option, the bounding set is reset to the empty capability set, and all prior settings have no effect. If set to "~" (without any further argument), the bounding set is reset to the full set of available capabilities, also undoing any previous settings. This does not affect commands prefixed with "+".

AmbientCapabilities=

Controls which capabilities to include in the ambient capability set for the executed process. Takes a whitespace-separated list of capability names, e.g. CAP_SYS_ADMIN, CAP_DAC_OVERRIDE, CAP_SYS_PTRACE. This option may appear more than once in which case the ambient capability sets are merged (see the above examples in CapabilityBoundingSet=). If the list of capabilities is prefixed with "~", all but the listed capabilities will be included, the effect of the assignment inverted. If the empty string is assigned to this option, the ambient capability set is reset to the empty capability set, and all prior settings have no effect. If set to "~" (without any further argument), the ambient capability set is reset to the full set of available capabilities, also undoing any previous settings. Note that adding capabilities to ambient capability set adds them to the process's inherited capability set.

Ambient capability sets are useful if you want to execute a process as a non-privileged user but still want to give it some capabilities. Note that in this case option keep-caps is automatically added to SecureBits= to retain the capabilities over the user change. AmbientCapabilities= does not affect commands prefixed with "+".

Also, you can get those answers by searching systemd allow bind port with google. I think google should always be the first to ask about those technical problems.

@OMICRON3069 commented on GitHub (Dec 28, 2019): No problem, and you can read systemd manual in detail at https://www.freedesktop.org/software/systemd/man/systemd.exec.html CapabilityBoundingSet= > Controls which capabilities to include in the capability bounding set for the executed process. See capabilities(7) for details. Takes a whitespace-separated list of capability names, e.g. CAP_SYS_ADMIN, CAP_DAC_OVERRIDE, CAP_SYS_PTRACE. Capabilities listed will be included in the bounding set, all others are removed. If the list of capabilities is prefixed with "\~", all but the listed capabilities will be included, the effect of the assignment inverted. Note that this option also affects the respective capabilities in the effective, permitted and inheritable capability sets. If this option is not used, the capability bounding set is not modified on process execution, hence no limits on the capabilities of the process are enforced. This option may appear more than once, in which case the bounding sets are merged by OR, or by AND if the lines are prefixed with "\~" (see below). If the empty string is assigned to this option, the bounding set is reset to the empty capability set, and all prior settings have no effect. If set to "~" (without any further argument), the bounding set is reset to the full set of available capabilities, also undoing any previous settings. This does not affect commands prefixed with "+". AmbientCapabilities= > Controls which capabilities to include in the ambient capability set for the executed process. Takes a whitespace-separated list of capability names, e.g. CAP_SYS_ADMIN, CAP_DAC_OVERRIDE, CAP_SYS_PTRACE. This option may appear more than once in which case the ambient capability sets are merged (see the above examples in CapabilityBoundingSet=). If the list of capabilities is prefixed with "\~", all but the listed capabilities will be included, the effect of the assignment inverted. If the empty string is assigned to this option, the ambient capability set is reset to the empty capability set, and all prior settings have no effect. If set to "\~" (without any further argument), the ambient capability set is reset to the full set of available capabilities, also undoing any previous settings. Note that adding capabilities to ambient capability set adds them to the process's inherited capability set. > Ambient capability sets are useful if you want to execute a process as a non-privileged user but still want to give it some capabilities. Note that in this case option keep-caps is automatically added to SecureBits= to retain the capabilities over the user change. AmbientCapabilities= does not affect commands prefixed with "+". Also, you can get those answers by searching `systemd allow bind port` with google. I think google should always be the first to ask about those technical problems.
Author
Owner

@kinggrowler commented on GitHub (Dec 28, 2019):

Very interesting, thanks! What was your experience doing an upgrade?

I think google should always be the first to ask about those technical problems.

I don't disagree but found in my IT career, when creating or updating a ticket, it was a powerful choice to include all information in the ticket so as to prevent people needing to click elsewhere for answers. It's one thing to say "do this" but it's more helpful to include why.

But I'm retired now and no longer do IT work so I don't know what the hot trends are regarding this. Cheers!

@kinggrowler commented on GitHub (Dec 28, 2019): Very interesting, thanks! What was your experience doing an upgrade? > I think google should always be the first to ask about those technical problems. I don't disagree but found in my IT career, when creating or updating a ticket, it was a powerful choice to include all information in the ticket so as to prevent people needing to click elsewhere for answers. It's one thing to say "do this" but it's more helpful to include why. But I'm retired now and no longer do IT work so I don't know what the hot trends are regarding this. Cheers!
Author
Owner

@OMICRON3069 commented on GitHub (Dec 29, 2019):

Things are little different in my situation. I compile those code (not just only AGH) on my local machine, and sync those binaries to my server through syncthing.

Indeed, it makes sense to include additional information to prevent people for further searching, maybe I will try it in the future!

@OMICRON3069 commented on GitHub (Dec 29, 2019): Things are little different in my situation. I compile those code (not just only AGH) on my local machine, and sync those binaries to my server through [syncthing](https://github.com/syncthing/syncthing). Indeed, it makes sense to include additional information to prevent people for further searching, maybe I will try it in the future!
Author
Owner

@simonbcn commented on GitHub (Jan 21, 2020):

Any of those solutions doesn't work in a new install. AdGuardHome always wants to run as root the first time.

@simonbcn commented on GitHub (Jan 21, 2020): Any of those solutions doesn't work in a new install. _AdGuardHome_ always wants to run as root the first time.
Author
Owner

@ameshkov commented on GitHub (Jan 21, 2020):

@simonbcn the thing is that AdGuard Home detects the first installation by checking for AdGuardHome.yaml presence. If you create this file by yourself before running AGH, it won't check for root access.

@ameshkov commented on GitHub (Jan 21, 2020): @simonbcn the thing is that AdGuard Home detects the first installation by checking for `AdGuardHome.yaml` presence. If you create this file by yourself before running AGH, it won't check for root access.
Author
Owner

@simonbcn commented on GitHub (Jan 21, 2020):

@ameshkov I've tried to create a empty file with that name but it doesn't work:

...
ene 21 15:26:08 juan-pc audit[1]: SERVICE_START pid=1 uid=0 auid=4294967295 ses=4294967295 msg='unit=adguardhome comm="systemd" exe="/usr/lib/systemd>
ene 21 15:26:08 juan-pc kernel: audit: type=1130 audit(1579616768.611:1971): pid=1 uid=0 auid=4294967295 ses=4294967295 msg='unit=adguardhome comm="s>
ene 21 15:26:08 juan-pc AdGuardHome[203323]: 2020/01/21 15:26:08 [info] Service control action: run
ene 21 15:26:08 juan-pc AdGuardHome[203323]: 2020/01/21 15:26:08 [info] AdGuard Home, version v0.100.9, channel release
ene 21 15:26:08 juan-pc AdGuardHome[203323]: 2020/01/21 15:26:08 [info] AdGuard Home is running as a service
ene 21 15:26:08 juan-pc AdGuardHome[203323]: 2020/01/21 15:26:08 [info] home.upgradeSchema0to1(): called
ene 21 15:26:08 juan-pc AdGuardHome[203323]: 2020/01/21 15:26:08 [info] home.upgradeSchema1to2(): called
ene 21 15:26:08 juan-pc AdGuardHome[203323]: 2020/01/21 15:26:08 [info] home.upgradeSchema2to3(): called
ene 21 15:26:08 juan-pc AdGuardHome[203323]: 2020/01/21 15:26:08 [fatal] DNS configuration is not a map
ene 21 15:26:08 juan-pc systemd[1]: adguardhome.service: Main process exited, code=exited, status=1/FAILURE
-- Subject: Unit process exited
-- Defined-By: systemd
-- Support: https://lists.freedesktop.org/mailman/listinfo/systemd-devel
-- 
-- An ExecStart= process belonging to unit adguardhome.service has exited.
-- 
-- The process' exit code is 'exited' and its exit status is 1.
ene 21 15:26:08 juan-pc systemd[1]: adguardhome.service: Failed with result 'exit-code'.
-- Subject: Unit failed
-- Defined-By: systemd
-- Support: https://lists.freedesktop.org/mailman/listinfo/systemd-devel
-- 
-- The unit adguardhome.service has entered the 'failed' state with result 'exit-code'.
ene 21 15:26:08 juan-pc audit[1]: SERVICE_STOP pid=1 uid=0 auid=4294967295 ses=4294967295 msg='unit=adguardhome comm="systemd" exe="/usr/lib/systemd/>
...
@simonbcn commented on GitHub (Jan 21, 2020): @ameshkov I've tried to create a empty file with that name but it doesn't work: ``` ... ene 21 15:26:08 juan-pc audit[1]: SERVICE_START pid=1 uid=0 auid=4294967295 ses=4294967295 msg='unit=adguardhome comm="systemd" exe="/usr/lib/systemd> ene 21 15:26:08 juan-pc kernel: audit: type=1130 audit(1579616768.611:1971): pid=1 uid=0 auid=4294967295 ses=4294967295 msg='unit=adguardhome comm="s> ene 21 15:26:08 juan-pc AdGuardHome[203323]: 2020/01/21 15:26:08 [info] Service control action: run ene 21 15:26:08 juan-pc AdGuardHome[203323]: 2020/01/21 15:26:08 [info] AdGuard Home, version v0.100.9, channel release ene 21 15:26:08 juan-pc AdGuardHome[203323]: 2020/01/21 15:26:08 [info] AdGuard Home is running as a service ene 21 15:26:08 juan-pc AdGuardHome[203323]: 2020/01/21 15:26:08 [info] home.upgradeSchema0to1(): called ene 21 15:26:08 juan-pc AdGuardHome[203323]: 2020/01/21 15:26:08 [info] home.upgradeSchema1to2(): called ene 21 15:26:08 juan-pc AdGuardHome[203323]: 2020/01/21 15:26:08 [info] home.upgradeSchema2to3(): called ene 21 15:26:08 juan-pc AdGuardHome[203323]: 2020/01/21 15:26:08 [fatal] DNS configuration is not a map ene 21 15:26:08 juan-pc systemd[1]: adguardhome.service: Main process exited, code=exited, status=1/FAILURE -- Subject: Unit process exited -- Defined-By: systemd -- Support: https://lists.freedesktop.org/mailman/listinfo/systemd-devel -- -- An ExecStart= process belonging to unit adguardhome.service has exited. -- -- The process' exit code is 'exited' and its exit status is 1. ene 21 15:26:08 juan-pc systemd[1]: adguardhome.service: Failed with result 'exit-code'. -- Subject: Unit failed -- Defined-By: systemd -- Support: https://lists.freedesktop.org/mailman/listinfo/systemd-devel -- -- The unit adguardhome.service has entered the 'failed' state with result 'exit-code'. ene 21 15:26:08 juan-pc audit[1]: SERVICE_STOP pid=1 uid=0 auid=4294967295 ses=4294967295 msg='unit=adguardhome comm="systemd" exe="/usr/lib/systemd/> ... ```
Author
Owner

@szolin commented on GitHub (Jan 21, 2020):

@simonbcn You should exec AGH under root for the first time. After you finish the installation wizard you'll have a yaml config file. Now you can use this file even on a new PC - root user isn't required anymore.

@szolin commented on GitHub (Jan 21, 2020): @simonbcn You should exec AGH under root for the first time. After you finish the installation wizard you'll have a yaml config file. Now you can use this file even on a new PC - root user isn't required anymore.
Author
Owner

@simonbcn commented on GitHub (Jan 21, 2020):

@szolin but the installation wizard asks for user/password in "Authentication" and this is should be configured for the final user.
I think the start of Adguardhome is wrong because it doesn't check if it really has write access to save that configuration file before it wants to run as root always.

@simonbcn commented on GitHub (Jan 21, 2020): @szolin but the installation wizard asks for user/password in "_Authentication_" and this is should be configured for the final user. I think the start of _Adguardhome_ is wrong because it doesn't check if it really has write access to save that configuration file before it wants to run as root always.
Author
Owner

@szolin commented on GitHub (Jan 21, 2020):

has write access to save that configuration file

We don't do that indeed, but we don't have to. What's the use-case here?

this is should be configured for the final user

The user is AGH administrator - we currently assume that he has root access.

In other words, your use-case is not common. And allowing to start under a normal user will lead to problems for the most users during installation wizard steps - when they choose 53 and 80 ports. Can you maybe propose a good solution to this whole behaviour?

@szolin commented on GitHub (Jan 21, 2020): > has write access to save that configuration file We don't do that indeed, but we don't have to. What's the use-case here? > this is should be configured for the final user The user is AGH administrator - we currently assume that he has root access. In other words, your use-case is not common. And allowing to start under a normal user will lead to problems for the most users during installation wizard steps - when they choose 53 and 80 ports. Can you maybe propose a good solution to this whole behaviour?
Author
Owner

@simonbcn commented on GitHub (Jan 21, 2020):

Why AGH needs root rights?

@simonbcn commented on GitHub (Jan 21, 2020): Why AGH needs root rights?
Author
Owner

@szolin commented on GitHub (Jan 21, 2020):

Why AGH needs root rights?

And I've just explained that:

And allowing to start under a normal user will lead to problems for the most users during installation wizard steps - when they choose 53 and 80 ports

@szolin commented on GitHub (Jan 21, 2020): > Why AGH needs root rights? And I've just explained that: > And allowing to start under a normal user will lead to problems for the most users during installation wizard steps - when they choose 53 and 80 ports
Author
Owner

@simonbcn commented on GitHub (Jan 21, 2020):

So the problem is not that the configuration file does not exist, it is that it needs sudo rights to access those ports. Therefore your proposed solution (to provide a default AGH. config file) would not work.

@simonbcn commented on GitHub (Jan 21, 2020): So the problem is not that the configuration file does not exist, it is that it needs sudo rights to access those ports. Therefore your proposed solution (_to provide a default AGH. config file_) would not work.
Author
Owner

@szolin commented on GitHub (Jan 21, 2020):

Why not? It will if you set different port numbers there. You won't be able to listen on ports <1024 without special system configuration, as explained by the thread starter.

@szolin commented on GitHub (Jan 21, 2020): Why not? It will if you set different port numbers there. You won't be able to listen on ports <1024 without special system configuration, as explained by the thread starter.
Author
Owner

@simonbcn commented on GitHub (Jan 21, 2020):

That is the problem, this application assumes many things and that is why it calls for sudo rights but it should not be like that. At least, not if we want this program to be portable to any distro linux safely.
setcap CAP_NET_BIND_SERVICE is the solution if I don't want run this program as root. But AGH doesn't test anything before ask for sudo rights.
Perhaps it should do a test after the user configures the URLs and ports and if a problem occurs indicate to the user the need to run as root.
On the other hand, wouldn't it require root rights whenever the program is restarted to open the <1024 ports?

@simonbcn commented on GitHub (Jan 21, 2020): That is the problem, this application assumes many things and that is why it calls for sudo rights but it should not be like that. At least, not if we want this program to be portable to any distro linux safely. `setcap CAP_NET_BIND_SERVICE` is the solution if I don't want run this program as root. But AGH doesn't test anything before ask for sudo rights. Perhaps it should do a test after the user configures the URLs and ports and if a problem occurs indicate to the user the need to run as root. On the other hand, wouldn't it require root rights whenever the program is restarted to open the <1024 ports?
Author
Owner

@ameshkov commented on GitHub (Jan 21, 2020):

That is the problem, this application assumes many things and that is why it calls for sudo rights but it should not be like that. At least, not if we want this program to be portable to any distro linux safely.

That's why there is #723.

setcap CAP_NET_BIND_SERVICE is the solution if I don't want run this program as root. But AGH doesn't test anything before ask for sudo rights.

@simonbcn besides using ports 53 and 80, AGH also offers to set static IP and that also requires root access.

If we want to make AGH run without root, we'll have to move the initial setup logic to the package, i.e. come up with a bash script that will ask the very same questions (prompt for ports, admin user/password, offer to set static IP), then build the AdGuardHome.yaml, run setcap CAP_NET_BIND_SERVICE, and finally, run AGH itself.

I think that building AdGuardHome.yaml is the most problematic part of this. We could add a command-line option that will do this, something like this:
./AdGuardHome --init --web-port=80 --dns-port=53 --username=admin --password=admin

What do you think?

@ameshkov commented on GitHub (Jan 21, 2020): > That is the problem, this application assumes many things and that is why it calls for sudo rights but it should not be like that. At least, not if we want this program to be portable to any distro linux safely. That's why there is #723. > setcap CAP_NET_BIND_SERVICE is the solution if I don't want run this program as root. But AGH doesn't test anything before ask for sudo rights. @simonbcn besides using ports 53 and 80, AGH also offers to set static IP and that also requires root access. If we want to make AGH run without root, we'll have to move the initial setup logic to the package, i.e. come up with a bash script that will ask the very same questions (prompt for ports, admin user/password, offer to set static IP), then build the `AdGuardHome.yaml`, run `setcap CAP_NET_BIND_SERVICE`, and finally, run AGH itself. I think that building `AdGuardHome.yaml` is the most problematic part of this. We could add a command-line option that will do this, something like this: `./AdGuardHome --init --web-port=80 --dns-port=53 --username=admin --password=admin` What do you think?
Author
Owner

@simonbcn commented on GitHub (Jan 22, 2020):

The problem is not just the configuration file, it is all the files and folders that the initialization process creates with the root user:

...
ene 22 10:39:23 juan-pc AdGuardHome[31340]: 2020/01/22 10:39:23 [info] Service control action: run
ene 22 10:39:23 juan-pc AdGuardHome[31340]: 2020/01/22 10:39:23 [info] AdGuard Home, version v0.100.9, channel release
ene 22 10:39:23 juan-pc AdGuardHome[31340]: 2020/01/22 10:39:23 [info] AdGuard Home is running as a service
ene 22 10:39:23 juan-pc AdGuardHome[31340]: 2020/01/22 10:39:23 [error] Stats: open DB: /var/lib/adguardhome/data/stats.db: open /var/lib/adguardhome>
ene 22 10:39:23 juan-pc AdGuardHome[31340]: 2020/01/22 10:39:23 [fatal] Couldn't initialize statistics module
ene 22 10:39:23 juan-pc systemd[1]: adguardhome.service: Main process exited, code=exited, status=1/FAILURE
...
...
$ tree -pu /var/lib/adguardhome
/var/lib/adguardhome
├── [-rwxr-xr-x adguardhome]  AdGuardHome
├── [-rw-r--r-- adguardhome]  AdGuardHome.yaml
└── [drwxr-xr-x root    ]  data
    ├── [drwxr-xr-x root    ]  filters
    │   └── [-rw-r--r-- root    ]  1.txt
    ├── [-rw-r--r-- root    ]  sessions.db
    └── [-rw-r--r-- root    ]  stats.db
...
@simonbcn commented on GitHub (Jan 22, 2020): The problem is not just the configuration file, it is all the files and folders that the initialization process creates with the root user: ``` ... ene 22 10:39:23 juan-pc AdGuardHome[31340]: 2020/01/22 10:39:23 [info] Service control action: run ene 22 10:39:23 juan-pc AdGuardHome[31340]: 2020/01/22 10:39:23 [info] AdGuard Home, version v0.100.9, channel release ene 22 10:39:23 juan-pc AdGuardHome[31340]: 2020/01/22 10:39:23 [info] AdGuard Home is running as a service ene 22 10:39:23 juan-pc AdGuardHome[31340]: 2020/01/22 10:39:23 [error] Stats: open DB: /var/lib/adguardhome/data/stats.db: open /var/lib/adguardhome> ene 22 10:39:23 juan-pc AdGuardHome[31340]: 2020/01/22 10:39:23 [fatal] Couldn't initialize statistics module ene 22 10:39:23 juan-pc systemd[1]: adguardhome.service: Main process exited, code=exited, status=1/FAILURE ... ``` ``` ... $ tree -pu /var/lib/adguardhome /var/lib/adguardhome ├── [-rwxr-xr-x adguardhome] AdGuardHome ├── [-rw-r--r-- adguardhome] AdGuardHome.yaml └── [drwxr-xr-x root ] data ├── [drwxr-xr-x root ] filters │   └── [-rw-r--r-- root ] 1.txt ├── [-rw-r--r-- root ] sessions.db └── [-rw-r--r-- root ] stats.db ... ```
Author
Owner

@ameshkov commented on GitHub (Jan 22, 2020):

The problem is not just the configuration file, it is all the files and folders that the initialization process creates with the root user

The point is that you should not run AGH with root access at all.

You should instead place the AdGuardHome.yaml file near the binary and run AGH under the user you're intending to use after that.

@ameshkov commented on GitHub (Jan 22, 2020): > The problem is not just the configuration file, it is all the files and folders that the initialization process creates with the root user The point is that you should not run AGH with root access at all. You should instead place the `AdGuardHome.yaml` file near the binary and run AGH under the user you're intending to use after that.
Author
Owner

@simonbcn commented on GitHub (Jan 22, 2020):

The problem is in the application as it is designed now. I have to run it for the first time as root but that implies that all files/folders created at that time belong to the root user.
I cannot create a generic configuration file for any user who installs this application. That has to be configured by everyone when they first run it.

@simonbcn commented on GitHub (Jan 22, 2020): The problem is in the application as it is designed now. I have to run it for the first time as root but that implies that all files/folders created at that time belong to the root user. I cannot create a generic configuration file for any user who installs this application. That has to be configured by everyone when they first run it.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/AdGuardHome#1104
No description provided.