Package: guix;
Reported by: Christopher Baines <mail <at> cbaines.net>
Date: Mon, 9 May 2022 10:46:01 UTC
Severity: important
Done: Ludovic Courtès <ludo <at> gnu.org>
Bug is archived. No further changes may be made.
To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 55335 in the body.
You can then email your comments to 55335 AT debbugs.gnu.org in the normal way.
Toggle the display of automated, internal messages from the tracker.
View this report as an mbox folder, status mbox, maintainer mbox
bug-guix <at> gnu.org
:bug#55335
; Package guix
.
(Mon, 09 May 2022 10:46:02 GMT) Full text and rfc822 format available.Christopher Baines <mail <at> cbaines.net>
:bug-guix <at> gnu.org
.
(Mon, 09 May 2022 10:46:02 GMT) Full text and rfc822 format available.Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):
From: Christopher Baines <mail <at> cbaines.net> To: bug-guix <at> gnu.org Subject: openssh-service no longer listens on IPv6 Date: Mon, 09 May 2022 11:39:47 +0100
[Message part 1 (text/plain, inline)]
This looks to be a recent regression, probably connected with the shepherd now doing the listening, rather than sshd itself. Previously, you could use both IPv4 and IPv6. netstat -tlnp | grep sshd tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 26683/sshd: /gnu/st tcp6 0 0 :::22 :::* LISTEN 26683/sshd: /gnu/st Now though, it looks like with shepherd doing the listening, you can only use IPv4. netstat -tlnp | grep 22 tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1/guile On an affected machine, you can reproduce this by trying to SSH over v6. cbaines <at> lakeside ~$ ssh 127.0.0.1 The authenticity of host '127.0.0.1 (127.0.0.1)' can't be established. ED25519 key fingerprint is SHA256:1wV7w84awrGv5ilP5e8k5ygIvSkXSJ6LIy3MnqZG2Jw. This key is not known by any other names Are you sure you want to continue connecting (yes/no/[fingerprint])? ^C cbaines <at> lakeside ~$ ssh ::1 ssh: connect to host ::1 port 22: Connection refused This isn't an issue if you're not using IPv6, but if you have a machine only accessible via IPv6, then you can't ssh in. The main workaround I've found is getting access via other means, then starting sshd listening on a different port (as the shepherd is using 22).
[signature.asc (application/pgp-signature, inline)]
Ludovic Courtès <ludo <at> gnu.org>
to control <at> debbugs.gnu.org
.
(Thu, 12 May 2022 12:38:01 GMT) Full text and rfc822 format available.bug-guix <at> gnu.org
:bug#55335
; Package guix
.
(Fri, 13 May 2022 14:19:01 GMT) Full text and rfc822 format available.Message #10 received at 55335 <at> debbugs.gnu.org (full text, mbox):
From: Christopher Baines <mail <at> cbaines.net> To: 55335 <at> debbugs.gnu.org Subject: Re: bug#55335: openssh-service no longer listens on IPv6 Date: Fri, 13 May 2022 13:21:47 +0100
[Message part 1 (text/plain, inline)]
Christopher Baines <mail <at> cbaines.net> writes: > This looks to be a recent regression, probably connected with the > shepherd now doing the listening, rather than sshd itself. > > Previously, you could use both IPv4 and IPv6. > > netstat -tlnp | grep sshd > tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 26683/sshd: /gnu/st > tcp6 0 0 :::22 :::* LISTEN 26683/sshd: /gnu/st > > Now though, it looks like with shepherd doing the listening, you can > only use IPv4. > > netstat -tlnp | grep 22 > tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1/guile > > > On an affected machine, you can reproduce this by trying to SSH over v6. > > cbaines <at> lakeside ~$ ssh 127.0.0.1 > The authenticity of host '127.0.0.1 (127.0.0.1)' can't be established. > ED25519 key fingerprint is SHA256:1wV7w84awrGv5ilP5e8k5ygIvSkXSJ6LIy3MnqZG2Jw. > This key is not known by any other names > Are you sure you want to continue connecting (yes/no/[fingerprint])? ^C > > cbaines <at> lakeside ~$ ssh ::1 > ssh: connect to host ::1 port 22: Connection refused > > > This isn't an issue if you're not using IPv6, but if you have a machine > only accessible via IPv6, then you can't ssh in. The main workaround > I've found is getting access via other means, then starting sshd > listening on a different port (as the shepherd is using 22). I've had another look at how this might be fixed. One workaround that seems to work is having the service just listen on an IPv6 socket as I believe Linux translates IPv4 connections to IPv6. The openssh system test seems to pass, and I believe this would fix not being able to connect over IPv6, although it seems likely that this would break things relying on IPv4 usage, like configuration based on specific IP addresses. I think the more rigerous approach would be to have shepherd listen on two sockets, one for IPv4 and another for IPv6. That's currently difficult though because of the above behaviour, the IPv6 socket blocks opening the IPv4 one. I've got a patch [1] to Guile that adds the constants needed for the setsockopt call and once that's possible, I believe the setsockopt call would need to happen in make-inetd-constructor. 1: https://lists.gnu.org/archive/html/guile-devel/2022-05/msg00007.html Without reverting to the previous behaviour, maybe the best way forward is to at least allow having the service listen via IPv6. That would mean those affected by the loss of IPv6 support could enable it, and would hopefully avoid breaking anyones configuration where they're relying on native IPv4 connections. I'll send a patch for this shortly. Chris
[signature.asc (application/pgp-signature, inline)]
bug-guix <at> gnu.org
:bug#55335
; Package guix
.
(Fri, 13 May 2022 14:24:02 GMT) Full text and rfc822 format available.Message #13 received at 55335 <at> debbugs.gnu.org (full text, mbox):
From: Christopher Baines <mail <at> cbaines.net> To: 55335 <at> debbugs.gnu.org Subject: [PATCH] services: Allow shepherd to listen for IPv6 connections to openssh. Date: Fri, 13 May 2022 15:23:12 +0100
Prior to the switch to the openssh service using inetd, you could connect over IPv4 or IPv6. With inetd, you can only connect over IPv4, meaning for machines with just IPv6 connectivity, you can't connect. Switching to listing via IPv6 should support IPv4 connections, as Linux is capable of translating IPv4 connections to IPv6. I think there's a risk that switching to this approach will affect some uses of the openssh service. Therefore, this commit makes this a configuration option, which is #f by default. In the future, once it's easy to do so via Guile and the shepherd, it would be good if two sockets were used, one for IPv4 and one for IPv6. That's not easy at the moment, as the IPv6 socket conflicts with the IPv4 one, due to the translation behaviour described above. * gnu/services/ssh.scm (openssh-listen-via-ipv6?): New procedure. (openssh-shepherd-service): Factor in listen-via-ipv6? when constructing the socket address. * doc/guix.texi (Networking Services): Document the new listen-via-ipv6? field. --- doc/guix.texi | 9 +++++++++ gnu/services/ssh.scm | 13 +++++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/doc/guix.texi b/doc/guix.texi index c168a66072..b168cb379e 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -19119,6 +19119,15 @@ Match Address 192.168.0.1 PermitRootLogin yes")) @end lisp +@item @code{listen-via-ipv6?} (default: @code{#f}) +When listening via a inetd-style Shepherd service, connections will only +be accepted via IPv4. + +To have the shepherd listen instead via IPv6, set this option to +#t. Depending on how network connections are handled, this will either +enable connecting via IPv6 and translated IPv4, or just enable IPv6 +connections only. + @end table @end deftp diff --git a/gnu/services/ssh.scm b/gnu/services/ssh.scm index 7fbbe383e5..427f0e4739 100644 --- a/gnu/services/ssh.scm +++ b/gnu/services/ssh.scm @@ -363,7 +363,13 @@ (define-record-type* <openssh-configuration> ;; proposed in <https://bugs.gnu.org/27155>. Keep it internal/undocumented ;; for now. (%auto-start? openssh-auto-start? - (default #t))) + (default #t)) + + ;; Boolean + ;; XXX: The service should really listen via IPv4 and IPv6 by default, but + ;; this is a little tricky. See https://issues.guix.gnu.org/55335 + (listen-via-ipv6? openssh-listen-via-ipv6? + (default #f))) (define %openssh-accounts (list (user-group (name "sshd") (system? #t)) @@ -535,7 +541,10 @@ (define openssh-command (start #~(if (defined? 'make-inetd-constructor) (make-inetd-constructor (append #$openssh-command '("-i")) - (make-socket-address AF_INET INADDR_ANY + (make-socket-address #$(if (openssh-listen-via-ipv6? config) + #~AF_INET6 + #~AF_INET) + INADDR_ANY #$port-number) #:max-connections #$max-connections) (make-forkexec-constructor #$openssh-command -- 2.34.0
bug-guix <at> gnu.org
:bug#55335
; Package guix
.
(Fri, 13 May 2022 15:24:02 GMT) Full text and rfc822 format available.Message #16 received at 55335 <at> debbugs.gnu.org (full text, mbox):
From: Jack Hill <jackhill <at> jackhill.us> To: Christopher Baines <mail <at> cbaines.net> Cc: 55335 <at> debbugs.gnu.org Subject: Re: bug#55335: [PATCH] services: Allow shepherd to listen for IPv6 connections to openssh. Date: Fri, 13 May 2022 11:23:18 -0400 (EDT)
Thanks for looking into this! Does this fix work for you (I assume so)? I tried a simpler patch to use a v6 socket: --- a/gnu/services/ssh.scm +++ b/gnu/services/ssh.scm @@ -535,7 +535,7 @@ (define openssh-command (start #~(if (defined? 'make-inetd-constructor) (make-inetd-constructor (append #$openssh-command '("-i")) - (make-socket-address AF_INET INADDR_ANY + (make-socket-address AF_INET6 INADDR_ANY #$port-number) #:max-connections #$max-connections) (make-forkexec-constructor #$openssh-command and that does indeed produce a v6 socket that also accepts v4 connection. The output of `ss -tulpen`: tcp LISTEN 0 10 *:22 *:* users:(("shepherd",pid=1,fd=29)) ino:1522146 sk:2001 cgroup:/ v6only:0 <-> However, while ssh is now able to connect to the socket, something is going wrong in the handoff to sshd. I see the following message printed on the console when trying to connect: Uncaught exception in task: In fibers.scm: 150:8 4 (_) In shepherd/service.scm: 1435:21 3 (_) 1280:30 2 (socket-address->string #(10 # 37896 0 0)) In unknown file: 1 (inet-ntop 2 42540578165178177408896616697074944157) In ice-9/boot-9.scm: 1685:16 0 (raise-exception _ #:continualbe? _) ice-9/boot-9.scm:1685:16: In procecure raise-exception: Value our of range 0 to 18446744073709551615: 42540578165178177408896616697074944157 Best, Jack
bug-guix <at> gnu.org
:bug#55335
; Package guix
.
(Fri, 13 May 2022 15:26:02 GMT) Full text and rfc822 format available.Message #19 received at 55335 <at> debbugs.gnu.org (full text, mbox):
From: Jack Hill <jackhill <at> jackhill.us> To: Christopher Baines <mail <at> cbaines.net> Cc: 55335 <at> debbugs.gnu.org Subject: Re: bug#55335: [PATCH] services: Allow shepherd to listen for IPv6 connections to openssh. Date: Fri, 13 May 2022 11:25:51 -0400 (EDT)
On Fri, 13 May 2022, Jack Hill wrote: > Thanks for looking into this! Does this fix work for you (I assume so)? I > tried a simpler patch to use a v6 socket: > > > --- a/gnu/services/ssh.scm > +++ b/gnu/services/ssh.scm > @@ -535,7 +535,7 @@ (define openssh-command > (start #~(if (defined? 'make-inetd-constructor) > (make-inetd-constructor > (append #$openssh-command '("-i")) > - (make-socket-address AF_INET INADDR_ANY > + (make-socket-address AF_INET6 INADDR_ANY > #$port-number) > #:max-connections #$max-connections) > (make-forkexec-constructor #$openssh-command > > and that does indeed produce a v6 socket that also accepts v4 connection. The > output of `ss -tulpen`: > > tcp LISTEN 0 10 *:22 *:* > users:(("shepherd",pid=1,fd=29)) ino:1522146 sk:2001 cgroup:/ v6only:0 <-> > > However, while ssh is now able to connect to the socket, something is going > wrong in the handoff to sshd. I see the following message printed on the > console when trying to connect: > > Uncaught exception in task: > In fibers.scm: > 150:8 4 (_) > In shepherd/service.scm: > 1435:21 3 (_) > 1280:30 2 (socket-address->string #(10 # 37896 0 0)) > In unknown file: > 1 (inet-ntop 2 42540578165178177408896616697074944157) > In ice-9/boot-9.scm: > 1685:16 0 (raise-exception _ #:continualbe? _) > ice-9/boot-9.scm:1685:16: In procecure raise-exception: > Value our of range 0 to 18446744073709551615: > 42540578165178177408896616697074944157 > > Best, > Jack I should have specified: now neither v4 or v6 work. Best, Jack
bug-guix <at> gnu.org
:bug#55335
; Package guix
.
(Sat, 14 May 2022 08:43:01 GMT) Full text and rfc822 format available.Message #22 received at 55335 <at> debbugs.gnu.org (full text, mbox):
From: Ludovic Courtès <ludo <at> gnu.org> To: Jack Hill <jackhill <at> jackhill.us> Cc: Christopher Baines <mail <at> cbaines.net>, 55335 <at> debbugs.gnu.org Subject: Re: bug#55335: openssh-service no longer listens on IPv6 Date: Sat, 14 May 2022 10:42:20 +0200
Hi, Jack Hill <jackhill <at> jackhill.us> skribis: > However, while ssh is now able to connect to the socket, something is > going wrong in the handoff to sshd. I see the following message > printed on the console when trying to connect: > > Uncaught exception in task: > In fibers.scm: > 150:8 4 (_) > In shepherd/service.scm: > 1435:21 3 (_) > 1280:30 2 (socket-address->string #(10 # 37896 0 0)) > In unknown file: > 1 (inet-ntop 2 42540578165178177408896616697074944157) > In ice-9/boot-9.scm: > 1685:16 0 (raise-exception _ #:continualbe? _) > ice-9/boot-9.scm:1685:16: In procecure raise-exception: > Value our of range 0 to 18446744073709551615: 42540578165178177408896616697074944157 Oops, another embarrassing bug, now fixed in Shepherd commit 27dd4df9d83e9c59668bd9e6ca05a3a4983e10d2. Thanks, Ludo’.
bug-guix <at> gnu.org
:bug#55335
; Package guix
.
(Sat, 14 May 2022 14:17:02 GMT) Full text and rfc822 format available.Message #25 received at 55335 <at> debbugs.gnu.org (full text, mbox):
From: Ludovic Courtès <ludo <at> gnu.org> To: Christopher Baines <mail <at> cbaines.net> Cc: 55335 <at> debbugs.gnu.org Subject: Re: bug#55335: openssh-service no longer listens on IPv6 Date: Sat, 14 May 2022 16:16:42 +0200
Hi, Christopher Baines <mail <at> cbaines.net> skribis: > Prior to the switch to the openssh service using inetd, you could connect over > IPv4 or IPv6. With inetd, you can only connect over IPv4, meaning for machines > with just IPv6 connectivity, you can't connect. > > Switching to listing via IPv6 should support IPv4 connections, as Linux is > capable of translating IPv4 connections to IPv6. I think there's a risk that > switching to this approach will affect some uses of the openssh > service. Therefore, this commit makes this a configuration option, which is #f > by default. > > In the future, once it's easy to do so via Guile and the shepherd, it would be > good if two sockets were used, one for IPv4 and one for IPv6. That's not easy > at the moment, as the IPv6 socket conflicts with the IPv4 one, due to the > translation behaviour described above. Yes, I was going to suggest turning the ‘address’ argument of ‘make-inetd-constructor’ into ‘addresses’ (plural), with backward compatibility. For sshd, we’d do: (make-inetd-constructor (append #$openssh-command '("-i")) (list (make-socket-address AF_INET INADDR_ANY #$port-number) (make-socket-address AF_INET6 INADDR_ANY #$port-number))) It’s not that simple, due to the v6-to-v4 translation you mention: --8<---------------cut here---------------start------------->8--- scheme@(guile-user)> (define v4 (make-socket-address AF_INET INADDR_ANY 5555)) scheme@(guile-user)> (define v6 (make-socket-address AF_INET6 INADDR_ANY 5555)) scheme@(guile-user)> (define s4 (socket AF_INET SOCK_STREAM 0)) scheme@(guile-user)> (define s6 (socket AF_INET6 SOCK_STREAM 0)) scheme@(guile-user)> (bind s4 v4) scheme@(guile-user)> (bind s6 v6) ice-9/boot-9.scm:1685:16: In procedure raise-exception: In procedure bind: Address already in use Entering a new prompt. Type `,bt' for a backtrace or `,q' to continue. --8<---------------cut here---------------end--------------->8--- … but it can be made to work: --8<---------------cut here---------------start------------->8--- scheme@(guile-user)> (define s4 (socket AF_INET SOCK_STREAM 0)) scheme@(guile-user)> (define s6 (socket AF_INET6 SOCK_STREAM 0)) scheme@(guile-user)> (define IPPROTO_IPV6 41) scheme@(guile-user)> (define IPV6_V6ONLY 26) scheme@(guile-user)> (setsockopt s6 IPPROTO_IPV6 IPV6_V6ONLY 1) scheme@(guile-user)> (bind s4 v4) scheme@(guile-user)> (bind s6 v6) --8<---------------cut here---------------end--------------->8--- So ‘make-inetd-constructor’ would interpret v6 addresses as v6-only, with the understanding that the caller has to explicitly pass all the relevant addresses. Thoughts? We could release Shepherd shortly with the fixes that have accumulated. The service in Guix would be able to use it, but only if PID 1 is recent enough. Thanks, Ludo’.
bug-guix <at> gnu.org
:bug#55335
; Package guix
.
(Sat, 14 May 2022 15:50:02 GMT) Full text and rfc822 format available.Message #28 received at 55335 <at> debbugs.gnu.org (full text, mbox):
From: Ludovic Courtès <ludo <at> gnu.org> To: Christopher Baines <mail <at> cbaines.net> Cc: 55335 <at> debbugs.gnu.org Subject: Re: bug#55335: openssh-service no longer listens on IPv6 Date: Sat, 14 May 2022 17:49:31 +0200
Hi, Christopher Baines <mail <at> cbaines.net> skribis: > Switching to listing via IPv6 should support IPv4 connections, as Linux is > capable of translating IPv4 connections to IPv6. I think there's a risk that > switching to this approach will affect some uses of the openssh > service. Therefore, this commit makes this a configuration option, which is #f > by default. [...] > + (make-socket-address #$(if (openssh-listen-via-ipv6? config) > + #~AF_INET6 > + #~AF_INET) > + INADDR_ANY > #$port-number) Thinking about it, what do you think is the risk of using AF_INET6 unconditionally? AFAICS it just works. Is there a switch somewhere that might affect that behavior? (I still think that changing ‘make-inetd-constructor’ to accept multiple addresses is a better fix longer-term, but if we can have this quick fix, that’s great.) Ludo’.
bug-guix <at> gnu.org
:bug#55335
; Package guix
.
(Sat, 14 May 2022 19:11:02 GMT) Full text and rfc822 format available.Message #31 received at 55335 <at> debbugs.gnu.org (full text, mbox):
From: Jack Hill <jackhill <at> jackhill.us> To: Ludovic Courtès <ludo <at> gnu.org> Cc: Christopher Baines <mail <at> cbaines.net>, 55335 <at> debbugs.gnu.org Subject: Re: bug#55335: openssh-service no longer listens on IPv6 Date: Sat, 14 May 2022 15:09:55 -0400 (EDT)
[Message part 1 (text/plain, inline)]
On Sat, 14 May 2022, Ludovic Courtès wrote: > Hi, > > Thinking about it, what do you think is the risk of using AF_INET6 > unconditionally? > > AFAICS it just works. Is there a switch somewhere that might affect > that behavior? Yes, I beleive that it's in sysctl: ``` $ sysctl net.ipv6.bindv6only net.ipv6.bindv6only = 0 ``` If enabled, the v6 socket wouldn't work for v4. Disabled is the default on Guix System. I don't know what would happen if v6 were disabled entirely. Hopefully that's not something we have to worry about in 2022. HTH, Jack
bug-guix <at> gnu.org
:bug#55335
; Package guix
.
(Tue, 17 May 2022 21:36:01 GMT) Full text and rfc822 format available.Message #34 received at 55335 <at> debbugs.gnu.org (full text, mbox):
From: Christopher Baines <mail <at> cbaines.net> To: Ludovic Courtès <ludo <at> gnu.org> Cc: 55335 <at> debbugs.gnu.org Subject: Re: bug#55335: openssh-service no longer listens on IPv6 Date: Tue, 17 May 2022 22:33:29 +0100
[Message part 1 (text/plain, inline)]
Ludovic Courtès <ludo <at> gnu.org> writes: > Hi, > > Christopher Baines <mail <at> cbaines.net> skribis: > >> Switching to listing via IPv6 should support IPv4 connections, as Linux is >> capable of translating IPv4 connections to IPv6. I think there's a risk that >> switching to this approach will affect some uses of the openssh >> service. Therefore, this commit makes this a configuration option, which is #f >> by default. > > [...] > >> + (make-socket-address #$(if (openssh-listen-via-ipv6? config) >> + #~AF_INET6 >> + #~AF_INET) >> + INADDR_ANY >> #$port-number) > > Thinking about it, what do you think is the risk of using AF_INET6 > unconditionally? I'm assuming that configuration that looks at the IP addresses will be affected, e.g. things like: Match Address 127.0.0.* PubkeyAuthentication yes But this is just a guess. > AFAICS it just works. Is there a switch somewhere that might affect > that behavior? > > (I still think that changing ‘make-inetd-constructor’ to accept multiple > addresses is a better fix longer-term, but if we can have this quick > fix, that’s great.) I'm also interested in a quick fix. I'd like to either make the switch to using AF_INET6 unconditionally, or push the patch I sent for allowing it to be used through a configuration option.
[signature.asc (application/pgp-signature, inline)]
bug-guix <at> gnu.org
:bug#55335
; Package guix
.
(Wed, 18 May 2022 09:32:02 GMT) Full text and rfc822 format available.Message #37 received at 55335 <at> debbugs.gnu.org (full text, mbox):
From: Ludovic Courtès <ludo <at> gnu.org> To: Christopher Baines <mail <at> cbaines.net> Cc: 55335 <at> debbugs.gnu.org Subject: Re: bug#55335: openssh-service no longer listens on IPv6 Date: Wed, 18 May 2022 11:30:46 +0200
Hi Chris, Christopher Baines <mail <at> cbaines.net> skribis: > I'm also interested in a quick fix. I'd like to either make the switch > to using AF_INET6 unconditionally, or push the patch I sent for allowing > it to be used through a configuration option. How about going with unconditional AF_INET6 for now? That way we wouldn’t have that new option that will likely become a no-op afterwards. I’ll propose changes to the Shepherd soon, so we can fix it for good. Thanks, Ludo’.
bug-guix <at> gnu.org
:bug#55335
; Package guix
.
(Wed, 18 May 2022 14:08:01 GMT) Full text and rfc822 format available.Message #40 received at 55335 <at> debbugs.gnu.org (full text, mbox):
From: Ludovic Courtès <ludo <at> gnu.org> To: 55335 <at> debbugs.gnu.org Cc: Ludovic Courtès <ludo <at> gnu.org> Subject: [PATCH Shepherd 2/3] tests: Update inetd tests to pass a list of endpoints. Date: Wed, 18 May 2022 16:06:44 +0200
* tests/inetd.sh: Pass 'make-inetd-constructor' a list of endpoints. --- tests/inetd.sh | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/tests/inetd.sh b/tests/inetd.sh index ef18800..83037bf 100644 --- a/tests/inetd.sh +++ b/tests/inetd.sh @@ -42,15 +42,18 @@ cat > "$conf" <<EOF (make <service> #:provides '(test-inetd) #:start (make-inetd-constructor %command - (make-socket-address AF_INET - INADDR_LOOPBACK - $PORT)) + (list + (endpoint (make-socket-address + AF_INET + INADDR_LOOPBACK + $PORT)))) #:stop (make-inetd-destructor)) (make <service> #:provides '(test-inetd-unix) #:start (make-inetd-constructor %command - (make-socket-address AF_UNIX - "$service_socket") + (list + (endpoint (make-socket-address + AF_UNIX "$service_socket"))) #:max-connections 5) #:stop (make-inetd-destructor))) -- 2.36.0
bug-guix <at> gnu.org
:bug#55335
; Package guix
.
(Wed, 18 May 2022 14:08:02 GMT) Full text and rfc822 format available.Message #43 received at 55335 <at> debbugs.gnu.org (full text, mbox):
From: Ludovic Courtès <ludo <at> gnu.org> To: 55335 <at> debbugs.gnu.org Cc: Ludovic Courtès <ludo <at> gnu.org> Subject: [PATCH Shepherd 1/3] service: 'make-inetd-constructor' accepts a list of endpoints. Date: Wed, 18 May 2022 16:06:43 +0200
* modules/shepherd/service.scm (endpoint->listening-socket) (open-sockets): New procedures. (make-inetd-constructor): Change 'address' parameter to 'endpoints'. Mark #:socket-style, #:socket-owner, #:socket-group, #:socket-directory-permissions, and #:listen-backlog as deprecated. [spawn-child-service, accept-clients]: Take 'server-address' parameter and use it. Update callers. Add compatibility later for when ENDPOINTS is an address. (make-inetd-destructor): Adjust. (make-systemd-destructor)[endpoint->listening-socket, open-sockets]: Remove. Adjust to new return value of 'open-sockets'. * NEWS: Mention it. --- NEWS | 13 ++ doc/shepherd.texi | 54 ++++---- modules/shepherd/service.scm | 255 +++++++++++++++++------------------ 3 files changed, 161 insertions(+), 161 deletions(-) diff --git a/NEWS b/NEWS index c51e8e2..4ce7a48 100644 --- a/NEWS +++ b/NEWS @@ -12,6 +12,19 @@ Copyright © 2013-2014, 2016, 2018-2020, 2022 Ludovic Courtès <ludo <at> gnu.org> Please send Shepherd bug reports to bug-guix <at> gnu.org. * Changes in version 0.9.1 +** ‘make-inetd-constructor’ now accepts a list of endpoints + +In 0.9.0, ‘make-inetd-constructor’ would take a single address as returned by +‘make-socket-address’. This was insufficiently flexible since it didn’t let +you have an inetd service with multiple endpoints. ‘make-inetd-constructor’ +now takes a list of endpoints, similar to what ‘make-systemd-constructor’ +already did. + +For compatibility with 0.9.0, if the second argument to +‘make-systemd-constructor’ is an address, it is automatically converted to a +list of endpoints. This behavior will be preserved for at least the whole +0.9.x series. + ** ‘shepherd’ reports whether a service is transient ** ‘herd status’ shows whether a service is transient ** Fix possible file descriptor leak in ‘make-inetd-constructor’ diff --git a/doc/shepherd.texi b/doc/shepherd.texi index 3d01186..9efc48e 100644 --- a/doc/shepherd.texi +++ b/doc/shepherd.texi @@ -1082,11 +1082,28 @@ services, specifically those in @code{nowait} mode where the daemon is passed the newly-accepted socket connection while @command{shepherd} is in charge of listening. -@deffn {procedure} make-inetd-constructor @var{command} @var{address} - [#:service-name-stem _] [#:requirements '()] @ - [#:socket-style SOCK_STREAM] [#:listen-backlog 10] @ +Listening endpoints for such services are described as records built +using the @code{endpoint} procedure: + +@deffn {procedure} endpoint @var{address} [#:name "unknown"] @ + [#:style SOCK_STREAM] [#:backlog 128] @ [#:socket-owner (getuid)] [#:socket-group (getgid)] @ - [#:socket-directory-permissions #o755] @ + [#:socket-directory-permissions #o755] +Return a new endpoint called @var{name} of @var{address}, an address as +return by @code{make-socket-address}, with the given @var{style} and +@var{backlog}. + +When @var{address} is of type @code{AF_UNIX}, @var{socket-owner} and +@var{socket-group} are strings or integers that specify its ownership and that +of its parent directory; @var{socket-directory-permissions} specifies the +permissions for its parent directory. +@end deffn + +The inetd service constructor takes a command and a list of such +endpoints: + +@deffn {procedure} make-inetd-constructor @var{command} @var{endpoints} + [#:service-name-stem _] [#:requirements '()] @ [#:max-connections (default-inetd-max-connections)] @ [#:user #f] @ [#:group #f] @ @@ -1095,14 +1112,9 @@ in charge of listening. [#:file-creation-mask #f] [#:create-session? #t] @ [#:resource-limits '()] @ [#:environment-variables (default-environment-variables)] -Return a procedure that opens a socket listening to @var{address}, an -object as returned by @code{make-socket-address}, and accepting connections in -the background; the @var{listen-backlog} argument is passed to @var{accept}. - -When @var{address} is of type @code{AF_UNIX}, @var{socket-owner} and -@var{socket-group} are strings or integers that specify its ownership and that -of its parent directory; @var{socket-directory-permissions} specifies the -permissions for its parent directory. +Return a procedure that opens sockets listening to @var{endpoints}, a list +of objects as returned by @code{endpoint}, and accepting connections in the +background. Upon a client connection, a transient service running @var{command} is spawned. Only up to @var{max-connections} simultaneous connections are @@ -1133,24 +1145,6 @@ environment (see below), which usually checks them using the libsystemd or libelogind @uref{https://www.freedesktop.org/software/systemd/man/sd_listen_fds.html, client library helper functions}. - -Listening endpoints for such services are described as records built -using the @code{endpoint} procedure: - -@deffn {procedure} endpoint @var{address} [#:name "unknown"] @ - [#:style SOCK_STREAM] [#:backlog 128] @ - [#:socket-owner (getuid)] [#:socket-group (getgid)] @ - [#:socket-directory-permissions #o755] -Return a new endpoint called @var{name} of @var{address}, an address as -return by @code{make-socket-address}, with the given @var{style} and -@var{backlog}. - -When @var{address} is of type @code{AF_UNIX}, @var{socket-owner} and -@var{socket-group} are strings or integers that specify its ownership and that -of its parent directory; @var{socket-directory-permissions} specifies the -permissions for its parent directory. -@end deffn - The constructor and destructor for systemd-style daemons are described below. diff --git a/modules/shepherd/service.scm b/modules/shepherd/service.scm index ded8283..e93466a 100644 --- a/modules/shepherd/service.scm +++ b/modules/shepherd/service.scm @@ -1225,6 +1225,90 @@ as argument, where SIGNAL defaults to `SIGTERM'." (lambda (ignored . args) (not (zero? (status:exit-val (system (apply string-append command))))))) + +;;; +;;; Server endpoints. +;;; + +;; Endpoint of a systemd-style or inetd-style service. +(define-record-type <endpoint> + (make-endpoint name address style backlog owner group permissions) + endpoint? + (name endpoint-name) ;string + (address endpoint-address) ;socket address + (style endpoint-style) ;SOCK_STREAM, etc. + (backlog endpoint-backlog) ;integer + (owner endpoint-socket-owner) ;integer + (group endpoint-socket-group) ;integer + (permissions endpoint-socket-directory-permissions)) ;integer + +(define* (endpoint address + #:key (name "unknown") (style SOCK_STREAM) + (backlog 128) + (socket-owner (getuid)) (socket-group (getgid)) + (socket-directory-permissions #o755)) + "Return a new endpoint called @var{name} of @var{address}, an address as +return by @code{make-socket-address}, with the given @var{style} and +@var{backlog}. + +When @var{address} is of type @code{AF_UNIX}, @var{socket-owner} and +@var{socket-group} are strings or integers that specify its ownership and that +of its parent directory; @var{socket-directory-permissions} specifies the +permissions for its parent directory." + (make-endpoint name address style backlog + socket-owner socket-group + socket-directory-permissions)) + +(define (endpoint->listening-socket endpoint) + "Return a listening socket for ENDPOINT." + (match endpoint + (($ <endpoint> name address style backlog + owner group permissions) + (let* ((sock (non-blocking-port + (socket (sockaddr:fam address) style 0))) + (owner (if (integer? owner) + owner + (passwd:uid (getpwnam owner)))) + (group (if (integer? group) + group + (group:gid (getgrnam group))))) + (setsockopt sock SOL_SOCKET SO_REUSEADDR 1) + (when (= AF_UNIX (sockaddr:fam address)) + (mkdir-p (dirname (sockaddr:path address)) permissions) + (chown (dirname (sockaddr:path address)) owner group) + (catch-system-error (delete-file (sockaddr:path address)))) + + (bind sock address) + (listen sock backlog) + + (when (= AF_UNIX (sockaddr:fam address)) + (chown sock owner group) + (chmod sock #o666)) + + sock)))) + +(define (open-sockets endpoints) + "Return a list of listening sockets corresponding to ENDPOINTS, in the same +order as ENDPOINTS. If opening of binding one of them fails, an exception is +thrown an previously-opened sockets are closed." + (let loop ((endpoints endpoints) + (result '())) + (match endpoints + (() + (reverse result)) + ((head tail ...) + (let ((sock (catch 'system-error + (lambda () + (endpoint->listening-socket head)) + (lambda args + ;; When opening one socket fails, abort the whole + ;; process. + (for-each (match-lambda + ((_ . socket) (close-port socket))) + result) + (apply throw args))))) + (loop tail (cons sock result))))))) + ;;; ;;; Inetd-style services. @@ -1311,18 +1395,13 @@ as argument, where SIGNAL defaults to `SIGTERM'." ;; service. (make-parameter 100)) -(define* (make-inetd-constructor command address +(define* (make-inetd-constructor command endpoints #:key (service-name-stem (match command ((program . _) (basename program)))) (requirements '()) - (socket-style SOCK_STREAM) - (socket-owner (getuid)) - (socket-group (getgid)) - (socket-directory-permissions #o755) - (listen-backlog 10) (max-connections (default-inetd-max-connections)) (user #f) @@ -1333,15 +1412,17 @@ as argument, where SIGNAL defaults to `SIGTERM'." (create-session? #t) (environment-variables (default-environment-variables)) - (resource-limits '())) - "Return a procedure that opens a socket listening to @var{address}, an -object as returned by @code{make-socket-address}, and accepting connections in -the background; the @var{listen-backlog} argument is passed to @var{accept}. + (resource-limits '()) -When @var{address} is of type @code{AF_UNIX}, @var{socket-owner} and -@var{socket-group} are strings or integers that specify its ownership and that -of its parent directory; @var{socket-directory-permissions} specifies the -permissions for its parent directory. + ;; Deprecated. + (socket-style SOCK_STREAM) + (socket-owner (getuid)) + (socket-group (getgid)) + (socket-directory-permissions #o755) + (listen-backlog 10)) + "Return a procedure that opens sockets listening to @var{endpoints}, a list +of objects as returned by @code{endpoint}, and accepting connections in the +background. Upon a client connection, a transient service running @var{command} is spawned. Only up to @var{max-connections} simultaneous connections are @@ -1370,7 +1451,7 @@ The remaining arguments are as for @code{make-forkexec-constructor}." connection-count (canonical-name service)) (default-service-termination-handler service status)) - (define (spawn-child-service connection client-address) + (define (spawn-child-service connection server-address client-address) (let* ((name (child-service-name)) (service (make <service> #:provides (list name) @@ -1387,7 +1468,7 @@ The remaining arguments are as for @code{make-forkexec-constructor}." #:file-creation-mask file-creation-mask #:create-session? create-session? #:environment-variables - (append (inetd-variables address + (append (inetd-variables server-address client-address) environment-variables) #:resource-limits resource-limits) @@ -1396,7 +1477,7 @@ The remaining arguments are as for @code{make-forkexec-constructor}." (register-services service) (start service))) - (define (accept-clients sock) + (define (accept-clients server-address sock) ;; Return a thunk that accepts client connections from SOCK. (lambda () (let loop () @@ -1407,7 +1488,7 @@ The remaining arguments are as for @code{make-forkexec-constructor}." (local-output (l10n "Maximum number of ~a clients reached; \ rejecting connection from ~:[~a~;~*local process~].") - (socket-address->string address) + (socket-address->string server-address) (= AF_UNIX (sockaddr:fam client-address)) (socket-address->string client-address)) (close-port connection)) @@ -1415,46 +1496,35 @@ rejecting connection from ~:[~a~;~*local process~].") (set! connection-count (+ 1 connection-count)) (local-output (l10n "Accepted connection on ~a from ~:[~a~;~*local process~].") - (socket-address->string address) + (socket-address->string server-address) (= AF_UNIX (sockaddr:fam client-address)) (socket-address->string client-address)) - (spawn-child-service connection client-address))))) + (spawn-child-service connection + server-address client-address))))) (loop)))) (lambda args - (let ((owner (if (integer? socket-owner) - socket-owner - (passwd:uid (getpwnam socket-owner)))) - (group (if (integer? socket-group) - socket-group - (group:gid (getgrnam socket-group)))) - (sock (socket (sockaddr:fam address) socket-style 0))) - (catch #t - (lambda () - (non-blocking-port sock) - (setsockopt sock SOL_SOCKET SO_REUSEADDR 1) - - (when (= AF_UNIX (sockaddr:fam address)) - (mkdir-p (dirname (sockaddr:path address)) - socket-directory-permissions) - (chown (dirname (sockaddr:path address)) owner group) - (catch-system-error (delete-file (sockaddr:path address)))) - (bind sock address) - (when (= AF_UNIX (sockaddr:fam address)) - (chown sock owner group) - (chmod sock #o666)) - - (listen sock listen-backlog) - (spawn-fiber (accept-clients sock)) - sock) - (lambda args - (close-port sock) - (apply throw args)))))) + (let* ((endpoints (match endpoints + (((? endpoint?) ...) endpoints) + (address (list (endpoint address + #:style socket-style + #:backlog listen-backlog + #:socket-owner socket-owner + #:socket-group socket-group + #:socket-directory-permissions + socket-directory-permissions))))) + (sockets (open-sockets endpoints))) + (for-each (lambda (endpoint socket) + (spawn-fiber + (accept-clients (endpoint-address endpoint) + socket))) + endpoints sockets) + sockets))) (define (make-inetd-destructor) "Return a procedure that terminates an inetd service." - (lambda (sock) - (close-port sock) + (lambda (sockets) + (for-each close-port sockets) #f)) @@ -1462,35 +1532,6 @@ rejecting connection from ~:[~a~;~*local process~].") ;;; systemd-style services. ;;; -;; Endpoint of a systemd-style service. -(define-record-type <endpoint> - (make-endpoint name address style backlog owner group permissions) - endpoint? - (name endpoint-name) ;string - (address endpoint-address) ;socket address - (style endpoint-style) ;SOCK_STREAM, etc. - (backlog endpoint-backlog) ;integer - (owner endpoint-socket-owner) ;integer - (group endpoint-socket-group) ;integer - (permissions endpoint-socket-directory-permissions)) ;integer - -(define* (endpoint address - #:key (name "unknown") (style SOCK_STREAM) - (backlog 128) - (socket-owner (getuid)) (socket-group (getgid)) - (socket-directory-permissions #o755)) - "Return a new endpoint called @var{name} of @var{address}, an address as -return by @code{make-socket-address}, with the given @var{style} and -@var{backlog}. - -When @var{address} is of type @code{AF_UNIX}, @var{socket-owner} and -@var{socket-group} are strings or integers that specify its ownership and that -of its parent directory; @var{socket-directory-permissions} specifies the -permissions for its parent directory." - (make-endpoint name address style backlog - socket-owner socket-group - socket-directory-permissions)) - (define (wait-for-readable ports) "Suspend the current task until one of @var{ports} is available for reading." @@ -1538,58 +1579,10 @@ The colon-separated list of endpoint names. This must be paired with @code{make-systemd-destructor}." (lambda args - (define (endpoint->listening-socket endpoint) - ;; Return a listening socket for ENDPOINT. - (match endpoint - (($ <endpoint> name address style backlog - owner group permissions) - (let* ((sock (non-blocking-port - (socket (sockaddr:fam address) style 0))) - (owner (if (integer? owner) - owner - (passwd:uid (getpwnam owner)))) - (group (if (integer? group) - group - (group:gid (getgrnam group))))) - (setsockopt sock SOL_SOCKET SO_REUSEADDR 1) - (when (= AF_UNIX (sockaddr:fam address)) - (mkdir-p (dirname (sockaddr:path address)) permissions) - (chown (dirname (sockaddr:path address)) owner group) - (catch-system-error (delete-file (sockaddr:path address)))) - - (bind sock address) - (listen sock backlog) - - (when (= AF_UNIX (sockaddr:fam address)) - (chown sock owner group) - (chmod sock #o666)) - - sock)))) - - (define (open-sockets addresses) - (let loop ((endpoints endpoints) - (result '())) - (match endpoints - (() - (reverse result)) - ((head tail ...) - (let ((sock (catch 'system-error - (lambda () - (endpoint->listening-socket head)) - (lambda args - ;; When opening one socket fails, abort the whole - ;; process. - (for-each (match-lambda - ((_ . socket) (close-port socket))) - result) - (apply throw args))))) - (loop tail - `((,(endpoint-name head) . ,sock) ,@result))))))) - - (let* ((sockets (open-sockets endpoints)) - (ports (match sockets - (((names . ports) ...) - ports))) + (let* ((ports (open-sockets endpoints)) + (sockets (map (lambda (endpoint socket) + (cons (endpoint-name endpoint) socket)) + endpoints ports)) (variables (list (string-append "LISTEN_FDS=" (number->string (length sockets))) (string-append "LISTEN_FDNAMES=" -- 2.36.0
bug-guix <at> gnu.org
:bug#55335
; Package guix
.
(Wed, 18 May 2022 14:08:02 GMT) Full text and rfc822 format available.Message #46 received at 55335 <at> debbugs.gnu.org (full text, mbox):
From: Ludovic Courtès <ludo <at> gnu.org> To: 55335 <at> debbugs.gnu.org Cc: Ludovic Courtès <ludo <at> gnu.org> Subject: [PATCH Shepherd 3/3] Interpret AF_INET6 endpoints as IPv6-only. Date: Wed, 18 May 2022 16:06:45 +0200
* configure.ac: Check the values of IPPROTO_IPV6 and IPV6_V6ONLY. * modules/shepherd/system.scm.in (ipv6-only): New procedure. * modules/shepherd/service.scm (endpoint->listening-socket): Call it if ADDRESS is AF_INET6. (define-as-needed): New macro. (IN6ADDR_LOOPBACK, IN6ADDR_ANY): New variables. * tests/inetd.sh: Add 'test-inetd6' and 'test-inetd-v6-only' services. Test them. --- NEWS | 11 +++++++ configure.ac | 12 +++++++ doc/shepherd.texi | 14 ++++++++ modules/shepherd/service.scm | 19 +++++++++++ modules/shepherd/system.scm.in | 11 +++++++ tests/inetd.sh | 58 ++++++++++++++++++++++++++++++++++ 6 files changed, 125 insertions(+) diff --git a/NEWS b/NEWS index 4ce7a48..3798b31 100644 --- a/NEWS +++ b/NEWS @@ -25,6 +25,17 @@ For compatibility with 0.9.0, if the second argument to list of endpoints. This behavior will be preserved for at least the whole 0.9.x series. +** ‘AF_INET6’ endpoints are now interpreted as IPv6-only + +In 0.9.0, using an ‘AF_INET6’ endpoint for ‘make-systemd-constructor’ would +usually have the effect of making the service available on both IPv6 and IPv4. +This is due to the default behavior of Linux, which is to bind IPv6 addresses +as IPv4 as well (the default behavior can be changed by running +‘sysctl net.ipv6.bindv6only 1’). + +‘AF_INET6’ endpoints are now interpreted as IPv6-only. Thus, if a service is +to be made available both as IPv6 and IPv4, two endpoints must be used. + ** ‘shepherd’ reports whether a service is transient ** ‘herd status’ shows whether a service is transient ** Fix possible file descriptor leak in ‘make-inetd-constructor’ diff --git a/configure.ac b/configure.ac index bf91560..b745813 100644 --- a/configure.ac +++ b/configure.ac @@ -141,6 +141,18 @@ AC_SUBST([SIG_BLOCK]) AC_SUBST([SIG_UNBLOCK]) AC_SUBST([SIG_SETMASK]) +dnl Check for constants not exported by Guile as of 3.0.8. +AC_MSG_CHECKING([<netinet/in.h> constants]) +AC_COMPUTE_INT([IPPROTO_IPV6], [IPPROTO_IPV6], [ + #include <sys/socket.h> + #include <netinet/in.h>]) +AC_COMPUTE_INT([IPV6_V6ONLY], [IPV6_V6ONLY], [ + #include <sys/socket.h> + #include <netinet/in.h>]) +AC_MSG_RESULT([done]) +AC_SUBST([IPPROTO_IPV6]) +AC_SUBST([IPV6_V6ONLY]) + AC_MSG_CHECKING([whether to build crash handler]) case "$host_os" in linux-gnu*) build_crash_handler=yes;; diff --git a/doc/shepherd.texi b/doc/shepherd.texi index 9efc48e..841b854 100644 --- a/doc/shepherd.texi +++ b/doc/shepherd.texi @@ -1093,6 +1093,20 @@ Return a new endpoint called @var{name} of @var{address}, an address as return by @code{make-socket-address}, with the given @var{style} and @var{backlog}. +When @var{address} is of type @code{AF_INET6}, the endpoint is +@emph{IPv6-only}. Thus, if you want a service available both on IPv4 +and IPv6, you need two endpoints. For example, below is a list of +endpoints to listen on port 4444 on all the network interfaces, both in +IPv4 and IPv6 (``0.0.0.0'' for IPv4 and ``::0'' for IPv6): + +@lisp +(list (endpoint (make-socket-address AF_INET INADDR_ANY 4444)) + (endpoint (make-socket-address AF_INET6 IN6ADDR_ANY 4444))) +@end lisp + +This is the list you would pass to @code{make-inetd-constructor} or +@code{make-systemd-constructor}---see below. + When @var{address} is of type @code{AF_UNIX}, @var{socket-owner} and @var{socket-group} are strings or integers that specify its ownership and that of its parent directory; @var{socket-directory-permissions} specifies the diff --git a/modules/shepherd/service.scm b/modules/shepherd/service.scm index e93466a..6df550c 100644 --- a/modules/shepherd/service.scm +++ b/modules/shepherd/service.scm @@ -1251,6 +1251,10 @@ as argument, where SIGNAL defaults to `SIGTERM'." return by @code{make-socket-address}, with the given @var{style} and @var{backlog}. +When @var{address} is of type @code{AF_INET6}, the endpoint is +@emph{IPv6-only}. Thus, if you want a service available both on IPv4 and +IPv6, you need two endpoints. + When @var{address} is of type @code{AF_UNIX}, @var{socket-owner} and @var{socket-group} are strings or integers that specify its ownership and that of its parent directory; @var{socket-directory-permissions} specifies the @@ -1273,6 +1277,11 @@ permissions for its parent directory." group (group:gid (getgrnam group))))) (setsockopt sock SOL_SOCKET SO_REUSEADDR 1) + (when (= AF_INET6 (sockaddr:fam address)) + ;; Interpret AF_INET6 endpoints as IPv6-only. This is contrary to + ;; the Linux defaults where listening on an IPv6 address also listens + ;; on its IPv4 counterpart. + (ipv6-only sock)) (when (= AF_UNIX (sockaddr:fam address)) (mkdir-p (dirname (sockaddr:path address)) permissions) (chown (dirname (sockaddr:path address)) owner group) @@ -1309,6 +1318,16 @@ thrown an previously-opened sockets are closed." (apply throw args))))) (loop tail (cons sock result))))))) +(define-syntax-rule (define-as-needed name value) + (unless (defined? 'name) + (module-define! (current-module) 'name value) + (module-export! (current-module) '(name)))) + +;; These values are not defined as of Guile 3.0.8. Provide them as a +;; convenience. +(define-as-needed IN6ADDR_LOOPBACK 1) +(define-as-needed IN6ADDR_ANY 0) + ;;; ;;; Inetd-style services. diff --git a/modules/shepherd/system.scm.in b/modules/shepherd/system.scm.in index 2562764..0978c18 100644 --- a/modules/shepherd/system.scm.in +++ b/modules/shepherd/system.scm.in @@ -32,6 +32,7 @@ prctl PR_SET_CHILD_SUBREAPER getpgid + ipv6-only SFD_CLOEXEC signalfd consume-signalfd-siginfo @@ -141,6 +142,16 @@ ctrlaltdel(8) and see kernel/reboot.c in Linux." (list err)) result))))) +(define (ipv6-only port) + "Make PORT, a file port backed by a socket, IPv6-only (using the IPV6_V6ONLY +socket option) and return PORT. + +This is useful when willing to make a listening socket that operates on IPv6 +only (by default, Linux binds AF_INET6 addresses on IPv4 as well)." + ;; As of Guile 3.0.8, IPPROTO_IPV6 and IPV6_V6ONLY are not exported. + (setsockopt port @IPPROTO_IPV6@ @IPV6_V6ONLY@ 1) + port) + (define (allocate-sigset) (bytevector->pointer (make-bytevector @SIZEOF_SIGSET_T@))) diff --git a/tests/inetd.sh b/tests/inetd.sh index 83037bf..c05d6fe 100644 --- a/tests/inetd.sh +++ b/tests/inetd.sh @@ -48,6 +48,28 @@ cat > "$conf" <<EOF INADDR_LOOPBACK $PORT)))) #:stop (make-inetd-destructor)) + (make <service> + #:provides '(test-inetd6) + #:start (make-inetd-constructor %command + (list + (endpoint (make-socket-address + AF_INET + INADDR_LOOPBACK + $PORT)) + (endpoint (make-socket-address + AF_INET6 + IN6ADDR_LOOPBACK + $PORT)))) + #:stop (make-inetd-destructor)) + (make <service> + #:provides '(test-inetd-v6-only) + #:start (make-inetd-constructor %command + (list + (endpoint (make-socket-address + AF_INET6 + IN6ADDR_LOOPBACK + $PORT)))) + #:stop (make-inetd-destructor)) (make <service> #:provides '(test-inetd-unix) #:start (make-inetd-constructor %command @@ -81,6 +103,7 @@ test $($herd status | grep '\+' | wc -l) -eq 2 converse_with_echo_server () { guile -c "(use-modules (ice-9 match) (ice-9 rdelim)) + (define IN6ADDR_LOOPBACK 1) (define address $1) (define sock (socket (sockaddr:fam address) SOCK_STREAM 0)) (connect sock address) @@ -98,10 +121,45 @@ do "(make-socket-address AF_INET INADDR_LOOPBACK $PORT)" done +# Unavailable on IPv6. +! converse_with_echo_server \ + "(make-socket-address AF_INET6 IN6ADDR_LOOPBACK $PORT)" + $herd stop test-inetd ! converse_with_echo_server \ "(make-socket-address AF_INET INADDR_LOOPBACK $PORT)" +if guile -c '(socket AF_INET6 SOCK_STREAM 0)'; then + # Test IPv6 support. + $herd start test-inetd6 + + converse_with_echo_server \ + "(make-socket-address AF_INET6 IN6ADDR_LOOPBACK $PORT)" + converse_with_echo_server \ + "(make-socket-address AF_INET INADDR_LOOPBACK $PORT)" + + $herd stop test-inetd6 + + ! converse_with_echo_server \ + "(make-socket-address AF_INET6 IN6ADDR_LOOPBACK $PORT)" + ! converse_with_echo_server \ + "(make-socket-address AF_INET INADDR_LOOPBACK $PORT)" + + $herd start test-inetd-v6-only + + converse_with_echo_server \ + "(make-socket-address AF_INET6 IN6ADDR_LOOPBACK $PORT)" + ! converse_with_echo_server \ + "(make-socket-address AF_INET INADDR_LOOPBACK $PORT)" + + $herd stop test-inetd-v6-only + + ! converse_with_echo_server \ + "(make-socket-address AF_INET6 IN6ADDR_LOOPBACK $PORT)" + ! converse_with_echo_server \ + "(make-socket-address AF_INET INADDR_LOOPBACK $PORT)" +fi + # Now test inetd on a Unix-domain socket. $herd start test-inetd-unix -- 2.36.0
jackhill <at> jackhill.us, mail <at> cbaines.net, bug-guix <at> gnu.org
:bug#55335
; Package guix
.
(Wed, 18 May 2022 14:08:02 GMT) Full text and rfc822 format available.Message #49 received at 55335 <at> debbugs.gnu.org (full text, mbox):
From: Ludovic Courtès <ludo <at> gnu.org> To: 55335 <at> debbugs.gnu.org Cc: Ludovic Courtès <ludo <at> gnu.org> Subject: [PATCH Shepherd 0/3] Endpoints for inetd services + IPv6-only endpoints Date: Wed, 18 May 2022 16:06:42 +0200
Hi! Here’s a couple of changes to the Shepherd addressing the concerns Chris raised in <https://issues.guix.gnu.org/55335>: • ‘make-inetd-constructor’ now accepts a list of endpoints, like ‘make-systemd-constructor’, instead of a single address. • AF_INET6 endpoints are now interpreted as IPv6-only. I’ve pushed this in the Shepherd repo as ‘wip-inetd-ipv6’. You’re welcome to test that branch in Guix System VMs or something. Lemme know what you think! If it’s good, we can merge it and release the Shepherd 0.9.1 with this and other fixes that have accumulated. Ludo’. Ludovic Courtès (3): service: 'make-inetd-constructor' accepts a list of endpoints. tests: Update inetd tests to pass a list of endpoints. Interpret AF_INET6 endpoints as IPv6-only. NEWS | 24 +++ configure.ac | 12 ++ doc/shepherd.texi | 68 ++++---- modules/shepherd/service.scm | 274 +++++++++++++++++---------------- modules/shepherd/system.scm.in | 11 ++ tests/inetd.sh | 71 ++++++++- 6 files changed, 294 insertions(+), 166 deletions(-) base-commit: 05f169e896ea6520a8daebee68e5844e605526c4 -- 2.36.0
bug-guix <at> gnu.org
:bug#55335
; Package guix
.
(Wed, 18 May 2022 14:29:03 GMT) Full text and rfc822 format available.Message #52 received at 55335 <at> debbugs.gnu.org (full text, mbox):
From: Ludovic Courtès <ludo <at> gnu.org> To: 55335 <at> debbugs.gnu.org Subject: Re: bug#55335: openssh-service no longer listens on IPv6 Date: Wed, 18 May 2022 16:28:43 +0200
Ludovic Courtès <ludo <at> gnu.org> skribis: > + (make <service> > + #:provides '(test-inetd6) > + #:start (make-inetd-constructor %command > + (list > + (endpoint (make-socket-address > + AF_INET > + INADDR_LOOPBACK > + $PORT)) > + (endpoint (make-socket-address > + AF_INET6 > + IN6ADDR_LOOPBACK > + $PORT)))) > + #:stop (make-inetd-destructor)) > + (make <service> > + #:provides '(test-inetd-v6-only) > + #:start (make-inetd-constructor %command > + (list > + (endpoint (make-socket-address > + AF_INET6 > + IN6ADDR_LOOPBACK > + $PORT)))) > + #:stop (make-inetd-destructor)) I should point out that this new test hangs with Fibers 1.1.0; we need this fix: https://github.com/wingo/fibers/commit/c25dcb9cc4b5b977474ffe555b40ce2f1d0d1edc I’ve contacted Aleix to see if we could release Fibers 1.1.1. Otherwise we’ll use a snapshot in Guix. Ludo’.
Ludovic Courtès <ludo <at> gnu.org>
:Christopher Baines <mail <at> cbaines.net>
:Message #57 received at 55335-done <at> debbugs.gnu.org (full text, mbox):
From: Ludovic Courtès <ludo <at> gnu.org> To: 55335-done <at> debbugs.gnu.org, Christopher Baines <mail <at> cbaines.net>, Jack Hill <jackhill <at> jackhill.us> Subject: Re: bug#55335: openssh-service no longer listens on IPv6 Date: Sun, 22 May 2022 22:08:46 +0200
Hello! With Shepherd 0.9.1 released, I believe Guix commit d2b3400f79ffaed3357650307376ab69a7ec3b1b fixes this bug for good, also adding a system test for SSH access over IPv6 (both with OpenSSH and Dropbear). Let me know if anything’s amiss! Thanks, Ludo’.
bug-guix <at> gnu.org
:bug#55335
; Package guix
.
(Sun, 22 May 2022 22:36:01 GMT) Full text and rfc822 format available.Message #60 received at 55335-done <at> debbugs.gnu.org (full text, mbox):
From: Jack Hill <jackhill <at> jackhill.us> To: Ludovic Courtès <ludo <at> gnu.org> Cc: Christopher Baines <mail <at> cbaines.net>, 55335-done <at> debbugs.gnu.org Subject: Re: bug#55335: openssh-service no longer listens on IPv6 Date: Sun, 22 May 2022 18:35:43 -0400 (EDT)
[Message part 1 (text/plain, inline)]
On Sun, 22 May 2022, Ludovic Courtès wrote: > Hello! > > With Shepherd 0.9.1 released, I believe Guix commit > d2b3400f79ffaed3357650307376ab69a7ec3b1b fixes this bug for good, also > adding a system test for SSH access over IPv6 (both with OpenSSH and > Dropbear). > > Let me know if anything’s amiss! > > Thanks, > Ludo’. It's working well for me, allowing connections over both v4 and v6. I have another host that I can only access with a v6 via wireguard address, which I haven't been able to upgrade yet. I don't anticipate any problems there though. Many thanks! Jack
bug-guix <at> gnu.org
:bug#55335
; Package guix
.
(Mon, 23 May 2022 13:31:02 GMT) Full text and rfc822 format available.Message #63 received at 55335-done <at> debbugs.gnu.org (full text, mbox):
From: Ludovic Courtès <ludo <at> gnu.org> To: Jack Hill <jackhill <at> jackhill.us> Cc: Christopher Baines <mail <at> cbaines.net>, 55335-done <at> debbugs.gnu.org Subject: Re: bug#55335: openssh-service no longer listens on IPv6 Date: Mon, 23 May 2022 15:30:12 +0200
Hi Jack, Jack Hill <jackhill <at> jackhill.us> skribis: > It's working well for me, allowing connections over both v4 and v6. I > have another host that I can only access with a v6 via wireguard > address, which I haven't been able to upgrade yet. I don't anticipate > any problems there though. Good, thanks for reporting back! Ludo’.
bug-guix <at> gnu.org
:bug#55335
; Package guix
.
(Mon, 23 May 2022 15:30:02 GMT) Full text and rfc822 format available.Message #66 received at 55335 <at> debbugs.gnu.org (full text, mbox):
From: Simon Streit <simon <at> netpanic.org> To: 55335 <at> debbugs.gnu.org Cc: ludo <at> gnu.org, mail <at> cbaines.net Subject: Re: bug#55335: openssh-service no longer listens on IPv6 Date: Mon, 23 May 2022 17:29:15 +0200
Ludovic Courtès <ludo <at> gnu.org> writes: > Let me know if anything’s amiss! Looking all good. v4 and v6 connections are working now.
Debbugs Internal Request <help-debbugs <at> gnu.org>
to internal_control <at> debbugs.gnu.org
.
(Tue, 21 Jun 2022 11:24:04 GMT) Full text and rfc822 format available.
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.