squid3.0单网卡透明代理服务器[原创]

看网上很多人都做了squid的透明代理,今天自己也试验了一个,使用的是squid3.0stable8版本+iptables,下面就吧我的过程总结如下,首先看下我的拓扑结构
squid单网卡,通过交换机可以直接连接到Internet,A和B两组client可以处在不同的网段或相同的网段,只要可以和squid所在网段互通就行
本文本着只把透明代理实现的最基本过程整理如下,对于squid详细配置,以及iptables相对应的安全配置一概不涉及,有需要的朋友请自行去相应网站查找
言归正传,我的环境如下
vmware6.0模拟两个系统1、centos4.4(squid:192.168.220.128),2、winxp(ip:192.168.220.140)
squid基本配置:

acl manager proto cache_object
acl localhost src 127.0.0.1/32
acl to_localhost dst 127.0.0.0/8
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 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

http_access allow manager localhost
http_access deny manager
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports

http_access allow localnet

http_access deny all
always_direct allow localnet

http_port 3128 transparent       #透明代理的关键参数

hierarchy_stoplist cgi-bin ?

access_log /opt/squid/var/logs/access.log squid
cache_dir ufs /tmp 10 2 4 no-store

refresh_pattern ^ftp: 1440 20% 10080
refresh_pattern ^gopher: 1440 0% 1440
refresh_pattern (cgi-bin|?) 0 0% 0
refresh_pattern . 0 20% 4320

visible_hostname 1

cache_effective_user squid
cache_effective_group squid

然后正常启动squid,测试机xp系统ie中设置代理服务器,可以正常上网,说明,squid目前运行正常

接下来是iptables的配置

echo "1" >/proc/sys/net/ipv4/ip_forward
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-ports 3128

完成后,将xp中ie的代理去掉,更改xp的网关为192.168.220.128,然后配置好dns,直接在访问网页,就可以看到你想要的页面了,而squid中也有正常访问的日志了

这次最简单的squid透明代理就做完了

关于实施中的一点点问题,最先开始的时候,squid中我没有添加transparent这个参数,结果加完iptables后,访问返回的错误的页面如下

ERROR
The requested URL could not be retrieved

--------------------------------------------------------------------------------

While trying to retrieve the URL: /

The following error was encountered:

Invalid URL
Some aspect of the requested URL is incorrect. Possible problems:

Missing or incorrect access protocol (should be `http://'' or similar)
Missing hostname
Illegal double-escape in the URL-Path
Illegal character in hostname; underscores are not allowed
Your cache administrator is webmaster.

后来加上这个参数后就正常了

使用squid实现按源ip选择分流[原创]

先简单介绍一下情况,拓扑图是这样的

        ip-class-1                           ip-class-2
(192.168.21.0、24~25.0、24)          (192.168.31.0~35.0、24)
                          |                                  |
                             |                         |
                               |                   | 
                                   squid-3.0
                                 (192.168.1.1)
                                 |             |
                               |                  |
                            |                        |
                 web-class-1                web-class-3
大概拓扑是这个样子的,可能实际情况比这个更加的负载
我为了实现这样一个拓扑,使用的环境
vmvare6.0,起3个虚拟机,ip分别211.128(squid),211.129(nginx),211.130(apache)
其中两台web又做服务端,又做client
squid的关键配置
                

acl a src 192.168.211.129/32
acl b src 192.168.211.130/32
cache_peer 192.168.211.130 parent 80 0 no-query originserver name=www1 round-robin
cache_peer 192.168.211.129 parent 80 0 no-query originserver name=www2 round-robin
cache_peer_domain www1 a.b.c
cache_peer_domain www2 a.b.c
cache_peer_access www1 allow a
cache_peer_access www2 allow b

第1,2行定义两个client,真实环境请自行更改

第3,4行定义后端的两台RS,并做了round-robin,如果RS很多请自行添加,如果需要做会话保持,请使用sourcehash替换round-robin

第5,6行定义域名走哪个RS,示例中的a.b.c域名使用rr方式投递到两台RS上
第7行定义a过来的请求都投递到www1的RS上
第8行定义b过来的请求都投递到www2的RS上

配置好了后启动squid和web,接下来进行测试
模拟client的两台机器我都用的是wget这个参数,由于我没有仔细研究wget的参数,所以不知道哪个参数包含no-cache头,所以每次wget前我都会用squidclient+purge参数清除缓存,以达到测试的准确性

现在a上进行,wget -S –spider http://a.b.c/,返回的结果是头中包含apache的版本号,而且每次都是apache的版本号,说明,从a ip过来的请求都投递到了www1的RS上
再在b上进行,使用相同的wget命令,返回结果的头中包含nginx的版本号,而且每次都是,说明,从b ip过来的请求都投递到www2的RS上了

如此,如果真实环境,你可以把a的请求或b的请求投递到一组RS上按不同的需求,使用RR或者sourcehash的负载均衡方式。

防止自己的squid被当成代理来用[技术]

今天群里有个人问,自己的squid总被公网上的人拿来当代理上网用,要如何解决
我现在就把自己维护过程中用的几个方法总结一下
1,设定域名的办法
思路:定义好自己的域名,只有自己的域名能被squid代理,自己域名以外的任何域名都被deny
配置:

acl mydomain dstdomain a.b.c     #定义自己的域名
http_access allow mydomain       #只允许自己的域名被访问
http_access deny all             #阻止所有一切访问

然后重启squid,这样别人就无法使用你的squid作为代理了,但你的业务还是保持正常的
但以上办法,被阻止的人会看到你的squid的错误页面,如果你会改源码,可以做个新的错误页面,所以还有个更完美的办法来实现,就是使用deny_info这个参数,配置如下

acl mydomain dstdomain a.b.c      #定义自己的域名
http_access allow mydomain        #只允许自己的域名被访问
http_access deny all              #阻止所有一切访问

deny_info http://a.b.c all        #阻止所有访问的同时,把请求转到a.b.c主页

这样做最终结果就是无论外部的人用你的squid访问什么网站都会跳到你的首页,这招挺损的,哈哈
再说说另外的一个方法吧
2,不使用dns
多数人都喜欢在自己的服务器上配置dns,但往往squid后端的RS都是内网地址,解析都是通过hosts文件走的,或者内部的dns,这样如果你设置了 dns,就可能会被外面的人利用上网,所以我的做法是去掉dns,只使用hosts文件,同时在启动squid是使用-D参数,这个参数的意思就是不检测本地dns

通过以上两个办法足以使你的squid不会被外人拿来使用

squid2.7方便解决文件描述符大小[技术]

今天上squid官网,无意中发现squid2.7居然在5月31号发布了,出于对新产品的好奇吧,就看了一下 squid.conf中的配置,发现还真是多了不少东西,这其中我认为最有用,也是给squid安装带来方便的参数,max_filedescriptors,这个参数可以指定squid使用的文件描述符大小,但前提是不能超过编译是–with-maxfd这个参数设定的大小,自此,就再也不需要使用ulimit设置文件描述符了,当然squid2.7还增加了其他的一些特性,具体还等之后仔细研究

squid2.6stable12+clamav+havp搭建防毒代理

squid 2.6stable12 的安装

useradd squid

./configure –prefix=/opt/squid –enable-async-io=40 –enable-storeio=”aufs,coss,diskd,ufs” –enable-useragent-log –enable-referer-log –enable-kill-parent-hack –enable-forward-log –enable-snmp –enable-cache-digests –enable-default-err-language=Simplify_Chinese –enable-poll –enable-removal-policies=”heap,lru” –enable-large-cache-files –disable-internal-dns –enable-x-accelerator-vary –enable-follow-x-forwarded-for –with-large-files –disable-ident-lookups –enable-underscore –disable-arp-acl –with-maxfd=65500

make && make install

cd /opt/squid
mkdir cache1 cache1
chown -R squid.squid cache1 cache2 var

squid.conf的内容

http_port 3128

cache_mem 100 MB
cache_swap_low 75
cache_swap_high 98

emulate_httpd_log on
logformat combined %>a %ui %un [%tl] “%rm %ru HTTP/%rv” %Hs %<st “%{Referer}>h” “%{User-Agent}>h”
access_log /opt/web-squid/var/logs/access.log combined
redirect_rewrites_host_header off

acl all src 0.0.0.0/0.0.0.0
acl manager proto cache_object
acl localhost src 127.0.0.1/255.255.255.255
acl SSL_ports port 443 563
acl Safe_ports port 80          # http

acl CONNECT method CONNECT
http_access allow manager localhost
http_access deny manager
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access allow all

cache_effective_user squid
cache_effective_group squid

cache_replacement_policy lru

cache_dir aufs /opt/web-squid/cache1 50 32 64
cache_dir aufs /opt/web-squid/cache2 50 32 64
cache_log /opt/web-squid/var/logs/cache.log
cache_store_log none
cache_swap_log /opt/web-squid/var/logs/swap.log
log_ip_on_direct on
pid_filename /opt/web-squid/var/logs/squid.pid
visible_hostname testwebsquid
logfile_rotate 5

安裝 Clam AntiVirus
首先从http://www.clamav.net/下载clamav0.90包

useradd clamav

./configure
make
make install

注:安装过程中有可能会出现zlib版本不够的情况,请去http://www.zlib.net/下载最新的zlib进行安装

安装过程:
./configure
make
make install

安裝 HAVP
http://www.server-side.de/download.htm下载havp 0.86的包

useradd havp

./configure
make
make install

chown -R havp.havp /var/log/havp /var/tmp/havp /var/run/havp

vi /usr/local/etc/havp/havp.config

### 注释以下这行
#REMOVETHISLINE deleteme

### ClamAV Library Scanner (libclamav) → 由 HAVP 直接取用 ClamAV 的病毒资料库
ENABLECLAMLIB true
CLAMDBDIR /var/lib/clamav

### ClamAV Socket Scanner (clamd) → 交由 clamd 扫毒 (须先启动 clamd), 以上两者择一使用即可,我使用的上面那种模式)
ENABLECLAMD true
CLAMDSOCKET /tmp/clamd

其他效能相关的设定:

### 理論上越多的執行緒效能效能越好, 但仍需視伺服器資源而定
SERVERNUMBER 40
MAXSERVERS 200

### 只記錄 error log. 較少的 Log 記錄可減輕伺服器負擔
LOGLEVEL 0

### 不對圖片檔掃毒, 可減輕 CPU 負擔
SCANIMAGES false

### 这个是havp的监听端口,默认是8080,因为8080是tomcat的默认端口,所以我改成3129了,
PORT=3129

挂载独立磁盘区 /var/tmp/havp (一定要加上 -o mand 參數)

mount -o mand /dev/hda3 /var/tmp/havp

如果沒有多餘的 device 可以掛載, 可參考以下兩種方法:

a. 用記憶體建立虛擬磁碟

mkfs -t ext2 /dev/ram0 8192 (建立 8MB RAM Disk)
mount -o mand /dev/ram0 /var/tmp/havp

b. 使用硬碟空間建立虛擬磁碟

dd if=/dev/zero of=/root/havp_tmp.img bs=128K count=1 seek=1024 (建立 128MB Virtual Disk)
mkfs.ext2 /root/havp_tmp.img
mount -o loop,mand /root/havp_tmp.img /var/tmp/havp

ps. HAVP 可扫描的档案大小将受限于这里所挂载的磁盘空間

更新 shared libraries 资料库 (for ClamAV)

vi /etc/ld.so.conf –> 加入: /usr/local/lib
ldconfig

启动 HAVP

/usr/local/sbin/havp &

squid和havp的捆绑

编辑squid.conf文件
加入如下两行

cache_peer 127.0.0.1 parent 3129 0 no-query no-digest no-netdb-exchange default
cache_peer_access 127.0.0.1 allow all

到目前位置squid+clamav+havp就已经配置完成了
使用squid做代理然后去http://www.eicar.org/anti_virus_test_file.htm这个网站进行测试吧

HAVP 會直接使用 ClamAV 的 Library, 所以 ClamAV 的服務是不需要啟動的.
您只要使用 ClamAV 的 freshclam 來更新 ClamAV 的病毒碼就行了,
方法如下:
1. 以 crontab 排程: 0 0 * * * /usr/local/bin/freshclam –verbose(每天午夜更新病毒碼)

Clamav升级配置文件

vi /usr/local/clamav/etc/freshclam.conf
##
## Example config file for freshclam
## Please read the clamav.conf(5) manual before editing this file.
## This file may be optionally merged with clamav.conf.
##

# You can change the default database directory here.
#DatabaseDirectory /var/lib/clamav

# Path to the log file (make sure it has proper permissions)
UpdateLogFile /var/log/freshclam.log
# Enable verbose logging.
LogVerbose

# Use system logger (can work together with UpdateLogFile).
LogSyslog

# By default when freshclam is started by root it drops privileges and
# switches to the “clamav” user. You can change this behaviour here.
#DatabaseOwner clamav

# The main database mirror is database.clamav.net (this is a round-robin
# DNS that points to many mirrors on the world) and in most cases you
# SHOULD NOT change it.
DatabaseMirror database.clamav.net

# How many attempts to make before giving up.
MaxAttempts 3

# How often check for a new database. We suggest checking for it every
# two hours.
Checks 12
# Proxy settings
#HTTPProxyServer myproxy.com
#HTTPProxyPort 1234
#HTTPProxyUsername myusername
#HTTPProxyPassword mypass

# Send the RELOAD command to clamd.
#NotifyClamd [/optional/config/file/path]

# Run command after database update.
#OnUpdateExecute command

# Run command if database update failed.
#OnErrorExecute command

以上内容有部分是看了其他文章后加入的,并非完全本人原创