![Apache 反向代理 mTLS 仅在客户端和代理之间,常规 TLS 在代理和后端之间](https://linux22.com/image/784690/Apache%20%E5%8F%8D%E5%90%91%E4%BB%A3%E7%90%86%20mTLS%20%E4%BB%85%E5%9C%A8%E5%AE%A2%E6%88%B7%E7%AB%AF%E5%92%8C%E4%BB%A3%E7%90%86%E4%B9%8B%E9%97%B4%EF%BC%8C%E5%B8%B8%E8%A7%84%20TLS%20%E5%9C%A8%E4%BB%A3%E7%90%86%E5%92%8C%E5%90%8E%E7%AB%AF%E4%B9%8B%E9%97%B4.png)
我正在尝试创建一个 apache 反向代理(用于 web 服务),其中我需要客户端和代理本身之间进行相互身份验证 (mTLS),但我不需要代理和后端之间进行 mTLS(多个后端在不同端口上运行多个 web 服务),常规 SSL 就足够了。
我想要实现的目标的示意图:
我正在考虑一个类似于下面的 Apache 配置,但是我的 Apache 知识非常有限,我希望得到建议。
注意:下面的配置只显示 1 个 vHost(而不是整个 apache 配置),因为我计划在后端拥有与 Webservices 一样多的 vHost(因为这将服务于多个应用程序):
# ---------------------------------------------
# mTLS vHost for Service <Appl_a>
# ---------------------------------------------
<VirtualHost <dns_alias>:<PortID>
ServerName <dns_alias>
# Custom logs for this vHost
ErrorLog "<Logdir>/error_log"
TransferLog "<Logdir>/access_log"
# SSL activation on the proxy itself
SSLEngine on
SSLCertificateFile "<Path_to_keys>/proxy.cer" # Proxy cert file + CA trust cert
SSLCertificateKeyFile "<Path_to_keys>/proxy.key" # Proxy private key
# security options
ProxyRequests off # only a reverse proxy
SSLProtocol -all +TLSv1.2 +TLSv1.3 # we only allow TLS 1.2 et 1.3
SSLHonorCipherOrder On # server forces ciphers (not the client)
# client certificate authentication (for mTLS between proxy & client)
SSLProxyEngine On
SSLVerifyClient require
SSLVerifyDepth 10
SSLCACertificateFile "<Path_to_keys>/client.cer" # Client's certificate file or CA only ? (as they are both signed by the same CA) ?
# I BELIEVE I DONT NEED THIS
# as it would only be if i wanted mTLS between proxy and backend
# (or to forward client certs to the backend, can you please confirm ?)
SSLProxyCACertificateFile "<Path_to_keys>/server.cer"
SSLProxyMachineCertificateFile "<Path to keys>/proxy.pem"
SSLProxyVerify require
SSLProxyCheckPeerName off
SSLProxyCheckPeerCN off
SSLProxyCheckPeerExpire off
# Proxy
RequestHeader set SSL_CLIENT_CERT "" # I BELIEVE this is also useless
<Location />
RequestHeader set SSL_CLIENT_CERT "%{SSL_CLIENT_CERT}s" # USELESS ? as this is to forward the client cert to the backend, but i don't need mTLS to reach backends ?
ProxyPass https://<appl_URL>:<appl_PORT>/<WS_URL>
ProxyPassReverse ttps://<appl_URL>:<appl_PORT>/<WS_URL>
</Location>
</VirtualHost>
# ---------------------------------------------
# mTLS vHost for Service <n>
# ---------------------------------------------
... same for another port/ws
您能否帮我确认一下此配置是否合理,或者您将如何做这样的事情。我认为此配置中的多个部分是无用的,因为它们旨在将客户端证书转发到后端以进行完整的相互身份验证代理(这不是我想要的) - 请参阅配置中的注释。
第二件事:如果我想在代理级别终止流量并将请求作为 HTTP 转发到后端,该怎么办?我是否应该在 Proxy 和 ProxyPassReverse 指令中将 https 替换为 http?
先感谢您,
答案1
对于第 1 点:
在适当的虚拟主机中,您只需要两个额外的指令和一个可选指令。
一个指令来告诉 Apache 授权哪些 CA 来颁发客户端证书(这是您承认的客户端证书的根 CA 列表):
SSLCACertificateFile "/path/to/ca-auth-list.pem"
然后,在您希望 mTLS 发生的每条路径中,或者如果您愿意的话,在整个虚拟主机中:
SSLVerifyClient require
额外定义您支持链中的 CA 深度或数量:
SSLVerifyDepth 2
对于第 2 点:
反向代理连接与客户端发送到服务器的内容完全不同,因此代理的后端可以是 https/http/ajp/ws 或您可能需要的任何内容。
附言:不要将 Location 用于 proxypass 指令,ProxyPass 已经在其第一个参数中提供了一个位置,但是 location 和 proxypass 指令以相反的方式进行解释,因此混合它们会导致麻烦。