Bug 55098

Summary: does not listen to IP4 when both IP4 address and IP6 wild card address is used on host where IP6 is not bridged to IP4
Product: Apache httpd-2 Reporter: Kiri <hohyeis>
Component: CoreAssignee: Apache HTTPD Bugs Mailing List <bugs>
Status: NEW ---    
Severity: normal    
Priority: P2    
Version: 2.4.4   
Target Milestone: ---   
Hardware: All   
OS: All   

Description Kiri 2013-06-13 09:18:03 UTC
Specifying a "Listen" directive which results in binding to the IPV6 wild card address will cause Apache HTTPD to not bind to the IPV4 address. On hosts where IPV6 data is not routed to corresponding IPV4 ports, this causes HTTPD to be unreachable by IPV4.

When the IPV4 address is the wild card address, no error is emitted and the server runs.

When the IPV4 address is a specific address, an error is emitted and the server ends without fully starting service. The latter address is excluded by the former.
An example error message is:

(98)Address already in use: AH00072: make_sock: could not bind to address 127.0.0.1:80
no listening sockets available, shutting down

An example combination of directives causing that error is

Listen [::]:80
Listen 127.0.0.1:80

An example combination of directives for the wild card addresses is

Listen 0.0.0.0:80
Listen [::]:80

On Linux, setting
sysctl net.ipv6.bindv6only=1
causes the IPV6 and IPV4 protocols not to be bridged.
net.ipv6.bindv6only=0
, which is the default, causes them to be bridged.
Comment 1 Joe Orton 2013-06-13 18:58:26 UTC
You need to be more precise about what you think the bug is.

By default httpd enables v4mapped connections on inet6 sockets on Linux.  This is a configure-time option, --disable-v4-mapped disables it.

When v4mapped support is enabled, the v6only option is turned off on listening inet6 sockets.

In this case, with the configuration you specify, the kernel will fail to bind().  That is expected.
Comment 2 Kiri 2013-06-13 20:21:45 UTC
Looking at
apachectl -V
, it appears that
--disable-v4-mapped
was not used at compile time, as there is no '-D' set for it.

In the environment and configuration I write about, bridging from IP6 to IP4 does not happen by default because
sysctl net.ipv6.bindv6only=1
is set.

I have just tried to see whether apache setting those socket options caused the connections to be bridged or mapped. It does not. That is a good thing because if it did, it would be a security hole.

Since, as desired, incoming IP4 connections are not connected to IP6 listening ports in this configuration,
the network addresses for IP4 and IP6 are effectively fully separated (presuming there is no bug in Linux).

As a consequence, a TCP connection attempting to connect to 127.0.0.1:80 will not reach a listener on [::]:80.
Comment 3 Joe Orton 2013-06-14 08:38:14 UTC
httpd does always override the sysctl setting on Linux.  I don't remember why...  It doesn't seem particularly desirable, at least on Linux, especially since the Linux default is the same as the httpd default and httpd has no run-time override.
Comment 4 Kiri 2013-06-18 09:44:52 UTC
> httpd does always override the sysctl setting on Linux.

That is not working or causing Linux to receive IPV4 connections to an IPV6 socket. If it were working that way or is under some circumstances, it would be better to change it.

Better would be either to use default behaviour for the OS or, 
if Apache does set behaviour for IPV 4 to 6 mapping,
to set it to not bridge/map between the two.

Currently it is working neither as mapped nor as unmapped. 
(with the described system configuration.)