前言:最近开发微信小程序,坑爹的小程序需要https协议才请求,这里总结一下开发过程,积累学习经验。
(1)linux centos7安装nginx教程:linux nginx安装以及配置
(2)小程序的官网也给出了https的搭建教程:HTTPS服务器配置
我查看文章发现现在主流的ssl证书有openssl和startssl,这里我们使用openssl证书来开发,毕竟跟微信小程序保持一致比较安全些。
(1)进入想要生成私钥的目录,如果没有就创建一个
#进入nginx的安装目录
cd /usr/local/nginx
#创建一个存放私钥的文件夹(自定义)
mkdir key
#进入key文件夹
cd key
(2)生成私钥
openssl genrsa -out server.key 2048
(3)生成csr文件
openssl req -new -key server.key -out certreq.csr
以下黑色标识文字仅供参考,请根据商户自己实际情况进行填写
Country Name: CN //您所在国家的ISO标准代号,中国为CN
State or Province Name:guandong //您单位所在地省/自治区/直辖市
Locality Name:shenzhen //您单位所在地的市/县/区
Organization Name: Tencent Technology (Shenzhen) Company Limited //您单位/机构/企业合法的名称
Organizational Unit Name: R&D //部门名称
Common Name: www.example.com //通用名,例如:www.itrus.com.cn。此项必须与您访问提供SSL服务的服务器时所应用的域名完全匹配。
Email Address: //您的邮件地址,不必输入,直接回车跳过
"extra"attributes //以下信息不必输入,回车跳过直到命令执行完毕。
注:上述是微信小程序官方文档,亲测完全可以生成。执行上面的命令后,在当前目录下即可生成私钥文件server.key和certreq.csr csr文件。
(1)找到安装nginx的源码根目录,如果没有的话下载新的源码。
注:nginx的安装目录和配置文件的目录不是一个目录,千万不要弄错,我一般将安装文件都放在opt文件夹下。
安装nginx参考文章:linux nginx安装以及配置
(2)查看ngixn版本极其编译参数
/usr/local/nginx/sbin/nginx -V
为什么是这个路劲呢,因为我们配置编译的nginx就是这个路径,nginx在sbin目录下启动、关闭。
在configure arguments:后面显示的原有的configure参数如下:
--prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --with-file-aio --with-http_realip_module
(3)进入nginx安装目录
进入的是我们解压nginx的目录
cd /opt/nginx-1.11.6
(4)执行重新编译的代码和模块
我们安装完nginx并执行ssl需要第三方的模块,否则我们会修改nginx.conf配置文件监听443端口就会出现缺少ssl模块的错误。
./configure --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --with-file-aio --with-http_realip_module
./configure –prefix=nginx安装路径 –with-模块
这里注意一个小细节,就是- -后的空格,千万要空出来,要不然编译模块会出错。
(5)make编译
make 千万别make install,否则就覆盖安装了
make
make完之后在objs目录下就多了个nginx,这个就是新版本的程序了。
(6)备份原有的nginx文件(备份是一个良好的习惯,再修改配置文件的时候最好都要备份一下)
cp /usr/local/nginx/sbin/nginx/usr/local/nginx/sbin/nginx.bak
这里备份的也是我们nginx配置文件的,不是安装文件的,要注意下。
(7)将新生成的nginx程序覆盖原有的nginx(这个时候nginx要停止状态)
cp objs/nginx /usr/local/nginx/sbin/nginx
(8)测试新的nginx程序是否正确
/usr/local/nginx/sbin/nginx -t
如果显示如下说明成功,否则失败
nginx: theconfiguration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx:configuration file /usr/local/nginx/conf/nginx.conf test issuccessful
(9)启动nginx,可以通过命令查看是否已经加入成功
#启动nginx(进入sbin目录启动)
cd /usr/local/nginx/sbin
./nginx
#查看
/usr/local/nginx/sbin/nginx -V
如果你的configure arguments:后面是空,说明编译失败,你需要检查编译的代码是否写对,地址是否正确,每个模块前都有空格。
注:我再配置过程中也失败过很多次,首先你要检查你的nginx再配置过程中是否关闭,在检查你编译的模块是否成功,这个地方很重要,影响整合nginx的执行,最后查看你nginx是否覆盖成功。如果失败就从第二步从头开始
这里配置是最重要的,大家可以多参考文章,我这里是根据自己的需求配置的,还有很多问题。
(1)进入nginx.conf配置文件
vi /usr/local/nginx/conf/nginx.conf
想要https就要监听443端口,nginx.conf已经预留出了server,只要我们放开权限,修改即可。
监听443端口
server {
listen 443 ssl;
server_name www.example.com;
ssl on;
ssl_certificate /usr/local/nginx/key/server.crt;
ssl_certificate_key /usr/local/nginx/key/server.key;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; #指定SSL服务器端支持的协议版本
ssl_ciphers HIGH:!aNULL:!MD5;
#ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP; #指定加密算法
ssl_prefer_server_ciphers on; #在使用SSLv3和TLS协议时指定服务器的加密算法要优先于客户端的加密算法
}
注:ssl_certificate 和 ssl_certificate_key 的路径就是我们ssl证书申请的路径
ssl_certificate证书其实是个公钥,它会被发送到连接服务器的每个客户端,ssl_certificate_key私钥是用来解密的,所以它的权限要得到保护但nginx的主进程能够读取。当然私钥和证书可以放在一个证书文件中,这种方式也只有公钥证书才发送到client。
ssl_session_timeout 客户端可以重用会话缓存中ssl参数的过期时间,内网系统默认5分钟太短了,可以设成30m即30分钟甚至4h。
ssl_protocols指令用于启动特定的加密协议,nginx在1.1.13和1.0.12版本后默认是ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2,TLSv1.1与TLSv1.2要确保OpenSSL >= 1.0.1 ,SSLv3 现在还有很多地方在用但有不少被攻击的漏洞。
ssl_ciphers选择加密套件,不同的浏览器所支持的套件(和顺序)可能会不同。这里指定的是OpenSSL库能够识别的写法,你可以通过 openssl -v cipher ‘RC4:HIGH:!aNULL:!MD5’(后面是你所指定的套件加密算法) 来看所支持算法。
ssl_prefer_server_ciphers on设置协商加密算法时,优先使用我们服务端的加密套件,而不是客户端浏览器的加密套件。
监听80端口
server {
listen 80;
server_name www.example.com;
rewrite ^(.*) https://$server_name$1 permanent;
}
因为http是默认端口,监听80端口可以让http重定向到https端口上。
(2)https转http (这个跟上面的配置就不一样了)
我弄https的时候安装上面的方法配置完配置文件执行时没问题的,但是并不是我想要的,因为我监听443和80端口后就占用了这两个端口,并且我想使用https来访问我的tomcat,但是配置后发现访问的都是nginx的。这我就需要让https来重定向到我tomcat的http上。在网上找了一圈资料,几乎都是http转https的,并不符合我的需求。所以我自己想办法进行转发。
nginx.conf配置文件
server {
listen 443 ssl;
server_name www.example.com;
ssl on;
ssl_certificate /usr/local/nginx/key/server.crt;
ssl_certificate_key /usr/local/nginx/key/server.key;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; #指定SSL服务器端支持的协议版本
ssl_ciphers HIGH:!aNULL:!MD5;
#ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP; #指定加密算法
ssl_prefer_server_ciphers on; #在使用SSLv3和TLS协议时指定服务器的加密算法要优先于客户端的加密算法
location /{
proxy_pass http://localhost:8080;
}
}
这里我使用location的proxy_pass实现重定向,访问https直接重定向到我的http上。
因为我们还没有购买证书,所以虽然是https,但是对浏览器是不受信任的。
(3)映射80端口使用nginx配置tomcat
server{
listen 80;
server_name www.example.com:8081;
location / {
proxy_pass http://localhost:8081
}
}
配置这个的好处就是端口号本来只能唯一,但是我们通过配置就可以重定向,让我们的非80端口也能使用80端口。
如果你是找一个知名的ssl证书颁发机构如VeriSign、Wosign、StartSSL签发的证书,浏览器已经内置并信任了这些根证书,如果你是自建C或获得二级CA授权,都需要将CA证书添加到浏览器,这样在访问站点时才不会显示不安全连接。不够买证书微信小程序会不支持。证书生成的方法有很多,这里简单说一下。
(1)购买阿里云的免费证书
购买免费型DV SSL证书
审核一下
下载证书
重新配置nginx.conf配置文件
server {
listen 443 ssl;
server_name www.example.com;
ssl on;
ssl_certificate /usr/local/nginx/key/2141051716***.pem;
ssl_certificate_key /usr/local/nginx/key/2141051716***.key;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; #指定SSL服务器端支持的协议版本
ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP; #指定加密算法
ssl_prefer_server_ciphers on; #在使用SSLv3和TLS协议时指定服务器的加密算法要优先于客户端的加密算法
location /{
proxy_pass http://localhost:8081;
}
}
注:阿里免费的证书在测试高版本的IOS上不可行,安卓可行,如果微信小程序的话肯定是不是的,建议购买ssl证书。
(2)getssl证书购买
getssl官网
购买证书在配置nginx.conf即可
HTTPS服务器配置
nginx重新编译添加ssl模块
nginx配置ssl加密(单/双向认证、部分https)