Dear Maintainer, I have a repository server running on fe80::1, which is easy to access for new systems because of IPv6 SLAAC -- normally, this just works. Since I upgraded to Jessie, I cannot reach it via apt anymore, because apt sends invalid Host: headers: | # apt -o Debug::Acquire::http=yes update [...] | GET /dists/test-base/Release HTTP/1.1 | Host: [fe80::1%tap0]:8080 | Cache-Control: max-age=0 | Accept: text/* | User-Agent: Debian APT-HTTP/1.3 (1.0.9.8.3) This results in a "bad request" from Apache 2.2 on the server. RFC 7230, section "5.4. Host" tells us: Host = uri-host [ ":" port ] And "uri-host" references "host" in RFC 3986, section "3.2.2. Host". To be concise: IPv6 addresses shall be written as groups of four hexadecimal digits in square brackets, but the interface identifier should be left out. (BTW: it has no meaning to the server, as it is local to the client.) Therefore I believe apt should strip out interface identifiers when constructing Host headers, while it should still use them to create the TCP connection.
Hi!
apt 3.0.1 still displays this behaviour: interface name ("ens3" in my
case) is visible in value of "Host" header (which is also visible in
HTTP GET method in wireshark).
acerion@debian:~$ grep CODENAME /etc/os-release
VERSION_CODENAME=trixie
acerion@debian:~$ apt --version
apt 3.0.1 (amd64)
acerion@debian:~$ cat /etc/apt/sources.list
deb [trusted=yes] http://[fe80::201:2ff:fe01:101%ens3]/12 ./
acerion@debian:~$ sudo apt -o Debug::Acquire::http=yes update
[...]
0% [Working]GET /12/./Release HTTP/1.1
Host: [fe80::201:2ff:fe01:101%ens3]
Cache-Control: max-age=0
Accept: text/*
User-Agent: Debian APT-HTTP/1.3 (3.0.1)
Answer for: http://[fe80::201:2ff:fe01:101%ens3]/12/./Release
HTTP/1.1 200 OK
Server: nginx/1.22.1
Date: Fri, 02 May 2025 14:03:14 GMT
Content-Type: application/octet-stream
Content-Length: 228
Last-Modified: Tue, 08 Apr 2025 18:11:40 GMT
Connection: keep-alive
ETag: "67f566dc-e4"
Accept-Ranges: bytes
Get:2 http://[fe80::201:2ff:fe01:101%ens3]/12 ./ Release [228 B]
As you can see, nginx/1.22.1 handles the GET method with interface name
in "Host" header without problems (which doesn't mean that such
behaviour of apt is fine). I didn't try this with current version of
Apache.
I've looked at two other pieces of software: wget and curl. It looks
like wget doesn't support zone identifiers in IPv6 address literals in
host names, but curl does, and curl doesn't send the zone identifier in
the HTTP header.
Here is one of relevant commits to curl:
https://github.com/curl/curl/commit/bdb2dbc103
It looks like curl is storing the proper part of hostname and the zone
id in "connection" structure for later use. It's important to notice
how lib/url.c/zonefrom_url() sets value of conn->scope_id integer, and
how the integer is later assigned to sa6->sin6_scope_id.
Related links:
https://datatracker.ietf.org/doc/html/rfc6874
https://datatracker.ietf.org/doc/html/rfc4007#section-11
https://bugzilla.mozilla.org/show_bug.cgi?id=700999
Kamil