OpenSSL 自建CA 以及颁发证书

操作环境

[root@localhost ssl]# cat /etc/os-release
NAME="openEuler"
VERSION="22.03 (LTS-SP1)"
ID="openEuler"
VERSION_ID="22.03"
PRETTY_NAME="openEuler 22.03 (LTS-SP1)"
ANSI_COLOR="0;31"
[root@localhost ssl]# pwd
/home/ssl
[root@localhost ssl]# ls
[root@localhost ssl]# openssl version
OpenSSL 1.1.1m  14 Dec 2021
[root@localhost ssl]#

CA私钥(ca.key)

openssl genrsa -des3 -out ca.key 2048

生成密钥对,该命令随即会提示您输入密钥保护密码,后续在生成、签发、验证证书时均需要此密码。请妥善相关密钥及密码。

如果使用 openssl genrsa -out rootCA.key 2048,即不使用参数 -des3 就可以生成无需密码管理的密钥对。
[root@localhost ssl]# openssl genrsa -des3 -out ca.key 2048
Generating RSA private key, 2048 bit long modulus (2 primes)
........................................................................................................................................................+++++
.............+++++
e is 65537 (0x010001)
Enter pass phrase for ca.key:`your password`
Verifying - Enter pass phrase for ca.key:`your password`
[root@localhost ssl]# more ca.key
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,584A614D3F6DDBEF

Y33THs+01q9vLDD2CjG/ocu3sygcZZv8/aE1FQ.....................
非必须

 

可以将ca.key转为pem文件,或者你在之前生成的时候就换成 .pem文件

openssl rsa -in ca.key -out ca-key.pem

 

 

CA自签名证书(ca.crt)

# 简化的命令
openssl req -x509 -key ca.key -sha256 -days 365 -out ca.crt


# 复杂的命令: openssl req -x509 -new -nodes -key ca.key -sha256 -days 3650 -out ca.pem
与之前的命令相比,这个命令增加了 -new 和 -nodes 选项:

- new: 在复杂的命令中,这个选项表示创建一个新的证书请求或证书。
       然而,在简化的命令中,由于 -x509 已经指示要生成一个新的自签名证书,所以 -new 实际上是隐含的,因此可以	   省略。
 
- nodes: 这个选项用于防止对私钥进行加密(我们之前的ca.key是需要输入密码的,使用了-des3参数)。
		 在复杂的命令中,增加这个参数来保证 省略加密 是为了方便在脚本或自动化环境中使用私钥。
		 然而,在这个复杂的命令中,如果 ca.key 私钥文件已经是没有加密的,或者您不介意在生成证书时手动输入密码			来解密私钥(尽管这通常不是生成自签名证书时的常见做法),那么 -nodes 也可以省略。
		 
- sha256 : 这个参数指定了用于签名证书的哈希算法。具体来说,加上 -sha256 参数会指示 OpenSSL 使用 SHA-256 算法对证书进行签名。
如果不加这个参数,OpenSSL 可能会使用默认的哈希算法,这个默认算法可能会根据 OpenSSL 的版本和配置而有所不同。

以文本形式输出查看ca证书

openssl x509 -in ca.crt -text -noout

以上用于查看和解析 X.509 证书的详细信息,并以文本格式输出,但不输出证书本身。下面是该命令各部分的解释:

  • x509: 这是 OpenSSL 中用于处理 X.509 证书的命令。X.509 是一种广泛使用的公钥证书标准,用于在公钥基础设施(PKI)中分发公钥。

  • in ca.crt: 指定输入文件,即要查看的 X.509 证书文件。在这个例子中,证书文件名为 ca.crt。

  • text: 指示 OpenSSL 以文本格式输出证书的详细信息。这包括证书的版本、序列号、签名算法、颁发者(Issuer)和主题(Subject)信息、公钥、扩展等。

  • noout: 阻止 OpenSSL 输出证书本身。由于使用了 -text 选项来查看证书的详细信息,因此 -noout 确保只输出这些详细信息,而不包括证书的 PEM 或 DER 编码表示。

该命令的作用是读取 ca.crt 文件中的 X.509 证书,并以文本格式输出其详细信息,但不包括证书本身的编码数据。 请注意,ca.crt 通常是一个包含 X.509 证书的文件,该文件可能以 .crt、.pem、.cer 或 .der 作为文件扩展名。在这个上下文中,.crt 扩展名仅表示该文件包含一个证书,而不涉及文件的编码格式(尽管 .crt 和 .pem 通常用于表示基于文本的 PEM 编码证书)。

Server端私钥(server.key)

openssl genrsa -out server.key 2048

使用CA证书(ca.crt)与密钥(ca.key)签署服务器的证书签名请求(server.csr)

openssl req -new  -key server.key -out server.csr

 

 

查看下这个 签名请求文件的内容

openssl req -text -noout -verify -in server.csr

 

 

证书签名请求(server.csr)

openssl x509 -req -sha256 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -days 3650 -out server.crt

Nginx配置SSL

server {
    #配置HTTPS的默认访问端口为443。
    #如果未在此处配置HTTPS的默认访问端口,可能会造成Nginx无法启动。
    #如果您使用Nginx 1.15.0及以上版本,请使用listen 443 ssl代替listen 443和ssl on。
    listen 443 ssl;

    #填写证书绑定的域名
    server_name localhost;

    #填写证书文件名称
    ssl_certificate      your server.crt;
    #填写证书私钥文件名称
    ssl_certificate_key  your server.key;


   ssl_session_timeout 5m;
    #表示使用的加密套件的类型
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
    #表示使用的TLS协议的类型,您需要自行评估是否配置TLSv1.1协议。
    ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;

    ssl_prefer_server_ciphers on;



    #access_log  /var/log/nginx/host.access.log  main;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

    #error_page  404              /404.html;
    
    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    # proxy the PHP scripts to Apache listening on 127.0.0.1:80
    #
    #location ~ \.php$ {
    #    proxy_pass   http://127.0.0.1;
    #}

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    #location ~ \.php$ {
    #    root           html;
    #    fastcgi_pass   127.0.0.1:9000;
    #    fastcgi_index  index.php;
    #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
    #    include        fastcgi_params;
    #}

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    #location ~ /\.ht {
    #    deny  all;
    #}
}

 

Nginx如果未开启SSL模块,配置Https时提示错误

报错:

nginx: [emerg] the “ssl” parameter requires ngx_http_ssl_module in /usr/local/nginx/conf/nginx.conf:37

原因很简单,nginx缺少http_ssl_module模块,编译安装的时候带上–with-http_ssl_module配置就行了,但是现在的情况是我的nginx已经安装过了,怎么添加模块,其实也很简单,往下看:

做个说明:我的nginx的安装目录是/usr/local/nginx这个目录,我的源码包在/root/nginx-1.26.2目录

Nginx开启SSL模块 切换到源码包:

cd /root/nginx-1.26.2

查看nginx原有的模块

/usr/local/nginx/sbin/nginx -V

在configure arguments:后面显示的原有的configure参数如下:

–prefix=/usr/local/nginx --with-http_stub_status_module

那么我们的新配置信息就应该这样写:

./configure --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module

运行上面的命令即可,等配置完

配置完成后,运行命令

make

这里不要进行make install,否则就是覆盖安装

然后备份原有已安装好的nginx

cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.bak

然后将刚刚编译好的nginx覆盖掉原有的nginx(这个时候nginx要停止状态)

cp ./objs/nginx /usr/local/nginx/sbin/

然后启动nginx,仍可以通过命令查看是否已经加入成功

/usr/local/nginx/sbin/nginx -V

 

升级https后解决http资源文件访问被阻止

以 https 访问网站时页面内容显示异常,打开浏览器控制台可以发现大量的报错信息。

Mixed Content: The page at 'https://example.com' was loaded over HTTPS, but requested an insecure stylesheet 'http://example.com/static/css/example.css'. This request has been blocked; the content must be served over HTTPS.

解决方法

方法一:在源代码中查找混合内容

您可以在源代码中直接搜索混合内容。在源代码中搜索 http 开头的资源链接文件,将其替换为 https 。

方法二:使用 “upgrade-insecure-requests” CSP 指令强制浏览器以https方式访问http资源,此方法有两种方法添加CSP指令。

1、通过在网页 head 中添加标签

<html>
<head>
...
<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">
</head>
...

2、通过 在请求响应中插入响应头信息: “Content-Security-Policy: upgrade-insecure-requests”

如 Nginx 配置中配置如下修改即可:

server {
  ...
  location / {
      ...
      add_header Content-Security-Policy upgrade-insecure-requests;
      ...
  }
}
}

 

通过以上修改即可解决混合内容被浏览器阻止而导致页面显示异常的问题。

升级https后解决http接口访问被阻止

通过location /api/添加反向代理。

server {
	listen       8443 ssl;
	server_name  localhost;

	ssl_certificate      your server.crt;
	ssl_certificate_key  your server.key;

	ssl_session_cache    shared:SSL:1m;
	ssl_session_timeout  5m;

	ssl_ciphers  HIGH:!aNULL:!MD5;
	ssl_prefer_server_ciphers  on;

	location / {
		root   html/dist;
		index  index.html index.htm;
		try_files $uri $uri/ /index.html;
	#    add_header Content-Security-Policy "upgrade-insecure-requests" always;
	}
	location /api/ {
		# default_type  application/json;
		# internal;
		# keepalive_timeout   30s;
		# keepalive_requests  1000;
		# 支持keep-alive
		# proxy_http_version 1.1;
		rewrite /api(/.*) $1 break;
		proxy_pass_request_headers on;
		# more_clear_input_headers Accept-Encoding;
		proxy_next_upstream error timeout;
		proxy_set_header Host $host;
		proxy_set_header X-Real-IP $remote_addr;
		proxy_set_header REMOTE-HOST $remote_addr;
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
		proxy_pass http://localhost:9660/;
	}
}

 

阅读剩余
THE END