Skip to content

systemd socket activation fails on IPv6 #741

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
linuxgemini opened this issue Aug 21, 2022 · 6 comments
Closed

systemd socket activation fails on IPv6 #741

linuxgemini opened this issue Aug 21, 2022 · 6 comments

Comments

@linuxgemini
Copy link

Describe the bug
When unbound is run with systemd's socket activation (see additional information below for an example socket file); unless you set specific IPv4 addresses to listen (like 127.0.0.1:553) on the socket file and set do-ip6: no (also set port: 553 for this example) on unbound.conf, you will get these two error lines:

error: setsockopt(..., IPV6_V6ONLY, ...) failed: Invalid argument
fatal error: could not open ports

To reproduce
Steps to reproduce the behavior:

  1. Compile and install unbound with systemd support (--enable-systemd).
  2. Copy the built contrib/unbound.service from source to /usr/lib/systemd/system/.
  3. Install the systemd socket file below to /usr/lib/systemd/system/.
  4. Configure /usr/local/etc/unbound/unbound.conf like below.
  5. Reload systemd daemon. (systemctl daemon-reload)
  6. Start the unbound socket. (systemctl start unbound.socket)
  7. Start the unbound service. (systemctl start unbound.service)
  8. Check service log. (Assuming journald is installed, journalctl -xeu unbound)

Expected behavior
Unbound starting.

System:

  • Unbound version: 1.16.2
  • OS: Debian 11 (bullseye)
  • unbound -V output:
    Version 1.16.2
    
    Configure line: --enable-systemd --enable-subnet --enable-tfo-client --enable-tfo-server --enable-dnstap --enable-dnscrypt --enable-cachedb --enable-ipsecmod --enable-ipset --with-pthreads --with-dynlibmodule --with-pyunbound --with-pythonmodule --with-libevent=/usr --with-libexpat=/usr --with-libhiredis=/usr --with-libnghttp2=/usr --with-protobuf-c=/usr --with-libsodium=/usr --with-libmnl=/usr
    Linked libs: libevent 2.1.12-stable (it uses epoll), OpenSSL 1.1.1n  15 Mar 2022
    Linked modules: dns64 python dynlib cachedb ipsecmod subnetcache ipset respip validator iterator
    DNSCrypt feature available
    TCP Fastopen feature available
    
    BSD licensed, see LICENSE in source package for details.
    Report bugs to unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues
    

Additional information

File /usr/lib/systemd/system/unbound.socket:

[Socket]
BindIPv6Only=both

ListenDatagram=553
ListenStream=553

[Install]
WantedBy=sockets.target

File /usr/local/etc/unbound/unbound.conf:

server:
  verbosity: 1
  port: 553

  use-systemd: yes

  do-daemonize: no

  username: ""

python:

dynlib:

remote-control:
  control-enable: no
@wcawijngaards
Copy link
Member

It turns out that unbound by default wants to create sockets with the ipv6-only option applied, and creates separate sockets for IP v4 and IPv6. This is because separate sockets was considered safer, so this is the default. But you specify the ipv6 only setting in the systemd config file, and then unbound tries to set its own, different default opinion. This is what causes the error printout, I think.

It is fixed by having unbound not set the V6ONLY flag on IPv6 sockets for sockets from systemd. That can be controlled with the systemd BindIPv6Only setting in the systemd.socket file. That should fix the issue, thank you for reporting it.

@ilteriseroglu-ty
Copy link

ilteriseroglu-ty commented Aug 22, 2022

Thank you for the incredibly fast fix! Will report back after testing the latest master.

But you specify the ipv6 only setting in the systemd config file [...]

The funny thing is, that option (BindIPv6Only=both) is actually the default (at most distros) because /proc/sys/net/ipv6/bindv6only is set to 0 and if the socket option is not set, the default will read the procfile.

Edit: whoops. replied with my corporate account, anyway.

@linuxgemini
Copy link
Author

Okay so interestingly enough, this time it can't create IPv4 only sockets (which isn't really an issue since the ::ffff:IPv4-address translation layer works when you disable do-ip4: no)

unbound[759011]: [1661159580] unbound[759011:0] error: systemd sd_listen_fds(): no such socket for 127.0.0.1 port 553 (len 16)

@wcawijngaards
Copy link
Member

Perhaps configuration with interface: ::1 would solve this since you want unbound to open only an IPv6 socket?

@linuxgemini
Copy link
Author

That'd also work, yeah.

@clhodapp
Copy link

clhodapp commented Jan 21, 2025

So far as I can tell, unbound still falls over when you try to use systemd socket activation with IPv6, unless you give it an explicit IPv6 interface to listen on (which is counter to the idea of socket activation).

It will try to open its port on 127.0.01, which it should not do (because systemd already has a dual-stack socket open).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants