原理
利用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 transparent
# 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 ignore-reload ignore-no-cache
refresh_pattern -i \.htm$ 1440 90% 129600 override-lastmod override-expire ignore-reload ignore-no-cache
refresh_pattern -i \.css$ 1440 50% 129600 override-lastmod override-expire ignore-reload ignore-no-cache
refresh_pattern -i \.shtml$ 1440 90% 129600 override-lastmod override-expire ignore-reload ignore-no-cache
refresh_pattern -i \.jpg$ 1440 90% 129600 override-lastmod override-expire ignore-reload ignore-no-cache
refresh_pattern -i \.png$ 1440 90% 129600 override-lastmod override-expire ignore-reload ignore-no-cache
refresh_pattern -i \.gif$ 1440 90% 129600 override-lastmod override-expire ignore-reload ignore-no-cache
refresh_pattern -i \.bmp$ 1440 90% 129600 override-lastmod override-expire ignore-reload ignore-no-cache
refresh_pattern -i \.js$ 1440 90% 129600 override-lastmod override-expire ignore-reload ignore-no-cache
refresh_pattern -i \.mp3$ 1440 50% 2880 override-lastmod override-expire ignore-reload ignore-no-cache
refresh_pattern -i \.wmv$ 1440 50% 2880 override-lastmod override-expire ignore-reload ignore-no-cache
refresh_pattern -i \.rm$ 1440 50% 2880 override-lastmod override-expire ignore-reload ignore-no-cache
refresh_pattern -i \.swf$ 1440 50% 2880 override-lastmod override-expire ignore-reload ignore-no-cache
refresh_pattern -i \.mpeg$ 1440 50% 2880 override-lastmod override-expire ignore-reload ignore-no-cache
refresh_pattern -i \.wma$ 1440 50% 2880 override-lastmod override-expire ignore-reload ignore-no-cache
# 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 reload-into-ims
#
# 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 transparent
# 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 ignore-reload ignore-no-cache
refresh_pattern -i \.htm$ 1440 90% 129600 override-lastmod override-expire ignore-reload ignore-no-cache
refresh_pattern -i \.css$ 1440 50% 129600 override-lastmod override-expire ignore-reload ignore-no-cache
refresh_pattern -i \.shtml$ 1440 90% 129600 override-lastmod override-expire ignore-reload ignore-no-cache
refresh_pattern -i \.jpg$ 1440 90% 129600 override-lastmod override-expire ignore-reload ignore-no-cache
refresh_pattern -i \.png$ 1440 90% 129600 override-lastmod override-expire ignore-reload ignore-no-cache
refresh_pattern -i \.gif$ 1440 90% 129600 override-lastmod override-expire ignore-reload ignore-no-cache
refresh_pattern -i \.bmp$ 1440 90% 129600 override-lastmod override-expire ignore-reload ignore-no-cache
refresh_pattern -i \.js$ 1440 90% 129600 override-lastmod override-expire ignore-reload ignore-no-cache
refresh_pattern -i \.mp3$ 1440 50% 2880 override-lastmod override-expire ignore-reload ignore-no-cache
refresh_pattern -i \.wmv$ 1440 50% 2880 override-lastmod override-expire ignore-reload ignore-no-cache
refresh_pattern -i \.rm$ 1440 50% 2880 override-lastmod override-expire ignore-reload ignore-no-cache
refresh_pattern -i \.swf$ 1440 50% 2880 override-lastmod override-expire ignore-reload ignore-no-cache
refresh_pattern -i \.mpeg$ 1440 50% 2880 override-lastmod override-expire ignore-reload ignore-no-cache
refresh_pattern -i \.wma$ 1440 50% 2880 override-lastmod override-expire ignore-reload ignore-no-cache
# 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 reload-into-ims
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 生效
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本地发起的了,带缓存。
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
-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 = 262144
net.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 = 20000
net.ipv4.tcp_max_syn_backlog = 16384
# TIME-WAIT recycle
net.ipv4.tcp_fin_timeout = 15
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
# tcp keepalive
net.ipv4.tcp_keepalive_time=120
net.ipv4.tcp_keepalive_intvl=30
net.ipv4.tcp_keepalive_probes=3
### tcp retry
net.ipv4.tcp_syn_retries = 0
net.ipv4.tcp_synack_retries = 0
### vmware
vm.swappiness = 1
vm.vfs_cache_pressure=50
vm.overcommit_memory = 1
vm.dirty_background_ratio = 3
vm.dirty_ratio = 40
vm.dirty_expire_centisecs = 1000
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参数优化
# change tcp windows
ip route change default dev via 10.0.0.1 eth0 initrwnd 20 initcwnd 20
ip route change default dev via 10.0.0.1 eth0 initrwnd 20 initcwnd 20
这里将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
(~~~~~~~~~~~~完结~~~~~~~~~~~~)
没有评论:
发表评论