Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.
Sign upGitHub is where the world builds software
Millions of developers and companies build, ship, and maintain their software on GitHub — the largest and most advanced development platform in the world.
"invalid header field value" when including http.request.tls.client.certificate_pem placeholder in a header #3767
Comments
Interesting. I think the problem is the PEM is not URL encoded, so I think it's complaining about certain characters contained there. I think likely @gdhameeja I think we might need another placeholder, |
Right. Will take this up and add the placeholder. |
Why does it need to be URL encoded in an HTTP header? |
Taking another quick look at why this happens, I think it's because of the newlines rather than |
That might be more accurate. It is true that header values can't have raw new lines; I bet Apache is escaping them. Our header manipulation should probably do the same thing. Edit: Wait, shouldn't Go (std lib) already be escaping it for us? |
Looks like it hits this check: https://godoc.org/golang.org/x/net/http/httpguts#ValidHeaderFieldValue in https://golang.org/src/net/http/transport.go I'm not certain how to decipher that Edit: Yeah Edit2: Looks like HTTP headers use |
Looks like nginx solves this by providing two variables (one of which is deprecated): http://nginx.org/en/docs/http/ngx_http_ssl_module.html#var_ssl_client_escaped_cert The deprecated one used Following their lead on the naming, I think |
It's weird to URL-encode a header value though. Is there any other option that's more elegant? What if we just strip the header/footer lines and remove all the newlines? To clarify, this means that the header value is basically just the base64-encoded DER content of the certificate. That should suffice. If the upstream really wants PEM they can tack headers on the front and back and then add newlines if they want it to look pretty. (I'll also add that communicating a certificate via a header is just plain weird.) |
I don't see the harm in URL encoding it personally. It'll be more compatible with existing applications written to support the approach Apache and Nginx take with passing through certificates via headers. If we do the DER approach then it should be called |
Let's do that then. It will solve the problem and won't introduce any unnecessary weirdness into the code base. URL-encoding base64 just seems odd to me. We don't need to urlencode it: just use the base64. I'll get around to implementing this sooner or later, unless someone would like to get to it first! |
Caddy version:
v2.2.0 h1:sMUFqTbVIRlmA8NkFnNt9l7s0e+0gw+7GPIrhty905A=
I am trying to pass pem-encoded client certificate to proxied service via a X-SSL-Cert header, like so:
I am trying to use recently added
client.certificate_pem
placeholder (497c3f7#diff-18e521e381018c19bda45164dcad2b9cR347 ) which, if I understand correctly, is synonymous to apache'sSSL_CLIENT_CERT
(i.e. in an apache config one would writeRequestHeader set X-SSL-Cert "%{SSL_CLIENT_CERT}s"
).But for the given Caddyfile I get a 502 Bad Gateway with the following error in the logs: