Hi, We recently experienced a bug on berlin.guix where we’d be locked out of SSH access because shepherd (0.9.1) would say that the maximum connection number on the sshd inetd service had been reached.
That threshold is a feature (see ‘max-connections’ in <openssh-configuration>) but there’s a possibility in this case that a bug in ‘make-inetd-constructor’ or thereabout led it to get a wrong idea of the number of active connections. Unfortunately, we lack syslogs that would give us info about the time where inetd connections started accumulating¹. I tried to come up with a scenario that could lead to that problem with the test below, to no avail. If you’ve experienced something similar, or if you noticed that ‘sshd-*’ services have accumulated on a server of yours, please let us know! Thanks, Ludo’. ¹ That, in turn, was a bug in the rottlog default config, fixed in e5a6900baf758a12024283171bf45f2fe90121ee.
diff --git a/tests/inetd.sh b/tests/inetd.sh index 0301b68..894ce98 100644 --- a/tests/inetd.sh +++ b/tests/inetd.sh @@ -77,6 +77,15 @@ cat > "$conf" <<EOF (endpoint (make-socket-address AF_UNIX "$service_socket"))) #:max-connections 5) + #:stop (make-inetd-destructor)) + (make <service> + #:provides '(test-inetd-fail) + #:start (make-inetd-constructor '("$(type -P false)") + (list + (endpoint (make-socket-address + AF_INET + INADDR_LOOPBACK + $PORT)))) #:stop (make-inetd-destructor))) (start 'test-inetd) @@ -95,6 +104,11 @@ file_descriptor_count () ls -l /proc/$shepherd_pid/fd/[0-9]* | wc -l } +# Trigger startup of the finalizer thread, which creates a couple of pipes. +# That way, those extra file descriptors won't influence the comparison with +# INITIAL_FD_COUNT done at the end. +$herd eval root '(gc)' + initial_fd_count=$(file_descriptor_count) $herd status test-inetd | grep started @@ -203,3 +217,16 @@ $herd status # At this point, shepherd should have INITIAL_FD_COUNT - 1 file descriptors # opened. test $(file_descriptor_count) -lt $initial_fd_count + +# Now test a service that fails as soon as it's passed an incoming connection. +$herd start test-inetd-fail +for i in $(seq 1 10) +do + $herd status + test $($herd status | grep '\+' | wc -l) -eq 2 + ! converse_with_echo_server \ + "(make-socket-address AF_INET INADDR_LOOPBACK $PORT)" +done + +$herd stop test-inetd-unix +test $(file_descriptor_count) -lt $initial_fd_count