tomcat & nginx 在 centos 环境下部署并启用 let’s encrypt
相信这也是一个比较常见或用得比较多的一个场景:
一台 CentOS 服务器,业务应用是用的 Tomcat ,前端用 Nginx 做转发,然后全站启用 SSL 。
下面讲讲大致的做法。
1、安装 tomcat
yum install tomcat
装完 tomcat 之后,可以装一些管理包,看自己需要了。
yum install tomcat-webapps tomcat-admin-webapps
然后配置 Tomcat Web 管理界面
vi /usr/share/tomcat/conf/tomcat-users.xml
将其中 admin 部分注释去掉
2、安装 nginx
在 CentOS 中,默认是不能使用 yum 来安装 nginx 的,按 nginx 官网的指引,如下:
建立 /etc/yum.repos.d/nginx.repo,内容如下:
[nginx] name=nginx repo baseurl=http://nginx.org/packages/centos/OSRELEASE/$basearch/ gpgcheck=0 enabled=1 # 如果是 centos 7.x ,则上面的 OSRELEASE 改成 7 。
3、防火墙上开放默认端口
firewall-cmd --add-port=8080/tcp --zone=public --permanent firewall-cmd --add-port=80/tcp --zone=public --permanent firewall-cmd --add-port=443/tcp --zone=public --permanent firewall-cmd --reload
# 开放 8080 是为了验证 tomcat 有没有启动起来。等到 nginx 的转发设置好之后,就可以关掉这个端口了。
4、安装 certbot
Let’s encrypt 官网推荐使用 certbot ,工具官网是: https://certbot.eff.org/ ,按上面的指引进行安装。
yum install epel-release yum install certbot
5、申请新证书
certbot certonly --email root@mydomain.com --webroot -w /usr/share/nginx/html -d ssl.mydomain.com -d www.mydomain.com -d test.mydomain.com # 可以让多个域名使用相同的证书,如无问题,会在 /etc/letsencrypt/live/ssl.mydomain.com/ 目录下生成 key 和证书文件。
6、修改 nginx 配置文件
server { listen 80; server_name ssl.mydomain.com; return 301 https://$server_name$request_uri; } server { listen 443 ssl http2; server_name ssl.mydomain.com; root /usr/share/nginx/html; ssl on; ssl_certificate /etc/letsencrypt/live/ssl.mydomain.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/ssl.mydomain.com/privkey.pem; ssl_session_timeout 10m; keepalive_timeout 70; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5; ssl_prefer_server_ciphers on; }
然后重启 nginx ,打开 https://ssl.mydomain.com/ ,如果没啥意外的话,就可以看到绿锁了。
7、将 tomcat 的端口请求发送到 nginx
server { listen 80; server_name ssl.mydomain.com; return 301 https://$server_name$request_uri; location / { proxy_pass http://127.0.0.1:8080/; proxy_set_header X-Real-IP $remote_addr; } } server { listen 443 ssl http2; server_name ssl.mydomain.com; root /usr/share/nginx/html; ssl on; ssl_certificate /etc/letsencrypt/live/ssl.mydomain.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/ssl.mydomain.com/privkey.pem; ssl_session_timeout 10m; keepalive_timeout 70; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5; ssl_prefer_server_ciphers on; location / { proxy_pass http://127.0.0.1:8080/; proxy_set_header X-Real-IP $remote_addr; } }
如果发现 nginx 转发 tomcat 出现 502 ,在 error 日志中显示:
failed (13: Permission denied) while connecting to upstream
等字样,则是 selinux 的问题,执行:
setsebool -P httpd_can_network_connect=1
就可以了。
在这里,可以留意一下,为了保证 tomcat 应用的安全,可以在 tomcat 中的配置文件中是设置它只监听本地的请求。在每个 tomcat 连接器里面添加一个 address 属性设置为 127.0.0.1 就可以了。
8、证书的更新
由于 let’s encrypt 证书有效期大约是 3 个月,所以可以用 crontab 来定时每个月的 1 号早上 3 点钟更新证书并重启 nginx 。
0 3 1 * * root certbot renew --quiet && service nginx restart
这里有个问题,如果 nginx 的首页做了自动跳转或转发,就会导致 web 根文件夹不能被 let’s encrypt 找到,进而无法验证域名所有权,也无法签发证书了,怎么弄呢?
在 nginx 的配置文件中添加一个地址如下:
location /.well-known/acme-challenge { root /var/www/letsencrypt; }
然后记得也要建立 /var/www/letsencrypt 这个目录,然后再执行
certbot certonly --email root@mydomain.com --webroot -w /var/www/letsencrypt -d ssl.mydomain.com
就可以了。