Skip to content
This repository was archived by the owner on Jun 19, 2025. It is now read-only.
This repository was archived by the owner on Jun 19, 2025. It is now read-only.

unable to verify clients using haproxy as a TLS proxy #334

@frogu

Description

@frogu

Bug description

TLS proxy documentation states that a proxy such as nginx or haproxy may be used, but only nginx example is provided.

my haproxy configuration for the header
http-request set-header X-Tls-Client-Cert %[ssl_c_der,base64]

my minio-kes (docker: minio/kes:v0.22.3) configuration for the proxy:
(my.crt and my.key signed by CA, the cacert is available in the container)

tls:
    cert: /ssl/my.crt
    key: /ssl/my.key
    identities: 
      - redacted
      - redacted
    proxy:
        header:
            cert: X-Tls-Client-Cert

issues:

  1. the proxy can connect, but can not check /v1/status -> {"message":"no client certificate is present"}, I was forced to accept http400 as valid response for the healthcheck
  2. haproxy (in the version embedded in vmware nsx-v) can only send base64 or hex encoded DER certificate, without any newlines, does not have set-var exposed or url_enc available
  3. internal/proxy.go uses url.QueryUnescape which replaces "+" with " ", which makes it an invalid base64 string
  4. last 3 errors result in message: "invalid client certificate" without any indication at which moment the error occurred (query unescape, pem decode, x509 parse certificate)

Expected behavior

  • proxy identities should be allowed to call /v1/status
  • documentation updated with working haproxy config for setting the http header with the client certificate
  • proxy able to parse base64 encoded DER certificate
  • error message returned by server more informative

Additional context

  1. minio-kes docker v0.22.3
  2. Ubuntu 18.04.4 LTS (should not be relevant)
  3. x86_64
  4. Can not swap haproxy for nginx (because it is an internal vmware-nsx-v loadbalancer)

Ideas for solution

Provide another parser for base64 encoded DER certificate, and a configuration variable, to choose the parser.
e.g.
tls.proxy.header.content_format: X
where X is one of "base64urlencPEM", "base64DER"
or
tls.proxy.header.generated_by: Y
where Y is one of "nginx", "haproxy"

which chooses an appropriate parser.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions