@delight
2015-01-10T17:12:49.000000Z
字数 11816
阅读 3478
ziproxy
squid
本文档隶属于Dolphin Proxy项目原型配置文档,目前(2013/12/23)所有配置可能需要进一步优化,故以下配置参数的值仅供参考使用。
环境:Ubuntu 12.04 LTS x64
ziproxy(以及其他)的安装,可以从source里面直接安装二进制版,也可以自行编译安装。一般而言,source里面的版本不会是软件的最新版本,而是经过测试的较为稳定的版本,但是最新版会修正一些bug,因此可根据情况妥善考虑。这里(以及下面)都是使用命令直接从source里面安装的。
输入sudo aptitude install ziproxy
,目前源里面的版本是3.2.0(使用aptitude show ziproxy
可以查看源里面的版本)。安装后服务(守护进程)会自动启动,并自动加入开机启动项。
输入sudo vim /etc/ziproxy/ziproxy.conf
,编辑配置文件。默认配置需要修改的部分并不多,,以下是对配置文件的详细分析,如果要做快速测试,那么仅需要修改常规选项部分。
#监听端口,默认8080
Port=8001
#本地网卡绑定,默认绑定所有
#如果有多网卡,可以考虑绑定特定的IP
Address="127.0.0.1"
#Debug Log,默认关闭
DebugLog = "/var/log/ziproxy/debug.log"
#Error Log,默认关闭
ErrorLog = "/var/log/ziproxy/error.log"
#Access Log,默认关闭
AccessLog = "/var/log/ziproxy/access.log"
#指定dump服务pid号的文件,默认打印到标准输出
PIDFile = "/var/run/ziproxy.pid"
#下一跳代理地址,默认关闭
NextProxy = "127.0.0.1"
NextPort=3128
#禁止外部连接,仅接受来自该IP的请求
OnlyFrom="127.0.0.1"
#最大同时访问数,默认无限制
MaxActiveUserConnections = 20
#以另外的身份运行,权限控制,默认关闭(以当前用户运行)
RunAsUser = "ziproxy"
RunAsGroup = "ziproxy"
#信号拦截/屏蔽,默认关闭
InterceptCrashes = false
#加密认证,默认关闭,枚举选项
AuthMode = 0
#认证文件(纯文本),当AutoMode=1时使用
AuthPasswdFile = "/etc/ziproxy/http.passwd"
#认证文件(SSAL),当AutoMode=2时使用
AuthSASLConfPath = "/etc/ziproxy/sasl/"
#对外部服务器的绑定地址,默认使用OS的默认IP
#可以用来做负载均衡,有些网站会拒绝一个IP的频繁请求
#所有绑定IP的使用几率是均等的
BindOutGoing={}
#与上述选项对应,在请求时不转换ip的白名单
BindOutgoingExList="/etc/ziproxy/bo_exception.list"
#上述白名单中应该绑定的特定IP
BindOutgoingExAddr="98.7.65.43"
#是否将ziproxy作为透明代理,默认关闭
#如果需要打开,必须对本地用户做相应的转发处理
#与传统代理功能可以并存
TransparentProxy = false
#传统代理
ConventionalProxy = true
#是否允许CONNECT请求,默认打开
#一般用来过滤https请求
AllowMethodCONNECT = true
#本地请求限制(HTTP),配合透明代理使用,默认关闭
RestrictOutPortHTTP = {80, 8080}
#本地请求限制(HTTPS)
RestrictOutPortCONNECT = {443}
#更改UA,默认不更改,以下示例表示如何伪装Firefox
RedefineUserAgent = "Mozilla/5.0 (compatible; UltraBrowser/8.1; CP/M; console40x24; z80)"
总体相关
#黑名单,不使用ziproxy的列表;可以作为bug的临时解决方案
URLNoProcessing = "/etc/ziproxy/noprocess.list"
#禁止访问的名单,会返回一个403错误
URLDeny = "/etc/ziproxy/deny.list"
#Check header的选项,默认关闭
ViaServer = ...
#超时设置,默认90s
ConnTimeout = 90
Gzip相关
#是否在Accept-Encoding中覆盖客户端设置,加入gzip选项,默认true
#ziproxy会根据客户端原始的Http首部决定是否需要解压gzip流
OverrideAcceptEncoding = true
#如果远程服务器已经启用gzip压缩,是否解压
#ziproxy的某些操作(html优化、DNS相关的选项)必须解压后才能操作
#一般与下面的Gzip选项同值
DecompressIncomingGzipData = true
#最大解压缩比例(如果超出,则放弃解压),默认是20倍
MaxUncompressedGzipRatio = 2000
#最大压缩文件(默认1M),超出此数值不再(重新)压缩
MaxSize=1048576
#是否使用gzip无损压缩
Gzip=true
#使用gzip压缩的文件类型,默认一大堆,基本包含了所有text like选项
LosslessCompressCT={...}
LosslessCompressCTAlsoXST = true
#优化html/css/js的选项,默认关闭
#在当前版本,该功能还不稳定
ProcessHTML = false
ProcessCSS = false
ProcessJS = false
#HTML优化的细节,仅当ProcessHTML=true时生效
ProcessHTML_CSS = true
ProcessHTML_JS = true
ProcessHTML_tags = true
ProcessHTML_text = true
ProcessHTML_PRE = true
ProcessHTML_NoComments = true
ProcessHTML_TEXTAREA = true
Image相关
#原图像最大压缩率,超过该数值不再重新压缩图像
MaxUncompressedImageRatio = 500
#压缩的图像格式
ProcessPNG=true
ProcessGIF=true
ProcessJPG=true
#压缩的图像质量,四个参数指的都是压缩率的百分比(压缩后的体积:压缩前)
#分别应用于图像像素在(0,5000],(5000,50000]或某个尺度<150pixel,(50000,250000], (250000,...)范围内
ImageQuality = {65,65,65,65}
#Image压缩后是否允许信息丢失,默认关闭
#如果打开,会进一步压缩图像,但是可能做图像alpha通道去除、gif只保留第一帧等处理
AllowLookChange = true
#是否转化成灰度图像,默认关闭
ConvertToGrayscale = false
##JPEG 2000相关选项
##注意JPEG2000一般不能直接在浏览器中显示,因此必须还要转回普通JPEG才能显示
##JPEG2000的压缩比更高,因此可以用来节省传输流量
#原文件是JP2000时是否处理
ProcessJP2=false
#是否压缩成JP2
ProcessToJP2=true
#禁止JP2输出(会覆盖上一个选项)
ForceOutPutNoJP2=false
#根据客户端智能选择是否压缩成JP2
JP2OutRequiresExpCap = true
#JP2压缩的图像质量
JP2ImageQuality = {65,65,65,65}
#下面还有一些JP2的图像压缩算法的选项,这里从略
Ad-Blocker功能:通过黑名单设置,ziproxy可以作为广告过滤器
#名单,默认有个简单的过滤:不显示1×1的透明GIF对象
URLReplaceData = "/etc/ziproxy/replace.list"
#类似,但是仅屏蔽可见元素(即不会屏蔽脚本),兼容性更好
URLReplaceDataCT = "/etc/ziproxy/replace_ct.list"
#配合上个选项,屏蔽的类型
URLReplaceDataCTList = {"image/jpeg", "image/gif", "image/png", "application/x-shockwave-flash"}
#依然是一个类型自动扩展的便捷选项
URLReplaceDataCTListAlsoXST = true
TOS相关
#TOS选项开关,默认关闭
TOSMarking = false
#默认情况
TOSFlagsDefault = 0
#特殊TOS控制名单
TOSMarkAsDiffURL = "/etc/ziproxy/change_tos.list"
#特殊TOS控制类型
TOSMarkAsDiffCT = {"video/flv", "video/x-msvideo", "audio/*",
"application/x-shockwave-flash", "application/x-rpm",
"application/x-msi", "application/x-tar"}
#以上类型子类型的前缀为"x-"时,是否也使用特殊TOS控制
TOSMarkAsDiffCTAlsoXST = true
#特殊TOS流量阈值
TOSMarkAsDiffSizeBT = 4000000
#对特殊名单或特殊类型进行的TOS设置
TOSFlagsDiff = 16
DNS相关
#如果拥有DNS缓存服务器,可以考虑以下选项
#由于比较专业,请自行查看注释文件
PreemptNameRes = false
PreemptNameResMax = 50
PreemptNameResBC = true
#如果用户使用IE浏览,对于出错信息的优化
WA_MSIE_FriendlyErrMsgs = true
测试分为两个部分:页面总体测试和元素单个测试,需要测试的主要参数是压缩率和压缩所用时间。测试之前需要使用sudo service ziproxy restart
重启服务,以应用修改后的配置文件。
以上配置文件中我们使用了传统正向代理的转发方式,因此手工测试只需要把浏览器的代理设为常规选项中的Address:Port
即可。推荐使用可以随时切换代理的插件,chrome可以使用SwithySharp,Firefox可使用著名的AutoProxy,方便随时切换代理状态,插件的使用方法较为简单,请自行搜索。
测试步骤为:打开一个页面,按F12
打开开发者工具(IE9+, chrome, firefox, 以下以chrome为例),在Network
选项页查看压缩效果;关闭代理,打开同一页面,按Ctrl+F5
强制刷新,然后看看原始页面大小,进行对比;或者在开发者工具中设置关闭cache,亦可避免浏览器直接从缓存中读取内容(响应代码304)。注意Size
表示传输大小,而Content
表示实际大小,二者的区别参见这里。页面总体加载时间显示在最下方,而元素的加载时间可以通过各自的Timeline
查看。
这里通过分析ziproxy的日志文件来达到自动测试的目的,AccessLog
的格式如下:
Log format:
TIME (unix time as seconds.msecs)
PROCESS_TIME (ms)
[USER@]ADDRESS (address with daemon mode only)
FLAGS
ORIGINAL_SIZE
SIZE_AFTER_(RE)COMPRESSION
METHOD
URL
所以,根据URL(第8列)来分析PROCESS_TIME、ORIGINAL_SIZE和SIZE_AFTER_(RE)COMPRESSION这三列(2,5,6)即可得到所需数据。
如果是编译安装ziproxy,官方提供了ziproxylogtool
这个日志分析工具。当然,也可以自己写一个脚本分析。可以使用PhantomJS作为前端自动化测试工具(可配合CasperJS),将其后端配置为ziproxy,即可将整个测试工作自动化。
sudo aptitude install squid3
,目前源里面的版本是3.1.19。
从源里面直接安装的版本不能支持ssl,我们要使用https_port
,所以这里需要编译安装。
sudo apt-get build-dep openssl
sudo apt-get build-dep openssh
sudo apt-get install devscripts build-essential fakeroot
sudo apt-get build-dep squid3
sudo apt-get source squid3
cd squid-<version>
sudo vim debian/rules
在DEB_CONFIGURE_EXTRA_FLAGS
中添加--enable-ssl
(如果需要动态证书生成功能,还需要加上--enable-ssl-crtd
选项),然后使用sudo debuild -us -uc -b
进行自动编译,编译的时间可能比较长。其输出是几个deb包,使用dpkg安装即可,可能会缺少某些依赖,请根据提示安装。安装完成后可以使用sudo squid3 -v | grep ssl
看一下是不是已经激活。
如果需要squid的最新版,就只能编译安装了。从网站上下载squid的最新源码,安装依赖(可以用上面的build-dep
方法),然后configure,注意这里的选项非常多,可以参考以下:
./configure -prefix=/usr -localstatedir=/var -libexecdir=${prefix}/lib/squid3 -srcdir=. -datadir=${prefix}/share/squid3 -sysconfdir=/etc/squid3 -with-default-user=proxy -with-logdir=/var/log -with-pidfile=/var/run/squid3.pid -enable-inline -enable-async-io=8 -enable-storeio="ufs,aufs,diskd" -enable-removal-policies="lru,heap" -enable-delay-pools -enable-cache-digests -enable-underscores -enable-icap-client -enable-follow-x-forwarded-for -enable-basic-auth-helpers="LDAP,MSNT,NCSA,PAM,SASL,SMB,YP,DB,POP3,getpwnam,squid_radius_auth,multi-domain-NTLM" -enable-ntlm-auth-helpers="smb_lm," -enable-digest-auth-helpers="ldap,password" -enable-negotiate-auth-helpers="squid_kerb_auth" -enable-external-acl-helpers="ip_user,ldap_group,session,unix_group,wbinfo_group" -enable-arp-acl -enable-esi -enable-ssl -enable-ssl-crtd -enable-icmp -enable-zph-qos -enable-wccpv2 -disable-translation -with-logdir=/var/log/squid3 -with-filedescriptors=65536 -with-large-files -with-default-user=proxy
其实有些选项用默认的就可以了,这里全部列出来了…官方的安装文档是2.6的,不保证一样适用。另外需要注意,编译安装后,程序的名字是squid而不是squid3,切记切记。
squid3的配置较之ziproxy更加复杂,可以参考这本《squid 中文权威指南》进行上手。虽然该书中使用的squid版本较为陈旧,但是绝大多数参数配置还是类似的,3.1的官方文档见此,当然也可以直接看/etc/squid3/squid3.conf
文档。
由于squid3的配置参数过于繁多,这里仅列出需要注意的几个部分,其余部分请自行查看相关注释或官方文档。
#监听端口,默认是3128
#可以绑定IP或hostname,可以在此设置透明代理
http_port 8002
#监听https请求的端口,只在加速模式有用,默认没有打开
https_port 443
#外部访问地址,配合acl使用,在访问特定网址时使用特定IP
#默认为none
tcp_outgoing_address none
Access List,即ACL,是访问控制的核心部分,其格式是acl aclname acltype argument
,其中acltype
是配置文件内定的关键词,包括port, dst, src, proto, method, myip, myip, dstdomain,srcdomain, time, ident, proxy_auth, src_as, dst_as..,共计20多项,默认打开了最小配置。
一般而言,src使用ip匹配,dst使用域名匹配(dstdomain
)速度较快,否则需要进行正/反向DNS查询,增加延迟时间;src_as
和dst_as
使用了路由器的AS(自主系统)号;myport
, myip
, mydomain
指的都是对squid自身参数的配置(从哪个端口/ip/域名可以访问squid);method
, proto
分别指的是HTTP方法和访问协议;ident
指的是RFC 1413规定的ident协议;maxconn
可以限制用户的最大TCP连接数;browser
可以限制UA;以_regex
为后缀的选项,支持正则表达式;以_type
为后缀的选项,限制的是Content-Type
首部的内容。
acl的匹配使用OR逻辑,aclname
可以拆开成多行,也可以合并成一行(用空格隔开)。Squid在重新启动(或使用squid -k reconfigure
重新加载配置)后,会从上向下扫描ACL,构建数据结构,将所有分组放在内存中。squid以一种叫做splay tree的数据结构存放一般的acl,该数据结构会在search发生后,返回结果的同时,将树的root旋转到树根的位置,如果下次搜索命中同一acl,查询时间会减少到O(1);对于正则acl,则使用链表存储,以减少比较时间。
根据匹配规则速度的区别,acl type被分为fast
和slow
两类,详见官方文档,推荐尽量使用标记为fast
的类型。
#默认选项
#
# 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
其他相关的选项:
#处理XFF报文首部
follow_x_forwarded_for deny all
#与XFF报文头相关的选项
acl_uses_indirect_client
delay_pool_uses_indirect_client
log_uses_indirect_client
根据acl,我们指定相应的访问规则。后缀以_access
结尾的选项,都是访问规则,其语法是xxx_access all|deny [!]aclname
.与acl相反,访问规则的匹配使用and逻辑,这意味着我们应该把匹配最少的规则放在最前面(越通用的规则越应该靠后)。一个技巧:
无论何时,你编写了一个带两个或更多ACL元素的规则,建议你在其后紧跟一条相反的,更广泛的规则。
换句话说,要满足交集的同时,排除不相交的部分。
#http_access的默认选项
#
# Recommended minimum Access Permission configuration:
#
# Only allow cachemgr access from localhost
# 注意:第一句的意思是允许manager和localhost的交集
# 第二句的意思是拒绝manager,结合第一句就是:不允许属于manager但不属于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
#
# 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
除了最常用的http_access
外,还有一些相关选项:
adapted_http_access
#根据服务器的响应来判断
http_reply_access
#本地icp查询,用于squid集群
icp_access
#htcp相关控制
htcp_access
htcp_clr_access
#hit miss控制
miss_access
#ident查询控制
ident_lookup_access
#reply数据的最大值(防止下载big item)
reply_body_max_size
和acl类似,访问规则也被划分为slow
和fast
两类,注意:fast的访问规则只能对应fast的acl,但是slow的访问规则可以对应所有的acl,其中最重要的http_access
是slow
类型的。
主要配置cache_peer
参数,格式是cache_peer hostname type http_port icp_port [options]
,其中type
是parent
, sibling
, or multicast
.parent
标明下一跳的代理地址(在本项目中应该是ziproxy);另外两个都是用于cache集群控制的。
这一部分的配置相当复杂,请参考权威指南第10章的内容。
该部分极其影响服务器性能,请谨慎修改。可参考权威指南第7,8章内容。
#占用内存,注意这里只是附加内存的建议最大值
#squid必然会占用超过该数值的内存
cache_mem 256 MB
#缓存在内存中的元素的最大大小
maximum_object_size_in_memory 512 KB
#cache文件存放位置
#cache_dir scheme directory size L1 L2 [options]
#size的计算有一定的技巧,可参考文档
cache_dir
必要时可打开相关log进行调试。
#自定义log的格式,比较灵活,有几个预置的可选格式,默认用下面这个:
#logformat squid %ts.%03tu %6tr %>a %Ss/%03>Hs %<st %rm %ru %un %Sh/%<A %mt
logformat
access_log
icap_log
cache_store_log
referer_log
forward_log
...
log格式参数详见这里。
而返回参数的意义参见官方faq.
在启动squid之前,首先需要初始化cache_dir
(如果你在配置中修改了这一选项,也要这么做一次),使用sudo squid3 -z
;然后推荐使用sudo squid3 -k parse
分析一下配置文件,自己核对一下选项(或者使用sudo squid3 -k check
)来查询错误,最后使用sudo service squid3 start
启动服务(如果是自己编译的,请使用sudo squid -s
启动)。
每次更新squid.conf后,都需要重新加载配置,使用sudo squid3 -k reconfigure
可以达到不重启服务重新加载的目的。注意该操作会中断当前所有连接(参见这里)。如果需要7*24小时服务,可以考虑使用外部acl,参考acl_external_type
条款,这种类型的acl显然是slow
的。
修改ziproxy.conf,防止外部直连
#这里填充允许请求的地址
OnlyFrom = "127.0.0.1"
修改squid3.conf,增加转发设置:
#请求转发到本地ziproxy监听端口(默认8080)
cache_peer localhost parent 8001 0 no-query no-digest
#禁止squid直连网络
never_direct allow all
将浏览器代理改为squid3的监听端口(这里设置是8002),其余步骤类似ziproxy部分。
可以通过分析squid3的accesslog,统计TCP_MEM_HIT
等字段出现的次数来统计缓存命中率。由于
squid使用广泛,官方直接给出了大量分析日至文件的脚本,
可根据个人需要选择使用。
推荐使用squidclient分析命中率,使用sarg进行数据统计和报表生成。
sudo squidclient -p 3128 mgr:info
,即可看到squid的运行情况,其中有内存、磁盘命中率。
先配置/etc/sarg/sarg.conf
,修正access log的位置,然后运行sudo sarg
即可生成报表。其他使用帮助可以自行搜索。