Total Pageviews

Saturday 4 June 2016

ziproxy和squid3搭建过程及配置步骤

环境:Ubuntu 12.04 LTS x64

ziproxy部分

1. 安装

ziproxy(以及其他)的安装,可以从source里面直接安装二进制版,也可以自行编译安装。一般而言,source里面的版本不会是软件的最新版本,而是经过测试的较为稳定的版本,但是最新版会修正一些bug,因此可根据情况妥善考虑。这里(以及下面)都是使用命令直接从source里面安装的。
输入sudo aptitude install ziproxy,目前源里面的版本是3.2.0(使用aptitude show ziproxy可以查看源里面的版本)。安装后服务(守护进程)会自动启动,并自动加入开机启动项。

2. 配置

输入sudo vim /etc/ziproxy/ziproxy.conf,编辑配置文件。默认配置需要修改的部分并不多,,以下是对配置文件的详细分析,如果要做快速测试,那么仅需要修改常规选项部分。

常规选项

  1. #监听端口,默认8080
  2. Port=8001
  3. #本地网卡绑定,默认绑定所有
  4. #如果有多网卡,可以考虑绑定特定的IP
  5. Address="127.0.0.1"
  6. #Debug Log,默认关闭
  7. DebugLog = "/var/log/ziproxy/debug.log"
  8. #Error Log,默认关闭
  9. ErrorLog = "/var/log/ziproxy/error.log"
  10. #Access Log,默认关闭
  11. AccessLog = "/var/log/ziproxy/access.log"
  12. #指定dump服务pid号的文件,默认打印到标准输出
  13. PIDFile = "/var/run/ziproxy.pid"
  14. #下一跳代理地址,默认关闭
  15. NextProxy = "127.0.0.1"
  16. NextPort=3128

控制选项

  1. #禁止外部连接,仅接受来自该IP的请求
  2. OnlyFrom="127.0.0.1" (注意:一定要去掉本行的注释。 我在自己的vps上,忘了注释掉本行,竟然导致网上有25000多个connections连接到这个ziproxy,最终导致我的vps不堪重负而down机)
  3. #最大同时访问数,默认无限制
  4. MaxActiveUserConnections = 20
  5. #以另外的身份运行,权限控制,默认关闭(以当前用户运行)
  6. RunAsUser = "ziproxy"
  7. RunAsGroup = "ziproxy"
  8. #信号拦截/屏蔽,默认关闭
  9. InterceptCrashes = false
  10. #加密认证,默认关闭,枚举选项
  11. AuthMode = 0
  12. #认证文件(纯文本),当AutoMode=1时使用
  13. AuthPasswdFile = "/etc/ziproxy/http.passwd"
  14. #认证文件(SSAL),当AutoMode=2时使用
  15. AuthSASLConfPath = "/etc/ziproxy/sasl/"
  16. #对外部服务器的绑定地址,默认使用OS的默认IP
  17. #可以用来做负载均衡,有些网站会拒绝一个IP的频繁请求
  18. #所有绑定IP的使用几率是均等的
  19. BindOutGoing={}
  20. #与上述选项对应,在请求时不转换ip的白名单
  21. BindOutgoingExList="/etc/ziproxy/bo_exception.list"
  22. #上述白名单中应该绑定的特定IP
  23. BindOutgoingExAddr="98.7.65.43"
  24. #是否将ziproxy作为透明代理,默认关闭
  25. #如果需要打开,必须对本地用户做相应的转发处理
  26. #与传统代理功能可以并存
  27. TransparentProxy = false
  28. #传统代理
  29. ConventionalProxy = true
  30. #是否允许CONNECT请求,默认打开
  31. #一般用来过滤https请求
  32. AllowMethodCONNECT = true
  33. #本地请求限制(HTTP),配合透明代理使用,默认关闭
  34. RestrictOutPortHTTP = {80, 8080}
  35. #本地请求限制(HTTPS)
  36. RestrictOutPortCONNECT = {443}
  37. #更改UA,默认不更改,以下示例表示如何伪装Firefox
  38. RedefineUserAgent = "Mozilla/5.0 (compatible; UltraBrowser/8.1; CP/M; console40x24; z80)"

数据处理

总体相关
  1. #黑名单,不使用ziproxy的列表;可以作为bug的临时解决方案
  2. URLNoProcessing = "/etc/ziproxy/noprocess.list"
  3. #禁止访问的名单,会返回一个403错误
  4. URLDeny = "/etc/ziproxy/deny.list"
  5. #Check header的选项,默认关闭
  6. ViaServer = ...
  7. #超时设置,默认90s
  8. ConnTimeout = 90
Gzip相关
  1. #是否在Accept-Encoding中覆盖客户端设置,加入gzip选项,默认true
  2. #ziproxy会根据客户端原始的Http首部决定是否需要解压gzip流
  3. OverrideAcceptEncoding = true
  4. #如果远程服务器已经启用gzip压缩,是否解压
  5. #ziproxy的某些操作(html优化、DNS相关的选项)必须解压后才能操作
  6. #一般与下面的Gzip选项同值
  7. DecompressIncomingGzipData = true
  8. #最大解压缩比例(如果超出,则放弃解压),默认是20倍
  9. MaxUncompressedGzipRatio = 2000
  10. #最大压缩文件(默认1M),超出此数值不再(重新)压缩
  11. MaxSize=1048576
  12. #是否使用gzip无损压缩
  13. Gzip=true
  14. #使用gzip压缩的文件类型,默认一大堆,基本包含了所有text like选项
  15. LosslessCompressCT={...}
  16. LosslessCompressCTAlsoXST = true
  17. #优化html/css/js的选项,默认关闭
  18. #在当前版本,该功能还不稳定
  19. ProcessHTML = false
  20. ProcessCSS = false
  21. ProcessJS = false
  22. #HTML优化的细节,仅当ProcessHTML=true时生效
  23. ProcessHTML_CSS = true
  24. ProcessHTML_JS = true
  25. ProcessHTML_tags = true
  26. ProcessHTML_text = true
  27. ProcessHTML_PRE = true
  28. ProcessHTML_NoComments = true
  29. ProcessHTML_TEXTAREA = true
Image相关
  1. #原图像最大压缩率,超过该数值不再重新压缩图像
  2. MaxUncompressedImageRatio = 500
  3. #压缩的图像格式
  4. ProcessPNG=true
  5. ProcessGIF=true
  6. ProcessJPG=true
  7. #压缩的图像质量,四个参数指的都是压缩率的百分比(压缩后的体积:压缩前)
  8. #分别应用于图像像素在(0,5000],(5000,50000]或某个尺度<150pixel,(50000,250000], (250000,...)范围内
  9. ImageQuality = {65,65,65,65}
  10. #Image压缩后是否允许信息丢失,默认关闭
  11. #如果打开,会进一步压缩图像,但是可能做图像alpha通道去除、gif只保留第一帧等处理
  12. AllowLookChange = true
  13. #是否转化成灰度图像,默认关闭
  14. ConvertToGrayscale = false
  15. ##JPEG 2000相关选项
  16. ##注意JPEG2000一般不能直接在浏览器中显示,因此必须还要转回普通JPEG才能显示
  17. ##JPEG2000的压缩比更高,因此可以用来节省传输流量
  18. #原文件是JP2000时是否处理
  19. ProcessJP2=false
  20. #是否压缩成JP2
  21. ProcessToJP2=true
  22. #禁止JP2输出(会覆盖上一个选项)
  23. ForceOutPutNoJP2=false
  24. #根据客户端智能选择是否压缩成JP2
  25. JP2OutRequiresExpCap = true
  26. #JP2压缩的图像质量
  27. JP2ImageQuality = {65,65,65,65}
  28. #下面还有一些JP2的图像压缩算法的选项,这里从略
Ad-Blocker功能:通过黑名单设置,ziproxy可以作为广告过滤器
  1. #名单,默认有个简单的过滤:不显示1×1的透明GIF对象
  2. URLReplaceData = "/etc/ziproxy/replace.list"
  3. #类似,但是仅屏蔽可见元素(即不会屏蔽脚本),兼容性更好
  4. URLReplaceDataCT = "/etc/ziproxy/replace_ct.list"
  5. #配合上个选项,屏蔽的类型
  6. URLReplaceDataCTList = {"image/jpeg", "image/gif", "image/png", "application/x-shockwave-flash"}
  7. #依然是一个类型自动扩展的便捷选项
  8. URLReplaceDataCTListAlsoXST = true

优化选项

TOS相关
  1. #TOS选项开关,默认关闭
  2. TOSMarking = false
  3. #默认情况
  4. TOSFlagsDefault = 0
  5. #特殊TOS控制名单
  6. TOSMarkAsDiffURL = "/etc/ziproxy/change_tos.list"
  7. #特殊TOS控制类型
  8. TOSMarkAsDiffCT = {"video/flv", "video/x-msvideo", "audio/*",
  9. "application/x-shockwave-flash", "application/x-rpm",
  10. "application/x-msi", "application/x-tar"}
  11. #以上类型子类型的前缀为"x-"时,是否也使用特殊TOS控制
  12. TOSMarkAsDiffCTAlsoXST = true
  13. #特殊TOS流量阈值
  14. TOSMarkAsDiffSizeBT = 4000000
  15. #对特殊名单或特殊类型进行的TOS设置
  16. TOSFlagsDiff = 16
DNS相关
  1. #如果拥有DNS缓存服务器,可以考虑以下选项
  2. #由于比较专业,请自行查看注释文件
  3. PreemptNameRes = false
  4. PreemptNameResMax = 50
  5. PreemptNameResBC = true

特殊选项

  1. #如果用户使用IE浏览,对于出错信息的优化
  2. WA_MSIE_FriendlyErrMsgs = true

3. 测试

测试分为两个部分:页面总体测试和元素单个测试,需要测试的主要参数是压缩率和压缩所用时间。测试之前需要使用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,即可将整个测试工作自动化。

Squid3部分

1. 安装

sudo aptitude install squid3,目前源里面的版本是3.1.19。
从源里面直接安装的版本不能支持ssl,我们要使用https_port,所以这里需要编译安装。
  1. sudo apt-get build-dep openssl
  2. sudo apt-get build-dep openssh
  3. sudo apt-get install devscripts build-essential fakeroot
  4. sudo apt-get build-dep squid3
  5. sudo apt-get source squid3
  6. cd squid-<version>
  7. 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,注意这里的选项非常多,可以参考以下:
  1. ./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,切记切记。

2. 配置

squid3的配置较之ziproxy更加复杂,可以参考这本《squid 中文权威指南》进行上手。虽然该书中使用的squid版本较为陈旧,但是绝大多数参数配置还是类似的,3.1的官方文档见此,当然也可以直接看/etc/squid3/squid3.conf文档。
由于squid3的配置参数过于繁多,这里仅列出需要注意的几个部分,其余部分请自行查看相关注释或官方文档。

网络参数

  1. #监听端口,默认是3128
  2. #可以绑定IP或hostname,可以在此设置透明代理
  3. http_port 8002
  4. #监听https请求的端口,只在加速模式有用,默认没有打开
  5. https_port 443
  6. #外部访问地址,配合acl使用,在访问特定网址时使用特定IP
  7. #默认为none
  8. 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_asdst_as使用了路由器的AS(自主系统)号;myportmyipmydomain指的都是对squid自身参数的配置(从哪个端口/ip/域名可以访问squid);methodproto分别指的是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被分为fastslow两类,详见官方文档,推荐尽量使用标记为fast的类型。
  1. #默认选项
  2. #
  3. # Recommended minimum configuration:
  4. #
  5. acl manager proto cache_object
  6. acl localhost src 127.0.0.1/32 ::1
  7. acl to_localhost dst 127.0.0.0/8 0.0.0.0/32 ::1
  8. # Example rule allowing access from your local networks.
  9. # Adapt to list your (internal) IP networks from where browsing
  10. # should be allowed
  11. acl localnet src 10.0.0.0/8 # RFC1918 possible internal network
  12. acl localnet src 172.16.0.0/12 # RFC1918 possible internal network
  13. acl localnet src 192.168.0.0/16 # RFC1918 possible internal network
  14. acl localnet src fc00::/7 # RFC 4193 local private network range
  15. acl localnet src fe80::/10 # RFC 4291 link-local (directly plugged) machines
  16. acl SSL_ports port 443
  17. acl Safe_ports port 80 # http
  18. acl Safe_ports port 21 # ftp
  19. acl Safe_ports port 443 # https
  20. acl Safe_ports port 70 # gopher
  21. acl Safe_ports port 210 # wais
  22. acl Safe_ports port 1025-65535 # unregistered ports
  23. acl Safe_ports port 280 # http-mgmt
  24. acl Safe_ports port 488 # gss-http
  25. acl Safe_ports port 591 # filemaker
  26. acl Safe_ports port 777 # multiling http
  27. acl CONNECT method CONNECT
其他相关的选项:
  1. #处理XFF报文首部
  2. follow_x_forwarded_for deny all
  3. #与XFF报文头相关的选项
  4. acl_uses_indirect_client
  5. delay_pool_uses_indirect_client
  6. log_uses_indirect_client
根据acl,我们指定相应的访问规则。后缀以_access结尾的选项,都是访问规则,其语法是xxx_access all|deny [!]aclname.与acl相反,访问规则的匹配使用and逻辑,这意味着我们应该把匹配最少的规则放在最前面(越通用的规则越应该靠后)。一个技巧:
无论何时,你编写了一个带两个或更多ACL元素的规则,建议你在其后紧跟一条相反的,更广泛的规则。
换句话说,要满足交集的同时,排除不相交的部分。
  1. #http_access的默认选项
  2. #
  3. # Recommended minimum Access Permission configuration:
  4. #
  5. # Only allow cachemgr access from localhost
  6. # 注意:第一句的意思是允许manager和localhost的交集
  7. # 第二句的意思是拒绝manager,结合第一句就是:不允许属于manager但不属于localhost的集合
  8. http_access allow manager localhost
  9. http_access deny manager
  10. # Deny requests to certain unsafe ports
  11. http_access deny !Safe_ports
  12. # Deny CONNECT to other than secure SSL ports
  13. http_access deny CONNECT !SSL_ports
  14. # We strongly recommend the following be uncommented to protect innocent
  15. # web applications running on the proxy server who think the only
  16. # one who can access services on "localhost" is a local user
  17. #http_access deny to_localhost
  18. #
  19. # INSERT YOUR OWN RULE(S) HERE TO ALLOW ACCESS FROM YOUR CLIENTS
  20. #
  21. # Example rule allowing access from your local networks.
  22. # Adapt localnet in the ACL section to list your (internal) IP networks
  23. # from where browsing should be allowed
  24. http_access allow localnet
  25. http_access allow localhost
  26. # And finally deny all other access to this proxy
  27. http_access deny all
除了最常用的http_access外,还有一些相关选项:
  1. adapted_http_access
  2. #根据服务器的响应来判断
  3. http_reply_access
  4. #本地icp查询,用于squid集群
  5. icp_access
  6. #htcp相关控制
  7. htcp_access
  8. htcp_clr_access
  9. #hit miss控制
  10. miss_access
  11. #ident查询控制
  12. ident_lookup_access
  13. #reply数据的最大值(防止下载big item)
  14. reply_body_max_size
和acl类似,访问规则也被划分为slowfast两类,注意:fast的访问规则只能对应fast的acl,但是slow的访问规则可以对应所有的acl,其中最重要的http_accessslow类型的。

ssl相关参数(见ssl特性研究文档)

多服务器查询/转发策略

主要配置cache_peer参数,格式是cache_peer hostname type http_port icp_port [options],其中typeparentsibling, or multicast.parent标明下一跳的代理地址(在本项目中应该是ziproxy);另外两个都是用于cache集群控制的。
这一部分的配置相当复杂,请参考权威指南第10章的内容。

cache设置

该部分极其影响服务器性能,请谨慎修改。可参考权威指南第7,8章内容。
  1. #占用内存,注意这里只是附加内存的建议最大值
  2. #squid必然会占用超过该数值的内存
  3. cache_mem 256 MB
  4. #缓存在内存中的元素的最大大小
  5. maximum_object_size_in_memory 512 KB
  6. #cache文件存放位置
  7. #cache_dir scheme directory size L1 L2 [options]
  8. #size的计算有一定的技巧,可参考文档
  9. cache_dir

log相关

必要时可打开相关log进行调试。
  1. #自定义log的格式,比较灵活,有几个预置的可选格式,默认用下面这个:
  2. #logformat squid %ts.%03tu %6tr %>a %Ss/%03>Hs %<st %rm %ru %un %Sh/%<A %mt
  3. logformat
  4. access_log
  5. icap_log
  6. cache_store_log
  7. referer_log
  8. forward_log
  9. ...
log格式参数详见这里
而返回参数的意义参见官方faq.

其他部分(暂略)

3. 加载配置

在启动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的。

4. 联合ziproxy

修改ziproxy.conf,防止外部直连
  1. #这里填充允许请求的地址
  2. OnlyFrom = "127.0.0.1"
修改squid3.conf,增加转发设置:
  1. #请求转发到本地ziproxy监听端口(默认8080)
  2. cache_peer localhost parent 8001 0 no-query no-digest
  3. #禁止squid直连网络
  4. never_direct allow all

5. 测试

将浏览器代理改为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即可生成报表。其他使用帮助可以自行搜索.
from https://www.zybuluo.com/delight/note/2285

http://ziproxy.sourceforge.net/