HAProxy community

Converting pre 2.1 HAProxy code to be 2.1 compliant (vscode)

Hey Guys,

I got a little problem with a small piece of code which I wondered if anyone had an idea how to convert this to be HAProxy v2.1+ compliant.

I have used this code for the past year or so without issues, it rewrites the url so it works with code-server and supporting multi users based on /u/username scheme.

I have tried several versions but I am not winning.

Exact line which I believe needs changing:
reqrep ^([^\ :]*)\ /u/majestic/(.*) \1\ /\2

Below I am enclosing the full config in case its somewhere else. If anyone has any ideas or how to write this better, I would really love to hear form you. Thank you.

Full HAProxy code

  # vscode (majestic)
  acl vscode_majestic hdr(host) -i coder.example.io
  acl vscode_majestic_req path_beg /u/majestic/
  acl vscode_majestic_req path /u/majestic/
  http-request redirect scheme https drop-query append-slash if { path -m str /u/majestic }
  use_backend vscode_majestic if vscode_majestic_req
# vscode (majestic)
backend vscode_majestic
  redirect scheme https if !{ ssl_fc }
  reqrep ^([^\ :]*)\ /u/majestic/(.*)     \1\ /\2
  server vscode01 172.27.1.102:8081 check

VS Code server systemd script

[Unit]
Description=Visual Studio Code Server (majestic)
After=network.target

[Service]
EnvironmentFile=/data/coder/majestic/.env
ExecStart=/data/coder/majestic/bin/code-server --base-path /u/majestic --host 0.0.0.0 --port 8081 --user-data-dir /data/coder/majestic/user-data /data/coder/majestic/projects
User=majestic
Restart=always
RestartSec=1

[Install]
WantedBy=multi-user.target

Versions I have tried:

http-request replace-path ^([^\ :]*)\ /u/majestic/(.*)     \1\ /\2
http-request set-path "%[path,regsub(^/u/majestic/,/)]"
http-request replace-path ^([^\ ]*\ /)u/majestic[/]?(.*)     \1\2

Any tips/advise, I would be extremely grateful.

Kind Regards,

Majestic

This should work:

http-request replace-path ^/u/majestic/ /

Close, but now getting “ERR_TOO_MANY_REDIRECTS”

Any ideas?

Can you share the output of curl -vv <url>

❯ curl -v https://coder.example.io/u/majestic/
*   Trying 94.130.xx.xx...
* TCP_NODELAY set
* Connected to coder.example.io (94.130.xx.xx) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/cert.pem
  CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* ALPN, server accepted to use h2
* Server certificate:
*  subject: CN=*.example.io
*  start date: May  8 10:22:18 2020 GMT
*  expire date: Aug  6 10:22:18 2020 GMT
*  subjectAltName: host "coder.example.io" matched cert's "*.example.io"
*  issuer: C=US; O=Let's Encrypt; CN=Let's Encrypt Authority X3
*  SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x7f8dcc80f200)
> GET /u/majestic/ HTTP/2
> Host: coder.example.io
> User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)
> Accept: */*
> Referer:
>
* Connection state changed (MAX_CONCURRENT_STREAMS == 100)!
< HTTP/2 302
< content-type: text/plain
< location: http://coder.example.io/u/majestic/login
< date: Fri, 15 May 2020 11:57:49 GMT
< x-served-by: vscode01
< strict-transport-security: max-age=15768000; includeSubDomains; preload
< referrer-policy: no-referrer-when-downgrade
<
* Connection #0 to host coder.netspeedy.io left intact
* Closing connection 0

Its the same if you add an ending slash or without in the url.

May have seen it, looks like its going from HTTPS to HTTP and then back again in a loop. Theres a line which is different in my original config. Will try adding that for a second.

Seems made no difference, I added in redirect scheme https if !{ ssl_fc } to the backend which is what the old proxy had.

Nothing seems to be in the logs to say whats up.

Ive tried taking out the other redirects and still does it.

This is not a problem related to this redirect. This is simply the backend application not knowing that it runs a) on HTTPS and b) on / instead of /u/majestic/.

Are you saying this worked fine previously with reqrep in the old release?

Yeah it does, if I switch the LB back to the old one, it works perfectly.

Im switching the backend to SSL and seeing what it does. Usually I non-ssl to the backend, and the front end does the SSL.

In that case I clearly don’t have the full picture. Share the entire old and new configuration.

Scrapping this idea, seems theres another way I can do this rather than using proxy to do the magic, feel free to remove this post, thanks.

1 Like