BUG: Version 3.7.4 option 'DontCache' results in bad HOST header being sent upstream.
Version: 3.7.4-1
Distro: Gentoo
src_uri: https://salsa.debian.org/blade/apt-cacher-ng/-/archive/debian/3.7.4-1/apt-cacher-ng-debian-3.7.4-1.tar.gz
Gentoo Bug: #878833
Possible Related Debian Bug: #1023388
The previous version 3.6.3-1 did not exhibit this bug, unfortunately that version has been dropped from the Gentoo repos.
When the option 'DontCache' is present any request that matches will be passed to upstream web server with mangled headers, at least HOST and User-Agent, but other headers could similarly be mangled.
In the failed requests (status 400) the web server is unable to handle the request with the intended vhost as:
HOST header: "rsync.localdomain, rsync.localdomain"
or HOST header: "pki.localdomain, pki.localdomain"
The User-Agent was similarly mangled, but that would not have impacted the web server's ability to properly respond
User-Agent header: "Apt-Cacher-NG/3.7.4, curl/7.87.0"
or User-Agent header: "Apt-Cacher-NG/3.7.4, Wget/1.21.3"
This "comma space" separated host list results in the web server (at least apache2) responding with 400 "Bad Request"
I note that ExposeOrigin: 0
and ExposeOrigin: 1
had the exact same result.
I have not tested this with a debug build, and so apt-cacher.log and apt-cacher.err do not contain any more enlightening information.
eg: apt-cacher.log
1676965369|M|Download of gentoo/distfiles/zip30.zip started
1676965369|I|166|127.0.0.1|gentoo/distfiles/zip30.zip [HTTP error, code: 400]
1676965369|E|166|127.0.0.1|gentoo/distfiles/zip30.zip [HTTP error, code: 400]
eg: apt-cacher.err
Tue Feb 21 18:42:49 2023|Detected incoming connection from the TCP socket
Tue Feb 21 18:42:49 2023|Client name: 127.0.0.1:41430
Tue Feb 21 18:42:49 2023|Decoded request URI: http://rsync.localdomain/gentoo/distfiles/zip30.zip
Tue Feb 21 18:42:49 2023|Processing new job, http://rsync.localdomain/gentoo/distfiles/zip30.zip
Tue Feb 21 18:42:49 2023|Download started, storeHeader for gentoo/distfiles/zip30.zip, current status: 1
For the examples below both versions of apt-cacher-ng (3.6.3-1 and 3.7.4-1) have:
DontCache: www.localdomain rsync.localdomain /distfiles/layout\.conf
For the web server log snippets below the format is:
<client> <ident> <user> <time> <"request"> <status> <size> <referer> <"User-Agent header"> <HOST="Host header">
I have not included the curl / wget cli output as the logging from the local web servers is more relevant (whether the cli client actually downloaded the requested resource can be inferred from the web server's status response in these test cases)
request direct to rsync web server (to show expected server log)
$ curl http://rsync.localdomain/gentoo/distfiles/zip30.zip -o zip30.zip
# RSYNC server, rsync vhost
10.1.1.10 - - [21/Feb/2023:16:02:41 +1100] "GET /gentoo/distfiles/zip30.zip HTTP/1.1" 200 1287223 "-" "curl/7.87.0" HOST="rsync.localdomain"
# file downloaded
request via working apt-cacher-ng (3.6.3-1) running on rsync.localdomain
$ curl http://rsync.localdomain/gentoo/distfiles/zip30.zip -o zip30.zip -x "http://rsync.localdomain:3142"
# RSYNC server, rsync vhost
10.1.1.11 - - [21/Feb/2023:16:03:16 +1100] "GET /gentoo/distfiles/zip30.zip HTTP/1.1" 200 1287223 "-" "Apt-Cacher-NG/3.6.3" HOST="rsync.localdomain"
# file downloaded
request via apt-cacher-ng (3.7.4-1) running on localhost
Note that the rsync.localdomain vhost never saw the request: the default / fallback vhost handled the request
$ curl http://rsync.localdomain/gentoo/distfiles/zip30.zip -o zip30.zip -x "http://localhost:3142"
# RSYNC server, **FALLBACK** vhost
10.1.1.10 - - [21/Feb/2023:16:03:30 +1100] "GET /gentoo/distfiles/zip30.zip HTTP/1.1" 400 294 "-" "Apt-Cacher-NG/3.7.4, curl/7.87.0" HOST="rsync.localdomain, rsync.localdomain"
# failed - 400 response received
modifying localhost apt-cacher-ng to have (i.e. remove rsync vhost):
DontCache: www.localdomain /distfiles/layout\.conf
request via apt-cacher-ng (3.7.4-1) running on localhost
succeeds, of course the file is also copied into cache, which is unwanted
$ curl http://rsync.localdomain/gentoo/distfiles/zip30.zip -o zip30.zip -x "http://localhost:3142"
# RSYNC server, rsync vhost
10.1.1.10 - - [21/Feb/2023:16:04:10 +1100] "GET /gentoo/distfiles/zip30.zip HTTP/1.1" 200 1287223 "-" "Apt-Cacher-NG/3.7.4" HOST="rsync.localdomain"
# file downloads **BUT is also copied into apt-cacher-ng cache**
request via apt-cacher-ng (3.7.4-1) running on localhost
on Gentoo the /distfiles/layout.conf must not be cached, the package manager needs it to be current to accurately understand the mirror's directory layout (flat vs hashed)
$ curl http://rsync.localdomain/gentoo/distfiles/layout.conf -o layout.conf -x "http://localhost:3142"
# RSYNC server, **FALLBACK** vhost
10.1.1.10 - - [21/Feb/2023:16:04:34 +1100] "GET /gentoo/distfiles/layout.conf HTTP/1.1" 400 294 "-" "Apt-Cacher-NG/3.7.4, curl/7.87.0" HOST="rsync.localdomain, rsync.localdomain"
# failed - 400 response received
After reading the Debian bug listed above (1023388) I performed some additional tests
The hostname (pki.localdomain) is not listed in "DontCache" nor are any of the request URIs
# All responses: PKI server, **FALLBACK** vhost
$ http_proxy=http://localhost:3142/ wget http://pki.localdomain/
10.1.1.10 - - [21/Feb/2023:18:50:42 +1100] "GET / HTTP/1.1" 400 294 "-" "Apt-Cacher-NG/3.7.4, Wget/1.21.3" HOST="pki.localdomain, pki.localdomain"
$ http_proxy=http://localhost:3142/ wget http://pki.localdomain/ssl/
10.1.1.10 - - [21/Feb/2023:18:52:10 +1100] "GET /ssl/ HTTP/1.1" 400 294 "-" "Apt-Cacher-NG/3.7.4, Wget/1.21.3" HOST="pki.localdomain, pki.localdomain"
$ http_proxy=http://localhost:3142/ wget http://pki.localdomain
10.1.1.10 - - [21/Feb/2023:18:59:11 +1100] "GET / HTTP/1.1" 400 294 "-" "Apt-Cacher-NG/3.7.4, Wget/1.21.3" HOST="pki.localdomain, pki.localdomain"
So it appears whatever is mangling the requests that match "DontCache" is also mangling requests to a path name URI.
What is interesting is if I use a (non-root) pathname request without the trailing '/'
# All responses: PKI server, pki vhost
$ http_proxy=http://localhost:3142/ wget http://pki.localdomain/ssl
10.1.1.10 - - [21/Feb/2023:18:52:11 +1100] "GET /ssl HTTP/1.1" 301 306 "-" "Apt-Cacher-NG/3.7.4" HOST="pki.localdomain"
10.1.1.10 - - [21/Feb/2023:18:52:11 +1100] "GET /ssl/ HTTP/1.1" 200 1410 "-" "Apt-Cacher-NG/3.7.4" HOST="pki.localdomain"
# successfully downloaded a html file
Here apt-cacher-ng receives a redirect (301), parses it, and follows the new "pathname" without mangling the User-Agent or Host headers.
apt-cacher-ng.conf
CacheDir: /var/cache/apt-cacher-ng
LogDir: /var/log/apt-cacher-ng
SupportDir: /usr/lib/apt-cacher-ng
Remap-debrep: file:deb_mirror*.gz /debian ; file:backends_debian # Debian Archives
Remap-uburep: file:ubuntu_mirrors /ubuntu ; file:backends_ubuntu # Ubuntu Archives
Remap-klxrep: file:kali_mirrors /kali ; file:backends_kali # Kali Linux Archives
Remap-cygwin: file:cygwin_mirrors /cygwin # ; file:backends_cygwin # incomplete, please create this file or specify preferred mirrors here
Remap-sfnet: file:sfnet_mirrors /sfnet # ; file:backends_sfnet # incomplete, please create this file or specify preferred mirrors here
Remap-alxrep: file:archlx_mirrors /archlinux # ; file:backend_archlx # Arch Linux
Remap-fedora: file:fedora_mirrors # Fedora Linux
Remap-epel: file:epel_mirrors # Fedora EPEL
Remap-slrep: file:sl_mirrors # Scientific Linux
Remap-secdeb: security.debian.org security.debian.org/debian-security deb.debian.org/debian-security /debian-security ; deb.debian.org/debian-security security.debian.org
Remap-gentoo: file:gentoo_mirrors_au.gz /gentoo # Gentoo Archives
ReportPage: acng-report.html
VerboseLog: 1
ExThreshold: 7
FollowIndexFileRemoval: 0
Debug: 7
ExposeOrigin: 0
LocalDirs: acng-doc /usr/share/doc/apt-cacher-ng-3.7.4_p1-r2
ConnectProto: v4 v6
gentoo.conf
PfilePatternEx: .*
VfilePatternEx: /distfiles/layout\.conf
SVfilePatternEx: /distfiles/layout\.conf
PassThroughPattern: keys\.gentoo\.org:443$
DontCache: www.localdomain rsync.localdomain /distfiles/layout\.conf