1. The problem I’m having:
We are using Caddy as a forward proxy with following plugin GitHub - caddyserver/forwardproxy: Forward proxy plugin for the Caddy web server.
When we call some domain, that redirects to other domain Caddy logs have “status 0”:
curl -I https://tableau.com --proxy http://proxy.host.local:3128
HTTP/1.1 200 OK
Server: Caddy
Content-Length: 0
HTTP/1.1 301 Moved Permanently
Server: AkamaiGHost
Content-Length: 0
Location: https://www.tableau.com/
Date: Mon, 26 Aug 2024 16:04:36 GMT
Connection: keep-alive
Invoke-WebRequest -uri https://tableau.com -Proxy http://proxy.host.local:3128
Invoke-RestMethod :
Access Denied
Access Denied
You don't have permission to access "http://tableau.com/" on this server.
Reference #18.c1ec655f.1724687930.59bb8bf
https://errors.edgesuite.net/18.c1ec655f.1724687930.59bb8bf
At line:1 char:2
+ (Invoke-RestMethod -uri https://tableau.com -Proxy http://proxy.host.local ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
The question is it possible to see any other “status” in logs like 301/307 (or any other “msg” instead of “handled request”) as sometimes it is a bit hard to troubleshoot?
2. Error messages and/or full log output:
Aug 26 15:39:20 proxy.host.local caddy[6184]: {"level":"info","ts":1724686760.250102,"logger":"http.log.access.json","msg":"handled request","request":{"remote_ip":"10.0.100.161","remote_port":"37292","client_ip":"10.0.100.161","proto":"HTTP/1.1","method":"CONNECT","host":"tableau.com:443","uri":"tableau.com:443","headers":{"User-Agent":["curl/7.61.1"],"Proxy-Connection":["Keep-Alive"]}},"bytes_read":0,"user_id":"","duration":0.157647736,"size":4638,"status":0,"resp_headers":{"Server":["Caddy"]}}
Aug 26 16:08:18 proxy.host.local caddy[6184]: {"level":"info","ts":1724688498.070776,"logger":"http.log.access.json","msg":"handled request","request":{"remote_ip":"10.0.109.144","remote_port":"50460","client_ip":"10.0.109.144","proto":"HTTP/1.1","method":"CONNECT","host":"tableau.com:443","uri":"tableau.com:443","headers":{"User-Agent":["Mozilla/5.0 (Windows NT; Windows NT 10.0; en-GB) WindowsPowerShell/5.1.17763.6054"]}},"bytes_read":0,"user_id":"","duration":0.251075173,"size":4579,"status":0,"resp_headers":{"Server":["Caddy"]}}
3. Caddy version:
caddy --version
v2.7.5 h1:HoysvZkLcN2xJExEepaFHK92Qgs7xAiCFydN5x5Hs6Q=
caddy list-modules --versions
http.handlers.forward_proxy v0.0.0-20231105195054-31f01c98cad1
4. How I installed and ran Caddy:
a. System environment:
Operating System: Oracle Linux Server 8.10
Kernel: Linux 5.15.0-3.60.5.1.el8uek.x86_64
Architecture: x86-64
b. Command:
see below
c. Service/unit/compose file:
# cat /etc/systemd/system/caddy.service
[Unit]
Description=Caddy
Documentation=https://caddyserver.com/docs/
After=network.target network-online.target
Requires=network-online.target
[Service]
Type=notify
User=caddy
Group=caddy
ExecStart=/usr/local/bin/caddy run --environ --config /etc/caddy/Caddyfile
ExecReload=/usr/local/bin/caddy reload --config /etc/caddy/Caddyfile --force
TimeoutStopSec=5s
LimitNOFILE=1048576
LimitNPROC=512
PrivateTmp=true
ProtectSystem=full
AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE
[Install]
WantedBy=multi-user.target
# cat /etc/systemd/system/caddy.service.d/overrides.conf
[Service]
RestartPreventExitStatus=1
Restart=on-failure
RestartSec=5s
AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_SYS_RESOURCE
d. My complete Caddy config:
{
debug
admin localhost:2019
servers :3128 {
trusted_proxies static 10.0.102.0/25 10.0.102.128/25 10.0.103.0/25
listener_wrappers {
proxy_protocol {
allow 10.0.102.0/25 10.0.102.128/25 10.0.103.0/25
}
}
client_ip_headers X-Forwarded-For
metrics
}
log json {
output file /var/log/caddy/caddy.log {
roll_size 100mb
roll_keep 7
roll_keep_for 7d
}
format json
}
}
(base) {
log json
handle /metrics {
metrics
}
handle /caddy/health-check {
@goingDown vars {http.shutting_down} true
respond @goingDown "Bye-bye in {http.time_until_shutdown}" 503
respond 200
}
}
:3128 {
import base
@group1 client_ip 10.0.104.0/21 10.0.96.0/21
route @group1 {
forward_proxy {
hide_ip
hide_via
acl {
allow *.eu-central-1.amazonaws.com
allow *.eu-west-1.amazonaws.com # https://s3.eu-west-1.amazonaws.com redirects to https://aws.amazon.com/s3/ on non-allowed GET
allow *.s3-eu-west-1.amazonaws.com
allow *.s3-eu-central-1.amazonaws.com
allow s3.amazonaws.com
allow iam.amazonaws.com
allow ec2.amazonaws.com
allow tableau.com # redirects to https://www.tableau.com
deny all
}
}
}
route {
forward_proxy {
acl {
deny all
}
}
}
}
import /etc/caddy/conf.d/*
5. Links to relevant resources:
HTTP status code 0 in Caddy logs for a reverse proxy (with template) has some explanation:
Status code 0 is the same as an HTTP 200 status response. It usually happens when the request goes unhandled by Caddy (as in no configured routes wrote a response).