Pihole is falling with failed to create listening socket

Hello,

I am trying to run pihole on free-tier but I am getting permission denied on port 53,

2022-02-12T15:26:22.000 [info] Using IPv4 and IPv6
2022-02-12T15:26:22.000 [info] ::: setup_blocklists now setting default blocklists up:
2022-02-12T15:26:22.000 [info] ::: TIP: Use a docker volume for /etc/pihole/adlists.list if you want to customize for first boot
2022-02-12T15:26:22.000 [info] ::: Blocklists (/etc/pihole/adlists.list) now set to:
2022-02-12T15:26:22.000 [info] https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts
2022-02-12T15:26:22.000 [info] dnsmasq: failed to create li
2022-02-12T15:26:22.000 [info] dnsmasq: failed to create li↩︎tening socket for port 53: Permission denied
2022-02-12T15:26:22.000 [info] [cont-init.d] 20-start.sh: exited 1.
2022-02-12T15:26:22.000 [info] [cont-finish.d] executing container finish scripts...
2022-02-12T15:26:22.000 [info] [cont-finish.d] done.
2022-02-12T15:26:22.000 [info] [s6-finish] waiting for services.
2022-02-12T15:26:22.000 [info] Reaped child process with pid: 584, exit code: 0
2022-02-12T15:26:22.000 [info] Reaped child process with pid: 599, exit code: 0
2022-02-12T15:26:22.000 [info] Reaped child process with pid: 614, exit code: 0
2022-02-12T15:26:22.000 [info] Reaped child process with pid: 622, exit code: 0
2022-02-12T15:26:22.000 [info] Reaped child process with pid: 651, exit code: 0
2022-02-12T15:26:22.000 [info] Reaped child process with pid: 680, exit code: 0
2022-02-12T15:26:22.000 [info] Reaped child process with pid: 688, exit code: 0
2022-02-12T15:26:22.000 [info] Reaped child process with pid: 696, exit code: 0
2022-02-12T15:26:22.000 [info] Reaped child process with pid: 865, exit code: 0
2022-02-12T15:26:22.000 [info] [s6-finish] sending all processes the TERM signal.
2022-02-12T15:26:22.000 [info] hallpass exited, pid: 509, status: signal: 1
2022-02-12T15:26:22.000 [info] hallpass exited, pid: 870, status: signal: 15

Here is the fly.toml

app = "some-name"

kill_signal = "SIGINT"
kill_timeout = 5

[env]

[experimental]
  allowed_public_ports = []
  auto_rollback = true

[[services]]
  http_checks = []
  internal_port = 80
  protocol = "tcp"
  script_checks = []

  [services.concurrency]
    hard_limit = 25
    soft_limit = 20
    type = "connections"

  [[services.ports]]
    handlers = ["http"]
    port = 80

  [[services.ports]]
    handlers = ["tls", "http"]
    port = 443

  [[services.tcp_checks]]
    grace_period = "1s"
    interval = "15s"
    restart_limit = 6
    timeout = "2s"

[[services]]
  internal_port = 53
  protocol = "udp"

  [[services.ports]]
    port = "53"

Dockerfile

FROM pihole/pihole:latest
ENV INTERFACE eth0
ENV DNSMASQ_LISTENING ALL

Command to run it flyctl launch also I have tried with flyctl deploy

I am new to fly.io :slight_smile:

Thank you in advance!

That’s weird, I wonder if something changed in the pihole image.

Try adding this to your Dockerfile:

ENV DNSMASQ_USER=root
2 Likes

Hello @kurt,

You are awesome.

Thank you very much for your help!

It worked after mentioning user as root.

2 Likes

docker-pihole 2022.1 defaults to running FTL (dnsmasq) as a non-root user, and adds some capabilities to the pihole-FTL executable (among other things, so pihole can create a listening socket on port 53!)

From what I can tell, the way they add those capabilities is compatible with running in Docker, but not compatible with running in a lightweight VM (the way fly.io does).

An alternative to kurt’s solution (“run as root”) is to change pihole-docker’s startup code to fix the permissions to work in fly. I have this in my Dockerfile, and it resolved the issue for me on fly. (I’m also dropping some other caps because I’m not using pihole for DHCP):

# Add 'permitted' cap to setcap command (setcap ...+ei to setcap ...+eip) and
# drop some of the permissions (CAP_NET_RAW, CAP_NET_ADMIN)
RUN set -ex \
    && sed -i -E -e 's/(setcap.*\+ei)([^p])/\1p\2/' \
                 -e 's/CAP_NET_(RAW|ADMIN),?//g' \
           /bash_functions.sh
1 Like

docker-pihole 2022.4.1 changes the way it handles capabilities even further, but is still not compatible with running on fly.io without tweaks (either running pihole-FTL as root, or different hacks to /bash_functions.sh).

The pihole-FTL service will be in a restart loop:

2022-04-02T19:05:59Z [info]Starting pihole-FTL (no-daemon) as pihole
2022-04-02T19:05:59Z [info]Stopping pihole-FTL
2022-04-02T19:05:59Z [info]pihole-FTL: no process found

(/var/log/pihole-FTL will also show an error along the lines of “failed to create listening socket for port 53 : Permission denied”)

I’ve amended my previous Dockerfile modifications to the following:

# Override detection with hardcoded list of caps to provide to the pihole-FTL
# binary -- dropping some not needed (CAP_NET_RAW and CAP_NET_ADMIN). Fly.io
# doesn't run in docker, so the "detect based on current caps" logic won't
# work. The "capsh --print" added is just for debugging.
#
# https://github.com/pi-hole/docker-pi-hole/blob/70bad9f08f2651d686ae0e4ff374208265ad5ad9/bash_functions.sh#L10-L18
# (note the 'setcap' invocation trims the first character off the string,
# hence the leading ',')
RUN set -ex \
    && sed -i -E -e 's/^(\s+)(if \[\[ \$\{CAP_STR\} \]\]; then)/\1capsh --print\n\1CAP_STR=",CAP_CHOWN,CAP_NET_BIND_SERVICE,CAP_SYS_NICE"\n\2/' \
           /bash_functions.sh
1 Like