码迷,mamicode.com
首页 > Web开发 > 详细

Apache + SSL 搭建Https

时间:2015-09-19 16:37:25      阅读:297      评论:0      收藏:0      [点我收藏+]

标签:

阅读目录

 

 笔者最近在研究Https,在半年前发现做的HTTPS都是错误的,总以为能实现访问就成功了,但是并不是这样!在网上搜索了很多资料发现讲得全面的并不多,所以笔者将配置的全过程都完整的记录下来,以提供参考

简单介绍

一般情况下,我们打开网站默认的是使用明文传输方式,但在日常生活中,当我们在登录或者支付交易时,网站就会自动跳转至SSL(Secure Sockets Layes)加密传输模式,SSL的功能就是提供加密数据

网络传输过程中的数据加密则是全部委托给SSL协议来完成,而TLS(Transport Layes Security)是对SSL的扩展与优化,它可以提供数据的安全,同时也保证数据的完整性


 证书(Certificate)是HTTPS的核心,但是其实证书并不是一个单一的东西,而是几种技术的综合

加密/解密

  • 避免消息明文传输,对消息进行加密,早期一般是用对称加密算法,现在一般都是不对称加密,最常见的算法就是RSA

消息摘要

  • 这个技术主要是为了避免消息被篡改,消息摘要是把一段信息,通过某种算法,得出一串字符串!这个字符串就是消息的摘要,如果消息被篡改"发生了变化",那么摘要也一定会发生变化"如果2个不同的消息生成的摘要是一样的,那么这就叫发生了碰撞"

数字签名 

  • 数字签名是为了验证双方的身份,避免身份伪造

单向认证和双向认证

  • 单向认证:如百度、以及淘宝之内的网站
  • 双向认证:如银行对安全要求很高的网站,也会采用双向认证,如U盾、安全控件什么的,其实就是固化的客户端证书

 Apache Http Server通过mod_ssl模块来实现对SSL/TLS的支持,所以等下环境搭建的时候需要安装mod_ssl模块

SSL涉及到的内容非常繁杂,包括各种术语、命令、算法等,所涉及到的我都没有完全理解,此篇随便笔者将会把自己理解的都尽量解释一下,如果需要深究,需要花大量的时间来完成

https协议默认的端口号为443

环境介绍

此篇随笔将搭建单向Https

本环境的安装默认使用yum源在线安装,笔者没有使用源码来安装是因为一直没有好一个模块,所以这里直接就用Yum安装,yum安装好过后不会去关心模块

环境安装

  • 保证CentOS操作系统能够通外网
[root@www ~]# ping -c 3 www.baidu.com
PING www.a.shifen.com (61.135.169.121) 56(84) bytes of data.
64 bytes from 61.135.169.121: icmp_seq=1 ttl=52 time=40.3 ms
64 bytes from 61.135.169.121: icmp_seq=2 ttl=52 time=40.9 ms
64 bytes from 61.135.169.121: icmp_seq=3 ttl=52 time=39.7 ms

--- www.a.shifen.com ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2042ms
rtt min/avg/max/mdev = 39.705/40.339/40.920/0.497 ms
  • 安装Apache  httpd服务
[root@www ~]# yum -y install httpd
  • 安装Openssl
[root@www ~]# yum -y install openssl
  • 安装mod_ssl模块来实现对SSL的支持
[root@www ~]# yum -y install mod_ssl
[root@www ~]# ls -l /etc/httpd/conf.d/ssl.conf
-rw-r--r--. 1 root root 9446 9月  19 11:08 /etc/httpd/conf.d/ssl.conf

创建CA(Certificate Authority)

CA也称为"根证书" 

服务端做了一个证书,但是这是没有法律效力的,谁都可以自己做证书,就根本达不到安全的目的!所以就要有一个机构,负责来确认服务端的身份,然后统一的签发证书,这样才能有权威性 

当用户用浏览器通过HTTPS协议访问一个网站,网站首先会发过来一个自己的证书(certificate),接下来浏览器就会到权威机构(CA),去验证一下这个证书是不是它签发的,如果是的话,就信任这个网站的证书,继续访问。如果不是的话,要怎么处理就依赖于实现了,一般的浏览器会弹出一个警告,让用户自己决定要不要继续访问,当然直接拒绝也是可以的 

现在国际上有3大CA机构,如果是要自己做一个网站的话,如上所述,一般是需要请这些权威机构帮忙签发证书的!现在所有的主流浏览器,默认都安装了这些CA的根证书,所以如果网站的证书是这些权威机构签发的,浏览器就不会发出警告了。比如淘宝网证书是由GlobalSign签发的,所以访问淘宝网,浏览器不会发出警告 

技术分享

这里还有一个链条的关系,比如我有10个子网站,如果每个都要去找CA签发证书,就很麻烦,我可以找CA给我签发一个次级根证书,然后再用这个次级根证书给自己签发10个证书,那么只要客户的浏览器里有CA根证书就可以了,这10个证书都可以通过认证,不要求客户安装次级根证书

技术分享

 其实如果是企业应用,那完全可以自己给自己当CA,因为可以要求目标用户(操作系统)安装自己的CA根证书,效果是一样的,还可以省下请权威CA签发证书的费用(互联网应用分发自己的CA到无数的互联网用户上,难度非常大)

  •  进入openssl的配置目录
[root@www ~]# cd /etc/pki/tls
[root@www tls]# ls -l
总用量 24
lrwxrwxrwx. 1 root root    19 9月  18 17:25 cert.pem -> certs/ca-bundle.crt
drwxr-xr-x. 2 root root  4096 9月  18 19:42 certs                 //存放证书目录
drwxr-xr-x. 2 root root  4096 9月  18 19:30 misc
-rw-r--r--. 1 root root 10906 6月  23 21:07 openssl.cnf           //openssl配置文件
drwxr-xr-x. 2 root root  4096 9月  18 19:42 private               //存放私钥和csr的目录
  • 创建CA私钥
[root@www tls]# openssl genrsa -aes256 -out private/ca.key.pem 2048
				   //私钥文件名是ca.key.pem ,RSA的长度是2048,默认512
Generating RSA private key, 2048 bit long modulus
...+++
..............................+++
e is 65537 (0x10001)
Enter pass phrase for private/ca.key.pem:            	    //创建一个私钥的密码
Verifying - Enter pass phrase for private/ca.key.pem:		//再次输入密码
  •  查看刚才创建的私钥信息
[root@www tls]# openssl rsa -noout -text -in private/ca.key.pem
Enter pass phrase for private/ca.key.pem:          //输入私钥密码
Private-Key: (2048 bit)						
 			 		  ~~~看不懂啊~~~

最后的.pem扩展名,是表示该私钥用PEM编码,实际上私钥和证书都是用PEM编码的,PEM只是一种编码格式,httpd可以直接处理这种编码格式,但是浏览器和JAVA都不行,所以在需要的时候,会把编码从PEM改成PKCS,后面笔者会介绍,只要知道证书和私钥都有编码,只是编码是PEM还是PKCS的区别而已,就像编程中的"你好,世界"可以用UTF-8编码,也可以用GBK编码一样,内容是不变的 

  • 创建CA签名请求
[root@www tls]# openssl req -new -key private/ca.key.pem -out private/ca.csr -subj "/C=CN/ST=CQ/L=CQ/O=lansha/OU=lansha/CN=*.lansha.com"
Enter pass phrase for private/ca.key.pem:          //输入私钥密码

这里要注意的是,如果不用-subj参数,那么就会在命令行交互输入签发目标的身份识别信息,这叫DN(Distinguished Name),其中别的都不要紧,最重要的是CN那一行,因为我这里是根证书,所以我设置为*.lansha.com,这样我后面用这个CA签发的www.lansha.com、web.lansha.com ……,全都是有效的 

  • 生成的签名请求文件,ca.csr 
[root@www tls]# openssl req -noout -text -in private/ca.csr
Certificate Request:
 			  ~~~和上面一样,还是看不懂~~~
  • 自己签发CA根证书 
[root@www tls]# openssl x509 -req -days 365 -sha1 -extensions v3_ca -signkey private/ca.key.pem -in private/ca.csr -out certs/ca.cer
				//这里的参数非常复杂,x509证书格式,有效时间为1年,使用安全哈希算法
Signature ok
subject=/C=CN/ST=CQ/L=CQ/O=lansha/OU=lansha/CN=*.lansha.com
Getting Private key
Enter pass phrase for private/ca.key.pem:          //输入私钥密码    

生成的ca.cer,就是最终的根证书了!这个文件非常重要,因为后续的服务端证书、客户端证书,都是用这个CA签发的,也要把它分发给客户,让他们导入到自己的浏览器或者系统中

  • 把根证书从PEM编码转为PKCS编码 

这步其实不是必选的,但是前面说过,JAVA环境是不能直接用PEM编码的证书的,很多浏览器也不行,所以有时候也需要转一下编码 

得到的ca.p12就是转码后的CA根证书,在不能直接用ca.cer的时候,就用ca.p12代替

[root@www tls]# openssl pkcs12 -export -cacerts -inkey private/ca.key.pem -in certs/ca.cer -out certs/ca.p12
Enter pass phrase for private/ca.key.pem:          //输入私钥密码   
Enter Export Password:							   //可以新建一个密码	
Verifying - Enter Export Password:				   //再次输入密码

签发服务端证书

现在CA根证书和私钥都有了,就可以开始签发服务端证书了(签发请求ca.csr是过程文件,有了cer就不再需要它了,要删掉也可以),下面的命令和签发CA证书时都差不多,但是参数上有区别 

  • 创建服务端私钥 

[root@www tls]# openssl genrsa -aes256 -out private/server.key.pem 2048
Generating RSA private key, 2048 bit long modulus
...............................................+++
........................................................................................................................................................................+++
e is 65537 (0x10001)
Enter pass phrase for private/server.key.pem:                 //输入一个私钥密码      
Verifying - Enter pass phrase for private/server.key.pem:	  //再次输入密码
  • 创建服务端证书签发请求 
[root@www tls]# openssl req -new -key private/server.key.pem -out private/server.csr -subj "/C=CN/ST=CQ/L=CQ/O=lansha/OU=lansha/CN=www.lansha.com"
Enter pass phrase for private/server.key.pem:          //输入私钥密码   

和上面ca.csr的区别在于,这里的CN不是*.lansha.com,而是www.lansha.com,因为笔者现在是在为www.lansha.com申请证书 

  • 利用CA根证书,签发服务端证书 
[root@www tls]# openssl x509 -req -days 365 -sha1 -extensions v3_req -CA certs/ca.cer -CAkey private/ca.key.pem -CAserial ca.srl -CAcreateserial -in private/server.csr -out certs/server.cer
Signature ok
subject=/C=CN/ST=CQ/L=CQ/O=lansha/OU=lansha/CN=www.lansha.com
Getting CA Private Key
Enter pass phrase for private/ca.key.pem:          //输入私钥密码   

这里和前面自己签发CA证书时,参数区别就比较大了,最后得到的server.cer,就是服务端证书

配置文件编辑

  • 编辑ssl.conf配置文件
[root@www tls]# cd /etc/httpd/conf.d/
[root@www conf.d]# vim ssl.conf
<VirtualHost www.lansha.com:443>
DocumentRoot "/var/www/html"
ServerName www.lansha.com:443
ErrorLog logs/ssl_error_log
TransferLog logs/ssl_access_log
SSLEngine on 
SSLCertificateFile  	/etc/pki/tls/certs/server.cer              
SSLCertificateKeyFile   /etc/pki/tls/private/server.key.pem	
#SSLCACertificateFile   /etc/pki/tls/certs/ca.cer  
#SSLVerifyClient require  
#SSLVerifyDepth  10  
</VirtualHost>

后面3个注释掉的,是双向认证才会用到 

  • 重启httpd服务
[root@www ~]# service httpd restart
停止 httpd:                                               [确定]
正在启动 httpd:httpd: Could not reliably determine the server‘s fully qualified domain name, using www.lansha.com for ServerName
Apache/2.2.15 mod_ssl/2.2.15 (Pass Phrase Dialog)
Some of your private key files are encrypted for security reasons.
In order to read them you have to provide the pass phrases.

Server www.lansha.com:443 (RSA)                         //输入服务器私钥密码
Enter pass phrase:

OK: Pass Phrase Dialog successful.
                                                           [确定]
  • 加入防火墙规则
[root@www ~]# iptables -I INPUT -p tcp --dport 443 -j ACCEPT
[root@www ~]# service iptables save                    //保存防火墙规则
iptables:将防火墙规则保存到 /etc/sysconfig/iptables:     [确定]

测试单向认证

  •  写入一个Index.html 至网站默认目录

[root@www ~]# echo "<h1>Test Https</h1>" > /var/www/html/index.html
  • 用 https://localhost尝试来访问,浏览器报警

技术分享

上面配置文件中我只给 www.lansha.com 域名监听443端口

前面创建CSR时,输入的CN的作用,这个证书是为www.lansha.com申请的,这里请求的地址却是localhost,不匹配所以报错,为了能用www.lansha.com这个主机名来访问,可以使用搭建DNS或者修改Hosts文件

[root@www ~]# vim /etc/hosts
192.168.1.134   www.lansha.com
  • 用 https://www.lansha.com 尝试访问

技术分享

 这次浏览器还是告警,但是告警信息变了

  • 查看一下这个站点的证书信息

技术分享

可以看到这个证书是由*.lansha这个CA颁发的,浏览器不认识,所以不信任由这个CA签发的所有证书

接下来就需要把ca.cer导入浏览器,这里直接导入server.cer也是可以的,但是后面如果又创建一个网站比如说www2.lansha.com、www3.lansha.com,那么又不行了,所以最好的办法是直接导入CA根证书,那么后续只要是用这个根证书签发的证书,浏览器都会信任 

  • 导入证书

浏览器-->编辑-->首选项-->高级-->加密-->查看证书-->证书机构--导入证书

技术分享

技术分享

技术分享

  • 再次访问,可以看到成功了,浏览器不告警,并且URL栏前面有一个小锁

技术分享

到这里Https就搭建完成了,思路还是非常清晰的

参考资料

Apache + SSL 搭建Https

标签:

原文地址:http://www.cnblogs.com/vforbox/p/4818958.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!