-
-
Notifications
You must be signed in to change notification settings - Fork 412
Description
On a Linux system set up with both IPv4 and IPv6, I've used LISTEN * assuming it would mean any address. This has in fact only added a listener on IPv4 0.0.0.0 but did not add any IPv6 capability.
After some reading in https://stackoverflow.com/questions/27480094/ipv6-is-equivalent-to-0-0-0-0-when-listening-for-connections I've also checked that it works to use LISTEN 0.0.0.0 and LISTEN my.host.name (including an IPv6 setup when the hostname points to such address).
Finally, checked that for "any" address I can LISTEN :: or LISTEN ::0 which however disables the IPv4 listener at least on this system where IPv4-over-IPv6 is supported (what that SO discussion refers to as "a dual-stack listener bound to INADDR6_ANY", probably).
WARNING: Note that depending on line order, this can remove IPv6 support even though it is in config file; and even more confusingly the LAST active config line wins the race:
:; cat upsd.conf
DEBUG_MIN 6
LISTEN *
LISTEN ::
:; journalctl -flu nut-server
Aug 05 12:57:27 pve nut-server[2856573]: 0.000170 [D1] debug level is '6'
Aug 05 12:57:27 pve nut-server[2856573]: 0.000179 [D3] setuptcp: try to bind to :: port 3493
Aug 05 12:57:27 pve nut-server[2856573]: 0.000193 listening on :: port 3493
Aug 05 12:57:27 pve nut-server[2856573]: 0.000197 [D3] setuptcp: try to bind to * port 3493
Aug 05 12:57:27 pve nut-server[2856573]: 0.000263 [D3] setuptcp: bind: Address already in use
Aug 05 12:57:27 pve nut-server[2856573]: 0.000273 [D3] setuptcp: bind: Address already in use
Aug 05 12:57:27 pve nut-server[2856573]: 0.000278 not listening on * port 3493
...
Aug 05 12:57:27 pve systemd[1]: Started Network UPS Tools - power devices information server.
Aug 05 12:57:32 pve nut-server[2856573]: User upsmon@::ffff:127.0.0.1 logged into UPS [myups]
:; netstat -anp | grep 3493
tcp 0 0 127.0.0.1:38304 127.0.0.1:3493 ESTABLISHED 2790659/upsmon
tcp6 0 0 :::3493 :::* LISTEN 2856573/upsd
tcp6 0 0 127.0.0.1:3493 127.0.0.1:38304 ESTABLISHED 2856573/upsd
vs.
:; cat upsd.conf
DEBUG_MIN 6
LISTEN ::
LISTEN *
:; journalctl -flu nut-server
Aug 05 13:07:54 pve nut-server[2875736]: 0.000293 [D1] debug level is '6'
Aug 05 13:07:54 pve nut-server[2875736]: 0.000313 [D3] setuptcp: try to bind to * port 3493
Aug 05 13:07:54 pve nut-server[2875736]: 0.000430 listening on * port 3493
Aug 05 13:07:54 pve nut-server[2875736]: 0.000444 [D3] setuptcp: try to bind to :: port 3493
Aug 05 13:07:54 pve nut-server[2875736]: 0.000463 [D3] setuptcp: bind: Address already in use
Aug 05 13:07:54 pve nut-server[2875736]: 0.000478 not listening on :: port 3493
...
Aug 05 13:07:54 pve systemd[1]: Started Network UPS Tools - power devices information server.
Aug 05 13:08:02 pve nut-server[2875736]: User upsmon@127.0.0.1 logged into UPS [myups]
### Note there is no IPv6 listener
:; netstat -anp | grep 3493
tcp 0 0 0.0.0.0:3493 0.0.0.0:* LISTEN 2875736/upsd
tcp 0 0 127.0.0.1:55644 127.0.0.1:3493 ESTABLISHED 2790659/upsmon
tcp 0 0 127.0.0.1:3493 127.0.0.1:55644 ESTABLISHED 2875736/upsd
Note that it DOES work to specify two non-conflicting addresses, e.g. any for IPv4 and exact addr/hostname for IPv4:
:; journalctl -flu nut-server
Aug 05 13:02:10 pve nut-server[2868613]: listening on my.host.name port 3493
Aug 05 13:02:10 pve nut-server[2868613]: listening on * port 3493
...
Aug 05 13:02:17 pve nut-server[2868613]: User upsmon@127.0.0.1 logged into UPS [myups]
:; netstat -anp | grep 3493
tcp 0 0 0.0.0.0:3493 0.0.0.0:* LISTEN 2868613/upsd
tcp 0 0 127.0.0.1:3493 127.0.0.1:34290 ESTABLISHED 2868613/upsd
tcp 0 0 127.0.0.1:34290 127.0.0.1:3493 ESTABLISHED 2790659/upsmon
tcp6 0 0 1234:1234:1234:a00:3493 :::* LISTEN 2868613/upsd
Currently I do not see any hints about :: or ::0 in such role in the NUT docs, and I think that at least a few docs lines should be added, and maybe the LISTEN * activity (re-)defined to support actually all addresses according to currently handled address families.
:; git grep LISTEN | grep ::
conf/upsd.conf.sample:# LISTEN ::1 3493
docs/config-notes.txt: LISTEN ::1 3493
docs/man/upsd.conf.txt:"LISTEN 'interface' 'port'"::
docs/man/upsd.conf.txt:127.0.0.1 if no LISTEN addresses are specified (and ::1 if IPv6 support is
docs/man/upsd.conf.txt: LISTEN ::1
docs/security.txt:`127.0.0.1` if no LISTEN addresses are specified (and `::1` if IPv6 support is
docs/security.txt: LISTEN ::1
scripts/augeas/nutupsdconf.aug.in: * LISTEN 127.0.0.1 LISTEN 192.168.50.1 LISTEN ::1 LISTEN 2001:0db8:1234:08d3:1319:8a2e:0370:7344
For that matter, use of asterisk is also not specifically documented:
:; git grep LISTEN | grep '*'
scripts/augeas/nutupsdconf.aug.in: * LISTEN interface port
scripts/augeas/nutupsdconf.aug.in: * Multiple LISTEN addresses may be specified. The default is to bind to 0.0.0.0 if no LISTEN addresses are specified.
scripts/augeas/nutupsdconf.aug.in: * LISTEN 127.0.0.1 LISTEN 192.168.50.1 LISTEN ::1 LISTEN 2001:0db8:1234:08d3:1319:8a2e:0370:7344
server/conf.c: /* LISTEN <address> [<port>] */
server/upsd.c: * no other valid LISTEN interface */
server/upsd.c: /* default behaviour if no LISTEN addres has been specified */
server/upsd.c: /* check if we have at least 1 valid LISTEN interface */
The "any" names involved are not locally resolvable (I wondered if this could be why NUT only bound to IPv4 0.0.0.0):
:; getent hosts '0.0.0.0'
:; getent hosts '*'
:; getent hosts '::'
:; getent hosts '::0'
# IPv6 loopback for example IS resolvable:
:; getent hosts '::1'
::1 ip6-localhost ip6-loopback
CC @clepple @aquette : am I missing anything here? Does anything (older documented behaviors, least-surprise principle) preclude from just declaring and implementing a definitive behavior for LISTEN * lines?
Are there known systems where listening on both IPv4 0.0.0.0 and the "specifically unspecified" IPv6 address 0:0:0:0:0:0:0:0 a.k.a. :: is possible?
Is there some programmatic way (portable, or several for different OSes) to check for dual-stack support (e.g. to "know" we can march ahead grabbing :: or ::0 and it will handle IPv4 too... or just handle * by trying to take these two in this order)?