AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / server / 问题 / 1035044
Accepted
ZioByte
ZioByte
Asked: 2020-09-24 06:11:10 +0800 CST2020-09-24 06:11:10 +0800 CST 2020-09-24 06:11:10 +0800 CST

覆盖特定 nginx 虚拟服务器的“SSL 客户端:否”

  • 772

我有一堆客户(太多而无法轻松改造),每个客户都持有一个证书(由我无法控制的非标准 CA 签名;我刚刚生成了 CSR)。

现在我需要设置一个“安全”的 Web 服务,其中服务器以通常的 ssl (https) 方式标识,客户端应该使用其证书来标识(主题已经保存了我唯一标识客户端所需的所有信息)。

不幸的是,在签名过程中,几乎所有“目的”标志都被清除了:

openssl x509 -in 57EMM020001.cer -noout -purpose 
Certificate purposes:
SSL client : No
SSL client CA : No
SSL server : No
SSL server CA : No
Netscape SSL server : No
Netscape SSL server CA : No
S/MIME signing : Yes
S/MIME signing CA : No
S/MIME encryption : No
S/MIME encryption CA : No
CRL signing : No
CRL signing CA : No
Any Purpose : Yes
Any Purpose CA : Yes
OCSP helper : Yes
OCSP helper CA : No
Time Stamp signing : No
Time Stamp signing CA : No

我假设“400 SSL证书错误”的“罪魁祸首”是第一个:“SSL客户端:否”。

有没有办法告诉我的本地 nginx 服务器(我可以完全控制它)忽略这些设置?

我完全理解这通常是“不好的”,因为如果没有为特定目的生成证书......那么,它不应该用于该目的!但这是我非常具体的服务器,我觉得我有权决定我信任谁。

有什么方法可以说服 nginx 以稍微宽松的方式做事吗?

我当前(不工作)的设置非常简单:

server {
    listen 443 ssl;

    resolver 127.0.0.1 8.8.8.8;
    set $backend "http://localhost:5000";

    server_name updates.example.com;

    ssl_certificate /etc/ssl/certs/server.pem;
    ssl_certificate_key /etc/ssl/private/server.key;

    ssl_client_certificate /etc/ssl/certs/CAroot.cer;
    ssl_verify_client on;

    location / {
        proxy_connect_timeout   60;
        proxy_read_timeout      60;
        proxy_send_timeout      60;
        proxy_intercept_errors  off;
        proxy_http_version      1.1;
        proxy_set_header        Host               $http_host;
        proxy_set_header        X-Real-IP          $remote_addr;
        proxy_set_header        X-Forwarded-For    $proxy_add_x_forwarded_for;
        proxy_set_header        X-Forwarded-Proto  $scheme;
        proxy_set_header        X-Client-Subject   $ssl_client_s_dn;
        proxy_pass $backend;
    }    
}

当然,我检查了:

openssl verify -verbose -CAfile /etc/ssl/certs/CAroot.cer 57EMM020001.cer 
57EMM020001.cer: OK

提前致谢

nginx certificate-authority client-certificate
  • 1 1 个回答
  • 255 Views

1 个回答

  • Voted
  1. Best Answer
    ZioByte
    2020-09-24T09:40:29+08:002020-09-24T09:40:29+08:00

    我找到了一个可行的解决方案,但这并不是很优雅,所以我会暂时不接受它,希望有人能提出更好的解决方案。

    删除ssl_client_certificate并切换到ssl_verify_client optional_no_ca实际上会获取客户端证书,但它不会尝试检查它,因此后端可以自主进行检查。

    我当前的 nginx 设置是:

    server {
        listen 443 ssl;
    
        resolver 127.0.0.1 8.8.8.8;
        set $backend "http://localhost:5000";
    
        server_name updates.example.com;
    
        ssl_certificate /etc/ssl/certs/server.pem;
        ssl_certificate_key /etc/ssl/private/server.key;
    
        ssl_verify_client optional_no_ca;
    
        location / {
            proxy_connect_timeout   60;
            proxy_read_timeout      60;
            proxy_send_timeout      60;
            proxy_intercept_errors  off;
            proxy_http_version      1.1;
            proxy_set_header        Host               $http_host;
            proxy_set_header        X-Real-IP          $remote_addr;
            proxy_set_header        X-Forwarded-For    $proxy_add_x_forwarded_for;
            proxy_set_header        X-Forwarded-Proto  $scheme;
            proxy_set_header        X-Client-Subject   $ssl_client_s_dn;
            proxy_set_header        X-Client-Cert      $ssl_client_cert;
            proxy_pass $backend;
        }
    }
    

    后端(一个简单的 python/flask 安装)包括:

    def get_id(headers):
        cer = headers.get('X-Client-Cert')
        with NamedTemporaryFile('w+') as ntf:
            for lin in cer.splitlines():
                ntf.write(lin.strip())
                ntf.write('\n')
            ntf.flush()
            p = run(['openssl', 'verify', '-CAfile', cafile, ntf.name])
        if p.returncode == 0:
            m = search(r'/CN=([~/]+)', headers.get('X-Client-Subject'))
            if m:
                return m.group(1)
        return None
    
    • 1

相关问题

  • Gzip 与反向代理缓存

  • nginx 作为代理的行为

  • Nginx 学习资源 [关闭]

  • 提供 70,000 个静态文件 (jpg) 的最佳方式?

  • 在 Apache、LightTPD 和 Nginx Web 服务器上提供 PHP 5.x 应用程序的现状?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    新安装后 postgres 的默认超级用户用户名/密码是什么?

    • 5 个回答
  • Marko Smith

    SFTP 使用什么端口?

    • 6 个回答
  • Marko Smith

    命令行列出 Windows Active Directory 组中的用户?

    • 9 个回答
  • Marko Smith

    什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同?

    • 3 个回答
  • Marko Smith

    如何确定bash变量是否为空?

    • 15 个回答
  • Martin Hope
    Tom Feiner 如何按大小对 du -h 输出进行排序 2009-02-26 05:42:42 +0800 CST
  • Martin Hope
    Noah Goodrich 什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同? 2009-05-19 18:24:42 +0800 CST
  • Martin Hope
    Brent 如何确定bash变量是否为空? 2009-05-13 09:54:48 +0800 CST
  • Martin Hope
    cletus 您如何找到在 Windows 中打开文件的进程? 2009-05-01 16:47:16 +0800 CST

热门标签

linux nginx windows networking ubuntu domain-name-system amazon-web-services active-directory apache-2.4 ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve