NGINX Unit

SSL/TLS 证书§

/certificates 部分的 控制 API 处理与 Unit 的 侦听器 一起使用的 TLS 证书。

要为侦听器设置 SSL/TLS,请将包含证书链和私钥的 .pem 文件上传到 Unit,并在侦听器的配置中命名上传的捆绑包;接下来,可以通过 SSL/TLS 访问侦听器。

注意

有关 Unit 中证书颁发和续订的详细信息,请参阅 TLS with Certbot 中的示例。

首先,使用证书链和私钥创建一个 .pem 文件

$ cat cert.pem ca.pem key.pem > bundle.pem

通常,网站的证书(可选,后面跟中间 CA 证书)足以构建证书链。如果您向链中添加更多证书,请按从叶到根的顺序排列它们。

将生成的捆绑包文件上传到 Unit 的证书存储中,并使用适当的名称(在本例中为 bundle

# curl -X PUT --data-binary @bundle.pem --unix-socket \
       /path/to/control.unit.sock https://127.0.0.1/certificates/bundle

    {
        "success": "Certificate chain uploaded."
    }

警告

不要对使用 strong class="program">curl 上传的文件使用 -d;此选项会损坏 .pem 文件。在上传基于文件的 data 时,请使用 --data-binary 选项,以避免数据损坏。

在内部,Unit 将上传的证书捆绑包与其 state 子目录中的其他配置 data 一起存储;控制 API 使用 /certificates 将其中一些属性公开为 GET 表格 JSON

{
    "certificates": {
        "bundle": {
            "key": "RSA (4096 bits)",
            "chain": [
                {
                    "subject": {
                        "common_name": "example.com",
                        "alt_names": [
                            "example.com",
                            "www.example.com"
                        ],

                        "country": "US",
                        "state_or_province": "CA",
                        "organization": "Acme, Inc."
                    },

                    "issuer": {
                        "common_name": "intermediate.ca.example.com",
                        "country": "US",
                        "state_or_province": "CA",
                        "organization": "Acme Certification Authority"
                    },

                    "validity": {
                        "since": "Sep 18 19:46:19 2022 GMT",
                        "until": "Jun 15 19:46:19 2025 GMT"
                    }
                },
                {
                    "subject": {
                        "common_name": "intermediate.ca.example.com",
                        "country": "US",
                        "state_or_province": "CA",
                        "organization": "Acme Certification Authority"
                    },

                    "issuer": {
                        "common_name": "root.ca.example.com",
                        "country": "US",
                        "state_or_province": "CA",
                        "organization": "Acme Root Certification Authority"
                    },

                    "validity": {
                        "since": "Feb 22 22:45:55 2023 GMT",
                        "until": "Feb 21 22:45:55 2026 GMT"
                    }
                }
            ]
        }
    }
}

注意

通过索引访问数组项,例如链中的各个证书及其属性

# curl -X GET --unix-socket /path/to/control.unit.sock \
       https://127.0.0.1/certificates/bundle/chain/0/
# curl -X GET --unix-socket /path/to/control.unit.sock \
       https://127.0.0.1/certificates/bundle/chain/0/subject/alt_names/0/

接下来,将上传的捆绑包添加到 侦听器;生成的控制 API 配置可能如下所示

{
    "certificates": {
        "bundle": {
            "key": "<key type>",
            "chain": [
                "<certificate chain, omitted for brevity>"
            ]
        }
    },

    "config": {
        "listeners": {
            "*:443": {
                "pass": "applications/wsgi-app",
                "tls": {
                    "certificate": "bundle"
                }
            }
        },

        "applications": {
            "wsgi-app": {
                "type": "python",
                "module": "wsgi",
                "path": "/usr/www/wsgi-app/"
            }
        }
    }
}

全部完成;现在可以通过 SSL/TLS 访问应用程序

$ curl -v https://127.0.0.1
    ...
    * TLSv1.2 (OUT), TLS handshake, Client hello (1):
    * TLSv1.2 (IN), TLS handshake, Server hello (2):
    * TLSv1.2 (IN), TLS handshake, Certificate (11):
    * TLSv1.2 (IN), TLS handshake, Server finished (14):
    * TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
    * TLSv1.2 (OUT), TLS change cipher, Client hello (1):
    * TLSv1.2 (OUT), TLS handshake, Finished (20):
    * TLSv1.2 (IN), TLS change cipher, Client hello (1):
    * TLSv1.2 (IN), TLS handshake, Finished (20):
    * SSL connection using TLSv1.2 / AES256-GCM-SHA384
    ...

最后,您可以从存储中删除不再需要的证书捆绑包

# curl -X DELETE --unix-socket /path/to/control.unit.sock \
       https://127.0.0.1/certificates/bundle

    {
        "success": "Certificate deleted."
    }

注意

您无法删除配置中仍然引用的证书捆绑包,使用 put 覆盖现有捆绑包,或删除不存在的捆绑包。