CentOS搭建基于Apache与OpenSSL自签名证书的HTTPS服务并解决客户端浏览器信任问题
CentOS基本配置略……
除了正文的正事之外还有几个重要的小问题:
1、可能需要配置iptables,详细的不讲了,一个小例子
iptables -I INPUT -p tcp --dport 443 -j ACCEPT
2、可能需要CentOS的selinux配置 ,放开某一端口
semanage port -l |grep http # 查看哪些端口可用
senamage 端口 增加 类型 [] 协议 TCP/UDP 端口
semanage port -a -t http_port_t -p tcp 801
senamage 端口 修改 类型 [] 协议 TCP/UDP 端口
semanage port -m -t http_port_t -p tcp 801
senamage 端口 删除 类型 [] 协议 TCP/UDP 端口
semanage port -d -t http_port_t -p tcp 801
正文开始
Apache服务器安装
首先安装Apache服务器在CentOS上:
yum install httpd
对应的配置文件
cat /etc/httpd/conf/httpd.conf
详细的配置过程记不太清了,下面是配置文件记得修改了的部分
...
ServerRoot "/etc/httpd"
#
# Listen: Allows you to bind Apache to specific IP addresses and/or
# ports, instead of the default. See also the <VirtualHost>
# directive.
#
# Change this to Listen on specific IP addresses as shown below to
# prevent Apache from glomming onto all bound IP addresses.
#
#Listen 12.34.56.78:80
Listen 7070 # 这里可以自行指定,需要到对应的端口上放开外部的访问即可
...
#
# ServerName gives the name and port that the server uses to identify itself.
# This can often be determined automatically, but we recommend you specify
# it explicitly to prevent problems during startup.
#
# If your host doesn't have a registered DNS name, enter its IP address here.
#
ServerName www.healer.com # 这个域名也是自己指定一下,在hosts文件中要加上
#
# Deny access to the entirety of your server's filesystem. You must
# explicitly permit access to web content directories in other
# <Directory> blocks below.
#
<Directory />
AllowOverride none
#Require all denied
Require all granted # 一开始可能会有外部的终端无法访问的情况,这条命令配置权限
</Directory>
...
IncludeOptional conf.d/*.conf # 这里指明了其他的一些配置文件在哪里
安装bind和mod_ssl(一般bind应该是有的):
yum install bind
yum install mod_ssl
一般安装好之后就能够找到ssl的配置文件,我的CentOS在“/etc/httpd/conf.d/ssl.conf”,配置文件如下(部分修改的地方):
[root@localhost anchors]# cat /etc/httpd/conf.d/ssl.conf
Listen 443 https # 监听端口也可以重新指定
SSLPassPhraseDialog exec:/usr/libexec/httpd-ssl-pass-dialog
SSLSessionCache shmcb:/run/httpd/sslcache(512000)
SSLSessionCacheTimeout 300
SSLRandomSeed startup file:/dev/urandom 256
SSLRandomSeed connect builtin
#SSLRandomSeed startup file:/dev/random 512
#SSLRandomSeed connect file:/dev/random 512
#SSLRandomSeed connect file:/dev/urandom 512
SSLCryptoDevice builtin
#SSLCryptoDevice ubsec
<VirtualHost _default_:443>
# General setup for the virtual host, inherited from global configuration
DocumentRoot "/var/www/html"
ServerName www.healer.com:443 # 这里应该是需要重新改一下的,一开始的用不了
# Use separate log files for the SSL virtual host; note that LogLevel
# is not inherited from httpd.conf.
ErrorLog logs/ssl_error_log
TransferLog logs/ssl_access_log
LogLevel warn
# SSL Engine Switch:
# Enable/Disable SSL for this virtual host.
SSLEngine on
SSLProtocol all -SSLv2 -SSLv3
SSLCipherSuite HIGH:3DES:!aNULL:!MD5:!SEED:!IDEA
#SSLCipherSuite RC4-SHA:AES128-SHA:HIGH:MEDIUM:!aNULL:!MD5
SSLHonorCipherOrder on
SSLCertificateFile /etc/httpd/mycerts/server.crt # 这里是比较关键的部分,这里需要有自己的SSL证书文件,参见后面的OpenSSL生成在签名证书
SSLCertificateKeyFile /etc/httpd/mycerts/server.key # 这里需要指定SSL证书对应的私钥,这个只有在服务器上有
#SSLCertificateChainFile /etc/pki/tls/certs/server-chain.crt # 这里原本是要配置的,但是自己生成的证书啥的,也没有信任链啥的就注释掉了
#SSLCACertificateFile /etc/pki/tls/certs/ca-bundle.crt
#SSLVerifyClient require
#SSLVerifyDepth 10
#SSLOptions +FakeBasicAuth +ExportCertData +StrictRequire
<Files ~ "\.(cgi|shtml|phtml|php3?)$">
SSLOptions +StdEnvVars
</Files>
<Directory "/var/www/cgi-bin">
SSLOptions +StdEnvVars
</Directory>
BrowserMatch "MSIE [2-5]" \
nokeepalive ssl-unclean-shutdown \
downgrade-1.0 force-response-1.0
CustomLog logs/ssl_request_log \
"%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
</VirtualHost>
我的配置好之后还报出来了一个关于mod_foo.so的,这个应该是在httpd.conf配置文件中,尝试解决添加模块未果后,注释掉也不影响啥(只是测试服务器,没有PHP相关的业务需求,记得这个mod_foo.so是和PHP解析有关的)
OpenSSL搭建CA服务器并签发服务器证书和秘钥
为了搭建这个测试环境,也没有必要去互联网上注册一个域名,买个证书啥的,于是选择使用OpenSSL生成自签名的证书作为Apache的证书配置文件
过程参照大佬文章
先整理一下思路,要有这个服务器的证书文件,首先有一个CA然,后大致流程如下:
一、修改配置文件(视情况而定),创建index.txt、serial文件
二、生成CA根证书
1.创建根证书私钥
2.使用根证书私钥创建一个自签根证书的申请
3.使用申请和私钥签发根证书
三、生成自签证书
1.创建自签证书私钥
2.创建一个自签证书申请
3.使用自签的根证书对自签证书申请进行签署
一、修改配置文件(视情况而定),创建index.txt、serial文件
建议:先检查一下OpenSSL的配置文件,不同操作系统弄位置不一样,我的是Kali2021比较新一点的版本:
/usr/lib/ssl/openssl.cnf
kali默认的配置文件:
...
####################################################################
[ ca ]
default_ca = CA_default # The default ca section
####################################################################
[ CA_default ]
dir = /etc/pki/CA # Where everything is kept
certs = $dir/certs # Where the issued certs are kept
crl_dir = $dir/crl # Where the issued crl are kept
database = $dir/index.txt # database index file.
#unique_subject = no # Set to 'no' to allow creation of
# several certs with same subject.
new_certs_dir = $dir/newcerts # default place for new certs.
certificate = $dir/cacert.pem # The CA certificate
serial = $dir/serial # The current serial number
crlnumber = $dir/crlnumber # the current crl number
# must be commented out to leave a V1 CRL
crl = $dir/crl.pem # The current CRL
private_key = $dir/private/cakey.pem# The private key
x509_extensions = usr_cert # The extensions to add to the cert
# Comment out the following two lines for the "traditional"
# (and highly broken) format.
name_opt = ca_default # Subject Name options
cert_opt = ca_default # Certificate field options
...
[ v3_req ]
# Extensions to add to a certificate request
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
## edit by myself begin
subjectAltname = @alt_names
[alt_names]
DNS.1 = www.healer.com
## edit by myself end
...
备注:看上面的配置文件主要的目的就是确认一下使用OpenSSL的相关的一些文件在什么位置,有没有对应的文件,哪些需要创建,哪些需要命名成特定的名字,有的可能默认就没有CA这个目录,我这个就是,所以还是需要手动创建一些东西,再到指定的目录中去生成证书
从配置文件可以看到,存放颁发证书的数据库文件index.txt和证书颁发的编号serial两个文件是必须要手动创建的。从配置文件里看到,默认公共目录是/etc/pki/CA(这个可以自己配置,我的kali默认就不是这个,很可能到后期会报错)
touch index.txt
echo 00 > serial
二、生成CA根证书 (切记下面的步骤不一定顺利,配合OpenSSL配置,才能完整生成)
由于Chrome和Firefox的检查机制不太一样,Chrome更加严格一些,在验证的过程中会检查SAN项(CA证书扩展项),大概是服务器的别名 ,踩了很多坑,最终摸索出来的方法
下面的配置过程,请有需要SAN扩展项的同学,配置到对应步骤的时候自行使用带SAN扩展项的命令,并且要记得在openssl.cnf文件中的指定位置配置相应的参数,详细方法参见openssl.cnf配置更改详情
1、创建根证书私钥
openssl genrsa -out private/cakey.pem 2048
这里我觉得应该是命名cakey.key,因为这个.pem文件一般是证书用,其实也不影响,主要是为了和上面的配置文件对应,Linux下后缀啥的影响不大
2、使用生成的根私钥创建一个根申请证书(.csr格式)
openssl req -new -key private/cakey.pem -out caroot.csr
3、使用根证书私钥签发申请证书
openssl x509 -req -days 36500 -in caroot.csr -signkey private/cakey.pem -out caroot.crt
增加SAN扩展项的命令:(下面的过程同样按照这个有SAN扩展项的方法)
openssl x509 -req -days 36500 -in caroot.csr -signkey private/cakey.pem -extensions v3_req -out caroot.crt
到这里就算是生成了CA服务器的根证书和私钥,下一步就是要以这个caroot.crt根证书,签发Apache服务器的SSL证书,建议下做一做功课补一下这些证书、私钥、证书请求文件相关的基础知识。(上面的cakey.pem和cakey.key感觉这里应该叫后者更合理,但我的配置文件是cakey.pem,我就按照我的配置文件来了,也可以去改配置文件。这些主要是为了避免最后一步使用根证书签发服务器证书的时候报错,有些文件找不到的情况)
三、生成自签证书
1、创建自签证书的私钥
openssl genrsa -out server.key 2048
2、创建自签证书申请(.csr格式)
openssl req -new -key server.key -out server.csr
增加SAN扩展项的命令:
openssl req -new -key server.key -reqexts SAN -config <(cat /usr/lib/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:www.healer.com")) -out server.csr
3、使用根证书和私钥签发server申请证书
openssl ca -in server.csr -cert caroot.crt -keyfile private/cakey.pem -out server.crt -days 36500
增加SAN扩展项的命令:
openssl ca -in server.csr -keyfile private/cakey.pem -cert caroot.crt -extensions SAN -config <(cat /usr/lib/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:www.healer.com")) -out server.crt
4、验证自签SSL证书是否ok
root@healer:/etc/pki/CA# openssl verify -verbose -CAfile caroot.crt server.crt
server.crt: OK
看到上面的结果基本上就算是生成成功了
备注:生成过程中的遇到某某文件找不到,某某文件无法打开等问题,建议从头开始,好好检查一下CA的配置文件,不一样的平台的位置不一样,配置也不太一样,网上的一个教程只适合一部分情况,最好还是先了解整体是什么结构怎么生成配置对应的文件,以及关键配置的含义,再行动,基本都可以解决。
将上面过程中生成的server.crt以及server.key文件配置到Apache服务器对应的位置上即可,并将caroot.crt根证书文件导入目标操作系统即可
主机hosts文件修改
还要修改主机的hosts文件,因为自己搭建的服务器,也没有往公网上挂,自然也不会有DNS服务器能够解析自己的域名
如Windows下:
Linux下的配置hosts文件,略……
操作系统OpenSSL自签名证书证书导入及添加信任
导入浏览器之后效果,CentOS的Firefox和Windows7下大Chrome检测成功为可信的证书,SSL配置成功
理论上实现上面这两张图的效果就OK了
证书导入可能遇到的问题
证书导入主机操作系统(浏览器访问的终端),Windows和Linux一样,导入系统并且添加信任之后,浏览器在浏览网页的时候会自己到系统里面找到相应的证书文件
CentOS7证书导入方法
/etc/pki/ca-trust/source/anchors # 证书存放位置,将自建证书导入此处
update-ca-trust # 执行命令更新证书
Windows导入证书方法
将自签名的证书导入Windows系统之前:
导入之前由CA服务器的根证书(server.crt是caroot.crt的自签名证书):
将CA服务器的根证书导入“受信任的根证书颁发机构”(不要导错位置了)
这时候使用Chrome就会暴露出来上面的没有配置SAN扩展项的问题:
针对上一问题的解决方式:(编辑一下OpenSSL的配置文件,加上对应的内容即可)
最终,Chrome上能够正常看到最开始的效果图就算是证书生成完成,切记Chrome浏览器下一定要配置SAN扩展选项