Friday, January 25, 2013

Install Golang and Compile Shadowsocks-go On iPhone


My last blog talked about how to create a Socks 5 proxy with shadowsocks-nodejs and shadowsocks python version on iPhone,  well, they all work perfectly only that the nodejs version costs too much of  RAM and python version is a little bit slow, however, thanks to  , we got golang version of shadowsocks, it has the same speed(maybe better) with nodejs version but cost very little RAM, so i choose the golang version for my daily use and nodejs version as a backup. Okay, let's begin to install google go language and shadowsocks-go on iPhone,  i believe i am the first person to do this.

一篇博客介绍了如何在iPhone上利用shadowsocks-nodejs和Python版创建Socks 5代理,他们运行的很好,只是nodejs版本消耗内存太多而Python版因为缺少gevent而比较慢,还好有人开发了Go版的,它拥有nodejs版的速度,却只用少量的内存,所以我现在主要用Go版的,nodejs版的作为备用。下面就开始在iPhone上安装Google Go 的编译环境和并编译shadowsocks-go for iPhone,我应该是第一个这么做的吧 :)

If you want to be lazy, you can download compiled binary of shadowsocks-go client, it can only run inside  jailbreak iPhone, iPad and iPod Touch
果你想偷懒,可以直接下载我编译好的,只能在越狱的iPhone,iPad,iPod Touch上使用。

Install Google Golang on iPhone


  • SSH into iPhone and run the following command:


wget http://cydia.radare.org/debs/go_15490_iphoneos-arm.deb

sudo dpkg -i go_15490_iphoneos-arm.deb


  • Now we have go languages installed, thanks +minux ma  for porting Golang to iOS, also thanks @trufae for making a working .deb package, they made it easy to install go on iPhone. However @trufae forgot to sign it's package, so we need to sign it after installation,
  • SSH into iPhone and run:

sudo apt-get install ldid
sudo ldid -s /var/go/bin/go
sudo ldid -s  /var/go/src/cmd/*
sudo ldid -s  /var/go/pkg/obj/cmd/* 

Config Google  Golang on iPhone


  • We need to add go to our PATH and also set GOPATH variable, GNU coreutils could help, it can set alias, PATH, export some variable and so.

mkdir ~/gosrc
sudo apt-get install coreutils

  • Next, we need to edit /etc/profile.d/coreutils.sh with vim or nano:

sudo vim /etc/profile.d/coreutils.sh

  • Add the following codes and save:


export GOPATH="/var/mobile/gosrc"
export GOROOT="/var/go"
export PATH="/var/go/bin:$PATH"

  • Now make our settings on the fly:

source /etc/profile.d/coreutils.sh 

Compile Shadowsocks-go on iPhone


  • Download Shadowsocks-go source code and unzip it:

wget --no-check-certificate https://github.com/shadowsocks/shadowsocks-go/archive/master.zip

unzip master.zip

  • We will have a  folder called shadowsocks-go-master at the current directory, now still need some trick:

mkdir -p ~/gosrc/src/github.com/shadowsocks/shadowsocks-go

cp -r shadowsocks-go-master/shadowsocks ~/gosrc/src/github.com/shadowsocks/shadowsocks-go/

cd shadowsocks-go-master/cmd/shadowsocks-local/

go build

sudo cp shadowsocks-local /usr/bin/

  • If no mistake, now we will have a excutable shadowsocks-go client named shadowsocks-local in /usr/bin, we can run it now, only for iPhone.


Run Shadowsocks-go on iPhone


  • First  create a config file for shadowsocks-go:

cd ~
touch config.json
vim config.json

  • Copy and paste the following code and save

{

    "server":"your server ip or domain name",

    "server_port":11111,
    "local_port":9090,
    "password":"your password, make this password long and complex enough",
    "timeout":600,
    "method":"rc4"
}


  • Also copy config.json to server, shadowsocks-go server version can be downloaded here:
  • on the server side:

nohup shadowsocks-server -c ~/config.json > /dev/null 2>&1 &

  • Or we can set an alias for this long command:

vim ~/.bashrc
alias sgp="nohup shadowsocks-server -c ~/config.json > /dev/null 2>&1 &"
source ~/.bashrc


  • on iPhone side:

nohup shadowsocks-local -c ~/config.json > /dev/null 2>&1 &

  • Or we can set an alias for this long command:

sudo vim /etc/profile.d/coreutils.sh
alias sgp="nohup shadowsocks-local -c ~/config.json > /dev/null 2>&1 &"
source /etc/profile.d/coreutils.sh

Create PAC file to use shadowsocks-go proxy on iPhone

Please see my last blog, the same with shadowsocks-nodejs and python version.

END
Follow me @cattyhouse




Tuesday, January 22, 2013

Jailbreak iPhone,Linux, OS X, Shadowsocks-nodejs, PAC, GFW, 翻墙

My last blog talked about getting through the GFW with Shadowsocks python version on a jailbreak iPhone, this time, i'm going to talk about a better alternative, Shadowsocks-nodejs, here we go:


How does it work?


  • Create a Socks 5 proxy inside the iPhone with Shadowsocks-nodejs.
  • Create a PAC file inside the iPhone to tell which connection goes Proxy and which one goes Direct.
  • Create a bash script to add website to PAC file, so we don't need to edit the file maunally.
  • Assign the PAC file to WiFi and 3g/edge/gprs network.
  • PAC on iPhone is a system wide proxy, it will work for all apps.

How we gonna make it?

1 Create a Socks 5 proxy.


  • Go get the Shadowsocks-nodejs code and config it, see the project homepage.
  • on the server side, we need to get nodejs installed, find it at nodejs.org, and run:
nohup node server.js > /dev/null 2>&1 &
  • on the iPhone side, we  also need to install nodejs, find it in cydia store, the version should be 0.6.14, it works like a charm, after we got it, run inside iPhone:
nohup node local.js > /dev/null 2>&1 &
  • now we  have a running Socks 5 proxy inside iPhone, for example, 127.0.0.1:9090

2 Create a PAC file.


  • A basic PAC file is something like this:

function FindProxyForURL(url, host) {  // this is the beginning of PAC file

var XXGFW = "SOCKS 127.0.0.1:9090"; // this defines a variable to look clean and easy to modify

if (
isPlainHostName(host) ||
shExpMatch(host, "*.local") ||
isInNet(dnsResolve(host), "10.0.0.0", "255.0.0.0") ||
isInNet(dnsResolve(host), "172.16.0.0",  "255.240.0.0") ||
isInNet(dnsResolve(host), "192.168.0.0",  "255.255.0.0") ||
isInNet(dnsResolve(host), "127.0.0.0", "255.255.255.0")) {

return "DIRECT";

} // this tells all local site to go DIRECT

if (
//added by hand
dnsDomainIs(host, "gmail.com") ||
dnsDomainIs(host, "blogger.com") ||
dnsDomainIs(host, "blogspot.com") ||
dnsDomainIs(host, "appspot.com") ||
dnsDomainIs(host, "bit.ly") ||
dnsDomainIs(host, "wikipedia.org") ||
dnsDomainIs(host, "twitter.com") ||
dnsDomainIs(host, "facebook.com") ||
dnsDomainIs(host, "google.com.hk") ||
dnsDomainIs(host, "youtube.com")) {

return XXGFW;

} // this tells the listed websites to go our Socks 5 proxy, "||" means OR

else {

return "DIRECT";

} // this tells everything else to go DIRECT

} // this is the end of PAC file

  • Save the above code to autoproxy.pac (for example) and move it to /var/root/ inside the iPhone, and run:

sudo chown mobile:mobile /var/root/autoproxy.pac
sudo chmod 777 /var/root/autoproxy.pac


3 Create a bash script to add website to PAC file

  • Now we got a working PAC, next we need to create a bash script, so that we can add any GFWed website into this PAC file, the script is like this:
#!/bin/bash
domain=$1
ed -s /var/root/autoproxy.pac << EOF
/\/\/added by hand/a
dnsDomainIs(host, "${domain}") ||
.
w
EOF
  • Save it and name it as agfw, move it to /usr/bin and give it the ability to excute:
sudo chmod +x /usr/bin/agfw
  • To run this script, we need to install ed in cydia store, once we find a website that is blocked by GFW, take the newly GFWed github.com for example, we can add it to PAC file just by running:
agfw github.com
  • Go and check the autoproxy.pac, we'll see that github.com is in there. Now we can view github.com with any  iPhone apps. We can add any website we want to the PAC file with this script, just a single command, it's pretty awesome :)

4 Assign the PAC file to WiFi and 3G/EDGE/GPRS network


  • For WiFi, go to Settings > WiFi > Your connected WiFi > HTTP Proxy > Auto, fill it with:
file:///var/root/autoproxy.pac
  • For  3G/Edge/GPRS, we need to edit the following file with iFile:
/var/preferences/SystemConfiguration/preferences.plist
  • Add the following colored code to the correct position of the this file:
<string>com.apple.CommCenter (ip1)</string> 
</dict> 
<key>Proxies</key> 
<dict> 
<key>ProxyAutoConfigEnable</key>
 <integer>1</integer> 
<key>ProxyAutoConfigURLString</key> 
<string>file:///var/root/autoproxy.pac</string> 
</dict>
 <key>UserDefinedName</key> 
<string>com.apple.CommCenter (ip1)</string>
  • Save and reboot to make it work.


What we got?


  • The proxy will work 24/7 as long as our VPS server works 24/7, always online, no login needed (compared to ssh tunnel & VPN), it just forwards GFWed connection to the server and get feed back.
  • This is the best solution for iPhone to make us feel that GFW seems not existed.
  • Gmail Push goes normal (in seconds) after i put main google domains into the PAC file, even when iPhone is sleeping.
  • The PAC file, the Socks 5 proxy and the Bash script that is used to add website to PAC file are all inside iPhone, once we found a website we can't open, just open Mobileterminal.app (which can be found on cydia store), run agfw balabala.com, done! pretty simple.
  • This solution also works for Linux and OS X client, because iOS is a lite version of OS X :)
END
Follow me @cattyhouse