在前面一节介绍了如何创建CA, 以及如何用CA对CSR 证书请求文件进行签名,从而生成签名的服务器端证书。生成签名证书不是我们的最终目的,利用生成的签名证书来加密通信才是我们要达到的目的;这里跟我一起来学习如何使用这个签名的证书来搭建最简单的https网站:
- 安装httpd包以及mod_ssl包,默认情况下,apache允许http以及https连接,通过curl的方式验证http网站是可以访问的.
然而访问https的时候,可以看到加密的 https://127.0.0.1 在默认情况下是无法访问的;报告“curl: (60) Issuer certificate is invalid.”错误,这是因为还没有可用证书的原因.
[root@localhost conf.d]# lsof -i:443
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
httpd 4761 root 6u IPv6 45014 0t0 TCP *:https (LISTEN)
httpd 4762 apache 6u IPv6 45014 0t0 TCP *:https (LISTEN)
httpd 4763 apache 6u IPv6 45014 0t0 TCP *:https (LISTEN)
httpd 4764 apache 6u IPv6 45014 0t0 TCP *:https (LISTEN)
httpd 4765 apache 6u IPv6 45014 0t0 TCP *:https (LISTEN)
httpd 4766 apache 6u IPv6 45014 0t0 TCP *:https (LISTEN)
[root@localhost conf.d]# lsof -i:80
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
httpd 4761 root 4u IPv6 45006 0t0 TCP *:http (LISTEN)
httpd 4762 apache 4u IPv6 45006 0t0 TCP *:http (LISTEN)
httpd 4763 apache 4u IPv6 45006 0t0 TCP *:http (LISTEN)
httpd 4764 apache 4u IPv6 45006 0t0 TCP *:http (LISTEN)
httpd 4765 apache 4u IPv6 45006 0t0 TCP *:http (LISTEN)
httpd 4766 apache 4u IPv6 45006 0t0 TCP *:http (LISTEN)
[root@localhost conf.d]# curl -I https://127.0.0.1/
curl: (60) Issuer certificate is invalid.
More details here: http://curl.haxx.se/docs/sslcerts.html
curl performs SSL certificate verification by default, using a "bundle"
of Certificate Authority (CA) public keys (CA certs). If the default
bundle file isn't adequate, you can specify an alternate file
using the --cacert option.
If this HTTPS server uses a certificate signed by a CA represented in
the bundle, the certificate verification probably failed due to a
problem with the certificate (it might be expired, or the name might
not match the domain name in the URL).
If you'd like to turn off curl's verification of the certificate, use
the -k (or --insecure) option.
[root@localhost conf.d]# curl -I http://127.0.0.1/
HTTP/1.1 403 Forbidden
Date: Tue, 17 Sep 2019 10:58:14 GMT
Server: Apache/2.4.6 (CentOS) OpenSSL/1.0.2k-fips
Last-Modified: Thu, 16 Oct 2014 13:20:58 GMT
ETag: "1321-5058a1e728280"
Accept-Ranges: bytes
Content-Length: 4897
Content-Type: text/html; charset=UTF-8
[root@localhost conf.d]#
- 在配置https之前,查看我们之前生成的签名证书以及私钥,我们需要这些信息来配置https加密.
[root@localhost cert_test]# ls -l
total 24
-rw-------. 1 root root 1359 Aug 18 21:31 CA_Cert.pem #CA证书
-rw-------. 1 root root 1675 Aug 18 21:20 CA_Key.key #CA的私钥
-rw-r--r--. 1 root root 1021 Aug 18 17:23 my_cert.csr #服务端证书请求文件
-rw-------. 1 root root 4509 Aug 18 22:12 my.crt #由CA签名之后的服务端证书
-rw-r--r--. 1 root root 1679 Aug 18 17:18 myprivate.key #服务端证书的私钥
[root@localhost cert_test]#
- 切换到httpd的配置目录,然后找到conf.d/ssl.conf文件,查看SSLCertificateFile, SSLCertificateKeyFile 参数的值, 并按照如下的值进行修改,然后把签名的服务器证书以及私钥放置到相应的路径下:
[root@localhost conf.d]# grep SSLCertificate ssl.conf | grep -Evi ^#
SSLCertificateFile /etc/pki/tls/certs/localhost.crt
SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
#修改上述参数的值,修改后如下:
[root@localhost conf.d]# grep SSLCertificate ssl.conf | grep -Evi ^#
SSLCertificateFile /etc/httpd/conf.d/my.crt
SSLCertificateKeyFile /etc/httpd/conf.d/myprivate.key
[root@localhost cert_test]# ls -l /etc/httpd/conf.d/myprivate.key /etc/httpd/conf.d/my.crt
-rw-r-----. 1 root root 4509 Aug 18 22:12 /etc/httpd/conf.d/my.crt
-rw-r-----. 1 root root 1679 Sep 17 21:50 /etc/httpd/conf.d/myprivate.key
[root@localhost cert_test]#
- 除了要提供服务器签名证书的路径外,通常需要提供 "证书链证书" 的路径,在这里,我们不需要提供"证书链证书" 的路径,因为我们是直接用CA签名的服务器证书;所以除了“服务器签名证书”外,只需要提供CA证书的路径,而不必提供“证书链证书”的信息:
[root@localhost conf.d]# grep SSLCACe ssl.conf
#SSLCACertificateFile /etc/pki/tls/certs/ca-bundle.crt
#修改上述参数的值,修改之后如下:
[root@localhost conf.d]# grep SSLCACe ssl.conf
SSLCACertificateFile /etc/httpd/conf.d/CA_Cert.pem
[root@localhost conf.d]# cp /root/cert_test/CA_Cert.pem /etc/httpd/conf.d/CA_Cert.pem
[root@localhost conf.d]# ls -l /etc/httpd/conf.d/CA_Cert.pem
-rw-r-----. 1 root root 1359 Sep 17 21:52 /etc/httpd/conf.d/CA_Cert.pem
[root@localhost conf.d]#
- 至此,https服务器的证书已经配置完成了,接下来重启httpd服务,遇到了如下的错误:
Sep 17 22:01:03 localhost.localdomain httpd[30975]: AH00526: Syntax error on line 100 of /etc/httpd/conf.d/ssl.conf:
Sep 17 22:01:03 localhost.localdomain httpd[30975]: SSLCertificateFile: file '/etc/httpd/conf.d/my.crt' does not exist or is empty
Sep 17 22:01:03 localhost.localdomain systemd[1]: httpd.service: main process exited, code=exited, status=1/FAILURE
Sep 17 22:01:03 localhost.localdomain kill[30977]: kill: cannot find process ""
Sep 17 22:01:03 localhost.localdomain systemd[1]: httpd.service: control process exited, code=exited status=1
Sep 17 22:01:03 localhost.localdomain systemd[1]: Failed to start The Apache HTTP Server.
-- Subject: Unit httpd.service has failed
-- Defined-By: systemd
-- Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
--
-- Unit httpd.service has failed.
经过检查,文件是存在的, 在centos中,默认情况下,selinux是打开的,所以关闭试试,果然重启成功:
[root@localhost cert_test]# setenforce 0
[root@localhost cert_test]# systemctl restart httpd.service
[root@localhost cert_test]#
- 至此,重启完成,用curl命令进行验证, 结果如下,提示证书是不受信任的;我们用-k参数跳过证书验证;
[root@localhost cert_test]# curl -I https://127.0.0.1/
curl: (60) Peer's certificate issuer has been marked as not trusted by the user.
More details here: http://curl.haxx.se/docs/sslcerts.html
curl performs SSL certificate verification by default, using a "bundle"
of Certificate Authority (CA) public keys (CA certs). If the default
bundle file isn't adequate, you can specify an alternate file
using the --cacert option.
If this HTTPS server uses a certificate signed by a CA represented in
the bundle, the certificate verification probably failed due to a
problem with the certificate (it might be expired, or the name might
not match the domain name in the URL).
If you'd like to turn off curl's verification of the certificate, use
the -k (or --insecure) option.
[root@localhost cert_test]#
#用-k参数跳过证书验证,可以看到curl的结果
[root@localhost cert_test]# curl -Ik https://127.0.0.1/
HTTP/1.1 403 Forbidden
Date: Tue, 17 Sep 2019 14:20:30 GMT
Server: Apache/2.4.6 (CentOS) OpenSSL/1.0.2k-fips
Last-Modified: Thu, 16 Oct 2014 13:20:58 GMT
ETag: "1321-5058a1e728280"
Accept-Ranges: bytes
Content-Length: 4897
Content-Type: text/html; charset=UTF-8
- 上面使用-k参数跳过证书验证虽然可以,但是能不能不跳过证书验证呢?
其实根据上面的提示,我们知道curl 用系统中bundle的证书来进行验证,而我们自己创建的证书当然不是系统bundle的,所以才提示“not trusted"。 但是我们可以使用:--cacert 选项来指定CA证书从而来避免该提示;
[root@localhost cert_test]# curl --cacert /etc/httpd/conf.d/CA_Cert.pem https://127.0.0.1/
curl: (51) Unable to communicate securely with peer: requested domain name does not match the server's certificate.
[root@localhost cert_test]#
我们发现还是报错,这次的错误是 证书绑定的域名和当前请求域名不匹配;我们前面创建证书的时候使用的域名是:www . my.com, 所以查看下证书,确认下,重新测试:
[root@localhost cert_test]#openssl x509 -in ./my.crt -subject #结果中指名了适用于网站www . my.com
......
#因为没有对www . my.com注册DNS, 所以我们修改/etc/hosts, 把www . my.com 指向127.0.0.1, 再重新验证:
[root@localhost cert_test]# curl -I --cacert /etc/httpd/conf.d/CA_Cert.pem https://www.my.com/
HTTP/1.1 403 Forbidden
Date: Tue, 17 Sep 2019 11:36:36 GMT
Server: Apache/2.4.6 (CentOS) OpenSSL/1.0.2k-fips
Last-Modified: Thu, 16 Oct 2014 13:20:58 GMT
ETag: "1321-5058a1e728280"
Accept-Ranges: bytes
Content-Length: 4897
Content-Type: text/html; charset=UTF-8
[root@localhost cert_test]#
至此,成功从创建证书到搭建自己的https网站完成了;
附:
数字证书系列--证书请求文件CSR
数字证书系列--CA以及用CA 签发用户证书
本文原创,转载请注明出处
网友评论