leafsummer
1/11/2016 - 3:37 AM

Linux系统下shadowsocks透明代理的配置.md

#!/bin/bash
# Shell scripts to control shadowsocks proxy on Linux
# Author:	Lance Liao	http://www.shuyz.com
# Date:		Sep 19th, 2015

ss_redir=/opt/shadowsocks/ss-redir
ss_config=/home/lance/.config/shadowsocks/s1_config.json

add_rules_ipset() {
    ipset create gfwlist hash:ip counters timeout 1200

    # Resolve DNS from the proxy to get optimized result for the proxy
    ipset add gfwlist 8.8.8.8
                 
    iptables -t nat -A OUTPUT -p tcp -m set --match-set gfwlist dst -j REDIRECT --to-port 1080
    
    # we should restart dnsmasq to put add rules to the set
    # if dnsmasq is start before the set is created, the site could not be open
    systemctl restart dnsmasq
}

add_rules_global()
{
	iptables -t nat -N SHADOWSOCKS

	# Ignore these IPs, the IP of proxy server should be included here
	iptables -t nat -A SHADOWSOCKS -d 192.210.133.78 -j RETURN

	# Ignore LANs IP address
	iptables -t nat -A SHADOWSOCKS -d 0.0.0.0/8 -j RETURN
	iptables -t nat -A SHADOWSOCKS -d 10.0.0.0/8 -j RETURN
	iptables -t nat -A SHADOWSOCKS -d 127.0.0.0/8 -j RETURN
	iptables -t nat -A SHADOWSOCKS -d 169.254.0.0/16 -j RETURN
	iptables -t nat -A SHADOWSOCKS -d 172.16.0.0/12 -j RETURN
	iptables -t nat -A SHADOWSOCKS -d 192.168.0.0/16 -j RETURN
	iptables -t nat -A SHADOWSOCKS -d 224.0.0.0/4 -j RETURN
	iptables -t nat -A SHADOWSOCKS -d 240.0.0.0/4 -j RETURN

	iptables -t nat -A SHADOWSOCKS -p tcp -j REDIRECT --to-ports 1080

	# using PREROUTING if you're using openwrt
	#iptables -t nat -I PREROUTING -p tcp -j SHADOWSOCKS
	iptables -t nat -A OUTPUT -p tcp -j SHADOWSOCKS
}

remove_rules()
{
	iptables -t nat -F SHADOWSOCKS
 	#iptables -t nat -D OUTPUT -j SHADOWSOCKS
	#iptables -t nat -X SHADOWSOCKS

    ipset flush gfwlist
}

start_ss_auto()
{
	echo starting ss-redir in auto mode...
	$ss_redir -c $ss_config 2>/tmp/ss.log &
	echo "adding ipset rules..."
    add_rules_ipset
	echo done.
}

start_ss_global()
{
	echo starting ss-redir in global mode...
	$ss_redir -c $ss_config 2>/tmp/ss.log &
	echo adding shadowsocks firewall rules...
    add_rules_global
	echo done.
}

stop_ss() {
	echo stopping ss-redir...
	killall ss-redir
	echo removing shadowsocks firewall rules...
    remove_rules
	echo done.
}

check_status()
{
	isfound=$(ps aux | grep "ss-redir" | grep -v "grep"); 
	if [ -z "$isfound" ]; then
		echo "ss-redir is dead!"
	else
		echo "ss-redir is alive"
	fi
	
	echo "ipset list:"
	ipset list gfwlist

	echo "nat rules list:"
	iptables -t nat -L
}

flash_iptables()
{
	echo "flushing all iptables rules..."

	ipset flush gfwlist

	iptables -F
	iptables -X
	iptables -t nat -F
	iptables -t nat -X
	iptables -t mangle -F
	iptables -t mangle -X
	iptables -P INPUT ACCEPT
	iptables -P FORWARD ACCEPT
	iptables -P OUTPUT ACCEPT

	echo "done."
}


if [ $# -eq 0 ]; then 
	check_status
	exit 0
fi

if [[ $1 = "start" ]]; then
	start_ss_auto
elif [[ $1 = "start_auto" ]]; then
	start_ss_auto
elif [[ $1 = "start_global" ]]; then
	start_ss_global
elif [[ $1 = "stop" ]]; then
	stop_ss
elif [[ $1 = "flush" ]]; then
	flash_iptables
else
	check_status
fi

exit 0
[Unit]
Description=shadowsocks proxy service
After=network.target

[Service]
User=root
Type=oneshot
ExecStart=/opt/shadowsocks/shadowsocks start
ExecStop=/opt/shadowsocks/shadowsocks stop
RemainAfterExit=yes
#PIDFile=/run/n2n.pid

[Install]
WantedBy=multi-user.target
  1. 开启ipv4转发
vi /etc/sysctl.conf
# 将net.ipv4.ip_forward=0更改为net.ipv4.ip_forward=1
sysctl -p
  1. 安装dnsmasq 和pdnsd解决dns污染

DNS的解析方案为 resolve.conf ==> dnsmasq ==> pdnsd dnsmasq只将被污染的域名请求发给pdnsd处理,其他的由于dnsmasq不转发请求,会被resolve.conf其他的国内DNS解析。

  • 安装
pacman -S dnsmasq pdnsd
  • pdnsd配置
#vi /etc/pdnsd.conf 
#修改端口并指定google的DNS
    global {
      perm_cache=1024;
      cache_dir="/var/cache";
  #   pid_file = /var/run/pdnsd.pid;
  #   run_as="lance";
      server_port=1053;
      server_ip = 127.0.0.1;  # Use eth0 here if you want to allow other
                  # machines on your network to query pdnsd.
      status_ctl = on;
  #   paranoid=on;       # This option reduces the chance of cache poisoning
                         # but may make pdnsd less efficient, unfortunately.
      query_method=tcp_only;
      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.
  }

  server {
      label="google-dns";
      ip=8.8.8.8;
      root_server=on;
      uptest=none;
  }

  server {        
      label="korea";
      ip=49.238.213.1; 
      root_server=on;
      uptest=none;
  }

配置完成之后通过命令行启动pdnsd --debug进入调试模式,然后测试nslookup -port=1053 twitter.com 127.0.0.1测试解析是否成功

  • dnsmasq的配置
vi /etc/dhcpcd.conf
# 文件末尾加上两行(去掉注释)
#  listen-address=127.0.0.1 
# conf-dir=/etc/dnsmasq.d/,*.conf
# 最后一行指定dnsmasq的解析规则目录,这里只解析被墙的域名,
# 参考https://gist.github.com/lanceliao/85cd3fcf1303dba2498c的脚本生成一份污染域名列表放到该目录下,列表自带ipset规则

  • resolve.conf的配置
vi /etc/resolv.conf

内容改成下面这样,由于dnsmas监听127.0.0.1的53端口,会先使用dnsmasq解析被污染域名,不在规则内的域名使用114解析

# Generated by resolvconf
domain lan

nameserver 127.0.0.1

nameserver 114.114.114.114
nameserver 114.114.115.115

nameserver 8.8.8.8
nameserver 8.8.4.4

这个文件可能被dhcpd改掉,所以保护一下

vi /etc/dhcpcd.conf
#最末尾加上下面这行
nohook resolv.conf

设成只读以防万一:chattr +i /etc/resolv.conf

  • DNS整体测试
systemctl start dnsmasq
systemctl start pdnsd

ping一下facebook(这里测试的是dnsmasq的53标准端口),查一下结果的ip如果正常就没问题

  1. 编写shadowsocks启动和停止脚本shadowsocks.sh,这个脚本将gfwlist的列表域名使用shadowsocks转发。dnsmasq的配置在/etc/dnsmasq.d目录下,由于gfwlist里面没有google的域名,我们另加一个配置文件:

    server=/.google.com.hk/127.0.0.1#1053                                          
    ipset=/.google.com.hk/gfwlist
    
    server=/.google.com/127.0.0.1#1053
    ipset=/.google.com/gfwlist
    
    server=/.google.jp/127.0.0.1#1053
    ipset=/.google.jp/gfwlist
    
    server=/.google.co.jp/127.0.0.1#1053
    ipset=/.google.co.jp/gfwlist
    
    server=/.google.co.uk/127.0.0.1#1053
    ipset=/.google.co.uk/gfwlist
    
    server=/.amazonaws.com/127.0.0.1#1053
    ipset=/.amazonaws.com/gfwlist
    
  2. 编写和启动shadowsocks服务shadowsocks.service

  3. 参考