使用 Unbound 搭建更好用的 DNS 服务器

用了好久的 DNSMasq 方案终于在大半年前彻底炸掉了。

原因不光是 DNSMasq 性能和安全性完全不足以撑起公网缓存/递归 DNS 的任务,也有想要做反污染和加速的时候确实太蛋疼的问题。

现在使用的方案是 Unbound+DNSCrypt,外带一份加速列表。这段时间看来,不管在我本机还是在公网服务的两台,效果和反馈都很不错。

准备工作

需要的程序:

  • unbound
  • dnscrypt-proxy
  • makefile
  • git

makefilegit 用于处理 dnsmasq-china-list

Unbound 配置

修改文件 /etc/unbound/unbound.conf。没有这个文件的话,一般需要找一下软件包里提供的配置 example 文件复制过去。这里列出的仅包含需要修改的部分,其他的按照默认配置一般没有问题。

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
num-threads: 2 # 线程数可以修改为物理核心数
interface: 0.0.0.0 # 侦听所有 IPv4 地址
interface: ::0 # 侦听所有 IPv6 地址
# 如果只需要本机使用,则一个 interface: 127.0.0.1 即可
so-rcvbuf: 4m
so-sndbuf: 4m # 本机使用的话,这俩 buf 可以取消注释
so-reuseport: yes # 如果开了多线程,就写 yes
msg-cache-size: 64m # 本机可以设置 4m 或者更小
rrset-cache-size: 128m # 本机可以设置 4m 或者更小
cache-max-ttl: 3600 # 建议设置一个不太大的值...专治各种运营商 DNS 缓存不服
outgoing-num-tcp: 256 # 限制每个线程向上级查询的 TCP 并发数
incoming-num-tcp: 1024 # 限制每个线程接受查询的 TCP 并发数
# 下面这四个不需要解释了吧,不想用那个就写 no
do-ip4: yes
do-ip6: yes
do-udp: yes
do-tcp: yes
tcp-upstream: no # 默认是 no,隧道状态比较稳的话也不需要写 yes。一些情况下强制使用 tcp 连上游的话写 yes
access-control: 0.0.0.0/0 allow # 本机用的话建议设置 127.0.0.0/8 allow,局域网用适当调整
root-hints: "/etc/unbound/root.hints" # 没有的话在 ftp://FTP.INTERNIC.NET/domain/named.cache 下载一份
hide-identity: yes # 不返回对 id.server 和 hostname.bind 的查询。
hide-version: yes # 不返回对 version.server 和 version.bind 的查询。
# 不过下面有 identity 和 version 的自定义选项,不隐藏这些的话,修改下选项还可以卖个萌(´・ω・`)
harden-glue: yes # 建议打开
module-config: "iterator" # 禁用 DNSSEC 检查,如果上游不支持 DNSSEC 就关掉。注意这个选项有可能在其他 include 的文件里
unwanted-reply-threshold: 10000000 # 针对各种网络不服,数值为建议值,具体可以自己修改看看效果
do-not-query-localhost: no # 一般是为了防止扯皮丢包开着,不过等下要用 DNSCrypt 所以关掉
prefetch: yes # 蛮好用的,开着吧
minimal-responses: yes # 省带宽,开着吧。本机用可以关掉
# 关键部分来了,把默认查询全部丢给 DNSCrypt。使用 [地址]@[端口] 指定查询地址和端口,默认端口 53。
# 然后把国内的地址丢给国内的缓存服务器。这两个选项的顺序不能错哟。
# 如果使用隧道查询,把这个地址改为隧道对端的地址,或者一个国外的 DNS 服务器都可以,例如 8.8.8.8。
# 具体看是在对端开 DNS 还是直接用国外的服务器。后者的话,前面 outgoing-interface 可以直接设置隧道本地端的地址,不过要配合 dnsmasq-china-list 的话,还是写路由表比较合适,否则不够灵活。
include: "/etc/unbound/accelerated-domains.china.unbound.conf"
forward-zone:
name: "."
forward-addr: 127.0.0.1@5353

DNSCrypt 配置

修改文件 /etc/default/dnscrypt-proxy

1
2
DNSCRYPT_PROXY_LOCAL_ADDRESS=127.0.0.1:5353 # 设置侦听在 127.0.0.1 端口 5353
DNSCRYPT_PROXY_RESOLVER_NAME=cisco # cisco 其实蛮快的,但是慢的话就去用个别的吧。d0wn 的那堆服务器真的不稳定,和名字一个样...

如果使用 systemd 的话这个文件就没用辣,看这里看这里

修改文件 /usr/lib/systemd/system/dnscrypt-proxy.socket

要修改的部分:

1
2
ListenStream=127.0.0.1:5353
ListenDatagram=127.0.0.1:5353

127.0.0.1:5353 就是上面 unbound 配置里 DNSCrypt 的监听地址。

dnsmasq-china-list 来加速

首先 clone 这个仓库到本地,然后在 Makefile 里修改 SERVER=114.114.114.114,改为你觉得最合适的国内缓存 DNS 服务器。114DNS 最不太近的一段时间里都挺残的所以不建议用。

执行 make unbound 来生成一份 unbound 配置,然后放在上面 unbound 配置里写的地址,也就是 /etc/unbound/accelerated-domains.china.unbound.conf

如果还需要一些特定的缓存上游设置,要放在 include: "/etc/unbound/accelerated-domains.china.unbound.conf" 这句前面。来举一只栗子。

举一只果子的栗子。

AppStore 的加载和下载速度一直在国内饱受一些极客们的诟病,然而同时饱受诟病的运营商 DNS 解析 AppStore 的下载地址反而是国内的 CDN 地址,速度会非常快。

需要使用 dig 工具,并且要在国内的网络环境下测试。Linux 发行版里都有包可以装,OS X 则自带。

第一条命令:dig +trace a100.phobos.apple.com.

递归追踪解析结果,这个记录被 CNAME 到了 a100.phobos-apple.com.akadns.net.

第二条命令:dig +trace a100.phobos-apple.com.akadns.net.,得到这条记录被 CNAME 到了 a1-a200.itunes-apple.com.akadns.net.

第三条命令:dig +trace a1-a200.itunes-apple.com.akadns.net.,看到了 CDN 的地址,a1-a200.phobos.apple.chinacache.net.

所以如果有国内的地址直接去跟踪解析 akadns.net 的 DNS 的话,一般是可以正确解析到国内 CDN 的。先找一个 akadns.net 的权威 NS 地址,比如 a1-128.akadns.net 对应的 IP 是 193.108.88.128。同时还得有国内的 CDN 地址也从国内地址去解析,那么配置里这样写:

1
2
3
4
5
6
forward-zone:
name: "akadns.net."
forward-addr: 193.108.88.128
forward-zone:
name: "chinacache.net."
forward-addr: 119.29.29.29 # DNSPod PublicDNS 的服务器地址

多次尝试之后,发现还有一个 CDN 地址 0gq2p7eckbs26f.mwcname.com,那么也把这个地址交给 unbound 通过国内网络解析。

1
2
3
forward-zone:
name: "mwcname.com."
forward-addr: 119.29.29.29

一并加到上面的配置里,然后来测试下。

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
Phoenix-X1-Carbon :: ~ » dig @127.0.0.1 a100.phobos.apple.com

; <<>> DiG 9.10.3-P4 <<>> @127.0.0.1 a100.phobos.apple.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 24454
;; flags: qr rd ra; QUERY: 1, ANSWER: 14, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;a100.phobos.apple.com. IN A

;; ANSWER SECTION:
a100.phobos.apple.com. 3596 IN CNAME a100.phobos-apple.com.akadns.net.
a100.phobos-apple.com.akadns.net. 117 IN CNAME a1-a200.itunes-apple.com.akadns.net.
a1-a200.itunes-apple.com.akadns.net. 297 IN CNAME a1-a200.phobos.apple.chinacache.net.
a1-a200.phobos.apple.chinacache.net. 1799 IN CNAME a1-a200.phobos.apple.cncssr.chinacache.net.
a1-a200.phobos.apple.cncssr.chinacache.net. 1799 IN CNAME cc00109.h.cncssr.chinacache.net.
cc00109.h.cncssr.chinacache.net. 120 IN A 223.99.228.87
cc00109.h.cncssr.chinacache.net. 120 IN A 113.207.33.15
cc00109.h.cncssr.chinacache.net. 120 IN A 113.207.33.12
cc00109.h.cncssr.chinacache.net. 120 IN A 202.110.80.14
cc00109.h.cncssr.chinacache.net. 120 IN A 61.179.105.154
cc00109.h.cncssr.chinacache.net. 120 IN A 61.179.105.7
cc00109.h.cncssr.chinacache.net. 120 IN A 119.188.138.172
cc00109.h.cncssr.chinacache.net. 120 IN A 120.192.248.195
cc00109.h.cncssr.chinacache.net. 120 IN A 221.181.39.76

;; Query time: 233 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Thu Apr 28 00:34:02 CST 2016
;; MSG SIZE rcvd: 387

走国内 CDN 了吧~

重启相关服务,更改自己所用的 DNS 地址,完事儿收工(「・ω・)「

=== 2016-04-30 14:00 更新 ===

如果需要 edns-client-subnet 支持的话,需要手动编译源码安装。命令

1
2
3
4
# 克隆源码
svn co http://unbound.nlnetlabs.nl/svn/branches/edns-subnet/
# 编译安装
./configure --enable-subnet --with-libevent && make && sudo make install

配置文件的格式

1
2
# 默认向所有服务器发送 edns-client-subnet
send-client-subnet: 0.0.0.0/0

如果只对特定权威 DNS 发送 edns-client-subnet 请求,则按照此格式写多行 IP。

公共场合请使用指纹识别器

前几天带本本去导师办公室修改论文,虽然开机启动速度快,但是还是在老师的注视之下紧张敲错了三遍密码…得,本来没在意的也记住密码了(ry

所以为啥有指纹识别器的本子偏偏要输密码(:з」∠)

检查设备

总之先来看下指纹识别器是哪家生产的好了。

1
2
Phoenix-X1-Carbon :: ~ » lsusb | grep -i 'finger'
Bus 001 Device 003: ID 138a:0017 Validity Sensors, Inc. Fingerprint Reader

搜索一下就发现 X1 Carbon Gen3 这么受欢迎的本子早已上了 ArchWiki https://wiki.archlinux.org/index.php/Lenovo_ThinkPad_X1_Carbon_(Gen_3)

安装驱动

安装 fprintd 包,这个包会依赖 libfprint,但是官方仓库中的 libfprint 目前的版本在此指纹识别器上无法正常工作,表现为 enroll 只扫描一次,并且无法验证指纹。

Note that recent versions of fprint are broken for this model : One is able to enroll a finger but recognition always fails.

GitHub 上已经有了 vfs5011 相关的 issue 和 fix,但是还没有发布新的稳定版。所以暂时安装 aur/libfprint-git 包。

配置指纹验证

Fprint - ArchWiki 上已经给出了配置方法。将 auth sufficient pam_fprintd.so 加入 /etc/pam.d/system-local-login 中的第一位置即可。同样方法可以用于 /etc/pam.d/ 下的其他文件。例如 KDE 登陆使用的 sddm

扫描指纹,以普通用户身份命令:

1
$ fprint-enroll

默认是右手食指。可以使用 -f 选项指定手指。正常的表现为成功扫描五次即可保存指纹,并且在需要验证的时候自动启动指纹识别器。不过还有个小问题,如果保存多个指纹,似乎只能识别保存指纹列表中的第一个。

然而我懒得折腾了就这样吧

尝试迁移到 AWS Cloud

发了个帖子抱怨服务器一大堆却没个放自己个人站的地儿。其实是服务器都是生产环境要跑各种业务,不能放自己的东西。其实个人站就一个博客一个知识库,还都是静态的,连买个 Linode 都觉得资源浪费。放在 GCE f1.micro 上吧,是便宜了不过网络抽死。如果不是因为要用 SSL 防运营商劫持和中间人攻击,真的直接扔 GitHub 了。

感谢 @sparanoid 的建议,花了一下午尝试将自己的静态网站部署在 AWS 云上。

AWS 准备工作

S3 文件桶

创建一个 S3 文件桶,并在「属性」 -> 「静态网站托管」页选择「启用网站托管」,然后索引文件填写 index.html

在此页面会得到一个网站终端节点,例如 example.com.s3-website-ap-northeast-1.amazonaws.com 这样。先复制备用。

上传 SSL 证书

其实之前签发了一张三年的 ShinoSaki ECC 证书,然而 AWS 不认(ノ=Д=)ノ┻━┻ 只好去签了 AlphaSSL 的泛域名。

需要安装 awscli,可以直接 sudo pip install awscli

上传证书命令如下(示例名称记得改成自己的哦)

1
aws iam upload-server-certificate --server-certificate-name cert-name --certificate-body file://example_com.pem --private-key file://example_com.key --certificate-chain file://ca.pem --path /cloudfront/yoursite/

前面的 file:// 也不能移去,否则会报错 A client error (MalformedCertificate) occurred when calling the UploadServerCertificate operation: Unable to parse certificate. Please ensure the certificate is in PEM format.

创建 CloudFront Distribution

如果是 Jekyll 一类会创建「文件名.html」的程序,origin 直接下拉菜单中选择 S3 的文件桶地址即可。但是 Hexo 和 MinoriWiki 都是目录名下的 index.html,所以只能使用之前得到的网站终端节点。填入地址后,下面的配置随自己的想法选择即可。Alternate Domain Names (CNAMEs) 填写自己的域名,然后下面的 SSL 选择 Custom SSL Certificate (example.com) 和一个对应的证书。Default Root Object 填写 index.html

为什么只能使用网站终端节点而不是 S3 地址的原因是 CloudFront 和 S3 的 Default Root Object 工作原理不同,如果是请求子目录,那么 CloudFront 不会给默认加上 index.html 导致 403。

创建之后 CloudFront 需要(很长一段)时间来部署。于是先把分配的 CDN 地址 xxxxxxxxxxxxx.cloudfront.net. 复制备用。

设置 Route 53

建立一个 Route53 Hosted Zone,然后导入以前的 zonefile 或者什么的。网站的地址 Type 选择 A - IPv4 address,然后 Alias 选择 Yes。Alias Target 是刚才复制的 CloudFront 的 CDN 地址。Routing Policy 选择 Simple——GeoDNS 将交由 CloudFront 完成。

网站程序准备

Hexo

Hexo 已经有了现成的 S3 deployer,不过主页上的那个不工作也不管别人给提交的 PR。所以推荐使用 hexo-deployer-aws-s3

不过貌似是会强制覆盖每个文件的,上传花了好久啊比 Git 慢多了… S3 啥时候支持 Git (ノ=Д=)ノ┻━┻

MinoriWiki

MinoriWiki 从一开始就是面向 UNIX 系使用者的一套超简单个人知识库,所以压根没考虑用 S3 啊(ノ=Д=)ノ┻━┻

不过自己写的东西好处就是可以各种改(死)所以半个下午发布了一个带有 S3 支持的新版。使用了 node-s3-client 库,可以只上传修改了的文件。

搞定

一路搞下来,CloudFront 也就差不多了,域名解析应该也更新了。试试看效果吧~

没啥访问量的个人站,用 Route53 + S3 + CloudFront 的开支一个月可以控制在 2 美元左右,但是性能、网络和可用性远远比一个月 2 美元的 VPS 好得多。

然而在国内… AWS 被滥用还是挺凶的。所以各种服务被干扰,于是成了现在这惨样。

其实还不如直接托管在 GitHub 然后上个支持自定义 SSL 和 PAYG 的 CDN

Sierra 4G LTE EM7345 with Arch Linux

X1 Carbon 2015 内置 Sierra EM7345 4G LTE 适配器,系统里看到是这样:

1
2
$ lsusb
Bus 001 Device 002: ID 1199:a001 Sierra Wireless, Inc.

根据 ThinkPad EM7345 4G LTE Mobile Broadband - Overview and Service Parts 这块 EM7345 基本完美支持联通的 3G/4G 制式。

插入 microSIM 卡,然后安装需要的包:

1
# pacman -S usbutils usb_modeswitch modemmanager mobile-broadband-provider-info

启用 modemmanager 服务

1
systemctl enable modemmanager.service

然后加载内核模块 cdc_mbim,文件 /etc/mkinitcpio.conf

1
MODULES="... cdc_mbim"

重新生成内核镜像

1
# mkinitcpio -p linux # or change to your kernel preset here

重启即可在 NetworkManager 中新建 GSM 设备的 broadband (移动宽带) 连接。

顺便上一张图,老家小城市还是郊区所以 4G 信号几乎没有,还是达到了这个速度,点个赞(๑•̀ㅂ•́)و✧

Sierra EM7345 4G LTE Speedtest on China Unicom

参考文档:

ThinkPad X1 Carbon 2015 与久违的 Arch Linux

对 X1 Carbon 2015 垂涎已久。然而中国市场不提供定制配置、没有 16G 内存的版本、512G PCIe SSD 的型号配置触控屏。这些都不能忍…于是折腾了好久,打扰了至少三位在美国的朋友,最终在黑色星期五当天下单,前天顺丰到手。

先晒一下单。这个配置在联想美国官网购买的原价是 2622.60 美元,黑色星期五的各种优惠后价格是 1630 美元。嘛… 多出来的预算败了一块 1TB SSD 当移动硬盘,真是麻烦帮忙带回国的朋友了(っ‘ω’c)

X1 Carbon 2015 20BSCTO1WW

  • Intel Core i7 5600U 2.6GHz / 3.6GHz
  • 16G (2x8G) DDR3 1600MHz On-board RAM
  • 512G PCIe SSD
  • 2560x1440 QWHD IPS
  • Fingerprint Reader
  • Sierra LTE EM7345

其中 SSD 是 SAMSUNG SM951,测试读写速度分别为 1546MB/s 和 1260MB/sdmidecode --type memory 显示有两条镁光制造的内存,这个倒是和网络上流传的单根内存不太一样。不过两根都是 on-board,所以是无法更换的。

屏幕颜色偏暖,大概是为了长时间工作不会太劳累设定的。ThinkScope 提供了一份 ICC 文件,效果有点偏蓝(紫红?)。不过屏幕型号并不是页面上写的 LG LP140GH1-SPA2,而是 LG LP140QH1-SPB1。总之雾面屏加 86% sRGB coverage 导致它的显示效果比旁边的 MacBook Pro Retina 差了一大截,而且 HiDPI 带来软件上的问题… 嘛这个后面再说。

X1 Carbon 2015 整个机身做工很好,拿着很有份量(不是沉!)给人一种很结实的感觉,完全没有其他 ThinkPad 的塑料感。唯一略心颤的是屏幕没办法像 MacBook Pro 一样稳,和其他笔记本一样调整屏幕角度还是会晃动几下,大概是铰链设计的差异导致。键盘仍然是那个熟悉的手感——哪怕是悬浮式键帽,仍然和老式 ThinkPad 键盘手感不相上下。换到这么舒服的键盘之后打字速度已经快到让 fcitx 分不清键序啦( ´∀ )σ)Д`)其实是 GTK 程序的 bug。ThinkLight 改到键盘下方,可以更好地看清键帽更高大上了,但是没办法当作光源看其他东西… 不过本来也不怎么亮还是爱护下眼睛吧。触控板很舒服,虽然大概还是不够和 MacBook Pro 相比,毕竟人家有底层驱动优化,系统层还支持很多手势。单从手感上来讲还是很不错的。

新本本送到后开机检查硬件,然后当然是要删掉预装的 Windows 10 然后换上 Arch Linux 啦。之前 T420 的 UEFI 安装 Arch Linux 总是启动不能,然而 X1 Carbon 就很顺利。当然是关掉了 Secure Boot 的。

续航感觉还不错,中午送到开箱检查的时候就还有 60% 的电量,然后从下午开始到晚上一直在安装配置系统,到半夜的时候报告还剩 15% 电量。中间有几次编译,所以顺便看了下散热。室内温度大概 10 摄氏度,sensors 检测高负载时最高温度 57 摄氏度,一般工作温度 35-40 摄氏度。这是有点出乎意料的,本来以为超极本的散热都会很悲剧。不过据说其他人也有到过 80 度的,所以要再用用看。

Sierra LTE EM7345 是 microSIM 槽,然而手头只有 nanoSIM 所以还没用上。回去学校把流量卡补成 microSIM 再玩玩看。

安装过程完全不折腾。硬件兼容性报告只有一句话:Everything works out of box.

如果一定要在兼容性上挑刺儿的话,大概是 GPS 只有在 Windows 下才有办法打开,打开之后就可以直接在 Linux 下用了。

回到 Arch Linux 上。一年没用,KDE 已经快不认识了。通过更改 DPI、字体大小和图标大小,Qt5 的程序算是很好的支持了 HiDPI。然而一些 GTK / Qt4 程序就没那么好说话了… 总之用各种奇怪的办法让这些跟不上时代的程序变得勉强能看。

刚开始用 MacBook Pro 不久的时候,除去再也无法接受 retina 之下的显示效果(retina 有毒啊)之外,由于键盘、输入法(!!!)、快捷键、工具链、UNIX 生态等等问题上,OS X 上的工作效率只有 Linux 的 1/3 左右(是真的,很早的时候解决一个问题大概花了一个多小时,后来在 OS X 上再次遇到却花了一个下午)。

总之用来这几天,可以说是非常满意的。没有任何生产商设置的门槛,OS-Specific 的东西通过各种 折腾 Google、折腾 IRC 频道里的各位、折腾 ArchWiki… 等基本都解决了。现在看到它就有想摸一摸、想用它工作的冲动(๑•̀ㅂ•́)و✧然后上个图~

Desktop

KInfoCenter

最后的一点牢骚。

一年多没怎么碰 Linux 桌面,虽然看起来变化很大,但是实际上的提升基本没有感觉到。倒不如说,由于硬件技术一直在革新,Linux 桌面却没有了当年的势头。前段时间去 KDE 主页看的时候发现他们把捐赠放到了首页上,而且赞助页看起来好粗糙,完全不像是 KDE 一贯精致的设计风格。从对 HiDPI 的支持来看更是如此。KDE/High-dpi issues 页面从半年前到现在基本没有太大的变化…

嘛。当然了就算是钱多得没处花的某有点软的公司也没让自己的操作系统好好的支持 HiDPI ( ´∀ )σ)Д`)

开源界仍然有大量被广泛使用的应用保持着粗制滥造、works for me 等等的心态。虽然绝大多数不会有人为之付费,但是这并不是不认真的理由。而且这样下去也并不会有多少杀手级的应用出现。

虽然作为 DevOps 的话只要有好用的命令行工具链就万事大吉了。 更何况现在厨子整天瞎搞,果子就算还能继续赚无脑追捧的大众的钱,它还能制作多少 developer-friendly 的产品呢…
(´・ω・`)

迁移到了 uWSGI

虽然 PHP FPM 一直用得还行… 唔,大概已经不能叫做「还行」了,因为它总是莫名其妙地一个请求不响应然后阻塞掉了其他所有的请求。然后就是无止境的 504 Gateway Timeout… 唯一的解决方案是重启 FPM。

然后负载一高就%@T$#$#%@#$%什么的不说了。

无缝切换 PHP FPM 到 uWSGI

安装必要的包

1
apt-get install uwsgi uwsgi-plugin-php supervisor

如果是全新安装的话,php 的各种库也要一起装上

1
apt-get install php5-cgi php5-mysql php5-curl php5-gd php5-idn php-pear php5-imap php5-mcrypt php5-mhash php5-pspell php5-recode php5-sqlite php5-tidy php5-xmlrpc php5-xsl

创建文件 /etc/uwsgi/apps-available/uwsgi-php.ini 并软连接到 /etc/uwsgi/apps-enabled/uwsgi-php.ini

1
ln -s /etc/uwsgi/apps-available/uwsgi-php.ini /etc/uwsgi/apps-enabled/uwsgi-php.ini

文件内容

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
[uwsgi]
plugins = php

; leave the master running as root (to allows bind on unix socket or low ports)
master = true
master-as-root = true

; listening on unix socket
socket = /var/run/uwsgi-php.sock
chown-socket = www-data:www-data

; drop privileges
uid = www-data
gid = www-data

; our working dir
project_dir = /var/www

; load additional PHP module ini files
env = PHP_INI_SCAN_DIR=/etc/php5/embed/conf.d

; ; or if you need to specify another PHP.ini
; php-ini = /etc/php5/embed/php.ini
; ; then load additional php module ini files manually
; for-glob = /etc/php5/embed/conf.d/*.ini
; php-ini-append = %(_)
; endfor =

; allow .php and .inc extensions
php-allowed-ext = .php
php-allowed-ext = .inc

; set php timezone
php-set = date.timezone=UTC

; disable uWSGI request logging
disable-logging = true
; use a max of 10 processes
processes = 10
; ...but start with only 2 and spawn the others on demand
cheaper = 2

如果要指定 php.ini 的话,env 会失效所以单独用一个循环来读入所有的额外模块配置。envphp-ini/for-glob 二选一。不知道有没有更优雅一些的方法呢…

创建 Supervisor 配置文件 /etc/supervisor/conf.d/uwsgi-php.conf

1
2
3
4
5
6
7
[program:uwsgi-php]
command = uwsgi --ini /etc/uwsgi/apps-enabled/uwsgi-php.ini
autorestart = true
user = root
stderr_logfile = /var/log/supervisor/uwsgi-php.log
logfile_maxbytes = 1048576
logfile_backups = 10

user 一定是 root,因为需要权限创建 unix socket。之后 uWSGI 会自动降权(参见前面的配置文件)。

然后在 NGINX PHP 的部分修改为

1
2
3
4
5
location ~ \.php$ {
include uwsgi_params;
uwsgi_modifier1 14;
uwsgi_pass unix:/var/run/uwsgi-php.sock;
}

最后重启所有服务并清理——

1
2
3
service supervisor restart
service nginx reload
apt-get purge php5-fpm

搞定(๑•̀ㅂ•́)و✧

末字幕组时代,我们何去何从

日本のアニメやドラマを勝手に翻訳して字幕を付け、違法配信する中国のアマチュア集団「字幕組」。北京在住のメンバーを取材してその実態や動機、違法性を伝えたところ、中国のネットメディアが本紙記事を翻訳、「字幕組がなくなれば抗日ドラマに洗脳される」などと擁護の声が殺到した。

这是好久之前出现在日本各大新闻站上的文章。今天偶然和朋友闲聊时再次聊到了版权问题。

前些时间开始,射手网、人人影视、极影等字幕发布站相继被 takedown,相关律师函甚至恐吓信开始出现在站长们的邮箱中。在中国,「版权」第一次闹得这么凶。然而可悲的是,这并不是因为中国人开始有了版权意识,而仅仅是影响了一些商业集团的利益。

在近期某字幕组发布的作品中,发布者这样写到:

現今,版權的世代到來
觀眾也都紛紛的看版權去了
這對我們來說不是什麼問題,因為我們本來就不在意什麼載量
做字幕本來就是自爽的,與其說是做給別人看,不如說是做給自己看
對字幕界比較大的問題其實是新人減少這件事

從這幾天MANGLOBE(動畫公司)倒閉事件來看
看似盛況的MAG(漫画、アニメ、ゲーム)也明確的顯示出,其實是正在走下坡的
但是國外購買版權這情況,是有助於動畫公司轉虧為盈,不再只是依靠BD賺錢
我們理所當然的是要感到高興
這絕對絕對不是壞事,有愛支持正版是對的

但同時我也希望各位,如果真的很喜歡某片的話
在經濟允許的情況下,買個BD原盤支持一下吧,因為並不是每個片子都有版權購買(AMAZON用郵局的VISA卡就能買囉)
請把口中的支持化作實際的支持吧,良好的作品不該讓它沈入水中

另一方面
由於版權大量崛起,似乎可以望見字幕組的數量會越來越少
有所謂的版權可以看後,也會大幅降低新人願意加入字幕組的意願,因此製作字幕的人會越來越少
最後,支撐著字幕組的人只剩下老人
工作,結婚,後宮,家庭,最後連老人們都各奔東西(現在越來越坑就是因為現實的干擾越來越多
接著就化作了時代的眼淚

曾经在早些年,在大陆的视频站大部分仍然只是互联网上用于大家互相上传视频自娱自乐的时候,并没有某相关部门令人无力吐槽的审查和胡搅蛮缠,日本动画也并没有那么大规模的影响力和市场。字幕组的相继出现,让国内的观众们能够看到制作精良的日本动画,也促进了国内 ACG 圈子的发展。更重要的,字幕组将日本的二次元文化、包含其中的人的素养,人性的光辉和思考,带给了越来越多的人。

在这个时候应运而生的发布站,整合了多个字幕组的作品给观众挑选,也直接加剧了字幕组之间的竞争。经过一段时间的发展,字幕组的工作流程越来越优化,翻译和字幕的质量越来越高,甚至做到了日本电视台首播后两三个小时就可以制作出精美字幕的程度。

字幕组的百家争鸣慢慢引起了商界的注意。好像就在一夜之间,各大视频站都开始争相购买日本动画的版权。这本来是一件好事,但是相关部门的审查、过长的广告等等问题引发了观众们的不满,他们开始将发布站和视频站推向一个对立面,微博上甚至出现了「视频站不给看,我们去xxx下载!」类似激进的言论。然而与此同时,某圈内朋友表示:

国内所有视频网站我都是VIP
我觉得体验还不错
就翻译有待加强

字幕组的建立,有些是因为兴趣爱好,也有些只是随口说出的玩笑。但是共有的一点,都对二次元文化充满了热爱。很多组员看到了喜欢的作品会攒下生活费购买蓝光盘用于收藏,根本不会拆封,只是为了支持一下制作公司而已。但是从法律上来讲,字幕组的行为依然不能被接受。

我们推动了动画在国内的推广,但是并没有实力给制作公司分钱。
所以是我们退场的时候了,让专业的来吧。

所有人都已经看到了残酷的现实。曾经为了兴趣抑或只是一句玩笑建立起的小组,一路走来承载着众多组员们的羁绊,转瞬间已经到了并不华丽的谢幕。

也许会有字幕组和发布站继续存在下去,但是更多人会选择在线观看视频站购买的正版动画。虽然并不是中国人的版权意识提高了,但是至少,视频公司不管是通过广告还是销售会员获得的利润,可以用来继续购买更多的版权动画给大家看。对动画制作公司,对观众们,都不是坏事。

说到底,大部分字幕组,只是为了大家能在一起玩得开心罢了。字幕只是让大家聚到一起的载体,就算没有再继续做字幕,这些「字幕组」之名也可以让组员们继续走在一起吧。想必,这段可能仅仅存在于近几代人中的记忆,会被小心翼翼地保存一生。

R.I.P

使用 IPSec 连接带有 chnroutes 的隧道网络配置小记

标题似乎不是很易懂,于是解释下先。

位于大陆的服务器 A 和位于海外的服务器 B,A 与 B 之间使用隧道互联成内网,服务器 A 配置 chnroutes 以在必要的时候通过海外服务器访问网络,并在服务器 A 上配置 IPSec 服务器,从而使终端用户能够在任何网络环境下安全接入内网。大致描述如下:

需要加速海外访问时:终端用户 <- IPSec VPN -> 服务器 A <- 隧道 -> 服务器 B <-> 互联网

需要访问大陆网域时:终端用户 <- IPSec VPN -> 服务器 A <-> 互联网

此场景适用于互联网公司为员工提供快速、安全、便捷的工作网络环境,对于个人用户来说负担较大,不建议使用。

配置隧道

最简单的方案在服务器 A 和 B 上配置 GRE 隧道即可,步骤简单不再赘述。需要注意的是为了能让客户端的内网地址能够访问到隧道的对端,也就是服务器 B 端,服务器 B 上配置隧道时 peer 的参数应当是包含服务器 A 和 VPN 客户端 IP 的 IP 段,例如 ip addr add 10.7.0.1 peer 10.7.0.2/24 dev gre0

隧道打通后,服务器 A 的路由配置为:

  • 到服务器 B 的公网 IP 路由经服务器 A 的公网网关出站
  • 默认出口路由为隧道对端
  • 注意设置内网之间的路由
  • chnroutes 配置到大陆的流量经由服务器 A 的公网网关出站

配置 IPSec

安装 strongswan

1
# apt-get install strongswan

修改 /etc/ipsec.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
config setup
charonstart=yes
nat_traversal=yes
uniqueids=never # 修改为 yes 可以限制为单个设备连接

conn ios
keyexchange=ikev1
authby=xauthpsk
xauth=server
left=%defaultroute
leftsubnet=0.0.0.0/0
leftfirewall=yes
right=%any
rightsubnet=10.7.0.64/26 # 在配置的隧道网段中选择一个小段以避免地址冲突
rightsourceip=10.7.0.65/26 # rightsubnet 和 rightsourceip 按情况
pfs=no
auto=add

修改 /etc/ipsec.secrets

1
2
3
: PSK "Your pre-shared key" # 预共享密钥,注意修改引号内部分

username : XAUTH "userP@ss" # 用户名和密码,按格式每行一个

配置 iptables 转发

1
# iptables -t nat -A POSTROUTING -o <公网网卡> -s <VPN 网段> -j SNAT --to-source <公网地址>

在本例中,iptables 的命令为

1
iptables -t nat -A POSTROUTING -o eth0 -s 10.7.0.64/26 -j SNAT --to-source xxx.xxx.xxx.xxx

DNS 加速优化

既然是服务器中转分流,那么需要在服务器上进行 DNS 解析方可获得最佳效果。

安装 dnsmasq 和 git

1
# apt-get install dnsmasq git

修改 /etc/dnsmasq.conf 部分:

1
2
server=8.8.8.8 # 默认上游服务器通过隧道交由 Google DNS 解析以获得最佳海外站点效果
conf-dir=/etc/dnsmasq.d # 启用配置文件目录

获取 dnsmasq-china-list,将其中的配置文件软连接到 /etc/dnsmasq.d 下即可使用 114DNS 直接解析大部分需要加速的国内站点。

屏蔽公网对本机 DNS 服务的直接访问:

1
2
# iptables -A INPUT -p udp -d <服务器 A 公网 IP> --dport 53 -j DROP
# iptables -A INPUT -p tcp -d <服务器 A 公网 IP> --dport 53 -j DROP

修改 /etc/strongswan.confcharon { ... } 块内添加:

1
dns1 = 10.7.0.2  # 此处可填服务器 A 上除公网 IP 和 localhost 之外的任意可绑定 IP 地址,例如隧道的本地端地址

测试

一切就绪后重启 strongswan 服务:

1
# service strongswan restart

客户端的 IPSec VPN 配置:

  • 服务器地址为服务器 A 的公网地址
  • 用户名、密码、预共享密钥为服务器 A 中配置文件中的值

连接上之后在客户端 ping 任意公网 IP、服务器 A 和服务器 B 的隧道端 IP 应该都是通的。至此,客户端连接 IPSec VPN 后所有流量都会加密经由服务器 A 中转,在必要时会经由海外服务器 B 转发,保证了访问工作必需站点的速度和在任何公共网络环境下的数据安全。

懒(烂)办法制作 Telegram Sticker Pack

Telegram 支持表情包 (Stickers Pack) 之后各个群里就开始出现各种奇怪的聊天表情。嘛,虽然有些做得不错但是终究是别人分享的,自己有很多好看的表情图片就不便使用了。

所以今天折腾了下,用现成的图片集来制作 stickers pack。本文使用的 sips 命令内置于 OS X 操作系统,Linux 则可以更方便地使用 ImageMagick 来操作。

Telegram 要求 Sticker 图片为 PNG 格式,并且要有透明层,至少一边为 512 像素,另一边则不超过 512 像素。最大文件大小为 350KB。透明层就算了,我不会玩 PS。那么直接偷懒(死)来批量把当前目录下 JPG 和 PNG 混杂的图片们统一转换为 PNG 好了。

命令:

1
2
3
4
5
6
# 创建 output 目录以存放输出图片...
mkdir -p output
# 把当前目录下的所有 JPG 文件转换为 PNG 丢进 output 目录里。
for i in *.jpg; do sips -s format png $i --out output/$i.png;done
# 把剩下的 PNG 图片丢进 output 准备下一步的批量操作以及简单清理... 没有的话可以跳过。
mv *.png output/ && rm *.jpg

接下来把所有图片缩放为宽或高最大为 512 像素,并且保持比例。

1
2
cd output
sips -Z 512 *.png

搞定。最后一步就是添加 Stickers Pack。需要敲这位机器人

几条命令发给 stickers bot:

  1. /newstickerpack
  2. 发送表情包的名字…
  3. 在内置的 emoji 中发送一个最符合你要发送图片的表情…
  4. 然后把对应的图片作为文件发送
  5. 如果还有其他图片的话重复 3-4
  6. 全部表情图片设置完毕,发送 /publish 命令
  7. 为你的 stickers pack 取一个短名字 (用于 URL)

KABOOM! 新的 Stickers Pack 制作完成~ 快拿链接去和大家分享吧~

最后贴我的芙兰酱的表情包
这些图片木有高清的所以如果谁能做一份高清的表情来请务必告诉我_(:3」

=== 2015.06.07 更新 ===

Mika 菊苣制作了一份芙兰酱的高清表情包

Kancolle Broker - 舰娘直连游戏!

废话:啊……我终于治好了自己的拖延症。

事情的起因,无非就是 2015 年的第一场大戏——舰娘国服。嘛。不多评论,大家心里都明白。之后用 nginx + SNI Proxy 配置了一个代理服务器方便大家在日本地区外玩舰娘。但是这种代理服务有一个很大的问题就是会引起恶意攻击,被用作 DDoS 攻击的肉鸡使用,因此日本法律也是禁止 VPN 服务器的。

这个 idea 出现的时候还在帝都,房间里没开空调没有暖气,4M带宽20人用还有人开迅雷,无奈只好烧朋友送的 4G 流量卡来维持网络需求。完全没有力气做事情的时候偏偏看到 DMM 那个变态到极点的登录验证……

于是一直拖到回家之后碰上一大堆喵窝的活动… bangumi.moe 那边也在一直催着干活,直到今天我才良心发现用力让自己头脑清醒一点,认真分析了下 DMM 的登录验证。

整个过程大概是这样:客户端请求登录页面,页面中包含两个 token,加载完毕后一个 token 作为 header 数据,一个作为 XHR POST 请求数据发送给服务器,获得另外两个 token。这两个 token 将作为用户登录 email 和 password 的 key。用户登录时 post 给服务器的数据大概是下面这样:

1
2
3
4
5
6
7
8
9
{
"token": "11dde99d39af2287fc6eed02632ccbee",
"login_id": "user@example.com",
"save_login_id": 0,
"password": "P@ssw0rd",
"use_auto_login": 0,
"dfdfa8466f24710893d99529acaaeef0": "user@example.com",
"2760cb37702b03d10d92caf9daaaf675": "P@ssw0rd"
}

… 好了,看晕了吧。咱就不吐槽日本人脑子里到底在想啥了。总之来看代码 -> Github

原理就是登录后用 cookie 拿到游戏 link 的 apptoken,而这个游戏的 link 是不会验证日本 IP 的。

想测试效果的话,那么先关闭本地的各种舰娘代理,移除所有相关的 hosts,然后访问这里。使用 DMM 帐号登录,成功的话会跳到舰娘的游戏页面。适用于所有在日本境外没有日本代理的情况下使用。

问:会不会有安全问题?

必须的。而且比 SNI 代理更不安全。但是反过来说,也是比 SNI 更安全的。因为 DMM 登录发送密码完全没有加密,只是靠 HTTPS。所以用这个程序的话:

  1. 密码都是可以在服务端记录的。虽然程序里完全没有记录密码相关的代码,但是要加也不是难事。
  2. 没有 HTTPS 的情况下,你发送的所有数据都是明文的。所以我做的这个 demo 用了 HTTPS 加密链接。

所以如果是有 HTTPS 加密且 deploy 这个程序的人比较靠谱的话,安全性还是有保障的。

至于大家是不是相信我……嗯这个看各位如何考量啦。

最后:我真的没玩过舰娘,我也不会去玩。