# ============================================================
# Nginx 双向 TLS (mTLS) 认证配置示例
# ============================================================
#
# 功能说明:
# - 客户端证书验证
# - 验证模式配置（可选/必须）
# - 证书撤销列表 (CRL)
# - 验证深度配置
#
# Lolly 对应配置:
# server:
#   ssl:
#     cert: "/path/to/server.crt"
#     key: "/path/to/server.key"
#     client_verify:
#       enabled: true
#       mode: "require"  # 可选值: none, request, require, optional_no_ca
#       client_ca: "/path/to/client-ca.crt"
#       verify_depth: 2
#       crl: "/path/to/crl.pem"
# ============================================================

server {
    listen 443 ssl;
    server_name mtls.example.com;

    # 服务端 SSL 配置
    ssl_certificate /etc/nginx/ssl/server.crt;
    ssl_certificate_key /etc/nginx/ssl/server.key;
    ssl_protocols TLSv1.2 TLSv1.3;

    # 客户端证书验证配置
    # Lolly 对应: ssl.client_verify 配置块

    # 验证模式:
    # none - 不请求客户端证书
    # request - 请求客户端证书，但即使验证失败也允许连接
    # require - 必须提供客户端证书，必须验证成功
    # optional_no_ca - 必须提供客户端证书，但不验证
    ssl_verify_client require;

    # 客户端 CA 证书（用于验证客户端证书）
    ssl_client_certificate /etc/nginx/ssl/client-ca.crt;

    # 证书链验证深度
    ssl_verify_depth 2;

    # 证书撤销列表 (CRL)
    ssl_crl /etc/nginx/ssl/crl.pem;

    # 获取客户端证书信息
    # $ssl_client_cert - 客户端证书原始内容
    # $ssl_client_s_dn - 客户端证书主题 DN
    # $ssl_client_i_dn - 客户端证书颁发者 DN
    # $ssl_client_serial - 客户端证书序列号
    # $ssl_client_verify - 验证结果: SUCCESS, FAILED, NONE

    location / {
        # 将客户端证书信息传递给后端
        proxy_pass http://backend:8080;
        proxy_set_header X-Client-Cert $ssl_client_cert;
        proxy_set_header X-Client-CN $ssl_client_s_dn_cn;
        proxy_set_header X-Client-Serial $ssl_client_serial;
        proxy_set_header X-Client-Verify $ssl_client_verify;
    }

    # 客户端证书验证失败处理
    location @client_cert_error {
        return 403 "Client certificate required or invalid";
    }

    # 验证失败时返回错误页面
    error_page 495 496 @client_cert_error;
    # 495 - 客户端证书验证失败
    # 496 - 未提供客户端证书
}

# mTLS 证书生成说明:
#
# 1. 创建 CA 证书:
#    openssl genrsa -out client-ca.key 4096
#    openssl req -new -x509 -days 3650 -key client-ca.key -out client-ca.crt
#
# 2. 创建客户端证书:
#    openssl genrsa -out client.key 2048
#    openssl req -new -key client.key -out client.csr
#    openssl x509 -req -days 365 -in client.csr -CA client-ca.crt -CAkey client-ca.key -CAcreateserial -out client.crt
#
# 3. 创建 CRL:
#    openssl ca -config ca.conf -gencrl -out crl.pem
#
# 4. 客户端使用证书:
#    curl --cert client.crt --key client.key https://mtls.example.com