末日审判
通过 mTLS,我试图找到一种方法来颁发客户端证书,该证书仅授予该客户端访问特定子域的权限。我怀疑这是不可能的,但我不确定。
我想要实现的目标
假设我有一台服务器监听路由到*.foo.flar.com
每个客户都被分配了自己的子域,以满足服务器地址中的通配符。
例如,customer1
应该通过 访问服务器customer1.foo.flar.com
,并且customer2
应该通过 访问服务器customer2.foo.flar.com
。
此外,必须阻止一个客户使用其他客户的子域访问服务器。因此,customer1
请求是非法的customer2.foo.flar.com
,应拒绝此类请求。
我希望能够通过 mTLS 和一些巧妙的 SAN 证书使用在会话层实现这一点,但我无法让它正常工作。
我如何设置
我对 TLS 还很陌生,所以很多内容都来自关于 SAN 配置的这个答案和这篇关于基本 mTLS 配置的文章。
我在这里省略了一些内容,例如 CA 证书生成和客户端和服务器 CSR 生成,以尝试保持集中,但如果您愿意,可以添加它。
我使用类似如下的方法创建了服务器证书:
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
然后我使用类似如下的方法创建了客户端证书:
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
服务器(用 Go 编写)配置为需要并验证客户端证书。
问题
问题是,当我测试此设置时,我预计连接会失败,但实际上它成功了。
如果我有客户端颁发的customer1
证书,则调用服务器customer1.foo.flar.com
,连接成功。
但是,如果我有一个客户端发布了证书,customer1
并调用了服务器customer2.foo.flar.com
,那么当我预计它会失败时,该连接也会成功。
我希望服务器在检查客户端证书时,能够发现customer1
无权访问customer2...
,并拒绝请求。但这似乎没有发生。
有想法吗?
答案1
客户端证书仅包含用于验证用户身份的信息。对已验证用户可执行的操作(授权)的任何限制(包括证书可在哪个站点接受)均由检查证书的服务器决定。