LouisBrunner / avahi2dns

Small DNS server which interface with avahi (perfect for Alpine Linux and musl)
MIT License
20 stars 4 forks source link

avahi2dns timeout #8

Open oliv3r opened 1 month ago

oliv3r commented 1 month ago

I have a docker container, where I install only avahi2dns and avahi itself.

While there's a sleep during startup needed due to #7 both services start up.

However avahi2dns complains about timeout, which makes me think it failed to connect to the dbus service.

I wonder if the connection to the system bus is properly error handled. In my container, the socket is mounted and available under /run/dbus/system_bus_socket and avahi is happily using it (this is actually a volume mount so that multiple containers can make use of the same socket, including the host itself. For all other services, this is working fine.

avahi-1  | Registering new address record for 127.0.0.1 on lo.IPv4.
avahi-1  | Server startup complete. Host name is riley.local. Local service cookie is 2198944653.
avahi-1  | Service "riley" (/etc/avahi/services/time.service) successfully established.
avahi-1  | Service "riley" (/etc/avahi/services/ssh.service) successfully established.
avahi-1  | Service "riley" (/etc/avahi/services/sftp-ssh.service) successfully established.
avahi-1  | + exec avahi2dns --addr 0.0.0.0 --debug
avahi-1  | time="2024-07-17T14:40:37Z" level=debug msg="config parsed" func=main.parseArgs file="github.com/LouisBrunner/avahi2dns/config.go:32" config="&{[home internal intranet lan local p
rivate test] 0.0.0.0 53 true}"
avahi-1  | time="2024-07-17T14:40:37Z" level=debug msg="connection to dbus..." func=main.runServer file="github.com/LouisBrunner/avahi2dns/server.go:14"
avahi-1  | time="2024-07-17T14:40:37Z" level=debug msg="connection to avahi through dbus..." func=main.runServer file="github.com/LouisBrunner/avahi2dns/server.go:21"
avahi-1  | time="2024-07-17T14:40:37Z" level=debug msg="adding dns handler" func=main.runServer file="github.com/LouisBrunner/avahi2dns/server.go:37" domain=home
avahi-1  | time="2024-07-17T14:40:37Z" level=debug msg="adding dns handler" func=main.runServer file="github.com/LouisBrunner/avahi2dns/server.go:37" domain=internal
avahi-1  | time="2024-07-17T14:40:37Z" level=debug msg="adding dns handler" func=main.runServer file="github.com/LouisBrunner/avahi2dns/server.go:37" domain=intranet
avahi-1  | time="2024-07-17T14:40:37Z" level=debug msg="adding dns handler" func=main.runServer file="github.com/LouisBrunner/avahi2dns/server.go:37" domain=lan
avahi-1  | time="2024-07-17T14:40:37Z" level=debug msg="adding dns handler" func=main.runServer file="github.com/LouisBrunner/avahi2dns/server.go:37" domain=local
avahi-1  | time="2024-07-17T14:40:37Z" level=debug msg="adding dns handler" func=main.runServer file="github.com/LouisBrunner/avahi2dns/server.go:37" domain=private
avahi-1  | time="2024-07-17T14:40:37Z" level=debug msg="adding dns handler" func=main.runServer file="github.com/LouisBrunner/avahi2dns/server.go:37" domain=test
avahi-1  | time="2024-07-17T14:40:37Z" level=info msg="starting DNS server" func=main.runServer file="github.com/LouisBrunner/avahi2dns/server.go:46" addr="0.0.0.0:53"
avahi-1  | time="2024-07-17T14:40:56Z" level=debug msg="received request" func=main.runServer.func1 file="github.com/LouisBrunner/avahi2dns/server.go:30" component=main request=";; opcode: QUERY, status: NOERROR, id: 65327\n;; flags: rd ad; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1\n\n;; QUESTION SECTION:\n;riley.local.\tIN\t A\n\n;; ADDITIONAL SECTION:\n\n;; OPT PSEUDOSECTION:\n; EDNS: version 0; flags: ; udp: 1232\n; COOKIE: 273018f7c8ef6907\n"
avahi-1  | time="2024-07-17T14:40:56Z" level=info msg="forwarding query to avahi" func=main.avahiToRecord file="github.com/LouisBrunner/avahi2dns/query.go:52" component=main name=riley.local. protocol=0 type=A

avahi-1  | time="2024-07-17T14:41:01Z" level=error msg="avahi A lookup failed, skipping query..." func=main.createDNSReply file="github.com/LouisBrunner/avahi2dns/query.go:22" component=main error="avahi resolve failure: Timeout reached"
avahi-1  | time="2024-07-17T14:41:01Z" level=debug msg="sending reply" func=main.runServer.func1 file="github.com/LouisBrunner/avahi2dns/server.go:32" component=main reply=";; opcode: QUERY, status: NOERROR, id: 0\n;; flags:; QUERY: 0, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0\n"
LouisBrunner commented 1 month ago

Continuing the discussion from #7. It seems like avahi2dns is running correctly and that individual requests are failing if Avahi isn't running when a DNS request comes. Is that correct?

Or is avahi2dns also failing to start if Avahi isn't running? (in which case please include logs).

oliv3r commented 1 month ago

I can disable avahi to show the difference

avahi-1  | time="2024-07-17T15:36:12Z" level=debug msg="config parsed" func=main.parseArgs file="github.com/LouisBrunner/avahi2dns/config.go:32" config="&{[home internal intranet lan local private test] 0.0.0.0 53 true}"
avahi-1  | time="2024-07-17T15:36:12Z" level=debug msg="connection to dbus..." func=main.runServer file="github.com/LouisBrunner/avahi2dns/server.go:14"
avahi-1  | time="2024-07-17T15:36:12Z" level=debug msg="connection to avahi through dbus..." func=main.runServer file="github.com/LouisBrunner/avahi2dns/server.go:21"
avahi-1  | time="2024-07-17T15:36:12Z" level=debug msg="adding dns handler" func=main.runServer file="github.com/LouisBrunner/avahi2dns/server.go:37" domain=home
avahi-1  | time="2024-07-17T15:36:12Z" level=debug msg="adding dns handler" func=main.runServer file="github.com/LouisBrunner/avahi2dns/server.go:37" domain=internal
avahi-1  | time="2024-07-17T15:36:12Z" level=debug msg="adding dns handler" func=main.runServer file="github.com/LouisBrunner/avahi2dns/server.go:37" domain=intranet
avahi-1  | time="2024-07-17T15:36:12Z" level=debug msg="adding dns handler" func=main.runServer file="github.com/LouisBrunner/avahi2dns/server.go:37" domain=lan
avahi-1  | time="2024-07-17T15:36:12Z" level=debug msg="adding dns handler" func=main.runServer file="github.com/LouisBrunner/avahi2dns/server.go:37" domain=local
avahi-1  | time="2024-07-17T15:36:12Z" level=debug msg="adding dns handler" func=main.runServer file="github.com/LouisBrunner/avahi2dns/server.go:37" domain=private
avahi-1  | time="2024-07-17T15:36:12Z" level=debug msg="adding dns handler" func=main.runServer file="github.com/LouisBrunner/avahi2dns/server.go:37" domain=test
avahi-1  | time="2024-07-17T15:36:12Z" level=info msg="starting DNS server" func=main.runServer file="github.com/LouisBrunner/avahi2dns/server.go:46" addr="0.0.0.0:53"
avahi-1  | time="2024-07-17T15:36:26Z" level=debug msg="received request" func=main.runServer.func1 file="github.com/LouisBrunner/avahi2dns/server.go:30" component=main request=";; opcode: QUERY, status: NOERROR, id: 25899\n;; flags: rd ad; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1\n\n;; QUESTION SECTION:\n;riley.local.\tIN\t A\n\n;; ADDITIONAL SECTION:\n\n;; OPT PSEUDOSECTION:\n; EDNS: version 0; flags: ; udp: 1232\n; COOKIE: 949f88bd2f588f91\n"
avahi-1  | time="2024-07-17T15:36:26Z" level=info msg="forwarding query to avahi" func=main.avahiToRecord file="github.com/LouisBrunner/avahi2dns/query.go:52" component=main name=riley.local. protocol=0 type=A
avahi-1  | time="2024-07-17T15:36:26Z" level=error msg="avahi A lookup failed, skipping query..." func=main.createDNSReply file="github.com/LouisBrunner/avahi2dns/query.go:22" component=main error="avahi resolve failure: The name org.freedesktop.Avahi was not provided by any .service files"
avahi-1  | time="2024-07-17T15:36:26Z" level=debug msg="sending reply" func=main.runServer.func1 file="github.com/LouisBrunner/avahi2dns/server.go:32" component=main reply=";; opcode: QUERY, status: NOERROR, id: 0\n;; flags:; QUERY: 0, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0\n"

same container, just with an echo added infront of my avahi startup line; so avahi is not started. This time we do see a avahi resolve failure, so that is good?

LouisBrunner commented 1 month ago

OK, so avahi2dns is running fine with individual request failing.

A few DNS queries failing when Avahi isn't running doesn't seem like a huge deal and fairly tolerant? I guess we could a retry or two, but it's unclear if that might help your case?

Both this project and the one which connects to Avahi (https://github.com/holoplot/go-avahi) use https://github.com/godbus/dbus and I haven't found any way to configure a timeout or retry.

oliv3r commented 1 month ago

But I haven't found a single query to go through yet; it always times out :( The timeouts feel quite long too, like a few seconds? Since this is running on a fast server (not a raspberry pi) and this is within its own docker container, there shouldn't be any performance issue?

And looking at the code, it does look like all error handling is in place; however actually getting 'something' from avahi is failing it seems.

here's my compose file

volumes:
  avahi:

services:
  avahi:
    build:
      dockerfile_inline: |
        FROM docker.io/library/alpine:latest
        RUN apk add --no-cache --repository="$$(sed '1 s|^\(.*alpine/\)\(.*\)$$|\1edge/testing|;2,$$d' "/etc/apk/repositories")" \
                'avahi' 'avahi2dns' && \
            printf '#!/bin/sh\n \
                set -eu\n \
                if [ "$${#}" -gt 0 ] && [ "$${1#-}" = "$${1}" ] && command -v "$${1}"; then\n \
                    exec "$${@}"\n \
                else\n \
                    if [ -f "/run/avahi-daemon/pid" ]; then\n \
                        echo "Found stale PID from previous run, removing"\n \
                        rm "/run/avahi-daemon/pid"\n \
                    fi\n \
                    avahi-daemon --file=/etc/avahi-daemon.conf --no-drop-root &\n \
                    echo "Avoiding connection race. See github.com/LouisBrunner/avahi2dns#7" \n \
                    sleep 10\n \
                    exec avahi2dns --addr "0.0.0.0" --debug\n \
                fi\n \
                exit 0\n' > '/init' && \
            chmod +x /init
        ENTRYPOINT [ "/init" ]
    init: true
    cap_add:
      - net_bind_service
      - setgid
      - setuid
      - sys_chroot
    cap_drop:
      - all
    depends_on:
      - dbus
    env_file:
      - common.env
    volumes:
      - dbus:/run/dbus:rw
      - /run/avahi-daemon:/run/avahi-daemon:rw
      - ./avahi/services:/etc/avahi/services:ro
      - ./avahi/avahi-daemon.conf:/etc/avahi-daemon.conf:ro
    network_mode: host
    restart: unless-stopped
oliv3r commented 1 month ago

@LouisBrunner any thoughts or insights how I could start resolving local domains? With zero successful resolvings I wonder what could possibly be going on; seems more like a bug/misconfiguration then a timeout issue ...

LouisBrunner commented 1 month ago

It looks like it could be a configuration issue, yeah. Could you try using something like avahi-browse or dns-sd to query Avahi directly and check if it's running? If it is then maybe use one of the DBus utility (or logging? I don't have enough experience with it to help) to make sure that Avahi is interacting with it?