Package: openssh-server
Version: 1:4.3p2-10
Severity: normal
Hi,
I started to get mysterious messages in my auth.log like this:
May 5 08:52:09 lh sshd[27269]: error: Failed to allocate internet-domain X11 display socket.
and decided to investigate why it fails. The debug output of sshd is
at least not immediately very helpful (at least if you don't know of
EADDRNOTAVAIL and recognize its string form):
------------------------------------------------------------
[...]
debug1: session_input_channel_req: session 0 req x11-req
debug2: bind port 6010: Cannot assign requested address
debug2: bind port 6011: Cannot assign requested address
debug2: bind port 6012: Cannot assign requested address
debug2: bind port 6013: Cannot assign requested address
debug2: bind port 6014: Cannot assign requested address
debug2: bind port 6015: Cannot assign requested address
debug2: bind port 6016: Cannot assign requested address
[...]
debug2: bind port 6998: Cannot assign requested address
debug2: bind port 6999: Cannot assign requested address
Failed to allocate internet-domain X11 display socket.
debug1: x11_create_display_inet failed.
[...]
------------------------------------------------------------
What happens is that in x11_create_display_inet() (channels.c),
getaddrinfo() apparently returns the IPv6 address family first, and
sshd only tries to bind to that. However I have no IPv6 address, but
IPv6 is enabled in the kernel:
------------------------------------------------------------
$ ifconfig
eth0 Link encap:Ethernet HWaddr 00:17:31:BC:14:5F
inet addr:82.130.40.84 Bcast:82.130.40.127 Mask:255.255.255.192
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:11664235 errors:272 dropped:0 overruns:0 frame:0
TX packets:4679903 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:7295902428 (6.7 GiB) TX bytes:1215730740 (1.1 GiB)
Interrupt:23 Base address:0xe000
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:3023153 errors:0 dropped:0 overruns:0 frame:0
TX packets:3023153 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:2334865217 (2.1 GiB) TX bytes:2334865217 (2.1 GiB)
------------------------------------------------------------
Hence, bind() to ::1 returns EADDRNOTAVAIL. From strace output:
------------------------------------------------------------
2410 socket(PF_INET6, SOCK_STREAM, IPPROTO_TCP) = 9
2410 setsockopt(9, SOL_IPV6, IPV6_V6ONLY, [1], 4) = 0
2410 setsockopt(9, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
2410 bind(9, {sa_family=AF_INET6, sin6_port=htons(6010), inet_pton(AF_INET6, "::1", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, 28) = -1 EADDRNOTAVAIL (Cannot assign requested address)
2410 write(2, "debug2: bind port 6010: Cannot a"..., 57) = 57
2410 close(9) = 0
2410 close(8) = 0
2410 socket(PF_NETLINK, SOCK_RAW, 0) = 8
2410 bind(8, {sa_family=AF_NETLINK, pid=0, groups=00000000}, 12) = 0
2410 getsockname(8, {sa_family=AF_NETLINK, pid=2410, groups=00000000}, [12]) = 0
2410 sendto(8, "\24\0\0\0\26\0\1\3j$<F\0\0\0\0\0\0\0\0", 20, 0, {sa_family=AF_NETLINK, pid=0, groups=00000000}, 12) = 20
2410 recvmsg(8, {msg_name(12)={sa_family=AF_NETLINK, pid=0, groups=00000000}, msg_iov(1)=[{"0\0\0\0\24\0\2\0j$<Fj\t\0\0\2\10\200\376\1\0\0\0\10\0\1"..., 4096}], msg_controllen=0, msg_flags=0}, 0) = 108
2410 recvmsg(8, {msg_name(12)={sa_family=AF_NETLINK, pid=0, groups=00000000}, msg_iov(1)=[{"\24\0\0\0\3\0\2\0j$<Fj\t\0\0\0\0\0\0\1\0\0\0\10\0\1\0\177"..., 4096}], msg_controllen=0, msg_flags=0}, 0) = 20
2410 close(8) = 0
2410 socket(PF_INET6, SOCK_DGRAM, IPPROTO_IP) = 8
2410 connect(8, {sa_family=AF_INET6, sin6_port=htons(6011), inet_pton(AF_INET6, "::1", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, 28) = -1 ENETUNREACH (Network is unreachable)
2410 close(8) = 0
2410 socket(PF_INET, SOCK_DGRAM, IPPROTO_IP) = 8
2410 connect(8, {sa_family=AF_INET, sin_port=htons(6011), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
2410 getsockname(8, {sa_family=AF_INET, sin_port=htons(45259), sin_addr=inet_addr("127.0.0.1")}, [8589934608]) = 0
2410 close(8) = 0
2410 socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 8
2410 setsockopt(8, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
2410 bind(8, {sa_family=AF_INET, sin_port=htons(6011), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
2410 socket(PF_INET6, SOCK_STREAM, IPPROTO_TCP) = 9
2410 setsockopt(9, SOL_IPV6, IPV6_V6ONLY, [1], 4) = 0
2410 setsockopt(9, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
2410 bind(9, {sa_family=AF_INET6, sin6_port=htons(6011), inet_pton(AF_INET6, "::1", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, 28) = -1 EADDRNOTAVAIL (Cannot assign requested address)
2410 write(2, "debug2: bind port 6011: Cannot a"..., 57) = 57
[...]
------------------------------------------------------------
>From how I read x11_create_display_inet(), it takes the first IPv*
address family given by getaddrinfo() and only tries to bind to that:
------------------------------------------------------------
2820 #ifndef DONT_TRY_OTHER_AF
2821 if (num_socks == NUM_SOCKS)
2822 break;
2823 #else
2824 if (x11_use_localhost) {
2825 if (num_socks == NUM_SOCKS)
2826 break;
2827 } else {
2828 break;
2829 }
2830 #endif
------------------------------------------------------------
In my case, X11UseLocalhost is enabled so the break on line 2826 is
eventually taken after all bind()s to a nonexistent interface have
failed.
I discovered the behavior of getaddrinfo() can apparently be
controlled by editing /etc/gai.conf (which is somewhat cryptic to me
as I don't know the IPv6 address scheme very well, and which curiously
has no man page), but even after following the advice there ("For
sites which prefer IPv4 connections change the last line to precedence
::ffff:0:0/96 100") the situation did not change, apparently IPv6 is
still reported first and sshd only tries to bind to that. This might
be a separate bug in e.g. /etc/gai.conf comments. This is what I have
in /etc/gai.conf now:
------------------------------------------------------------
# the defaults, according to the comments
label ::1/128 0
label ::/0 1
label 2002::/16 2
label ::/96 3
label ::ffff:0:0/96 4
label fec0::/10 5
label fc00::/7 6
# still defaults
precedence ::1/128 50
precedence ::/0 40
precedence 2002::/16 30
precedence ::/96 20
# and this is what I changed:
precedence ::ffff:0:0/96 100
------------------------------------------------------------
Perhaps x11_create_display_inet() should be modified to try the other
IPv* address family if bind()ing to the first one fails (and if
getaddrinfo() returns it). In the least I suggest making the error
messages more informative. There's no way I could have got a clue
about why it fails without stracing sshd or reading the source.
Sami
-- System Information:
Debian Release: lenny/sid
APT prefers unstable
APT policy: (500, 'unstable')
Architecture: amd64 (x86_64)
Kernel: Linux 2.6.20.4-grsec-sli
Locale: LANG=C, LC_CTYPE=fi_FI@euro (charmap=ISO-8859-15)
Shell: /bin/sh linked to /bin/bash
Versions of packages openssh-server depends on:
ii addus 3.102 Add and remove users and groups
ii debco 1.5.13 Debian configuration management sy
ii dpkg 1.13.25 package maintenance system for Deb
ii libc6 2.5-5 GNU C Library: Shared libraries
ii libco 1.39+1.40-WIP-2006.11.14+dfsg-2+b1 common error description library
ii libkr 1.6.dfsg.1-2 MIT Kerberos runtime libraries
ii libpa 0.79-4 Pluggable Authentication Modules f
ii libpa 0.79-4 Runtime support for the PAM librar
ii libpa 0.79-4 Pluggable Authentication Modules l
ii libse 2.0.8-1 SELinux shared libraries
ii libss 0.9.8e-4 SSL shared libraries
ii libwr 7.6.dbs-13 Wietse Venema's TCP wrappers libra
ii opens 1:4.3p2-10 Secure shell client, an rlogin/rsh
ii zlib1 1:1.2.3-13 compression library - runtime
openssh-server recommends no packages.
-- debconf information:
ssh/insecure_rshd:
ssh/insecure_telnetd:
ssh/new_config: true
* ssh/use_old_init_script: true
* ssh/disable_cr_auth: false
ssh/encrypted_host_key_but_no_keygen:
Attachment:
signature.asc
Description: Digital signature