博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
在 Nginx 上开启 https 实践
阅读量:6525 次
发布时间:2019-06-24

本文共 7913 字,大约阅读时间需要 26 分钟。

hot3.png

最近公司移动端API由http升级到https,Nginx作为前端负载均衡,Tomcat作为后端应用服务器。Tomcat不需要开启https,Nginx 需要开启https支持,在 Nginx 中的配置如下:

upstream mobile_https_proxy {        server 192.168.37.118:8081 weight=4 max_fails=2 fail_timeout=30s; #192.168.37.118:8081 是后端 Tomcat 的地址和端口}server {       listen 443;       server_name www.test.51offer.com;       root html;       index index.html index.htm;       ssl on;       ssl_certificate /usr/local/openssl/server-cert.cer; #服务器端证书       ssl_certificate_key /usr/local/openssl/server_nopwd.key; #服务器无密码私钥       ssl_client_certificate /usr/local/openssl/root-cert.cer;#CA证书       ssl_session_timeout 5m;       ssl_verify_client on;  #开户客户端证书验证       ssl_protocols SSLv3 TLSv1;       ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv3:+EXP;       ssl_prefer_server_ciphers on;       location ~* ^/mobile/ {                proxy_pass http://mobile_https_proxy;       }}

配置好后,执行如下命令使配置生效

/usr/local/nginx/sbin/nginx -s reload

在上面的配置中有三个证书

/usr/local/openssl/server-cert.cer; #服务器端证书/usr/local/openssl/server_nopwd.key; #服务器无密码私钥/usr/local/openssl/root-cert.cer;#CA证书

可以使用下面这个Shell脚本生成

#!/bin/shcerts=/usr/local/apps/certskeytool=/usr/java/jdk1.7.0_45/binshell=/usr/local/apps/shellsecho 准备工作...cd /usr/local/apps/echo 清理...rm -rf certsmkdir certscd certsecho 创建辅助目录...mkdir camkdir servermkdir clientecho 创建辅助文件...echo 0 > index.txtecho 01 > serialopenssl rand -out .rand 1000echo 创建根证私钥openssl genrsa -des3 -passout pass:123456 -out $certs/ca/root-key.key 2048echo 创建根证书请求文件openssl req -passin pass:123456 -new -key $certs/ca/root-key.key -out $certs/ca/root-req.csr -subj "/C=CN/ST=SH/L=SH/O=51offer/OU=51offer/CN=*.51offer.com"echo 自签根证书openssl x509 -passin pass:123456 -req -days 100000 -sha1 -signkey $certs/ca/root-key.key -in $certs/ca/root-req.csr -out $certs/ca/root-cert.cerecho 导出p12格式根证书openssl pkcs12 -export -clcerts -in $certs/ca/root-cert.cer -passin pass:123456 -inkey $certs/ca/root-key.key -passout pass:123456 -out $certs/ca/root.p12echo 生成root.jks文件cd $keytoolecho "y" | ./keytool -import -trustcacerts -storepass 123456 -alias root -file $certs/ca/root-cert.cer -keystore $certs/ca/root.jksecho 生成客户端keycd $certsopenssl genrsa -des3 -passout pass:123456 -out $certs/client/client-key.key 2048echo 生成客户端请求文件openssl req -passin pass:123456 -new -key $certs/client/client-key.key -out $certs/client/client-req.csr -subj "/C=CN/ST=SH/L=SH/O=51offer/OU=51offer/CN=www.test.51offer.com"echo 生成客户端证书(root证书,rootkey,客户端key,客户端请求文件这4个生成客户端证书)openssl x509 -passin pass:123456 -req -days 100000 -sha1 -CA $certs/ca/root-cert.cer -CAkey $certs/ca/root-key.key -CAserial ca.srl -CAcreateserial -in $certs/client/client-req.csr -out $certs/client/client-cert.cerecho 生成客户端p12格式根证书openssl pkcs12 -export -clcerts -in $certs/client/client-cert.cer -passin pass:123456 -inkey $certs/client/client-key.key -passout pass:123456 -out $certs/client/client.p12echo 生成客户端JKScd $keytoolecho "y" | ./keytool -import -v -trustcacerts -storepass 123456 -alias client -file $certs/client/client-cert.cer -keystore $certs/client/client.jksecho 生成客户端BKSecho "y" | ./keytool -import -v -trustcacerts -storepass 123456 -alias client -file $certs/client/client-cert.cer -keystore $certs/client/client.bks -deststoretype bks -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath $shell/bcprov-jdk15on-154.jarecho 生成服务端keycd $certsopenssl genrsa -des3 -passout pass:123456 -out $certs/server/server-key.key 2048echo 生成服务端请求文件openssl req -passin pass:123456 -new -key $certs/server/server-key.key -out $certs/server/server-req.csr -subj "/C=CN/ST=SH/L=SH/O=51offer/OU=51offer/CN=www.test.51offer.com"echo 生成服务端证书(root证书,rootkey,客户端key,客户端请求文件这4个生成客户端证书)openssl x509 -passin pass:123456 -req -days 100000 -sha1 -CA $certs/ca/root-cert.cer -CAkey $certs/ca/root-key.key -CAserial ca.srl -CAcreateserial -in $certs/server/server-req.csr -out $certs/server/server-cert.cerecho 生成服务端p12格式根证书openssl pkcs12 -export -clcerts -in $certs/server/server-cert.cer -passin pass:123456 -inkey $certs/server/server-key.key -passout pass:123456 -out $certs/server/server.p12echo 生成服务端无密码keyopenssl rsa -passin pass:123456 -in $certs/server/server-key.key -out $certs/server/server_nopwd.keyecho 生成服务端JKS,在服务器端开启双向验证后,客户端需要这个证书才能访问服务器端资源cd $keytoolecho "y" | ./keytool -import -v -trustcacerts -storepass 123456 -alias server -file $certs/server/server-cert.cer -keystore $certs/server/server.jksecho 生成服务端BKS,在服务器端开启双向验证后,Android客户端需要这个证书才能访问服务器端资源echo "y" | ./keytool -import -v -trustcacerts -storepass 123456 -alias server -file $certs/server/server-cert.cer -keystore $certs/server/server.bks -deststoretype bks -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath $shell/bcprov-jdk15on-154.jarecho success

其中 bcprov-jdk15on-154.jar 用于生成Android端使用的BKS证书,该文件可以下载。

使用HttpClient访问Nginx启用了https双向验证的代码如下:

package com.toulezu.httpsclient;import java.io.BufferedReader;import java.io.InputStream;import java.io.InputStreamReader;import java.security.KeyStore;import org.apache.http.HttpEntity;import org.apache.http.HttpResponse;import org.apache.http.client.HttpClient;import org.apache.http.client.methods.HttpGet;import org.apache.http.conn.scheme.Scheme;import org.apache.http.conn.ssl.SSLSocketFactory;import org.apache.http.impl.client.DefaultHttpClient;import org.apache.http.util.EntityUtils;/** * 通过 HttpClient 访问 https 网站例子 *  * @author toulezu * */public class HttpsClientJKS {	private static final String KEY_STORE_TYPE_JKS = "jks";	private static final String KEY_STORE_TYPE_P12 = "PKCS12";	private static final String SCHEME_HTTPS = "https";	private static final int HTTPS_PORT = 443;	private static final String HTTPS_URL = "https://www.test.51offer.com/mobile/school/countries";	private static final String KEY_STORE_CLIENT_PATH = "test-client.p12";	private static final String KEY_STORE_TRUST_PATH = "test-server.jks";	private static final String KEY_STORE_PASSWORD = "123456";	private static final String KEY_STORE_TRUST_PASSWORD = "123456";	public static void main(String[] args) throws Exception {		ssl();	}	private static void ssl() throws Exception {		HttpClient httpClient = new DefaultHttpClient();		try {			KeyStore keyStore = KeyStore.getInstance(KEY_STORE_TYPE_P12);			KeyStore trustStore = KeyStore.getInstance(KEY_STORE_TYPE_JKS);			InputStream ksIn = HttpsClientTrustStore.class.getClassLoader().getResourceAsStream(KEY_STORE_CLIENT_PATH);			InputStream tsIn = HttpsClientTrustStore.class.getClassLoader().getResourceAsStream(KEY_STORE_TRUST_PATH);			try {				keyStore.load(ksIn, KEY_STORE_PASSWORD.toCharArray());				trustStore.load(tsIn, KEY_STORE_TRUST_PASSWORD.toCharArray());			} finally {				try {					ksIn.close();				} catch (Exception ignore) {					ignore.printStackTrace();				}				try {					tsIn.close();				} catch (Exception ignore) {					ignore.printStackTrace();				}			}			SSLSocketFactory socketFactory = new SSLSocketFactory(keyStore, KEY_STORE_PASSWORD, trustStore);			Scheme sch = new Scheme(SCHEME_HTTPS, HTTPS_PORT, socketFactory);			httpClient.getConnectionManager().getSchemeRegistry().register(sch);			HttpGet httpget = new HttpGet(HTTPS_URL);			System.out.println("executing request" + httpget.getRequestLine());			HttpResponse response = httpClient.execute(httpget);			HttpEntity entity = response.getEntity();			System.out.println("----------------------------------------");			System.out.println(response.getStatusLine());			if (entity != null) {				System.out.println("Response content length: " + entity.getContentLength());				BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(entity.getContent()));				String text;				while ((text = bufferedReader.readLine()) != null) {					System.out.println(text);				}				bufferedReader.close();			}			EntityUtils.consume(entity);		} finally {			httpClient.getConnectionManager().shutdown();		}	}}

相关参考如下:

转载于:https://my.oschina.net/bbsyuemoncn/blog/670314

你可能感兴趣的文章
1、SpringBoot+Mybatis整合------简单CRUD的实现
查看>>
方法装饰器(Decorator)
查看>>
二叉查找树
查看>>
吴恩达机器学习笔记27-样本和直观理解2(Examples and Intuitions II)
查看>>
js:匿名函数/闭包前奏
查看>>
设计模式——工厂模式
查看>>
leetcode 322. 零钱兑换
查看>>
业务高速增长场景下的稳定性建设实战
查看>>
AngularJS笔记整理 指令交互 为不同的元素绑定方法
查看>>
CS0234: 命名空间“System.Web.Mvc”中不存在类型或命名空间名称“Ajax”(是否缺少程序集引用?)...
查看>>
CSS3学习手记(6) CSS3装换 2D转换
查看>>
winform 如何控制输入法
查看>>
jsp基础
查看>>
体会先哲的智慧
查看>>
动态规划系列 Leetcode 70. Climbing Stairs
查看>>
如何在服务层获取简单账表数据结果
查看>>
(转)Google Code SVN密码的解决之道(2010-11-14 20:36:51)转载▼
查看>>
表空间详解
查看>>
选择器代码
查看>>
swipe轮播插件零基础实用
查看>>