在 pfSense/FreeBSD 上安装 Squid

今年我们扯了一根自己的 4096 kbps ADSL 线路以便我们小组内部使用,不屏蔽端口,想访问什么就访问什么。为了同时访问工作网络和小组的网络,我们需要在不改变自己工作网络的网线和 IP 地址的情况下就能访问这根新的 ADSL 网络,所以需要在现有的工作网络上加一个 firwall/gateway 把 ADSL 和工作网络连接起来。简单的说我们现在有两套完全独立上网的网络,这样用户拿着笔记本进来插入工作网络网线就可以用工作网络上网,也可以改变代理服务器设置后用刚建的 ADSL 网络上网,或者不用网线,打开 WiFi 后直接进入 ADSL 所在的无线网络上网。下图中,如果 172.16.20.12 这台机器想上网,它可以使用 172.16.20.1 代理服务器通过工作网络上网,也可以通过使用代理服务器 172.16.20.10 通过 小组网络和 ADSL 上网。

小组:电话线 -- ADSL 路由器(10.0.0.1/8)
                 |
                 |
                 --------------  Firewall(10.0.0.2/172.16.20.10)
                                     |
                                     |
工作:Internet -- 路由器 -- 交换机 -- 工作网络(172.16.20.0/23)

为什么两个的网络要连起来呢?因为大家都不喜欢在网络之间切换,改 IP、网络设置、代理服务器等,很多时候大家需要同时在两个网络上,用工作网络(上网速度慢,很多端口被屏蔽,严格限制)访问内部所有的服务器,用新建的 ADSL 上网(网络速度快,没有屏蔽端口)。

要建这个 firewall/proxy/gateway 不需要很强大的硬件防火墙和服务器,所以 VPSee 决定把防火墙和 squid 服务安装在同一台机器上,节省资源。上个月对配置 Squid 服务器的硬件要求做了一些调查,接下来就是要在服务器上安装 Squid 服务。

pfSense 是一个基于 FreeBSD 的防火墙版本,从另一个 FreeBSD 防火墙 M0n0wall 发展而来,具有类似功能的 Linux 防火墙发行版本有 SmoothWall, Endian, IPCop, ClearOS, Untangle 等,试用了 一下 SmoothWall 发现非常简单易用,但是缺少一些我们需要的功能,SmoothWall 为了方便家庭用户使用把一些配置术语刻意简化了,比如配置网络的时候用到 Red/Green/Orange 让我摸不着头,我宁愿看到 nge0, bge0, eth0, 00:02:B3:CA:7B:92 等这些熟悉的术语,至少我能马上明白是什么意思。在测试 SmoothWall 的时候还遇到一些奇怪问题,比如启动了 DHCP 服务以后,客户端却不能及时得到 IP,要过几十秒钟,有时候甚至得不到 IP. pfSense 比 SmoothWall 强大很多,可自定义的模块很多,安装和配置第三方软件也很方便,使用起来特别顺手。

在 pfSense 上安装 Squid

安装 pfSense 过程很简单,这里省略,配置完 pfSense 网络接口后就开始安装 Squid,打开 pfSense 管理界面,在 System->packages 下面找到 squid 和 lightsquid(查看 squid 流量的工具)安装,成功后会在 Services 下看到 Proxy server 菜单,进去后可以配置 Squid 服务;在 Status->Proxy report 配置 Lighttpd 和查看 Squid 流量信息。
pfsense-squid

安装完 squid 后根据需要做一下配置,值得注意的是,默认安装后只有和这台 firewall/squid 服务器在同一个网段的机器才能通过这个 squid 访问 Internet,如果其他网段的电脑也想使用这个代理服务器的话除了在 Firewall: Rules 增加规则外,还需要在 Services->Proxy server: Access control 中增加网段到 Allowed subnets.

安装完 lightsquid 后要做如下配置:
1、配置 squid(Proxy server),enable /var/squid/log 路径;
2、配置 lightsquid(Proxy report)时需要点击 Refresh 按钮去创建 lightsquid reports,否则会得到一个出错页面。

在 FreeBSD 上安装 Squid

如果不用 pfSense,想在 FreeBSD 完整操作系统上安装 Squid:

# cd /usr/ports/www/squid
# make install

根据自己需要修改 squid.conf 配置文件:

# cp /usr/local/etc/squid/squid.conf.default /etc/squid/squid.conf
# vi /etc/squid/squid.conf

初始化 cache:

# /usr/local/sbin/squid -z

测试 squid 是否能正常运行:

# /usr/local/sbin/squid -NCd1

配置 Squid 服务器的硬件要求

去年有台 Squid 主服务器的主板坏了,因为有备份服务器所以不碍事,这台备份服务器是一台很老的 Pentium III 级别的 PC,平时不怎么用,只有主服务器 down 掉的时候才临时应付一下。VPSee 现在要抓紧时间把那台 Squid 主服务器换掉(在备份服务器坏掉之前~~),不考虑买新机器了,去年升级留下了很多老机器,以及一些内存、硬盘等配件,相互搭配一下应该可以配出几台好机器。

Squid 服务器的性能对内存和硬盘的要求比较敏感,硬盘缓存多少数据和需要多大内存之间有某种关系,这是因为每个缓存过的 object 在内存里都保留相应的 metadata,方便 Squid 能迅速查询 cache,这些 metadata 是由 StoreEntry 数据结构来保存的,每个 StoreEntry 占用 56 Bytes,加上每个 StoreEntry 都有1个 16-byte 的 cache key,所以保存在 cache 里面的每个 object 在内存中都对应占用 72 Bytes(metadata),这是在32位机器上的情况,如果是64位机器会占用更多(104 Bytes)。算下来在硬盘上缓存 1,000,000 个 objects 的话相应需要占用 72MB 内存用来做 metadata,而实际情况则比这个要多得多。这篇 Wiki 也解释了为什么 Squid 需要大量内存。如何来决定到底需要多少内存呢?能不能有某个公式可以直接套用呢? Squid: The Definitive Guide 这本书给出了这样一个建议,每缓存 1GB 需要 32MB 内存,这样的话一台 1GB 内存的机器可以在硬盘上缓存 32GB 的数据(object)。

As rule of thumb, you need 32 MB of memory for each GB of disk space.

除了知道以上内存和硬盘的关系以外,我们还需要通过实际需求来决定什么样配置的机器能满足用户需求并且取得最佳性价比。那么如何判断需要用多大的硬盘来缓存用户的记录呢?根据去年一年使用 LightSquid 对用户的日志统计和分析,VPSee 发现绝大部分用户每天消耗都不到 100MB 带宽(平均起来才 50MB 每用户每工作日),这样如果算每人每天平均消耗 50MB,每个月算20个工作日,那么每人每月就是消耗 1GB,算下来100人每月应该消耗 100GB 带宽,也就是要缓存每个月的用户记录的话需要 100GB 硬盘空间,根据上面 1GB/32GB 的公式,一台 4GB 内存的服务器就可以完全满足要求。幸运的是,Squid 服务器对 CPU 要求不高,只需要在老机器上加点内存就可以了。

还需要注意的是,一定要再配一台 Squid 服务器作为备份服务器以应付突发事件,cache 的数据不是很重要,所以不必做 RAID,不必花钱在一些昂贵的存储设备上,但是要保证至少有一台备份 Squid 服务器 stand by,在主服务器不能工作的时候能随时替换。Squid: The Definitive Guide 的作者推荐使用 FreeBSD 作为 Squid 服务器的操作系统。