dunglas / symfony-docker

A Docker-based installer and runtime for Symfony. Install: download and `docker compose up`.
https://dunglas.dev/2021/12/symfonys-new-native-docker-support-symfony-world/
2.59k stars 771 forks source link

[Question] Client Authentication Configuration Is Always Failing #373

Closed Spomky closed 1 year ago

Spomky commented 1 year ago

Hi,

I am trying to enable client authentication by editing docker/caddy/Caddyfile. I have followed the examples provided on the tls documentation, but I have not been successful so far (I am not familiar with Caddy).

At first sight, I put the config as follows:

tls {
    client_auth {
        mode verify_if_given
        trusted_ca_cert_file /etc/caddy/certs/user-mgmt.crt
        trusted_ca_cert_file /etc/caddy/certs/root.crt
    }
}

But when trying to run the server, the following exception is thrown:

{"level":"info","ts":1675060797.858568,"msg":"using provided configuration","config_file":"/etc/caddy/Caddyfile","config_adapter":"caddyfile"} Error: adapting config using caddyfile: /etc/caddy/Caddyfile:7: unrecognized directive: client_auth {"level":"info","ts":1675060822.0985522,"msg":"using provided configuration","config_file":"/etc/caddy/Caddyfile","config_adapter":"caddyfile"} Error: adapting config using caddyfile: server listening on [:80] is HTTP, but attempts to configure TLS connection policies

❓ Question: Do you have any idea on how to enable the client authentication feature?

root.crt

-----BEGIN CERTIFICATE----- MIIBzjCCAYCgAwIBAgIIB6Z9vu7ZtjowBQYDK2VwMFMxCzAJBgNVBAYTAkZSMQ8w DQYDVQQIEwZGcmFuY2UxDjAMBgNVBAcTBVBhcmlzMRQwEgYDVQQKEwtTcG9ta3kt TGFiczENMAsGA1UEAxMEcm9vdDAeFw0yMzAxMjkxOTA4MDBaFw0zMzAxMjkxOTA4 MDBaMFMxCzAJBgNVBAYTAkZSMQ8wDQYDVQQIEwZGcmFuY2UxDjAMBgNVBAcTBVBh cmlzMRQwEgYDVQQKEwtTcG9ta3ktTGFiczENMAsGA1UEAxMEcm9vdDAqMAUGAytl cAMhABYT5mCluTKeumeYvsj+0jnmDVythbMoFp50CLW6FAJso3IwcDAPBgNVHRMB Af8EBTADAQH/MB0GA1UdDgQWBBQRb9CbyIhEBeSCFn7GDFtfvkNcKDALBgNVHQ8E BAMCAQYwEQYJYIZIAYb4QgEBBAQDAgAHMB4GCWCGSAGG+EIBDQQRFg94Y2EgY2Vy dGlmaWNhdGUwBQYDK2VwA0EAVrfpY6fB/gN2A9QEHsrCZEA6WYTiWs8fXVFlOXNb kNLu+54hqwsQH7Ll66nq+ZJcIhfgrKvCZQrPyC9Fd2unAw== -----END CERTIFICATE-----

user-mgmt.crt

-----BEGIN CERTIFICATE----- MIIB0zCCAYWgAwIBAgIIAU3Z0YRLc24wBQYDK2VwMFMxCzAJBgNVBAYTAkZSMQ8w DQYDVQQIEwZGcmFuY2UxDjAMBgNVBAcTBVBhcmlzMRQwEgYDVQQKEwtTcG9ta3kt TGFiczENMAsGA1UEAxMEcm9vdDAeFw0yMzAxMjkxOTEwMDBaFw0zMzAxMjkxOTA4 MDBaMFgxCzAJBgNVBAYTAkZSMQ8wDQYDVQQIEwZGcmFuY2UxDjAMBgNVBAcTBVBh cmlzMRQwEgYDVQQKEwtTcG9ta3ktTGFiczESMBAGA1UEAxMJdXNlci1tZ210MCow BQYDK2VwAyEA0zBeWJi8dZEfKpTlP74UwFwFsQli6x7pwQ4rAY1Dw5GjcjBwMA8G A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFM1JomYRMfPJAbnDmLUHoOUdDboRMAsG A1UdDwQEAwIBBjARBglghkgBhvhCAQEEBAMCAAcwHgYJYIZIAYb4QgENBBEWD3hj YSBjZXJ0aWZpY2F0ZTAFBgMrZXADQQC4KJgdA18Fxph8Tlo+wAvYONXhMgT2TTvs XPACoh33FvduReFaYB7k1hiuVbCQFrW1PZpv3/5zdHgoApuEH+YA -----END CERTIFICATE-----

[EDIT]: by the way, when I will succeed in configuring the client authentication, I will take the opportunity to add the example for Caddy at https://symfony.com/doc/current/security.html#x-509-client-certificates

Spomky commented 1 year ago

In the end, I managed to get Caddy working fine. I share the configuration here below for everyone who could be stucked on this.

{ # Debug {$CADDY_DEBUG} } {$SERVER_NAME} { {$CADDY_EXTRA_CONFIG} tls { client_auth { mode verify_if_given trusted_ca_cert_file /etc/caddy/certs/ca.pem } } log route { root * /srv/app/public mercure { # Transport to use (default to Bolt) transport_url {$MERCURE_TRANSPORT_URL:bolt:///data/mercure.db} # Publisher JWT key publisher_jwt {env.MERCURE_PUBLISHER_JWT_KEY} {env.MERCURE_PUBLISHER_JWT_ALG} # Subscriber JWT key subscriber_jwt {env.MERCURE_SUBSCRIBER_JWT_KEY} {env.MERCURE_SUBSCRIBER_JWT_ALG} # Allow anonymous subscribers (double-check that it's what you want) anonymous # Enable the subscription API (double-check that it's what you want) subscriptions # Extra directives {$MERCURE_EXTRA_DIRECTIVES} } vulcain php_fastcgi unix//var/run/php/php-fpm.sock { env SSL_CLIENT_S_FINGERPRINT {http.request.tls.client.fingerprint} env SSL_CLIENT_S_CERTIFICATE {http.request.tls.client.certificate_der_base64} env SSL_CLIENT_S_ISSUER {http.request.tls.client.issuer} env SSL_CLIENT_S_SERIAL {http.request.tls.client.serial} env SSL_CLIENT_S_DN {http.request.tls.client.subject} } encode zstd gzip file_server } }

The main point is to pass the result of the client authentication verification to PHP-FPM via env vars. The placeholders are the ones listed in the doc at https://caddyserver.com/docs/json/apps/http/#docs

To be noted that it does not work on Symfony < 6.2 because the email address is not part of the subject string. With Symfony 6.3 and https://github.com/symfony/symfony/pull/48200, it works as expected using common name CN instead of emailAddress