部署基于Apache的全站HTTPS加密

一晚上的摸索,成功实现了全站HTTPS (TLS)加密!

0 Why HTTPS?

0.1 HTTPS加密了什么?

HTTPS作为应用层加密,目前主要用于HTTP协议,其加密的对象是应用层报文,将加密过的报文作为数据段,递交给传输层进一步封装发送。

在发送方。SSL接受应用层的数据(如HTTP或IMAP报文),对数据进行加密,然后把加了密的数据送往TCP套接字。在接收方,SSL从TCP套接字读取数据,解密后把数据交给应用层。

(谢希仁 编著《计算机网络(第6版)》)

0.2 HTTPS相对HTTP安全在哪?

HTTP报文的加密传输,意味着:

  • 用户的访问请求完全保密,如:点击了什么链接,浏览了哪些页面;
  • 用户发送的信息完全加密,如:登陆时的账号、密码、验证码,评论、留言、在线邮件、聊天等;
  • 服务器发送给用户的响应数据完全加密,如:网页内容,API响应;
  • 页面无劫持,无篡改,如:中间人(特别是某些运营商,CDN),将无法篡改网页内容,插入广告、弹窗等恶意信息

另外,公共CA主持的RSA加密体系,包含服务器及客户身份鉴别,意味着:

  • 访问前会验证站点证书的合法性(是否由可信CA签发,是否处于有效期),校验授权域名和实际访问是否匹配,确保访问的一致性,防范了恶意跳转、钓鱼网站等风险。

1 获取SSL证书

SSL证书方面,因为我采用的是腾讯云的平台,所以很方便地申请到了TrustAsia DV SSL CA - G5证书,授信时长一年。审核速度挺快,10分钟左右就会有短信和站内信通知。

TrustAsia DV SSL CA - G5 核心参数如下:

  • 签名算法: sha256RSA
  • 公钥:RSA (2048 Bits)
  • 指纹算法: sha1
  • 颁布者:
    • CN = TrustAsia DV SSL CA - G5 OU = Domain Validated SSL OU = Symantec Trust Network O = TrustAsia Technologies, Inc. C = CN
  • 证书路径:
    • VeriSign
      • TrustAsia DV SSL CA - G5
        • heary.cn

Let's Encrypt 另外,获取SSL的方式众多,国际上大力推广https且获得众多企业资助的组织 Let's Encrypt ,签发快,且免费。

当然实在不行也可以采用Ubuntu下的openssl自行签发,但这不是公共CA。

Let's Encrypt


2 部署至服务器

2.1 上传证书及私钥文件

网上大多数的文档资料大概都是基于CentOS。

我服务器上部署的ubuntu server 16.04情况并不相同,经查 apache2 主路径位于 /etc/apache2/

内容如下:

1
2
3
4
5
6
7
8
9
10
11
-rw-r--r--   1 root   root    7114 3月  15 20:52 apache2.conf
drwxr-xr-x 2 root root 4096 3月 9 10:03 conf-available/
drwxr-xr-x 2 root root 4096 3月 9 10:03 conf-enabled/
-rw-r--r-- 1 root root 1782 3月 19 2016 envvars
drwxrwxr-x 2 ubuntu ubuntu 4096 3月 15 19:40 heary_cn-ssl/
-rw-r--r-- 1 root root 31063 3月 19 2016 magic
drwxr-xr-x 2 root root 12288 3月 8 18:04 mods-available/
drwxr-xr-x 2 root root 4096 3月 15 20:50 mods-enabled/
-rw-r--r-- 1 root root 320 3月 19 2016 ports.conf
drwxr-xr-x 2 root root 4096 3月 15 20:48 sites-available/
drwxr-xr-x 2 root root 4096 3月 15 20:48 sites-enabled/

首先,heary_cn-ssl/ 是我上传并保存根信息,公钥证书和私钥文件的目录。

  • *.crt*.key文件上传或移动至该目录
    • 注意:修改/etc/apache2目录可能需要sudo权限

2.2 开启Apache SSL模块

接下来,开启Apache2的SSL模块。

  • sudo a2enmod ssl
    • 安装ssl模块
    • 安装完成后,可以发现mods-enabled/ 目录中会多出ssl.confssl.load的软连接。

2.3 配置https 443端口站点

接着,开始部署443端口站点配置。

  • 转入站点配置路径:

    • cd sites-available/
  • 复制默认的SSL站点配置模板以便修改

    • sudo cp default-ssl.conf heary_cn-ssl.conf
  • 修改新建SSL站点配置文件以部署本机的HTTPS加密

    • sudo vim heary_cn-ssl.conf
    • 修改以下项目:
  • ```apacheconf # SSL Engine Switch: # Enable/Disable SSL for this virtual host. SSLEngine on

    A self-signed (snakeoil) certificate can be created by installing

    the ssl-cert package. See

    /usr/share/doc/apache2/README.Debian.gz for more info.

    If both key and certificate are stored in the same file, only the

    SSLCertificateFile directive is needed.

    SSLCertificateFile /etc/apache2/heary_cn-ssl/2_heary.cn.crt SSLCertificateKeyFile /etc/apache2/heary_cn-ssl/3_heary.cn.key

    Server Certificate Chain:

    Point SSLCertificateChainFile at a file containing the

    concatenation of PEM encoded CA certificates which form the

    certificate chain for the server certificate. Alternatively

    the referenced file can be the same as SSLCertificateFile

    when the CA certificates are directly appended to the server

    certificate for convinience.

    SSLCertificateChainFile /etc/apache2/heary_cn-ssl/1_root_bundle.crt

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94

    - 进入开启站点目录:

    - **`cd /etc/apache2/sites-enabled/ `**

    - 创建软链接,链接到刚刚新建且修改好的配置文件

    - **`sudo ln -s ../sites-available/heary_cn-ssl.conf 001-default.conf `**
    - **理解**:这就是Apache2使配置项生效的方式,在 `***-available/` 中创建或修改配置文件,在`***-enabled/`中软连接到配置文件使其生效。实际上阅读apache2.conf可以看到,其主配置文件中会去扫描、包含(include)`***-enabled/` 的内容,使其生效。这种方式确实更有条理!

    ### 2.4 重启服务, done!

    最后,重启Apache2服务。

    - **`sudo service apache2 restart`**
    - OK,完成到这一步后,站点就可以用 https 访问了!

    ------

    ## 3 测试和Debug

    通常,原有的站点或博客架构等都会出现https和http混合的现象,此时Chrome, Edge等浏览器是不会给你的站点打上安全,或是小锁的标记的,因为你的站点并非完全基于https,仍有安全隐患。

    此时,你需要检查网络流,修改你的调用链接。

    ### 3.1 以Gravatar为例

    例如,我的博客中使用了**Gravatar** 服务,而原始的调用链接是使用的国内的CDN镜像链接,还未提供https服务。

    首先,查官方文档:

    > [Image Requests - Gravatar - A Globally Recognized Avatar](http://en.gravatar.com/site/implement/images/)
    >
    >
    >
    > **Combining Parameters**
    > You may combine any and all of the above parameters to produce more complex/refined requests. For example, this URL will request a 200px by 200px Gravatar rated G or PG, defaulting to a 404 response (no image) if there is not one associated with the requested email hash:
    >
    > **`https://www.gravatar.com/avatar/205e460b479e2e5b48aec07710c08d50?s=200&r=pg&d=404`**
    >
    > **Secure Requests**
    > As you may have noticed, all of the above example URLs start with HTTPS. You don\'t need to do anything special to load Gravatars on a secure page, just make sure your Gravatar URLs start with \'https\' (or you can use the \'protocol-agnostic\' approach of starting the URLs with \'//\' which will automatically use \'https:\' on a secure page, or \'http:\' on an insecure one).

    源代码修改过程就略去了,总之,一番测试和修改后,实现了全站HTTPS安全加密。

    ------

    ## 4 更进一步——http强制跳转https

    https功能实现,但需要手动指定https访问,显然,体验还不够完美。

    如果能实现http访问自动跳转到https呢?

    ### 4.1 原理

    - 技术原理:Apache 强大的地址重写(rewrite)技术。

    ### 4.2 开启Apache地址重写模块

    首先,开启Apache的地址重写模块:

    - **`sudo a2enmode rewrite`**

    ### 4.3 配置apache2.conf文件

    配置主配置文件,apache2.conf

    - **`sudo vim /etc/apache2/apache2.conf`**

    准许网站目录地址重写:

    - ```apacheconf
    # Sets the default security model of the Apache2 HTTPD server. It does
    # not allow access to the root filesystem outside of /usr/share and /var/www.
    # The former is used by web applications packaged in Debian,
    # the latter may be used for local directories served by the web server. If
    # your system is serving content from a sub-directory in /srv you must allow
    # access here, or in any related virtual host.
    <Directory />
    Options FollowSymLinks
    AllowOverride None
    Require all denied
    </Directory>

    <Directory /usr/share>
    AllowOverride None
    Require all granted
    </Directory>

    <Directory /var/www/>
    Options Indexes FollowSymLinks
    AllowOverride All
    Require all granted
    </Directory>

  • 将目标路径 AllowOverride设为ALL。

4.4 配置.htaccess文件

然后在需要跳转的网站根目录,也就是80端口的网站根目录/var/www/html下创建一个.htaccess文件,如果目录下已经有.htaccess文件,则用vi或者其他编辑器打开,在最下面添加写入如下语句即可

1
2
3
RewriteEngine on
RewriteCond %{HTTPS} !on
RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI} [L,R]
  • 注意:网上相关文章中,在我的服务器环境中有以下问题:
    • RewriteCond %{SERVER_PORT} !^443$
      • 此项无效,不会引起页面跳转。
    • RewriteCond %{HTTPS} !=on
      • 语法错误,网站被forbidden。
    • 可能与系统环境和Apache版本有关。

4.5 重启Apache2服务

最后,重启Apache2服务,使安装的rewrite module及对主配置文件的修改生效。

  • sudo service apache2 restart
  • OK,完成到这一步后,站点就会自动跳转到https了。

5 参考链接

5.1 SSL证书

Let's Encrypt

5.2 服务器部署https

证书安装指引 - 腾讯云文档

Ubuntu下Apache开启rewrite模块 - Linux公社

Apache配置http访问转https - CSDN

Apache2.0实现https+Apache http访问转到https