概述: 客户端和服务器端先进行三次握手,然后协商建立SSL会话。server端会向client端发送自己的证书,client会验证证书,如果没有问题的话,client会生成一个对称密钥发送给server端,当client再发送页面请求时,server会根据client的密钥将请求页面加密发给client,这就是说server要向第三方证书颁发机构申请一个证书,而如果要想让client验证并信任这个证书那么client需要信任这个机构,就意味着要将该机构的证书放在本机,来验证其他人的证书。因为无法在互联网上验证证书,所以此次测验在本地见一个私有CA,这个CA有自己的证书即自签证书,然后server端生成密钥,将密钥发送给CA,由CA根据公钥签署证书并回送给server端,server再配置服务器以使用这个证书并且在client发送请求时将证书发给client,然后client根据保存在本机的CA的证书来验证这个证书; 强调的是:client和server在协商SSL时是根据IP地址和端口来实现的,和主机名没有关系,这就意味着server端如果只有一个IP地址,那么它只能为一个主机提供SSL的功能;如果server提供了基于名字的虚拟主机功能的话,那么SSL只能提供给其中一个虚拟主机(他们虽然名字不一样,但是IP地址是一样的); 下面开始配置(实验是在两台主机上进行的,也可以在一台上): 1. server端首先要安装SSL模块 [root@localhost ~]# httpd -M #根据列出已安装的模块可以知道未安装SSL模块 [root@localhost ~]# yum list all | grep mod_ssl mod_ssl.i686 [root@localhost ~]# yum install mod_ssl.i686 #安装模块
该模块提供:
[root@localhost ~]# rpm -ql mod_ssl.i686
/etc/httpd/conf.d/ssl.conf #作为http服务的配置文件来使用
/usr/lib/httpd/modules/mod_ssl.so #SSL模块安装位置
/var/cache/mod_ssl #SSL会话的缓存数据
/var/cache/mod_ssl/scache.dir
/var/cache/mod_ssl/scache.pag
/var/cache/mod_ssl/scache.sem
2. 提供CA让server生成密钥并将密钥发给CA让CA签名
2.1 打开另一台主机(192.168.85.140)作为CA并生成自签证书
这个有专门的记录,具体情况不在细说:http://blog.chinaunix.net/uid-30212356-id-5138330.html
生成rsa私钥:
[root@localhost CA]# pwd
/etc/pki/CA
[root@localhost CA]# (umask 077; openssl genrsa -out ./private/cakey.pem 2048)
Generating RSA private key, 2048 bit long modulus
.........................+++
......+++
e is 65537 (0x10001)
[root@localhost CA]# ll private/
total 4 -rw------- 1 root root 1675 Aug 12 10:09 cakey.pem
生成自签证书:
[root@localhost CA]# openssl req -new -x509 -key ./private/cakey.pem -out cacert.pem -days 365
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:Henan
Locality Name (eg, city) [Default City]:Nanyang
Organization Name (eg, company) [Default Company Ltd]:Skynet
Organizational Unit Name (eg, section) []:Test
Common Name (eg, your name or your server's hostname) []:ca.a.com #证书要发给的那个主机的主机名,而且要和以后访 Email Address []:admin@a.com 问时在浏览器上输入的要一致,否则会警告;
[root@localhost CA]# ll
total 20
-rw-r--r-- 1 root root 1383 Aug 12 11:38 cacert.pem
drwx------. 2 root root 4096 Aug 12 11:37 private
2.2 修改/etc/pki/tls/openssl.cnf中的默认选项为
[ CA_default ]
dir = /etc/pki/CA # Where everything is kept #指定CA主目录
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 ctificates 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
RANDFILE = $dir/private/.rand # private random number file
这些目录需创建,而且这就是为什么创建的文件是固定格式和存放在固定目录下的原因了...
[root@localhost CA]# touch index.txt
[root@localhost CA]# echo 00 > serial
[root@localhost CA]# ll
total 24
-rw-r--r-- 1 root root 1383 Aug 12 11:38 cacert.pem
drwxr-xr-x. 2 root root 4096 Nov 22 2013 certs
drwxr-xr-x. 2 root root 4096 Nov 22 2013 crl
-rw-r--r-- 1 root root 0 Aug 12 11:49 index.txt
drwxr-xr-x. 2 root root 4096 Nov 22 2013 newcerts
drwx------. 2 root root 4096 Aug 12 11:37 private
-rw-r--r-- 1 root root 3 Aug 12 11:49 serial
到这里CA就完成了,接下来如果有主机需要证书,只需将生成的公钥发送过来,CA签证在发回去即可;
3.server端生成密钥并发送给CA签署
[root@www ssl]# (umask 077; openssl genrsa -out ./httpd.key 1024) #这里可以是.key的也可以是.pem的,没有要求
Generating RSA private key, 1024 bit long modulus
............++++++
.........................++++++
e is 65537 (0x10001)
[root@www ssl]# ll
total 4
-rw------- 1 root root 887 Aug 12 11:57 httpd.key
生成证书签发请求,注意填写的信息一定要和CA的一致,否则不会签发
[root@www ssl]# openssl req -new -key httpd.key -out http.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:Henan
Locality Name (eg, city) [Default City]:Nanyang
Organization Name (eg, company) [Default Company Ltd]:Skynet
Organizational Unit Name (eg, section) []:Test
Common Name (eg, your name or your server's hostname) []:
#这里填写的主机名是你要给的http服务的那个主机名称,例如我创建了基于端口的虚拟主机,所以我给了这台虚拟主机
[root@www ssl]# cat /etc/httpd/conf.d/virtual.conf <VirtualHost 192.168.85.128:80> ServerName DocumentRoot /var/www/a </VirtualHost> <VirtualHost 192.168.85.128:8080> ServerName />
DocumentRoot /var/www/aa </VirtualHost>
Email Address []:root@a.com
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
然后将请求发送给CA
[root@www ssl]# scp http.csr 192.168.85.140:/etc/pki/CA/http_ssl #这个目录我事先创建用来存放http的证书请求的
The authenticity of host '192.168.85.140 (192.168.85.140)' can't be established.
RSA key fingerprint is e5:5e:5f:35:39:f9:71:f0:80:7b:60:a6:83:eb:7c:aa.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.85.140' (RSA) to the list of known hosts.
root@192.168.85.140's password:
http.csr 100% 680 0.7KB/s 00:00
然后再CA(client端:192.168.85.140)上签署
[root@localhost CA]# openssl ca -in http_ssl/http.csr -out ./http_ssl/http.crt -days 365
Using configuration from /etc/pki/tls/openssl.cnf
Check that the request matches the signature
Signature ok
Certificate Details:
Serial Number: 0 (0x0)
Validity
Not Before: Aug 12 19:15:53 2015 GMT
Not After : Aug 11 19:15:53 2016 GMT
Subject:
countryName = CN
stateOrProvinceName = Henan
organizationName = Skynet
organizationalUnitName = Test
commonName =
emailAddress = root@a.com
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
Netscape Comment:
OpenSSL Generated Certificate
X509v3 Subject Key Identifier:
E2:27:A3:7A:E9:6C:77:57:1C:D8:FB:5D:2D:09:F9:F6:3F:13:49:CC
X509v3 Authority Key Identifier:
keyid:FC:BE:BB:E1:55:5B:96:DB:D4:8F:92:61:78:7C:16:75:BB:3A:A2:37
Certificate is to be certified until Aug 11 19:15:53 2016 GMT (365 days)
Sign the certificate? [y/n]:y
1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
在CA上查看是否签署成功
[root@localhost CA]# cat index.txt #签署证书的信息
V 160811191553Z 00 unknown /C=CN/ST=Henan/O=Skynet/OU=Test/CN=/emailAddress=root@a.com
[root@localhost CA]# cat serial #已经签署一个了,下一个是01编号
01
4.将签署的证书发送给请求者server端
[root@localhost CA]# scp ./http_ssl/http.crt 192.168.85.128:/etc/httpd/ssl
The authenticity of host '192.168.85.128 (192.168.85.128)' can't be established.
RSA key fingerprint is e5:5e:5f:35:39:f9:71:f0:80:7b:60:a6:83:eb:7c:aa.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.85.128' (RSA) to the list of known hosts.
root@192.168.85.128's password:
http.crt 100% 3796 3.7KB/s 00:00
server端上查看一下:
[root@www ssl]# pwd
/etc/httpd/ssl
[root@www ssl]# ll
total 12 -rw-r--r-- 1 root root 3796 Aug 12 12:20 http.crt -rw-r--r-- 1 root root 680 Aug 12 12:03 http.csr
-rw------- 1 root root 887 Aug 12 11:57 httpd.key
因为在CA端的/etc/pki/CA/newcerts中已经有了证书的记录,所以为了安全最好将刚才发送过来的server的证书签署请求和签发证书删了
[root@localhost CA]# ll newcerts/
total 4
-rw-r--r-- 1 root root 3796 Aug 12 12:15 00.pem
5. 在server端上配置server端可以使用证书
[root@www conf.d]# pwd
/etc/httpd/conf.d
[root@www conf.d]# cp ssl.conf ssl.conf.bak #先备份
[root@www conf.d]# ll
total 40
-rw-r--r--. 1 root root 118 May 19 2009 mod_dnssd.conf
-rw-r--r-- 1 root root 392 Jul 24 04:50 README
-rw-r--r-- 1 root root 9465 Mar 3 09:01 ssl.conf
-rw-r--r-- 1 root root 9465 Aug 12 12:29 ssl.conf.bak
-rw-r--r-- 1 root root 192 Aug 12 11:02 virtual.conf
-rw-r--r-- 1 root root 299 Mar 3 09:01 welcome.conf
修改<VirtualHost _default_:443>段为:
<VirtualHost 192.168.85.128:443> #使用SSL的虚拟主机名
DocumentRoot "/var/www/a" #该虚拟主机的主目录要和/etc/httpd/conf.d/virtual.con中段的保持一致
ServerName #同上
ErrorLog logs/ssl_error_log #定义错误日志
TransferLog logs/ssl_access_log #定义访问日志,注意SSL用的不是CostumeLog
LogLevel warn #定义日志级别
SSLEngine on #是否启用SSL功能
SSLProtocol all -SSLv2 #支持使用的SSL协议,这里的是除了SSL-2的使用协议
SSLCipherSuite DEFAULT:!EXP:!SSLv2:!DES:!IDEA:!SEED:+3DES #SSL加密套件,有!号说明不使用
SSLCertificateFile /etc/httpd/ssl/http.crt #SSL证书文件,记得修改为签发的证书
SSLCertificateKeyFile /etc/httpd/ssl/httpd.key #server端的私钥文件
<Files ~ "\.(cgi|shtml|phtml|php3?)$">
SSLOptions +StdEnvVars
</Files>
<Directory "/var/www/cgi-bin">
SSLOptions +StdEnvVars
</Directory>
SetEnvIf User-Agent ".*MSIE.*" \
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>
最后再确认语法是否错误,重启服务,查看443端口是否监听
[root@www conf.d]# httpd -t
Syntax OK
[root@www conf.d]# service httpd restart
Stopping httpd: [ OK ]
Starting httpd: [ OK ]
[root@www conf.d]# netstat -ntlp | grep :443
tcp 0 0 :::443 :::* LISTEN 3087/httpd