mTLS 无法与 FastAPI 和 Uvicorn 一起使用

问题描述 投票:0回答:1

我对 ssl 完全陌生,如果这是一个非常明显的问题,我很抱歉。我的项目需要 mTLS 身份验证,我不得不承认,我真的很困惑! (这大约是进入这个兔子洞的第 10 个小时)。 我正在使用一个简单的 FastAPI 应用程序和 Uvicorn

我使用 Let's Encrypt 设置了 https,没有任何问题,只需将以下内容添加到我的 uvicorn 命令中:

ssl_keyfile="mtls/letsencrypt/privkey.pem",
ssl_certfile="mtls/letsencrypt/fullchain.pem"

有人指出本教程:https://medium.com/@rob.blackbourn/how-to-use-cfssl-to-create-self-signed-certificates-d55f76ba5781创建一些自签名证书,

本教程启用 mTLS:https://ahaw021.medium.com/mutual-tls-mtls-with-fastapi-and-uvicorn-3b9e91bdf5a6

然而,海水仍然很浑浊。我用过

cfssl gencert -ca intermediate_ca.pem -ca-key intermediate_ca-key.pem -config cfssl.json -profile=client host.json | cfssljson -bare client

创建

client.pem
client-key.pem
client.csr
。然后我使用以下命令从我的
client.crt
文件创建
client.pem

openssl x509 -outform der -in mtls/cert/client.pem -out mtls/cert/client.crt

并从 Chrome 的设置中安装它。但是,当我运行 uvicorn 命令并转到我的域时,chrome 不会显示

client.crt
,显然当我单击“取消”时,它会给我
ERR_EMPTY_RESPONSE

我尝试使用 Postman 调用端点,因此我为 crt 文件选择了

client.crt
,为证书下的密钥文件选择了
client-key.pem
,并在常规设置和端点的设置选项卡下启用了 SSL。我要么收到两个错误之一,具体取决于我的故障排除方法:

Error: error:0900006e:PEM routines:OPENSSL_internal:NO_START_LINE

Error: socket hang up
我完全不知道该做什么,我显然在某个时候出了问题,但不知道在哪里。 在尝试 mTLS 之前我已经测试过该应用程序,HTTPS 工作正常。我的蒸馏代码如下:

#main.py
from fastapi import FastAPI
import uvicorn
import ssl

from routers import router1,router2

app = FastAPI(root_path="/api/v1",)
app.include_router(router1.router)
app.include_router(router2.router)

@app.post("/auth")
async def auth() -> Token:
    #oauth2 authentication
    pass

@app.get("/a")
async def endpoint_a():
    return {"a":"b"}

if __name__ == "__main__":
    uvicorn.run("main:app", 
                host="0.0.0.0", 
                port=8000,
                ssl_keyfile="mtls/letsencrypt/privkey.pem", # Provided by Let's Encrypt
                ssl_certfile="mtls/letsencrypt/fullchain.pem",

                ssl_ca_certs="mtls/certs/fullchain.pem", # combined ca.pem and intermediate_ca.pem
                ssl_cert_reqs=ssl.CERT_REQUIRED
                )

cfssl 使用的配置文件:

#cfssl
{
    "signing": {
      "default": {
        "expiry": "8760h"
      },
      "profiles": {
        "intermediate_ca": {
          "usages": [
              "signing",
              "digital signature",
              "key encipherment",
              "cert sign",
              "crl sign",
              "server auth",
              "client auth"
          ],
          "expiry": "8760h",
          "ca_constraint": {
              "is_ca": true,
              "max_path_len": 0, 
              "max_path_len_zero": true
          }
        },
        "peer": {
          "usages": [
              "signing",
              "digital signature",
              "key encipherment", 
              "client auth",
              "server auth"
          ],
          "expiry": "8760h"
        },
        "server": {
          "usages": [
            "signing",
            "digital signing",
            "key encipherment",
            "server auth"
          ],
          "expiry": "8760h"
        },
        "client": {
          "usages": [
            "signing",
            "digital signature",
            "key encipherment", 
            "client auth"
          ],
          "expiry": "8760h"
        }
      }
    }
  }

#ca.json
{
    "CN": "Joseph0M API CA",
    "key": {
      "algo": "rsa",
      "size": 2048
    },
    "CA": {
        "expiry": "8766h",
        "pathlen": 2
    },
    "names": [
    {
      "C": "GB",
      "L": "London",
      "O": "Joseph0M",
      "E": "email",
      "ST": "England"
    }
   ]
  }

#intermediate_ca.json
{
    "CN": "Joseph0M API Intermediate CA",
    "key": {
      "algo": "rsa",
      "size": 2048
    },
    "names": [
      {
        "C":  "GB",
        "L":  "London",
        "O":  "Joseph0M",
        "E": "email",
        "ST": "England"
      }
    ],
    "ca": {
      "expiry": "42720h"
    }
  }
  
#host.json
{
    "CN": "my domain",
    "key": {
      "algo": "rsa",
      "size": 2048
    },
    "names": [
    {
      "C": "GB",
      "L": "London",
      "O": "Joseph0M",
      "E": "email",
      "ST": "England"
    }
    ],
    "hosts": [
      "domain name",
      "localhost",
      "ip address of server"
    ]
  }

任何帮助将不胜感激,谢谢!

ssl postman fastapi uvicorn mtls
1个回答
0
投票

所以,我终于让它工作了,由于某种原因,由中间 ca 签署的客户端证书不起作用,所以我用 root 签署了它们,并将

ca.pem
添加到
ssl_ca_certs
。感谢 Maarten 的帮助,非常感谢!对于那些可能处于类似情况的人,以下内容也很有帮助:https://mtls.dev/

© www.soinside.com 2019 - 2024. All rights reserved.