Skip to content

Instantly share code, notes, and snippets.

@bugre
Forked from nasrulhazim/haproxy-cors.md
Last active May 23, 2023 18:13
Show Gist options
  • Save bugre/984a3a99c8e52a96292c4ce660fa4478 to your computer and use it in GitHub Desktop.
Save bugre/984a3a99c8e52a96292c4ce660fa4478 to your computer and use it in GitHub Desktop.
Setting Up CORS in HAProxy

The "Credentials" is important if you're using Authentication..

frontend localnodes
    bind *:80
    reqadd X-Forwarded-Proto:\ http

    # Add CORS headers when Origin header is present
    capture request header origin len 128
    http-response add-header Access-Control-Allow-Origin %[capture.req.hdr(0)] if { capture.req.hdr(0) -m found }
    rspadd Access-Control-Allow-Methods:\ GET,\ HEAD,\ OPTIONS,\ POST,\ PUT  if { capture.req.hdr(0) -m found }
    rspadd Access-Control-Allow-Credentials:\ true  if { capture.req.hdr(0) -m found }
    rspadd Access-Control-Allow-Headers:\ Origin,\ Accept,\ X-Requested-With,\ Content-Type,\ Access-Control-Request-Method,\ Access-Control-Request-Headers,\ Authorization  if { capture.req.hdr(0) -m found }

    default_backend backend_apps

frontend localnodes-https
    # Certificate
    bind *:443 ssl crt /etc/ssl/private/domain_com.pem
    reqadd X-Forwarded-Proto:\ https

    # Add CORS headers when Origin header is present
    capture request header origin len 128
    http-response add-header Access-Control-Allow-Origin %[capture.req.hdr(0)] if { capture.req.hdr(0) -m found }
    rspadd Access-Control-Allow-Methods:\ GET,\ HEAD,\ OPTIONS,\ POST,\ PUT  if { capture.req.hdr(0) -m found }
    rspadd Access-Control-Allow-Credentials:\ true  if { capture.req.hdr(0) -m found }
    rspadd Access-Control-Allow-Headers:\ Origin,\ Accept,\ X-Requested-With,\ Content-Type,\ Access-Control-Request-Method,\ Access-Control-Request-Headers,\ Authorization  if { capture.req.hdr(0) -m found }

    default_backend backend_apps
        
backend backend_apps
    # Force HTTPS
    http-request set-header X-Forwarded-Port %[dst_port]
    http-request add-header X-Forwarded-Proto https if { ssl_fc }
    redirect scheme https if !{ ssl_fc }
    server App1 192.168.1.201:80 check
    server App2 192.168.1.202:80 check
    server App3 192.168.1.203:80 check
    server App4 192.168.1.204:80 check
    server App5 192.168.1.205:80 check
@bugre
Copy link
Author

bugre commented May 23, 2023

Note to myself in the future:
Take care of OPTION requests without hiting the backend server
Important part is that backend should NOT expect CORS headers
(_based on idea of: https://datmt.com/backend/configure-haproxy-to-accept-preflight-requests/)

frontend foobar
  ...
  acl is_options method OPTIONS
  use_backend cors_backend if is_options
  default_backend baz_backend

backend cors_backend
  http-after-response set-header Access-Control-Allow-Origin "*"
  http-after-response set-header Access-Control-Allow-Headers "*"
  http-after-response set-header Access-Control-Allow-Credentials "true"
  http-after-response set-header Access-Control-Allow-Methods "GET, DELETE, OPTIONS, POST, PUT, PATCH"
  http-after-response set-header Access-Control-Max-Age "31536000"
  http-request return status 200

backend baz_backend
  ... your servers regular requests..
  ... eventually you'll have to delete Origin and Referer headers before sending up to backends to asure they're not checking cors.
  ...
  http-request del-header Origin
  http-request del-header Referer

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment