Wenjian's Blog

Live and Learn

Tag Archives: OpenWrt

HOWTO: 利用OpenWrt路由器上的Shadowsocks+DNSMasq科学上网

HOWTO: Prevent DNS cache pollution一文中,我介绍了利用DNS服务器的非标准端口来防止DNS污染。但即使获得了正确的ip地址,我们也不一定能上网,原因。。。你懂的。这儿介绍一种方法,在OpenWrt路由器上利用Shadowsocks和DNSMasq达到局域网内零配置科学上网。

一个Shadowsocks服务器是必须的,你可以在自己的VPS上搭建一个,方法参见HOWTO: Install and configure shadowsocks on VPS/Ubuntu。或者你可以找一个免费的Shadowsocks服务器,推荐一个获取免费账号的网址https://www.shadowsocks.net/get

安装Shadowsocks

我的OpenWrt版本是AA 12.09,首先更新libpolarssl到最新版本:

$ wget https://downloads.openwrt.org/snapshots/trunk/ar71xx/packages/base/libpolarssl_1.3.8-1_ar71xx.ipk
$ sudo opkg install libpolarssl_1.3.8-1_ar71xx.ipk

下载并安装Shadowsocks:

$ wget http://shadowsocks.org/nightly/shadowsocks-libev-polarssl_1.4.6_ar71xx.ipk
$ sudo opkg install shadowsocks-libev-polarssl_1.4.6_ar71xx.ipk

配置Shadowsocks

Shadowsocks安装之后在/usr/bin会有三个文件:

  • ss-local    <== socks5 协议代理
  • ss-redir    <== 透明代理
  • ss-tunnel  <== 端口转发

本文方法利用的是shadowsocks的透明代理功能。

编辑配置文件/etc/shadowsocks.json,

{
    "server":"xxx.xxx.xxx.xxx",
    "server_port":8388,
    "local_port":1081,
    "password":"demo",
    "timeout":600,
    "method":"aes-256-cfb"
}
  • server: 你的Shadowsocks服务器的IP地址 (IPv4/IPv6).
  • server_port: 你的Shadowsocks服务器端口.
  • local_port: 本地端口.
  • password: 你的Shadowsocks服务器的账号密码.
  • method: 你的Shadowsocks服务器采用的加密方式, “bf-cfb”, “aes-256-cfb”, “des-cfb”, “rc4”, 等等.

编辑/etc/init.d/shadowsocks

#!/bin/sh /etc/rc.common
# Copyright (C) 2006-2011 OpenWrt.org

START=94

SERVICE_USE_PID=1
SERVICE_WRITE_PID=1
SERVICE_DAEMONIZE=1

start() {
 service_start /usr/bin/ss-redir -c /etc/shadowsocks.json
}

stop() {
 service_stop /usr/bin/ss-redir
}

运行Shadowsocks透明代理:

$ sudo /etc/init.d/shadowsocks start
$ sudo /etc/init.d/shadowsocks enable

添加防火墙规则

我们可以从APNIC获得最新的中国IP地址列表,利用iptables添加防火墙规则,保存以下文本为gen-firewall-gfw.sh

#!/bin/ash

# Write gfw iptables
firewall_gfw="/usr/bin/firewall-gfw.sh"
if [ -f $firewall_gfw ]; then
 rm $firewall_gfw
fi

echo "#!/bin/ash" >>$firewall_gfw
echo >>$firewall_gfw
echo "# Create a new chain named SHADOWSOCKS" >>$firewall_gfw
echo "iptables -t nat -N SHADOWSOCKS" >>$firewall_gfw
echo >>$firewall_gfw

echo "# Ignore shadowsocks server" >>$firewall_gfw
echo "iptables -t nat -A SHADOWSOCKS -d xxx.xxx.xxx.xxx -j RETURN" >>$firewall_gfw
echo >>$firewall_gfw

echo "# Ignore LANs ip addresses" >>$firewall_gfw
echo "iptables -t nat -A SHADOWSOCKS -d 0.0.0.0/8 -j RETURN" >>$firewall_gfw
echo "iptables -t nat -A SHADOWSOCKS -d 10.0.0.0/8 -j RETURN" >>$firewall_gfw
echo "iptables -t nat -A SHADOWSOCKS -d 127.0.0.0/8 -j RETURN" >>$firewall_gfw
echo "iptables -t nat -A SHADOWSOCKS -d 169.254.0.0/16 -j RETURN" >>$firewall_gfw
echo "iptables -t nat -A SHADOWSOCKS -d 172.16.0.0/16 -j RETURN" >>$firewall_gfw
echo "iptables -t nat -A SHADOWSOCKS -d 192.168.0.0/16 -j RETURN" >>$firewall_gfw
echo "iptables -t nat -A SHADOWSOCKS -d 224.0.0.0/4 -j RETURN" >>$firewall_gfw
echo "iptables -t nat -A SHADOWSOCKS -d 240.0.0.0/4 -j RETURN" >>$firewall_gfw
echo >>$firewall_gfw

echo "# Ignore China ip addresses" >>$firewall_gfw
# Get latest delegated internet number resources from apnic
cd /tmp
if [ -f "delegated-apnic-latest" ]; then
 echo "deleting old delegated internet number resources ..."
 rm delegated-apnic-latest
fi
echo "Downloading latest delegated internet number resources from apnic ..."
wget -c http://ftp.apnic.net/stats/apnic/delegated-apnic-latest

echo "Extracting china ip addresses from downloaded latest delegated internet number resources ..."
cat delegated-apnic-latest | awk -v awk_firewall_gfw=$firewall_gfw -F '|' '/CN/&&/ipv4/ \
 {print "iptables -t nat -A SHADOWSOCKS -d " $4 "/" 32-log($5)/log(2) " -j RETURN" >>awk_firewall_gfw}'
 
echo >>$firewall_gfw

echo "# Ohter ip addresses should be redirected to shadowsocks' local port" >>$firewall_gfw
echo "iptables -t nat -A SHADOWSOCKS -p tcp -j REDIRECT --to-ports 1081" >>$firewall_gfw
echo >>$firewall_gfw

echo "# Apply the rules" >>$firewall_gfw
echo "iptables -t nat -A PREROUTING -p tcp -j SHADOWSOCKS" >>$firewall_gfw

echo "Firewall rules for shadowsocks have been written into file " $firewall_gfw

然后

$ chmod +x gen-firewall-gfw.sh
$ ./gen-firewall-gfw.sh
$ sudo ./firewall-gfw.sh

用iptables命令查看一下这些规则有没有添加进去:

$ sudo iptables -t nat --list

大功告成。

现在所有通过你的路由器上网的设备无需设置就可以科学上网啦。

Useful links on building OpenWrt for WRT1900AC

WRT1900AC was announced on 6th of January 2014 as a router developed to be used with OpenWrt.

Specifications:

Model: Linksys WRT1900AC
Technology: Wireless-AC
Standards: 802.11a, 802.11b, 802.11g, 802.11n. 802.11ac
Frequency: Dual
Bands: Simultaneous: 2.4 GHz (Wireless-N), 5.0 GHz (Wireless-AC)
Security: WEP 64/128-bit, WPA2-Personal & Enterpise (AES/TKIP), WPS
Antennas: 4x External Detachable Antennas
Antenna Gain (peak): 2.4GHz: 2.5dBi
5GHz: 3.8dBi
Antenna Type: Dipole
Output Power: 2.4GHz: 19dBm
5GHz: 21dBm
Warranty: 2 year hardware limited warranty
OS Compatibility: Windows, Mac
Minimum System Requirements: PC with CD or DVD drive, running Windows XP SP3 (32-bit), Vista SP1/SP2 (32 & 64-bit), Win7 (32-bit & 64-bit) and Win8 (32-bit & 64-bit)
Mac: Wi-Fi enabled with CD or DVD drive, Mac OS® X Leopard v10.5.8 or later, Snow Leopard v10.6.1 or later, Lion v10.7, or Mountain Lion v10.8 Available USB 2.0 port
Package Contents: Linksys Dual Band Gigabit Wi-Fi Router AC1900, WRT1900AC, Quick Start Guide, CD-ROM with Documentation, 4 Antennas, Ethernet Cable, Power Adapter, Power Cord

Hardware Highlights:

SoC Ram Flash Network USB Serial JTag eSata
Marvell MV78230 256 MiB 128 MiB 1×2.0 1×3.0 Yes

Serial Port:

1 2 3 4 5 6
GND ? RX ? TX ?

Useful Links:

OpenWrt forum thread for official statement: Update on Linksys WRT1900AC support

McWRT: https://github.com/Chadster766/McWRT

Prebuilt images: https://github.com/wrt1900ac/opensource

jimmychungbelkin/Mamba: https://github.com/jimmychungbelkin/Mamba

HOWTO: 从APNIC获取中国IP地址列表

关于APNIC

全球IP地址块被IANA(Internet Assigned Numbers Authority)分配给全球三大地区性IP地址分配机构,它们分别是:
1、ARIN(American Registry for Internet Numbers)
负责北美、南美、加勒比以及非洲撒哈啦部分的IP地址分配。同时还要给全球NSP(Network Service Providers)分配地址。
2、RIPE(Reseaux IP Europeens)
负责欧洲、中东、北非、西亚部分地区(前苏联)
3、APNIC(Asia Pacific Network Information Center)
负责亚洲、太平洋地区

APNIC是管理亚太地区IP地址分配的机构,它有着丰富准确的IP地址分配库,同时这些信息也是对外公开的。

APNIC IP地址分配信息总表的获取

APNIC提供了每日更新的亚太地区IPv4,IPv6,AS号分配的信息表
http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest
该文件的格式与具体内容参见
ftp://ftp.apnic.net/pub/apnic/stats/apnic/README.TXT

通过该文件我们能够得到APNIC辖下IPv4地址空间的分配情况。

通过脚本提取IP信息

我的脚本如下

#!/bin/sh
wget -c http://ftp.apnic.net/stats/apnic/delegated-apnic-latest

cat delegated-apnic-latest | awk -F '|' '/CN/&&/ipv4/ {print $4 "/" 32-log($5)/log(2)}'

保存为脚本执行,输出如下

Connecting to ftp.apnic.net (202.12.29.205:80)
delegated-apnic-late 100% |*******************************************| 1653k 0:00:00 ETA
1.0.1.0/24
1.0.2.0/23
1.0.8.0/21
1.0.32.0/19
1.1.0.0/24
1.1.2.0/23
1.1.4.0/22
1.1.8.0/21
1.1.16.0/20
1.1.32.0/19
1.2.0.0/23
1.2.2.0/24
1.2.4.0/24
1.2.5.0/24
1.2.6.0/23
1.2.8.0/24
1.2.9.0/24
1.2.10.0/23
1.2.12.0/22
1.2.16.0/20
1.2.32.0/19
1.2.64.0/18
...

获得这些地址之后可以在OpenWrt上配合shadowsocks翻墙 ^_^

HOWTO: Schedule jobs with cron on OpenWrt

No additional software needs to be installed on OpenWrt, as it already has the crond binary included.

Configuration

Cron jobs need to be specified in /etc/crontabs/root. For now, just create an empty file:

# touch /etc/crontabs/root

Create a symbolic link to the crontab file:

# ln -sf /etc/crontabs/root /etc/crontab

it allows me to reference the crontab file using /etc/crontab.

Enable and start crond:

# /etc/init.d/crond start
# /etc/init.d/crond enable

Verify that crond successfully started by checking the syslog using:

# logread

and you should see something similar to this at the end of the logread output

Sep 11 17:26:40 OpenWrt cron.info crond[634]: crond: crond (busybox 1.19.4) started, log level 8

Usage

Now that you have crond running on OpenWrt, it can be used to periodically run any task that you want. Just add an entry to/etc/crontab for each task that you want periodically executed.

For example, if you want to run a script (/usr/bin/demo) daily at 23:30, the following would be added to crontab:

30 23 * * * /usr/bin/demo >/dev/null 2>&1

Restart crond to make this change take effect:

# /etc/init.d/cron restart

HOWTO: Prevent DNS cache pollution

Let us try to get the ip of twitter from the default port (53) of OpenDNS:

# dig @208.67.222.222 twitter.com
; <<>> DiG 9.9.1-P3 <<>> @208.67.222.222 -p 53 twitter.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 28025
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;twitter.com. IN A

;; ANSWER SECTION:
twitter.com. 300 IN A 37.61.54.158

;; Query time: 8 msec
;; SERVER: 208.67.222.222#53(208.67.222.222)
;; WHEN: Wed Sep 10 07:51:57 2014
;; MSG SIZE rcvd: 56

Obviously 37.61.54.158 is not what we want.

Let us try with port 5353 and  443:

# dig @208.67.222.222 -p 5353 twitter.com

; <<>> DiG 9.9.1-P3 <<>> @208.67.222.222 -p 5353 twitter.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 64372
;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;twitter.com. IN A

;; ANSWER SECTION:
twitter.com. 15 IN A 199.59.148.82
twitter.com. 15 IN A 199.59.149.230
twitter.com. 15 IN A 199.59.150.7
twitter.com. 15 IN A 199.59.149.198

;; Query time: 85 msec
;; SERVER: 208.67.222.222#5353(208.67.222.222)
;; WHEN: Wed Sep 10 08:03:49 2014
;; MSG SIZE rcvd: 104
# dig @208.67.222.222 -p 443 twitter.com

; <<>> DiG 9.9.1-P3 <<>> @208.67.222.222 -p 443 twitter.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 2939
;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;twitter.com. IN A

;; ANSWER SECTION:
twitter.com. 4 IN A 199.59.148.10
twitter.com. 4 IN A 199.59.149.198
twitter.com. 4 IN A 199.59.148.82
twitter.com. 4 IN A 199.59.150.7

;; Query time: 294 msec
;; SERVER: 208.67.222.222#443(208.67.222.222)
;; WHEN: Wed Sep 10 08:04:53 2014
;; MSG SIZE rcvd: 104

Now we got it !!!

In OpenWrt, edit /etc/config/dhcp, change dnsmasq section

config dnsmasq
    option domainneeded '1'
    option boguspriv '1'
    option localise_queries '1'
    option rebind_protection '1'
    option rebind_localhost '1'
    option local '/lan/'
    option domain 'lan'
    option expandhosts '1'
    option authoritative '1'
    option readethers '1'
    option leasefile '/tmp/dhcp.leases'
#   option resolvfile '/tmp/resolv.conf.auto'
    option noresolv 1
    list server '208.67.222.222#5353'
    list server '/pool.ntp.org/208.67.222.222'

HOWTO: Install and configure pdnsd on OpenWrt

Introduction

OpenWrt is described as a Linux distribution for embedded devices.
Instead of trying to create a single, static firmware, OpenWrt provides a fully writable filesystem with package management. This frees you from the application selection and configuration provided by the vendor and allows you to customize the device through the use of packages to suit any application. For developer, OpenWrt is the framework to build an application without having to build a complete firmware around it; for users this means the ability for full customization, to use the device in ways never envisioned.

The latest stable release is AttitudeAdjustment 12.09.

Installation

To install pdnsd, run command:

# opkg update
# opkg install pdnsd

Configuration

Edit configuration file /etc/pdnsd.conf.

The global section specifies parameters that affect the overall behaviour of the server. If you specify multiple global sections, the settings of those later in the file will overwrite the earlier given values.

The detailed description of the options can be found here.

Here is my global section

global {
        perm_cache=2048;
        cache_dir="/var/pdnsd";
#       pid_file = /var/run/pdnsd.pid;
#       run_as="nobody";
        server_port = 5353;
        server_ip = any; 
        status_ctl = on;
#       paranoid=on; 
        query_method=tcp_udp;
        min_ttl=15m; # Retain cached entries at least 15 minutes.
        max_ttl=1w; # One week.
        timeout=10; # Global timeout option (10 seconds).
        neg_domain_pol=on;
        udpbufsize=1024; # Upper limit on the size of UDP messages.
}

Each server section specifies a set of name servers that pdnsd should try to get resource records or authoritative name server information from. The servers are queried in the order of their appearance (or parallel to a limited extend). If one fails, the next one is taken and so on.
You probably want to specify the dns server in your LAN, the caching dns servers of your internet provider or even a list of root servers in one or more server sections.

The detailed description of the options can be found here.

I added opendns server in my configuration file

server {
        label= "opendns";
        ip = 208.67.222.222;
        port = 5353;
        root_server = on;
        uptest = none;
}

You can also add Google Public DNS. More DNS can be found here.

Usage

Enable and start pdnsd:

# /etc/init.d/pdnsd enable
# /etc/init.d/pdnsd start

Test with:

# dig @127.0.0.1 -p 5353 youtube.com
; <<>> DiG 9.9.1-P3 <<>> @127.0.0.1 -p 5353 youtube.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 49334
;; flags: qr rd ra; QUERY: 1, ANSWER: 11, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;youtube.com. IN A

;; ANSWER SECTION:
youtube.com. 300 IN A 173.194.127.135
youtube.com. 300 IN A 173.194.127.137
youtube.com. 300 IN A 173.194.127.142
youtube.com. 300 IN A 173.194.127.136
youtube.com. 300 IN A 173.194.127.133
youtube.com. 300 IN A 173.194.127.132
youtube.com. 300 IN A 173.194.127.128
youtube.com. 300 IN A 173.194.127.131
youtube.com. 300 IN A 173.194.127.130
youtube.com. 300 IN A 173.194.127.129
youtube.com. 300 IN A 173.194.127.134

;; Query time: 311 msec
;; SERVER: 127.0.0.1#5353(127.0.0.1)
;; WHEN: Fri Sep 5 20:58:07 2014
;; MSG SIZE rcvd: 216