Configure shadowsocks transparent proxy + gfwlist(PAC) on OpenWRT Router


You must have Shadowsocks services which can be gained in the following way before actually starting to configure.


The environment this article used, FYI:
  • OpenWrt 18.06.1/LuCI openwrt-18.06
The Overall Idea:
DNS part:
if the requested address is in gfwlist
    forward DNS request to 127.0.0.1:5353 which is listened by dns-forwarder
    dns-forwarder forwards the request to 8.8.8.8 for translating
    8.8.8.8 is in gfwlist, so match iptables rules and is fowared to 1080
    ss-redir listen on port 1080, foward request to shadowsocks server
else
    use public DNS servers or the DNS servers provided by the ISP

other data:
if the requested address is in gfwlist
    match iptables rules and is fowared to 1080
    ss-redir listen on port 1080, foward request to shadowsocks server
else
    normal way

Step 1: Install dependencies(Very Important
All the operations mentioned here are either based on SSH or the web management page provided OpenWRT.
First of all, add GPG Key via SSH to pass signature verification:
wget http://openwrt-dist.sourceforge.net/packages/openwrt-dist.pub -O /tmp/openwrt-dist.pub
opkg-key add /tmp/openwrt-dist.pub

Then, on the web management page, in "System">"Software">"Configuration", find "Custom feeds" and add two lines:
src/gz openwrt_dist http://openwrt-dist.sourceforge.net/packages/base/mips_24kc
src/gz openwrt_dist_luci http://openwrt-dist.sourceforge.net/packages/luci
Attention: Orange italic words with red background must be replaced by the architecture of your router's CPU. You can check by using the command 'opkg print-architecture'。

Then, update the software list by command 'opkg update'. (If you are in China within the GFW, this may failed because of the interference. Just try a few more times. If it fails every time, please find a PC which can access the outside network and download the software ipk packages mentioned by the following instructions. After that, use 'scp' to upload them to your router and manually install them.)

After 'opkg update', we can start to install software:
opkg install shadowsocks-libev-ss-local
opkg install shadowsocks-libev-ss-redir
opkg install shadowsocks-libev-ss-tunnel
opkg install ip ipset libpthread iptables-mod-tproxy
opkg install dns-forwarder luci-app-dns-forwarder
opkg install zlib
opkg remove dnsmasq && opkg install dnsmasq-full
The Installation of dnamasq-full in the last line is very important, or the service of DHCP and DNS will not work properly. What is worse, the scripts in dnsmasq.d will not be recognized, either. As a result, dnsmasq will malfunction and your router will not be able to DNS properly and cannot access to the Internet. Please make sure the dnsmasq-full is successfully installed.

Step 2: Configure Shadowsocks
Create a new shadowsocks folder in '/root/'. Then, enter it and create a json file. We use 'vultr.json' here as an example. Of course, you can choose other names as long as it is the same as the path referred in the following steps.
cd /root/
mkdir shadowsocks
vim vultr.json

Use the following text as the content of vultr.json:

{
    "server":"1.1.1.1",
    "server_port":"1234",
    "password":"passwordpassword",
    "local_port":"1080",
    "method":"aes-128-gcm",
    "fast_open":true,
}
Please modify the content above according to your own Shadowsocks service.
  • server: Shadowsocks server ip
  • server_port: Shadowsocks server port
  • password: Shdowsocks password
  • local_port: local port for shadowsocks service. You can keep the default value.
  • method: the method of encryption
  • fast_open:tcp fast open, we'll mention it in the following steps. You may also delete this field to close it.
Create a new file named shadowsocks in '/etc/init.d/' with the following content:
#!/bin/sh /etc/rc.common

START=95

SERVICE_USE_PID=1
SERVICE_WRITE_PID=1
SERVICE_DAEMONIZE=1
SERVICE_PID_FILE=/var/run/shadowsocks.pid
CONFIG=/root/shadowsocks/vultr.json

start() {
# Proxy Mode
service_start /usr/bin/ss-redir -c $CONFIG -b 0.0.0.0 -f $SERVICE_PID_FILE
}

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

Save and exit. Make it executable:
chmod +x /etc/init.d/shadowsocks

Enable it to make it start with the router:
/etc/init.d/shadowsocks enable

Start the service:
/etc/init.d/shadowsocks start

Check if the service is successfully started:
netstat -lnp | grep ss-redir

If started, you should see something like this:
tcp        0      0 0.0.0.0:1080            0.0.0.0:*               LISTEN      1493/ss-redir

Enable TCP fastopen (need your kenerl version later than 3.7. To check your kernel version, you can use the command 'uname -r')
Find 'net.ipv4.tcp_fastopen' in '/etc/sysctl.conf' and set it to '3'. If it does not exist, add a line at the bottom of '/etc/sysctl.conf':
net.ipv4.tcp_fastopen = 3

Then, activate the modification:
sysctl -p
/etc/init.d/shadowsocks restart

Step 3: Configure dnsmasq and ipset
In OpenWRT web management page, choose "Network">"Firewall">"Custom Rules". Add the following content in which port 1080 corresponds to 'local_port' in the configuration file of Shadowsocks. Please modify if your port is not 1080.
ipset -N gfwlist iphash
iptables -t nat -A PREROUTING -p tcp -m set --match-set gfwlist dst -j REDIRECT --to-port 1080
iptables -t nat -A OUTPUT -p tcp -m set --match-set gfwlist dst -j REDIRECT --to-port 1080
ip6tables -t nat -A PREROUTING -p tcp -m set --match-set gfwlist dst -j REDIRECT --to-port 1080

ip6tables -t nat -A OUTPUT -p tcp -m set --match-set gfwlist dst -j REDIRECT --to-port 1080
ipset add gfwlist 8.8.8.8
(ip6tables is for ipv6. The ipv6 traffic has also been filtered by GFW.)

Then, configure dnsmasq. Please make sure that dnsmasq-full is successfully installed
Create a new directory /etc/dnsmasq.d. And use the following command to add the path into configuration:
uci add_list dhcp.@dnsmasq[0].confdir=/etc/dnsmasq.d
uci commit dhcp

Check if the configuration is successful:
uci get dhcp.@dnsmasq[0].confdir

Attention:For OpenWRT version (not LEDE version), you may need to add a new line 'conf-dir=/etc/dnsmasq.d' at the bottom of /etc/dnsmasq.conf. 

Last, add gfwlist configuration file. Thanks to cokebar for scripts and configuration file.
Download dnsmasq_gfwlist_ipset.conf and move it to '/etc/dnsmasq.d'. In addition, cokebar also provides a script https://github.com/cokebar/gfwlist2dnsmasq to generate the latest configuration file automatically. To use this script, you may need to install some dependencies which is well instructed by the link provided above. We can write a script and add it to crontab so that the latest gfwlist can be automatically generated. Here is my script for your reference:
#!/bin/sh

if [ -f /root/dnsmasq_gfwlist_ipset.conf ]; then
    echo "Deleting old dnsmasq_gfwlist_ipset.conf..."
    rm /root/dnsmasq_gfwlist_ipset.conf
    echo "Deleted"
fi

/root/gfwlist2dnsmasq.sh -s gfwlist -o /root/dnsmasq_gfwlist_ipset.conf
echo "Moving dnsmasq_gfwlist_ipset.conf to /etc/dnsmasq.d"
mv /root/dnsmasq_gfwlist_ipset.conf /etc/dnsmasq.d/dnsmasq_gfwlist_ipset.conf
echo "Restarting the dnsmasq service..."

/etc/init.d/dnsmasq restart


Step 4: Configure DNS
To prevent DNS pollution (DNS poisoning or DNS spoofing), we need to make the addresses of blocked sites translated via proxy.
In the web management page of OpenWRT, choose 'Services'>'DNS-forwarder':
  • Choose "Enable"
  • Set "Listen Port" to 5353. Attention, the port here must correspond to the port set in dnsmasq_gfwlist_ipset.conf in which default number is 5353
  • Set "Listen Address" to 127.0.0.1
  • Set "DNS Server" to 8.8.8.8
Save and apply.

Last, in the configuration of WAN ("Network">"Interfaces">"WAN" Tab>"Advanced Settings")
  • Cancel "Use DNS servers advertised by peer"
  • Set "Use custom DNS servers" to 127.0.0.1
Save and apply.

Finally, in "Network">"DHCP and DNS" page:
  • Set "DNS forwardings" to the DNS provided by your ISP or public DNS, e.g. 114.114.114.114
We've competed the configuration so far. Now you can test if the router can be connected and whether Google or Youtube can be visited directly from your laptop or phone. If not, please reboot your router and clean the DNS cache on your PC or phone.

Other
*after the configuration of Shadowsocks, you can use ss-local to test if the configuration is correct and usable:
ss-local -c /root/shadowsocks/vultr.json -b <your router's IP> -l 1081
If no error returns, please set socks v5 in your browser's proxy setting. The IP is your router's IP and the port is 1081. Then try to visit baidu.com and search for 'ip'. The first line of the results will show the location of your IP. Please check if it is the IP and location of your Shadowsocks server.

*If you have any other questions, please comment.


评论

  1. It's useful, thanks for your share, I change some part of the set up https://www.dengqiwen.com/post/openwrt-transparent-proxy-setup and
    my problems is that how to deal with the udp traffic? add another iptables rules???

    回复删除

发表评论

此博客中的热门博文

Openwrt路由器上配置shadowsocks透明代理+gfwlist(PAC)

Using Haproxy + shadowsocks (ha + ss) to setup multi ss backend and load balance