使用HTTP Alternative Services实现免备案

由于众所周知的原因,国内的主机都是封闭80端口需要备案才能开启的。
这对不能备案的域名(如moe)以及不想备案的朋友来说,就意味着不能使用国内的主机来搭建网站。
为了提高访问速度,主站只能妥协使用HK/JP/TW的主机来搭建,图源视频等静态资源使用国内CDN来获得较好的访问体验。

随着时代的变革,HSTS Preload List的出现,让国内主机免备案成为了可能。

80不能用,干脆就不用,直接443走起

但是,HSTS Preload List虽然可以实现免备案,其缺点也很多。

  1. 作用周期长。提交Preload List后至少需要长达半年的时间才能硬编码入Chrome正式版,Firefox、Edge则需要更久。
  2. 取消周期也长。
  3. 对旧浏览器不兼容。IE就无容置疑了,对于某些国产浏览器,何时更新Chromium内核也是一个谜。
  4. 使用HSTS意味着强制HTTPS,不允许任何Mixed Content出现,包括证书过期后网站不能再访问等。

结论是,只开放443端口使用HSTS Preload是不明智的选择。
实际上,使用这种方法的博主也不多,备案的都备案了,不备案的就使用连接性好的主机。

在去年IESG通过了一项与HTTP有关的新协议HTTP Alternative Services。
如果你还不知道HTTP Alternative Services是什么,那么可以先去看一下这篇博文。
使用HTTP Alternative Services免备案至少需要2台VPS,1国内1国外,当然有能力改造的可以忽视。

0.环境

我们先使用国外VPS搭建好了一个正常的纯静态网站 http://httpsvc.loli.pet ,使用的WebServer为nginx,编译参数为

➜  ~ sudo nginx -V
nginx version: nginx/1.13.9
built with OpenSSL 1.1.1-pre2 (alpha) 27 Feb 2018
TLS SNI support enabled
configure arguments: --with-cc-opt='-g -O2 -fstack-protector-strong -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2 -Wno-c++11-extensions' --with-ld-opt='-Wl,-rpath,/usr/local/lib/ -L/usr/local/include/luajit-2.1/' --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-pcre-jit --with-debug --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_addition_module --with-http_dav_module --with-http_geoip_module --with-http_gzip_static_module --with-http_image_filter_module --with-http_sub_module --with-http_xslt_module --with-mail --with-mail_ssl_module --with-http_v2_module --with-openssl=../openssl-1.1.1-pre2 --with-openssl-opt=enable-weak-ssl-ciphers --add-module=../nginx-upstream-fair --add-module=../ngx_http_substitutions_filter_module --add-dynamic-module=../ngx_http_auth_pam_module --add-dynamic-module=../nginx-dav-ext-module --add-dynamic-module=../echo-nginx-module --add-dynamic-module=../ngx_brotli --add-dynamic-module=../headers-more-nginx-module --add-dynamic-module=../incubator-pagespeed-ngx-1.13.35.2-stable --add-dynamic-module=../ngx_devel_kit-0.3.1rc1/ --add-dynamic-module=../lua-nginx-module-0.10.12rc2

访问http自动跳转https,是比较常规的设定。

1.国内服务器设定

下载安装Caddy

curl https://getcaddy.com | bash -s personal

Q:我可以使用其他WebServer吗
A:可以,但是Chrome上会不能工作
Q:为什么不能工作呢
A:参照这里这里,目前Chrome只能使用Quic协议来替代,这也是为什么选用Caddy的原因。

编写Caddyfile

httpsvc.loli.pet:788 {
 log /home/www/log/httpsvc.loli.pet.caddy.log
 tls /opt/ssl.pem /opt/ssl.key
 root /homt/www/httpsvc.loli.pet
 header / -Alt-Svc
}

 对于静态blog用户来说只要定时同步/Webhook拉取目录即可,对于动态blog的话可能就要做数据库主从配置。
当然要是不在意的话使用Proxy+Cache也是没问题的。
要注意的是,配置中header / -Alt-Svc不能漏。
原因是Caddy在有-quic参数时会自动为网站加上Quic的 Alt-Svc 头,这会覆盖后面我们要添加的。

➜ ~ curl --resolve 'httpsvc.loli.pet:788:127.0.0.1' https://httpsvc.loli.pet:788 -I 
HTTP/2 200 
accept-ranges: bytes
alt-svc: quic=":788"; ma=2592000; v="39"
content-type: text/html; charset=utf-8
etag: "p5tspxt6q"
last-modified: Mon, 19 Mar 2018 06:58:45 GMT
content-length: 37826
date: Mon, 19 Mar 2018 07:32:57 GMT

此处的 alt-svc: quic=":788"; ma=2592000; v="39"

启动Caddy

caddy -quic

2.海外服务器设定

然后,加上 alt-svc 头,alt-svc的基本格式可以参照imququ的博文编写,我写好的规则是这样的。

add_header Alt-Svc 'quic="cn.loli.pet:788", h2="cn.loli.pet:788"; ma=2592000; persist=1; v="39"';

加上GeoIP处理,就是这样子的(需要ngx_http_geoip_modulengx_http_lua_module)

header_filter_by_lua_block {
  if ngx.var.geoip_country_code == "CN" then
    ngx.header['Alt-Svc'] = 'quic="cn.loli.pet:788", h2="cn.loli.pet:788"; ma=2592000; persist=1; v="39"';
  end
}

reload设定后,打开浏览器就可以看到效果了。

3.成果

未加上alt-svc 

加上alt-svc

Chrome效果:

可以看到在请求途中切换为了国内主机,并以后的请求都为此ip

Firefox效果:

Firefox也是一样,不过Firefox支持h2的替代,没有使用quic。

Edge和IE不支持HTTP Alternative Services,表现为全程走海外节点。

总之教程就到这里结束啦,虽然使用国内节点也不能提升太大的访问速度就是了

( ̄▽ ̄)

3 comments

  1. 为什么我这里 Chrome Dev Tools 里没有协议那一列。而且好像我的 Chrome(Chromium Version 65.0.3325.181 (Official Build) Built on Ubuntu , running on elementary 0.4.1 (64-bit))的 QUIC 是默认关闭的。

Leave a comment

电子邮件地址不会被公开。 必填项已用*标注

退出移动版