背景
HTTP协议是明文传输的,而HTTPS是经过了证书认证和秘钥加密解密,所以在传输上来说更加安全。简言之,HTTPS = HTTP + SSL/TLS。那么怎么让我们自己的网站可以通过HTTPS协议访问呢?可以通过nginx代理来实现。
步骤
HTTPS改造步骤很简单,分为四步:
- 安装nginx
- 本地生成证书和公私钥并上传服务器
- nginx配置代理和加密认证
- 重启nginx
1、安装nginx
nginx安装,在服务器上这里我们采取比较方便的rpm包的安装方式,上官方网站http://nginx.org/packages/centos/7/x86_64/RPMS/
。
因为我的服务器环境是centos7
操作系统,架构是x86_64
(可以使用uname -a
查看)。所以我选择nginx-1.20.0-1.el7.ngx.x86_64.rpm
这个包。
把包上传到服务器后使用rpm ivh nginx-1.20.0-1.el7.ngx.x86_64.rpm
,其他安装方式可自行度娘。
2、生成证书和公私钥
这里我们使用keytool生成,keytool是JDK自带的工具,大家也可以去一些云服务厂商,例如阿里云申请免费的HTTPS证书。JDK生成过程中会需要输入一些信息,比如单位名称和用户信息。keytool生成命令如下:
# 1、生成秘钥,在e盘新建keystore目录
keytool -genkey -alias uat -keypass password -keyalg RSA -keysize 1024 -validity 365 -keystore E:/keystore/uat.keystore -storepass password
# 2、导出证书
keytool -export -alias uat -keystore E:/keystore/uat.keystore -storepass password -rfc -file E:/keystore/uat.cer
效果如图示:
以上步骤完成后现在我们在E:/keystore/
目录下有两个文件uat.cer
和uat.keystore
。接下来需要用Java代码解析出秘钥:
try {
BASE64Encoder encoder = new BASE64Encoder();
//读取文件内容
FileInputStream is = new FileInputStream("E:/keystore/uat.keystore");
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(is, "password".toCharArray());
PrivateKey key = (PrivateKey) ks.getKey("uat", "password".toCharArray());
String encoded = encoder.encode(key.getEncoded());
System.out.println(encoded);
is.close();
} catch (Exception e){
e.printStackTrace();
}
复制控制台输出内容,将内容粘贴到自己新建的uat.key
的文件中,格式需要自己改下加上头和尾,下面给出我自己可用uat.key
的例子:
-----BEGIN RSA PRIVATE KEY-----
MIICdwIBADBNBgkqhkiG9w0BAQEFAASCAmEwggJdAgDAAoGBAJSd+qHE1gtSRcFBhFQdpTEyIdla
FcqPDMrV7PtHwu0SVeV8zn/0QPITrOxDJi8gnDL+aD8yD6gLAgukIV5FCsG+MOT/aCyIZC4Bs9pG
C9Wzfu2H8bo2o5DSgsiPSNBySYBadKKA9Q2yFZMIHreUNmprQ7pmce7AHUqqMAXIB8p7AgMBAAEC
gYBhs2mtJ4W/c5q/7Z5c3hBXQynVhc+Fln1GA1Sb7RVMXR1y/JWUsLJxclXgDFTx7nJBY9aMlRCN
3I6/sGrvWlzy+CGYjDpYG8UKLE2krM+FD+nVrziV0EREj/cyud5rrpVpHdN0qy+ab5238fKKdaJh
F8CeX1jlfjTZyXxo+moDQQJBCNmg6AnhcQ4+dIb/Od3ezlxzL+GUP6S6iOozDeSCIavcco/vS3i1
MuWWuLZjI4W56o2IjugAw81IgW7qlP33OjkCQQCu0hr3dULeP9Vf2W/Jq0tdtRMu0yVJem+IUNqg
yXRNEAF76xLsLamzInWeQvSrp+4olrKo92zuurB5xEwHJzpTAkAyYNg2KVTlijmpYn2/yasVpaiI
3Kua839sT6NAqYsn4KE4hpl++NsuYKSju/FmLHKKjvkd5cdtxwIHAhBNdiSpAkEAghpBEWqGIiq1
XEjQpfBB/XIV3aIrvLxOps8tdb2XPQatZBC1G6l8AqGhkO9ZcSpf1nsYaSECQ8RSM7y/rA8omwJB
ALuTMihYqJ9AdnlzwAucTy/vnYKb0yiMlWxNZ08hJVDGnenKbjr3kyy05PBRhA2sswCa3n+5y8e1
og0DLGxzZNA=
-----END RSA PRIVATE KEY-----
完成上述步骤我们得到了两个文件:uat.cer
和uat.key
。在nginx配置目录下/etc/nginx/
再新建一个文件夹keystore
,将两个文件上传到新建的文件下/etc/nginx/keystore/
。
3、配置nginx
列出nginx配置如下,部分配置可按自己需求进行更改,比如说我这里要将本地的8080服务改造HTTPS访问,配置如下:
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
# ssl on; #开启SSL
# ssl_certificate /etc/nginx/keystore/uat.cer; #SSL证书
# ssl_certificate_key /etc/nginx/keystore/uat.key; #SSL密钥
server{
listen 443 ssl;
server_name 127.0.0.1:8080;
# ssl on;
ssl_certificate /etc/nginx/keystore/uat.cer; #SSL证书
ssl_certificate_key /etc/nginx/keystore/uat.key; #SSL密钥
# limit request body size
client_max_body_size 100m;
location / {
proxy_pass http://127.0.0.1:8080;
# proxy_set_header X-Forwarded-For $remote_addr;
}
}
server {
listen 80;
server_name 127.0.0.1:8080;
#将请求转成https
rewrite ^(.*)$ https://$host$1 permanent;
}
}
IP可根据自己实际情况进行修改,在配置的时候只需要配置服务的IP和端口,url的后缀无需配置。上述配置就是把https://127.0.0.1:80
的请求代理到http://127.0.0.1:8080
。在访问的时候只要是https://127.0.0.1:80
起头的请求,nginx都会代理到http://127.0.0.1:8080
。
4、重启nginx
因为我们是rpm包安装的,nginx已经注册成服务,所以可以使用systemctl restart nginx
。如果是其他方式安装的可以使用nginx -s reload
重启nginx。下面我们访问https://127.0.0.1
就可以出现访问http://127.0.0.1:8080
一样的效果了!