自签名证书生成
关于HTTPS证书、证书链、HTTPS通信流程等,这里不做解决,不清楚的可以自行查询该方面的内容。
为了生成自签名私钥,需要执行下面流程:
- 生成RSA私钥。可以增加-des3参数来控制生成私钥是否使用密码,如果使用密码后续签发证书也需要输入密码。
- 不指定密码:openssl genrsa -out server.key 2048
- 指定密码:openssl genrsa -des3 -out server.key 2048
使用不指定密码方式生成证书,如下:
$ openssl genrsa -out server.key 2048
$ ls
server.key
$ cat server.key
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCcuvDy8xIVFw2Y
xw27noZA72lHJXuTl8DqFU//vvwueB4rxQDSA8CqXEVM6JxA8aMWw5iQz8WnN5SO
oGU3LFBrsoVtooXooQ2jiJPN+u9mAAgPilPBLpJB4sYA+xplA3NMIY2BXxRWr61N
UP0OqeD6T9yqJauz+v9im+SiiIZmZiBrWnD83uae19rN3WLSehhhJlwVwPtIFAX+
AnVH6Rh0sgIDabQsR04nte1AUdZ0WR4U04BsiXY9UIyF5K8xECpgj6+iM15Wc2N7
+SSPnh2gEBvcYW9L1ySlvujVuszadeahYxAsRRrzjWgGGmi1yOOoVMFLN1Pzv5tt
BPWmlEuHAgMBAAECggEACubL5LI4k0P3u6U41NCJeRHOCldWmaUIE6Ao4NqZcugC
/TtmO7VsHM1vOpLBb5j/JZG0VnpFPsTUbflFIQnRjDQuKLqRwuUU7EePNFgcd8VP
yjjua3UAUlniOOY+Z0FOr0B0Ncf1w7PTg5m7CF6TmgWdDS6ym0G9qs+6Hv4NDyk2
f5VUB+bEhor1kmJX6L31eXoDSal34EvUF9VtLU1Xgkjo0KYI/b0mXtJXMIuhIS9O
3Kopi6uuGbM+wCDeYBGiKZedX+3knMQbIBXKMg7QEH8OP+USzr78ubfcNsTDTG9f
6UtcO94AjTpP7jgZkMzt6nCt6jOXVXr6p0A9k0wT1QKBgQDM+J3190i97UPADiel
31XwltxQOMu9Yv3CjSr/KmQdhrDkvtxIsYmPR30oPHceMqHNwktM36p/DiRFKZ8r
mEmYf+aYhD0yygkCEgvlK4CgWhlKGVKQl1KaBWEyoWoB6mH7YjLenykQYaK+NULm
PV3kUTdDRYSfbBJvIDPiZnjk1QKBgQDDv8u/1OFNtoV3+zcG/Ym8DZinYpoCdseQ
JQawu3cQPCA4gGXnfadN1GqjU39sexX3gjzTDPwRleyY8C/rt//d7pm0YymNl8aD
4nLHDR/s5lGkeP6ZwJNI6LjOHuuea7rU4tkPwkdYI/cfKGt433EM6PRO09QlUirn
t5vRfH9M6wKBgG6oBfdFQiMvFXV47tSw5t+VQmmYz/11lNPUjJLnGteJ4LQNijVA
i6grixkO06wc35eKvkZJNe2T/+bK2qCZfZnz6tUKB1QFGKnifkOBodZv7dlAJH/l
AfYe02OXGvjfxXgGgroHKQ8r9sVDUdOk66yYYAJUZI4AtU8DDp+6fKflAoGAFENG
VBU1PVYnesQGbjLQjybZJnqOdrLU9ZbfmmvNZ2DR9QdVhSD8sJHMeBuslQ4ot/ZD
VZWCgk+CrlIuo7foRJDuWD3rjzym0AAg4Xn6VAuDaAMeV8wXcvSkLLIGsd9095SD
4524xOb0LcWBWoHGsg9rOr2yuCpJRrM67fR1OQECgYEAw/VaKkKvOBfpZmAFil3Q
dUNvjAos1+54vruyxuuO1DmTmqiw6nAbYxc6xxlEH1IxI9vvI6yj35X3JRsQI5d2
1f9EYz/EpxrvVaeGg7WxwkDeGz0aBH4p5tsvSImUc8tbu8lWmT5MkB0hlKs7xcv0
NLTEeqZs2LMrldpVF2UaPHQ=
-----END PRIVATE KEY-----
- 使用私钥生成证书。
- 命令:openssl req -x509 -sha256 -new -key server.key -out server.crt
命令执行后会提示一些交互操作,其中:
- Country Name:国家名,这些可以填CN。
- State or Province Name:省份,可以填Zhejiang。
- Locality Name:城市名,可以填Hangzhou。
- Organization Name:组织名,一般是公司。
- Organizational Unit Name:部门。
- Common Name:该值最重要,必须是要自签名的域名,如果使用IP则是自签名的IP。不能填错。
- Email Address:邮箱地址。
$ openssl req -x509 -sha256 -new -key server.key -out server.crt
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:CN
State or Province Name (full name) [Some-State]:Zhejiang
Locality Name (eg, city) []:Hangzhou
Organization Name (eg, company) [Internet Widgits Pty Ltd]:NetEase
Organizational Unit Name (eg, section) []:Shufan
Common Name (e.g. server FQDN or YOUR name) []:127.0.0.1
Email Address []:uniwjj@gmail.com
$ ls
server.crt server.key
$ cat server.crt
-----BEGIN CERTIFICATE-----
MIID+TCCAuGgAwIBAgIUY/XWmujPgtKBZI5HMCo9MzJxvZEwDQYJKoZIhvcNAQEL
BQAwgYsxCzAJBgNVBAYTAkNOMREwDwYDVQQIDAhaaGVqaWFuZzERMA8GA1UEBwwI
SGFuZ3pob3UxEDAOBgNVBAoMB05ldEVhc2UxDzANBgNVBAsMBlNodWZhbjESMBAG
A1UEAwwJMTI3LjAuMC4xMR8wHQYJKoZIhvcNAQkBFhB1bml3ampAZ21haWwuY29t
MB4XDTIzMTIxODE1NTQ0NVoXDTI0MDExNzE1NTQ0NVowgYsxCzAJBgNVBAYTAkNO
MREwDwYDVQQIDAhaaGVqaWFuZzERMA8GA1UEBwwISGFuZ3pob3UxEDAOBgNVBAoM
B05ldEVhc2UxDzANBgNVBAsMBlNodWZhbjESMBAGA1UEAwwJMTI3LjAuMC4xMR8w
HQYJKoZIhvcNAQkBFhB1bml3ampAZ21haWwuY29tMIIBIjANBgkqhkiG9w0BAQEF
AAOCAQ8AMIIBCgKCAQEAnLrw8vMSFRcNmMcNu56GQO9pRyV7k5fA6hVP/778Lnge
K8UA0gPAqlxFTOicQPGjFsOYkM/FpzeUjqBlNyxQa7KFbaKF6KENo4iTzfrvZgAI
D4pTwS6SQeLGAPsaZQNzTCGNgV8UVq+tTVD9Dqng+k/cqiWrs/r/YpvkooiGZmYg
a1pw/N7mntfazd1i0noYYSZcFcD7SBQF/gJ1R+kYdLICA2m0LEdOJ7XtQFHWdFke
FNOAbIl2PVCMheSvMRAqYI+vojNeVnNje/kkj54doBAb3GFvS9ckpb7o1brM2nXm
oWMQLEUa841oBhpotcjjqFTBSzdT87+bbQT1ppRLhwIDAQABo1MwUTAdBgNVHQ4E
FgQUmWPDjuLs1+Otoawr9onvHUqbU6EwHwYDVR0jBBgwFoAUmWPDjuLs1+Otoawr
9onvHUqbU6EwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAIYY/
Co0SVTbt4zqfOnlk0K0kVtu1UXo/uZESpA2lX0/4G4Zumx4H3FnMwDD6RwV0xmNc
RNLWi5RatE8vXqjAwDoFs5wgnhlj0hzuCMhDzrRMzQ4cUY72ImVQnfhcfatp+/9U
v2EUZXEkv5LyFJC0Lny8qVeF0u/d3uRlJYhMc0jm7f1lgix0+7dyB4juRNlAL8MH
8YfHZJOba2dPHRUou0b08TG0gR99lQfWy1BXXK0DidjhLfmd1QEg2mt6obfzjFC3
tbGAMzsRlVLxG79Ra0+zc7Da20Tuov85D408pjM/DyKbt3UX2B4O8bnsSjFZKz+E
+isiWu8m6axv4dEvoA==
-----END CERTIFICATE-----
上述生成流程较长,需要多次交互操作,可以合成一条命令执行,如下:
openssl req -x509 -sha256 -new -key server.key -out server.crt -days 3650 -subj /C=CN/ST=Zhejiang/L=Hangzhou/O=Netease/OU=Shufan/CN=127.0.0.1/emailAddress=uniwjj@gmail.com
Nginx配置自签名证书
自签名证书生成好之后,就可以在Nginx中配置。
- 监听SSL端口。
server {
listen 80 default_server;
listen [::]:80 default_server;
+ listen 443 ssl;
...
}
- 指定SSL证书。
server {
...
+ ssl_certificate /etc/nginx/ca/server.crt;
+ ssl_certificate_key /etc/nginx/ca/server.key;
...
}
- 重新加载Nginx配置。
sudo nginx -s reload
- 测试验证,可以使用curl命令进行测试。因为是自签名证书,操作系统并不认,所以直接使用curl命令时会提示报错,可以增加-k参数。
$ curl https://127.0.0.1/
curl: (60) SSL certificate problem: self signed certificate
More details here: https://curl.se/docs/sslcerts.html
curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.
$ curl -k https://114.55.132.63/
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
Docker集成
镜像文件
依赖的文件如下:
$ ls
Dockerfile install-ca.sh run-app.sh
- Dockerfile文件内容
FROM nginx:1.25.3
# 添加作者信息
MAINTAINER ginger uniwjj@gmail.com
WORKDIR /opt
ADD ./run-app.sh /opt/run-app.sh
ADD ./install-ca.sh /opt/install-ca.sh
ENV CA_DOMAIN_NAME ""
ENV CA_DAYS "365"
ENV CA_DIR "/etc/nginx/ca"
ENV CA_FILE_NAME "server"
ENV CA_EMAIL "uniwjj@gmail.com"
RUN mkdir -p /etc/nginx/ca \
&& apt-get update \
&& apt-get install -y openssl
EXPOSE 80 443
CMD ["bash","run-app.sh"]
- 证书生成及安装脚本install-ca.sh
#!/bin/bash
if [ ! -f "/etc/nginx/conf.d/default.conf" ];then
echo "nginx default.conf not exists, self-signed ca is not supported"
exit 0
fi
if [ -z $CA_DOMAIN_NAME ];then
echo "CA_DOMAIN_NAME not exists, self-signed ca is not supported"
exit 0
fi
echo "CA_DOMAIN_NAME is $CA_DOMAIN_NAME"
echo "CA_DAYS is $CA_DAYS"
echo "CA_DIR is $CA_DIR"
echo "CA_FILE_NAME is $CA_FILE_NAME"
echo "CA_EMAIL is $CA_EMAIL"
openssl genrsa -out "$CA_DIR/$CA_FILE_NAME.key" 4096
openssl req -x509 -sha256 -new -key "$CA_DIR/$CA_FILE_NAME.key" -out "$CA_DIR/$CA_FILE_NAME.crt" -days $CA_DAYS -subj /C=CN/ST=Zhejiang/L=Hangzhou/O=Netease/OU=Shufan/CN=$CA_DOMAIN_NAME/emailAddress=$CA_EMAIL
echo "self-signed ca is issued"
sed -i "/server_name localhost;/a\ listen 443 ssl;\n\n ssl_certificate $CA_DIR/$CA_FILE_NAME.crt;\n ssl_certificate_key $CA_DIR/$CA_FILE_NAME.key;\n" /etc/nginx/conf.d/default.conf
echo "self-signed ca is installed"
- Nginx启动脚本run-app.sh
#!/bin/bash
bash install-ca.sh
nginx -g "daemon off;";
构建镜像
$ sudo docker build -t nginx-ca:1.25.3 .
[+] Building 1.8s (10/10) FINISHED docker:default
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 457B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/nginx:1.25.3 1.6s
=> [1/5] FROM docker.io/library/nginx:1.25.3@sha256:10d1f5b58f74683ad34eb29287e07dab1e90f10af243f151bb50aa5dbb4d62ee 0.0s
=> [internal] load build context 0.0s
=> => transferring context: 64B 0.0s
=> CACHED [2/5] WORKDIR /opt 0.0s
=> CACHED [3/5] ADD ./run-app.sh /opt/run-app.sh 0.0s
=> CACHED [4/5] ADD ./install-ca.sh /opt/install-ca.sh 0.0s
=> CACHED [5/5] RUN mkdir -p /etc/nginx/ca && apt-get update && apt-get install -y openssl 0.0s
=> exporting to image 0.0s
=> => exporting layers 0.0s
=> => writing image sha256:098e87b1c9c83b19190f6fb09e97f8c9d800126ffa05c3255be076109d46a372 0.0s
=> => naming to docker.io/library/nginx-ca:1.25.3 0.0s
容器启动
使用下面命令启动一个支持自签名ca证书的Nginx容器:
docker run -d \
-p 80:80 \
-p 443:443 \
-e CA_DOMAIN_NAME="127.0.0.1" \
-e CA_DAYS=3650 \
--name some-nginx \
nginx-ca:1.25.3
在启动时,可以指定如下配置:
- CA_DOMAIN_NAME:ca证书关联的域名。
- CA_DAYS:ca证书有效期,默认365天。
- CA_DIR:ca证书存储目录,默认/etc/nginx/ca。
- CA_FILE_NAME:ca证书文件名,默认server。
- CA_EMAIL:ca证书关联的邮箱。
启动后,仍然使用curl命令进行测试,可以看到HTTPS已生效。
$ curl -k https://114.55.132.63/
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>