在Netty中支持https服务器
一、生成测试证书 1、安装Openssl sudo apt-get install openssl 2、生成证书( openssl生成证书 - fengmenghello的日志 - 网易博客) # 设定相关的目录 mkdir -p /etc/ssl mkdir -p /etc/ssl/private chmod og-rwx /etc/ssl/private mkdir -p /etc/ssl/certs mkdir -p /etc/ssl/crl mkdir -p /etc/ssl/newcerts # 设定 OpenSSL 设定档[3] mv /usr/share/ssl/openssl.cnf /etc/ssl ln -s /etc/ssl/openssl.cnf /usr/share/ssl/openssl.cnf # 设定 OpenSSL 设定档的位置[4] export OPENSSL_CONF="/etc/ssl/openssl.cnf" # 把 OpenSSL 设定档的位置加进 .bashrc 中[5] echo "# OpenSSL 设定档的位置" >> ~/.bashrc echo "export OPENSSL_CONF=\"/etc/ssl/openssl.cnf\"" >> ~/.bashrc # 制作乱数档[6] openssl rand -out /etc/ssl/private/.rand 1024 chmod og-rwx /etc/ssl/private/.rand 然后修改 /etc/ssl/openssl.cnf ,把这一行 dir = ./demoCA # Where everything is kept 改成这样 dir = /etc/ssl # Where everything is kept 制作最高层认证中心 (Root CA) 若你之前做过最高层认证中心,不要重做,不然原来签发的凭证,都会失效,都要重签。除非最高层认证中心自己过期、档案遗失、 Private Key 外泄,否则绝对不要重做最高层认证中心。 假设你要做的最高层认证中心叫做 myrootca 。 1. 制作 Private Key (及 Public Key ) 这里我们做一支新的 Private Key 。 Public Key 可由 Private Key 推得,所以不用特别去做。 请为最高层认证中心的 Private Key 设定一个适当的密码。 # 制作 RSA[7] Private Key openssl genrsa -des3 -out /etc/ssl/private/myrootca.key 2048 chmod og-rwx /etc/ssl/private/myrootca.key 2. 填写凭证申请书 凭证申请书,是把你的资料,和这个 Public Key 夹在一起,以便认证中心审核,签上签名用的。所以这个步骤,会问你这个 Key 的相关资料,包括国家、城市、单位名称、部门名称、凭证名称、联络人的信箱,以及申请的效期等等。请一一填写。详情请参考「什么是凭证?」。 若你要直接用最高层认证中心来直接当凭证用,凭证名称 (Common Name) 请用伺服器的全名 (www.abc.com) 。详情请参考「其她 SSL/X.509 凭证的做法」。 若不知如何填写,请参阅「如何填写凭证申请书」。 # 填写凭证申请书 openssl req -new -key /etc/ssl/private/myrootca.key -out /tmp/myrootca.req 3. 签发凭证 最高层认证中心因为没有上级了,没有人能给它签名,只能自己给自己签名。详情请参考「什么是最高层认证中心?」。 最高层认证中心最好永远不要过期。要是过期重签,所有原来它签发的凭证也都要重签,所有 SSL 程式也都要重新设定。所以我们效期签 7305 天(大约 20年)。若不设效期的话,预设是 30 天(一个月)。 签完凭证,凭证申请书就不用了,可以删掉。 # 自己给自己签名 openssl x509 -req -days 7305 -sha1 -extfile /etc/ssl/openssl.cnf -extensions v3_ca -signkey /etc/ssl/private/myrootca.key -in /tmp/myrootca.req -out /etc/ssl/certs/myrootca.crt # 删除凭证申请书 rm -f /tmp/myrootca.req 这样就好了。 Private Key 在 /etc/ssl/private/myrootca.key ,自己签名的 Public Key 凭证在 /etc/ssl/certs/myrootca.crt 。 myrootca.key 是 Private Key ,要小心存好保护,只有 root 才能读,权限建议 0444 。 myrootca.crt 是 Public Key 凭证,要尽量散出去,让大家用。最好放到内部网路上,或放到网站上,让大家自己下载,自己加进去。 制作伺服器用的凭证 假设你要做 myhost 的凭证: 1. 制作 Private Key (及 Public Key ) 这里我们做一支新的 Private Key 。 Public Key 可由 Private Key 推得,所以不用特别去做。 请先登入到要用凭证的那台伺服器上。 注意:伺服器的 Private Key 不要设密码,不然 SSL 伺服器程式启动的时候,一去读凭证和 Private Key ,就要问一次密码。每次重开机,依序启动每个伺服器程式的时候,一碰到要读 Private Key 的伺服器程式,都会停下来等键盘输入密码。要是放假没人,或伺服器放在 IDC 机房,从远端重开机或 Crash 后自行重开机,却当在那里等键盘敲密码,开不了机,那就不好玩了。 # 制作 RSA Private Key openssl genrsa -out /etc/ssl/private/myhost.key 2048 chmod og-rwx /etc/ssl/private/myhost.key 2. 填写凭证申请书 凭证申请书,是把你的资料,和这个 Public Key 夹在一起,以便认证中心审核,签上签名用的。所以这个步骤,会问你这个 Key 的相关资料,包括国家、城市、单位名称、部门名称、凭证名称、联络人的信箱,以及申请的效期等等。这里凭证名称 (Common Name) 要用伺服器的全名 (www.abc.com) ,其她请一一填写。详情请参考「什么是凭证?」。 若不知如何填写,请参阅「如何填写凭证申请书」。 # 填写凭证申请书 openssl req -new -key /etc/ssl/private/myhost.key -out /tmp/myhost.req 3. 用最高层认证中心签发凭证[8] 伺服器凭证的效期其实无所谓,过期重签一张就好了。 SSL 程式认的是认证中心,不是凭证,所以凭证签了就会生效,不用去设定 SSL 程式。不过为免重签的麻烦,我们效期还是签 3650 天(大约十年)。 签完凭证,凭证申请书就不用了,可以删掉。 # 签发凭证 openssl x509 -req -days 3650 -sha1 -extfile /etc/ssl/openssl.cnf -extensions v3_req -CA /etc/ssl/certs/myrootca.crt -CAkey /etc/ssl/private/myrootca.key -CAserial /etc/ssl/myrootca.srl -CAcreateserial -in /tmp/myhost.req -out /etc/ssl/certs/myhost.crt # 删除凭证申请书 rm -f /tmp/myhost.req 这样就好了。[9] Private Key 在 /etc/ssl/private/myhost.key ,要小心存好保护,只有 root 才能读,建议权限为 0400 ; Public Key 凭证在 /etc/ssl/certs/myhost.crt ,要尽量散出去,让大家用。这组 Public/Private Key 凭证可以做为 myhost 的 SSL 凭证,用在 HTTPS 或 POP3S/TLS/SSL 上。最好不要把档案搬到别的地方。你可以在设定档里,把凭证位置设定到这里。 Private Key 不要到处放,以免不小心忘记保护。
三、把证书导入KeyStore( Setting Up SSL with Netty
) 1、生成keystore keytool -keysize 2048 -genkey -alias tomcat -keyalg RSA -keystore tomcat.keystore
2、导入证书 keytool -import -alias root -keystore tomcat.keystore -trustcacerts –file myhost.crt
四、代码中使用HTTPS ChannelPipeline
pipeline
=
ch
.pipeline();
try
{ SSLContext
sslcontext
= SSLContext.getInstance(
"TLS"
);
KeyManagerFactory
kmf
= KeyManagerFactory.getInstance(
"SunX509"
);
KeyStore
ks
= KeyStore.getInstance(
"JKS"
);
String
keyStorePath
=
"/data/vhosts/youli_server/certs/tomcat.keystore"
;
String
keyStorePassword
=
"XXXXXXXX"
;
ks
.load(
new
FileInputStream(
keyStorePath
),
keyStorePassword
.toCharArray());
String
keyPassword
=
"XXXXXXXX"
;
kmf
.init(
ks
,
keyPassword
.toCharArray());
sslcontext
.init(
kmf
.getKeyManagers(),
null
,
null
);
SSLEngine
sslEngine
=
sslcontext
.createSSLEngine();
sslEngine
.setUseClientMode(
false
);
sslEngine
.setNeedClientAuth(
false
);
pipeline
.addLast(
new
SslHandler(
sslEngine
));
//务必放在第一位 logger
.info(
"initChannel: addLast SslHandler"
);
}
catch
(Exception
e
) { e
.printStackTrace();
}
pipeline
.addLast(
new
ReadTimeoutHandler(60,TimeUnit.
SECONDS
));
pipeline
.addLast(
new
WriteTimeoutHandler(60,TimeUnit.
SECONDS
));
pipeline
.addLast(
new
HttpRequestDecoder());
pipeline
.addLast(
new
HttpResponseEncoder());
pipeline
.addLast(
new
HttpObjectAggregator(1048576));
pipeline
.addLast(
new
ChunkedWriteHandler());
pipeline
.addLast(
new
XChannelHandler());
推荐阅读
- 热闹中的孤独
- 你到家了吗
- Shell-Bash变量与运算符
- JS中的各种宽高度定义及其应用
- 闲杂“细雨”
- 杜月笙的口才
- 2021-02-17|2021-02-17 小儿按摩膻中穴-舒缓咳嗽
- 深入理解Go之generate
- 赢在人生六项精进二阶Day3复盘
- 祖母走了