Total Pageviews

Wednesday 20 September 2017

看到网址前的小叹号,隐私就处在危险的境地-谈https的重要性

当你看到 Chrome 网址旁边出现了小叹号,一定不要输入自己重要的银行卡和账号密码。小叹号的出现,意味着与网站之间的连接是不安全的。网银,重要的邮箱服务,账号管理,都不应该出现小叹号。

网址旁边的小叹号提示站点仍在使用不安全的 HTTP 协议。

什么是 HTTPS,作用是什么?
如果网站仍然使用 HTTP,传输数据是不加密的,在数据流经的节点上网页内容就可能被其他人修改,植入恶意的代码和广告。

本来你访问网页A,中间人可以将一段恶意代码添加到网页A中,甚至用另一个网页B来替代原本你要访问的网站。

这项手段可以做极端的坏事,例如盗取你的账号密码,对财产直接造成损害。也能做一些“灰色”的变现收入,例如在他人网站上加广告,而网站的主人却不知情。如果你是联通用户,相信你对中国联通流量劫持,在他人网页中加广告已经恨之入骨。

HTTPS 相比 HTTP 多了一个 Secure,就是为了解决上面提到的 HTTP的局限。HTTPS 可以为我们提供:
机密性(confidentiality)
完整性(integrity)
身份验证(authentication)
用送信来举例,简单解释上面三个特性:确保给你送信的就是你认识的那个写信人(身份验证),并且信的内容是没有被篡改的(完整性),中间也没有人偷看(机密性)。

HTTPS 已取得阶段性胜利
根据 Google 自己的统计,HTTPS 的推广已经取得阶段性胜利,切换到 HTTPS 的网站在不断增长。到目前为止,使用 Chrome 桌面端的用户所访问的流量,已经有一半都使用了 HTTPS。

Google 还发布了“各大热门网站的 HTTPS 实施情况”报告,督促这些站点尽快使用安全的 HTTPS 连接。有趣的是一直宣称自己是中国第一大安全公司的 360.cn 出现在热门站点的头一个,并未使用 HTTPS。

Chrome 浏览器加大安全提示力度
为了让用户浏览网页更佳安全,Chrome 很早就在地址栏前方显示连接站点的安全性提示。但之前 Chrome 并不会将 HTTP 连接的站点标记为“不安全”站点,只是有一个灰色的感叹号提示可能的风险。

从 2017年1月 开始,Chrome 56 版本将修改安全提示,针对收集用户密码或信用卡却仍在使用 HTTP 的网站,标记为“不安全”站点。

灰色感叹号的图标旁边,将加入文字提示。从设计中我们可以看到,目前 Chrome 仍然给 HTTP 连接的站点中性的提示。Chrome 团队认为这样是不够的,中性提示并不能反映出 HTTP 连接的安全风险。

未来对非HTTPS站点将醒目提示
用户研究发现,灰色感叹号提示并不足以让用户理解站点是不安全的,同时用户也会对过于频繁出现的警告麻木。Chrome 计划未来强化不安全 HTTP 站点的提示,在地址栏使用醒目红色的标记。

在不久后版本中“隐身模式”下,就将采用红色来标记“不安全”的提示。因为“隐身模式”场景下,用户期望就是最大程度保护隐私。最终,Chrome 可能会对所有的 HTTP 站点都进行红色标记。

所有的站点未来都应该默认使用 HTTPS。

在国内复杂的网络环境下,需要时刻保持警惕。鼓励大家对象亲人、老人普及安全知识,拒绝流氓骗子。

https://transparencyreport.google.com/https/top-sites
---------

使用 HTTPS 保护网站的安全

什么是 HTTPS?

HTTPS(超文本传输安全协议)是一种互联网通信协议,可确保在用户的计算机与网站之间所传递的数据的完整性和机密性。用户在访问网站时,都希望自己的在线体验安全无虞且具有私密性。因此,我们建议您采用 HTTPS 来保护用户与您网站的连接(这与网站上的内容无关)。
使用 HTTPS 发送的数据可以通过传输层安全协议 (TLS) 得到保护。该协议可提供三层关键保护:
  1. 加密 - 加密交换数据,使其免受窥探。这意味着在用户浏览网站期间,没有人能够“听到”其会话内容,也无法在多个网页上跟踪其活动或窃取其信息。
  2. 数据完整性 - 不管是有意还是无意,在数据传输期间数据都无法被修改或损坏,也不会被检测。
  3. 身份验证 - 证明用户可与目标网站通信,这有助于保护用户免遭中间人攻击并建立用户信任,进而带来其他商业效益。

实施 HTTPS 时的最佳做法

使用强大的安全证书

在为网站启用 HTTPS 的过程中,您必须获得安全证书。证书由数字证书认证机构 (CA) 颁发,该机构会采取有关措施,确认您的网站地址是否确实属于您的组织,从而保护访问者免受中间人攻击。在设置证书时,您可以选择 2048 位密钥,来确保高级别的安全性。如果所持证书的密钥(1024 位)安全性较弱,请将其升级到 2048 位。选择网站证书时,请注意以下几点:
  • 从提供技术支持的可靠 CA 处获取证书。
  • 确定所需证书的类型:
    • 适用于单个安全源的单个证书(例如:www.example.com)。
    • 适用于多个已知安全源的多网域证书(例如www.example.com、cdn.example.com、example.co.uk)。
    • 适用于具有多个动态子域名的安全源的通配型证书(例如:a.example.com、b.example.com)。

使用服务器端 301 重定向

使用服务器端 301 HTTP 重定向将用户和搜索引擎重定向至 HTTPS 网页或资源。

确认 Google 能否抓取您的 HTTPS 网页并将其编入索引

  • 请勿通过 robots.txt 文件阻止抓取您的 HTTPS 网页。
  • 请勿在您的 HTTPS 网页中包含 noindex 元标记。
  • 使用 Google 抓取工具测试 Googlebot 能否访问您的网页。

支持 HSTS

我们建议 HTTPS 网站支持 HSTS。因为即使用户在浏览器地址栏中输入的是 http,HSTS 也会通知浏览器自动请求 HTTPS 页面。它还会通知 Google 在搜索结果中提供安全网址。这些都可以最大限度降低向用户提供不安全内容的风险。
要支持 HSTS,请使用支持 HTTP 严格传输安全 (HSTS) 的网络服务器并启用 HSTS。
HSTS 会增加回滚策略的复杂性。我们建议您按照以下方式启用 HSTS:
  1. 首先,滚动未启用 HSTS 的 HTTPS 页面。
  2. 开始发送 max-age 较短的 HSTS 标头。通过用户和其他客户端监控您的流量,并监控相关内容的效果,如广告。
  3. 逐步增加 HSTS 的 max-age。
  4. 如果 HSTS 不会对您的用户和搜索引擎产生负面影响,则您可以要求将网站添加到 Chrome HSTS 预加载列表中(如果需要的话)。

考虑使用 HSTS 预加载。

如果您启用了 HSTS,则可以选择支持 HSTS 预加载,以进一步提高安全性。要启用此功能,您必须在 HSTS 标头中设置 includeSubDomains 指令。子域名匹配的工作原理如下:如果网站 www.example.com 支持含 includeSubdomains 的 HSTS 标头,则它将与以下域名匹配:
网站网址:
www.example.com
includeSubDomains = true
www.example.com匹配
foo.www.example.com匹配
example.com不匹配
foo.example.com不匹配

避免以下常见问题

在使用 TLS 保护网站安全的整个过程中,请避免以下错误:
问题措施
过期的证书确保证书始终最新。
注册了错误网站名称的证书检查您是否已为证书注册了正确的主机名称。例如,如果您为www.example.com注册证书且您的网站配置为使用example.com,则会发生证书名称不匹配错误。
缺少服务器名称指示(SNI)支持确保网络服务器支持SNI且您的受众通常使用支持的浏览器。所有新式浏览器都支持SNI,但如果您需要支持旧版浏览器,则需要一个专用的IP。
抓取问题请勿使用robots.txt屏蔽抓取HTTPS网站。
索引编制问题尽可能允许通过搜索引擎将网页编入索引。避免使用 noindex 元标记。
旧版协议旧版协议易受攻击;请务必使用最新版 TLS 库并实施最新版协议。
混合型安全元素HTTPS网页上只嵌入HTTPS内容。
HTTP和HTTPS上的内容不同确保HTTP网站和HTTPS上的内容相同。
HTTPS上的HTTP状态代码错误确认网站是否返回正确的HTTP状态代码。例如,200 OK(页面可访问)或 404/410(页面不存在)。

更多提示

有关在网站上使用 HTTPS 网页的更多提示,请参阅 HTTPS 迁移常见问题解答

从 HTTP 迁移到 HTTPS

如果您将网站从 HTTP 迁移到 HTTPS,则 Google 会将其视为一次包含网址更改的网站迁移。这可能会暂时地影响您的部分流量。有关详情,请访问网站迁移概览页面
在 Search Console 中添加 HTTPS 属性;Search Console 分别处理 HTTP 和 HTTPS;这些属性的数据不会在 Search Console 中共享。因此,如果您有这两种协议的网页,则必须为每种协议单独设置 Search Console 属性。

更多信息

要详细了解如何在您的网站上实施 TLS,请参阅以下资源:
from https://support.google.com/webmasters/answer/6073543
------------

https://developers.google.com/web/fundamentals/security/encrypt-in-transit/enable-https ,(在服务器上启用 HTTPS)

-----------


Let's Encrypt 给网站加 HTTPS 完全指南


前段时间在北京联通3G移动网络下,发现自己的站点被联通劫持注入恶心的话费充值广告,决定让我的网站强制使用 HTTPS,避免 ISP 劫持。

使用 HTTPS 前的一些疑惑

现在是 2016 年,使用 HTTPS 已经不像几年前是一件昂贵的事情。当然我也是自己了解了一圈才消除了自己的疑惑,主要是:
  1. 我的网站(一个简单的博客)可能没必要使用 HTTPS 
  2. HTTPS 会不会让网站速度变慢? 
  3. HTTPS 需要花钱吧?证书好像不便宜 
  4. 配置和维护 HTTPS 代价很高
要回答这些问题,推荐大家去看一下 Google I/O 2016 的视频(Youtube):Mythbusting HTTPS: Squashing security’s urban legends - Google I/O 2016
视频里把所有问题都详细一一解答,强烈推荐大家把视频看完。
我简单总结:
  1. 每个网站都应该用 HTTPS,就算是全静态站点也同样如此,运营商劫持严重干扰访问者的体验 
  2. 有几项技术可以提高 HTTPS 的性能,包括 Strict Transport SecurityTLS False Start 和 HTTP/2 ,这些技术让 HTTPS 速度不慢,某些情况下会甚至更快 
  3. HTTPS 针对个人单个(或者几个)域名的使用来说,已经是免费的 
  4. 配置和维护 HTTPS 异常简单,Let's Encrypt 这个项目通过自动化把事情简单化了

有哪些靠谱的免费 HTTPS 证书提供商?

选择证书提供商有3个主要考量:1. 浏览器和操作系统支持程度 2. 证书类型 3. 维护成本

1. 浏览器和操作系统支持程度

基本你能查到的热门证书提供商,支持程度都不会太差。例如 Let's Encrypt 的支持可以访问:Which browsers and operating systems support Let’s Encrypt
可以看到,Android 2.3.6 以上,Firefox 2.0 以上,Windows Vista 以上,iOS 3.1 以上,Google Chrome全平台都是支持的。这一点就不用太担心了,看你你的网站受众情况来决定。对于我来说,我完全不在乎 Windows XP 的 IE 用户。

2. 证书类型

HTTPS 证书分为3类, 1. DV 域名验证证书 2. OV 组织机构验证证书 3. EV 增强的组织机构验证证书。每类证书在审核和验证方面要求严格程度不同,浏览器会在地址栏给予不同证书不一样的展现。
一般个人使用DV证书完全够了,浏览器表现为地址栏前会有绿色的小锁。下面聊到的免费证书都是 DV 域名验证证书。

3. 维护成本

推荐 Let's Encrypt,虽然有效期只有3个月,但可以用 certbot 自动续期,完全不受影响。而且 Let's Encrypt 因为有了 certbot 这样的自动化工具,配置管理起来非常容易。

生成 Let's Encrypt 证书

Let's Encrypt 证书生成不需要手动进行,官方推荐 certbot 这套自动化工具来实现。3步轻松搞定:
  1. 下载安装 certbot (Let’s Encrypt项目的自动化工具) 
  2. 创建配置文件 
  3. 执行证书自动化生成命令
下面的教程运行在 Arch Linux 上,其他操作系统也大同小异。你可以在 certbot 网站上,选择你的 Web Server 和 操作系统,就能看到对应的安装和配置教程。

1. 下载安装 certbot

在 Arch Linux 上,安装很简单:
$ sudo pacman -Syu
$ sudo pacman -S certbot

2. 创建配置文件

先创建存放配置文件的文件夹:
$ sudo mkdir /etc/letsencrypt/configs
编辑配置文件:
$ sudo vim /etc/letsencrypt/configs/example.com.conf
把 example.com 替换成自己的域名,配置文件内容:
# 写你的域名和邮箱
domains = example.com  
rsa-key-size = 2048  
email = your-email@example.com  
text = True

# 把下面的路径修改为 example.com 的目录位置
authenticator = webroot  
webroot-path = /var/www/example  
这里需要解释一下,上面配置文件用了 webroot 的验证方法,这种方法适用于已经有一个 Web Server 运行中的情况。certbot 会自动在 /var/www/example 下面创建一个隐藏文件 .well-known/acme-challenge ,通过请求这个文件来验证 example.com 确实属于你。外网服务器访问 http://www.example.com/.well-known/acme-challenge ,如果访问成功则验证OK。
我们不需要手动创建这个文件,certbot 会根据配置文件自动完成。

3. 执行证书自动化生成命令

一切就绪,我们现在可以运行 certbot 了。
$ sudo certbot -c /etc/letsencrypt/configs/example.com.conf certonly

## 片刻之后,看到下面内容就是成功了
IMPORTANT NOTES:  
 - Congratulations! Your certificate and chain have been saved at /etc/letsencrypt/live/example.com/fullchain.pem.
如果运行顺利,所有服务器所需要的证书就已经生成好了。他们被放在了 /etc/letsencrypt/live/example.com/ 下:
$ ls /etc/letsencrypt/live/example.com/
cert.pem #server cert only  
privkey.pem #private key  
chain.pem #intermediates  
fullchain.pem #server cert + intermediates  

配置 Nginx 加入证书

到这里已经成功一大半了,只需要配置 Nginx 支持刚刚生成的证书。而且这个配置有最佳实践可以参考,访问:Mozilla SSL Configuration Generator,这是 Mozilla 搞得一个 HTTPS 配置文件自动生成器,支持 Apache,Nginx 等多种服务器。按照这个配置文件,选择 Intermediate 的兼容性。这里生成的配置文件是业界最佳实践和结果,让 Nginx 打开了各种增加安全性和性能的参数。
默认配置文件是这样的:
server {  
    listen 80 default_server;
    listen [::]:80 default_server;

    # Redirect all HTTP requests to HTTPS with a 301 Moved Permanently response.
    return 301 https://$host$request_uri;
}

server {  
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    # certs sent to the client in SERVER HELLO are concatenated in ssl_certificate
    ssl_certificate /path/to/signed_cert_plus_intermediates;
    ssl_certificate_key /path/to/private_key;
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:50m;
    ssl_session_tickets off;

    # Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits
    ssl_dhparam /path/to/dhparam.pem;

    # intermediate configuration. tweak to your needs.
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS';
    ssl_prefer_server_ciphers on;

    # HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months)
    add_header Strict-Transport-Security max-age=15768000;

    # OCSP Stapling ---
    # fetch OCSP records from URL in ssl_certificate and cache them
    ssl_stapling on;
    ssl_stapling_verify on;

    ## verify chain of trust of OCSP response using Root CA and Intermediate certs
    ssl_trusted_certificate /path/to/root_CA_cert_plus_intermediates;

    resolver <IP DNS resolver>;

    ....
}
请根据自己的服务配置修改和添加内容,重点只需要关注6行
server {  
    listen 443 ssl http2;
    ....
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    ssl_dhparam /etc/nginx/ssl/dhparam.pem;

    ssl_trusted_certificate /etc/letsencrypt/live/example.com/root_ca_cert_plus_intermediates;

    resolver <IP DNS resolver>;
    ....
}
这6行中,部分文件还不存在,逐个说明。
首先是第一行 listen 443 ssl http2;  作用是启用 Nginx 的 ngxhttpv2_module 模块支持 HTTP2,Nginx 版本需要高于 1.9.5,且编译时需要设置 --with-http_v2_module。Arch Linux 的 Nginx 安装包中已经编译了这个模块,可以直接使用。如果你的 Linux 发行版本中的 Nginx 并不支持这个模块,可以自行 Google 如何加上。
ssl_certificate 和 ssl_certificate_key ,分别对应 fullchain.pem 和 privkey.pem,这2个文件是之前就生成好的证书和密钥。
ssl_dhparam 通过下面命令生成:
$ sudo mkdir /etc/nginx/ssl
$ sudo openssl dhparam -out /etc/nginx/ssl/dhparam.pem 2048
(可选)ssl_trusted_certificate 需要下载 Let's Encrypt 的 Root Certificates,不过根据 Nginx 官方文档 所说,ssl_certificate 如果已经包含了 intermediates 就不再需要提供 ssl_trusted_certificate,这一步可以省略:
$ cd /etc/letsencrypt/live/example.com
$ sudo wget https://letsencrypt.org/certs/isrgrootx1.pem
$ sudo mv isrgrootx1.pem root.pem
$ sudo cat root.pem chain.pem > root_ca_cert_plus_intermediates
resolver 的作用是 “resolve names of upstream servers into addresses”, 在這個配置中,resolver 是用來解析 OCSP 服務器的域名的,建议填写你的 VPS 提供商的 DNS 服务器,例如我的 VPN 在 Linode,DNS服务器填写:
resolver 106.187.90.5 106.187.93.5;
Nginx 配置完成后,重启后,用浏览器测试是否一切正常。
$ sudo systemctl restart nginx
这时候你的站点应该默认强制使用了 HTTPS,并且浏览器地址栏左边会有绿色的小锁.

自动化定期更新证书

Let's Encrypt 证书有效期是3个月,我们可以通过 certbot 来自动化续期。
在 Arch Linux 上,我们通过 systemd 来自动执行证书续期任务。
$ sudo vim /etc/systemd/system/letsencrypt.service
[Unit]
Description=Let's Encrypt renewal

[Service]
Type=oneshot  
ExecStart=/usr/bin/certbot renew --quiet --agree-tos  
ExecStartPost=/bin/systemctl reload nginx.service  
然后增加一个 systemd timer 来触发这个服务:
$ sudo vim /etc/systemd/system/letsencrypt.timer
[Unit]
Description=Monthly renewal of Let's Encrypt's certificates

[Timer]
OnCalendar=daily  
Persistent=true

[Install]
WantedBy=timers.target  
启用服务,开启 timer:
$ sudo systemctl enable letsencrypt.timer
$ sudo systemctl start letsencrypt.timer
上面两条命令执行完毕后,你可以通过 systemctl list-timers 列出所有 systemd 定时服务。当中可以找到 letsencrypt.timer 并看到运行时间是明天的凌晨12点。
在其他 Linux 发行版本中,可以使用 crontab 来设定定时任务,自行 Google 吧。

用专业在线工具测试你的服务器 SSL 安全性

Qualys SSL Labs 提供了全面的 SSL 安全性测试,填写你的网站域名,给自己的 HTTPS 配置打个分。
如果你完全按照我上面教程配置,遵循了最佳实践,你应该和我一样得分是 A+.
这意味着你启用了HTTPS,现在足够的安全,并且使用了最新技术,保证了性能。
--------

让你的nginx网站得到A+


nginx 配置

将 nginx 配置的 server block 改成如下内容:
server {
    listen      80 default_server;
    listen      [::]:80 default_server;
    server_name <domain_name>;
    root        /path/to/your/site;
}
启动 nginx:
~> sudo systemctl enable nginx --now
接着签证书:
~> sudo certbot --nginx
certbot会修改nginx配置,因此需要以root身份运行。另外这个nginx插件会读nginx配置判断域名,因此在nginx配置的server_name处应该填入完整的域名。 接着会有一个交互式的界面确认一些信息,顺序填写就好。
最后重启nginx:
~> sudo systemctl restart nginx

nginx 调优

这个时候 https 应该已经配置好了,不过强迫症表示在 ssllabs 只能拿到B不太开心。
关于如何调优,在这里有完整的介绍,下面是我对 nginx 配置作的改动:
  1. listen 443 ssl;改成listen 443 ssl http2;:添加 HTTP/2 支持。
  2. 加上 listen [::]:443 ssl http2:certbot 的 nginx 似乎没有考虑到 IPv6 的支持,所以缺了这一行。
  3. ssl_ciphers改成"EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH":表示不想支持IE6。
  4. 加上Strict-Transport-Security "max-age=63072000; includeSubdomains; ";这一行:HSTS(如果不想把http重定向加到https可以不加)。
  5. 自制一个dhparam,加到配置里。
接着重启 nginx 即可,现在能拿到 A+ 了,在这里也能测试到有 http2 支持了。

No comments:

Post a Comment