AdguardTeam / AdGuardHome

Network-wide ads & trackers blocking DNS server
https://adguard.com/adguard-home.html
GNU General Public License v3.0
24.77k stars 1.79k forks source link

Faulty error detection, leads to crash: "[fatal] This is the first launch of AdGuard Home. You must run it as Administrator." #4714

Open yscialom opened 2 years ago

yscialom commented 2 years ago

Issue Details

Context

Description

Under docker, when running AdGuardHome as a non-root user, AdGuardHome displays the following and exits

2022/07/06 15:46:36.407393 [info] AdGuard Home, version v0.107.7
2022/07/06 15:46:36.408149 [info] This is the first time AdGuard Home is launched
2022/07/06 15:46:36.408611 [info] Checking if AdGuard Home has necessary permissions
2022/07/06 15:46:36.409062 [fatal] This is the first launch of AdGuard Home. You must run it as Administrator.

Expected Behavior

Under docker, when running AdGuardHome as a non-root user with the NET_BIND_SERVICE capability granted, AdGuardHome starts normally.

How to reproduce

Edit AdGuardHome's Dockerfile (See this draft PR on yscialom/AdGuardHome), build and run with docker run -e PUID=$(id -un) ....

Preliminary Analysis

Non-root user can bind processes to ports <1024

This can be checked by running the following commands inside the docker container

$ id
uid=100(adguardhome) gid=101(adguardhome) groups=101(adguardhome),101(adguardhome)

$ getcap ../AdGuardHome
../AdGuardHome cap_net_bind_service=eip

$ nc -vlp80
listening on [::]:80 ...

Source Code

This error "This is the first launch of AdGuard Home. You must run it as Administrator." can be found in internal/home/home.go:520:

    if ok, err := aghnet.CanBindPrivilegedPorts(); !ok || err != nil {
        log.Fatal("This is the first launch of AdGuard Home. You must run it as Administrator.")
    }

with CanBindPrivilegedPorts defined in internal/aghnet/net_linux.go:24:

func canBindPrivilegedPorts() (can bool, err error) {
    cnbs, err := unix.PrctlRetInt(
        unix.PR_CAP_AMBIENT,
        unix.PR_CAP_AMBIENT_IS_SET,
        unix.CAP_NET_BIND_SERVICE,
        0,
        0,
    )
    // Don't check the error because it's always nil on Linux.
    adm, _ := aghos.HaveAdminRights()

    return cnbs == 1 || adm, err
}

with unix.PrctlRetInt being a binding on linux' system call prctl(2) reading:

PR_CAP_AMBIENT_IS_SET
                    The prctl() call returns 1 if the capability in
                    arg3 is in the ambient set and 0 if it is not.

Additional tests are necessary to determine if unix.PrctlRetInt is bugged, badly called, or whatever. But one can be convinced that, in this scenario, AdGuardHome should be able to open port 53 and should not exist with an error.

Why this issue matters

I discovered this issue while preparing a pull request to allow the docker flavour of AdGuardHome to run as a non-root user. This is indeed beneficial for two reasons:

Additional Information

Result of ./AdGuardHome -v --version

AdGuard Home
Version: v0.107.7
Channel: release
Go version: go1.17.9
Commit time: 2022-06-06 15:10:40 +0000 UTC
GOOS: linux
GOARCH: amd64
Race: false
Dependencies:
    github.com/AdguardTeam/dnsproxy@v0.43.1 (sum: h1:E777KfQAi+VurOoWEdGQ5iqjSOOAzzbTfLOEzj8heCs=)
    github.com/AdguardTeam/golibs@v0.10.8 (sum: h1:diU9gP9qG1qeLbAkzIwfUerpHSqzR6zaBgzvRMR/m6Q=)
    github.com/AdguardTeam/urlfilter@v0.16.0 (sum: h1:IO29m+ZyQuuOnPLTzHuXj35V1DZOp1Dcryl576P2syg=)
    github.com/NYTimes/gziphandler@v1.1.1 (sum: h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I=)
    github.com/aead/chacha20@v0.0.0-20180709150244-8b13a72661da (sum: h1:KjTM2ks9d14ZYCvmHS9iAKVt9AyzRSqNU1qabPih5BY=)
    github.com/aead/poly1305@v0.0.0-20180717145839-3fee0db0b635 (sum: h1:52m0LGchQBBVqJRyYYufQuIbVqRawmubW3OFGqK1ekw=)
    github.com/ameshkov/dnscrypt/v2@v2.2.3 (sum: h1:X9UP5AHtwp46Ji+sGFfF/1Is6OPI/SjxLqhKpx0P5UI=)
    github.com/ameshkov/dnsstamps@v1.0.3 (sum: h1:Srzik+J9mivH1alRACTbys2xOxs0lRH9qnTA7Y1OYVo=)
    github.com/beefsack/go-rate@v0.0.0-20220214233405-116f4ca011a0 (sum: h1:0b2vaepXIfMsG++IsjHiI2p4bxALD1Y2nQKGMR5zDQM=)
    github.com/cheekybits/genny@v1.0.0 (sum: h1:uGGa4nei+j20rOSeDeP5Of12XVm7TGUd4dJA9RDitfE=)
    github.com/digineo/go-ipset/v2@v2.2.1 (sum: h1:k6skY+0fMqeUjjeWO/m5OuWPSZUAn7AucHMnQ1MX77g=)
    github.com/fsnotify/fsnotify@v1.5.4 (sum: h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI=)
    github.com/go-ping/ping@v0.0.0-20211130115550-779d1e919534 (sum: h1:dhy9OQKGBh4zVXbjwbxxHjRxMJtLXj3zfgpBYQaR4Q4=)
    github.com/google/go-cmp@v0.5.7 (sum: h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o=)
    github.com/google/gopacket@v1.1.19 (sum: h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8=)
    github.com/google/renameio@v1.0.1 (sum: h1:Lh/jXZmvZxb0BBeSY5VKEfidcbcbenKjZFzM/q0fSeU=)
    github.com/google/uuid@v1.3.0 (sum: h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=)
    github.com/insomniacslk/dhcp@v0.0.0-20220405050111-12fbdcb11b41 (sum: h1:Yg3n3AI7GoHnWt7dyjsLPU+TEuZfPAg0OdiA3MJUV6I=)
    github.com/josharian/native@v1.0.0 (sum: h1:Ts/E8zCSEsG17dUqv7joXJFybuMLjQfWE04tsBODTxk=)
    github.com/kardianos/service@v1.2.1 (sum: h1:AYndMsehS+ywIS6RB9KOlcXzteWUzxgMgBymJD7+BYk=)
    github.com/lucas-clemente/quic-go@v0.27.1 (sum: h1:sOw+4kFSVrdWOYmUjufQ9GBVPqZ+tu+jMtXxXNmRJyk=)
    github.com/marten-seemann/qtls-go1-17@v0.1.1 (sum: h1:DQjHPq+aOzUeh9/lixAGunn6rIOQyWChPSI4+hgW7jc=)
    github.com/mdlayher/ethernet@v0.0.0-20220221185849-529eae5b6118 (sum: h1:2oDp6OOhLxQ9JBoUuysVz9UZ9uI6oLUbvAZu0x8o+vE=)
    github.com/mdlayher/netlink@v1.6.0 (sum: h1:rOHX5yl7qnlpiVkFWoqccueppMtXzeziFjWAjLg6sz0=)
    github.com/mdlayher/raw@v0.0.0-20211126142749-4eae47f3d54b (sum: h1:MHcTarUMC4sFA7eiyR8IEJ6j2PgmgXR+B9X2IIMjh7A=)
    github.com/mdlayher/socket@v0.2.3 (sum: h1:XZA2X2TjdOwNoNPVPclRCURoX/hokBY8nkTmRZFEheM=)
    github.com/miekg/dns@v1.1.49 (sum: h1:qe0mQU3Z/XpFeE+AEBo2rqaS1IPBJ3anmqZ4XiZJVG8=)
    github.com/patrickmn/go-cache@v2.1.0+incompatible (sum: h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=)
    github.com/pkg/errors@v0.9.1 (sum: h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=)
    github.com/ti-mo/netfilter@v0.4.0 (sum: h1:rTN1nBYULDmMfDeBHZpKuNKX/bWEXQUhe02a/10orzg=)
    github.com/u-root/uio@v0.0.0-20220204230159-dac05f7d2cb4 (sum: h1:hl6sK6aFgTLISijk6xIzeqnPzQcsLqqvL6vEfTPinME=)
    go.etcd.io/bbolt@v1.3.6 (sum: h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU=)
    golang.org/x/crypto@v0.0.0-20220411220226-7b82a4e95df4 (sum: h1:kUhD7nTDoI3fVd9G4ORWrbV5NY0liEs/Jg2pv5f+bBA=)
    golang.org/x/net@v0.0.0-20220425223048-2871e0cb64e4 (sum: h1:HVyaeDAYux4pnY+D/SiwmLOR36ewZ4iGQIIrtnuCjFA=)
    golang.org/x/sync@v0.0.0-20210220032951-036812b2e83c (sum: h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=)
    golang.org/x/sys@v0.0.0-20220422013727-9388b58f7150 (sum: h1:xHms4gcpe1YE7A3yIllJXP16CMAGuqwO2lX1mTyyRRc=)
    golang.org/x/text@v0.3.7 (sum: h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=)
    gopkg.in/natefinch/lumberjack.v2@v2.0.0 (sum: h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=)
    gopkg.in/yaml.v2@v2.4.0 (sum: h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=)
    howett.net/plist@v1.0.0 (sum: h1:7CrbWYbPPO/PyNy38b2EB/+gYbjCe2DXBxgtOOZbSQM=)
yscialom commented 2 years ago

Related: https://github.com/AdguardTeam/AdGuardHome/issues/4681 Yet different: in issue 4681 AdGuardHome is (or seams to be) run as root, making those issues completely different.

EugeneOne1 commented 1 year ago

@yscialom, hello. Unfortunately, we can't reproduce the issue, could you please share some setup details? How exactly do you run the AdGuard Home as non-root user? Do you login to the container as unpriveleged user or use some custom Dockerfile?

yscialom commented 1 year ago

@EugeneOne1 I had to tweak the Dockerfile: https://github.com/yscialom/AdGuardHome/pull/1/files This is my ultimate goal, but I need this issue to be resolved beforehand.

yscialom commented 1 year ago

(Issue description updated to better explain how to reproduce)

danielwdlh commented 11 months ago

I have this problem as well, trying to run it inside a Debian LXC container.

root@adguard1:/var/log/AdGuardHome# cat /etc/systemd/system/AdGuardHome.service 
[Unit]
Description=AdGuard Home: Network-level blocker
ConditionFileIsExecutable=/opt/AdGuardHome/AdGuardHome
After=syslog.target network-online.target

[Service]
StartLimitInterval=5
StartLimitBurst=10
ExecStart=/opt/AdGuardHome/AdGuardHome "-s" "run"
WorkingDirectory=/opt/AdGuardHome
StandardOutput=file:/var/log/AdGuardHome/AdGuardHome.out
StandardError=file:/var/log/AdGuardHome/AdGuardHome.err
Restart=always
RestartSec=10
EnvironmentFile=-/etc/sysconfig/AdGuardHome
User=adguard
Group=adguard

[Install]
WantedBy=multi-user.target
root@adguard1:/var/log/AdGuardHome# ls -la .
total 14
drwxr-xr-x 2 adguard adguard   4 Oct 31 18:35 .
drwxr-xr-x 7 root    root     15 Oct 31 18:35 ..
-rw-r--r-- 1 root    root    530 Oct 31 18:41 AdGuardHome.err
-rw-r--r-- 1 root    root      0 Oct 31 18:35 AdGuardHome.out
root@adguard1:/var/log/AdGuardHome# ls -la /opt/AdGuardHome
total 15072
drwxrwxrwx 2 adguard adguard        7 Oct 18 15:19 .
drwxr-xr-x 3 root    root           3 Oct 31 18:30 ..
-rwxrwxrwx 1 adguard adguard 29188096 Oct 18 15:19 AdGuardHome
-rw-rw-rw- 1 adguard adguard      587 Oct 18 15:19 AdGuardHome.sig
-rw-r--r-- 1 adguard adguard    98824 Oct 18 15:19 CHANGELOG.md
-rw-r--r-- 1 adguard adguard    35149 Oct 18 15:19 LICENSE.txt
-rw-r--r-- 1 adguard adguard    21918 Oct 18 15:19 README.md
root@adguard1:/var/log/AdGuardHome# getcap /opt/AdGuardHome/AdGuardHome
/opt/AdGuardHome/AdGuardHome cap_net_bind_service,cap_net_raw=eip
root@adguard1:/var/log/AdGuardHome# cat AdGuardHome.err
2023/10/31 18:43:44 [info] AdGuard Home, version v0.107.40
2023/10/31 18:43:44 [info] service: control action: run
2023/10/31 18:43:44.765371 [info] AdGuard Home, version v0.107.40
2023/10/31 18:43:44.765382 [info] AdGuard Home is running as a service
2023/10/31 18:43:44.765394 [info] This is the first time AdGuard Home is launched
2023/10/31 18:43:44.765399 [info] Checking if AdGuard Home has necessary permissions
2023/10/31 18:43:44.765408 [fatal] This is the first launch of AdGuard Home. You must run it as Administrator.
root@adguard1:/var/log/AdGuardHome#

I was able to work around this issue by

It's now running happily on port 80/53.

root@adguard1:/var/log/AdGuardHome# nslookup dns.google 127.0.0.1
Server:         127.0.0.1
Address:        127.0.0.1#53

Non-authoritative answer:
Name:   dns.google
Address: 8.8.8.8
Name:   dns.google
Address: 8.8.4.4
Name:   dns.google
Address: 2001:4860:4860::8844
Name:   dns.google
Address: 2001:4860:4860::8888

root@adguard1:/var/log/AdGuardHome#

image image

QEDeD commented 7 months ago

Also hitting this issue it seems. Any progress or something I can do to help the issue along? :)

yscialom commented 6 months ago

Hello @QEDeD,

Could you please check the PR #4728 and see if there's something you can help with?