月度归档:2018年01月

CentOS 7 编译安装nginx并启用TLS1.3

暂时转向caddy,caddy已经可以支持tls v1.3

更新日志

20180708
OpenSSL于2018年6月8日更新了关于tls 1.3的说明,见此wiki,本文按新wiki修改更新;
主要变化有:OpenSSL目前同时支持“draft-26”, "draft-27" and "draft-28"草案;简化流程,编译时默认开启tls 1.3,无需enable参数;加密算法表达的更新;
Chrome canary 69.0.3484.0 和 Firefox Nightly 63.0a1支持tls1.3 Draft 28。
20180411
Firefox Nightly 61.0a1支持tls1.3 Draft 26。
20180404
IESG批准将TLS 1.3 Draft 28作为TLS version 1.3 的建议标准;
至20180404,Openssl支持的标准为Draft 26。
20180312
Chrome 65正式版已经发布,支持tls1.3 Draft 23。
20180207
修正部分错误。
如果TLSv1.3如期发布,OpenSSL 1.1.1 将于2018年4月17日面向公众发布。对于服务器来说,我还是喜欢CentOS,支持周期很长,折腾一次可以用很长世间,因此以下记录一下在基于LNMP的CentOS 7 系统上启用TLSv1.3的过程。

1 升级系统

yum update

升级后的系统版本为:

cat /etc/centos-release CentOS Linux release 7.5.1804 (Core)

2 安装官方mainline版的nginx

通过官方源安装nginx的目的是:
自动生成nginx的配置文件,减少大量的工作;
获取nginx的编译参数。

配置源:

vi /etc/yum.repos.d/nginx.repo

写入如下内容:

[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/mainline/centos/7/$basearch/
gpgcheck=0
enabled=1

安装nginx:

yum install nginx -y

查看nginx版本:

nginx -v nginx version: nginx/1.15.1

获取编译参数:

nginx -V nginx version: nginx/1.15.1 built by gcc 4.8.5 20150623 (Red Hat 4.8.5-28) (GCC) built with OpenSSL 1.0.2k-fips 26 Jan 2017 TLS SNI support enabled configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie'

修改nginx源,将enabled=1改为enabled=0,防止yum update时nginx被更新掉

vi /etc/yum.repos.d/nginx.repo [nginx] name=nginx repo baseurl=http://nginx.org/packages/mainline/centos/7/$basearch/ gpgcheck=0 enabled=0

3 编译nginx

安装可能用到的依赖:

yum install -y git gcc gcc-c clang automake make autoconf libtool zlib-devel libatomic_ops-devel pcre-devel openssl-devel libxml2-devel libxslt-devel gd-devel GeoIP-devel gperftools-devel  perl-devel perl-ExtUtils-Embed

获取源码:

git clone https://github.com/nginx/nginx.git
git clone https://github.com/openssl/openssl.git
git clone https://github.com/grahamedgecombe/nginx-ct.git

nginx-ct是启用证书透明度(Certificate Transparency)策略的模块。为了启用Certificate Transparency和TLSv1.3,需要额外加入如下编译参数:

--add-module=../nginx-ct/ --with-openssl=../openssl/

加在官方编译参数后面,简单修改形成完整的编译参数:

auto/configure --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie' --add-module=../nginx-ct/ --with-openssl=../openssl/

进入nginx源码目录,并输入如上完整的编译参数。
开始编译:

make

查看编译好的nginx信息:

./objs/nginx -v nginx version: nginx/1.15.2

备份已经安装好的官方mainline版,安装编译版:

mv /usr/sbin/nginx /usr/sbin/nginx.1.15.1.20180708.official.mainline
cp ./objs/nginx /usr/sbin/

4 修改nginx配置文件内的ssl_protocols和ssl_ciphers,默认启用TLSv1.3的前三项常用的加密算法

...
ssl_protocols          TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
ssl_ciphers            EECDH+CHACHA20:ECDHE+aECDSA+CHACHA20:ECDHE+aRSA+CHACHA20:ECDHE+aECDSA+AESGCM:ECDHE+aRSA+AESGCM:ECDHE+aECDSA+AES256+SHA384:ECDHE+aRSA+AES256+SHA384:ECDHE+aECDSA+AES256+SHA:ECDHE+aRSA+AES256+SHA;
...

重启nginx服务以使修改生效:

systemctl restart nginx

5 测试TLSv1.3是否生效

5.1 使用testssl工具
git clone --depth 1 https://github.com/drwetter/testssl.sh.git
cd testssl.sh
./testssl.sh --help

命令为(coldawn.com需要换成自己的域名):

./testssl.sh -p coldawn.com ... Testing protocols via sockets except SPDY+HTTP2 SSLv2 not offered (OK) SSLv3 not offered (OK) TLS 1 offered TLS 1.1 offered TLS 1.2 offered (OK) TLS 1.3 offered (OK): draft 28, draft 27, draft 26 NPN/SPDY h2, http/1.1 (advertised) ALPN/HTTP2 h2, http/1.1 (offered) ...

详细的情况,用大写的P作为参数:

./testssl.sh -P coldawn.com

 Testing server preferences

 Has server cipher order?     yes (OK)
 Negotiated protocol          TLSv1.3
 Negotiated cipher            TLS_AES_256_GCM_SHA384, 253 bit ECDH (X25519)
 Cipher order
    TLSv1:     ECDHE-RSA-AES256-SHA
    TLSv1.1:   ECDHE-RSA-AES256-SHA
    TLSv1.2:   ECDHE-RSA-CHACHA20-POLY1305 ECDHE-RSA-AES256-GCM-SHA384 ECDHE-RSA-AES128-GCM-SHA256 ECDHE-RSA-AES256-SHA384 ECDHE-RSA-AES256-SHA
    TLSv1.3:   TLS_AES_256_GCM_SHA384 TLS_CHACHA20_POLY1305_SHA256 TLS_AES_128_GCM_SHA256
5.2 使用现代浏览器

Chrome canary 69.0.3484.0 和 Firefox Nightly 63.0a1已经支持tls1.3 Draft 28。

HTML网页中插入经base64编码的中文(Data URLs)的一个方法

Data URLs出现的目的是将经base64编码的小文件直接插入文档中。相对常用的用法是将小图片转换为Data URLs直接嵌入到网页中。
有时候我们在编写网页时写入中文会出现乱码,这时我们想到了Data URLs。比如说,有人问:把base64编码格式的中文显示在HTML中,该怎么做,回答者认为是不可以的。
其实,方法也不是没有。举个例子,我们想在网页中以Data URLs方式写入“中文字符”四个字,其过程是:
1 将“中文字符”四个字利用在线编码工具进行base64编码,编码后为

5Lit5paH5a2X56ym

2 按照示例,添加“前缀”、“类型”后,Data URLs为:

data:text/plain;base64,5Lit5paH5a2X56ym

3 将上述URL复制到Chrome的地址栏进行解码,发现为乱码:

涓枃瀛楃

4 原因是对于text文本,Data URLs默认的编码类型是US-ASCII。所以对于中文文本来说,需要将编码类型注明为UTF-8,Data URLs的正确写法是:

data:text/plain;charset=UTF-8;base64,5Lit5paH5a2X56ym

此时再复制到Chrome地址栏,则会正常显示其内容:

中文字符

5 直接将上述Data URLs数据插入HTML网页中,不会解析为“中文字符”,而是直接显示这串数据。这时需要使用到一个HTML5引入的标签:embed,其包含一个类型type的属性。写法为:

<embed src="data:text/plain;charset=UTF-8;base64,5Lit5paH5a2X56ym" type="text/plain" />

将上述Data URLs数据插入HTML网页中则会正确解析为“中文字符”。

上述方法可以把base64编码格式的中文显示在HTML中,但是其显示样式还需要进一步调整。

在 Mac 或 PC 上更改Apple ID 国家或地区为美国的方法

将iCloud数据放到中国有国家安全和苹果方面的考虑,云上贵州也会为当地带来经济增长。大家都注意到了隐私声明:《iCloud(由云上贵州运营)条款与条件》中有意思的地方之一:

您理解并同意,苹果公司和云上贵州有权访问您在此服务中存储的所有数据,包括根据适用法律向对方和在彼此之间共享、交换和披露所有用户数据(包括内容)的权利。

虽然明知早已没有隐私,但是仍有人以为更改国家和地区就可以避免将iCloud数据存放在云上贵州从而避免所有数据被有权访问。有些人尝试了但没有成功,卡在付款方式那里,没有“无”这个选项。

付款信息为何没有“无”

苹果官方给出了“如果您无法在编辑 Apple ID 付款信息时选取“无””的解释和解决方案,简要的记录如下:
1 如果您有未付余款或应付账款
您必须先付清余款,然后才能选择“无”作为付款方式。
2 如果您有自动续订的订阅
除非您取消订阅,否则可能无法选择“无”。
3 如果您是首次使用 iTunes Store 或 App Store
如果您是首次通过现有的 Apple ID 来使用商店,则必须提供付款方式。创建帐户后,您可以将付款信息更改为“无”。
4 如果您不在创建的 Apple ID 所属的国家或地区
如果您是首次创建 Apple ID,而且创建时身处这个 Apple ID 所属的国家或地区之外的地方,那么您必须输入付款方式。这种情况下,您无法选择礼品卡或商店余额作为付款方式。
例如,如果您身处美国,但所创建的 Apple ID 的账单邮寄地址却在中国,那么您将无法选取“无”作为付款方式。
5 如果您更改了帐号所属国家或地区
当您更改现有 Apple ID 所属的国家或地区时,必须提供付款方式并更新您的账单选项。这种情况下,您无法选择礼品卡或商店余额作为付款方式。更改国家或地区后,如果您要移除付款方式,可将付款信息更改为“无”。
6 如果您是“家人共享”的一员
当您设置“家人共享”时,家庭组织者必须提供有效的付款方式。这个付款方式将用于家庭成员发起的所有购买,且只有家庭组织者可以更改。
如果您要停止使用“家人共享”,可以解散您的家庭群组。

可行的做法

参照上面的条目逐一排查,该付清的付清,该取消的取消,该解散的解散,然后全程使用美国IP,按照官方提供的方法:在 Mac 或 PC 上更改您的国家或地区,使用iTunes进行操作。
1 打开iTunes,登陆Apple ID。
2 从您电脑屏幕顶部或 iTunes 窗口顶部的菜单栏中,选取“帐户”>“查看我的帐户”。
3 在“帐户信息”页面上,点按“国家或地区”右边的“更改国家或地区”。
4 从“选择国家或地区”菜单中,选择新的国家或地区,比如:美国。
5 下拉阅读条款与条件以及 Apple 隐私政策,两次点按“同意”。
6 在付款信息页面,付款方式选择无,付款地址找一个免税州,比如俄勒冈州(Oregon)的某地址,点按“继续”完成更改。

注:上文主要的讲的是更改国家和地区的方法;
如果是想创建美国Apple ID的话,那么还是全程美国IP,在iTunes中下载一个免费应用,按照提示操作就可以了。

解决Chrome书签管理器无法打开的问题

1 出现的问题

谷歌浏览器Chrome的扩展程序书签管理器(Bookmark Manager)在Chrome某次版本升级后就打不开了。具体情况是,点击Chrome状态栏右侧“三个竖点” > “书签(Bookmarks)” > “书签管理器(Bookmark manager)”,会出现如下提示:

eemcgdkfndhakfknompkggombfjjjeno is blocked

Requests to the server have been blocked by an extension.

Try disabling your extensions.

ERR_BLOCKED_BY_CLIENT
eemcgdkfndhakfknompkggombfjjjeno 已被屏蔽

对服务器的请求已遭到某个扩展程序的阻止。

尝试停用扩展程序。

ERR_BLOCKED_BY_CLIENT

2 解决的方法

在地址栏中输入:

chrome://flags/#enable-md-bookmarks

将默认的“Default”改为“Disabled”,重启浏览器,问题解决。
原因是Material Design书签功能目前存在bug,关闭就好了。

使用qBittorrent时遇Kernel Power 事件 ID 41 错误致windows 10 重启一例

1 问题描述

环境:windows 10 64位操作系统,博通ac网卡
之前用IDM下载文件,看电影等任何操作,一切正常。但使用qBittorrent下载种子时,短则几秒,长也不到一分钟,电脑就直接黑屏重启。且没有蓝屏错误代码出现。

2 问题分析

简要说一下排除步骤吧。

2.1 事件查看器(Event Viewer)

因为没有蓝屏代码,首先查看Windows X 系统自带的事件查看器,在Windows 日志 > 系统下,可以看到一条红色叹号图标的“关键(Critical)”错误,类似如下:

系统已在未先正常关机的情况下重新启动。如果系统停止响应、发生崩溃或意外断电,则可能会导致此错误。
The system has rebooted without cleanly shutting down first. This error could be caused if the system stopped responding, crashed, or lost power unexpectedly.
…
来源(s):       Kernel-Power
事件 ID(E):    41
级别(L):       关键

按照Kernel-Power 41 检索,发现微软有一篇技术文档来说明此问题,有点符合场景三的描述:Scenario 3: The system randomly restarts and no Stop error BugcheckCode is listed, or the computer is completely unresponsive (hard hang)。系统随机重启,且未列出关机的相关错误代码,或者电脑完全没有反应(硬件故障)。可能原因是:超频,内存问题,电源问题,过热。显然都不太是。
此外有人建议更新声卡驱动来解决这个问题,经测试无效。

2.2 Windows 10 调试工具(Debugging Tools for Windows (WinDbg, KD, CDB, NTSD))

微软提供了一个新的诊断工具:Windows 调试器 (WinDbg),我们按方法三来安装一个独立运行的版本,在安装Windows 10 SDK时仅勾选 Debugging Tools for Windows来安装。
微软该技术文档,将系统错误日志Minidump(位置在“C:\Windows\Minidump\”文件夹中)复制到桌面,打开WinDbg,在其菜单栏依次点击File > Open Crash Dump…来打开dmp文件。
待出现Bugcheck Analysis信息后,点击 !analyze -v来进一步分析错误原因。可以看到比较可疑的地方:

…
Probably caused by : bcmwl63a.sys ( bcmwl63a+8ef6f )
…
6: kd> .trap 0xffff8f805fd6a5d0
NOTE: The trap frame does not contain all registers.
Some register values may be zeroed or incorrect.
…

看起来是wifi驱动bcmwl63a.sys导致的问题,这是一个老生常谈的问题了。

2.3 更新WIFI驱动

出问题的Wifi网卡是博通的ac网卡BCM4352,驱动是Windows 10自带的:

驱动提供商:     Broadcom
驱动日期:       7/6/2015
驱动版本:       7.35.290.0

找到比较新的是联想提供的这个版本:

WLAN Driver (Atheros, Realtek, Broadcom) for Windows 7 (64-bit) - Lenovo B41-35, B51-35

Document ID: DS103113
Release Date: 12/28/2017

下载7gb301wf.exe并双击释放到c盘后,通过在设备管理器中右键更新驱动,并指向该文件夹来更新驱动,升级后的驱动是如下版本:

驱动提供商:     Broadcom
驱动日期:       7/20/2015
驱动版本:       7.35.295.2

打开qbittorrent测试,真的是好了一会会,没有一打开几秒钟就崩溃。但是一个多小时后问题又出现了,还是这个bcmwl63a.sys的错误。

2.4 禁用tereto(IPv6)

网上有使用bittorrent时出现该问题的情况,但更新Wifi驱动或者使用旧版驱动后问题依旧。不过在回帖中technonymous提到禁止teredo (ipv6)可解决该问题,以管理员方式运行命令行提示符,输入如下命令:

netsh interface teredo set state disabledok.

暂时正常,仍在观察中。
原因可能是因为qbittorrent等bt软件需要发送接收大量udp包,与tereto隧道兼容不好所致,尽管根本没有IPv6。微软有一篇文档提到:因为操作系统无法分配足够的堆栈空间为 UDP 数据包有许多内核过滤器 driversinstalled 时,将出现此问题。该文档中有一句:UNEXPECTED_KERNEL_MODE_TRAP,而在我的WinDbg中也有一行:6: kd> .trap 0xffff8f805fd6a5d0,不知是否有关。

wordpress博客启用 UpdraftPlus作者的两步验证插件后登陆时不跳出验证码界面的解决办法

使用两步验证插件来保护wordpress登陆是个常用安全防范措施。来自大名鼎鼎的wordpress博客备份工具UpdraftPlus作者的Two Factor Authentication是个很方便使用的两步验证解决方案。

碰到的一个尴尬情况

启用这个两步验证插件后,正常情况是,在wordpress登陆界面输入用户名和密码后,点击登陆,会自动跳转到输入两步验证码的界面。但有时候输入用户名和密码后,点击登陆后,两步验证码的界面一直不出现,而是看到登陆按钮左边有个圈一直转啊转。

解决办法

尝试使用带www和不带www的域名地址登陆,看哪个可以成功出现两步验证码的界面。
我的碰到的情况是使用co1dawn.com/wp-login.php登陆时就会出现上面的尴尬情况;
这时加上www,即登陆www.co1dawn.com/wp-login.php就会正常出现两步验证码。
也许你是相反的情况。

华硕路由器或刷了梅林的路由器导致光纤宽带PPPoE连接每天断线的解决办法

碰到的现象

使用华硕路由器或者其他路由器刷了梅林固件后,梅林固件本质上就是华硕固件改版而成(描述可能不太准确),通过PPPoE方式进行的光纤连接,差不多每天都会断线,并且不会自动重连,需要重启路由器和光猫才能重新连接上网。

可能的原因

华硕或梅林固件有个叫“网络监测”(Internet Detection)的功能,该功能默认开启,通过PPP echo方式发送数据包到ISP处并取得回应来保持宽带连接,当重试10次得不到回应时断开连接。早在2013年就有人提出更改PPP echo设置会导致PPPoE断线
这个问题并不是十分常见,估计是因为仅部分地区的ISP路由设备未对路由器发出的PPP Echo进行回应所致。

解决的方法

很简单,就是关闭该功能。
登陆路由器,依次定位到:
外部网络(WAN) > 互联网连接 > 帐号设置 > 网络监测
将默认的PPP Echo改为关闭
因为该问题引起的原因是和PPPoE相关,因此当使用华硕路由器或其他路由器刷了梅林固件后出现PPPoE断线问题时,不管是光纤还是普通宽带都可以尝试该方法。
如果是ISP所谓主动断线来释放IP就无效了。