IE浏览器非法ContentTyep缓冲目录位置泄露缺陷 (MS,缺陷)

来源:岁月联盟 编辑:zhuzhu 时间:2010-02-13
IE浏览器非法ContentTyep缓冲目录位置泄露缺陷 (MS,缺陷)

发布日期: 2003-12-19
曾几何时,凡配备电脑的单位几乎都已架设了内部局域网,以实现单位内部的互连互通。但这些还远远不够,因为内部人员还需要与外面的世界打交道,如与远程工作人员的即时通信、杀毒软件的定时升级等,所以我们还要与Internet实现互连互通。这时我们就有两种方案供选择:一是为每个员工申请一个接入帐号,二是在局域网上架设互联网网关,让所有局域网用户共享单个帐号上网。鉴于第二种方案更加经济可行,并且现在的宽带足以满足大部分单位网上办公之需,所以人们通常更喜欢采用后一种方式。而本文的目的就是向读者介绍如何用Linux机器打造一个经济实用的Internet全能网关。

尽管本文所用的是Red Hat Linux9.0作为示范,读者在使用其他发行版本时可能遇到文件路径和文件名有所区别的情况,但方法是一致的,所以不会有太大的困难。

一、安装Internet连接

单位利用网关接入互联网时,大多使用的是ADSL、VDSL以及宽带IP等,通常只需要再添加一块以太网卡(笔者的网卡也是由通信公司给我安宽带时一块带来的),并且ISP网关地址等设置等工作都由ISP工作人员来代劳,所以这里不再多说。

二、架设代理服务器

从现在起,以下的工作就需要我们自己动手了。首先要做的是配置代理服务器。这里我们选择Squid作为我们的代理服务器软件加以说明。之所以选择它,是由于它具有以下优点:

1.易于控制

2.能够节省大约30%的通信量(当然,如果采用包月制这一点意义不大,否则就不得不考虑了)

3.能够加速Web页的访问

4.功能丰富

当然金无全赤,它的不足之处在于该软件本身稍微大了一点,另外,有时它要占用更多的内存,但这些都在可以容忍的范围之内。话又说回来,又要马儿跑又要马儿不吃草只不过是人们的一个愿望罢了。

该软件的安装非常简单,如下:

# rpm -ihv squid-2.5.STABLE1-2.i386.rpm

Squid安装后,其配置文件位于目录/etc/squid下面。另外,它还有一个指向该目录的符号链接errors,专门为所有用户存放出错消息。

现在从编辑/etc/squid/squid.conf开始着手来配置常用的代理。在“NETWORK OPTION”段,将http_port的参数设为运行代理服务器的机器的IP地址和端口号:

http_port 192.168.0.1:3128

在“OPTION WHICH AFFECT THE CACHE SIZE”段,参数cache_mem规定了分配给高速缓冲对象的内存总量,默认的情况下该值为8M。我们可以根据实际情况加以修改,比如,若您的机器的内存小于等于32M,您最好将该参数降为4M;如果您的内存很大,您也可以提高该参数的值,如改为10M或更高。

参数maximum_object_size定义了允许存放在磁盘高速缓冲区中的对象的最大尺寸。默认时,该值为4096K。您还可以根据磁盘可用空间的大小来调节该值,如您可以将其改为1024K。

在LOGFILE PATHNAMES AND CACHE DIRECTORIES部分,参数emulate_httpd_log定义了日志文件的类型和结构。默认时,该参数的值为off,这时的日志文件有较强的专用倾向,例如时间被设成Unix风格,只有通专用的程序将其转化成某种特殊格式后别的程序才能读懂。当参数emulate_httpd_log的值设为on时,日志文件的格式将与Apache的日志文件格式保持一致。需要注意的是,该参数的值与日志分析程序密切相关,因为不同的分析程序使用的格式是不同的。

在“OPTIONS FOR TUNING THE CACHE”段,有三个参数需要注意,它们是quick_abort_min、quick_abort_max和quick_abort_pct。它们的作用是决定Squid是否缓存下载过程中被异常终止的文件。默认时,前两个参数的值为16K,最后一个参数的值为95%。若这些参数的值设置不当,可能会导致程序行为变得非常古怪,例如,即使我们当前并没有使用Squid,但它仍可能会莫名其妙地向缓冲区下载一些东西。对于小型低速网络,这些参数的推荐值为:将参数quick_abort_max的值设为1或2;将参数quick_abort_pct的值设为98%或99%。

在“TIMEOUT ”段中,参数shutdown_lifetime定义了代理停机后的最大超时值。它决定了何时关闭所有用户已打开的TCP连接,默认时该参数的值为30秒,对于小型网络来说,它的值可降为15秒,甚至10秒。

在“ACCESS CONTROLS”段,给出了对访问控制列表ACL——Squid的特色功能之一——的定义。默认时,Squid被配置成仅允许本机用户(Squid程序所在主机的接口)访问代理。最简单的方法是在acl列表中添加如下行:

acl mynetwork src 192.168.0.0/255.255.255.0

其中,mynetwork是该ACL的名字;src是一个关键词,它定义了ACL的类型(在我们的例子中为C类IP网络);192.168.0.0是网络的IP地址,后面的255.255.255.0是网络掩码。需要注意的是,只要定义网络地址,那就必须给出该地址的网络掩码。

同时,我们需要在参数表中给出http_access的访问规则:

http_access mynetwork allow

另外,http_access的各个规则间的顺序是非常重要的,因为各个规则的处理是按照从上往下的顺序进行,直到遇到第一个匹配为止。所以,一定要将上面这一行添加到下面这行之后:

http_access allow localhost

并且一定要在下面这行之前:

http_access deny all


需要注意,这个例子只能适用于该软件自身所带的配置文件。其他情况下,各个访问规则可能有所不同,因此这个同意访问的行的安放位置可能有所不同。

ALF还有个非常有用的功能,那就是从文件中载入。除了直接写地址外,我们还可以设置一个路径名,例如:

acl myuserlist src "/etc/squid/acl/myusers.lst"

该命令规定用于myuserlist的所有IP地址都从/etc/squid/acl/myusers./lst获取。这时,Squid将以只读的方式来尝试访问该文件。该文件必须列出所有的IP地址,并且每个地址单独占一行。

ACL除了IP地址外,还包括日期、时间、域名、URL(可以以列表的方式也可以用规则表达式的方式表示)、端口、协议等项。这些都可以用ACL加以控制。这给与了管理员更多的选择来控制对代理的访问。具体使用方法请参考Squid自身所带的文档,这里只给出一些有用的“偏方”:

1.远离色情之类站点:

acl allow_url url_regex "/etc/squid/acl/allow_url"
acl deny_url url_regex "/etc/squid/acl/deny_url"
……
http_access allow allow_url
http_access deny deny_url
其中,在文件deny_url中包含的是些规则表达式,用以定义被拒绝的站点:
^http://.*porno.*
^http://.*xxx.*
^http://.*/.linkexchange/.com/cgi-bin

文件allow_url中,使该列表中的一些例外站点,例如:

^http://.*linuxxx.*

2.供运行在HTTPS上的应用程序

默认的情况下,Squid将拒绝除了端口443和563之外的所有端口上的HTTPS请求,这会导致某些在它们自己的端口上使用HTTPS的应用程序无法正常工作。处理这种情况时,最直接的方法就是将这些行标注出来,例如:

http_access deny CONNECT !SSL_ports

但是这样一来,我们就把代理的大门向所有使用SSL的公用程序都打开了。所以最好是先找出哪个应用程序使用的是哪个端口再说。例如,ICQ对应的端口为5190,所以可以修改以下行:

acl SSL_ports port 443 563

为其添加端口5190:

acl SSL_ports port 443 563 5190

现在就差重新启动Squid了。

3.据实际限制对代理的访问

很多情况下我们只允许在一天当中的一些特定时间段内通过代理访问互联网,那该如何设置呢?其实利用Squid来实现此项功能很简单,如下所示:

# Define access time:
acl worktime_am time MTWHF 8:00-11:00
acl worktime_pm time MTWHF 12:00-16:40
# Define access lists:
acl time_unlimited src "/etc/squid/time_unlimited.list"
acl time_limited src "/etc/squid/time_limited.list"
...
# Set rules:
http_access allow time_unlimited
http_access allow time_limited !worktime_am !worktime_pm
http_access deny all


通过上面的展示,您是不是已经体会到了Squid的强大和简便了呢?!

在 “MISCELLANEOUS”段中,包含有deny_info的许多有用的设置。deny_info定义了当匹配一个http_access deny规则时,将向用户显示哪些出错消息,其用法如下所示:

deny_info ERROR_MESSAGE acl_name

其中,ERROR_MESSAGE是包含消息文本的文件名。该文件位于目录/etc/squid/errors下面。acl_name是包含这个有效规则的ACL。

现在我们可以运行已经配置过的代理软件了:

# service squid start
init_cache_dir /var/spool/squid... Starting squid: [ ok ]


第一次启动时,将建立一个专用的目录树/var/spool/squid:一个存放各种对象的磁盘缓冲区。变量init_cache_dir就是专门用于控制该目录的。一般来说,第一次启动可能会慢些,因为他要进行一些创建目录等只有第一次启动时才做的工作,但是以后再启动时就快多了。

到目前为止,我们的服务器端已经配置完成,他已经可以为局域网提供代理上网服务了。但是在用户端,还需要配置浏览器让HTTP、HTTPS和FTP等协议通过代理服务器工作。

尽管我们的服务器已能工作,但每次还得手动启动它,现在介绍如何让代理服务器在机器开机时自动运行,如下所示:

# chkconfig squid on

三、配置防火墙和NAT(地址伪装)

我们已经为局域网的用户打开了一扇通向互联网的大门了,现在坐下来想想是否还得做点什么?对了,我们这个代理服务器还不太安全。当然,一个有着正确配置的代理服务能够保证岂不会被一些不速之客所访问,但是其他服务是否也已经得到了很好的保护呢?接下来我们就通过Linux的一个常用工具——防火墙来为上述问题提供一个满意的答案。

现在大部分Linux发行版都带有以下两个软件包:ipchains和iptables,但前者已经有些过时,所以我们将专门介绍Red Hat 默认采用的iptables。

我们首先解决安全问题。在/etc/sysconfig目录下存放着一个名为iptables的文件,该文件采用iptables-save和iptables-restore实用程序所特有的格式。如果在安装时选择了中级保护,那么该文件将由lokkit程序创建,如下所示:

# Firewall configuration written by lokkit
# Manual customization of this file is not recommended.
# Note: ifup-post will punch the current nameservers through the
# firewall; such entries will *not* be listed here.
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:RH-Lokkit-0-50-INPUT - [0:0]
-A INPUT -j RH-Lokkit-0-50-INPUT
-A FORWARD -j RH-Lokkit-0-50-INPUT
-A RH-Lokkit-0-50-INPUT -i lo -j ACCEPT
-A RH-Lokkit-0-50-INPUT -p tcp -m tcp --dport 0:1023 --syn -j REJECT
-A RH-Lokkit-0-50-INPUT -p tcp -m tcp --dport 2049 --syn -j REJECT
-A RH-Lokkit-0-50-INPUT -p udp -m udp --dport 0:1023 -j REJECT
-A RH-Lokkit-0-50-INPUT -p udp -m udp --dport 2049 -j REJECT
-A RH-Lokkit-0-50-INPUT -p tcp -m tcp --dport 6000:6009 --syn -j REJECT
-A RH-Lokkit-0-50-INPUT -p tcp -m tcp --dport 7100 --syn -j REJECT
COMMIT

这个配置文件从逻辑上可以分为三部分。首先出现的是默认策略,允许所有ITPUT、FORWORD和OUTPUT数据包通过。接下来是一条特殊规则RH-Lokkit-0-50-INPUT,他后面的每一行都是一条规则。数据包依次经过这些规则的过滤,直至找到一个匹配的。这里一个常犯的错误是将一条允许规则置于一条拒绝规则之后。为此,创建规则的时候,首先应该是主机的允许规则,然后是主机的拒绝规则,接下来是网络的允许规则,最后是网络的拒绝规则。

我们这里这个中等级别的安全配置文件允许本地接口的所有数据包,拒绝1023及其以下的端口上的输入数据包,并拒绝X Window系统和字体服务器端口。如果连接是从本地发起的,过滤器将允许所有的数据包。该配置对工作站来说已经非常合理了,但对于一个网关服务器来说,还欠些火候,所以还要进一步改进。在改进之前,我们假设网关的IP地址为192.168.0.1,通过以太接口eth0接入内部网络192.168.0.0。

为了能方便使用电子邮件等服务,我们这里会用到NAT技术,它有时又称为地址伪装。它的作用在于将来自内部机器的IP数据包做些转换工作,使它们在外部看来是网关发出的。但外部的数据进入时,NAT在进行相应的逆变换。

首先要做的是允许转发全局数据包,可以通过以下任何一条命令来实现,或者:

# echo 1 > /proc/sys/net/ipv4/ip_forward或者:# sysctl -w net.ipv4.ip_forward=1

但无论使用上面哪条命令,都必须在超级用户模式下进行。另外,还需要修改/etc/sysctl.conf文件中的下面一行:

net.ipv4.ip_forward = 0
将这一行改为:
net.ipv4.ip_forward = 1


下一步是配置iptables。一般情况下,电子邮件服务会用到三个端口:25,通过SMTP发送电子邮件;110,通过POP3接收电子邮件;143,通过IMAP4接收电子邮件。至于新闻组,它使用的是端口119。要允许经由这些端口的连接的话,我们还得向文件/etc/sysconfig/ipchains中添加部分规则。

我们现在来为我们的用户机器配置DNS,因为电子邮件客户程序需要它。如果我们知道邮件服务器的IP地址的话,我们可以将其放入Linux的/etc/hosts文件,对于Windows9X/ME则放入c:/windows/hosts,对于WindowsNT/2000/XP放入c:/winnt/system32/drivers/etc/hosts。

通常情况下规则的顺序是非常重要的,用于电子邮件的规则也不例外,具体如下所示:

# Simple firewall for internet gateway
*filter
:INPUT ACCEPT [0:0]

# Deny forward for security reasons
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
:RH-FW-INPUT - [0:0]

# Redirect all input-forwarded packets to our special rule
-A INPUT -j RH-FW-INPUT

# Accept all packets for local interface (lo)
-A RH-FW-INPUT -i lo -j ACCEPT

# Define custom rules
# This part equal to some part from generated by Lokkit utility
-A RH-FW-INPUT -p tcp -m tcp --dport 0:1023 --syn -j REJECT
-A RH-FW-INPUT -p tcp -m tcp --dport 2049 --syn -j REJECT
-A RH-FW-INPUT -p udp -m udp --dport 0:1023 -j REJECT
-A RH-FW-INPUT -p udp -m udp --dport 2049 -j REJECT
-A RH-FW-INPUT -p tcp -m tcp --dport 6000:6009 --syn -j REJECT
-A RH-FW-INPUT -p tcp -m tcp --dport 7100 --syn -j REJECT

# Allow access to mail/news/DNS
-A FORWARD -s 192.168.0.0/24 -p tcp -m tcp --dport 25 -j ACCEPT
-A FORWARD -s 192.168.0.0/24 -p tcp -m tcp --dport 110 -j ACCEPT
-A FORWARD -s 192.168.0.0/24 -p tcp -m tcp --dport 143 -j ACCEPT
-A FORWARD -s 192.168.0.0/24 -p tcp -m tcp --dport 119 -j ACCEPT
-A FORWARD -s 192.168.0.0/24 -p tcp -m tcp --dport 53 -j ACCEPT
-A FORWARD -s 192.168.0.0/24 -p udp -m udp --dport 53 -j ACCEPT
COMMIT

# Enable masquerading
*nat
:PREROUTING ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A POSTROUTING -p tcp -s 192.168.0.0/24 -o ppp0 -j MASQUERADE
-A POSTROUTING -p udp -s 192.168.0.0/24 -o ppp0 -j MASQUERADE
COMMIT
然后添加如下命令来加载用于地址伪装的内核模块:
# touch /etc/rc.d/rc.modules
# chmod +x /etc/rc.d/rc.modules
# ln -s /etc/rc.d/rc.modules /etc/rc.modules
# cat > /etc/rc.d/rc.modules
modprobe ip_conntrack
modprobe ip_conntrack_ftp
modprobe iptable_nat
modprobe ip_nat_ftp
^D


若要不想重新启动系统的话,可以运行rc.modules:

# /etc/rc.d/rc.modules

出于安全的考虑,我们当前的转发策略为DENY,因为这样就可以拒绝非法IP数据包。

在修改完我们的配置文件后,还得运行iptables才能让它发挥作用。另外,如果能让iptables自动载入那就更好了。现在动手吧:

# service ipchains start
Reseting all current rules and user queries [ OK ]
Cleaning all current rules and user queries [ OK ]
Loading rules iptables [ OK ]
# chkconfig iptables on


有时候启动iptables会中断某些服务,所以建议打开对REJECT和DROP规则的日志。另外,用-j LOG –log-prefix “short comment”替换掉-j DROP 或-j REJECT,这样一来就会为被阻止的数据包向系统日志/var/log/messages中添加相应的消息,籍此您就可以精心制作出更合适的允许规则了。当然,有些我们也能允许某些用户使用网络外部的其他一些服务,但你应该尽量避免这样做,因为它会降低网络的整体安全性能。