2007-12-02

windows和linux混合系统的多重启动


windows和linux混合系统的多重启动从来都是一个启动加载器加载另一个系统的引导记录或启动加载器.
因此Vista,Linux的双重启动也是如此:

方法1:用Vista的bootMbr加载grub
方法2:把Grub装到mbr,用grub "chainloader (hd0,1)+1"

方法2和XP没什么好说的,现在说方法1.

Vista的bootMbr可以看成一个小的操作系统,加载几种不同的程序

先来看:bcdedit /?create 中的一段话:

/application <apptype> 指定新项必须是应用程序项。
<apptype> 指定应用程序类型。
<apptype> 可以是下列类型之一:
BOOTSECTOR
OSLOADER
RESUME
STARTUP

如果使用其他应用程序类型而不是这些类型, 则还必须指定已知的标识符。

再来看,我系统的实际的BCD记录:

Windows 启动管理器
--------------------
标识符 {bootmgr}
device partition=D:
description Windows Boot Manager
locale zh-CN
inherit {globalsettings}
default {current}
displayorder {ntldr}
{current}
{cdb7d744-a02e-11dc-a438-00115b1add5f}
toolsdisplayorder {memdiag}
timeout 30
Windows 启动加载器
-------------------
标识符 {current}
device partition=C:
path Windowssystem32winload.exe
description Microsoft Windows Vista
locale zh-CN
inherit {bootloadersettings}
osdevice partition=C:
systemroot Windows
resumeobject {91d7a191-a009-11dc-8f33-c08105f3e2d8}
nx OptIn
Windows 启动加载器
-------------------
标识符 {cdb7d741-a02e-11dc-a438-00115b1add5f}
device partition=D:
path ghldr
description GHLDR-O
从休眠状态恢复
---------------------
标识符 {91d7a191-a009-11dc-8f33-c08105f3e2d8}
device partition=C:
path Windowssystem32winresume.exe
description Windows Resume Application
locale zh-CN
inherit {resumeloadersettings}
filepath hiberfil.sys
pae No
debugoptionenabled No
Windows 内存测试程序
---------------------
标识符 {memdiag}
device partition=D:
path bootmemtest.exe
description Windows 内存诊断
locale zh-CN
inherit {globalsettings}
badmemoryaccess Yes
Windows 旧 OS 加载器
------------------------
标识符 {ntldr}
device partition=D:
path ntldr
description 早期版本的 Windows
实模式启动扇区
---------------------
标识符 {cdb7d744-a02e-11dc-a438-00115b1add5f}
device partition=D:
path NSTNeoGrub.mbr
description NeoGrub Bootloader
EMS 设置
------------
标识符 {emssettings}
bootems Yes
调试器设置
-----------------
标识符 {dbgsettings}
debugtype Serial
debugport 1
baudrate 115200
RAM 故障
-----------
标识符 {badmemory}
全局设置
---------------
标识符 {globalsettings}
inherit {dbgsettings}
{emssettings}
{badmemory}
启动加载器设置
--------------------
标识符 {bootloadersettings}
inherit {globalsettings}
恢复加载器设置
----------------------
标识符 {resumeloadersettings}
inherit {globalsettings}

可见vista的boorMbr(Windows 启动管理器)
可以加载:
OSLOADER(Windows 启动加载器)
BOOTSECTOR(实模式启动扇区)

也就是说,我们可以把Grub修改成上面两种程序中的一种,来让"Windows 启动管理器"来加载.

第一种的配置例如上面的:
Windows 启动加载器
-------------------
标识符 {cdb7d741-a02e-11dc-a438-00115b1add5f}
device partition=D:
path ghldr
description GHLDR-O
但这样的文件,ghldr,实现起来是比较麻烦的,因为缺少资料.

第二种:
实模式启动扇区
---------------------
标识符 {cdb7d744-a02e-11dc-a438-00115b1add5f}
device partition=D:
path NSTNeoGrub.mbr
description NeoGrub Bootloader
则已经有了产品:NeoGrub.mbr

这是我D:NST的文件:
d:NST>dir
驱动器 D 中的卷是 XPHOME 卷的序列号是 A05A-B1BB
d:NST 的目录
2007/12/02 02:16 <dir> .
2007/12/02 02:16 <dir> ..
2007/12/02 02:16 397 menu.lst
2007/06/15 05:19 8,192 NeoGrub.mbr
2 个文件 8,589 字节
2 个目录 393,293,824 可用字节
d:NST>type menu.lst
# NeoSmart NeoGrub Bootloader Configuration File#
# This is the NeoGrub configuration file, and should be located at D:NSTmenu.lst
# Please see the EasyBCD Documentation for information on how to create/modify entries:
# <a href="http://neosmart.net/wiki/display/EBCDhttp://neosmart.net/wiki/display/EBCD">http://neosmart.net/wiki/display/EBCD</a>
find --set-root --ignore-floppies /boot/grub/menu.lst
configfile /boot/grub/menu.lst
# All your boot are belong to NeoSmart!
d:NST>

这样,Grub就会按分区顺序寻找/boot/grub/menu.lst

也许你会问,到哪里去找这个NeoGrub呢?
上面的文件已经透露了:
请google "EasyBCD"

2007-06-22

Linux系统的构成和相互间的依赖(从LFS看Linux)

原题 : 换个角度看LFS——反向分析LFS


更新日志
2006-08-12:修改有歧义的句子一处。
2006-06-21:增加对结尾插图的说明。
2006-06-21:修改最后一副插图。
2006-06-21:修改笔误一处。

前言
  写了几篇关于LFS的制作过程中的文章,但分析性的文章还没怎么写过,论坛上也有一些分析性的文章,但大多数都是真对某个特定部分的,最近酝酿了一下,准备写点分析性质的文章调剂调剂。
  这次用的标题大概已经能说明本文分析的角度,按照LFS的顺序写,似乎总不能摆脱LFS的制作过程的牵制,总觉得像写制作教程,所以决定反过来写,利用一个大家熟悉的情景为开始反过来推出整个LFS的过程,本文不能算专业的分析文章,只是想简单的说明白LFS为什么要这样的过程。
  本文并不是要完全还原LFS,只是为了说明一种分析过程,因此文中部分内容和实际的LFS略有出入。
  限于水平的问题,我只能将我现在的理解来写,如果有什么错误或者不当的地方希望大家及时指出。
  本文的读者应该是一个已经经历过LFS至少一次的朋友,如果你从来没搞过LFS,建议亲自动手制作一遍后再看本文,应至少看过下面文章中的一篇:
  《Linux from scratch》英文版本
  《LFS-Book 6.1.1 中文正式版》
  《手把手教你如何建立自己的Linux系统(LFS速成手册)》

  更新,由于篇幅比较长所以难免出现一些错误或者笔误,也有可能加入新内容,因此难免会进行修正或增删一些内容,如果本文被转载您可以在本人的Blog或者www.linuxsir.org的LFS版中中查看最新版本。
  我的Blog:http://youbest.cublog.cn
  linuxsir:http://www.linuxsir.org/bbs/showthread.php?t=262010
  如须转载请注明作者为冲天飞豹(youbest),并请保持文章的完整和提供转载出处。

工作情景:
  我正在用VIM编辑一篇文件


分析:
  问:那么要完成这个任务我需要些什么呢?
  答:硬件(略),本文将不对硬件做任何分析。
    软件:VIM

  问:那么运行VIM又需要什么条件呢?
  答:一个Linux内核
    一组支持VIM运行的动态库,按照比较标准的组合,应该是glibc和ncurses这两个库来承担VIM的运行时动态库

  问:那么内核需要什么条件呢?
  答:符合内核运行的硬件环境。

  问:glibc又需要什么条件呢?
  答:于glibc相适应的Linux内核

  问:ncurses需要什么条件呢?
  答:合适的glibc

最后我们来画一副图来描述这个关系



  那么这个关系图基本上就可以描述一个VIM运行的环境需求,当然在启动VIM的过程中少不了一个shell的参与,通常我们用BASH来完成,那么这个任务的整个大致环境和关系大致如下图所示。


  清楚了这个问题,下面需要解决的就是这个运行环境从哪里来的呢?
  通常Linux下的软件都提供了源代码,我们可以用这些源代码来组合成我们自己需要的二进制程序。
  在这个例子中,我们想要有一个VIM,那么我们要先下载一份VIM的完整源代码,然后利用一组编译工具来完成VIM的编译。
  对于一个通常编译的过程大致如下图





  这其中最复杂的就是make阶段,make会调用目录中的Makefile来执行一系列的工作,其中包括创建必要的文件,以及调用gcc和binutils来编译源代码和链接目标文件,最终生成需要的可执行文件和附属文件。
  所以make过程中一般需要用到的是gcc,binutils,make和一些系统程序(不同的软件需求不同)。


这样我们再来画最开始的运行环境的图


  好了,这样我们就清楚了这个整个运行时候的环境是从哪里来的了。用红色虚线框起来的就是整个构造运行时环境的必要条件了,其实就是我们通常在LFS中最常见到的一个词汇:工具链。
  那么下面的一个问题就是这些工具运行的条件是什么?
  这些编译环境中的应用程序也和其它程序一样必须有运行的环境:
  GCC依赖于glibc
  binutils依赖于glibc
  make依赖于glibc
  头文件是在编译时候gcc所需要的,但本身都是一些文本文件,因此没有需要的运行环境。
  常用工具依赖于glibc和各种需要用到的动态库。

  这里的一个新问题就是编译环境中使用的glibc和Linux内核和“运行时环境”中的glibc与Linux内核是否是同一个。
  答案很显然,绝对不是,因为“运行时环境”中的glibc和Linux内核是依靠工具链中编译工具来完成的,所以工具链所依赖的glibc和Linux内核于目标系统的不可能是同一个(但版本什么的是可以一样的,这里说的不同是指已经编译成二进制的实体不同)。
说明:
  为了说明方便,下面将“运行时环境”称为目标系统。
  但就LFS而言目标就是要做一个通用的可自主扩展(编译)的系统,所以在完成目标系统的glibc后又编译了一整套工具链中的东西,目的是将工具链中的工具全部移植到目标系统中,以便在完成目标系统后可以抛弃工具链而又能够自主的进行编译,而这些工具依赖的环境就是目标系统的glibc了。
  内核这东西比较特殊,虽然运行任何程序都需要用的内核,但本身在制作目标系统过程中,目标系统的Linux内核却不需要先进行编译,因为使用 Linux内核并不像glibc那样是依靠动态链接库的方式被调用的,内核不是用动态库的方式被调用的,因此不需要先编译,只要提供对应的头文件即可,后面将不再探讨Linux内核的问题。
  作为LFS的另一个目标就是要建立一个“纯净”的系统,因此编译glibc的编译器和最后目标系统里的编译器应该保持一致,同时目标系统是完全依靠工具链编译出来的,而工具链应该是在目标系统建立完毕后可以很方便的剥离掉的,而且为了保持工具链的稳定工具链中的工具所依赖的glibc以及其它用到的动态库应该是不会被替换掉的。
  要解决上面这个问题,那么最好的方法就是将工具链放置在一个独立的目录中,LFS将其放在了/tools目录下,因此在用工具链建立目标系统的过程中将PATH设置为/bin:/usr/bin:/tools/bin来让bash调用命令时能首先调用目标系统中已经建立好的命令,如果没有则从工具链中调用。这样的话在目标系统还没有编译工具的情况下使用工具链来进行编译。
  好了,现在已经可以用工具链来完成目标系统的编译了,下面的问题就是这个工具链是如何来的呢?
  这个问题就要回到前面所提到的工具链运行时所依赖的环境,还是这个glibc,要编译这个glibc必须是在工具链的编译工具生成之前,而工具链的编译工具又依赖于glibc,那么这个glibc就不能是现在工具链中的编译工具编译出来的,那么是谁编译的呢?
  这个问题的答案:当然还是编译器编译的这个glibc和工具链里的编译工具,也就是说在工具链中的编译工具编译目标系统之前需要另一个编译器来编译这个在使用的工具链中的编译器和编译器所依赖的glibc。


  用蓝色的虚线框起来的部分就是生成工具链的工具链,我暂时称为“预工具链”。
  “预工具链”的存在则能完成工具链中的glibc,以及工具链中的编译工具,并且工具链中的工具将被编译成依赖于工具链中的glibc。
  那么现在要解决的问题就是这个“预工具链”是如何建立起来的。
  答案还是一样,需要一套编译工具来编译出这个“预工具链”。

  现在要提到的一个问题就是,用不同版本的gcc编译出来的程序可能不一样,而不同的gcc编译出来的目标文件要用能正确处理的binutils的版本来链接成可执行文件,因此我们现在已经能确定的gcc、binutils版本是工具链中的版本,那么用工具链编译出来的目标系统是符合我们的要求的。
  那么编译工具链中的glibc和gcc以及binutils的gcc和binutils的版本现在还没有确定,但根据LFS的“纯净”目标,也就是说 gcc和binutils也必须和工具链中的gcc和binutils相同才行。而其它的常用工具及make虽然参与,但不会对编译的二进制产生影响(前提是必须能正确处理它应该做的事情)。

  现在的问题就集中到“预工具链”中的gcc和binutils上了,只要能编译出和工具链中的gcc与binutils相同版本就可以了,也就是说只要一套编译环境能编译gcc和binutils就可以了。

  那么问题是这一套编译环境是怎么来的呢?
  如果还继续按照前面的套路,这个问题就成了无穷无尽的了,这个不是我们想做的,现在已经能“纯净”的建立一套符合条件的工具链就已经达到我们的目的了,因此编译“预工具链”的binutils和gcc的任务我们就采用一套能正确编译的发行版或者预制好的编译环境就可以了,我们可以称这个发行版或者预制好的编译环境为“主系统”。
  那么我们现在只要能用这个“主系统”编译出“预工具链”的binutils和gcc就可以了,“预工具链”中的其它部分就直接采用“主系统”里的就可以了。
  但这里有一个问题就是:“主系统”中的gcc和binutils与“预工具”中要求的gcc和binutils版本不同(通常会老些),但只要能正确编译binutils、gcc就行了,gcc具备自我编译的功能,因此建议编译不同版本的gcc采用bootstrap的方式比较好。当然“主系统”中的在参与编译过程中的其它工具也需要符合要求就成。
  最后用一副图来表达简单的表达整个过程,也算本文的结尾。
(转载请保持文章的完整性,请注明作者和出处)

                               作者:冲天飞豹(youbest)
                               Email:youbest@sina.com
                               2006年6月21日

希望大家能多写一些分析性的文章,共同提高。




说明:上图的内容实际上并不是标准的LFS编译关系,按照LFS的做法,应该在预工具链编译完成工具链中的glibc、gcc和binutils,工具链后续的部分是由工具链的gcc和binutils来完成的,但本文并不追求和LFS完全一致,只是为了说明整个过程是如何反向推出来的,而且我认为按照图里的方法也完全没问题,完全不影响目标系统的“纯净”度。
图中实际上也表现了一种可以用来编译不同平台上的工具链的方法,因为在编译整个工具链的过程中都由预工具链来完成的(此方法我自己没实验过,只是一个设计)。


更新日志:

2006年6月21日:
修改笔误一处
由linuxsir上的doom3d发现并报告

2006年6月21日:
在结尾的图片上加入gcc的bootstrap的标记。
由linuxsir上的doom3d建议

2006年6月21日:
对结尾的图片做出说明。

2006年8月12日:
修改有歧义的句子一处。

2007-06-18

关于无线全球电力广播的不知道可不可信的报道

关于无线全球电力广播的不知道可不可信的报道

他(特斯拉)的最著名的发明是“特斯拉线圈”,这是一种分布参数高频共振变压器,可以获得上百万伏的高频电压。 特斯拉线圈的线路和原理都非常简单,但要将它调整到与环境完美的共振很不容易,特斯拉就是特别擅长这项技艺的人。

  特斯拉后来发明了所谓的“放大发射机”,现在称之为大功率高频传输线共振变压器,用于无线输电试验。特斯拉的无线输电技术。值得一题的是:特斯拉把地球作为内导体,地球电离层作为外导体,通过他的放 大发射机,使用这种放大发射机特有的径向电磁波振荡模式,在地球与电离层之间建立起大约 8 赫兹的低频共振,利用环绕地球的表面电磁波来传输能量。

(这个怎么弄呀!整个地球岂不是要变成一个球形的电容器,一次充放电要多大的能量呀!)

  这一系统 与现代无线电广播的能量发射机制不同,而与交流电力网中的交流发电机与输电线的关系类似,当没有电力接收端的时候,发射机只与天地谐振腔交换无功能量,整 个系统只有很少的有功损耗,而如果是一般的无线电广播,发射的能量则全部在空间中损耗掉了。

  特斯拉有生之年没有财力实现这一主张。后人从理论上完全证实了 这种方案的可行性,证明这种方案不仅可行,而且效率极高,对生态安全,并且不会干扰无线电通信。只不过涉及到世界范围内的能量广播和免费获取,在现有的政 治和经济体制下,无人实际问津这种主张。

2007-06-02

xorg配置的一些看法

xorg配置的一些看法
以下是本人的一些看法,如有错误请指正:
--------------------------------------------------------------------------------
关于液晶显示器采用高的刷新频率而不是最佳刷新频率的问题:
如果是液晶显示器的话,很多是有一个显示效果最好的刷新频率,设高了,如果没超出显示器的范围,还是能工作的,但是显示器的显示效果反而不好。
这时候应该在你xorg.conf中有效的那一段Section "Monitor" 中添加或修改VertRefresh设置成VertRefresh (显示器底限) - (最佳频率+0.3到0.5)
因为X进行显示模式匹配的时候,同一分辨率的索引项,是安刷新频率从高到低排列的,也就是说合格的显示模式中,同一分辨率的,高刷新频率的模式会优先采用。
------------------------------------------------------------------------------------
关于X采用的刷新频率高于显示器的实际工作能力的问题:
X是跟据程序中Probe phase (硬件侦测)生成的数据和VertRefresh信息,HorizSync信息设定,进行显示模式索引的建立的。当VertRefres高限过高,或根本没提供VertRefresh信息时,能否正确进行显示模式索引的建立就依赖于Probe phase,Probe phase绝大部分情况下还是能很好工作的,但是程序毕竟不是万能的。就有可能采用的刷新频率高于显示器的实际工作能力。
另外HorizSync也是一个很有用的参数,因为显示器的刷新频率和分辨率是关联的,高分辨率时能工作的刷新频率就低。X就是根据HorizSync计算不同分辨率下的刷新频率的高限的。HorizSync不正确,即使VertRefres正确,也可能导致X在使用较高分辨率时刷新频率过高。
解决办法:(不太适用于不会在文本方式下工作的人)
1.先去掉所有的HorizSync VertSync 配置(Comment all HorizSync and VertSync values to use DDC)
2.1的方法不行的话,就需要收工指定HorizSync VertSync,在没有可靠资料的情况下:
如果是液晶显示器的话:VertRefresh高限设成 (最佳频率+0.3到0.5),一般最佳的是在60或65。 如果是CRT 17寸的话,VertRefresh 高限应该可以设到70。
如果同时装有windows的话,VertRefresh 高限设成你windows正在使用的刷新频率+0.3到0.5,同时Modes设成对应的Windows正在使用的分辨率。
3.2的办法不行的话把显卡驱动模块改成 "vga",去掉所有的HorizSync VertSync 配置,先提供一个图形界面供你上网,然后就google你的显示器型号,应该能找到一些资料吧。
-------------------------------------------------------------------------------------
还有的一些疑问,希望知道的告诉我:
现在还不清楚是xorg.conf中的配置和Probe phase是怎样配合的,有时候发现光靠Probe phase(就是xorg.conf不作配置)X能工作,这时xorg.conf添加了错误配置后反而不能工作,并不是设想的xorg.conf和Probe phase只要有一个能正确进行就能工作。这大概就是为什么有的xorg.conf的配置软件会在xorg.conf写入一行:
### Comment all HorizSync and VertSync values to use DDC:

2007-05-31

Visio,整理思路,交流思想的好工具(1)

任何历史老师或学生都知道,要理解历史事件仅仅靠记住其发生日期是远远不够的。每个历史事件的发生,都有一系列错综复杂的小事件作前导,并最终导致了该历史事件的发生。您可以使用 Visio 因果图来显示这种历史因果关系的循环。

您可以将因果图添加到您的课程安排中,或将它们留作家庭作业,以帮助学生分析特定事件背后的原因。或者,如果您是一名学生,那么可以将因果图放入您的研究论文和其他课外作业中。

什么是因果图?
因果图的发明者 Kaoru Ishikawa 是一名管理专家,其最初的目的是改进车间的质量控制工作。正如以下示例所示,因果图还能表达其他环境中的因果关系。



由于因果图的形状很像鱼的骨架,所以它又称作鱼骨图。鱼的脊骨上几根最大的鱼骨表示主要的原因类别。例如,在本例中,主要的原因类别有盎格鲁人/朱特人、丹麦人、萨克逊人和诺曼底人,这些种族群体都想控制英格兰,从而导致了该战争的爆发。

主要类别中的较小鱼骨表示主要的原因。例如,在本例中,在萨克逊人这个类别方面,黑斯廷斯战争的主要原因在于公元 1051 年萨克逊王爱德华许诺将王位传给威廉一世。

您还可以在主要原因上添加次要原因。

如何创建因果图?
当您打开因果模板后,您会发现因果图的基本骨干已经搭建好。您只需向其中添加类别和名称。

创建因果图
启动 Visio。在“选择绘图类型”窗口中,单击“业务进程”,然后单击“因果图”。
将在绘图页上打开一个因果图,其中已经具备脊骨和类别。

单击脊骨,然后键入事件(或结果)的名称。
确定所需的原因类别数量。
要添加类别,将“类别 1”或“类别 2”形状拖到绘图页上放好,使箭头接触到脊骨。
要删除类别,单击它,然后按 Delete 键。
单击每个类别形状,并键入原因类别的名称。
对于每个类别,确定所需的主要原因数量。对于每个主要原因,执行以下操作:
将“主要原因”形状拖到绘图页,并将箭头与类别线对齐。
单击每个主要原因形状,并键入原因的说明。
如果您要在某些主要原因中添加次要原因,请执行以下操作:
将“次要原因”形状拖到绘图页上,并将箭头与主要原因线对齐。
单击每个次要原因形状,并键入原因的说明。
保存并命名该因果图。

2007-05-30

访问控制技术 IP ACL

技术从来都是一把双刃剑,网络应用与互联网的普及在大幅提高企业的生产经营效率的同时,也带来了诸如数据的安全性,员工利用互联网做与工作不相干事等负面影响。如何将一个网络有效的管理起来,尽可能的降低网络所带来的负面影响就成了摆在网络管理员面前的一个重要课题。



  A公司的某位可怜的网管目前就面临了一堆这样的问题。A公司建设了一个企业网,并通过一台路由器接入到互联网。在网络核心使用一台基于IOS的多层交换机,所有的二层交换机也为可管理的基于IOS的交换机,在公司内部使用了VLAN技术,按照功能的不同分为了6个VLAN。分别是网络设备与网管(VLAN1,10.1.1.0/24)、内部服务器(VLAN2)、Internet连接(VLAN3)、财务部(VLAN4)、市场部(VLAN5)、研发部门(VLAN6),出口路由器上Fa0/0接公司内部网,通过s0/0连接到Internet。每个网段的三层设备(也就是客户机上的缺省网关)地址都从高位向下分配,所有的其它节点地址均从低位向上分配。该网络的拓朴如下图所示:

自从网络建成后麻烦就一直没断过,一会儿有人试图登录网络设备要捣乱;一会儿领导又在抱怨说互联网开通后,员工成天就知道泡网;一会儿财务的人又说研发部门的员工看了不该看的数据。这些抱怨都找这位可怜的网管,搞得他头都大了。那有什么办法能够解决这些问题呢?答案就是使用网络层的访问限制控制技术――访问控制列表(下文简称ACL)。

那么,什么是ACL呢?ACL是种什么样的技术,它能做什么,又存在一些什么样的局限性呢?

ACL的基本原理、功能与局限性

  网络中常说的ACL是Cisco IOS所提供的一种访问控制技术,初期仅在路由器上支持,近些年来已经扩展到三层交换机,部分最新的二层交换机如2950之类也开始提供ACL的支持。只不过支持的特性不是那么完善而已。在其它厂商的路由器或多层交换机上也提供类似的技术,不过名称和配置方式都可能有细微的差别。本文所有的配置实例均基于Cisco IOS的ACL进行编写。

基本原理:ACL使用包过滤技术,在路由器上读取第三层及第四层包头中的信息如源地址、目的地址、源端口、目的端口等,根据预先定义好的规则对包进行过滤,从而达到访问控制的目的。

功能:网络中的节点资源节点和用户节点两大类,其中资源节点提供服务或数据,用户节点访问资源节点所提供的服务与数据。ACL的主要功能就是一方面保护资源节点,阻止非法用户对资源节点的访问,另一方面限制特定的用户节点所能具备的访问权限。

配置ACL的基本原则:在实施ACL的过程中,应当遵循如下两个基本原则:

u 最小特权原则:只给受控对象完成任务所必须的最小的权限

u 最靠近受控对象原则:所有的网络层访问权限控制

局限性:由于ACL是使用包过滤技术来实现的,过滤的依据又仅仅只是第三层和第四层包头中的部分信息,这种技术具有一些固有的局限性,如无法识别到具体的人,无法识别到应用内部的权限级别等。因此,要达到end to end的权限控制目的,需要和系统级及应用级的访问权限控制结合使用。

ACL配置技术详解

“说那么多废话做什么,赶快开始进行配置吧。”,A公司的网管说。呵呵,并不是我想说那么多废话,因为理解这些基础的概念与简单的原理对后续的配置和排错都是相当有用的。说说看,你的第一个需求是什么。

“做为一个网管,我不期望普通用户能telnet到网络设备”――ACL基础

“补充一点,要求能够从我现在的机器(研发VLAN的10.1.6.66)上telnet到网络设备上去。”。hamm,是个不错的主意,谁都不希望有人在自己的花园中撤野。让我们分析一下,在A公司的网络中,除出口路由器外,其它所有的网络设备段的是放在Vlan1中,那个我只需要在到VLAN 1的路由器接口上配置只允许源地址为10.1.6.66的包通过,其它的包通通过滤掉。这中只管源IP地址的ACL就叫做

标准IP ACL:

我们在SWA上进行如下的配置:

access-list 1 permit host 10.1.6.66

access-list 1 deny any

int vlan 1

ip access-group 1 out

这几条命令中的相应关键字的意义如下:

access-list:配置均ACL的关键字,所有的ACL均使用这个命令进行配置。

access-list后面的1:ACL号,ACL号相同的所有ACL形成一个组。在判断一个包时,使用同一组中的条目从上到下逐一进行判断,一遇到满足的条目就终止对该包的判断。1-99为标准的IP ACL号,标准IP ACL由于只读取IP包头的源地址部分,消耗资源少。

permit/deny:操作。Permit是允许通过,deny是丢弃包。

host 10.1.6.66/any:匹配条件,等同于10.1.6.66 0.0.0.0。刚才说过,标准的ACL只限制源地址。Host 10.1.6.66(10.1.6.66 0.0.0.0)的意思是只匹配源地址为10.1.6.66的包。0.0.0.0是wildcards,某位的wildcards为0表示IP地址的对应位必须符合,为1表示IP地址的对应位不管是什么都行。简单点说,就是255.255.255.255减去子网掩码后的值,0.0.0.0的wildcards就是意味着IP地址必须符合10.1.6.66,可以简称为host 10.1.6.66。any表示匹配所有地址。

注意:IOS中的ACL均使用wildcards,并且会用wildcards对IP地址进行严格的对齐,如你输入一条access-list 1 permit 10.1.1.129 0.0.0.31,在你show access-list看时,会变成access-list 1 permit 10.1.1.128 0.0.0.31,PIXOS中的ACL均使用subnet masks,并且不会进行对齐操作。更为详细的关于IP V4地址的资料可以参见拙著《IP v4基础知识》http://www.ultratechnology.net/showarticle.php?s=&articleid=60 一文

int vlan1///ip access-group 1 out:这两句将access-list 1应用到vlan1接口的out方向。其中1是ACL号,和相应的ACL进行关联。Out是对路由器该接口上哪个方向的包进行过滤,可以有in和out两种选择。

注意:这里的in/out都是站在路由器或三层模块(以后简称R)上看的,in表示从该接口进入R的包,out表示从该接口出去的包。

好了,这就是一个最基本的ACL的配置方法。什么,你说普通用户还能telnet到RTA?那你在int vlan3上现加一个ip access-group 1 out吧。Hammmm,等等,你这样加上去普通用户就访问不了internet了。让我们把刚才的ACL去掉,重新写一个。

回忆一下,我们的目的是除了10.1.6.66能够进行telnet操作外,其它用户都不允许进行telnet操作。刚才我们说过,标准的IP ACL只能控制源IP地址,不能控制到端口。要控制到第四层的端口,就需要使用到:

扩展的IP ACL的配置

先看看配置实例吧。在SWA上进行如下配置:

int vlan 1

no ip access-group 1 out

exit

no access-list 1

access-list 101 permit tcp host 10.1.6.66 any eq telnet

access-list 101 deny tcp any any eq telnet

int vlan 1

ip access-group 101 out

int vlan 3

ip access-group 101 out

你应该注意到到这里的ACL有一些变化了,现在对变化的部分做一些说明:

access-list 101:注意这里的101,和刚才的标准ACL中的1一样,101是ACL号,表示这是一个扩展的IP ACL。扩展的IP ACL号范围是100-199,扩展的IP ACL可以控制源IP、目的IP、源端口、目的端口等,能实现相当精细的控制,扩展ACL不仅读取IP包头的源地址/目的地址,还要读取第四层包头中的源端口和目的端口,的IP在没有硬件ACL加速情况下,会消耗大量的CPU资源。

int vlan 1///no ip access-group 1 out///exit///no access-list 1:取消access-list 1,对于非命名的ACL,可以只需要这一句就可以全部取消。注意,在取消或修改一个ACL前,必须先在它所应用的接口上先把应用给no掉,否则会导致相当严重的后果。

tcp host 10.1.6.66 any eq telnet:匹配条件。完整格式为:协议 源地址 源wildcards [关系] [源端口] 目的地址 目的wildcards [关系] [目的端口]。其中协议可以是IP、TCP、UDP、EIGRP等,[]内为可选字段。仅在协议为tcp/udp等具备端口号的协议才有用。关系可以是eq(等于)、neq(不等于)、lt(大于)、range(范围)等。端口一般为数字的1-65535,对于周知端口,如23(服务名为telnet)等可以用服务名代替。源端口和目的端口不定义时表示所有端口。

把这个ACL应用上去后,用户们开始打电话来骂娘了,因为他们都访问不了Internet了,是哪里出了问题了呢?

注意:所有的ACL,缺省情况下,从安全角度考虑,最后都会隐含一句deny any(标准ACL)或deny ip any any(扩展IP ACL)。所以在不了解业务会使用到哪些端口的情况下,最好在ACL的最后加上一句permit ip any any,在这里就是access-list 101 permit ip any any。

现在用户倒是能够访问Internet了,但我们的可怜的网管却发现普通用户还是能够telnet到他的SWA上面,因为SWA上面有很多个网络接口,而且使用扩展的ACL会消耗很多的资源。有什么简单的办法能够控制用户对网络设备的Telnet访问,而又不消耗太多的资源呢?这就需要使用到:

对网络设备自身的访问如何进行控制的技术

让我们先把刚才配置的ACL都取掉(具体配置略,不然后读者会以为我在骗稿费了。),再在每台网络设备上均进行如下配置:

access-list 1 permit host 10.1.6.66

line vty 0 4(部分设备是15)

access-class 1 in

这样就行了,telnet都是访问的设备上的line vty,在line vty下面使用access-class与ACL组进行关联,in关键字表示控制进入的连接。

就这么简单?wk,你丫是不是在玩我们,为什么还要绕一大圈?臭鸡蛋和烂西红柿开始在70的脑袋上方狂飞。(5555555,偶也只是想向大家把ACL的基础知识讲的明白一些的嘛)。经过刚才的配置,我们可以理出一个简单的ACL配置步骤了:

u 分析需求,找清楚需求中要保护什么或控制什么;为方便配置,最好能以表格形式列出。在本文的后面会举例的。

u 分析符合条件的数据流的路径,寻找一个最适合进行控制的位置;

u 书写ACL,并将ACL应用到接口上;

u 测试并修改ACL。

当A公司的领导知道在网管能够控制普通用户对网络设备的访问后,我们的可怜的网管就收到了很多看起来很难的要求。领导要求网管:
“使用ACL技术对网络访问进行精细化控制”――ACL进阶配置

命名的IP ACL

由于最近服务器网段的机器老是被人用telnet、rsh等手段进行攻击,我们只对员工开放web服务器(10.1.2.20)所提供的http、FTP服务器(10.1.2.22)提供的FTP服务和数据库服务器(10.1.2.21:1521)。好吧,我们着手进行配置,可是我们的ACL刚写到一半,发现前面写的几句好像有问题,一个no命令输进去,整个ACL都没了,唉,一切都得重来,难道就没有一个变通的办法么?有,这里我就需要用到:

命名的IP acl提供的两个主要优点是:

l 解决ACL号码不足的问题。

l 可以自由的删除ACL中的一条语句,而不必删除整个ACL。

命名的ACL的主要不足之处在于无法实现在任意位置加入新的ACL条目。比如上面那个例子中,我们进行了如下的配置:

ip access-list extend server-protect

permit tcp 10.1.0.0 0.0.255.255 host 10.1.2.20 eq www

permit tcp 10.0.0.0 0.0.255.255 host 10.1.2.21 eq 1521

permit tcp 10.1.0.0 0.0.255.255 host 10.1.2.22 eq ftp

配置到这里,我们发现permit tcp 10.0.0.0 0.0.255.255 host 10.1.2.21 eq 1521这句配错了,我们得把它给取掉并重新配置,OK,我样可以简单的进行如下配置:

ip access-list extend server- protect

no permit tcp 10.0.0.0 0.0.255.255 host 10.1.2.21 eq 1521

permit tcp 10.1.0.0 0.0.0.255 host 10.1.2.21 eq 1521

exit

int vlan 2

ip access-group server- protect

就可以了。现在对命名的IP access-list的配置方法解释如下:

ip access-list extend server-access-limit:ip access-list相当于使用编号的access-list中的access-list段。extend表明是扩展的ACL(对应地,standard表示标准的ACL)。server-access-limit是access-list的名字,相当于基于编号的ACL中的编号字段。

permit tcp 10.1.6.0 0.0.0.255 host 10.1.2.21 eq 1521:这一段和使用编号的access-list的后半段的意义相同,都由操作和条件两段组成。

其实基于名字的IP ACL还有一个很好的优点就是可以为每个ACL取一个有意义的名字,便于日后的管理与维护。所以Ultra工作室强烈建议各位看官在实际工作中均使用命名的ACL。

进一步完善对服务器数据的保护――ACL执行顺序再探讨

在服务器网段中的数据库服务器中存放有大量的市场信息,市场部门的人员不希望研发部门访问到数据库服务器,经过协商,同意研发部门的领导的机器(IP地址为10.1.6.33)可以访问到数据库服务器。这样,我们的服务器网段的的访问权限部分如下表所示:

协议
源地址
源端口
目的地址
目的端口
操作

TCP
10.1/16
所有
10.1.2.20/32
80
允许访问

TCP
10.1/16
所有
10.1.2.22/32
21
允许访问

TCP
10.1/16
所有
10.1.2.21/32
1521
允许访问

TCP
10.1.6/24
所有
10.1.2.21/32
1521
禁止访问

TCP
10.1.6.33/32
所有
10.1.2.21/32
1521
允许访问

IP
10.1/16
N/A
所有
N/A
禁止访问


于是,网管就在server-protect后面顺序加了两条语句进去,整个ACL变成了如下形式:
ip access-list extend server-protect

permit tcp 10.1.0.0 0.0.255.255 host 10.1.2.20 eq www

permit tcp 10.1.0.0 0.0.255.255 host 10.1.2.21 eq 1521

permit tcp 10.1.0.0 0.0.255.255 host 10.1.2.22 eq ftp

deny tcp 10.1.6.0 0.0.0.255 host 10.1.2.21 eq 1521

permit tcp host 10.1.6.33 host 10.1.2.21 eq 1521

做完之后发现根本没起到应有的作用,研发部门的所有机器还是可以访问到数据库服务器。这是为什么呢?

前面我们提到过,ACL的执行顺序是从上往下执行,一个包只要遇到一条匹配的ACL语句后就会停止后续语句的执行,在我们的这个ACL中,因为前面已经有了一条permit tcp 10.1.0.0 0.0.255.255 host 10.1.2.21 eq 1521语句。内部网上所有访问10.1.2.21的1521端口的在这儿就全部通过了,跟本不会到后面两句去比较。所以导致达不到我们的目的。应该把server-protect这个ACL按如下形式进行修改才能满足我们的要求:
ip access-list extend server-protect

permit tcp host 10.1.6.33 host 10.1.2.21 eq 1521

deny tcp 10.1.6.0 0.0.0.255 host 10.1.2.21 eq 1521

permit tcp 10.1.0.0 0.0.255.255 host 10.1.2.21 eq 1521

permit tcp 10.1.0.0 0.0.255.255 host 10.1.2.20 eq www

permit tcp 10.1.0.0 0.0.255.255 host 10.1.2.22 eq ftp

这个例子告诉我们在写ACL时,一定要遵循最为精确匹配的ACL语句一定要写在最前面的原则,只有这样才能保证不会出现无用的ACL语句。
基于时间的ACL

在保证了服务器的数据安全性后,领导又准备对内部员工上网进行控制。要求在上班时间内(9:00-18:00)禁止内部员工浏览internet,禁止使用QQ、MSN。而且在2003年6月1号到2号的所有时间内都不允许进行上述操作。但在任何时间都可以允许以其它方式访问Internet。天哪,这可叫人怎么活呀,但领导既然这样安排,也只好按指示做了。

首先,让我们来分析一下这个需求,浏览internet现在基本上都是使用http或https进行访问,标准端口是TCP/80端口和TCP/443,MSN使用TCP/1863端口,QQ登录会使用到TCP/UDP8000这两个端口,还有可能使用到udp/4000进行通讯。而且这些软件都能支持代理服务器,目前的代理服务器主要布署在TCP 8080、TCP 3128(HTTP代理)和TCP1080(socks)这三个端口上。这个需求如下表所示:

应用
协议
源地址
源端口
目的地址
目的端口
操作

IE
TCP
10.1/16
所有
所有
80
限制访问

IE
TCP
10.1/16
所有
所有
443
限制访问

MSN
TCP
10.1/16
所有
所有
1863
限制访问

QQ
TCP
10.1/16
所有
所有
8000
限制访问

QQ
UDP
10.1/16
所有
所有
8000
限制访问

QQ
UDP
10.1/16
所有
所有
4000
限制访问

HTTP代理
TCP
10.1/16
所有
所有
8080
限制访问

HTTP代理
TCP
10.1/16
所有
所有
3128
限制访问

Socks
TCP
10.1/16
所有
所有
1080
限制访问

All other
IP
10.1/16
N/A
所有
N/A
允许访问


然后,让我们看看ACL应该在哪个位置配置比较好呢?由于是对访问Internet进行控制,涉及到的是公司内部所有的网段,这们这次把ACL就放到公司的Internet出口处。在RTA上进行如下的配置,就能够满足领导的要求了:

time-range TR1

absolute start 00:00 1 June 2003 end 00:00 3 June 2003

periodic weekdays start 9:00 18:00

exit

ip access-list extend internet_limit

deny tcp 10.1.0.0 0.0.255.255 any eq 80 time-range TR1

deny tcp 10.1.0.0 0.0.255.255 any eq 443 time-range TR1

deny tcp 10.1.0.0 0.0.255.255 any eq 1863 time-range TR1

deny tcp 10.1.0.0 0.0.255.255 any eq 8000 time-range TR1

deny udp 10.1.0.0 0.0.255.255 any eq 8000 time-range TR1

deny udp 10.1.0.0 0.0.255.255 any eq 4000 time-range TR1

deny tcp 10.1.0.0 0.0.255.255 any eq 3128 time-range TR1

deny tcp 10.1.0.0 0.0.255.255 any eq 8080 time-range TR1

deny tcp 10.1.0.0 0.0.255.255 any eq 1080 time-range TR1

permit ip any any

int s0/0

ip access-group internet_limit out

或int fa0/0

ip access-group internet_limit in

或者将ACL配置在SWA上,并

int vlan 3

ip access-group internet_limit out

呵呵,现在让我们来看看在基于时间的访问列表中都有哪些新内容吧:

time-range TR1:定义一个新的时间范围,其中的TR1是为该时间范围取的一个名字。

absolute:为绝对时间。只使用一次。可以定义为1993-2035年内的任意一个时点。具体的用法请使用?命令查看。

Periodic:为周期性重复使用的时间范围的定义。完整格式为periodic 日期关键字 开始时间 结束时间。其中日期关键字的定义如下所示:

Monday 星期一

Tuesday 星期二

Wednesday 星期三

Thursday 星期四

Friday 星期五

Saturday 星期六

Sunday 星期天

daily 每天

weekdays 周一至五

weekend 周末

access-list 101 deny ip 10.1.0.0 0.0.255.255 any time-range TR1:注意这一句最后的time-range TR1,使这条ACL语句与time-range TR1相关联,表明这条语句在time-range TR1所定义的时间范围内才起作用。

注意:给出三种配置位置是帮助大家深刻理解关于in/out的区别的。acl是对从一个接上流入(in)或流出(out)路由器的包进行过滤的。

网管发问了,“你是怎么找到这些应用的所使用的端口的?”。呵呵,在如下文件中可以找到大多数应用的端口的定义:

Win9x:%windir%services

WinNT/2000/XP:%windir%system32driversetcservices

Linux:/etc/services

对于在services文件中找不到端口的应用,可以在运行程序的前后,运行netstat –ap来找出应用所使用的端口号。
使用IP ACL实现单向访问控制

A公司准备实行薪资的不透明化管理,由于目前的薪资收入数据还放在财务部门的Vlan中,所以公司不希望市场和研发部门能访问到财务部Vlan中的数据,另一方面,财务部门做为公司的核心管理部门,又希望能访问到市场和研发部门Vlan内的数据。我们的网管在接到这个需求后就在SWA上做了如下的配置:

ip access-list extend fi-access-limit

deny ip any 10.1.4.0 0.0.0.255

permit ip any any

int vlan 5

ip access-group fi-access-limit in

int vlan 6

ip access-group fi-access-limit in

配置做完后,测试了一下,市场和研发部门确实访问不到财务部了,刚准备休息一下,财务部打电话过来说为访问不到市场与研发部门的数据了。这是怎么回事呢?

让我们回忆一下,在两台主机A与B之间要实现通讯,需要些什么条件呢?答案是既需要A能向B发包,也需要B能向A发包,任何一个方向的包被阻断,通讯都不能成功,在我们的例子中就存在这样的问题,财务部访问市场或研发部门时,包到到市场或研发部门的主机,由这些主机返回的包在到达路由器SWA时,由于普通的ACL均不具备检测会话状态的能力,就被deny ip any 10.1.4.0 0.0.0.255这条ACL给阻断了,所以访问不能成功。

要想实现真正意义上的单向访问控制应该怎么办呢?我们希望在财务部门访问市场和研发部门时,能在市场和研发部门的ACL中临时生成一个反向的ACL条目,这样就能实现单向访问了。这里就需要使用到反向ACL技术。我们可以按照如下配置实例就可以满足刚才的那个单向访问需求:

ip access-list extend fi-main

permit tcp any 10.1.0.0 0.0.255.255 reflect r-main timeout 120

permit udp any 10.1.0.0 0.0.255.255 reflect r-main timeout 200

permit icmp any 10.1.0.0 0.0.255.255 reflect r-main timeout 10

permit ip any any

int vlan 4

ip access-group fi-main in

ip access-list extend fi-access-limit

evaluate r-main

deny ip any 10.1.4.0 0.0.0.255

permit ip any any

int vlan 5

ip access-group fi-access-limit in

int vlan 6

ip access-group fi-access-limit in

现在对反向ACL新增加的内容一一解释如下:

n 新增了一个ACL(fi-main)并应用在具备访问权限的接口下(财务部所在的vlan4)的in方向,使用该acl中具备reflect关键字的acl条目来捕捉建立反向ACL条目所需要的信息。我们将该ACL称为主ACL。

n reflect r-main timeout xxx:其中的reflect关键字表明该条目可以用于捕捉建立反向的ACL条目所需要的信息。r-main是reflect组的名字,具备相同reflect组名字的所有的ACL条目为一个reflect组。timeout xxx表明由这条ACL条目所建立起来的反向ACL条目在没有流量的情况下,多长时间后会消失(缺省值为300秒),单位为秒。

n evaluate r-main:我们注意到在fi-access-limit(我们把它称为反ACL)增加了这样一句,这一句的意思是有符合r-main这个reflect组中所定义的acl条目的流量发生时,在evaluate语句所在的当前位置动态生成一条反向的permit语句。

反向ACL的局限性:

n 必须使用命名的ACL,其实这不能叫局限性,应该算注意事项吧;

n 对多通道应用程序如h323之类无法提供支持。

好了,到现在我们从IP ACL的基础知识讲起,中间讲述了标准的IP ACL、扩展的IP ACL、基于名字的ACL、基于时间的ACL、反向ACL等诸多内容,这些ACL在ios的基本IP特性集中都能提供支持,在一般的企业网或校园网中也应该完全够用了。如果各位看官还需要了解更加深入的知识,如CBAC之类能够为多通道应用程序提供良好支持的配置技术的,请参考《Cisco IOS Security Configuration Guide,Part 3: Traffic Filtering and Firewalls》。

“站住!”,70正想开溜,只听那网管一声大吼,“有什么办法能知道ACL都过滤了从哪儿来,到哪儿去的流量??”。呵呵,刚才忘记说了,你只需要在需要记录的acl条目的最后加一个log关键字,这样在有符合该ACL条目数据包时,就会产生一条日志信息发到你的设备所定义的日志服务器上去。谢谢大家的捧场,本文到此为止。