原理
利用iproute2可根据fwmark选路的功能,结合iptables mangle表set-mark功能,实现基于GeoIP的IP包自动选路。搭建翻墙网关Ultimate版所需软件列表:
- pdnsd
- opendns dnscrypt
- autossh
- openvpn
- iproute2
- xtables-addons
- squid (可选)
- gperftools (可选)
第一章 先决条件
- 一台境外VPS。
- 假定境外VPS的 名称(IP)为 MyVPS。
- MyVPS已经能够用SSH连通。
- MyVPS的SSH端口假定为3723(非标准端口)
- MyVPS已经可以通过身份认证(server_usa)登录(免密码)
- 网关名称为gateway。
- 该网关为局域网(小型公司或机构)的网关。
- 网关系统为ArchLinux(当然其他的也可以)。
- 系统分区已经按照建议分区方式进行了。
我的/etc/fstab为:/dev/sda1 /boot ext3 defaults 0 1
/dev/sda2 / xfs defaults 0 1
/dev/sda3 swap swap defaults 0 0
/dev/sda5 /usr xfs defaults 0 1
/dev/sda6 /var reiserfs defaults,notail,noatime,nodiratime 0 1
/dev/sda7 /tmp reiserfs defaults,notail,noatime,nodiratime 0 1
/dev/sda8 /home xfs defaults 0 1
/dev/sdb1 /var2 reiserfs defaults,notail,noatime,nodiratime,data=writeback 0 1 - 网关的出口为eth0。
- MyVPS和网关均开启了ip_forward。
第二章 目标
- 首先当然是无缝翻墙了,对于http(80)服务做到缓存,对于https(443)服务做到转发。
- 对于国内的网站,响应速度不能比直接上网慢。
- 如果MyVPS 断掉,不影响用户用上普通境外网站 (failsafe) 。
第三章 安装与配置
0. MyVPS的iptables
只有一条,在nat表中
-A POSTROUTING -o eth0 -j MASQUERADE
让来自gateway的数据包做NAT。1. 基础软件安装
可以用pacman 直接安装的软件为:pdnsd,autossh, openvpn, iproute2, squid
需要通过ArchLinux AUR安装的为:
opendns-dnscrypt, xtables-addons, gperftools
安装时请自己解决依赖关系(depends)。
能通过pacman直接安装的就不再叙述。
通过AUR 安装了以上软件后,需要做如下设置:
对于xtables-addons,需要执行
depmod -a <-- 更新 modules.dep, 内核模块都需这个操作
然后在 /etc/rc.conf中加入
MODULES=(xt_ipp2p xt_geoip) <-- 加载geoip模块(目前还未配置geoip)
最后在 /etc/rc.conf中加入
DAEMONS=(hwclock syslog-ng network netfs crond sshd open-vm-tools openvpn dnscrypt-proxy pdnsd squid iptables lighttpd)
2. iproute2 -- 新的路由表
在/etc/iproute2/rt_tables中加入一行
1 hof
这里我们新增加一张路由表,以区别默认的用户路由表。命名为hof,这里随便命名了,用gfw也行,数字 1 是这个表的数字编码,区分默认路由表253就可以了,我们主要就是利用这张表来进行翻墙。
ip route show <-- 可以返回默认路由表。
ip route show table hof <-- 返回hof表,目前应该是空的。
3. autossh配置 -- Across the great firewall
如何做到不用密码登陆服务器,请参考 这篇 。加到 /etc/rc.local 中:
/usr/bin/autossh -M 21000 -f -N -C -c blowfish -L 1194:localhost:1194 root@MyVPS -p3723 -i /root/server_usa <-- 身份文件(private key)
请先手动启动这个通道, 1194端口为OpenVPN的默认端口,我们让openvpn走SSH Tunnel加密隧道进行通信。至于为什么要走ssh tunnel, 参考这篇文章。
4. openvpn配置 -- 目标-- tun0的ip规则
参照前文 openvpn 最简配置,了解openvpn的基本配置原理,实现通过ssh隧道的vpn通信。配置如下,与前文openvpn的配置略有不同:
MyVPS:
# cat /etc/openvpn/server.conf
dev tunlocal 127.0.0.1
ifconfig 172.7.7.1 172.7.7.2 <-- 指定点对点设备的IP
proto tcp-server
secret static.key
cipher none
auth none
persist-key
persist-tun
user nobody
group nobody
keepalive 10 30
comp-lzo
tun-mtu 1300
Gateway:
[root@archlinux ~]# cat /etc/openvpn/client.conf
remote 127.0.0.1 1194
dev tun
ifconfig 172.7.7.2 172.7.7.1 <-- 指定点对点设备的IP
proto tcp-client
secret static.key
cipher none
auth none
persist-key
comp-lzo
tun-mtu 1300
script-security 2
up "up.sh"
up-delay <-- 关键,在成功建立通道后再执行脚本(改变路由表)
down "down.sh"
down-pre <-- 在TUN断掉前就及时执行down.sh,改变路由表
up-restart <-- 关键,在每次断线后(而不是程序中止),执行down,up脚本。及时改变路由。
remote 127.0.0.1 1194
dev tun
ifconfig 172.7.7.2 172.7.7.1 <-- 指定点对点设备的IP
proto tcp-client
secret static.key
cipher none
auth none
persist-key
persist-tun
#user nobody <-- 关键!
#group nobody <-- 需要用root权限启动,脚本运行需要root权限
keepalive 10 30comp-lzo
tun-mtu 1300
script-security 2
up "up.sh"
up-delay <-- 关键,在成功建立通道后再执行脚本(改变路由表)
down "down.sh"
down-pre <-- 在TUN断掉前就及时执行down.sh,改变路由表
openvpn配置好后,我们就可以编写路由规则脚本(up.sh, down.sh) 了:
当openvpn通道建立的时候,让带有某个标记的数据包,选用hof这张路由表,在hof表中,默认路由为openvpn的通道--tun0。
我们假设,对访问境外网的数据包,打的标记为,数字 65 (后面会用iptables+geoip打标记)
我们在openvpn通道建立的时候加入这个规则:
修改gateway上 /etc/openvpn/up.sh
#!/bin/sh
ip rule add fwmark 65 table hof <-- 让带有65标记的数据表走hof表
ip route add to default dev tun0 table hof initrwnd 20 initcwnd 20 <-- 默认路由为tun0
exit 0
exit 0
这里实现了根据ip标记的选路,注意initrwnd initcwnd参数,对于高延迟的路由,特别有用,尤其是境外网站,这样降低了初始tcp ACK的次数,这里将tcp的初始发送窗口和接受窗口都改为20倍MSS(小于MTU)。后面有关于这个问题的说明(TCP slow start),这里不详说。
为了实现当通道断掉的时候,或者说MyVPS不可用的情况下,也不妨碍正常的上国外网站(failsafe)。因此在openvpn断掉(down)的时候,要删除我们上面加入的规则,如下:
修改gateway上 /etc/openvpn/down.sh
#!/bin/sh
ip rule delete fwmark 65 table hof
ip route delete to default dev tun0 table hof
exit 0
exit 0
启动 openvpn
执行 ip addr 应该会有如下输出:
4: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1300 qdisc pfifo_fast state UNKNOWN qlen 100
link/none
inet 172.7.7.2 peer 172.7.7.1/32 scope global tun0
link/none
inet 172.7.7.2 peer 172.7.7.1/32 scope global tun0
确保vpn已经连接成功,tun0 设备出现,并通过ip rule show 和 ip route show table hof检查规则是否生效。
[root@archlinux ~]# ip rule show
0: from all lookup local
32765: from all fwmark 0x41 lookup hof
32766: from all lookup main
32767: from all lookup default
0: from all lookup local
32765: from all fwmark 0x41 lookup hof
32766: from all lookup main
32767: from all lookup default
[root@archlinux openvpn]# ip route show table hof
default dev tun0 scope link initcwnd 20 initrwnd 20
default dev tun0 scope link initcwnd 20 initrwnd 20
5. pdnsd配置 -- 加速dns解析
先配置一下dnscrypt ,让dnscrypt跑在非53端口,避免占用pdnsd的53端口
[root@archlinux ~]# cat /etc/conf.d/dnscrypt-proxy
DNSCRYPT_LOCALIP=127.0.0.1
DNSCRYPT_LOCALPORT=50 <-- 改为50
DNSCRYPT_USER=nobody
DNSCRYPT_LOCALIP=127.0.0.1
DNSCRYPT_LOCALPORT=50 <-- 改为50
DNSCRYPT_USER=nobody
重新启动你的dnscrypt。 剩下的是对pdnsd.conf的配置,如下:
global {
perm_cache=65536;
cache_dir="/var/cache/pdnsd";
pid_file = /var/run/pdnsd.pid;
run_as="nobody";
server_ip = any; # Use eth0 here if you want to allow other
# machines on your network to query pdnsd.
status_ctl = on;
query_method=tcp_only;
use_nss=off;
min_ttl=1d;
max_ttl=1w; # One week.
timeout=10; # Global timeout option (10 seconds).
par_queries=1;
neg_rrs_pol=on;
}
server {
label= "local dnscrypt";
ip = 127.0.0.1;
port = 50; # dnscrypt的50端口
timeout=10;
uptest=query;
edns_query=no;
}
server {
label= "google dns"; # 备用 dns
ip = 8.8.8.8,8.8.4.4;
timeout=10;
uptest=ping;
edns_query=no;
}
perm_cache=65536;
cache_dir="/var/cache/pdnsd";
pid_file = /var/run/pdnsd.pid;
run_as="nobody";
server_ip = any; # Use eth0 here if you want to allow other
# machines on your network to query pdnsd.
status_ctl = on;
query_method=tcp_only;
use_nss=off;
min_ttl=1d;
max_ttl=1w; # One week.
timeout=10; # Global timeout option (10 seconds).
par_queries=1;
neg_rrs_pol=on;
}
server {
label= "local dnscrypt";
ip = 127.0.0.1;
port = 50; # dnscrypt的50端口
timeout=10;
uptest=query;
edns_query=no;
}
server {
label= "google dns"; # 备用 dns
ip = 8.8.8.8,8.8.4.4;
timeout=10;
uptest=ping;
edns_query=no;
}
可以通过pdnsd-ctl status 查看pdnsd运行状态
6. squid 配置 -- 控制中心 (可选)
squid 的配置此处已经简化了,squid再也不用去管翻墙的事,翻墙的事让路由做了。squid 安装好后的默认配置就可以运行了,以下列出我的一些优化参数(可选):
##########################################################################
#
# Recommended minimum configuration:
#
acl manager proto cache_object
acl localhost src 127.0.0.1/32 ::1
acl to_localhost dst 127.0.0.0/8 0.0.0.0/32 ::1
# Example rule allowing access from your local networks.
# Adapt to list your (internal) IP networks from where browsing
# should be allowed
acl localnet src 10.0.0.0/8 # RFC1918 possible internal network
acl localnet src 172.16.0.0/12 # RFC1918 possible internal network
acl localnet src 192.168.0.0/16 # RFC1918 possible internal network
acl localnet src fc00::/7 # RFC 4193 local private network range
acl localnet src fe80::/10 # RFC 4291 link-local (directly plugged) machines
acl SSL_ports port 443
acl Safe_ports port 80 # http
acl Safe_ports port 21 # ftp
acl Safe_ports port 443 # https
acl Safe_ports port 70 # gopher
acl Safe_ports port 210 # wais
acl Safe_ports port 1025-65535 # unregistered ports
acl Safe_ports port 280 # http-mgmt
acl Safe_ports port 488 # gss-http
acl Safe_ports port 591 # filemaker
acl Safe_ports port 777 # multiling http
acl CONNECT method CONNECT
#
# Recommended minimum Access Permission configuration:
#
# Only allow cachemgr access from localhost
http_access allow manager localhost
http_access deny manager
# Deny requests to certain unsafe ports
http_access deny !Safe_ports
# Deny CONNECT to other than secure SSL ports
http_access deny CONNECT !SSL_ports
# We strongly recommend the following be uncommented to protect innocent
# web applications running on the proxy server who think the only
# one who can access services on "localhost" is a local user
#http_access deny to_localhost
##########################################################################
# INSERT YOUR OWN RULE(S) HERE TO ALLOW ACCESS FROM YOUR CLIENTS
#
# 禁止一些网站
acl denied_domains url_regex "/etc/squid/denied_domains.acl"
http_access deny denied_domains
# block xunlei(迅雷)
acl IP dstdom_regex [0-9]$
acl ROOT urlpath_regex ^/$
acl POST method POST
acl Octet_Stream req_mime_type application/octet-stream
http_access deny IP ROOT POST Octet_Stream
# Example rule allowing access from your local networks.
# Adapt localnet in the ACL section to list your (internal) IP networks
# from where browsing should be allowed
http_access allow localnet
http_access allow localhost
# And finally deny all other access to this proxy
http_access deny all
# Block Multithread downloading.(多线程下载)
acl partial rep_header Content-Range .*
http_reply_access deny partial
##########################################################################
# Squid normally listens to port 3128
http_port 3128 intercept
# Leave coredumps in the first cache dir
coredump_dir /var/cache/squid
##############################################################
forwarded_for off
via off
cache_dir aufs /var2/cache/squid 16384 32 512
cache_mem 4096 MB
dns_v4_first on
memory_pools off
memory_replacement_policy lru
cache_replacement_policy heap LFUDA
maximum_object_size 16384 KB
maximum_object_size_in_memory 2048 KB
dns_nameservers 127.0.0.1
access_log none
client_db on
half_closed_clients off
buffered_logs on
relaxed_header_parser on
refresh_pattern -i \.html$ 1440 90% 129600 override-lastmod override-expire
refresh_pattern -i \.htm$ 1440 90% 129600 override-lastmod override-expire
refresh_pattern -i \.css$ 1440 50% 129600 override-lastmod override-expire
refresh_pattern -i \.shtml$ 1440 90% 129600 override-lastmod override-expire
refresh_pattern -i \.jpg$ 1440 90% 129600 override-lastmod override-expire
refresh_pattern -i \.png$ 1440 90% 129600 override-lastmod override-expire
refresh_pattern -i \.gif$ 1440 90% 129600 override-lastmod override-expire
refresh_pattern -i \.bmp$ 1440 90% 129600 override-lastmod override-expire
refresh_pattern -i \.js$ 1440 90% 129600 override-lastmod override-expire
refresh_pattern -i \.mp3$ 1440 50% 2880 override-lastmod override-expire
refresh_pattern -i \.wmv$ 1440 50% 2880 override-lastmod override-expire
refresh_pattern -i \.rm$ 1440 50% 2880 override-lastmod override-expire
refresh_pattern -i \.swf$ 1440 50% 2880 override-lastmod override-expire
refresh_pattern -i \.mpeg$ 1440 50% 2880 override-lastmod override-expire
refresh_pattern -i \.wma$ 1440 50% 2880 override-lastmod override-expire
# Add any of your own refresh_pattern entries above these.
refresh_pattern ^ftp: 1440 20% 10080
refresh_pattern ^gopher: 1440 0% 1440
refresh_pattern -i (/cgi-bin/|\?) 0 0% 0
refresh_pattern . 0 20% 4320
#
# Recommended minimum configuration:
#
acl manager proto cache_object
acl localhost src 127.0.0.1/32 ::1
acl to_localhost dst 127.0.0.0/8 0.0.0.0/32 ::1
# Example rule allowing access from your local networks.
# Adapt to list your (internal) IP networks from where browsing
# should be allowed
acl localnet src 10.0.0.0/8 # RFC1918 possible internal network
acl localnet src 172.16.0.0/12 # RFC1918 possible internal network
acl localnet src 192.168.0.0/16 # RFC1918 possible internal network
acl localnet src fc00::/7 # RFC 4193 local private network range
acl localnet src fe80::/10 # RFC 4291 link-local (directly plugged) machines
acl SSL_ports port 443
acl Safe_ports port 80 # http
acl Safe_ports port 21 # ftp
acl Safe_ports port 443 # https
acl Safe_ports port 70 # gopher
acl Safe_ports port 210 # wais
acl Safe_ports port 1025-65535 # unregistered ports
acl Safe_ports port 280 # http-mgmt
acl Safe_ports port 488 # gss-http
acl Safe_ports port 591 # filemaker
acl Safe_ports port 777 # multiling http
acl CONNECT method CONNECT
#
# Recommended minimum Access Permission configuration:
#
# Only allow cachemgr access from localhost
http_access allow manager localhost
http_access deny manager
# Deny requests to certain unsafe ports
http_access deny !Safe_ports
# Deny CONNECT to other than secure SSL ports
http_access deny CONNECT !SSL_ports
# We strongly recommend the following be uncommented to protect innocent
# web applications running on the proxy server who think the only
# one who can access services on "localhost" is a local user
#http_access deny to_localhost
##########################################################################
# INSERT YOUR OWN RULE(S) HERE TO ALLOW ACCESS FROM YOUR CLIENTS
#
# 禁止一些网站
acl denied_domains url_regex "/etc/squid/denied_domains.acl"
http_access deny denied_domains
# block xunlei(迅雷)
acl IP dstdom_regex [0-9]$
acl ROOT urlpath_regex ^/$
acl POST method POST
acl Octet_Stream req_mime_type application/octet-stream
http_access deny IP ROOT POST Octet_Stream
# Example rule allowing access from your local networks.
# Adapt localnet in the ACL section to list your (internal) IP networks
# from where browsing should be allowed
http_access allow localnet
http_access allow localhost
# And finally deny all other access to this proxy
http_access deny all
# Block Multithread downloading.(多线程下载)
acl partial rep_header Content-Range .*
http_reply_access deny partial
##########################################################################
# Squid normally listens to port 3128
http_port 3128 intercept
# Leave coredumps in the first cache dir
coredump_dir /var/cache/squid
##############################################################
forwarded_for off
via off
cache_dir aufs /var2/cache/squid 16384 32 512
cache_mem 4096 MB
dns_v4_first on
memory_pools off
memory_replacement_policy lru
cache_replacement_policy heap LFUDA
maximum_object_size 16384 KB
maximum_object_size_in_memory 2048 KB
dns_nameservers 127.0.0.1
access_log none
client_db on
half_closed_clients off
buffered_logs on
relaxed_header_parser on
refresh_pattern -i \.html$ 1440 90% 129600 override-lastmod override-expire
refresh_pattern -i \.htm$ 1440 90% 129600 override-lastmod override-expire
refresh_pattern -i \.css$ 1440 50% 129600 override-lastmod override-expire
refresh_pattern -i \.shtml$ 1440 90% 129600 override-lastmod override-expire
refresh_pattern -i \.jpg$ 1440 90% 129600 override-lastmod override-expire
refresh_pattern -i \.png$ 1440 90% 129600 override-lastmod override-expire
refresh_pattern -i \.gif$ 1440 90% 129600 override-lastmod override-expire
refresh_pattern -i \.bmp$ 1440 90% 129600 override-lastmod override-expire
refresh_pattern -i \.js$ 1440 90% 129600 override-lastmod override-expire
refresh_pattern -i \.mp3$ 1440 50% 2880 override-lastmod override-expire
refresh_pattern -i \.wmv$ 1440 50% 2880 override-lastmod override-expire
refresh_pattern -i \.rm$ 1440 50% 2880 override-lastmod override-expire
refresh_pattern -i \.swf$ 1440 50% 2880 override-lastmod override-expire
refresh_pattern -i \.mpeg$ 1440 50% 2880 override-lastmod override-expire
refresh_pattern -i \.wma$ 1440 50% 2880 override-lastmod override-expire
# Add any of your own refresh_pattern entries above these.
refresh_pattern ^ftp: 1440 20% 10080
refresh_pattern ^gopher: 1440 0% 1440
refresh_pattern -i (/cgi-bin/|\?) 0 0% 0
refresh_pattern . 0 20% 4320
7. geoip 配置 -- 智能选路的基础
man xtables-addons
geoip部分已经说得很清楚了,直接复制过来:
The extra files you will need is the binary database files. They are generated from a country-subnet database with the geoip_build_db.pl tool that is shipped with the source package, and which should be available in compiled
packages in /usr/lib(exec)/xtables-addons/. The first command retrieves CSV files from MaxMind, while the other two build packed bisectable range files:
mkdir -p /usr/share/xt_geoip; cd /tmp; $path/to/xt_geoip_dl;
$path/to/xt_geoip_build -D /usr/share/xt_geoip GeoIP*.csv;
The shared library is hardcoded to look in these paths, so use them.
archlinux下 $path/to/xt_geoip_dl; 为 /usr/lib/iptables/xtables-addons/xt_geoip_dl
modprobe xt_geoip <!-- 让iptables match geoip 生效
xt_geoip_build需要perl的perl-text-csv-xs包,需要通过AUR安装:
http://aur.archlinux.org/packages/pe/perl-text-csv-xs/perl-text-csv-xs.tar.gz
8. iptables配置 -- 将上面的都连起来
还记得上面的OpenVPN建立的规则么,是的,我们现在就要开始给数据包打标记了:mangle表:
-A PREROUTING -p tcp -m tcp --dport 443 -m geoip ! --destination-country CN -j MARK --set-xmark 0x41/0xffffffff <-- 数字65
-A OUTPUT -p tcp -m tcp --dport 80 -m geoip ! --destination-country CN -j MARK --set-xmark 0x41/0xffffffff <-- 数字65
a) 对非CN的https(443端口)访问的ip地址,打标记65 ,注意是PREROUTING表,外来的443端口数据直接由tun0出去。确保对外的https能正常访问。
b) 对非CN的http(80端口)访问的ip地址,打标记65,注意是OUTPUT 表,这里是squid本地发起的了,带缓存。(如果没有安装squid,改为PREROUTING)
nat表:
-A PREROUTING -i eth0 -p udp -m udp --dport 53 -j REDIRECT --to-ports 53
-A PREROUTING -d 10.0.0.0/8 -j ACCEPT
-A PREROUTING -d 172.0.0.0/8 -j ACCEPT
-A PREROUTING -d 192.168.0.0/16 -j ACCEPT
-A PREROUTING -i eth0 -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 3128 (如果没有安装squid,以上红色部分不需要)
-A POSTROUTING -o tun0 -j MASQUERADE
a) 劫持所有的DNS查询请求到本地的pdnsd服务
b) 对于LAN的IP地址,10,172,192.168这些内网段,直接通过,不转到squid
(sorry~~~, mangle表没写好,导致了内网段也打上了65标记。)
c)把所有对http(80)端口的访问转发到3128端口(squid)
d) 对 tun0出口的做NAT(sigh~~~ 不想把路由写复杂了,就nat吧,简单)
第四章 优化 -- Let's fly
a) /etc/sysct.conf
#
# Kernel sysctl configuration
#
# Disable packet forwarding
net.ipv4.ip_forward=1
# Disable the magic-sysrq key (console security issues)
kernel.sysrq = 0
# Enable TCP SYN Cookie Protection
net.ipv4.tcp_syncookies = 1
kernel.sem = 100 fs.file-max = 6815744 net.ipv4.ip_local_port_range = 10000 65500
# memory net.core.rmem_default = 262144 net.core.wmem_default = 262144net.core.rmem_max = 16777216 net.core.wmem_max = 16777216 net.ipv4.tcp_rmem = 4096 4096 16777216 net.ipv4.tcp_wmem = 4096 4096 16777216 net.ipv4.tcp_mem = 786432 2097152 3145728
# backlogs net.core.somaxconn = 2048 net.core.netdev_max_backlog = 20000net.ipv4.tcp_max_syn_backlog = 16384
# TIME-WAIT recycle net.ipv4.tcp_fin_timeout = 15 net.ipv4.tcp_tw_reuse = 1net.ipv4.tcp_tw_recycle = 1 <-- 此参数比较有争议,慎用
# tcp keepalive net.ipv4.tcp_keepalive_time=120 net.ipv4.tcp_keepalive_intvl=30net.ipv4.tcp_keepalive_probes=3
### tcp retry net.ipv4.tcp_syn_retries = 0 net.ipv4.tcp_synack_retries = 0
### vm sysctl
vm.swappiness = 1
vm.vfs_cache_pressure=50 <-- 这一段目的为尽量延缓数据写入
vm.overcommit_memory = 0
vm.dirty_background_ratio = 20
vm.dirty_ratio = 40
vm.dirty_expire_centisecs = 180000 <-- UP
vm.dirty_writeback_centisecs = 180000 <-- UP
net.ipv6.conf.all.disable_ipv6 = 1
b) /etc/fstab
对squid swap分区优化:
/dev/sdb1 /var2 reiserfs defaults,notail,noatime,nodiratime,data=writeback 0 1
c) 对dns进行预加载 (可选)
cat /etc/cron.daily/dig
#!/bin/sh
pdnsd-ctl dump |grep "^[a-zA-Z0-9_\-\.]\+$" > /tmp/dnscommon.txt
dig @127.0.0.1 -f /tmp/dnscommon.txt > /dev/null
pdnsd-ctl dump |grep "^[a-zA-Z0-9_\-\.]\+$" > /tmp/dnscommon.txt
dig @127.0.0.1 -f /tmp/dnscommon.txt > /dev/null
这个cron script比较粗暴,只增不减,不过问题也不大,后期稳定在几万条记录。
d) gperftools 的tcmalloc优化
Google Performance Tools:gperftools提供的malloc函数很高效,特别适用于squid这种反复分配内存的应用,有利于降低cpu利用率,并提高响应速度。
采用的是最简单的LD_PRELOAD方式加载, 打开 /etc/rc.d/squid 在执行squid前加入一句:
. /etc/rc.conf
. /etc/rc.d/functions
. /etc/rc.d/functions
export LD_PRELOAD="/usr/lib/libtcmalloc.so"
....
e) QoS优化,让翻墙数据包先行 tc
在 /etc/rc.local 中,加入:
# QoS
tc qdisc add dev eth0 root handle 1: prio
tc filter add dev eth0 protocol ip parent 1: prio 0 u32 match ip dst MyVPS的IP/32 flowid 1:1
tc filter add dev eth0 protocol ip parent 1: prio 2 u32 match ip src 0/0 flowid 1:2
tc qdisc add dev eth0 root handle 1: prio
tc filter add dev eth0 protocol ip parent 1: prio 0 u32 match ip dst MyVPS的IP/32 flowid 1:1
tc filter add dev eth0 protocol ip parent 1: prio 2 u32 match ip src 0/0 flowid 1:2
稍微解释一下:
1. 对eth0设备,我们采用的带宽控制策略是PRIO,PRIO qdisc有固定的三个优先级1,2,3。
2. 我们让流向MyVPS的数据,flow到 1:1 这个最高优先级的band。
3. 让其他数据流向1:2这个最低优先级的band。
f) eth0的 tcp参数优化
在 /etc/rc.local 中,加入:
# change tcp windows
ip route change default dev via 10.0.0.1 eth0 initrwnd 20 initcwnd 20 <-- 假设出口网关IP是10.0.0.1(如路由器)这里将tcp的发送窗口和接受窗口都改为20倍MSS(小于MTU), 这个优化对于squid服务特别有用,解决tcp slow start 问题, 这里对访问国内网站加速。
g) 文件打开数的优化
修改 /etc/security/limits.conf
* - nofile 65535 <-- 进程最大文件数65535
[root@archlinux ~]# cat /etc/conf.d/squid
#
# Parameters to be passed to squid
#
SQUID_ARGS="-sYC"
SQUID_MAXFD=65535
#
# Parameters to be passed to squid
#
SQUID_ARGS="-sYC"
SQUID_MAXFD=65535
h) 磁盘调度方式调整
修改 /etc/rc.local,加入:
echo "deadline" > /sys/block/sda/queue/scheduler
echo "deadline" > /sys/block/sdb/queue/scheduler
echo "deadline" > /sys/block/sdb/queue/scheduler
提高IO响应速度。
参考资料
- Arch Linux
- Linux Advanced Routing & Traffic Control
- gperftools
- Xtables-addons
- The pdnsd Homepage
- OpenVPN
- AutoSSH
- TCP Slow Start Problem
(~~~~~~~~~~~~完结~~~~~~~~~~~~)
补: ubuntu用户必须关闭 (2012/9/25)
net.ipv4.conf.all.rp_filter = 0
net.ipv4.conf.default.rp_filter = 0
默认系统是开启的。在 /etc/sysctl.d 中。
from http://bullshitlie.blogspot.com/2012/04/ultimate.html