Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[THREESCALE-10156] Configure ssl_verify_client per product #1491

Merged
merged 8 commits into from
Oct 17, 2024

Conversation

tkan145
Copy link
Contributor

@tkan145 tkan145 commented Aug 26, 2024

What

Fix: https://issues.redhat.com/browse/THREESCALE-10156

Technical notes

This PR add a new env var called APICAST_HTTPS_VERIFY_CLIENT to allow switching client verification mode. Due to there is no supported way to add client cert to the gateway, only two values are supported

  • off: will not request client certificate
  • optional_no_ca (default): request client cert but will not validate it against the trust CA

APIcast will now also request client certificates if APICAST_HTTPS_VERIFY_CLIENT is set to off but only if Client Certificate Authentication policy is in chain.

Routing mode ssl_verify_client client certificate requested by
host optional_no_ca Client Certificate Validation policy
host off Client Certificate Validation policy
path optional_no_ca nginx due to no routing information available during the TLS handshake
path off won't request client certificate

Verification steps

  • Checkout master branch
  • Build a runtime image
make runtime-image IMAGE_NAME=apicast-test
  • Navigate into dev-environment and start gateway
cd dev-environments/listen-tls
make certs
make gateway IMAGE_NAME=apicast-test
  • Send a test request
curl --resolve example.com:8443:127.0.0.1 -v --cacert cert/rootCA.pem "https://example.com:8443/?user_key=123"

Check for this line in the curl log

* TLSv1.3 (IN), TLS handshake, Request CERT (13):
  • Check out this branch
  • Build a new runtime image
make runtime-image IMAGE_NAME=apicast-test
  • Navigate back to the dev-env
cd dev-environments/listen-tls

Edit the docker-compose.yaml file as follow

diff --git a/dev-environments/listen-tls/docker-compose.yml b/dev-environments/listen-tls/docker-compose.yml
index 6d89464f..866c5db8 100644
--- a/dev-environments/listen-tls/docker-compose.yml
+++ b/dev-environments/listen-tls/docker-compose.yml
@@ -12,6 +12,7 @@ services:
       APICAST_HTTPS_PORT: 8443
       APICAST_HTTPS_CERTIFICATE: /var/run/secrets/apicast/example.com.crt
       APICAST_HTTPS_CERTIFICATE_KEY: /var/run/secrets/apicast/example.com.key
+      APICAST_HTTPS_VERIFY_CLIENT: "off"
       THREESCALE_CONFIG_FILE: /tmp/config.json
       THREESCALE_DEPLOYMENT_ENV: staging
       APICAST_CONFIGURATION_LOADER: lazy
  • Start gateway
make gateway IMAGE_NAME=apicast-test
  • Send a test request
curl --resolve example.com:8443:127.0.0.1 -v --cacert cert/rootCA.pem "https://example.com:8443/?user_key=123"

Notice that * TLSv1.3 (IN), TLS handshake, Request CERT (13): is not in the log anymore

  • Stop the gateway and add the following to apicast-config.json file
diff --git a/dev-environments/listen-tls/apicast-config.json b/dev-environments/listen-tls/apicast-config.json
index 06014cab..45aaa87b 100644
--- a/dev-environments/listen-tls/apicast-config.json
+++ b/dev-environments/listen-tls/apicast-config.json
@@ -11,6 +11,12 @@
           "host": "backend"
         },
         "policy_chain": [
+          {
+            "name": "apicast.policy.tls_validation",
+            "configuration": {
+                "whitelist": []
+            }
+          },
           {
             "name": "apicast.policy.apicast"
           }

APIcast will return 400 due to missing certificates but our goal here is just check whether APIcast will request the client certificate or not

 ▲ APIcast/dev-environments/listen-tls curl --resolve example.com:8443:127.0.0.1 -v --cacert cert/rootCA.pem "https://example.com:8443/?user_key=123"
* Added example.com:8443:127.0.0.1 to DNS cache                                                                                                      
* Hostname example.com was found in DNS cache                                                                                                        
*   Trying 127.0.0.1:8443...                                                                                                                         
* Connected to example.com (127.0.0.1) port 8443                                                                                                     
* ALPN: curl offers h2,http/1.1                                                                                                                      
* TLSv1.3 (OUT), TLS handshake, Client hello (1):                                                                                                    
*  CAfile: cert/rootCA.pem                                                                                                                           
*  CApath: none                                                                                                                                      
* TLSv1.3 (IN), TLS handshake, Server hello (2):                                                                                                     
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):                                                                                             
* TLSv1.3 (IN), TLS handshake, Request CERT (13):                                                                                                    
* TLSv1.3 (IN), TLS handshake, Certificate (11):                                                                                                     
* TLSv1.3 (IN), TLS handshake, CERT verify (15):                                                                                                     
* TLSv1.3 (IN), TLS handshake, Finished (20):                                                                                                        
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):                                                                                          
* TLSv1.3 (OUT), TLS handshake, Certificate (11):                                                                                                    
* TLSv1.3 (OUT), TLS handshake, Finished (20):                                                                                                       
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384 / x25519 / RSASSA-PSS                                                                        

@tkan145 tkan145 force-pushed the THREESCALE-10156-ssl_verify_client branch 3 times, most recently from 28c345b to 004af4f Compare August 28, 2024 07:04
…hain

Adding support to request client certificate in `ssl_certificate` phase
when `APICAST_HTTPS_VERIFY_CLIENT` is set to `off`
Initially the X509_STORE object was free in _gc metamethod. However
the previously patch remove this and potentially cause memory leak.
For security reason, omit internal SSL verification error and return
a generic error instead. The details are shown in the log
@tkan145 tkan145 force-pushed the THREESCALE-10156-ssl_verify_client branch from 004af4f to e85a9ce Compare August 29, 2024 04:45
@tkan145 tkan145 marked this pull request as ready for review August 29, 2024 05:08
@tkan145 tkan145 requested review from a team as code owners August 29, 2024 05:08

**Default:** `optional_no_ca`
**Values:**
- `off`: Don't request client certificates and don't do client certificate verification.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- `off`: Don't request client certificates and don't do client certificate verification.
- `off`: Do not request client certificates or perform client certificate verification.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggesting the removal of the contraction and use of "don't" twice in one line.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

- `off`: Don't request client certificates and don't do client certificate verification.
- `optional_no_ca`: Requests the client certificate, but does not fail the request when the client certificate is not signed by a trusted CA certificate.

Enables verification of client certificates. The client certificates can be verified with TLS Client Certificate Validation policy
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Enables verification of client certificates. The client certificates can be verified with TLS Client Certificate Validation policy
Enables verification of client certificates. You can verify client certificates with TLS Client Certificate Validation policy.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

- `off`: Don't request client certificates and don't do client certificate verification.
- `optional_no_ca`: Requests the client certificate, but does not fail the request when the client certificate is not signed by a trusted CA certificate.

Enables verification of client certificates. The client certificates can be verified with TLS Client Certificate Validation policy
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Enables verification of client certificates. The client certificates can be verified with TLS Client Certificate Validation policy
Enables verification of client certificates. The client certificates can be verified with TLS Client Certificate Validation policy.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.


For this policy to work, APIcast need to be setup to listen for TLS connection.

By default, client certificates are requested during the TLS handshake, however, APIcast will not verify the certificate or terminate the request unless a TLS Validation Policy is in the chain. In most cases, the client not presenting a client certificate will not affect a service that does not have TLS Validation policy configured. The only exception is when the service is used by a browser or front-end application, which will cause the browser to always prompt the end user to select a client certificate to send if they have ANY client certificates configured when browsing the service.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
By default, client certificates are requested during the TLS handshake, however, APIcast will not verify the certificate or terminate the request unless a TLS Validation Policy is in the chain. In most cases, the client not presenting a client certificate will not affect a service that does not have TLS Validation policy configured. The only exception is when the service is used by a browser or front-end application, which will cause the browser to always prompt the end user to select a client certificate to send if they have ANY client certificates configured when browsing the service.
By default, during the TLS handshake, APIcast requests client certificates, but will not verify the certificate or terminate the request unless a TLS Validation Policy is in the chain. In most cases, the client not presenting a client certificate will not affect a service that does not have TLS Validation policy configured. The only exception is when a browser or front-end application uses the service. In this case, the browser will always prompt the user to choose a client certificate to send if they have any client certificates set up while accessing the service.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.


By default, client certificates are requested during the TLS handshake, however, APIcast will not verify the certificate or terminate the request unless a TLS Validation Policy is in the chain. In most cases, the client not presenting a client certificate will not affect a service that does not have TLS Validation policy configured. The only exception is when the service is used by a browser or front-end application, which will cause the browser to always prompt the end user to select a client certificate to send if they have ANY client certificates configured when browsing the service.

To work around this, the environment variable `APICAST_HTTPS_VERIFY_CLIENT` can be set to `off` to instruct APIcast to request a client certificate ONLY when the policy is in the chain.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
To work around this, the environment variable `APICAST_HTTPS_VERIFY_CLIENT` can be set to `off` to instruct APIcast to request a client certificate ONLY when the policy is in the chain.
To work around this, set the environment variable `APICAST_HTTPS_VERIFY_CLIENT` to `off`. This instructs APIcast to request a client certificate only when the policy is in the chain.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

Copy link
Contributor

@dfennessy dfennessy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added some suggestions.

Copy link
Contributor

@dfennessy dfennessy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM with those change :)

Copy link
Member

@eguzki eguzki left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verification steps working. Covered by tests.

LGTM

@tkan145 tkan145 merged commit 2e32a07 into 3scale:master Oct 17, 2024
13 of 14 checks passed
@tkan145 tkan145 deleted the THREESCALE-10156-ssl_verify_client branch October 17, 2024 00:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants