mTLS – Restrict Client Certificate to Specific Subdomain

opensslssl

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?

Best Answer

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.