技术帝的平台展示,网站建设、网站推广、SEO技术、网站优化、电子商务推广、平面美工和软件测试等技术干货分享。

使用bash脚本一键生成自签名SSL证书(CA+服务端+客户端),实现反向代理和源服务器双向认证

服务器 abel-lan 24℃ 0评论

在另一篇关于配置Apache反向代理的文章中,介绍了通过https + IP + 端口转发到源服务器,当时是通过关闭后端服务器https证书验证实现的,这样不安全也不规范。本文就来介绍如何使用openssl命令制作自签名证书,使用bash脚本一键生成自签名SSL证书(CA+服务端+客户端),运行脚本即可生成,无需繁琐的配置和一步步的操作;并详细介绍如何配置源服务器服务器自签名证书,配置反向代理和源服务器的双向认证。

使用openssl命令制作自签名证书

查找openssl命令

Linux 使用命令 find / -name openssl 查找 openssl 命令位置,如果Linux系统自身安装了,会找到 /usr/bin/openssl,我们可以直接使用openssl命令;若系统没有装openssl,但是Apache安装了openssl模块,可以找到 /opt/lampp/bin/openssl,我们可以使用apache的openssl生成证书。

Windows 安装Apache的,可在Apache/bin目录下找到openssl.exe,也是可以使用openssl生成证书的。

生成CA根证书 + 服务端证书(源服务器) + 客户端证书(反向代理服务器)

生成证书的配置文件和bash脚本已打包,可直接下载运行gen.sh。下载地址:生成证书的配置文件和bash脚本
下载解压后在新建文件夹中执行命令 ./gen.sh 或者 bash gen.sh。使用该脚本前需要确认有 openssl 命令。该脚本会生成一张 CA 自签发证书,然后使用该CA证书签发一张服务端证书(通用的PKCS#8格式)、一张客户端证书(PKCS#1格式用于反向代理服务器Apache)和另一张客户端证书(通用的PKCS#8格式)。
对生成证书命令感兴趣的朋友,和windows环境生成证书的,请看本文后半段生成CA根证书 + 服务端证书(源服务器) + 客户端证书(反向代理服务器)的详细介绍和实现方法

证书签发bash
证书签发bash

配置apache ssl证书

服务器端(即网站源服务器)配置ssl证书(含根证书)

  1. 修改 httpd-confListen 80 后加上 Listen 8001
  2. 修改 httpd-ssl.conf
<VirtualHost _default_:8001>
    ServerName 115.155.2.10

    #此处省略其他配置,请自己添加

    SSLEngine on
    SSLCertificateFile "/opt/lampp/etc/ssl.crt/server.pem"  #server公钥证书
    SSLCertificateKeyFile "/opt/lampp/etc/ssl.key/server.key"  #server私钥文件

    SSLVerifyClient require  #开启客户端证书验证 
    SSLCACertificateFile "/opt/lampp/etc/ssl.crt/ca.pem"  #根证书,可以验证所有它颁发的客户端证书
</VirtualHost>

代理服务器(即客户端)配置

修改 httpd-ssl.conf ,参考设置如下

<VirtualHost _default_:443>
    ServerName www.bluepost.cn
    ServerAlias bluepost.cn

    SSLEngine on
    SSLCertificateFile "conf/ssl.crt/bluepost.cn_public.crt"
    SSLCertificateKeyFile  "conf/ssl.key/bluepost.cn.key"
    SSLCertificateChainFile "conf/ssl.crt/bluepost.cn_chain.crt"

    SSLProxyEngine on
    SSLProxyCACertificateFile "conf/ssl.crt/ca.pem"  #自签名根证书,用于验证所有它颁发的自签名服务端和客户端证书
    SSLProxyMachineCertificateFile "conf/ssl.crt/client_key_crt.pem" #开启客户端证书验证时需要


    #设置代理通过IP和端口
    ProxyPreserveHost on  #打开host域名请求地址,如果使用代理,获取的请求地址是对外域名,如果off关闭,则获取的是ip地址请求
    ProxyPass / https://115.155.2.10:8001/  #将IP地址改为国外服务器的IP
    ProxyPassReverse / https://115.155.2.10:8001/
</VirtualHost>

浏览器访问自签名网站

直接用浏览器访问 https://115.155.2.10:8001/ ,会报错 此网站出具的安全证书不是由受信任的证书颁发机构颁发的。 这时我们需要将生成的 ca.pem 证书导入到【受信任的根证书颁发机构】,如果开启了客户端证书验证,还需要将 proxy_client.p12 证书文件导入到 【个人】->【证书】中。

遇到的问题1 – 自签名证书报错ERR_CERT_COMMON_NAME_INVALID

使用自签名的证书后,chrome报错此服务器无法证实它就是 115.155.2.10 它的安全证书没有指定主题备用名称。这可能是因为某项配置有误或某个攻击者拦截了您的连接。
错误码是 NET::ERR_CERT_COMMON_NAME_INVALID:

问题原因

生成证书的时候没有加上备用名称字段,目前的浏览器校验证书都需要这个字段。

解决方法

生成证书的时候需要添加上备用名称(subjectAltName)扩展字段。使用 openssl 生成crt证书时,需要配置 subjectAltName 参数,详细介绍见修改配置文件server-openssl.cnf文件 alt_names

遇到的问题2 – 配置反向代理后,访问网站报错Reason: Error during SSL Handshake with remote server

浏览器直接通过端口访问正常,但是通过域名访问报错如下:

Proxy Error
The proxy server could not handle the request
Reason: Error during SSL Handshake with remote server

Additionally, a 500 Internal Server Error error was encountered while trying to use an ErrorDocument to handle the request.

解决方法

请检查生成源服务器证书时,有没有将域名和IP都加入备用名称(subjectAltName)扩展字段中,修改方法见修改配置文件server-openssl.cnf文件 alt_names

生成CA根证书 + 服务端证书(源服务器) + 客户端证书(反向代理服务器)的详细介绍和实现方法

生成CA根证书

创建ca-openssl.cnf文件

[req]
distinguished_name  = req_distinguished_name
req_extensions = v3_req

[req_distinguished_name]
countryName           = Country Name (2 letter code)
countryName_default = CN
stateOrProvinceName   = State or Province Name (full name)
stateOrProvinceName_default = Some-State
organizationName          = Organization Name (eg, company)
organizationName_default = Internet Widgits Pty Ltd
commonName            = Common Name (eg, YOUR name)
commonName_default = AbelCA

[v3_req]
basicConstraints = CA:true
keyUsage = critical, keyCertSign

生成CA根证书

openssl req -x509 -new -newkey rsa:2048 -nodes -keyout ca.key -out ca.pem -config ca-openssl.cnf -days 3650 -extensions v3_req

生成服务端证书(源服务器)

创建server-openssl.cnf文件

[req]
distinguished_name  = req_distinguished_name
req_extensions     = v3_req

[req_distinguished_name]
countryName           = Country Name (2 letter code)
countryName_default   = CN
stateOrProvinceName   = State or Province Name (full name)
stateOrProvinceName_default = Shanghai
localityName          = Locality Name (eg, city)
localityName_default  = Shanghai
organizationName          = Organization Name (eg, company)
organizationName_default  = Example, Co.
commonName            = Common Name (eg, YOUR name)
commonName_max        = 64

####################################################################
[ ca ]
default_ca  = CA_default        # The default ca section

####################################################################
[ CA_default ]

dir     = . # Where everything is kept
certs       = $dir # Where the issued certs are kept
crl_dir     = $dir      # Where the issued crl are kept
database    = $dir/index.txt    # database index file.
new_certs_dir   = $dir      # default place for new certs.
certificate = $dir/ca.pem   # The CA certificate
serial      = $dir/serial       # The current serial number
crlnumber   = $dir/crlnumber    # the current crl number
crl     = $dir/crl.pem      # The current CRL
private_key = $dir/private/cakey.pem# The private key
RANDFILE    = $dir/private/.rand    # private random number file

[v3_req]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names

[alt_names]
DNS.1 = bluepost.cn
DNS.2 = *.bluepost.cn
IP.1 = 115.155.2.10

记得修改上述配置文件中的 alt_names ,将域名和IP改为自己的域名和IP,如果多个域名,可以按DNS.1/DNS.2/…来添加,同时还支持IP地址的形式,填入IP.1 = x.x.x.x就可以了。
一定要将需要签名的域名都加入,通过IP访问的需要将服务器公网IP和域名加上,否则会报错安全证书没有指定主题备用名称

生成服务端证书

# 创建服务端私钥
openssl genrsa -out server.key.rsa 2048
# 将私钥转换成更通用的 pkcs#8 格式
openssl pkcs8 -topk8 -in server.key.rsa -out server.key -nocrypt
# 根据私钥生成请求文件
openssl req -new -key server.key -out server.csr -config server-openssl.cnf
# 结合私钥和请求文件创建服务端证书,有效期10年
openssl x509 -req -CA ca.pem -CAkey ca.key -CAcreateserial -in server.csr -out server.pem -extensions v3_req -extfile server-openssl.cnf -days 3650

生成客户端证书(反向代理服务器)

反向代理服务器httpd-ssl.cnf需要配置SSLProxyMachineCertificateFile

# 创建客户端私钥
openssl genrsa -out proxy_client.key 2048
# 根据私钥生成请求文件
openssl req -new -key proxy_client.key -out proxy_client.csr
# 结合私钥和请求文件创建服务端证书,有效期10年
openssl x509 -req -CA ca.pem -CAkey ca.key -CAcreateserial -in proxy_client.csr -out proxy_client.pem -days 3650
# 将私钥和对应的证书链合成 PKCS#12 格式,KeyStore 密码和私钥密码均为 123456
openssl pkcs12 -export -CAfile ca.pem -in proxy_client.pem  -inkey proxy_client.key -out proxy_client.p12 -passout pass:123456
# 把客户端证书和密钥合成一个文件,用于 **反向代理服务器作为客户端证书配置** 
# 注意秘钥必需是pkcs1格式,如果不是,需要用命令 openssl rsa -in private-pkcs8.key -outform private.key
cat proxy_client.key proxy_client.pem > client_key_crt.pem

转载请注明:半亩方塘 » 使用bash脚本一键生成自签名SSL证书(CA+服务端+客户端),实现反向代理和源服务器双向认证

赞 (5)支付宝扫码打赏微信扫码打赏分享
发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址