felix-cao / Blog

A little progress a day makes you a big success!
31 stars 4 forks source link

基于 OpenSSL 生成自签名 SSL 证书并使用 Nginx 配置 https 服务 #225

Open felix-cao opened 3 months ago

felix-cao commented 3 months ago

SSL: Secure Sockets Layer certificate, 安全套接字协议, SSL 证书是数字证书的一种.

CA: Certificate Authority, 数字证书颁发机构.

nginx 使用 https 协议需要配置证书,通过 CA 机构获取的证书是收费的,出于研究测试的话可以通过 openssl 自己制作证书,使用 openssl 制作证书如下:

(1) 生成CA根证书 (2) 生成服务器证书请求 (3) 通过 CA 根证书和服务器证书请求生成服务器证书 服务器证书生成后,便可以在 nginx 进行配置

1. 利用 OpenSSL 生成 CA 根证书

OpenSSL 是一个用于生成密钥、公钥,证书,以及进行证书签名的工具。

CA 要给别人颁发证书,首先自己得有一个作为根证书,我们得在一切工作之前修改好 CA 的配置文件、序列号、索引等等。

1.1 配置

使用 openssl 之前,需要对其进行配置,设置好证书的存放目录,序列 ID 的存放位置。基本默认的是遏制都已经做好了,只需要更改一下 dir 的值即可。

CentOS 7 中有个 openssl 的示例文件: /etc/pki/tls/openssl.cnf

sudo cp /etc/pki/tls/openssl.cnf /etc/ssl/openssl.cnf

然后,根据 openssl.cnf[ CA_default ] 描述的文件结构,创建对应的文件目录和文件

# mkdir -pv /etc/pki/CA/{certs,crl,newcerts,private}
# touch /etc/pki/CA/{serial,index.txt}

文件说明:

# tree /etc/pki
/etc/pki
├── CA
│   ├── certs          (已颁发的证书保存目录)
│   ├── crl              (证书撤销列表存放目录)
│   ├── index.txt     (数据库索引文件,记录着一些已签署的证书信息)
│   ├── newcerts    (新签署证书的保存目录)
│   ├── private        (存放CA私钥的目录)
│   └── serial        (当前证书序列号)

1.2 指定证书编号

根证书是用来生成服务器证书的,证书之间是存在链式关系,当信任根证书时,由其衍生出来的证书都会被信任。

从根证书开始每一个证书都有一个对应的编号,是通过serial的值来进行维护的,首先指明证书的开始编号

# echo 01 >> /etc/pki/CA/serial

1.3 生成 CA 私钥

使用 umask 077 使得之后生成文件的默认权限为 077,使用 openssl 工具生成 4096 位的 rsa 秘钥,该秘钥存放在 /etc/pki/CA/private/cakey.pem

# umask 077; openssl genrsa -out /etc/pki/CA/private/cakey.pem 4096

1.4 生成 CA 证书

使用刚生成的私钥生成 CA 证书,CA 证书保存在 /etc/pki/CA/cacert.pem

# openssl req -new -x509 -key /etc/pki/CA/private/cakey.pem \
  -subj /C=CN/ST=Anhui/L=Hefei/O=Futuremove/OU=GA/CN=GA \
  -out /etc/pki/CA/cacert.pem -days 36500

2. 生成 Server 端证书

2.1 生成 Server 端私钥 (*.pem)

首先我创建并进入了 ~/portainer 目录,然后生成服务端的私钥

# cd /opt/portainer
# openssl genrsa -out https.pem 4096

2.2 生成 Server 端证书请求 (*.csr)

# openssl req -new -key https.pem \
  -subj "/C=CN/ST=Anhui/L=Hefei/O=Futuremove/CN=portainer.56512.com/emailAddress=czf2008700@163.com" \
  -days 36500 -out https.csr 

这里使用 -subj 可以预先完成证书请求者信息的填写,但要注意,填入的信息中 CSTL 一定要与签署的根证书一样,如果忘记了根证书乱填了什么,可以通过如下指令进行查询:

# openssl x509 -in 根证书的路径+名字 -noout -subject
# openssl x509 -in /etc/pki/CA/cacert.pem -noout -subject
subject= /C=CN/ST=Anhui/L=Hefei/O=Futuremove/OU=GA/CN=GA

2.3 生成 Server 端证书 (*.cert)

执行以下命令之后就能得到证书文件 https.cert,这就是用于发送给客户端的证书。

# openssl ca -in https.csr -out https.crt -days 36500

image

3. Nginx 配置 https

server {
    listen 80;
    server_name portainer.56512.com;
    rewrite ^(.*)$ https://${server_name}$1 permanent;
}

server {

  # 监听443端口,处理所有HTTPS请求
  listen 443 ssl;

  server_name portal.56512.com;

  # SSL配置 
  ssl_certificate /opt/portainer/https.crt;
  ssl_certificate_key /opt/portainer/https.pem;
  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
  ssl_ciphers HIGH:!aNULL:!MD5;

  # 代理配置,将HTTPS请求代理到另一个HTTPS服务器
  location / {
      client_max_body_size 1024m;
      proxy_redirect off;
      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr; # 获取用户的真实IP
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_pass http://portainer/;
      index index.html index.htm;
  }
}