Code Blog

Displaying 1-4 of 4 results.
2016/12/14 VPN,OpenWRT

I made a previous post about how I set up Shadowsocks on my OpenWRT router (back in February, see post ...). My router had basically stopped working so I had to go through it and try to understand what was wrong. After some testing it seemed that the TCP-tunnel was working fine but the ChinaDNS had problems working correctly.

The shadowsocks-libev has also been updated. The shadowsocks-libev-spec seems to have been discontinued and is now merged in the shadowsocks-libev, which has more functions sorted (now supporting SOCKS proxy and transparent proxy). The same is true for the luci frontend, everything is now through one single GUI.

To solve the problems with DNS I also installed the DNS-forwarder package.

Shadowsocks-libev is written in pure C and only depends on libev and OpenSSL or mbedTLS or PolarSSL.
Using alternative crypto library There are three crypto libraries available: OpenSSL (default) mbedTLS PolarSSL (Deprecated)

Client side/
└── usr/
  └── bin/
    ├── ss-local // provides SOCKS proxy
    ├── ss-redir // provides transparent proxy, since v2.2.0 also supports UDP
    └── ss-tunnel // used for packet transmission, can be used DNS lookups

Server side/
└── usr/
  └── bin/
    └── ss-server // server executable

wget -O- '' | awk -F\| '/CN\|ipv4/ { printf("%s/%d\n"
, $4, 32-log($5)/log(2)) }' > ignore.list

I installed the following packages by first downloading them on my computer and scp them over to the router.

opkg update

opkg install ip ipset libopenssl iptables-mod-tproxy

Shadowsocks-libev required that I first installed libpcre and libpthread packages.




config dns-forwarder
option enable '1'
option listen_addr ''
option listen_port '5300'
option dns_servers ''


config dnsmasq
option domainneeded '1'
option boguspriv '1'
option localise_queries '1'
option rebind_protection '1'
option rebind_localhost '1'
option expandhosts '1'
option readethers '1'
option leasefile '/tmp/dhcp.leases'
option localservice '1'
option noresolv '1'
option nohosts '1'
option local ''

config dhcp 'lan'
option interface 'lan'
option start '100'
option limit '150'
option leasetime '12h'
option dhcpv6 'server'
option ra 'server'
option ra_management '1'

config dhcp 'wan'
option interface 'wan'
option ignore '1'

config odhcpd 'odhcpd'
option maindhcp '0'
option leasefile '/tmp/hosts/odhcpd'
option leasetrigger '/usr/sbin/odhcpd-update'


config chinadns
option enable '1'
option bidirectional '0'
option chnroute '/etc/chinadns_chnroute.txt'
option port '5353'
option server ','

Another new feature is that Shadowsocks now supprts AES-256-CTR. I have used CFB before. CTR is used if you want good parallelization (ie. speed), instead of CBC/OFB/CFB.



2016/06/01 OpenWRT

In order to keep the router in a stable condition I want to reboot it automatically every morning. This is a bit trickier than one would expect because the clock may get caught in an inifinite loop of reboots, see link below for more details. So the recommended way is to add a delay and update the clock before rebooting the router.

# Reboot at 4:30am every day
# Note: To avoid infinite reboot loop, wait 70 seconds
# and touch a file in /etc so clock will be set
# properly to 4:31 on reboot before cron starts.
30 4 * * * sleep 70 && touch /etc/banner && reboot

Good tips from:

2016/03/30 VPN,OpenWRT

Useful commands from ssh terminal

/etc/init.d/shadowsocks enable
/etc/init.d/shadowsocks start
/etc/init.d/ChinaDNS enable
/etc/init.d/ChinaDNS start
killall dnsmasq 
/etc/init.d/dnsmasq start
iptables -L -n -v
iptables -L OUTPUT -n -v iptables -L FORWARD -n -v cat /proc/meminfo cat /proc/cpuinfo netstat -tulpn

Note: dropbear is the ssh-server included in OpenWRT. Its a lightweight ssh-server.

shadowsocks-libev vs shadowsocks-libev-spec

shadowsocks-libev includes ss-{local,redir,tunnel}. Default config is running ss-local creating a local SOCKS proxy. shadowsocks-libev-spec is a special version for OpenWrt, that includes ss-{redir,rules,tunnel}. ss-redir will create the transparent proxy. ss-rules generates the proxy rules. ss-tunnel provide UDP transmission. Starting from v1.5.2 it uses the LuCI interface.


PandoraBox is a router firmware fork of OpenWRT, made by the Chinese OpenWRT community. The Intellectual Property and copyright laws must be different in China, since the source code contain Mediatek copyrighted material, which is clearly not allowed in the standard version of OpenWRT. Basically PandoraBox added wifi-support for routers still not supported in OpenWRT, but the source code cannot be added to the OpenWRT distribution for copyright reasons. If OpenWRT lack support for a router it is possible PandoraBox may support it instead.

GFWList - Sites blocked in China

We have already set up the China accelerated list in my previous OpenWRT post. However there is also the foreign_list.conf (GFWList) that can be added to dnsmasq.

In this way the logic will be:

  1. Check China accelerated list: Directly resolve IP if match is found, otherwise continue
  2. Check China blocked list: Directly resolve IP if match is found, otherwise continue 
  3. Use ChinaDNS for all remaining DNS requests. ChinaDNS will decide if it will use China DNS server or tunnel to DNS server outside of China. ChinaDNS uses the /etc/chinadns_chnroute.txt file to determine if an IP is in China or not.

Traffic statistics


vnStati - provides image output support for statistics collected using vnstat


Good list of different software for bandwidth monitoring:

Update: vnStat worked but did not have a lot of options to configure. I wanted to see amount of traffic going through Shadowsocks tunnel but this didnt seem possible with vnStat.

OpenWRT Ad-blocker - Privoxy

The privoxy package is designed to filter out traffic going to known ad-site servers. I could not find a package build in the stable Chaos Chamber repository, but there is a package build available in the snapshot/trunk repository, see:

Snapshots are automatically built every 1-2 days from the SVN trunk (development) repository sources by the buildbot. They are untested and might not work properly.

opkg update
opkg list | grep privoxy
opkg install privoxy
opkg install luci-app-privoxy

Update: Seems I had some problem to get this package to work well with Redsocks2/Shadowsocks/ChinaDNS so I removed privoxy and vnstat and the router was working well again. To remove packages from OpenWRT run "opkg remove packagename".

Alternative to ChinaDNS - DNSCrypt

DNSCrypt uses strong encryption for DNS traffic.There's an updated list of public servers DNSCrypt can use. For more information see 

For OpenWRT one need to install the package "dnscrypt-proxy".

/etc/dnsmasq.conf configuration file example: 

# Ignore the resolve file /etc/resolv.conf
# Use DNSCrypt as upstream DNS server 
# Turn off DHCP for the network interface 
# Local hosts file 

Alternative to Shadowsocks - obfsproxy

Shadowsocks may not be enough because of deep packet inspection used by the GFW. One alternative is using an obfuscated SSH tunnel, based on Tor's obfsproxy.

DNS cache: pdnsd

pdnsd is a DNS server designed for local caching of DNS information. Correctly configured, it can significantly increase browsing speed on a broadband connection. Compared to BIND or dnsmasq it can remember its cache after a reboot; "p" stands for persistent.

I can't find a package to install for my version of OpenWRT, might need to build from source code.

dnsmasq -> ChinaDNS -> If China: / If outside China -> pdnsd -> ss-tunnel ->

Other notes & links to websites

There is a shadowsocks version using polarssl, so I quick check online revealed the following:

mbed TLS (previously PolarSSL) is an implementation of the TLS and SSL protocols and the respective cryptographic algorithms and support code required.
Its a light-weight open source cryptographic and SSL/TLS library written in C with small memory footprint.

Then there is another package available called ShadowVPN, which seems to offer similiar functionality as Shadowsocks+Redsocks2 but maybe faster and more lightweight, see link:
ShadowVPN is a fast, safe VPN based on libsodium 

Both ShadowVPN and PolarSSL might be interesting to test out. I'm not really sure how to set up a ShadowVPN server that the OpenWRT can tunnel to though but maybe there is more information available if I would actually install the package.  

I found a lot of good and helpful information (in Chinese) at  
For example the tester script I have copied from

Now here's a story, the guy that developed shadowsocks (clowwindy) is Chinese, and run into some trouble last year:

On August 22 2015, an open source project called ShadowSocks was removed from GitHub. According to the project’s author, the police contacted him and asked him to stop working on the tool and to remove all of the code from GitHub. He later removed the reference of the police, presumably under the pressure of the police.

I guess he mentioned the police in the first readme notice as the source code was taken down. Now the "" file at github reads "Removed according to regulations.". That's just insane. China plays by other rules.

More tips

Speed up Apple downloads:

Create the file /etc/dnsmasq.d/apple.conf and add the line below to it:

I read online that:

"shadowsocks-libev has ss-redir which works as a transparent proxy, so redsocks is not needed"

Not sure about this, will need to try it myself


2016/03/29 VPN,OpenWRT

I bought an old Netgear WNDR4300 router to play around with to install customised router firmware. This makes it possible to add a lot of functions a consumer router wouldn't normally have, which can be quite useful, especially here in China where you have the Great Firewαll to cope with.

There are actually made router firmware projects, "DD-WRT", "Tomato" and "OpenWRT" being the more wellknown. OpenWRT is built on Linux (as is DD-WRT and Tomato) but comes with a modular design and package-management system which makes it possible to configure the system according to the user's needs.

Netgear WNDR4300 was actually designed to run a version of OpenWRT as its firmware from the start, so it seems reasonable to assume that since it was designed for OpenWRT, its also a good choice of router to try out newer versions of OpenWRT. It is also one of the recommended routers to run OpenWRT which was the reason I decided to buy this model.

Step 1: Download firmware for WNDR4300

The WNDR4300 has actually been made in different versions, so first step is to check which version it actually is (it was WNDR4300 version 1 in my case). OpenWRT firmware builds are available for many different platforms, depending on CPU and other hardware. The documentation was a bit confusing but after some research I found that the WNDR4300 has a Atheros AR9344 560MHz CPU and belongs to the "ar71xx" OpenWRT platform. 

I downloaded latest stable build, the 15.05.1 (Chaos Calmer) release:
There is also a SquashFS version available, which I think will save RAM on the device as the read-only part of the filesystem can be compressed but I haven't tried that version. The WNDR4300 comes with 128 MB flash + 128 MB RAM memory, which should be quite ok. The OpenWRT website states that the smallest installation requires 4 MB flash + 16 MB ram.

Step 2: Upload firmware to router

There are different ways to do this, but uploading by tftp seems to be recommened. To do this reset the router and put it in listening mode.

  1. Power off the router
  2. Press the reset button and keep holding it down during power up. Keep pressing reset until the power LED starts blinking green.
  3. The router is now running with ip and is waiting for firmware upload
  4. Connect to a LAN port on the back of the router with tp-cable (luckily I have my Macally usb-ethernet converter for my Macbook)
  5. Set a static ip for the computer in 192.168.1.x subnet (i.e. and use as gateway
  6. Upload the firmware to the router. I read somewhere that too long filename may cause problem so I renamed the firmware file “openwrt-15.05.1-ar71xx-nand-wndr4300-ubi-factory.img” to “firmware.img".
    Run the following commands:
    tftp -e
    mode binary
    put firmware.img

Then wait for power LED to turn green again. Go to using web browser and set a new root password. Also set the correct timezone in the System -> System menu.

I also changed the local LAN ip to in order to not interfere with my other router. Need to re-apply the ssh settings under “administration” after updating the LAN ip number (otherwise ssh is refused, guess it expects

Step 3: Install packages

The next step is to install "Shadowsocks" and "ChinaDNS" packages. Many guides online also list Redsocks2 in order to set up Shadowsocks as a transparent proxy but the current version of Shadowsocks has transparent proxy functionality built-in so Redsocks2 is not needed. Note that OpenWRT-shadowsocks comes in two versions - shadowsocks-libev and shadowsocks-libev-spec. I use the later one, it comes with LuCl web interface and does not need Redsocks2.

Shadowsocks SOCKS5 proxy client
ChinaDNS Resolve DNS (Determine if IP is in China or not; avoid DNS pollution etc)

Use terminal and ssh to login to the router:
ssh [email protected]

OpenWRT comes pre-installed with opkg package manager (an OpenWRT fork of ipkg). There is also a "Software" menu in the OpenWRT GUI which can also be used to install packages.

opkg update
opkg install shadowsocks-libev-spec
opkg install ChinaDNS

The commands above may work (opkg download and install packages) but here I run into a problem, because opkg couldn't find any prebuilt packages to install. I tried adding some custom package feeds but since OpenWRT version 15.05 the package manager (opkg) started checking signatures for all packages (which is a good thing), but unfortunately had the repository that keeps Shadowsocks / ChinaDNS no valid signatures!

It should be possible to change the configuration in /etc/opkg.conf from “option check_signature 1” to “option check_signature 0” to avoid the signature check but this didnt work for me for some reason (I later read a post that removing the line will cancel the signature check, but changing to zero doesn't work).

I instead installed them locally, which means I first need to manually download the packages and copy (scp) them over to the router.

The package files are available to download from:

LuCI is the Web User Interface of OpenWRT. Each module has two packages, the actual router module software installation (ar71xx for this platform) and a corresponding GUI plugin.



Copy over all IPK packages to the router /tmp folder using scp:
scp *.ipk [email protected]:/tmp/

Then run installation of all packages. I don't think the installation order should make any difference.
Each package is installed by running "opkg install packagename.ipk".

opkg update
opkg install ChinaDNS_1.3.2-3_ar71xx.ipk
and so on ...

While installing shadowsocks I got an error message: "failed to find a module named nf_tproxy_core". Not sure about what this means, but I read at a forum that a router reboot is enough to solve this problem. I haven't noticed any problems after rebooting (no errors/warnings in kernel or system log files either).

Step 4: Configure software

  1. Input your Shadowsocks server settings (server ip & port, password and encryption). The configuration will be stored in /etc/config/shadowsocks 
  2. Update "DHCP and DNS" settings, see screenshots below. Need to change 2 settings - "DNS forwardings" and "Ignore resolve file" - for ChinaDNS to work correctly.
  3. Turn on "UDP Forward" for Shadowsocks (this may not be available for older versions). I don't run the global "UDP-Relay Server" for Shadowsocks.

Shadowsocks uses port 1080 as default for it's SOCKS5 proxy. Need to fill in server IP & port, password and encryption method. I haven't used "One-time authentication", wasn't sure what this function was, but from Shadowsocks documentation one can read:

One-time authentication (shortened as OTA) is a new experimental feature designed to improve the security against CCA (Chosen-ciphertext attack). 

DNS uses UDP protocol for DNS lookups which may get blocked going outside China (i.e. Google's DNS servers are blocked). To avoid this the UDP packets can be tunneled in a Shadowsocks TCP connection. Shadowsocks will use port 5300 to listen for UDP packets and forward to the public DNS server (run by Google) at port 53. Port 53 is the standard port for DNS.

Bi-directional filter seems to try to solve inconsistencies in IP number for CDN-networks that has servers both in China and abroad. I haven't tried this yet, so I'm not sure when/how this helps.

I use the default settings for ChinaDNS. Regarding the upstreams servers, the server at is DNS server run by China Telecom (located in Nanjing, China) and the server at is Google's DNS server. The CHNRoute file is the IP subsets that ChinaDNS uses to determine if an IP is in China or not.

ChinaDNS is using port 5353 to listen for incoming connections by default. Set "DNS forwardings" to unless you changed this value.

Need to turn on the "Ignore resolve file" setting.

Extra stuff - tester script

Build a script to test connectivity and automatically restart shadowsocks if connection isn't working.
For this to work we first need to install wget (wget is already installed but it is the stripped down busybox version which will not work with the script below)

opkg update
opkg install wget

Create the file /root/tester (make executable chmod 755) and add the script below:

LOGTIME=$(date "+%Y-%m-%d %H:%M:%S")
wget --spider --quiet --tries=1 --timeout=3
if [ "$?" == "0" ]; then
echo '['$LOGTIME'] No Problem.'
exit 0
wget --spider --quiet --tries=1 --timeout=3
if [ "$?" == "0" ]; then
echo '['$LOGTIME'] Problem detected, restarting shadowsocks.'
/etc/init.d/shadowsocks restart
echo '['$LOGTIME'] Network Problem. Do nothing.'


*/10 * * * * /root/tester >> /var/log/shadowsocks_watchdog.log 2>&1
0 1 * * 7 echo "" > /var/log/shadowsocks_watchdog.log

Under scheduled tasks set up a cronjob as the screenshot above. This will run the tester script every 10 minutes to check status and automatically restart Shadowsocks if it detects a problem. A log file will be kept at /var/log/shadowsocks_watchdog.log

Increase DNS lookup speed

Download the files listed in table below from

accelerated-domains.china.conf Faster lookup of China domains
bogus-nxdomain.china.conf Certain China ISP return unwanted redirects when domain is not found
google.china.conf Speed up access to Google servers in China

Create the folder /etc/dnsmasq.d and copy all files to that folder 
Edit dnsmasq configuration file /etc/dnsmasq.conf and add the line below: