折腾 – 折腾(存档) https://blog.sorz.org 已停止更新和维护。该页面为2018年3月创建的存档,其内容可能已过于陈旧、与现状不符,仅作为历史存档用作参考。 Sun, 14 Jan 2018 11:08:20 +0000 zh-CN hourly 1 https://wordpress.org/?v=4.9.4 简单的 BT Tracker 连接检测 /p/bt-tracker-helper/ /p/bt-tracker-helper/#respond Sat, 24 Oct 2015 09:43:43 +0000 /?p=348077

RT @kgen: 大家 BT 下载的时候,不要开着 VPN,发达国家的版权投诉猛如虎。版权方会主动放出一些正版的 BT 种子,然后收集所有连接来源 IP,投诉或索赔。

这对于 VPN 提供商来说也是一个很头疼的问题。现在的 BT 客户端为了避免被封,已经经进化出了各种加密、混淆手段,直接检测 P2P 流量很困难。不过,大多数时候,客户端都在下载是都会同时连接一些 BitTorrent tracker 服务器。这些服务器数量有限且地址、端口号相对固定,可以非常容易地收集,并直接通过 IP 地址和端口号判断而不必对流量内容进行深度检测。探测到了就扔炸弹。是一个简单易行的判断用户是否正在使用 BT 的方法。

这个方法已在某家梯子站上部署了有一段时间了。鉴于它误报率(false postive rate)低但漏报率(false negtive rate)高,检测到的「处罚」会比较严厉——发现连接就立即挂断这条 VPN 连接。效果似乎还不错,仅有的几次投诉经过排查,发现都是在这套机制的某些环节失效时发生的。

当时为了方便操作,写了几个脚本。现在重新整理了一下,放在了 GitHub 上。这个脚本主要用于从 BT 种子文件里收集 trackers 的地址,然后解析域名得到对应的 IP 地址、协议和端口号。脚本本身并不进行检测等操作,只是为了方便配置防火墙而写。

示例

先在各处收集一些 BT 种子,这些种子文件中通常会包含一个或多个的 trackers。可使用./trackers.py torrent获得 trackers 的 URL 列表,重复的地址会被自动剔除:

$ ./trackers.py torrent *.torrent > trackers.txt

$ cat trackers.txt
> http://tracker.yify-torrents.com
> udp://tracker.justseed.it:1337
> udp://tracker.openbittorrent.com:80
> http://nyaatorrents.info:3277
  ......

防火墙通常需要匹配 IP 地址而非域名,并且一个域名可能对应多个 IP。这个脚本提供了解析 tracker URL 的功能,每个地址会被解析为一个或多个 IP 地址 – 协议 – 端口 的组合:

$ ./trackers.py raw trackers.txt
> 188.166.82.104 tcp 6881
> 94.23.217.90 udp 1337
> 179.43.146.110 udp 80
  ......

使用 ipset 来匹配这些连接是一个不错的选择。可以使用./trackers.py ipset直接生成 ipset 规则,这些规则可经由ipset restore导入系统:

$ ./trackers.py ipset trackers trackers.txt > ipset.rules

$ cat ipset.rules
> create -exist trackers hash:ip,port family inet
> add -exist trackers 188.166.82.104,tcp:6881
> add -exist trackers 94.23.217.90,udp:1337
> add -exist trackers 179.43.146.110,udp:80
> ...

# ipset restore -file ipset.rules

另外,虽然不是很推荐这么做,从收集 trackers 到导入 ipset 的操作也可以一步完成:

# ./trackers.py torrent *.torrent | ./trackers.py ipset trackers - | ipset restore

导入 ipset 后,可以使用 iptables 匹配这个 ipset,进行进一步操作。例如可使用iptables -j LOG记录下连接 trackers 的行为:

# iptables -N TRACKERS
# iptables -A FORWARD -m set --match-set trackers dst,dst -j TRACKERS
# iptables -A TRACKERS -m limit --limit 1/sec --limit-burst 10 \
  -j LOG --log-level info --log-prefix trackers
# iptables -A TRACKERS -j DROP

一些发行版本使用了 syslogd 管理日志,可以修改它的配置,将连接记录转发至其他程序进行进一步处理。例如文章开头所说的,通过日志中记录的源 IP 识别出对应的用户,然后将其断线。

]]>
/p/bt-tracker-helper/feed/ 0
当小学生学会了 DDoS /p/childish-ddos/ /p/childish-ddos/#comments Tue, 01 Sep 2015 14:11:46 +0000 /?p=348060 ddos-threat-01

ddos-threat-02

ddos-threat-02a

ddos-threat-03

ddos-threat-04

编辑于 2015-09-03

]]>
/p/childish-ddos/feed/ 13
Cubieboard 更新至主线内核 /p/cubieboard-on-mainline-kernel/ /p/cubieboard-on-mainline-kernel/#comments Sun, 28 Jun 2015 14:02:06 +0000 /?p=348052 Allwinner 此前一直在使用它自己 fork 的 kernelU-Boot
现在,他们正在努力将这些代码并入主线。

我在用的 Arch Linux,众所周知,是一个比较激进的发新版本。它已经开始送主线内核linux-armv7啦。

毫无悬念地,更新后就无法启动了。原因似乎是它没有更新 U-Boot。
参照这篇 Mainline U-Boot 编译最新的主线版 U-Boot 然后写入 SD 卡就好了。

需要注意的是,boot.cmd内容需要根据 Arch Linux 的安排有所更改:

setenv bootargs console=ttyS0,115200 root=/dev/mmcblk0p2 rootwait panic=10
load mmc 0:1 0x43000000 dtbs/${fdtfile}
load mmc 0:1 0x42000000 zImage
bootz 0x42000000 - 0x43000000

(不同之处也就是使用bootz来载入zImagefdtfile位于dtbs/下)

另外注意似乎还有一些驱动不太完善,比如无法使用 NAND,具体请参考 Linux mainlining effort

]]>
/p/cubieboard-on-mainline-kernel/feed/ 2
HSTS Preloading – 让你的域名「嵌入」主流浏览器,一同发行 /p/hsts-preload-list/ /p/hsts-preload-list/#comments Thu, 19 Mar 2015 19:39:59 +0000 /?p=348035 有点标题党的味道,但确实有这种效果,比如我现在用的这个域名sorz.org目前可以在 ChromiumFirefox 的源代码中找到。理论上,它也会出现在 Safari 和新版的 IE 里[1]

当然「听起来好像很厉害」只是个副作用,其目的还是为了确保安全。

TL;DR – 如果你的网站也支持全站 HTTPS,可以考虑配妥 HSTS 后在此提交申请

(2015-11 更新)现在 Qualys 的 SSL Server Test 也会显示相关信息啦:
ssllabs-result-with-hsts

一切为了安全

现代浏览器在安全上真是做足了功夫。

HTTPS

SSL 协议在早在上世纪末就已提出[2]。目前广泛使用的 TLS 1.2 是它的改良版,在 2008 年正式发布[3]。他们可以在很大程度上,保证数据在 浏览器 与 网站服务器 间传输时的安全,保证他们不在传输过程中被监听或者修改。

但目前仍有大量网站是不提供 HTTPS (SSL/TLS)连接的 [4],或是只在部分页面提供。浏览器不知道哪些网站使用 HTTPS,用户也不一定知道。现在通常的做法是,浏览器先默认使用 HTTP 连接,如果服务器要求安全连接,再通过这个 HTTP 连接返回给浏览器一个「重定向」,让浏览器转而使用 HTTPS。

这样有一个问题,因为 HTTP 是不安全的,这个「重定向」就有可能被攻击者吞掉。然后攻击者一方面冒充服务器,使用 HTTP 与浏览器进行通讯;另一方面冒充浏览器,与服务器使用 HTTPS 建立连接。这就是所谓的 SSLstrip 攻击。

HSTS

为了解决这个问题,HTTP Strict Transport Security (HSTS, HTTP 严格传输安全) 孕育而出。这个 2012 年才发布的新玩意儿其实很简单,就是制订了一种方法,让服务器能够告诉浏览器:「我支持 HTTPS,今后使用它连接我」。

具体来说,它在增加了一个 HTTP 头 Strict-Transport-Security,里面指明网站至少支持 HTTPS 多长时间、是否包含子域名等。浏览器会缓存这条规则,今后即使是用户或者网页指定了http://,浏览器也会无视掉它,强制使用安全连接。

Preload List

但这无法阻止首次访问网站时受攻击(此时还没有 HSTS 规则的缓存呢),浏览器们并不满足于此,推出了 HSTS Prelod List(预加载列表?)。顾名思义,就是将使用 HSTS 的网站域名直接内置(hard-coded)进浏览器。只要是出现在列表中的域名,就统统使用 HTTPS 连接,让攻击者无缝可钻,安全性大提升。

部署

唔.. 介绍了这么多背景,进入正题,怎么做?首先当然是要做好全站的 HTTPS 支持,这个就略过不提了。然后是部署 HSTS。最后是提交申请,进入浏览器的 Preload List。

UPDATE 20150904: 如果你在使用 CloudFlare,进入 Dashborad,在 Crypto 找到并开启 HSTS 就可以了。

HSTS

添加 HSTS 支持其实很简单,修改一下 Web 服务器的配置,增加一个 HTTP 头就行[5]。随手 Google 到了一篇文章,大家可以参考一下。

举个例子,这个域名目前使用的是:

Strict-Transport-Security: max-age=15552000; includeSubDomains; preload

max-age=15552000告诉浏览器缓存这条规则 180 天;includeSubDomains对子域名也使用相同的规则;preload允许将这条规则内置进浏览器。

部署完毕后,可以用这个网站测试一下。如果存在其他安全相关问题,也会被检测出来。

Preload List

Duang! 现在可以提交申请啦(自备梯子):
https://hstspreload.appspot.com/

这个网站似乎是 Google 牵头做的,但不仅 Chrome,Firefox、Safari 和 IE 也都会包含这个列表。所以只要在这里提交一次就行啦。

提交前注意几点:

  • 需在全站启用 HTTPS(包括子域名),同时重定向所有 HTTP 流量至 HTTPS;
  • max-age必须大于 10886400 秒(18 周);
  • includeSubdomainspreload
  • 不能反悔的哦。

另外,他说这个申请是要经过人工审核的(not automatic nor assured … undergo a manual review),所以可能要花上几周的时间。具体到并入个浏览器代码中,可能需要更长的时间。

老实说,当初我看见「人工审核」便没报太大希望,提交后就忘了这事了。近几天才偶然发现已经申请通过并入了浏览器,才知道其实并没有什么门槛(虽然目前的列表只有两千行左右)。所以我也不知道我从申请到通过花了多久…

附注

[1] 会并入随 Windows 10 发布的那个 IE 上,MSDN 是这样说的。所以我是不是还可以更标题党一点,比如「与 Windows 一同发布」或者「嵌入 Windows」,233。
[2] Wikipedia – Transport Layer Security
[3] RFC 5246 The Transport Layer Security (TLS) Version 1.2
[4] 65% of top 1,000,000 websites by 2014. Source.
[5] 其实要完全符合标准的话,还要复杂一些。如果你也在使用 nginx,可以参考这条评论进行设置,会更规范一些。

]]>
/p/hsts-preload-list/feed/ 34
室内空气监测 /p/air-mointor/ /p/air-mointor/#respond Sat, 28 Feb 2015 14:25:28 +0000 /?p=348022 GP2Y1010AU0F
左图[1] 是夏普的紧凑型光学灰尘密度传感器 GP2Y1010AU0F (PDF),淘宝三十元不到。

传感器内部有一个 LED,通过检测灰尘对光的反射的强度来估计空气中单位体积内灰尘的质量。
虽然因为无法区分灰尘颗粒的体积,无法直接推算出 PM2.5 数值,但我想它和 PM2.5 之间应该还是比较强的相关性的 来源请求

(嘛 30 块一个东西还是不要想太多比较好。

另一个传感器是 DHT22,淘宝大概 20 元一个。用于测量空气温度和湿度。

去年暑假我把这两个东西用了起来,监测室内空气状况并绘制图表然后显示在网页上。干嘛用?就是玩具,好玩嘛… 如果你也觉得有点意思,想搞个玩玩… 这篇文章也许可以用作参考。

事隔较久,一些细节记不太清了,可能会有些疏漏。相关代码在使用前记得改改文件名路径什么的。

读取传感器

这两传感器都不是面向一般用户的,没有 USB 这样方便的东西呢…
DHT22 是用一根线串行输入输出
GP2Y1010AU0F 输出的是模拟信号,要测量输出口的电压,根据电压来计算灰尘密度(如下图[2])。
电压——灰尘密度图示

DHT22 也许[3]能用 Cubieboard (山寨树莓派) 的 GPIO 来读取。
但 GP2Y1010AU0F 则需要测量电压(A/D),Cubieboard 不带此功能。

于是就用了 Arduino,先用它定时从传感器读取数据,然后通过串口(UART)发送给 Cubieboard
读取传感器的模块:DHT22.cpp DHT22.h, GP2Y1010AU0F.cpp GP2Y1010AU0F.h
每隔三秒读取一次两传感器,从串口输出 的 Arduino 代码:Sensors.ino

储存数据

数据通过 UART 传给了 Cubiebaord,接下来就是想怎么存怎么存啦。
这里按照传统来源请求用 RRDtool 来储存数据。简单方便[4]自带数据库顺带还能把画图给做了。

先用rrdtool create创建数据库:rrd-create.sh
别问我这些参数是啥意思,半年多过去了我早忘了(
RRDtool 也是挺坑的,参数多不说,写出来一点都不直观,不对手册根本不知道这都是些什么鬼(

arduino-uart.py 这个 Python 脚本将持续地从串口读取 Arduino 发来的数据,然后执行rrdtool update往数据库里喂数据。

呈现数据

使用rrdtool graph绘制折线图:graph.sh
./graph.sh 1d 绘制近一天的图像,./graph.sh 1w 绘制近一周的图像。
(输出和数据文件路径请修改开头的DIRDATA变量)

可以使用crontab -e或者 systemd-timer[5] 定时执行脚本更新图像。

再加个网页做索引:index.html
网页上方可选择查看近一天、一周、一个月的数据[6]。这样就基本完成啦。

完成

其实装好后我一直挺担心灰尘传感器的读数是否正确的,没法方法确认,读出来的 µg/cm³ 我也没啥概念。不过这幅大年三十的图看起来倒是挺像回事的:
灰尘折线图(图中数据单位有误,应为 µg/m³)

即使家里门窗紧闭,依然能看到中午一点和午夜的两条高峰。想必是受周边鞭炮燃放的影响吧。

附注

[1] 来源 iMall
[2] 来源 Datasheet PDF
[3] 我不太确定,因为 Cubieboard 的每一个 GPIO 口似乎只能在开机时设置为读或者写二选一,而 DHT22 的读写都在一根线上。也许能用两个 GPIO 口并加少许电路来实现?
[4] 好吧其实一点都不简单方便。
[5] systemd 用户请参考 Gist 中的.timer .service等文件。
[6] 需分别生成日、周、月的图片,参见 [4] 中的三个 .timer 文件。

]]>
/p/air-mointor/feed/ 0
简单的 SSTP 服务器 /p/sstp-server/ /p/sstp-server/#comments Wed, 01 Oct 2014 10:48:23 +0000 https://sorz.org/?p=347963 SSTP (Secure Socket Tunneling Protocol) 是微软开发的一种 VPN 协议,用 SSL/TLS 加密 PPP 流量。参见 使用 SSTP 协议的 VPN 有什么优势和缺陷?

本来没怎么关注这个东西,支持少非主流,IP over TCP,也是因为一些奇怪的事突然有了这方面需求了,才开始了解它。

SoftEther

目前在 Linux,服务器似乎只有 SoftEther 这个实现。这软件也是挺拼的,把各种流行的非主流的 VPN 协议都给实现了一遍,跨平台,GPL。还提供傻瓜化的 GUI 管理,中日英三语界面,简直就是部署 VPN 的大杀器。只是一来太重,二来对 RADIUS 支持不全,不太符合需求。

DIY

因为内部走的是 PPP,如果只是调用 pppd 并转发数据,由 pppd 负责用户认证等麻烦事,自己实现一个目测也不是太复杂。加上微软的官方文档甚详,近来又一直想学一下 Twisted 但又不知如何入手,决定来写一个试试。

托 Twisted 的简单易用,挺顺利地初步完成了这个 SSTP 服务器。

代码放在 GitHub 和 PyPI 上了,sorz/sstp-server
PyPI

安装使用

供参考,详见sstpd --help

sudo apt-get install python-dev python-pip python-twisted
sudo pip install sstp-server
sudo sstpd -c cert.pem --local 10.0.0.1 --remote 10.0.0.0/24

关于证书,请参考 HTTPS 证书相关教程。
别忘了建/etc/ppp/options.sstpd,一个例子:

name sstpd
require-mschap-v2
nologfd
nodefaultroute
ms-dns 8.8.8.8
ms-dns 8.8.4.4

需要 IPv6 支持的,可加参数--listen ::

麻烦

折腾过程中遇到的主要障碍还是关于 PPP 的。简单地转发是不行的,因为每个 SSTP 包中只允许放入一个 PPP frame,需要自行分离出每个 frame。

PPP 这个古老的协议比预想中的要复杂。Windows 在 SSTP 中使用的其实是这个 HDLC-like Framing。找了一份 SSTP 客户端的代码,它是自行对两种格式进行了转换。好在后来发现 pppd 其实自身就支持 HDLC(sync 参数),于是成功偷懒

但后来发现 HDLC 似乎需要 Linux 内核支持(CONFIG_PPP_SYNC_TTY = yes)。

更新:
果然偷懒失败了,用 HDLC 取巧的方法是不行的,偶尔会有 frame 被截断,后面就全乱了。于是还是老老实实地照着 RFC 1662 来做 framing,自行 (un)escape 一些字符。但是这样性能变得很糟糕,试着把这部分用 C 扩展重写了一遍。想来这还是我第一次出于解决问题的需要写 C 呢……

感谢 @deba12 指出了这个问题,并协助测试、改善性能。

安全性

目前这个实现其实是不完整的,没有实现 Crypto binding 部分,导致其可能遭受中间人攻击。

使用了 SSL 还会遭受中间人攻击?微软在文档末尾提供了一个这种攻击的情境,挺有意思的。

攻击者建立一个假 Wi-Fi AP,然后诱骗用户连接。
Wi-Fi 使用 802.11 EAP 进行认证,用户以为他是在登录 Wi-Fi,但实际上,攻击者将这个认证请求转发给了 SSTP(PPP) 服务器!用户确实在和真的认证服务器在对话,只不过认证的不是 Wi-Fi 而是 SSTP 服务。

Crypto binding 可以防止这种攻击,想详细了解请参见微软文档。
但实现这个有些复杂,我这边的使用情境暂时没有这个需求,就先放一放了。
(懒你就直说 _(:з」∠)_

]]>
/p/sstp-server/feed/ 73
OpenWrt VPN 按域名路由 /p/openwrt-outwall/ /p/openwrt-outwall/#comments Thu, 22 May 2014 14:50:23 +0000 https://sorz.org/?p=347911 简述

这是一种基于域名的 VPN 智能翻越方案。不同于 chnroutes 这类通过维护一个 IP 地址列表来区分国内外网站的方案,基于域名的方式不受 IP 地址变动的影响。仅需维护一个相对很少有变化的域名列表即可。

dnsmasq 在 2.66 版之后加入了对 ipset 的支持,可将指定域名的 IP 解析后自动加入某一 ipset 中。 再配置路由规制,使该 ipset 中的 IP 走 VPN 即可。

感谢 @wzyboy 提供了此方案的思路。

大致流程

  • 配置 VPN
  • 配置 dnsmasq,指定域名
  • 增加一个路由表,默认网关为 VPN
  • 使用 iptables 匹配 ipset 并打上 mark
  • 使用 ip rule 将打上 mark 的包送入该路由表

所需软件

  • iproute2
  • dnsmasq (>= 2.66, has ipset)
  • iptables (with ipset and mark modules)

opkg update
opkg install ip ipset kmod-ipt-ipset dnsmasq-full

OpenWrt 默认的dnsmasq包并不包含 ipset 支持,需安装dnsmasq-full(感谢 @leavic 的提醒)。亦可修改 makefile 自行编译,以节省空间。

配置文件

列举一下涉及的各部分配置文件,供参考。

VPN

各类 VPN 均可,请参考 VPN overview。注意请将 VPN 设为默认路由。

rt_tables

添加outwall路由表。 走 VPN 的流量都将使用此表。

echo "200 outwall" >> /etc/iproute2/rt_tables

rc.local

使系统启动时创建一个名为outwall的 ipset。
在 /etc/rc.local 中添加:

# vi /etc/rc.local
ipset create outwall hash:ip

名字可以随便取,与 dnsmasq.conf 和 firewall.user 中的保持一致即可。

firewall.user

将匹配 ipset outwall的包全部标上 mark 8。
在 /etc/firewall.user 中添加:

# vi /etc/firewall.user
iptables -t mangle -A fwmark -m set --match-set outwall dst -j MARK --set-mark 8

打上 mark 以后,就可以指定它们所使用的路由表了。
mark 值可随便选,保持一致即可。若同时装有 qos-scripts,mark 可选一个较大的值,以防与其发生冲突。

VPN Post-connected Script

确保以下脚本在每次 VPN 连接建立后执行。
不同 VPN 的配置方法可能不同。 一个比较通用的方法是使用 Hotplug

(我这次用的是 vpnc,所以比较偷懒地将脚本放在了/etc/vpnc/post-connect.d/下)

#!/bin/sh
ip route add 8.8.8.8 dev $TUNDEV
ip route add default dev $TUNDEV table outwall
ip rule add fwmark 8 table outwall

注意,须将$TUNDEV替换为 VPN 设备名,比如ppp0

这段脚本有三个作用:

  1. 让 8.8.8.8 走 VPN,防止 DNS 污染;
  2. 由于 VPN 断线时相关路由会被自动删除,所以在需要每次连接时添加一次;
  3. ip rule 在 VPN 断线时将手动删除(见下一节),切换至正常路由。

VPN Disconnect Script

见上节说明,须在 VPN 断线时 自动执行的脚本:

#!/bin/sh
ip rule del table outwall

dnsmasq.conf

请参考 dnsmasq man(8)
修改 /etc/dnsmasq.conf,在其中加入需要翻越的域名。 格式如下:

server=/域名/8.8.8.8
ipset=/域名/outwall
  • server将指定域名使用 8.8.8.8 查询(8.8.8.8 已配置为走 VPN,防止 DNS 污染);
  • ipset将指定域名的所有 IP 加入 ipset outwall中;
  • 可在一行添加多个域名,如ipset=/twitter.com/t.co/outwall
  • google.com将同时匹配 google.com 和 plus.google.com。com将匹配所有 .com 结尾域名。

一个可供参考的配置如下, 该配置:

  • 尽可能地让 Google 所有常用服务走 VPN
  • 允许访问 Facebook、Twitter 和 YouTube
  • 让 GitHub 的 CDN 走 VPN
server=/google.com/8.8.8.8
server=/googleusercontent.com/8.8.8.8
server=/gstatic.com/8.8.8.8
server=/googlehosted.com/8.8.8.8
server=/golang.org/8.8.8.8
server=/googleapis.com/8.8.8.8
ipset=/google.com/outwall
ipset=/googleusercontent.com/outwall
ipset=/gstatic.com/outwall
ipset=/googlehosted.com/outwall
ipset=/golang.org/outwall
ipset=/googleapis.com/outwall

server=/twitter.com/8.8.8.8
server=/twimg.com/8.8.8.8
server=/t.co/8.8.8.8
ipset=/twitter.com/outwall
ipset=/twimg.com/outwall
ipset=/t.co/outwall

server=/facebook.com/8.8.8.8
ipset=/facebook.com/outwall

server=/youtube.com/8.8.8.8
server=/ytimg.com/8.8.8.8
server=/ggpht.com/8.8.8.8
server=/youtu.be/8.8.8.8
server=/googlevideo.com/8.8.8.8
server=/youtube-nocookie.com/8.8.8.8
ipset=/youtube.com/outwall
ipset=/ytimg.com/outwall
ipset=/ggpht.com/outwall
ipset=/youtu.be/outwall
ipset=/googlevideo.com/outwall
ipset=/youtube-nocookie.com/outwall

server=/githubusercontent.com/8.8.8.8
server=/github.global.ssl.fastly.net/8.8.8.8
server=/githubapp.com/8.8.8.8
ipset=/githubusercontent.com/outwall
ipset=/github.global.ssl.fastly.net/outwall
ipset=/githubapp.com/outwall

关于 Shadowsocks

(更新于 2014-11-23)

补充说明一下,此方案亦可与 shadowsocks-libev 配合使用,配置起来会比 VPN 简单很多。自己用了几个月,体验良好。这里简单介绍一下配置方法。

1、在 shdowsocks.org 可以下载到已编译的 ipk 包,在 OpenWrt 上安装即可。

2、配置好 Shadowsocks,并运行,注意服务器那边需要支持 UDP 转发(请使用较新版并配好防火墙)。OpenWrt 中使用ss-redir代理 TCP 连接,使用ss-tunnel代理 DNS 查询。具体参数请参考范例:

ss-redir -c /etc/shadowsocks.json -l 1080
ss-tunnel -c /etc/shadowsocks.json -l 5533 -L 8.8.8.8:53 -u

3、在/etc/firewall.user中加入(参考):

iptables -t nat -N shadowsocks
iptables -t nat -A shadowsocks -m set ! --match-set outwall dst -j RETURN
iptables -t nat -A shadowsocks -p tcp --syn -m connlimit --connlimit-above 32 -j RETURN
iptables -t nat -A shadowsocks -p tcp -j REDIRECT --to-ports 1080

iptables -t nat -A PREROUTING -s 192.168.0.0/16 -j shadowsocks

这将使匹配outwall(这个 IPSet)的 TCP 连接指向ss-redir。后者将为这些连接建立隧道并通过 Shadowsocks 协议加密发送。

4、/etc/dnsmasq.conf中不再使用8.8.8.8,而是使用127.0.0.1#5533,范例如下:

server=/google.com/127.0.0.1#5533
ipset=/google.com/outwall

这将使 dnsmasq 将 DNS 查询请求发送至ss-tunnel,后者在将其通过 SS 转送至 Google Public DNS。

由于不再涉及路由,不需要安装配置iproute2,不再需要使用-j MARK打标记。当然,也不用在配置 VPN 及相关脚本。

优点:方便配置,不管是路由器还是服务器。
缺点:只代理 TCP 连接,UDP、ICMP (ping) 等无法使用。

]]>
/p/openwrt-outwall/feed/ 22
半公开 Shadowsocks 架设注意事项 /p/deploy-ss/ /p/deploy-ss/#comments Thu, 17 Apr 2014 10:14:22 +0000 https://sorz.org/?p=347891 作为一个轻量级代理工具,安装配置很方便,基本上照着 README 做就行了。
这里说下在 Linux VPS 上架设半公开 Shdowsocks 服务可能需要用到的两项额外配置

同样由于为了保持轻量,Shadowsocks(这类)工具并不提供访问控制(ACL)和流量控制(TC)功能。 这在某些情景下可能产生安全隐患:公开或半公开帐号,可能有不信任的人使用;服务器上同时运行了其他服务。

禁止访问本机与内网

在 Linux 中,使用 TCP/UDP 在进程间通讯十分常见,比如 MySQL、PHP-FPM、Memcached… 它们在 127.0.0.1 上开一个端口,让其他程序连接。

localhost 只有本地应用才可访问,所以一般认为是安全的。但挂上 Shadowsocks 后,在客户端发起的请求,在系统看来,就是本地应用发出的。

感谢 @lilydjwg 的提醒,可以这么做:

Step 1  以outwall用户身份运行 Shadowsocks

su -c "ssserver -c /path/to/config.json" outwall

或者,Ubuntu 用户可使用 Upstart 运行:

# /etc/init/ssserver.conf
description "Shadowsocks Server"
start on runlevel [2345]
stop on runlevel [016]
setuid outwall
setgid outwall
respawn
exec ssserver -c /path/to/config.json

(日志将保存在 /var/log/upstart/ 下)

再或者,更高大上的 systemd:不会

Step 2  用 owner 模块匹配进程 UID

iptables -A OUTPUT ! -o eth0 -m owner --uid-owner outwall \
    -j REJECT --reject-with icmp-host-prohibited

这样,Shadowsocks 就只能连接外网(eth0)了。

另外,如 @clowwindy 所言单机使用时用 Unix Socket 代替 TCP/UDP 个好主意

2015-03-12 更新:
Shadowsocks (Python) 最新版已可以通过--forbidden-ip IPLIST参数禁止访问指定 IP。

流量控制

之前用美帝的 VPS 就完全不用在意带宽问题.. 少说 100Mbps 多则 1Gbps 的口,不限也大丈夫… 换成港服后就蛋疼了…

试着用 tc/tcng 来做流量控制,似乎挺复杂的,我就说下大致思路吧:
将 SS 的上行流量分两类:发回墙内的 与 发给墙外的
前者优先级低于后者,两者均低于本机的其他服务。

发回墙内的,由于源端口总是为 SS 监听端口,所以直接在 tc 里匹配端口即可;
发给墙外的,端口不一,可用 iptables owner 匹配后打上 mark,再用 tc 匹配 mark。

iptables -t mangle -A POSTROUTING -m owner --uid-owner outwall
    -j MARK --set-mark 2

tc 略复杂啊,我觉得我没法讲清楚了(是你压根就不懂吧喂
有一个坑点需要注意,rate 有两重含义,一个是“保证带宽”,是一个确切的值。另一个是权重,可用带宽会按 rate 的比例分配。

2015-03-12 更新:
如果嫌 tc 麻烦,可使用 iptables 的hashlimit模块来实现限速。

]]>
/p/deploy-ss/feed/ 3
乱发数据包 /p/illegal-send/ /p/illegal-send/#comments Sun, 23 Mar 2014 10:43:58 +0000 https://sorz.org/?p=347865 这是去年写的一个用于干扰教学的工具。

Computer Networks 这门课,需要用到 Wireshark 这个抓包软件查看网络流量。
写了这玩意,通过广播一些特制的数据,可以在其他人的机子上刷出点有趣(?)的东西:在 Wireshark 上刷奇怪的东西

如图,一眼就能看出不正常.. 其实就是乱发 HTTP Response,并把原来显示状态码(200、404 …)的部分,改成了其他文字…

由于需要发,用了 WinPcap,它提供了一些 API 能够比较方便地跳过系统的协议栈,让网卡发送完全自定义的数据。这里使用了它的一个 Python 绑定 winpcapy

最后需要发送的是以太网帧,也就是说,要自己从 HTTP、TCP、IP 一路构建下来。为了简化工作使用了 dpkt ,里面提供了丰富的协议支持,能很方便地构建数据包。

一点小细节:Wireshark 会分析 TCP 协议,并把不正常的包用红色标出。为了避免这样,每个包的目的端口都是随机选取的,让 Wireshark 认为每个包都属于不同的 TCP 会话。当然换成随机的 IP 也没问题。

代码贴 Gist 上了 Gist 9721330

玩法:

  1. 下载安装 Python 2.7 和 WinPcap
  2. 下载打包的好的工具;
  3. 运行net_test.py得到网卡列表和对应的地址(e.g rpcap://\Device\NPF_{x-x-x-x-x});
  4. 运行net_test.py rpcap://\Device\NPF_{x-x-x-x-x}发送。
    完整用法是net_test.py <interface> [repeat_times [message]],可选重复次数与消息内容(默认是 5 次、发送随机表情)。

注意需要管理员权限,系统如有开 IP Forwarding 功能需关闭

代码不复杂,想玩更多花样可以自己改..
注意这样不按协议标准发数据的事.. 还是少做得好.. 玩玩就好,切勿滥用..

]]>
/p/illegal-send/feed/ 4
重构 ASS to SRT 字幕转换工具 /p/asstosrt/ /p/asstosrt/#comments Sat, 22 Feb 2014 14:22:27 +0000 https://sorz.org/?p=347827 重写了一遍两年前初学蛇语时写的字幕转换工具(ASS 字幕批量转 SRT)。

当时因常用某三星电视看动画,有这个需求。此外还想学下 Python,于是挖了这个坑..
自从最近把 VPS 邮件转发至 Gmail 后,不断被此坑在线版的错误报告骚扰,一翻代码,太羞耻了简直丑陋,决定换掉…

原有的功能都还在:批量、繁简转换、删特效字幕、仅保留首行、重排序、识别/指定编码。字幕重排序由可选改为强制启用。默认输出编码由 UTF-16 改为与源文件相同。兼容 Python 2.7 / 3.x。
不自带chardetlangconv这两个可选依赖了。后者为繁简转换所需,不在 PyPI 上,可在此处下载

非发烧用户请直接戳 在线版 就好了。
虽然网页还是旧的,内部已经换上了全新的 asstosrt。

Python 用户请直接:

pip install chardet
pip install asstosrt
asstosrt --help
]]>
/p/asstosrt/feed/ 9