Hi, I’m looking for some help as I ran out of options or maybe i am missing something.
I am sending a curl request towards and API with key authentication.
curl -v https://10.0.0.4/api/stass -H “X-API-KEY: hashedkey”
however, when passing through HAProxy, I am getting
[“Client KEY is not valid or header X-API-KEY not defined.”]
Is there anyway how I can forward the X-KEY header and it’s value as part of the header to the backend?
The basic configuration to send normal traffic to the backend works fine.
Haproxy will not strip this header. It will lowercases the header name though, due to the internal http representation.
But there is a simpler test:
Running curl against directly against the backend server, but lowercasing the header name (not the value),
curl -v https://10.0.0.4/api/stass -H "x-api-key: hashedkey"
If this doesn’t work, then your the backend server is not HTTP compliant as it HTTP header names are supposed to be case insensitive. If that is the case, then the following configuration would workaround this:
global
h1-case-adjust x-api-key X-API-KEY
Tried that but still getting the same response.
This is the haproxy config file.
global
log /dev/log local0
log /dev/log local1 notice
chroot /var/lib/haproxy
stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
stats timeout 30s
user haproxy
group haproxy
daemon
# Default SSL material locations
ca-base /etc/ssl/certs
crt-base /etc/ssl/private
ssl-default-bind-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS
ssl-default-bind-options no-sslv3
h1-case-adjust x-api-key X-API-KEY
defaults
log global
mode http
option httplog
option dontlognull
option forwardfor
timeout connect 36000s
timeout client 65s
timeout server 65s
retries 3
errorfile 400 /etc/haproxy/errors/400.http
errorfile 403 /etc/haproxy/errors/403.http
errorfile 408 /etc/haproxy/errors/408.http
errorfile 500 /etc/haproxy/errors/500.http
errorfile 502 /etc/haproxy/errors/502.http
errorfile 503 /etc/haproxy/errors/503.http
errorfile 504 /etc/haproxy/errors/504.http
frontend http-in
bind *:443 ssl crt /etc/haproxy/certs.d/ssl-certs.pem
bind *:80
default_backend http_backend
http-request capture req.hdr(X-Forwarded-For) len 64
option http-server-close
#~~~ Get real IP if CloudFlare is present
acl from_cf src -f /etc/haproxy/cloudflare.lst
acl cf_ip_hdr req.hdr(CF-Connecting-IP) -m found
http-request set-var(txn.realip) req.hdr(CF-Connecting-IP) if from_cf cf_ip_hdr
http-request set-var(txn.realip) src if !from_cf
http-request set-header X-Real-IP %[var(txn.realip)]
http-request set-header X-Forwared-For %[var(txn.realip)] if !from_cf
#~~~ save src temporary, restore later
http-request set-var(txn.realsrc) src
http-request set-src var(txn.realip)
http-request add-header X-Forwarded-Proto https
http-request add-header X-Forwarded-Port 443
http-request allow if { src -f /etc/haproxy/whitelist.lst }
http-request deny
#~~~ restore src original IP
http-request set-src var(txn.realsrc)
redirect scheme https if !{ ssl_fc }
# Define hosts
acl abc_true hdr(host) -i 10.0.0.4
# Figure out which one to use
use_backend http_backend if abc_true
backend http_backend
option forwardfor
balance roundrobin
http-request set-header X-Forwarded-For %[src]
mode http
server abc abc:443 ssl verify none check
server abc_external abc_external:443 ssl verify none backup
Please do the test with curl I asked about.
Yes I did the curl with -H "x-api-key: and still the same output response
Then the issue is not about lower-casing the header name in haproxy.
As haproxy doesn’t strip the header, and the modification it applies (lower-casing) is not breaking the application, the root cause of the issue is something else.
You’d have to take a look at what the application actually receives, if there is nothing to be done on the application end, check if you can downgrade to HTTP and capture the haproxy → backend server traffic, or otherwise you will have to decrypt HTTPS in wireshark (by using the private key of the certificate in with a non-FS cipher).