Nginx 建立 https 服务器
增加一个文本文件 /etc/yum.repos.d/nginx.repo
,内容是:
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/OS/OSRELEASE/$basearch/
gpgcheck=0
enabled=1
由于本地环境是 centos7.3,将 OS
替换为 centos
,将 OSRELEASE
替换为7
。然后:
$ yum update -y
$ yum install nginx
自签名证书 https 服务器
生成私钥和自签名证书:
$ openssl req -new -newkey rsa:2048 -nodes -x509 -keyout nginx.key -out nginx.crt -subj "/C=CN/ST=Shan Dong/L=Ji Nan/O=Inspur/OU=SBG/CN=c7304.ambari.apache.org"
-nodes
表示密钥不加密。
编辑 nginx 配置文件 /etc/nginx/conf.d/default.conf
,添加以下内容:
server {
listen 442 ssl;
server_name c7304.ambari.apache.org;
ssl_certificate /opt/https/nginx.crt; (证书)
ssl_certificate_key /opt/https/nginx.key; (私钥)
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
注意使用的 442 端口,而不是 https 默认的443端口。index.html 文件没有就手工需要一个。
重启 nginx,加载新的配置文件,测试https服务器:
$ service nginx start (刚装上nginx时要执行,之后就不用了)
$ nginx -t (测试nginx配置文件)
$ nginx -s reload (重新加载配置文件,修改nginx配置文件有执行这个命令)
可以用前面的 java 程序测试一下 https:
$ java HttpsTest https://c7304.ambari.apache.org:442 (报错)
必然报错,因为服务器证书没加入到可信证书库中。
将公钥导入 JDK 可信证书库
$ keytool -import -trustcacerts -keystore /usr/java/jdk1.8.0_131/jre/lib/security/cacerts -alias nginx -file nginx.crt -storepass changeit
有时要多次导入同名条目。如果提示重名,则删除条目的命令:
$ keytool -delete -keystore /usr/java/jdk1.8.0_131/jre/lib/security/cacerts -alias nginx -storepass changeit
重新用 java 程序测试:
$ java HttpsTest https://c7304.ambari.apache.org:442 (正常执行)
可以看到,不报错了。说明 nginx 的公钥证书导入到JDK可信证书库的操作起作用了。
用 curl 进行可信 https 测试
$ curl https://c7304.ambari.apache.org:442 (报错)
$ curl https://c7304.ambari.apache.org:442 --cacert /opt/https/nginx.crt (不报错,返回了网页)
curl 增加 --cacert
参数后,相当于把参数后的证书临时加入了 curl 的可信库。
注意,curl 的 --cacert 参数接受的是 PEM 格式的证书。把 JKS 格式的密钥库当参数传给 curl 是不行的,如 /etc/pki/java/cacerts
当 curl 参数不行。
curl 还有一个 -k
参数可以强制关闭可信检测:
$ curl -k https://c7304.ambari.apache.org (正常显示)
CA 签名证书 https 服务器
要获得一个 CA 签名的 nginx 公钥证书,除了通过免费 let's encrypt
网站或商用CA证书公司外,还可以自己搭建一个 内部CA。搭建办法参见附录。
除了搭建正式的 CA 外,还可以自建一个临时 CA。其实就是生成一个自签名的证书来充当CA根证书:
$ openssl req -new -newkey rsa:2048 -x509 -keyout ca.key -out ca.crt -subj "/C=CN/ST=Shan Dong/L=Ji Nan/O=Inspur/OU=SBG/CN=TempCA"
为了CA签名,先生成一个私钥和证书签名请求:
$ openssl req -new -newkey rsa:2048 -nodes -keyout nginx2.key -out nginx2.csr -subj "/C=CN/ST=Shan Dong/L=Ji Nan/O=Inspur/OU=SBG/CN=c7304.ambari.apache.org"
命令格式同前文的自签名相比,去掉了一个 -x509
。输出的文件命名也改了.csr。生成好后可以cat命令看一下.csr文件的内容,发现它的开始一行是 -----BEGIN CERTIFICATE REQUEST-----
,而证书的开始行是 -----BEGIN CERTIFICATE-----
。
然后,是自建CA处理证书签名请求(CSR),会提示输入CA私钥密码:
$ openssl x509 -req -CA ca.crt -CAkey ca.key -in nginx2.csr -out nginx2.crt -days 365 -CAcreateserial -passin pass:vagrant
可以用下列命令查看一下签名后的证书,能看到Issuer和Subject不一样了:
$ openssl x509 -noout -text -in nginx2.crt
注意,在下一章讲双向SSL时,也用这个临时CA对客户端证书进行签名。
配置 nginx
修改 nginx 的配置文件 /etc/nginx/conf.d/default.conf
,添加以下内容:
server {
listen 444 ssl;
server_name c7304.ambari.apache.org;
ssl_certificate /opt/https/nginx2.crt;
ssl_certificate_key /opt/https/nginx2.key;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}
使用端口 444 来测试自建CA签名证书搭建的 https 服务器。重新加载 nginx 配置文件:
$ nginx -s reload
测试 https 服务器
首先,用 curl 测试。需要说明的是,对于CA签名的证书,客户端需要信任是CA的公钥证书,而不是https服务器自己的。所以,curl的命令是:
$ curl https://c7304.ambari.apache.org --cacert ca.crt (正常执行)
用之前 java 程序测试,先要把CA证书导入自建可信证书库:
$ keytool -import -trustcacerts -keystore trust.jks -alias TempCA -file ca.crt -storepass vagrant
$ java -Djavax.net.ssl.trustStore=trust.jks HttpsTest https://c7304.ambari.apache.org:444 (正常执行)
下面删除 TempCA
这个条目,改成导入 nginx2.crt:
$ keytool -delete -keystore trust.jks -alias TempCA -storepass vagrant
$ keytool -import -trustcacerts -keystore trust.jks -alias nginx2 -file nginx2.crt -storepass vagrant
$ java -Djavax.net.ssl.trustStore=trust.jks HttpsTest https://c7304.ambari.apache.org:444 (正常执行)
无论导入https服务器自身的证书,还是为它签名的CA的证书 都可以。这与CURL有显著不同。
把 https 服务器证书导入 JDK 官方信任库的测试就不做了。
导入 IE 测试
将 ca.crt、nginx.cr、nginx2.crt 复制到 Windows 下,然后导入IE的 受信任的发布者 证书。但访问 https://c7304.ambaria.apache.org:442
或 https://c7304.ambaria.apache.org:444
都报告 此网站的安全证书存在问题。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论