Score:0

mTLS: restrict client cert to specific subdomain?

pk flag
Joe

tldr

Via mTLS, I'm trying to find a way of issuing a client cert that only grants that client to access a specific subdomain. I have a suspicion that this isn't possible, but I'm not certain.

What I'm trying to accomplish

Let's say I have a server listening to anything routed to *.foo.flar.com

Each customer is assigned their own subdomain that satisfies the wildcard in the server's address.

For example, customer1 should access the server via customer1.foo.flar.com, and customer2 should access the server via customer2.foo.flar.com.

Further, one customer must be prevented from accessing the server using a different customer's subdomain. So, it is illegal for customer1 to request customer2.foo.flar.com, and such a request should be rejected.

I was hoping that I could accomplish this at the session layer via mTLS and some clever SAN cert usage, but I'm having trouble getting it to work properly.

How I have things setup

I'm pretty new to playing around with TLS, so a lot of this came from this SO answer about SAN configuration and this article about basic mTLS configuration.

I've omitted some things here like CA cert generation and client and server CSR generation to try and keep things focused, but can add it if you'd like.

I created a server cert using something like:

openssl x509 \
  -req \
  -extfile <(printf "subjectAltName=DNS:*.foo.flar.com") \
  -days 365 \
  -in server.csr \ 
  -CA ca.crt \
  -CAkey ca.key \
  -CAcreateserial \
  -out server.crt

Then I created a client cert using something like:

openssl x509 \
  -req \
  -extfile <(printf "subjectAltName=DNS:customer1.foo.flar.com") \
  -days 365 \
  -in client.csr \ 
  -CA ca.crt \
  -CAkey ca.key \
  -CAcreateserial \
  -out client.crt

The server (written in Go) is configured to require and verify client certs.

The problem

The problem is that when I test this setup, the connection succeeds when I would expect it to fail.

If I have a client issued the customer1 cert call the server at customer1.foo.flar.com, the connection succeeds.

However, if I have a client issued the customer1 cert call the server at customer2.foo.flar.com, that connection also succeeds when I would expect it to fail.

I was hoping that, upon inspection of the client's cert, the server would see that customer1 does not have access to customer2..., and would reject the request. But this does not seem to be happening.

Ideas?

Score:3
se flag

Client certificates contain only the information to authenticate the user. Any restrictions on what the authenticated user can do (authorization) including on which site the certificate will be accepted are up to the server who checks the certificate.

pk flag
Joe
So setting SAN values on a client cert is purely informational and has no effects otherwise?
pk flag
Joe
Actually, now that I think of it more I guess that makes sense. Since the TLS handshake occurs before the server knows which resource is being requested there would be no way for TLS to take meaningful action.
Nikita Kipriyanov avatar
za flag
What makes a certificate unique, what is enough to distingush a certificate from others, i.e. to authenticate? Actual "signed" value in thе certificate is the public key, and what makes it a certificate is a CA signature which covers this key. The key is important because it is used in the actual asymmetric crypto. Everything else is "purely informational", however some elements like DN are easier to work with and it is possible them to be made unique, e.g. eglible to authentication.
Steffen Ullrich avatar
se flag
@NikitaKipriyanov: *Everything else is "purely informational"* - I don't agree. Apart from public key there are key usage restrictions, certificate purpose ... - which have a clearly defined meaning and standards how they should be handled. There is also SAN (and older: CN) which has a clearly defined and standardized meaning in the context of server certificates and protocols like HTTPS, SMTP, IMAP, ... . There isn't such a standard though for restricting client certificates to domains.
Nikita Kipriyanov avatar
za flag
The actual *authentication*, defined as the process of assessing the identity of the actor is mathematically tied to the key and *only* to the key. The private key is kept secret by some entity, and since an actor is able to decrypt the challenge we encrypted with their public key means they are this entity. The type of entity is recorded in the certificate, and the validity of this information is signed by the CA. In case of web site identity is its name, so we sign together key and SAN. In case of a client certificate we can use the key itself as the identifier of the entity, just like SSH.
Nikita Kipriyanov avatar
za flag
Certificate purpose, key usage restrictions, and so on, don't play any role in the authentication process. If the challenge was properly decrypted, we know for sure the other side has the private key. If one can establish identity of a public key (for example, by using some field of a certificate, e.g. SAN), they actually autheticated the other side. The all other fields are more informational and authorization-related. And you are right (in the answer), it's up to the other party if they could make use of that information.
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.