一、什么是squid?
squid可以做代理也可以做缓存
squid缓存不仅可以节省宝贵的带宽资源,也可以大大降低服务器的I/O.
squid不仅可以做正向代理,又可以做反向代理。
正向代理,squid后面是客户端,客户端上网要通过Squid去上;反向代理,squid后面是服务器,服务器返回给用户数据需要走squid.
正向代理用在企业的办公环境中,员工上网需要通过squid代理来上网,这样可以节省网络带宽资源。而反向代理用来搭建网站静态项(图片、html、流媒体、js、css等)的缓存服务器,它用于网站架构中。
二、安装squid
直接 yum 安装 squid
yum -y install squid
Version 3.1.23
常用命令:
service squid start // 启动 squid –z // 初始化缓存 squid –k parse // 检查语法 squidclient -h 127.0.0.1 -p 3128 mgr:info // 查看命中率 squid -krec // 重新加载配置文件
默认的主配置文件是 /etc/squid/squid.conf
内容如下:
# # Recommended minimum configuration: ## squid权限控制 acl和http_access 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 # 局域网内的IP,看情况是否考虑需要 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 # 定义ssl端口、一些安全端口和http访问的connect方法 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 # 拒绝connect到非ssl 443端口(上面定义了) 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 # 强烈建议去除注释。防止通过代理来访问本代理服务器上的web程序 # 以免认为是localhost用户访问web服务。 #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 # 允许localhost和局域网内用户的请求,根据需要调整 http_access allow localnet http_access allow localhost # And finally deny all other access to this proxy # 最后,拒绝其他的对代理的访问(不符合上面规则的统统拒绝,有先后顺序,如果这一句放在最上面,那就谁也不能用了) http_access deny all # Squid normally listens to port 3128 # 默认监听3128端口 http_port 3128 # 设置对外显示的主机名,(老版本的不加会报错) visible_hostname hostname # Uncomment and adjust the following to add a disk cache directory. # 存放缓存的目录,3个数字分别是:缓存目录占用磁盘100M大小,16个一级目录,256个二级目录 #cache_dir ufs /var/spool/squid 100 16 256 # Leave coredumps in the first cache dir # 将核心输出保存在第一个缓存目录 coredump_dir /var/spool/squid # 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
三、其它参数:(不在默认配置文件中,但是也只是介绍常用的)
cache_mem 64 MB //额外提供给squid使用的内存,squid的内存总占用为 X * 10+15+“cache_mem”,其中X为squid的cache占用的容量(以GB为单位), //比如下面的cache大小是100M,即0.1GB,则内存总占用为0.1*10+15+64=80M,推荐大小为物理内存的1/3-1/2或更多。 maximum_object_size 4 MB //设置squid磁盘缓存最大文件,超过4M的文件不保存到硬盘 minimum_object_size 0 KB //设置squid磁盘缓存最小文件 maximum_object_size_in_memory 4096 KB //设置squid内存缓存最大文件,超过4M的文件不保存到内存 logformat combined %>a %ui %un [%tl] "%rm %ru HTTP/%rv" %Hs %<st "%{Referer}>h" "%{User-Agent}>h" %Ss:%Sh //log文件日志格式 access_log /var/log/squid/access.log combined //log文件存放路径和日志格式 cache_log /var/log/squid/cache.log //设置缓存日志 logfile_rotate 60 //log轮循 60天 cache_swap_high 95 //cache目录使用量大于95%时,开始清理旧的cache cache_swap_low 90 //cache目录清理到90%时停止。 visible_hostname squid.david.dev //主机名 cache_mgr [email protected] //管理员邮箱 cache_effective_user squid //指定运行的用户 cache_effective_group squid //指定运行的组
四、访问控制ACL元素
该元素定义的语法如下:
acl aclname acltype string1 acl aclname acltype "file"
当使用文件时,该文件的格式为每行包含一个条目。
其中,acltype可以是src、dst、srcdomain、dstdomain、url_regex、urlpath_regex、time、port、proto、method中的一任意一种。
src:指明源地址。可以用以下的方法指定:
acl aclname src ip-address/netmask // 客户ip地址 acl aclname src addr1-addr2/netmask // 地址范围
dst:指明目标地址,即客户请求的服务器的IP地址,语法为:
acl aclname dst ip-address/netmask
srcdomain:指明客户所属的域,Squid将根据客户IP反向查询DNS,语法为:
acl aclname srcdomain foo.com
dstdomain:指明请求服务器所属的域,由客户请求的URL决定,语法为:
acl aclname dstdomain foo.com
// 此处需要注意的是:如果用户使用服务器IP而非完整的域名时,Squid将进行反向的DNS解析来确定其完整域名,如果失败,就记录为“none”。
time:指明访问时间,语法如下:
acl aclname time [day-abbrevs] [h1:m1-h2:m2][hh:mm-hh:mm]
日期的缩写指代关系如下:
S:指代Sunday M:指代Monday T:指代Tuesday W:指代Wednesday H:指代Thursday F:指代Friday A:指代Saturday
另外,h1:m1必须小于h2:m2,表达式为[hh:mm-hh:mm]。
port:指定访问端口。可以指定多个端口,比如:
acl aclname port 80 70 21 acl aclname port 0-1024 // 指定一个端口范围
proto:指定使用协议,可以指定多个协议:
acl aclname proto HTTP FTP
method:指定请求方法,比如:
acl aclname method GET POST
url_regex:URL 规则表达式匹配,语法为:
acl aclname url_regex[-i] pattern
urlpath_regex:URL-path规则表达式匹配,略去协议和主机名,其语法为:
acl aclname urlpath_regex[-i] pattern
在使用上述ACL元素的过程中,要注意如下几点:
acltype可以是任一个在ACL中定义的名称。
任何两个ACL元素不能用相同的名字。
每个ACL由列表值组成。当进行匹配检测的时候,多个值由逻辑或运算连接;换句话说,任一ACL元素的值被匹配,则这个ACL元素即被匹配。
并不是所有的ACL元素都能使用访问列表中的全部类型。
不同的ACL元素写在不同行中,Squid将这些元素组合在一个列表中。
proxy_auth : 通过外部程序进行用户验证
maxconn : 单一 IP 的最大连接数
arp : mac地址
五、http_access访问控制列表
根据访问控制列表允许或禁止某一类用户访问。如果某个访问没有相符合的项目,则默认为应用最后一条项目的“非”。比如最后一条为允许,则默认就是禁止。通常应该把最后的条目设为“deny all”或“allow all”来避免安全性隐患。
使用该访问控制列表要注意如下问题:
1.这些规则按照它们的排列顺序进行匹配检测,一旦检测到匹配的规则,匹配检测就立即结束。
2.访问列表可以由多条规则组成。
3.如果没有任何规则与访问请求匹配,默认动作将与列表中最后一条规则对应。
4.一个访问条目中的所有元素将用逻辑与运算连接(如下所示):http_access Action声明1 AND 声明2 AND
5.多个http_access声明间用或运算连接,但每个访问条目的元素间用与运算连接。
6.列表中的规则总是遵循由上而下的顺序。
实例:
1.禁止IP地址为192.168.1.102的客户机上网
acl badclientip src 192.168.1.102 http_access deny badclientip
2.禁止IP地址属于192.168.1.0这个子网的所有客户机上网
acl badclientsubnet src 192.168.1.0/24 http_access deny badclientsubnet
3.禁止所有终端用户访问IP地址为64.233.189.99(www.google.com)的网站
acl badserverip dst 64.233.189.99 http_access deny badserverip
4.禁止所有终端用户访问域名为www.google.com的网站
acl baddomain dstdomain -i www.google.com http_access deny dstdomain
需要注意的是,这个限制规则仅对google.com域的WWW服务进行了限制,而对于Mail服务等并未限制。
5.禁止所有终端用户访问域名包含为google.com的网站
acl badurl url_regex -i google.com http_access deny badurl
6.限制IP地址为192.168.1.102的客户机并发连接的最大连接数为5
acl clientip src 192.168.1.102 acl clientmaxconn maxconn 5 http_access deny clientip clientmaxconn
7.禁止客户机IP地址在192.168.2.0子网的所有终端客户在星期一到星期五的9:00到18:00访问Internet资源
acl clientnet src 192.168.2.0/24 acl worktime time MTWHF 9:00-18:00 http_access deny clientnet worktime
8.禁止终端用户在任何客户机上下载文件扩展名为mp3、exe、zip和rar类型的文件
acl badfile urlpath_regex -i \.mp3$ \.exe$ \.zip$ \.rar$ http_access deny badfile
六、正向代理
最简单的一种,用默认的配置文件启动squid服务即可,然后在客户端的浏览器,比如IE浏览器吧,菜单栏 -> 工具 -> Internet 选项 -> 连接 -> 局域网设置 -> 代理服务器
填写服务器IP地址和3128就可以了,如果不是在拒绝列表中,应该就可以上网了,服务器在国外,那就更好了,可以翻墙了。
但是,这种方式很不安全,因为是个人就可以用,不需要验证,所以适合在企业内部使用,而且吧,还不能访问强制使用https的网站,所以还得介绍一种带用户验证,且支持访问强制使用https方式网站的办法。
配置http验证:
安装 stunnel和httpd
stunnel 用来加密代理通道,httpd主要是用htpasswd生成基于 CRYPT 加密方式加密的密码(其它的不行,比如md5和sha1,是验证了IE8)
yum -y install stunnel httpd
1.配置squid
生成HTTP认证文件,输入对应的密码。这个认证文件用于之后HTTP代理的认证登录,如果不需要登录认证,可以略过。
htpasswd -c /etc/squid/passwd <登录用户名>
vim /etc/squid/squid.conf
auth_param basic program /usr/lib64/squid/ncsa_auth /etc/squid/passwd auth_param basic children 5 auth_param basic realm Squid proxy-caching web server auth_param basic credentialsttl 2 hours auth_param basic casesensitive off
// 上面这几句要放在配置文件最上面,路径要填写正确,32位系统应该是lib。
acl ncsa_users proxy_auth REQUIRED
// 放所有acl规则后面
http_access deny !ncsa_users http_access allow ncsa_users
// 放在所有http_access规则前面
2.配置stunnel
接下来,我们需要在Squid上添加一层加密。
生成公钥和私钥
生成私钥(privatekey.pem):
openssl genrsa -out privatekey.pem 2048
生成公钥(publickey.pem):
openssl req -new -x509 -key privatekey.pem -out publickey.pem -days 1095
(需要注意的是,Common Name需要与服务器的IP或者主机名一致)
合并:
cat privatekey.pem publickey.pem >> /etc/stunnel/stunnel.pem
修改stunnel配置
新建一个配置文件/etc/stunnel/stunnel.conf,输入如下内容
client = no [squid] accept = 4128 connect = 127.0.0.1:3128 cert = /etc/stunnel/stunnel.pem
启动stunnelh很简单直接输入 stunnel 就行
netstat -lnp|grep 4128 查看监听端口可以看出是否启动成功
本地浏览器配置
添加证书到受信任的根证书颁发机构列表中
以Windows下Chrome浏览器为例,将服务器上的公钥publickey.pem下载至本地,重命名至publickey.crt,在Chrome中依次点击 “设置” - “显示高级设置” - “HTTP/SSL” - “管理证书”,在“受信任的根证书颁发机构”选项卡中“导入”这个crt证书就完成了。
七、透明代理:
透明代理不需要在浏览器中设置IP和端口,可以让用户不知不觉中使用代理,但是需要设置网关,客户端的网关指向squid服务器就可以了,透明代理不能和http验证一起使用。
需要两个网卡,一个内网,一个外网
外网:10.0.3.15 内网:192.168.0.6
配置和普通代理差不多,只需要在监听端口后加上
http_port 3128 intercept // 新版本一般用这个(3以后的版本吧) http_port 3128 transparent
保存重启,还需要打开路由功能设置iptables 规则
iptables -t nat -A PREROUTING -i eth0 -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 3128 // 开启端口转发功能,把内网eth0的80端口转发到外网eth1的3128端口 iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE // 开启外网eth1的NAT网络地址转换功能 service iptables save // 保存规则 iptables restart // 重启防火墙
客户端设置,以windows7 为例
ip地址: 192.168.0.104 // 不冲突就行 子网掩码: 255.255.255.0 网关: 192.168.0.6 // squid服务器地址 dns 192.168.0.1
dns一定要设置一个,不然还是上不了网,这里被坑了好久,如果想使用squid服务器的地址,可以再安装个Bind DNS服务
打开浏览器应该可以了
八、反向代理:
普通代理和透明代理普遍使用在局域网,是为局域网用户访问Internet中的web站点提供缓存加速,而反向代理相反,主要为internet中的用户访问企业局域网内的web站点提供缓存加速,是一个反向的代理过程,因此称为反向代理。
使用squid反向代理,后台真正提供web服务的站点可以位于internet,也可以位于企业局域网内,提供web服务的主机可以有一个到多个。
在squid.conf文件中,实现反向代理服务最基本的选项有两处,在http_port后加“vhost”,accel是加速模式(注意:vhost与 transparent不能同时使用)使用cache_peer配置项指定后台真正提供web服务的主机(有时称为上游服务器)的ip地址、端口等。
格式:
添加对反向代理的支持,并在公网ip地址的80端口监听服务
vi /etc/squid/squid.conf
http_port 111.111.111.111:80 vhost
在DNS服务器上为域名添加A记录,值是squid服务器地址:111.111.111.111
指定web服务器主机位置
cache_peer web服务器地址 服务器类型 http端口 icp端口 [可选项]
web服务器地址:不解释
服务器的类型:对应到目标主机的缓存级别,上游web主机一般使用“parent”
http端口:web服务器web服务的端口如80、8080等icp端口:用于连接相邻的ICP(internet cache protocol)缓存服务器(通常为另外一台squid主机),如果没有,则使用0;可选项:是提供缓存时的一些附加插参数, 如:“originserver”表示该服务器作为提供web服务的原始主机,“weight=n”指定服务器的优先权重,n为整数,数字越大优先级越高 (默认为1);“max-conn=n”指定方向代理主机到web服务器的最大连接数。
环境描述:
公司使用4台web服务器实现负载均衡,并在前端使用squid做方向代理加速,internet用户直接服务的是squid反向代理服务器(公网ip并做好dns(cdn)解析),通过squid代理服务器间接访问时间的网站服务器。
实现步骤:
修改squid.conf配置文件
http_port 80 vhost acl allowuser 192.168.1.1/32 cache_peer 192.168.1.50 parent 81 0 no-query originserver weight=1 name=a cache_peer 192.168.1.50 parent 82 0 no-query originserver weight=1 name=b cache_peer 192.168.1.50 parent 80 0 no-query originserver weight=1 name=c cache_peer_domain a www.serverA.com cache_peer_domain b www.serverB.com cache_peer_domain c www.serverC.com
#以上六行配置表示:
#从客户端过来的请求,如果是 www.serverA.com,则Squid向 Server 192.168.1.50的端口81发送请求;
#从客户端过来的请求,如果是 www.serverB.com,则Squid向 Server 192.168.1.50的端口82发送请求;
#从客户端过来的请求,如果是 www.serverC.com,则Squid向 Server 192.168.1.50的端口80发送请求;
#换句话说:设定不同域名转发到不同的cache_peer上,如果没有这项.不同的域名可能被分发到同一台服务
器(或同一台服务器的端口)上.
#name=a表示给cache_peer一个别名
cache_peer_access a allow all cache_peer_access b allow all cache_peer_access c allow all
#设置访问权限,允许所有外部客户端访问 a b c
#如果是cache_peer_access a allow allowuser
#表示只允许allowuser访问 www.serverA.com
另一个例子:
acl user1 src 192.168.2.68/32 acl user2 src 192.168.2.94/32
#定义两个user IP
cache_peer 192.168.2.172 parent 80 0 no-query no-digest originserver name=www1 sourcehash cache_peer 192.168.2.173 parent 81 0 no-query no-digest originserver name=www2 sourcehash cache_peer_domain www1 www.domain.com cache_peer_domain www2 www.domian.com
#表明对www.domian.com的请求,squid向192.168.2.172的80端口和192.168.2.173的81端口发出请求
cache_peer_access www1 allow user1 cache_peer_access www2 allow user2
#允许user1访问192.168.2.172的80端口
#允许user2访问192.168.2.173的81端口
设置子父代理的cache_peer:
如果要设置父级的代理服务器,例如proxy.test.edu.cn那么可以这样配置
在#cache_peer hostname type 3128 3130 之下加入
cache_peer proxy.test.edu.cn parent 3128 3130 no-query no-netdb-exchange
如果要设置同级的代理服务器,如:192.168.1.41 192.168.1.42则可以这样来配置
cache_peer 192.168.1.41 sibling 3128 3130 proxy-only
....
注意目前各单位施行代理服务器分级管理,设置父级代理服务器,还必须取得上层单位的同意
说明:
(1)命令cache_peer的定义格式是:
cache_peer hostname type 3128 3130
hostname 是用来指定获取缓冲的PROXY主机的名字
type 是PROXY主机的类型,有以上PARENT SIBLING两种
3128:HTTP_PORT
3130:ICP_PORT
(2)附加配置选项(注意应为小写,配置时)
NO-QUERY:不做查询操作,直接获取数据
NO-NETDB-EXCHANGE:代理服务器之间不交互信息
NO-DIGEST:代理服务器之间不做摘要表查询,直接用ICP协议沟通(同级代理)
PROXY-ONLY:直接获取对方缓冲,转交给代理服务器的客户端,而不存入本地
ROUND-ROBIN:如果设置数部上层服务器,那么轮流查询父级服务器
LOGIN=USER:PASSWD:要求对方做帐号及密码验证,例如
cache_peer 192.168.1.41 sibling 3128 3130 login=kao:123456
举例:
以下为squid1机器上的配置
icp_port 3130 acl domian dst www.domian.com acl squid2 src xx.xx.xx.xx acl squid3 src xx.xx.xx.xx http_access allow squid2 http_access allow squid3
1.配置 squid2、squid3 为其邻居,当 squid1 在其缓存中没有找到请求的资源时,通过 ICP 查询去其邻居中取得缓存
cache_peer squid2 sibling 80 3130 cache_peer squid3 sibling 80 3130
2.squid1的三个父节点,originserver 参数指明是源服务器,round-robin 参数指明 squid 通过轮询方式将请求分发到其中一台父节点;squid 同时会对这些父节点的健康状态进行检查,如果父节点down了,那么 squid 会从剩余的 origin 服务器中抓取数据。
cache_peer 192.168.1.1 parent 8080 0 no-query originserver round-robin name=www1 cache_peer 192.168.1.2 parent 8080 0 no-query originserver round-robin name=www2 cache_peer 192.168.1.3 parent 8080 0 no-query originserver round-robin name=www3
3.将 www.domian.com 域的请求通过 RR 轮询方式转发到三个父节点中的一个
cache_peer_domain www1 domian cache_peer_domain www2 domian cache_peer_domain www3 domian
4.always_direct会导致所有请求都直接发送到原始服务器。而不会去查询sibling,对于www.domian.com这个域名不需要直接出去,而是要询问sibling。其余的域名,squid依然通过hosts去进行转发
always_direct allow !domain
如果是squid要代理一台web上的所有域名,那么就写成这样:
cache_peer 192.168.10.111 80 0 originserver
后面连cache_peer_domain 也省了。
参考:
1、http://www.chenyudong.com/archives/squid-forward-proxy.html
2、http://os.51cto.com/art/201009/225813.htm
3、http://www.predatorray.me/%E5%9C%A8VPS%E4%B8%8A%E6%90%AD%E5%BB%BASquid%E4%BB%A3%E7%90%86%E6%9C%8D%E5%8A%A1%E5%99%A8/
4、http://www.ahlinux.com/server/proxy/8771.html
5、http://blog.sina.com.cn/s/blog_5dc960cd0100d5hg.html
6、Google