HAProxy community

Strip port in host header

Hi. What is the correct way to strip port number in host header? I have an acl:
acl srv_all hdr_end(host) -i mydomain.com

It obviously fails when the host header contains a port number. Thanks in advance!

The correct way is to include the port in the match:

acl srv_all hdr_end(host) -i mydomain.com:8080

If you have multiple, use multiple matches:

acl srv_all hdr_end(host) -i mydomain.com
acl srv_all hdr_end(host) -i mydomain.com:8080
acl srv_all hdr_end(host) -i mydomain.com:1080

You probably don’t have a lot of different ports, right?

Thanks for the prompt reply!

Well… The ports amount is 2 (80 and 443), but there’re a lot of acls for host name matching:

# grep " hdr" 02_front.cfg | wc -l
43

And adding ports will double the rules number.

Is there another way to go?

Looks like I’ve figured it out:

http-request replace-header Host ([^:]+) \1

Any arguments against using this in the frontend section?

If your ports are 80 and 443 (for HTTPS) you should not seem them in the Host header at all, because those are standard ports, and browsers will not send them at all.

To match non-standard ports, my proposal is the “correct” way. If instead of the “correct” way you mean howto achieve this in the with the shortest amount of configuration lines, that is a different story of course.

It will certainly rewrite that header, remove the port. However the ACL matching probably comes first, so I’m not sure whether this fixes the issue.

I suggest you clarify why you are seeing this ports in the first place.

It appears some services (for example, https://branch.io/resources/aasa-validator/) send requests with a port inside.

Thanks for the clarification, I’ll definitely check it.

You could use a regex in the ACL instead for every domain:

acl srv_all hdr_reg(host) -i mydomain.com[^:]*

you can use the field converter to match against the name/ip part of the host header.

acl foo hdr(host),field(1,:) -m end bar

if you have a lot of domains to match against you can store them in a file, one per line, and use

acl foo hdr(host),field(1,:) -m end -f /path/to/file

1 Like

Thanks @jerome, the solution looks very nice! Are you aware which one performs better: a single http-request replace-header in the beginning of the frontend section or hdr(),field() in each acl?

I would prefer not involving regular expressions when not needed.

You can also strip the port with field, ie:
http-request set-header host %[hdr(host),field(1,:)]

which way is best would depend on your config and taste.

I completely agree. Thanks a bunch!