HTTPS 自签名证书

按照第三方原理来说, https 访问实际上通过第三方证书机构来认证访问过程, 个人可以自己扮演这个第三方证书机构来颁发证书, 同时只需要客户端信任自己颁发的证书就能直接进行 https 访问.

证书生成

这里首先需要在 Linux 上创建自己的 openssl 证书:

1
2
3
4
# 创建证书和私钥
sudo openssl req -x509 -nodes -days 3650 -newkey rsa:4096 \
-keyout /data/ssl/private.meteorcat.com.key \
-out /data/ssl/private.meteorcat.com.crt

这里具体参数:

  • req: 生成证书指令,
  • -x509: 默认创建生成 X.509 证书.
  • -nodes: 不采用短密码对证书进行进一步加密.
  • -days 3650: 证书有效时间(单位: 天), 自己按照习惯常用调整时间.
  • -newkey rsa:4096: 证书加密密钥和加密方式, 这里按照采用4096位RSA密钥.
  • -keyout: 生成的私钥文件路径
  • -out: 生成的证书路径.

输入之后会要求输入证书信息:

  • Country Name: 国家码, 中国采用 CN
  • State or Province Name: 地区省份码, 这里设置 Guang Dong
  • Locality Name (eg, city): 城市地区, 这里设置 Guang Zhou
  • Organization Name: 组织名称, 这里设置自定义组织名 MeteorCat Develop, Inc.
  • Organizational Unit Name: 单位地址名称, 这里设置 MeteorCat Develop
  • Common Name: 所有人名称或者服务器指定名, 这里设置 MeteorCat
  • Email Address: 邮件地址, 这里按照自己需要填写.

以上信息都不是必须, 所以按照自己随便填写即可.

这里就会在 /data/ssl 生成以下文件:

1
2
3
4
ls -l /data/ssl
# 生成如下文件
# -rw-r--r-- 1 meteorcat meteorcat 2232 Feb 21 00:46 private.meteorcat.com.crt
# -rw------- 1 meteorcat meteorcat 3272 Feb 21 00:45 private.meteorcat.com.key

同时这里可以加强安全采用 Forward_secrecy

这个是多个证书密钥都能共用的参数加密方式, 也可以不创建, 因为这一步骤并不是必须:

1
2
# 创建参数认证配置, 这一步的步骤比较长, 参数越长越长消耗性能越大, 2048长度差不多即可. 
sudo openssl dhparam -out /data/ssl/dhparam.pem 2048

这里的证书只能给 Linux 配置使用, 而 Window 只支持 p12 证书, 所以这里需要把 CRT 证书转化即可:

1
2
3
4
5
# crt 证书转 p12
openssl pkcs12 -export -in /data/ssl/private.meteorcat.com.crt \
-inkey /data/ssl/private.meteorcat.com.key \
-out /data/ssl/private.meteorcat.com.p12
# 这里会提示输入密码来对p12证书短密码加密, 可以按照需求来输入或者回车默认不需要密码即可

按照常规来说目前的文件如下:

1
2
3
4
5
6
ls -l /data/ssl
# 生成如下文件:
#-rw-r--r-- 1 meteorcat meteorcat 424 Feb 21 01:01 dhparam.pem
#-rw-r--r-- 1 meteorcat meteorcat 2232 Feb 21 00:46 private.meteorcat.com.crt
#-rw------- 1 meteorcat meteorcat 3272 Feb 21 00:45 private.meteorcat.com.key
#-rw------- 1 meteorcat meteorcat 4499 Feb 21 01:01 private.meteorcat.com.p12

至此证书已经完成好了, Window 客户端只需要 p12 证书, 而 crtkey 只需要服务器来使用, 这里把 p12 证书给 Window 客户端使用:

image

image

基本上一路回车即可, 最后就会导入自己签发的证书文件.

Nginx使用

直接创建自己的本地服务器私域网站服务, 这里手动创建私域网站:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#
# Private server configuration
#
server {
# server or port
server_name private.meteorcat.com;
listen 18080 ssl http2;

# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html;

# http support versions,
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;

# check server cipher
ssl_prefer_server_ciphers on;

# server cipher methods
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";

# certificate path
ssl_certificate /data/ssl/private.meteorcat.com.crt;

# certificate key path
ssl_certificate_key /data/ssl/private.meteorcat.com.key;

# dparams path
ssl_dhparam /data/ssl/dhparam.pem;

# bidirectional check
ssl_verify_client on;
ssl_client_certificate /data/ssl/private.meteorcat.com.crt;


# others......
root /var/www/html;

location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
}
}

ssl_verify_clientssl_client_certificate 是自签名证书必须, 会对客户端的证书验证, 如果客户端访问没有安装证书直接禁止访问, 可以用于安全请求访问验证.

重启 Nginx 之后, 在 Window 客户端 C:\Windows\System32\drivers\etchosts 文件追加解析:

1
2
# 前面是私域服务器IP, 后面是私域服务访问地址, 访问地址指向前面的IP
192.168.1.111 private.meteorcat.com

访问地址就能看见:

image

这里直接点击浏览器器 高级 -> 继续前往private.meteorcat.com(不安全) 是无视个人证书继续访问, 默认自己颁发的证书是不受信任的:

  1. 验证服务端要求提供的证书, 没有证书无法访问
    image

  2. 验证证书完成就
    image

这样就搭建自己的自签名私域网站.

脚本创建证书

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#!/bin/bash

SSL_PATH="/etc/nginx/ssl"

# sudo ?
if [[ "$EUID" != 0 ]]; then
echo "need sudo group"
exit 1
fi

# directory exists?
if [ ! -d $SSL_PATH ];then
mkdir $SSL_PATH
fi

# input filename
read -p "Input CER Name: "
CER_NAME="$REPLY.meteorcat.local"

# files
CER_KEY_FILE="$SSL_PATH/$CER_NAME.key"
CER_OUT_FILE="$SSL_PATH/$CER_NAME.crt"
CER_P12_FILE="$SSL_PATH/$CER_NAME.p12"
echo "==============================================================="
echo "CER: $CER_KEY_FILE"
echo "KEY: $CER_OUT_FILE"
echo "P12: $CER_P12_FILE"
echo "==============================================================="
read -p "Create CER File?(y|n): "
if [ $REPLY != "y" ];then
echo "[y]es Or [n]o, Exit"
exit 1
fi

# cer exists
if [ -f $CER_KEY_FILE ];then
echo "$CER_KEY_FILE Exists"
exit
fi
if [ -f $CER_OUT_FILE ];then
echo "$CER_OUT_FILE Exists"
exit
fi
if [ -f $CER_P12_FILE ];then
echo "$CER_P12_FILE Exists"
exit
fi

# create cer
openssl req -x509 -nodes -subj "/C=CA/ST=CA/L=CA/O=CA/OU=CA/CN=CA" -days 3650 -newkey rsa:4096 -keyout $CER_KEY_FILE -out $CER_OUT_FILE
if [ $? -ne 0 ]; then
echo "Failed by Create CER"
exit 1
fi

# create p12
openssl pkcs12 -export -in $CER_OUT_FILE -inkey $CER_KEY_FILE -out $CER_P12_FILE
if [ $? -ne 0 ]; then
echo "Failed by Create P12"
exit 1
fi

echo "Create Success!"

Nginx宿主机证书配置

宿主机即本身内部提供 Web/TCP/UDP 服务的机器

对于 Nginx 直接配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
server {
listen 60080 ssl http2;
server_name _;
server_name_in_redirect off;


# http support versions,
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;

# check server cipher
ssl_prefer_server_ciphers on;

# server cipher methods
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";

# certificate path
ssl_certificate /etc/nginx/ssl/public.meteorcat.local.crt;

# certificate key path
ssl_certificate_key /etc/nginx/ssl/public.meteorcat.local.key;

# bidirectional check
ssl_verify_client on;
ssl_client_certificate /etc/nginx/ssl/public.meteorcat.local.crt;

# 其他配置
}

Nginx代理机证书配置

宿主机即正式对外暴露的服务器, 用于转发到内网机

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
server {
# 设置监听端口
listen 80;
# 设置服务器访问域名
server_name public.meteorcat.local;
server_name_in_redirect off;

location / {

# 配置自签名证书代理
proxy_ssl_certificate /etc/nginx/ssl/public.meteorcat.local.crt;
proxy_ssl_certificate_key /etc/nginx/ssl/public.meteorcat.local.key;
proxy_ssl_trusted_certificate /etc/nginx/ssl/public.meteorcat.local.crt;


# 声明代理转发给服务器池, 注意这里访问用 https
proxy_pass https://192.168.1.2:60080;

}
}