Update on Building GRE Tunnel to break wall

Make it more automatic and reduce usage of rc.local

VPS A

cat /etc/network/interfaces

1
2
3
4
5
6
7
8
9
10
auto xxxx
iface xxxx inet tunnel
address 10.18.20.1
mode gre
endpoint <VPS B global IP>
dstaddr 10.18.20.2
local <VPS A global IP>
ttl 255
netmask 255.255.255.0
#post-up /sbin/ip route add 0.0.0.0/0 table 230 dev xxxx

cat /etc/network/if-up.d/xxxx-up

1
2
3
4
5
6
7
8
9
10
11
12
#!/bin/sh
# filename: xxxx-up
set -e
if [ "$IFACE" = xxxx ]; then
echo "==="$(date) "\n$IFACE up" > /var/log/xxxx-up.log
echo "$(/sbin/ifconfig $IFACE)" >> /var/log/xxxx-up.log
/sbin/ip rule add from 172.16.9.0/24 table 230 ## 172.16.9.0/24 is the vpn client subnet of VPS A
/sbin/ip route flush table 230
/sbin/ip route add 0.0.0.0/0 table 230 dev xxxx
/bin/bash /root/scripts/routes-up.sh
fi

head /root/scripts/routes-up.sh

The file is modified from https://github.com/sabersalv/freedom-routes, by appending “table 230” to each line

1
2
3
4
5
6
7
8
9
10
11
#!/bin/sh
export PATH="/bin:/sbin:/usr/sbin:/usr/bin"
gateway=$(/sbin/ip route show 0/0 | /bin/grep via | /bin/grep -Eo '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+')
ip -batch - <<EOF
route add 1.0.1.0/24 via $gateway table 230
route add 1.0.2.0/23 via $gateway table 230
route add 1.0.8.0/21 via $gateway table 230
route add 1.0.32.0/19 via $gateway table 230
route add 1.1.0.0/24 via $gateway table 230

cat /etc/network/if-down.d/xxxx-down

1
2
3
4
5
6
7
8
9
10
#!/bin/sh
# filename: xxxx-down
set -e
if [ "$IFACE" = xxxx ]; then
echo "==="$(date) "\n$IFACE down" > /var/log/xxxx-down.log
/sbin/ip rule del from 172.16.9.0/24 table 230
/sbin/ip route flush table 230
/sbin/ip route add default table 230 dev eth1 ## eth1 is the default global interface
fi

cat /etc/iproute2/rt_tables

1
2
3
4
5
6
7
8
9
10
11
12
#
# reserved values
#
255 local
254 main
253 default
0 unspec
#
# local
#
#1 inr.ruhep
230 outwall

VPS B

cat /etc/network/interfaces

1
2
3
4
5
6
7
8
9
auto xxxx
iface xxxx inet tunnel
address 10.18.20.2
mode gre
endpoint <VPS A global IP>
dstaddr 10.18.20.1
local <VPS B global IP>
ttl 255
netmask 255.255.255.0

iptables -t nat -nvL

1
2
3
Chain POSTROUTING (policy ACCEPT 27761 packets, 1696K bytes)
pkts bytes target prot opt in out source destination
9949 1112K MASQUERADE all -- * * 10.18.20.0/24 0.0.0.0/0

Build GRE tunnel to break wall

TLDR; GRE tunnel still works.

Since the GFW has improved eventually, it seems that it could do some in-depth detection on long-connection unknown traffic passing through the country internet border.

Say I have VPS A and B, VPS A is within the wall and VPS B is in another country.

Configs as below, and enable ipv4.forward, no need to mention again.

On VPS A:

cat /etc/rc.local

(exec /home/feuvan/scripts/gre.sh)

gre.sh

NAME=xxxx
REMOTE=<IP of VPS B>

ip tunnel add $NAME mode gre remote $REMOTE
ip addr add dev $NAME 10.18.20.1/24
ip link set dev $NAME up

/etc/iptables/rules.v4, for iptables-persistent

# Generated by iptables-save v1.4.21 on Wed Oct  7 21:41:32 2015
*mangle
:PREROUTING ACCEPT [165069:36215370]
:INPUT ACCEPT [55774:15585668]
:FORWARD ACCEPT [109295:20629702]
:OUTPUT ACCEPT [64319:8616282]
:POSTROUTING ACCEPT [173614:29245984]
-A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
COMMIT
# Completed on Wed Oct  7 21:41:32 2015
# Generated by iptables-save v1.4.21 on Wed Oct  7 21:41:32 2015
*nat
:PREROUTING ACCEPT [30:1332]
:INPUT ACCEPT [30:1332]
:OUTPUT ACCEPT [19:1309]
:POSTROUTING ACCEPT [19:1309]
-A PREROUTING -i eth1 -p tcp -m tcp --dport 8080 -j DNAT --to-destination 10.18.20.2:8080
-A POSTROUTING -d 10.18.20.2/32 -p tcp -m tcp --dport 8080 -j SNAT --to-source 10.18.20.1
COMMIT
# Completed on Wed Oct  7 21:41:32 2015
# Generated by iptables-save v1.4.21 on Wed Oct  7 21:41:32 2015
*filter
:INPUT ACCEPT [484280:623851754]
:FORWARD ACCEPT [872982:650674202]
:OUTPUT ACCEPT [574608:63020814]
COMMIT
# Completed on Wed Oct  7 21:41:32 2015

On VPS B,

grep -e "^[^#]" 3proxy.cfg

nserver 8.8.8.8
nscache 65536
users SOMEBIGSECRET
daemon
log 3proxy.log D
logformat "L%d-%m-%Y %H:%M:%S %z %N.%p %E %U %C:%c %R:%r %O %I %h %T"
rotate 30
auth strong
deny * * 127.0.0.1,192.168.1.1
allow * * * * *
proxy -n -a -p8080

gre.sh

NAME=xxxx
REMOTE=<IP of VPS A>

ip tunnel add $NAME mode gre remote $REMOTE
ip addr add dev $NAME 10.18.20.2/24
ip link set dev $NAME up

So when user hits VPSA port 8080, the traffic is pass through to VPS B via the GRE tunnel xxxx, which is still not affected by GFW.

And the long connection between your device and VPS A won’t be monitored by GFW either.

Enjoy.

Why IDE matters

It has been a long time since I became a coder, or a programmer if you don’t like naming it as coder. When in THU I was working on my own time, playing with some small tools/scripts, happily doing some cracks while playing games and hanging out with friends/girls. It was so called “coding for fun” time. After graduation I have to act as a society cell, began working for companies. Since then productivity overcomes fun, takes higher priority when make decisions. It’s a comparable question like business opportunity versus doing cool things for startup guys. You may have double shot, but most of the times you have to choose one of them.

To coders the most frequently used tool is their IDE. Well, somebody may say editor! or V.. or Em…. whatever. For me, IDE is the most important thing because it provides design time check.

Let’s overview part of the develop process again: you get design doc from pm or funny/crazy/important ideas pop up in your mind, then you have a general idea on how to implement then code. Sometimes you work with new technology/toolchain/environment, then design time check makes sense. Even if you are expert on the very familiar domain, it helps.

Today several advanced IDE can do something like intelligent check of possible bugs based on context and trying to defer the designer’s purpose. And yes, I mean Visual Studio or Xcode, these kind of resource consuming monsters. They can help you find basic errors like syntax error, spell error, and common errors like off-by-1, uninitialized usage of variables, infinite loop. Then you try compile, compiler gives you compile time check. The code/design again, compile again. These steps iterates until you’ve completed the work then deliver it to test role, tester/qa or yourself if you are building some kinds of tools for fun.

Following this process, if you have many times of switching between code/design and compile, you will mostly lost track if compile takes time…As it has been reported on media or you have realized, you may be distracted on sns/im/twitter/fb. Then after a short time you find that it’s time to go home or have lunch. But even if you are concentrated on your task and working very hard, IDE can help you work in a better way, save your precious time by reducing possibile bugs from the very beginning design time. And you have more confidential if there’s no warning shown when writing plain code or playing elements in UI designers.

Handle URL open from other apps in iOS

For short, declare UTImportedTypeDeclarations(for types that are not predefined as System Uniform Type Identifiers), CFBundleDocumentTypes in Info.plist, UIApplicationLaunchOptionsURLKey in

[launchOptions valueForKey:UIApplicationLaunchOptionsURLKey]

And for multitask apps, additionally respond to

(BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation // for iOS 4.2+

or

(BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url // for iOS 2.0+, deprecated.

One little trick to handle ALL file types:

<key>CFBundleDocumentTypes</key>
<array>
    <dict>
        <key>CFBundleTypeName</key>
        <string>All Files</string>
        <key>LSItemContentTypes</key>
        <array>
            <string>public.data</string>
            <string>public.content</string>
        </array>
    </dict>
</array>

remove a symbol from multiple platform Mach-O file

For Mach-O fat binaries that contains multiple platforms, stripping symbol may not work as you would expect.
So you have to extract the executables/libraries from Mach-O and thin it using lipo. Then you can remove the .o file you don’t like by “ar -d <.a> <.o>” or strip the symbol by “strip” which is no longer necessary.
After that, do the reverse steps to pack it back to a multiple platform Mach-O file.

Well, this post may be the last post this year.

zzxy.feuvan.net reloaded.

with telnet/ssh/web.

Thanks to ipv6, tunnel by he.net.
And datapipe6.c, lol.

As nginx mod_proxy doesn’t support ipv6 upstream, here is the workaround:
datapipe6 localhost 56789 2001:da8:200:900e:200:5efe:a66f:480c 80
And nginx config:

server {
listen 80;
server_name zzxy.feuvan.net;

location / {
proxy_pass http://localhost:56789;
proxy_set_header X-Real-IP $remote_addr;
proxy_cache_valid 10m;
}
location ~* .(jpg|jpeg|bmp|png|gif|mp3)$ {
proxy_pass http://localhost:56789;
proxy_set_header X-Real-IP $remote_addr;
proxy_cache two;
proxy_cache_key “$scheme$host$request_uri”;
proxy_cache_valid 600m;
}
}

Cernet sux.