Skip to content

Instantly share code, notes, and snippets.

@lanceliao
Last active September 20, 2019 14:55
Show Gist options
  • Save lanceliao/3099caed8750911dfe58 to your computer and use it in GitHub Desktop.
Save lanceliao/3099caed8750911dfe58 to your computer and use it in GitHub Desktop.
  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. 参考

[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
#!/bin/bash
# Shell scripts to control shadowsocks proxy on Linux
# Author: Lance Liao http://www.shuyz.com
# Date: Sep 19th, 2015
# Last updated: Apr 9, 2016
ss_redir=/opt/shadowsocks/ss-redir
ss_tunnel=/opt/shadowsocks/ss-tunnel
ss_config=/home/lance/.config/shadowsocks/s1_config.json
ss_port=1080
dns_port=1054
add_rules_ipset() {
set_ok=$(ipset list | grep "gfwlist")
if [ -z "$set_ok" ]; then
ipset create gfwlist hash:ip counters timeout 1200
else
echo 'ipset gfwlist already exists!'
fi
echo 'add dns servers to gfwlist...'
ipset add gfwlist 8.8.8.8
ipset add gfwlist 8.8.4.4
ipset add gfwlist 49.238.213.1
ipset add gfwlist 208.67.222.222
ipset add gfwlist 208.67.220.220
iptables -t nat -A OUTPUT -p tcp -m set --match-set gfwlist dst -j REDIRECT --to-port $ss_port
# 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
echo 'restarting dnsmasq...'
systemctl restart dnsmasq
}
add_rules_iptables()
{
iptables -t nat -N SHADOWSOCKS
# Ignore these IPs, the IP of proxy server should be included here
iptables -t nat -A SHADOWSOCKS -d 104.224.156.171 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 45.62.113.186 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 216.189.155.203 -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 $ss_port
# 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 SHADOWSOCKS
#iptables -t nat -D OUTPUT -p tcp -j SHADOWSOCKS
#iptables -t nat -X SHADOWSOCKS
ipset flush gfwlist
}
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 "iptables flushed."
}
init_proxy()
{
if [[ $1 = "auto" ]]; then
echo "initiliazing proxy in auto mode..."
echo "adding ipset for ss-redir..."
add_rules_ipset
else
echo "initiliazing proxy in global mode..."
echo "adding iptables rules for ss-redir..."
add_rules_iptables
fi
echo "starting ss-redir on port ${ss_port}..."
nohup $ss_redir -c $ss_config 2>/tmp/ss-redir.log &
echo "ss-redir started."
echo "start ss-tunnel on port ${dns_port}..."
nohup $ss_tunnel -c $ss_config -l $dns_port -L 8.8.8.8:53 -u 2>/tmp/ss-tunnel.log &
echo "ss-tunnel started."
echo "all done!"
}
stop_proxy() {
echo "stopping ss-redir..."
killall -9 ss-redir
echo "ss-redir killed."
echo "stop ss-tunnel..."
killall -9 ss-tunnel
echo "ss-tunnel killed."
echo removing shadowsocks firewall rules...
remove_rules
echo "firewall rules removed."
echo "all 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
isfound=$(ps aux | grep "ss-tunnel" | grep -v "grep");
if [ -z "$isfound" ]; then
echo "ss-tunnel is dead!"
else
echo "ss-tunnel is alive"
fi
echo "iptable nat rules:"
iptables -t nat -L
echo "ipset list:"
ipset list gfwlist
# echo "nat rules list:"
# iptables -t nat -L
}
if [ $# -eq 0 ]; then
check_status
exit 0
fi
if [[ $1 = "start" ]]; then
init_proxy auto
elif [[ $1 = "start_auto" ]]; then
init_proxy auto
elif [[ $1 = "start_global" ]]; then
init_proxy global
elif [[ $1 = "stop" ]]; then
stop_proxy
elif [[ $1 = "flush" ]]; then
flash_iptables
else
check_status
fi
exit 0
@wattic
Copy link

wattic commented Mar 26, 2016

/etc/resolv.conf 那里,似乎dnsmasq只认3条记录

@jiuxiaxixi
Copy link

写的非常好!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment