GRE / IPIP Tunnnel

#GFW促进学习系列#

假如有多个VPS,那么将这些VPS连接起来的最佳方式是 GRE / IPIP tunnel

Tunnel

VPS A: 假设 IP 1.2.3.4

ip tunnel add tunnelName mode gre remote 2.3.4.5
ip addr add dev tunnelName 192.168.20.1/24
ip link set dev tunnelName up

VPS B: 假设 IP 2.3.4.5

ip tunnel add tunnelName mode gre remote 1.2.3.4
ip addr add dev tunnelName 192.168.20.2/24
ip link set dev tunnelName up
  • 设置完成后,VPS A 上的隧道IP是 192.168.20.1,VPS B 上的隧道IP是 192.168.20.2
  • 只需启动时执行一次,隧道建立后自动在内核运行,无任何用户态守护进程
  • 使用 “ip tunnel del tunnelName” 删除隧道。
  • “gre” 可以换成 “ipip”,理论上 ipip 模式 overhead 更低,性能更好。但我实际测试时发现某些网络环境上 ipip tunnel 性能低下,可能因为网络某些节点的QoS策略。

Routing

在 VPS A 上建立路由表,通过与 VPS B 的 tunnel 访问 Internet:

VPS A

ip route add default dev tunnelName table 100
# 对特定流量走 tunnel
ip rule add iif tun0 table 100 prio 100

VPS B 上需要用 iptables 打开 MASQUERADE (SNAT)。

应用场景:你的本地网络连接 VPS A 更快,但某些设置区域限制的网站只有 VPS B 能够访问(如 hulu / DMM 等日本很多18禁网站)。通过上面这种方式本地首先用 VPN 连接 VPS A,然后在通过 Tunnel 实际由 VPS B 去访问目标网站。

ゾンビのあふれた世界で俺だけが襲われない

18禁网络小说站点人气投稿作品改编的同人gal. 原著小说, 批评空间, DMM, CG

ブランド SEACOXX
発売日 2015-02-20
18禁等 18禁/非抜きゲー/陵辱もの
対応OS Vista , 7(32bit) , 8
原画 サブロー
シナリオ 裏地ろくろ
音楽 solfa
声優 葉月雨(藤野 深月)
その他 飯島武士(エグゼクティブプロデューサー) , ROS(ゾンビデザイン) , よじろー(ゾンビデザイン) , 長内佑介(ゾンビデザイン)

游戏剧情到小说第2章结束. 最后竟然把弟弟 (優, まさる)写死了, 真是太惨了.

Screenshot 2015-06-26 00.13.00

301_0314

原著小说貌似停更了, 续篇无望.

PS. 刚发现游戏竟然出汉化了…

NOGIBINGO!

最近迷上了11区的综艺节目,于是去注册了一个 hulu.jp 账号,专门找「バラエティ」类型的节目看- -。虽然很多节目里面有一些恶趣味的元素,不过总体而言还是蛮搞笑的,能够轻松愉快地观看。

其中我最喜欢的综艺节目就是「NOGIBINGO!/NOGI ROOM ~乃木坂46がパジャマで女子トーク~」,看了这个后我对日本那堆组团刷的女性艺人团体的印象大有改观,也去找了些 AKB48、HKT48、SKE48、乃木坂46的专辑来听听,感觉都还蛮不错的。

截几张「NOGIBINGO!4」最新一期节目的图

乃木坂46の自宅映像でクイズを出題 ジタック46▽初々しすぎ! 中元13歳時の映像公開▽もはやお仕置き!? 星野家の熱湯風呂にメンバー唖然…。
シーズン 4 エピソード 10 (22 分)
放送日 2015/06/08

Screenshot 2015-06-09 12.48.39

Screenshot 2015-06-09 12.49.35

Linux 策略路由与多 VPN 并存最佳实践

#GFW促进学习系列

以在路由器上配置为例.

需要 iproute2, 部分设备 (如某些 ddwrt 路由固件默认并不支持, 可能需要自己编辑安装 iproute2 包). 各个脚本路径与所用设备及系统有关, dd-wrt 固件参考 Wiki)

Startup 脚本
在设备 startup 脚本里, 创建策略路由的 ip rule 规则

ip rule add from all fwmark 0x1/0x1 table 1 prio 1
ip rule add from all fwmark 0x2/0x2 table 2 prio 2
ip rule add from all table 3 prio 3
ip rule add from all table 4 prio 4
ip rule add from all table 5 prio 5

# table 10 及以上的路由表留给 VPN, 每个 VPN 一个

# 创建内网的路由规则, 避免被后面的 VPN 全局路由表覆盖
ip rule add to 192.168.0.0/16 table main prio 1
ip rule add to 127.0.0.0/8 table main prio 1
ip rule add to 169.254.0.0/16 table main prio 1

chnroutes
推荐用这个版本, 使用 iproute2 batch 批量导入路由表, 几千条国内路由只需要一秒即可加载完毕. 需要修改下 chnroutes.py, 使其生成的 vpn-up.sh 脚本把路由项加载在 table 4 而非默认路由表上.

chnroutes.py

    upfile.write('route add %s/%s $OLDGWn' % (ip, mask))

改为

    upfile.write('route add %s/%s $OLDGW table 4n' % (ip, mask))

pppoe 脚本
在设备 pppoe 拨号成功脚本里, 创建与外网 NIC 相关的路由规则

# 这个命令结果类似 'via 1.2.3.4 dev ppp0 ', 1.2.3.4 是你的 pppoe 远端网关 (P-t-P IP)
WAN_GW=$(ip route show 0/0 | sed -e 's/^default//')

# table 1: 使拥有 0x1 MARK 的数据包全部走默认网关
ip route add default $WAN_GW table 1

# table 3: 在这里加入所有 VPN 的服务器 IP, 使这些 IP 都直接走默认网关.
ip route add A.B.C.D/32 $WAN_GW table 3
....

# table 4: 加载 chnroutes
/path/to/chnroutes/vpn-up.sh

VPN 脚本
在每个 VPN 的连接成功脚本里增加对应的路由规则. OpenVPN 请把 redirect-gateway 选项去掉, 使用 “up up_script.sh” 执行下面的自定义路由脚本

# 192.168.100.1 是该 VPN 的网关地址
ip route add default via 192.168.100.1 table 10

# 或者使用 tun 接口名指定, 如果配置 VPN 使用固定 tun device name 的话
# ip route add default dev tun0 table 10

P-t-P link

root@debian:/etc/openvpn# ip addr show tun0
19: tun0:  mtu 1411 qdisc pfifo_fast state UNKNOWN qlen 100
    link/none 
    inet 192.168.100.2 peer 192.168.100.1/32 scope global tun0

对于上面这个tun设备 (OpenVPN 创建),本地 IP 是 192.168.100.2, 远端链路IP (P-t-P IP)是 192.168.100.1,P-t-P 与路由的 next hop (下一跳)概念不同。例如,对 ip route add 1.2.3.4/32 via 192.168.100.1 这条路由表,系统会直接将 packet 发送到对应的 tun 设备上。对于 192.168.100.1 这个 IP (或其所属虚拟网段) 本身的访问路由规则默认是在 main 表里自动添加的

192.168.100.1 dev tun0  proto kernel  scope link  src 192.168.100.2
# or
192.168.100.0/24 dev tun0  proto kernel  scope link  src 192.168.100.2

添加路由规则时, 使用 via 参数指定同一网段内的网关 (Gateway IP) 或 P-t-P 链路的远端IP。

ip route add A.B.C.D/32 via 192.168.100.1

PS. 这种情况下会自动根据 via 后面的地址计算出此条路由规则所属 interface 设备名; 貌似即使 tun 虚拟网卡没有指定对应的 P-t-P IP (ifconfig tun0 192.168.100.2 netmask 255.255.255.0 pointopoint 192.168.100.1)时仍然有效.

如果使用这种形式:

ip route add A.B.C.D/32 dev tun0

则直接设置数据包外发接口。

可以使用 “src 192.168.100.2” 设定数据包从接口发出时设置的源 IP (貌似一般无必要?).

NAT
设置 VPN 的 NAT 以及防火墙规则

iptables -I FORWARD -i br0 -o tun+ -j ACCEPT
iptables -I FORWARD -i tun+ -o br0 -j ACCEPT
iptables -I FORWARD -i br0 -o ipsec+ -j ACCEPT
iptables -I FORWARD -i ipsec+ -o br0 -j ACCEPT
iptables -t nat -A POSTROUTING -o tun+ -s 192.168.1.0/24 -j MASQUERADE
iptables -t nat -A POSTROUTING -o ipsec+ -s 192.168.1.0/24 -j MASQUERADE

# net.ipv4.ip_forward 不用设了, 路由器肯定是打开的.

MTU / MSS 相关
关于 TCP 连接的 MSS negotiation:

Each system announces its MSS, and the other system abides by it. When computer A sends a SYN packet with an MSS of 1,460 and computer B responds with a SYN/ACK that has an MSS of 1,380, computer A is not “proposing” that they use 1,460, and computer B is not countering with a different proposal; they are simply each announcing their own limit. B will not send any packets with a segment larger than 1,460 bytes to A, and A will not send any packets with a segment larger than 1,380 bytes to B. (There is no requirement that B send 1,460 byte segments to A; only that B not EXCEED 1,460 bytes. B can limit itself to 1,380 bytes if it chooses.). TCP 会话的一方应该会取对方告知的 MSS 和自己外发数据网卡 MTU – 40 这两者之中的较小值作为每次发送数据字节数.

只有 OpenVPN 提供 mssfix 选项, 其它 VPN 基本上都不支持设置 TCP 的 mss. 所以最好的方式是在用 iptables 统一设置所有通过 VPN tunnel 的 TCP 连接的 mss

# 自动将所有通过设备转发的数据包 TCP 连接的 mss 设为 tun MTU - 40 (理论最优值, 40 是 IPv4 Header + TCP header 长度) (如果是 IPv6, IP header 长度是 40)
iptables -t mangle -A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

应该只需要在路由器 或者 VPN 服务器其中之一设置即可, 貌似 ddwrt 路由器默认 iptables 规则已经包含着一条. 说明:
The –clamp-mss-to-pmtu automatically sets the MSS to the proper value, hence you don’t need to explicitly set it. It is automatically set to PMTU (Path Maximum Transfer Unit) minus 40 bytes, which should be a reasonable value for most applications.

Path Maximum Transfer Unit: 整个链路中各节点 MTU 的最小值. iptables 应该是将收到的数据包 -i 和 -o 两个 interface MTU 其中的较小值作为 PMTU.

然后设置 VPN tun 设备的 MTU, 许多 VPN 都提供了对应的配置参数 / 选项, 也可以直接用 iproute2 设置

# OpenVPN 配置 MTU 参数
tun-mtu 1400

# 通用
ip link set dev tun0 mtu 1400

需要保证 VPN 隧道经过封装后的数据包实际通过外网连接时不超过链路实际 MTU. 测试 tun MTU:

# 假设 tun 设备 MTU 设置为 1450
# 1450 - 20 (IPV4 header) -8 (ICMP header) = 1422
ping 8.8.8.8 -s 1422 -M do

如果能正常 ping 通, 则表示无问题.

对于 OpenVPN 而言, 最好的设置 MTU 方法是设置 link-mtu 参数, 将其修改为实际 Internet 网络链路MTU (1492 for pppoe) – 28 (IPv4 + UDP header), 客户端和服务器端均需要配置. 然后 OpenVPN 会自动设置生成的 tun MTU 为合适的值.

做完这些后, 多个 VPN 可以同时连接 (测试方法是能 ping 通每个 VPN 的远端 Gateway IP: ping 192.168.100.1).

策略路由
可以自行设置哪些流量走哪些 VPN.

# 优先级 (prio) 较小的路由规则优先匹配
ip rule add from all fwmark 0x4/0x4 lookup 10 prio 10
ip rule add from all lookup 11 prio 11

配合 iptables 对指定的转发流量打标记:

iptables -t mangle -A PREROUTING -j MARK --set-mark 0x4/0x4

备注:

iptables -t mangle 表里, 设置 MARK 必须在 PREROUTING / OUTPUT 里做 (因为显然必须在路由选择之前); 而设置 TCP mss 则最好在 FORWARD里做 (不适合在 POSTROUTING , 因为本机发出的数据包也会经过 POSTROUTING. 而本机发起的 TCP 连接 MSS 是自动设置为合适的值的, 不需要 iptables 再重复设置了).

设置和匹配 MARK 相关命令中的 0x4/0x4 这种写法表示对 MARK 中的某个比特位进行匹配。这样允许 MARK 里不同比特位的标记安全并存。注意 iptables 的 MARK target 不会停止遍历当前 chain。

Strongswan ikev2 VPN 配置

Why

  • ikev2 支持 mobike, 会极大提高 VPN 连接稳定性. (基本不掉线, 即使是移动设备上在 Mobile Network 和 Wifi 之间切换时.)
  • 基于 ipsec (第三层协议), 受到的干扰较小 (至少目前).

Server (Linux) (假设 IP 为 1.2.3.4)

参考 linux上用strongswan搭建ikev2协议vpn 编译安装 Strongswan (必须是 5.0+版本, Debian / Ubuntu 的 repository 里貌似只有 Strongswan 4), 生成服务器端的 CA 和 server 的证书和密钥 (caCert.pem, caKey.pem, serverKey.pem, clientCert.pem)并放到 “/etc/ipsec.d/” 里对应目录下. (client 端证书可以不需要, windows 7 以及 Linux / Android 上的 Strongswan 客户端均可以使用 eap-mschapv2 方式用户名 / 密码验证.)

/etc/ipsec.conf

config setup
    uniqueids=no #允许多设备同时在线

conn ipke2vpn 
    keyexchange=ikev2
    ike=aes256-sha1-modp1024!
    esp=aes256-sha1!
    dpdaction=clear
    dpddelay=300s
    rekey=no
    left=%defaultroute
    leftsubnet=0.0.0.0/0
    leftauth=pubkey
    leftcert=serverCert.pem
    leftid="C=US, O=strongSwan, CN=1.2.3.4"
    right=%any 
    rightsourceip=192.168.250.0/24
    rightauth=eap-mschapv2
    rightsendcert=never
    eap_identity=%any
    auto=add

/etc/ipsec.secrets

: RSA serverKey.pem
: PSK "Password"
username: EAP "Password"
username: XAUTH "Password"

‘: PSK “Password”‘ 这行是 L2TP / IPsec VPN 的配置. IKEv2 可以不需要.

/etc/strongswan.conf

charon {
        dns1 = 8.8.8.8
        dns2 = 8.8.4.4
}

Server 端通用 VPN 配置 (PPTP / OpenVPN / L2TP 等通用, 只要 VPN 设置的虚拟IP段属于 192.168.0.0/16)

sysctl -w net.ipv4.ip_forward=1
iptables -t nat -A POSTROUTING -s 192.168.16.0/16 -j MASQUERADE

配置完后, 系统启动时应该自动开启 VPN Server, 你也可以手工启动 / 关闭 VPN

ipsec start
ipsec stop
ipsec start --nofork # 将 log 输出到当前终端用于调试.

Windows 7 / 8 Client

使用系统自带的 VPN Client

导入服务器生成的 CA 证书: mmc -> File -> Add / Remove Snap-in -> 左侧选择 Certificates -> 点击 Add 按钮 -> 选择 “Computer Account” (重要) -> Local Computer -> OK. 然后右击左侧列表里 “Trusted Root Certificates” -> All Tasks -> Import, 选择 caCrt.pem 文件并导入.

  • 只需要导入 CA 证书. Server 证书客户端不需要
  • 必须使用上面的方式导入证书. 直接使用 “certmgr.msc” 导入的证书属于 “Current User”, 无法被 VPN 连接使用.
  • 你也可以使用可信 CA 签发的 Server 证书 (如 SartSSL), 这样所有 VPN 客户端 均不需要导入 CA.

在 Windows 系统网络管理面板里建立一个 VPN 连接, “Host name or IP address of destination” 里填写 VPN Server 的 IP 地址 1.2.3.4. VPN 连接配置如下:

Screenshot 2015-03-16 11.16.27

连接时, 输入服务器 ipsec.secrets 里 配置的 EAP 方式的用户名和密码 “username”, “Password”.

Android

使用 Strongswan VPN Client 应用.

将 CA 证书文件 caCrt.pem 复制到 Android 内置存储里, 然后在 Settings -> Security -> Install from internal storage 导入.

Strongswan VPN Client VPN Profile 配置

android_strongswan_ikev2_config

  • Android 系统导入根证书后, 有时会弹出 “Network may be monitored” 的 notification. 屏蔽方法是安装 Xposed 框架的 “Network Monitored Blocker” module.
  • Android 的 Strongswan 客户端使用了 Android 的 VPN API, 每次连接 VPN 时都会提示用户确认. 自动连接的方法是安装 XPosed 的 “VpnDialog Xposed module” 并在 module settings 里将 “Strongswan VPN Client” 这个应用加入列表. (但每次连接 VPN 时仍然会有个 toast 消息, 无法消除)
  • Android 4.4.2 及以下版本存在 Bug, 会导致 Stronswan 连接 VPN 后若较长时间不使用, VPN 会断开, 但 Notification Area 里仍然存在 “VPN Connected” 的消息无法消除, 并且无法重新连接 VPN, 必须重启设备. 解决这个 Bug 的唯一方法是升级到 Android 4.4.3 或 5.0.

Linux Strongswan ikev2 client

适用于桌面 Linux / 路由器等设备, 将 Strongswan 配置为 VPN Client 模式.

编译安装 Strongswan. 将 VPN Server 的 CA 证书 caCrt.pem 复制到 /etc/ipsec.d/cacerts/ 里.

/etc/ipsec.secrets 与 服务器端的完全相同.

/etc/ipsec.conf

conn ikev2-rw
    keyexchange=ikev2
    ike=aes256-sha1-modp1024!
    esp=aes256-sha1!
    right=1.2.3.4
    rightid=%1.2.3.4
    # 部分 strongswan 版本可能上面那行无效,需要明确指定 rightid 为服务端设置的 leftid  值
    #rightid="C=US, O=strongSwan, CN=1.2.3.4"
    rightsubnet=0.0.0.0/0
    rightauth=pubkey
    leftsourceip=%config
    leftsendcert=never
    leftauth=eap-mschapv2
    eap_identity=username
    auto=start

另外, 我发现 Linux 连接 ikev2 VPN Server 后, 会无法访问本地局域网内其他机器, 貌似因为 ikev2 VPN 自动添加的路由表 (table id 和优先级都是 220. ip route show table 220) 比系统默认路由表优先级高. Workaround:

    ip rule add from 192.168.0.0/16 table main prio 1

如果想共享 VPN Connection 给局域网内其它机器:

    sysctl -w net.ipv4.ip_forward=1
    iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o ipsec+ -j MASQUERADE

则其它机器将 Gateway 设为 192.168.1.2 即可自动通过 VPN 访问 Internet. 还可以再加上 chnroutes.

Update:
某日更新后发现 Linux strongswan ikev2 客户端连接不会创建单独的虚拟网卡了,而直接将获取的虚拟 IP 追加绑定到默认网卡 (eth0)上(使用 ip address 可以看到)。那么客户端的NAT规则就不能写 MASQUERADE 了,必须写

    # 192.168.250.2 是客户端分配到的虚拟网段地址
    iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to 192.168.250.2

很麻烦。不知道能不能设置回让 strongswan 单独创建一个虚拟网卡。

キミのとなりで恋してる!

目前在推这作, 可能最近拔作玩多了, 遇到这种纯爱日常(废萌?)的反而感觉不错.


星野 なぎさ (ほしの なぎさ) CV:歩サラ
小松 莉奈 (こまつ りな) CV:秋野花
知花 涼香 (ちばな りょうか) CV:香山いちご
関谷 恵 (せきや めぐみ) CV:あじ秋刀魚

可惜妹妹不能推, ALcot 社好像也从不出 FD 之类的东西, 所以只能遗憾了.

Screenshot 2014-12-19 22.13.57

PS. 我游戏玩得少, 感觉这货和春季限定有点像, 看 Staff 表脚本也不是同一个人啊, A社喜欢玩这种男主因故退出自己擅长领域社团的设定吗.

PS2. (2014.12.21)
感觉个人线好短, scene 也只有 3个 (每个女主). 这货定价 6800 日元, 应该不是小品作啊.

莉奈线里, 学姐说莉奈像”オオバナノエンレイソウ”, 虽然可能需要很多年才会开花, 但一旦开花后, 就会每年一直绽放出美丽的花瓣.
オオバナノエンレイソウ: 大花延齢草、Trillium camschatcense, 多年生草本植物. 北海道大学采用其作为校章图案.

本作剧本作者”おぅんごぅる“据说是”おるごぅる“老师(业界有”妹神”之称的妹系作品剧本作者, 之前因病引退. 其执笔作品包括”纯白交响曲”(学姐和红毛线), “实妹相伴的大泉君”, “死神之吻乃离别之味”等)的复出马甲.