上上篇文章《nginx 平滑升级&新增模块》提到了公司的 https 访问需求。当我新增了 SSL 模块之后,却发现以前还真没部署过 https 访问。
下面整理我的部署过程,并收集了一下 Apache 和 Tomcat 这 2 种 Linux 下常用的 WEB 软件配置 SSL 的简单简单步骤,以便回头翻阅。
一、下载证书
成功申请 SSL 证书之后,就可以下载到配置 SSL 的证书了!一般情况下,都可以选择下载相应 WEB 服务器的不同证书,或者直接打包下载主流 WEB 服务器的证书,如图所示:
下载后,就可以根据不同的 WEB 服务器来选择相应的证书了。
二、Nginx
先确认 nginx 安装时已编译 http_ssl 模块,也就是执行如下命令查看是否存在--with-http_ssl_module 参数:
linux-test:~ # /usr/local/nginx/sbin/nginx -V nginx version: nginx/1.6.0 built by gcc 4.4.7 20120313 (Red Hat 4.4.7-4) (GCC) TLS SNI support enabled configure arguments: --prefix=/usr/local/nginx --with-http_ssl_module --with-openssl=/usr/local/src/openssl-1.0.1/
如果没有这个参数,说明没有编译 SSL 模块,那么请参考上上篇文章自行解决,此处就不赘述了。
①、准备证书
Nginx 需要用到 2 个证书文件:
I. 证书公钥 (crt 格式)
II. 证书私钥(key 格式)
拿到证书后,将其上传到 nginx 下的 ssl 目录(也可自定义位置)。
②、修改配置
A. http 和 https 全局共存
在原 server 模块新增监听 443 端口,然后新增如下代码(具体看注释)。
server { listen 80; #新增监听 443 端口,并指定 443 为 ssl: listen 443 ssl; server_name yourdomain.com; #新增 ssl 配置---开始: ssl_certificate /usr/local/nginx/ssl/yourdomain_bundle.crt; #证书公钥文件路径 ssl_certificate_key /usr/local/nginx/ssl/yourdomain.key; #证书私钥文件路径 ssl_session_timeout 5m; #5 分钟 session 会话保持 ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers HIGH:!ADH:!EXPORT56:RC4+RSA:+MEDIUM; #新增 ssl 配置---结束: location / { #其他规则保持不变 } }
保存配置之后,先执行如下命令测试配置是否正确:
linux-test:~ # /usr/local/nginx/sbin/nginx -t #如下显示则为正确无误: nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
确认无误之后,执行如下命令重载 nginx,让配置生效:
linux-test:~ # /usr/local/nginx/sbin/nginx -s reload
如无错误,现在应该可以顺利访问 https://yourdomain.com/了!值得说明的是,这样配置后,http 和 https 是全局共存的,你能 http 访问到的页面,https 也可以访问得到。
B. 全局强制 https
如果是全局 https 访问,那么额外写一个监听 80 的 server,让 http 访问跳转到 https 上即可,下面是参考模板:
server{ listen 80; server_name yourdomain.com; root /path/for/yourdomain.com; location / { rewrite (.*) https://yourdomain.com$1 permanent; } } server { listen 443; server_name yourdomain.com; ssl on; ssl_certificate /usr/local/nginx/ssl/yourdomain_bundle.crt; #证书公钥文件路径 ssl_certificate_key /usr/local/nginx/ssl/yourdomain.key; #证书私钥文件路径 ssl_session_timeout 5m; ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers HIGH:!ADH:!EXPORT56:RC4+RSA:+MEDIUM; location / { #其他规则维持不变 } }
C. 部分强制 https,部分强制 http
可能有部分强迫症会有这样的需求:我只要部分页面强制 https 访问,比如后台及登陆页面,其他常规页面强制 http 访问,我该如何设置?
思路:和 B 方案一样,分别 2 个 server 模块,并新增判断规则,指定部分页面 http 访问,部分页面 https 访问。
具体可以参考一下张戈博客的配置(主要修改中文注释部分,其他配置保持不变):
#监听 httpserver server { listen 80; server_name zhang.ge m.zhang.ge; index index.html index.htm index.php default.html default.htm default.php; root /home/web/zhang.ge; include zhangge.conf; location ~ /uploads/.*\.(php|php5)?$ { deny all; } #若是匹配到 wp-login.php 登陆,则跳到 https location ~ /(wp-login\.php(.*)$) { rewrite ^(.*)$ https://zhang.ge$1 permanent; break; } #wordpress 后台强制跳到 https location /wp-admin { rewrite ^(.*)$ https://zhang.ge$1 permanent; } location ~ [^/]\.php(/|$) { try_files $uri =404; fastcgi_pass unix:/tmp/php-cgi.sock; fastcgi_index index.php; include fastcgi.conf; } location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ { expires 30d; } location ~ .*\.(js|css)?$ { expires 30d; } access_log /home/logs/zhang.ge.log access; } #监听 https server { listen 443; server_name zhang.ge m.zhang.ge; ssl on; ssl_certificate /usr/local/nginx/ssl/zhang.ge.crt; ssl_certificate_key /usr/local/nginx/ssl/zhang.ge.key; ssl_session_timeout 5m; ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers HIGH:!ADH:!EXPORT56:RC4+RSA:+MEDIUM; index index.html index.htm index.php default.html default.htm default.php; root /home/web/zhang.ge; #有偿服务付款页面使用 https 访问 location /wp-content/plugins/alipay { try_files $uri $uri/ /index.php?$args; } #若没有匹配到 wp-admin 或 wp-includes,则跳到 http 访问(反向逻辑:即只允许指定页面开启 https) location / { if ($request_uri !~* "wp-admin|wp-includes") { rewrite (.*) https://zhang.ge$1 permanent; } } location ~ /uploads/.*\.(php|php5)?$ { deny all; } location ~ [^/]\.php(/|$) { try_files $uri =404; fastcgi_pass unix:/tmp/php-cgi.sock; fastcgi_index index.php; include fastcgi.conf; } location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ { expires 30d; } location ~ .*\.(js|css)?$ { expires 30d; } access_log /home/wwwlogs/zhang.ge.log access; }
二、Apache
同样,先确认 Apache 安装时已添加 SSL 支持模块。如果没有请自行搜索搞定,本文不再赘述。
①、准备证书
Apache 需要用到三个证书文件:
I. 根证书:root_bundle.crt
II. 证书公钥:yourdomain.com.crt
III. 证书私钥:yourdomain.com.key
将下载好的三个证书文件,上传到 apache 下的 ssl 目录中(可自定义位置)。
②、修改配置
I. 编辑 httpd.conf 文件,取消以下内容的#注释符号:
#LoadModule ssl_module modules/mod_ssl.so #Include conf/extra/httpd-ssl.conf
II. 编辑 http-ssl.conf 文件,如下修改:
#找到如下行,并替换为证书公钥的实际路径: SSLCertificateFile /usr/local/apache/ssl/public.cer #找到如下行,并替换为证书私钥的实际路径: SSLCertificateKeyFile /usr/local/apache/ssl/private.key #找到如下行,取消行首注释符,并替换为根证书实际路径: #SSLCertificateChainFile /usr/local/apache/ssl/ca.cer
III. 保存退出,并重启 Apache 即可。
三、Tomcat
①、准备证书
Tomcat 只需要用到一个 jks 格式的证书文件,比如 yourdomain.com.jks。
拿到文件后,将其上传到 Tomcat 下的 conf 目录中。
②、修改配置
打开 conf 目录下的 server.xml 文件,找到以下内容:
<!-- <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true" maxThreads="150" scheme="https" secure="true" clientAuth="false" sslProtocol="TLS" /> -->
去掉前后的注释,并如下修改(或者直接其后添加以下代码亦可):
<Connector port="443" protocol="org.apache.coyote.http11.Http11Protocol" SSLEnabled="true" maxThreads="150" scheme="https" secure="true" keystoreFile="conf\yourdomain.jks" <!-- 此处填写你上传的证书的实际路径 --> keystorePass="password" clientAuth="false" sslProtocol="TLS" />
退出并保存,最后重启 Tomcat 即可。
四、解决警告
如果网页中存在不带 https 的资源,比如 http 协议的 js、css 或图片,那么访问这个 https 页面,某些浏览器(比如 IE)就会发出警告,提示页面中存在不安全的内容,并且不会加载这些 http 协议的资源,导致页面错乱等问题:
解决办法:
方法①、使用相对地址
只要将这些 http 的资源链接,改为相对地址。比如原链接是<img src="http://yourdomain.com/images/demo.png">那么改成<img src="/images/demo.png">即可。
方法②、修改网站代码
如果是全局 https 访问,那么你将网站代码中的链接均改为 https 好了。如果是 http 和 https 混合的,那么准备 2 套网站文件也行。然后在 nginx 当中设置不同的 root 路径。
为了省事,我推荐方法①。
好了,本文就写到这,希望能解您的燃眉之急!
(●'◡'●)ノ♥~~~路过,继续支持。
不错,好东西,谢谢分享。
来支持了!!
有点看不明白,可能技术不到家吧 :sad: 不过文章写得很好,有用得着地方
[color=blue]你好,我想问一下,网站当中有一些外链,像版权声明之类的外链,如果有这些外链是不是网站也会报有风险的提示?[/color]
有外链怎么会有风险呢。
真的不错,写的很好
有个疑惑,怎么对付百度,现在对https支持不好貌似
很不错的教程,非常感谢。
共享主机路过 :???:
实在没办法才来寻求帮助了,查了非常多资料,用得是lnmp,百度云,试过沃通,Let's Encrypt,StartSSL证书,中间有几次配置SSL成功访问,但后来一直是提示:SSL 连接出错,ERR_SSL_PROTOCOL_ERROR,nginx是v1.9.9,清理过浏览器缓存,重启VPS,也试过重新安装lnmp,换系统。始终是报错。。好郁闷,到底是什么问题啊,寻求Jager帮助!!! 如字数过多,请邮件好,谢谢了。
配置如下:
server {
listen 443 ssl http2;
ssl_certificate /usr/local/nginx/conf/bpplpp.com.crt;
ssl_certificate_key /usr/local/nginx/conf/bpplpp.com.key;
ssl_session_timeout 10m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-RC4-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:RC4-SHA:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!DSS:!PKS;
ssl_session_cache builtin:1000 shared:SSL:10m;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
server_name bpplpp.com;
access_log /data/wwwlogs/bpplpp.com_nginx.log combined;
index index.html index.htm index.php;
include /usr/local/nginx/conf/wordpress.conf;
root /data/wwwroot/bpplpp.com;
location ~ [^/]\.php(/|$) {
#fastcgi_pass remote_php_ip:9000;
fastcgi_pass unix:/dev/shm/php-cgi.sock;
fastcgi_index index.php;
include fastcgi.conf;
}
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|flv|ico)$ {
expires 30d;
access_log off;
}
location ~ .*\.(js|css)?$ {
expires 7d;
access_log off;
}
}
server {
listen 80;
server_name bpplpp.com;
rewrite ^/(.*) https://$server_name/$1 permanent;
}
改下试试:
谢谢Jager指导。测试军哥,运维,tennfy的lnmp,问题依旧。思考细节,以为443端口没开,测试结果相同。现在先暂时不考虑SSL
QQ287988783,可以给我看下
看了文章挺好,留存 申请了 现在的版本说是有中文语言,不知道是不是Jager说的一样?
这2个证书的用户组和所有者 还有权限是设置成什么?安全
证书配置完全后访问https出现Welcome to nginx!
默认路径 不显示网站内容只显示root /usr/local/nginx/html; 路径下的文件。请问怎么解决?
需要在已有站点的server配置文件中新增ssl配置,而不是nginx.conf
学习了。。
Apache部分开头。
#LoadModule ssl_module modules/mod_ssl.so
#Include conf/extra/httpd-ssl.conf
这个没用吧,第一是找不到这个模块,第二我查别人的2011年的就说当时的apache版本无需修改这个,只要yum install -y mod_ssl 即可。
多谢提醒,博客才能过来没用过apache,所以Apache是搬运的,并没有验证过。
今天 又来了 这文章不错 可不可以转载?
站长 你的网站中 关于 这个页面 打开是错误的 要注意!
关于页面 打开 显示 ERROR 502
本文 可不可以转载?