HAProxy community

Aliasing or Redirecting the Web URLS

Hi Guys,
I am looking for a HAProxy solution where we want to translate the incoming url to completely different url, I have gone through the documentation and implemented where backend is using server ip and port.
Kindly suggest if someone achieve this before?

Ask-
www.original.com/test --> www.wanaBeoriginal.co.in/umenhum

To rewrite the the Host part of the URL you need to rewrite the Host header. And for the path, use set-path. You can match it all against a acl in the form of base:

acl acl_original base -i www.original.com/test
http-request set-header Host www.wanaBeoriginal.co.in if acl_original
http-request set-path /umenhum if acl_original

Thanks @lukastribus, Let me try it.
Can you please confirm, These settings are going to be in frontend configuration, what about backend?
as per my understanding, I dont want anything in backend as my URLs are already being translated to new URL.
The problem is, I can not access my backend server via IP and PORT, Services only can be accessed via https url.
Kindly suggest.

https://cbonte.github.io/haproxy-dconv/2.1/configuration.html#4-http-request

You’re allowed to put “http-request” statements in backends and frontends.

Also, in my testing HAProxy is smart enough to handle multiple “http-request” redirects in frontend/backends. I’m doing HTTP to HTTPS redirects and adding WWW, works fine besides preserving headers.

They belong in the frontend. You don’t need anything else in the backend.

I don’t know what that means.

Can you please guide if below config is correct for below - ?

https://qa.dummy.com:6909/blog --> https://updated.qa.dummy.com/api/blog/v1

frontend 6909
  mode       http
  bind     *:6909
  acl acl_original base -i https://qa.dummy.com:6909 
  http-request set-header Host https://updated.qa.dummy.com if acl_original 
  http-request set-path /api/blog/v1 if acl_original

No, you need to remove the https:// prefix from both the ACL and the Host header.

Thanks, weirdly Settings are intermittently working when using https://qa.dummy.com:6909/blog but working fine when using direct url which is https://updated.qa.dummy.com/api/blog/v1

Getting below error when hitting HAProxy URL - https://qa.dummy.com:6909/blog from SOAP UI -
Thu Mar 26 09:49:04 EDT 2020:ERROR:Exception in request: javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?

I don’t know what you are trying to achieve, I don’t have your full configuration.

But what you did share is that port 6906 is not a SSL (HTTPS) port, but plaintext HTTP, so I’m unsure how https against port 6909 is supposed to work.

This is my config and I want to do a URL translation to new URL as below -

https://qa.dummy.com:6909/blog --> https://updated.qa.dummy.com/api/blog/v1

#---------------------------------------------------------------------
# Global settings
#---------------------------------------------------------------------
global
# to have these messages end up in /var/log/haproxy.log you will
# need to:
#
# 1) configure syslog to accept network log events.  This is done
#    by adding the '-r' option to the SYSLOGD_OPTIONS in
#    /etc/sysconfig/syslog
#
# 2) configure local2 events to go to the /var/log/haproxy.log
#   file. A line like the following can be added to
#   /etc/sysconfig/syslog
#
#    local2.*                       /var/log/haproxy.log
#
# log         127.0.0.1 local2
 
log 127.0.0.1  local0
chroot      /var/lib/haproxy
pidfile     /var/run/haproxy.pid
maxconn     4000
user        haproxy
group       haproxy
daemon

# turn on stats unix socket
stats socket /var/lib/haproxy/stats

#---------------------------------------------------------------------
# common defaults that all the 'listen' and 'backend' sections will
# use if not designated in their block
#---------------------------------------------------------------------
defaults
log                     global
mode                    http
option                  httplog
option                  dontlognull
unique-id-format %{+X}o\ %ci:%cp_%fi:%fp_%Ts_%rt:%pid
unique-id-header X-Unique-ID
retries                 3
option                  redispatch
option                  forwardfor
timeout http-request    50s
timeout queue           1m
timeout connect         10s
timeout client          1m
timeout server          1m
#timeout http-keep-alive 10s
timeout check           10s
maxconn                 3000    
stats                   enable


#---------------------------------------------------------------------
# haproxy-monitoring
#---------------------------------------------------------------------


listen haproxy-monitoring
   bind *:1936
   mode  http
   stats enable
   stats hide-version
   #http-request set-path /projects/%[var(req.rewrite_project)]%[path] if { var(req.rewrite_project) -m found }

   stats realm Haproxy\ Statistics
   stats uri /
   stats auth user:haproxy    



#---------------------------------------------------------------------
# main frontend which proxys to the backends
#---------------------------------------------------------------------
   
frontend 6909
  mode       http
  bind     *:6909
  acl acl_original base -i qa.dummy.com:6909 
  http-request set-header Host updated.qa.dummy.com if acl_original 
  http-request set-path /api/blog/v1 if acl_original
   
#---------------------------------------------------------------------

You are listening as HTTP on port 6909. That’s not HTTPS, you’d have to configure ssl and a certificate here. And where is the backend configuration?

I want to do only URL Translation so no backend configuration defined for it.

You mean you want to send a redirect then?

Then:

  • install the SSL certificate and enable SSL on port 6909
  • instead of set-header and set-path, use redirect

something like:

acl acl_original base -i qa.dummy.com:6909 
http-request redirect location https://updated.qa.dummy.com/api/blog/v1 if acl_original
HA-Proxy version 2.0.13 2020/02/13 - https://haproxy.org/
Build options :
  TARGET  = linux-glibc
  CPU     = generic
  CC      = gcc
  CFLAGS  = -O2 -g -fno-strict-aliasing -Wdeclaration-after-statement -fwrapv -Wno-unused-label -Wno-sign-compare -Wno-unused-parameter -Wno-old-style-declaration -Wno-ignored-qualifiers -Wno-clobbered -Wno-missing-field-initializers -Wtype-limits
  OPTIONS = USE_PCRE=1 USE_LIBCRYPT=1 USE_CRYPT_H=1 USE_OPENSSL=1 USE_ZLIB=1

Feature list : +EPOLL -KQUEUE -MY_EPOLL -MY_SPLICE +NETFILTER +PCRE -PCRE_JIT -PCRE2 -PCRE2_JIT +POLL -PRIVATE_CACHE +THREAD -PTHREAD_PSHARED -REGPARM -STATIC_PCRE -STATIC_PCRE2 +TPROXY +LINUX_TPROXY +LINUX_SPLICE +LIBCRYPT +CRYPT_H -VSYSCALL +GETADDRINFO +OPENSSL -LUA +FUTEX +ACCEPT4 -MY_ACCEPT4 +ZLIB -SLZ +CPU_AFFINITY +TFO +NS +DL +RT -DEVICEATLAS -51DEGREES -WURFL -SYSTEMD -OBSOLETE_LINKER +PRCTL +THREAD_DUMP -EVPORTS

Default settings :
  bufsize = 16384, maxrewrite = 1024, maxpollevents = 200

Built with multi-threading support (MAX_THREADS=64, default=4).
Built with OpenSSL version : OpenSSL 1.0.2k-fips  26 Jan 2017
Running on OpenSSL version : OpenSSL 1.0.2k-fips  26 Jan 2017
OpenSSL library supports TLS extensions : yes
OpenSSL library supports SNI : yes
OpenSSL library supports : SSLv3 TLSv1.0 TLSv1.1 TLSv1.2
Built with network namespace support.
Built with transparent proxy support using: IP_TRANSPARENT IPV6_TRANSPARENT IP_FREEBIND
Built with zlib version : 1.2.7
Running on zlib version : 1.2.7
Compression algorithms supported : identity("identity"), deflate("deflate"), raw-deflate("deflate"), gzip("gzip")
Built with PCRE version : 8.32 2012-11-30
Running on PCRE version : 8.32 2012-11-30
PCRE library supports JIT : no (USE_PCRE_JIT not set)
Encrypted password support via crypt(3): yes

Available polling systems :
      epoll : pref=300,  test result OK
       poll : pref=200,  test result OK
     select : pref=150,  test result OK
Total: 3 (3 usable), will use epoll.

Available multiplexer protocols :
(protocols marked as <default> cannot be specified using 'proto' keyword)
              h2 : mode=HTX        side=FE|BE     mux=H2
              h2 : mode=HTTP       side=FE        mux=H2
       <default> : mode=HTX        side=FE|BE     mux=H1
       <default> : mode=TCP|HTTP   side=FE|BE     mux=PASS

Available services : none

Available filters :
        [SPOE] spoe
        [COMP] compression
        [CACHE] cache
        [TRACE] trace

My settings are like this now -

frontend 6909
   mode       http
   bind       *:6909 ssl crt /etc/ssl/private/qa.dummy.com.pem
   acl acl_original base -i qa.dummy.com:6909
   http-request redirect location https://updated.qa.dummy.com/api/blog/v1 if acl_original

but when hitting from SOAP UI, getting below error -

503 Service Unavailable

No server is available to handle this request.

Though service is available.

My perm files contains -

Well the URL probabily isn’t https://qa.dummy.com:6909, so they ACL will not match.

Do you need to condition the redirect based on a specific URL or is that not actually required? If the latter is the case, then just remove the ACL condition and wholesale redirect to whatever destination you like.

Thanks so much lukastribus, It worked by disabling acl.