8

I would like Apache to listen on the link-local ipv6 address on a particular interface. I have the following line in my httpd.conf:

Listen [fe80::a00:16ff:fe89:420f]:80

Which is based on the Apache documentation here: https://httpd.apache.org/docs/2.4/bind.html "IPv6 addresses must be enclosed in square brackets"

My operating system/Apache version details are as follows:

$ httpd -v
Server version: Apache/2.4.18 (Unix)
Server built:   Dec 14 2015 08:05:54
$ uname -rv
4.3.3-3-ARCH #1 SMP PREEMPT Wed Jan 20 08:12:23 CET 2016

The result shown using journalctl -e is:

(22)Invalid argument: AH00072: make_sock: could not bind to address [fe80.....

IPv6 is working because I have sshd and dnsmasq listening. I have tried appending two different scope ID suffixes to the address. You can use either the interface id 3 or name net1 as a scopeid in both ping6 and sshd.

$ ip addr | grep -Po "^\d: \S+"
1: lo:
2: net0:
3: net1:

$ for scopeid in 3 net1; do ping6 -c 1 fe80::a00:16ff:fe89:420f%$scopeid; done | grep loss
1 packets transmitted, 1 received, 0% packet loss, time 0ms
1 packets transmitted, 1 received, 0% packet loss, time 0ms

sshd_config works with either: ListenAddress fe80::a00:16ff:fe89:420f%3

or: ListenAddress fe80::a00:16ff:fe89:420f%net1

So with all this in mind I tried the following in httpd.conf

Listen [fe80::a00:16ff:fe89:420f%3]:80

and Listen [fe80::a00:16ff:fe89:420f%net1]:80

Adding either scopeid made Apache fail earlier in its start up process. journalctl -e shows a syntax error when parsing httpd.conf as follows:

AH00526: Syntax error on line 52 of /etc/httpd/conf/httpd.conf:
Scope id is not supported

Apache listens on the localhost ipv6 if I do Listen [::1]:80

I would expect Listen 80 to get Apache to bind to both ipv4 and ipv6, but it doesn't. It only binds to ipv6 addresses - netstat shows:

tcp6  0  0    :::80    :::*     LISTEN

In this case, Apache does accept requests on the link-local address on net1. I have to specify 0.0.0.0:80 or a specific ipv4 address for it to listen on ipv4.

So, how do I make Apache bind to one specific link-local address (not all of them - I want to avoid listening on other interfaces), or is it just not possible for Apache to listen on a link-local ipv6 address?

4
  • Is your interface named 1 or net1? Either seems unlikely, so it's unclear why you attempted to use these. Commented Jan 22, 2016 at 23:17
  • 1
    You didn't include the scope in the link-local address. You need to do that sine the same link-local subnet is on all interfaces, and the scope determines which interface to use. Unfortunately, not all applications can use an address with the scope attached, and those applications basically cannot use specific link-local addresses.
    – Ron Maupin
    Commented Jan 23, 2016 at 1:33
  • The error message Scope id is not supported certainly suggests that it isn't supported - at least not with the version of Apache that you are using. I couldn't get Apace to do it either. Listening on :: will accept connections over link-local addresses, that's about as close to an answer as I can get. Any more definitive answer than that would have to be based on a reading of the actual source code.
    – kasperd
    Commented Jan 23, 2016 at 15:24
  • 1
    Thanks kasperd, I tried one last thing before resorting to the source code and it worked, so I've added an answer below.
    – bao7uo
    Commented Jan 23, 2016 at 18:15

1 Answer 1

6

Having spent some time on this it seems that the Apache documentation could be misleading, although I may have missed something. It says IPv6 addresses must be enclosed in square brackets. This is true for non link-local addresses. But I have now discovered that link-local addresses can be used, and must include a scope id, but without the square brackets. See below:

Apache documentation:

$ wget -q -O- https://httpd.apache.org/docs/2.4/bind.html | grep -Pao "(?<=p.)IPv6[ a-z]+"
IPv6 addresses must be enclosed in square brackets

My configuration:

$ grep -R ^Listen /etc/httpd/conf/
/etc/httpd/conf/httpd.conf:Listen fe80::a00:16ff:fe89:420f%3:80
/etc/httpd/conf/extra/httpd-ssl.conf:Listen fe80::a00:16ff:fe89:420f%net1:443

As you can see, I've used the interface id for the scope id with port 80, and the interface name for the scope id with port 443. This is just to show that either the interface id or name can successfully be used as the scope id.

Results:

$ sudo netstat -pant | grep -i httpd
tcp6   0    0 fe80::a00:16ff:fe89::80 :::*  LISTEN   709/httpd
tcp6   0    0 fe80::a00:16ff:fe89:443 :::*  LISTEN   709/httpd
4
  • 1
    +1 Good find. Although I would consider this more of a bug than a feature.
    – Dubu
    Commented Jan 24, 2016 at 22:51
  • It doesn't seem to be a bug - curl and apache and presumably more all seem to use the same syntax. If link local, you drop the [] and add %eth0 for example. Great find though, this was a life saver.
    – Goblinhack
    Commented Apr 13, 2016 at 15:25
  • Can confirm that the no-brackets, explicit-interface syntax works. On my instance, I have Listen fe80::20c:29ff:fe53:2218%eth0:443 and it works perfectly. Commented Jul 28, 2017 at 18:03
  • This works for ListenAddress in sshd_config! ... This feels wrong, like am I able to specify interface or not...oh well
    – Ray Foss
    Commented Jan 29, 2020 at 19:58

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .