如何在DDEV环境中使用自签名客户端证书(Apache)
问题根源
你猜的没错——DDEV的ddev-router会终止所有外部HTTPS请求的SSL连接,然后以纯HTTP方式将请求转发到Apache容器的80端口。这就导致你在Apache配置中写的:443虚拟主机块完全不会被触发,所有请求都走:80块,自然443内的配置无法生效。
可行解决方案
下面提供两种适配DDEV架构的实现方式,你可以根据需求选择:
方案一:通过ddev-router传递证书验证信息(推荐,符合DDEV常规流程)
这种方式让ddev-router负责接收客户端证书、完成验证,再将验证结果传递给后端Apache,由Apache或你的应用做访问控制。
存放CA证书
将你的自签名CA证书放到项目根目录的.ddev/certs/文件夹下(如果没有就新建),例如命名为my-custom-ca.crt。添加router自定义配置
在.ddev/nginx/目录下创建client-cert.conf文件,写入以下内容:# 指定用于验证客户端证书的CA文件路径 ssl_client_certificate /mnt/ddev_config/certs/my-custom-ca.crt; # 设置为optional允许无证书请求,若要强制验证可改为on ssl_verify_client optional; # 将验证结果和证书元数据通过HTTP头传递给Apache proxy_set_header X-Client-Verify $ssl_client_verify; proxy_set_header X-Client-DN $ssl_client_s_dn; proxy_set_header X-Client-Cert $ssl_client_cert;配置router挂载CA证书
修改.ddev/config.yaml,添加router的挂载配置,让它能访问到你的CA证书:router_mounts: - type: bind source: ./certs target: /mnt/ddev_config/certs在Apache中配置访问控制
打开.ddev/apache/apache-site.conf,在:80虚拟主机块内添加需要验证的路由规则。比如要保护/api/secure路径:<Location "/api/secure"> # 仅允许验证通过的客户端访问 Require expr %{HTTP_X_CLIENT_VERIFY} == "SUCCESS" </Location>如果你想在应用代码中自行验证证书,可以通过
X-Client-Cert头获取客户端证书内容,再用你的CA证书做校验。
方案二:让Apache直接处理SSL(绕过ddev-router)
适合不需要通过DDEV域名访问,直接访问容器端口的场景:
暴露Apache的SSL端口
修改.ddev/config.yaml,添加端口映射,将Apache容器的443端口暴露到宿主机:web_extra_exposed_ports: - name: "ssl" container_port: 443 host_port: 8443配置Apache的443虚拟主机
在.ddev/apache/apache-site.conf的:443块中补充SSL和客户端证书验证配置:<VirtualHost *:443> SSLEngine on # 使用DDEV默认的SSL证书(也可以替换成你自己的) SSLCertificateFile "/etc/ssl/certs/ddev-local.crt" SSLCertificateKeyFile "/etc/ssl/private/ddev-local.key" # 挂载你的CA证书路径 SSLCACertificateFile "/var/www/html/.ddev/certs/my-custom-ca.crt" SSLVerifyClient optional SSLOptions +StdEnvVars # 针对特定路由强制验证 <Location "/api/secure-endpoints"> Require ssl-verify-client </Location> # 保留原有其他配置 DocumentRoot /var/www/html/public # ... 其他原有配置 </VirtualHost>挂载CA证书到Apache容器
在.ddev/config.yaml中添加web容器的挂载配置:web_mounts: - type: bind source: ./certs target: /var/www/html/.ddev/certs访问测试
重启DDEV后,直接通过https://localhost:8443访问你的应用,此时Apache会直接处理SSL连接并验证客户端证书。
内容的提问来源于stack exchange,提问作者sclausen

