https-- 给网站穿上护甲

本贴最后更新于 2711 天前,其中的信息可能已经时移世改

这篇博文主要总结 + 介绍一下如何使得个人网站通过 https 进行加密传输,更好的保证传输数据可以不被他人窃取

requirements

在开始之前,你最好先了解一下:

  1. 什么是 http 和 https
  2. https 的工作原理
  3. https 的安全性是如何保证的,有没有什么单点故障

对于 https 的了解,大致需要了解:

  1. TLS/SSL 协议是什么

  2. 证书和根证书

  3. 对称加密算法和非对称加密算法工作原理

这里推荐几个网址,可以帮助了解:

猫尾博客:HTTPS 工作原理

编程随想:数字证书及 CA 的扫盲介绍

编程随想:扫盲 HTTPS 和 SSL/TLS 协议

获得证书

了解了前面的信息之后,就可以知道,想要个人网站使用 https 的方式来访问,首要的任务就是如何获得有效的安全证书。在这里我们借助 Let's Encrypt 获得免费证书,这里是他的官网:Let's Encrypt

更具官网的描述,需要下载 Certbot 到个人服务器上,Certbot 是一个客户端,负责从 Let's Encrypt 获得安全证书

下载 Cerbot(命令行):

> wget https://dl.eff.org/certbot-auto
> chmod a+x ./certbot-auto

Certbot 提供了两种配置模式,standalone 和 webroot,由于我的博客本身搭建在 nginx 和 tomcat 的基础上,所以我选择 webroot 方式(if you are running a local webserver)。

更具官网所描述,需要为 webserver 配置 /.well-known/acme-challenge ,由于我使用 nginx,也就是保证 Certbot 的服务器可以通过 nginx 访问到这个文件夹

在 nginx 的 nginx.conf 文件中写入以下配置

server {
        listen          80;
        server_name     www.lincloud.me;

        location ^~ /.well-known/acme-challenge/ {
            default_type "text/plain";
            root /usr/local/nginx/html;
        }

        location = /.well-known/acme-challenge/ {
            return 404;
        }
        rewrite ^(.*) https://$server_name$request_uri permanent;
    }

然后直接切到 Certbot 的目录, 命令行下运行

> ./certbot-auto certonly --webroot -w /usr/local/nginx/html/ -d www.lincloud.me

这里说明一下,-w 后面的内容表示的是我 nginx 的安装目录,定位到其下的 html 目录,我们之前定义的 /.well-known/acme-challenge/ 临时文件夹就在这个位置。 -d 之后的内容表示的是需要申请证书的域名。

注意:在这里域名我使用 www 开头的二级域名,这样可以保证一级域名 zhuhonglin.website 同样受到证书的保护。(这是由于在这里,使用 Certbot 签发的是单域名证书)

当命令行出现 Congratulations 时表示成功获得了证书,你申请的域名已经得到认证。

配置

要想用户可以通过 https 访问,还需要对 webserver 进行一些配置

首先切到 nginx 的 conf 目录下进行配置

由于我希望用户访问

http://lincloud.me
http://www.lincloud.me
https://lincloud.me
https://www.lincloud.me

上述四个网址的时候都可以进入我的博客地址,并且走 https 的路径。

所以记下来的配置文件:

upstream backend {
   server localhost:8080; # Tomcat/Jetty 监听端口
}

server {
  listen       80;
  server_name  lincloud.me;
  rewrite ^(.*) https://www.$server_name$request_uri permanent;
 
}

server {
  listen          80;
  server_name     www.lincloud.me;

  location ^~ /.well-known/acme-challenge/ {
    default_type "text/plain";
    root /usr/local/nginx/html;
  }

  location = /.well-known/acme-challenge/ {
    return 404;
  }
  
  rewrite ^(.*) https://$server_name$request_uri permanent;
}

   
server {
  listen      443 ssl;
  server_name  lincloud.me;

  rewrite ^(.*) https://www.$server_name$request_uri permanent;
}

server {
  listen              443 ssl;
  server_name         www.lincloud.me;

  ssl_certificate /etc/letsencrypt/live/www.lincloud.me/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/www.lincloud.me/privkey.pem;
  ssl_trusted_certificate /etc/letsencrypt/live/www.lincloud.me/chain.pem;

  location ^~ /static/ {
    root    /usr/local/nginx/html/;
  }

  location / {
    proxy_pass http://backend$request_uri;
    proxy_set_header  Host $host:$server_port;
    proxy_set_header  X-Real-IP  $remote_addr;
    proxy_set_header X-Forwarded-Proto https;
    client_max_body_size  10m;
  }

}

对于其他的访问网址,我全部重定向到了 https://www.lincloud.me 所以现在就看最后一个 server 是怎么处理的,最后一个 server 的 location 中,申明了代理的地址是 localhost:8080 ,也就是我的 tomcat 的位置,这里是我博客的真正位置。

在这里对于 nginx 来说,和外网通讯使用的是 https,而和 tomcat 通讯使用的是 http,所以需要告诉 tomcat,虽然这是 http 的请求,但实际上已经被 https 代理了,因此在 tomcat 的配置文件中(server.xml)配置如下信息:

<Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="443"
               proxyPort="443"
               URIEncoding="UTF-8"
               />

配置之后的 host

<Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">
  	<Valve className="org.apache.catalina.valves.RemoteIpValve"
		remoteIpHeader="x-forwarded-for"
		remoteIpProxiesHeader="x-forwarded-by"
		protocolHeader="x-forwarded-proto"
            />
</Host>

nginx 和 tomcat 都同时配置 x-forwarded-proto 头信息,从而告知 tomcat 已被 https 代理。

到这里基本就完成,但因为我是使用 solo 搭建的博客

所以需要修改一下 latke.properties 的内容,才能正确显示博客

# Browser visit protocol
serverScheme=https
# Browser visit domain name
serverHost=www.lincloud.me
# Browser visit port, 80 as usual, THIS IS NOT SERVER LISTEN PORT!
serverPort=443

ok,至此全部配置完毕

重启 tomcat,重启 nginx。就可以通过 https 来访问自己的主页了。

最后提醒一下,安全证书的使用期限是 90 天,90 天以后又需要使用 Certbot 更新证书

我使用了自动更新的命令,目前还不知道是否生效

以下是手动更新命令,certbot 会自动帮你完成

> ./certbot-auto renew

  • NGINX

    NGINX 是一个高性能的 HTTP 和反向代理服务器,也是一个 IMAP/POP3/SMTP 代理服务器。 NGINX 是由 Igor Sysoev 为俄罗斯访问量第二的 Rambler.ru 站点开发的,第一个公开版本 0.1.0 发布于 2004 年 10 月 4 日。

    313 引用 • 547 回帖
  • HTTPS
    99 引用 • 274 回帖 • 3 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
  • K

    你 HTTPS 之后, 后台发布文章的页面有没有乱码啊?

    1 回复
  • someone756

    怎么会乱码呢?

    1 回复
  • K

    然而, 我后台发布文章的 发布页面文本编辑器乱码~ 头疼ing...