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

downstream_mtls.match_subject_alt_names does not work on "policy" enforcement. #4614

Open
calderonth opened this issue Oct 2, 2023 · 1 comment

Comments

@calderonth
Copy link

What happened?

When configuring a Pomerium instance with mTLS enabled and setting the enforcement mode to "policy" the SAN matching does not happen and allows valid certificate missing the required SANs to access a route.

What did you expect to happen?

This does not happen when setting the enforcement mode to reject_connection.
The behavior should be consistent across enforcement modes for the SAN logic.

How'd it happen?

  • Configure downstream TLS and enable SAN matching.
  • Configure a route to use mTLS
  • Observe that a connection with a valid certificate but invalid SAN is allowed to access the route

What's your environment like?

pomerium --version
pomerium: 0.23.0-1693234251+5a4acc5c
envoy: 1.25.5+b1095c058415dfb2261e695a0f144311a7dc346b6eb47ecbb0a01b7de2c7299f

What's your config.yaml?

downstream_mtls:
  ca_file: /etc/pomerium/downstream_bundle.pem
  enforcement: policy
  match_subject_alt_names:
    - email: '.*@blah\.com'
...
routes:
  - from: https://verify-mtls.blah.com
    to: http://localhost:8000
    policy:
      - allow:
          or:
          - authenticated_user: true
          - client_certificate:
              fingerprint:
                - '3bdf2e5eee6e4a124664cee8c7b910ef20dc6d625075113017dfaa011950fe44'
                - '214407b8123eac731d2d06f3c17156b9189fd726c4cdd16892bb49268d7484ef'
    pass_identity_headers: true
    set_request_headers:
      x-pomerium-client-cert-fingerprint: ${pomerium.client_cert_fingerprint}

What did you see in the logs?

{"level":"info","service":"authorize","request-id":"8491db43-a086-4e4a-b02c-e41b93d6d614","check-request-id":"8491db43-a086-4e4a-b02c-e41b93d6d614","method":"GET","path":"/","host":"verify-mtls.blah.com","ip":"10.XX.XX.XX","user":"","email":"","allow":true,"allow-why-true":["client-certificate-ok"],"deny":false,"deny-why-false":[],"time":"2023-10-02T16:00:01-04:00","message":"authorize check"}
{"level":"info","service":"envoy","upstream-cluster":"route-4ce250db4024b66e","method":"GET","authority":"verify-mtls.blah.com","path":"/","user-agent":"curl/7.74.0","referer":"","forwarded-for":"10.XX.XX.XX","request-id":"8491db43-a086-4e4a-b02c-e41b93d6d614","duration":9.326234,"size":453,"response-code":200,"response-code-details":"via_upstream","time":"2023-10-02T16:00:02-04:00","message":"http-request"}
@kenjenkins
Copy link
Contributor

Hi @calderonth, the policy enforcement mode is intended to allow you to configure client certificate enforcement only on certain routes, by explicitly adding an invalid_client_certificate criterion to those routes. Please refer to the documentation for this setting:

  1. policy — Pomerium will not require client certificates for any routes unless explicitly required by a route policy.

This mode allows you to configure only certain routes to require a trusted client certificate. To configure a route to require client certificates, add a policy Deny rule with the invalid_client_certificate criterion. (See Pomerium Policy Language for more information.)

Note that the example policy you provided does not have any such invalid_client_certificate rule.

Recall the policy action semantics: "a user will have access to a route if at least one allow rule matches and no deny rules match."

Let's consider the example policy you provided:

    policy:
      - allow:
          or:
          - authenticated_user: true
          - client_certificate:
              fingerprint:
                - '3bdf2e5eee6e4a124664cee8c7b910ef20dc6d625075113017dfaa011950fe44'
                - '214407b8123eac731d2d06f3c17156b9189fd726c4cdd16892bb49268d7484ef'

This policy has one allow rule, consisting of two criteria combined with the or operator, so it will match if either one of the two criteria match. That is, access will be allowed for any users that can authenticate with the configured identity provider, or for any requests accompanied by a client certificate having a fingerprint matching one of the two listed values. Notice that there is no client certificate requirement at all for authenticated users, and also note that if a client presents a certificate with one of those two fingerprints, there is no requirement to authenticate with the identity provider.

To modify this policy so that it requires a trusted client certificate in all cases, you could add an explicit deny rule like so:

    policy:
      - allow:
          or:
          - authenticated_user: true
          - client_certificate:
              fingerprint:
                - '3bdf2e5eee6e4a124664cee8c7b910ef20dc6d625075113017dfaa011950fe44'
                - '214407b8123eac731d2d06f3c17156b9189fd726c4cdd16892bb49268d7484ef'
      - deny:
          or:
          - invalid_client_certificate: true

With this policy, all requests must be accompanied by a trusted client certificate, which given the downstream_mtls settings means it must be issued by a CA included in the downstream_bundle.pem file and it must have an email address SAN with the blah.com domain. (Note that the presence of the or operator in the allow rule still means that requests with a client certificate matching one of those two fingerprints will be allowed whether or not the user has authenticated with the identity provider, which may or may not be what you want.)

Or, if you wish to apply the client certificate requirements to all routes, please use the default enforcement mode, rather than enforcement: policy.

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

No branches or pull requests

2 participants