[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#422327: openssh-server: Fails to bind port for X11 forwarding, ipv4/ipv6 mess



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


Reply to: