有时候,当我孤独地坐着等待生命大门关闭时,一种与世隔绝的感觉就会像冷雾一样笼罩着我。远处有光明、音乐和友谊,但我进不去,命运之神无情地挡住了大门。我真想义正词严地提出抗议,因为我的心仍然充满了热情。但是那些酸楚而无益的话语流溢在唇边,欲言又止,犹如泪水往肚里流,沉默浸透了我的灵魂。然后,希望之神微笑着走来对我轻轻耳语说:“忘我就是快乐。”因而我要把别人眼睛所看见的光明当作我的太阳,别人耳朵所听见的音乐当作我的乐曲,别人嘴角的微笑当作我的快乐。

发布新日志

  • 转载:冒泡排序

    2009-08-28 16:40:10

    交换排序的基本思想是:两两比较待排序记录的关键字,发现两个记录的次序相反时即进行交换,直到没有反序的记录为止。
         应用交换排序基本思想的主要排序方法有:冒泡排序和快速排序。

    冒泡排序

    1、排序方法
         将被排序的记录数组R[1..n]垂直排列,每个记录R[i]看作是重量为R[i].key的气泡。根据轻气泡不能在重气泡之下的原则,从下往上扫描数组R:凡扫描到违反本原则的轻气泡,就使其向上"飘浮"。如此反复进行,直到最后任何两个气泡都是轻者在上,重者在下为止。
    (1)初始
         R[1..n]为无序区。

    (2)第一趟扫描
         从无序区底部向上依次比较相邻的两个气泡的重量,若发现轻者在下、重者在上,则交换二者的位置。即依次比较(R[n],R[n-1]),(R[n-1],R[n-2]),…,(R[2],R[1]);对于每对气泡(R[j+1],R[j]),若R[j+1].key<R[j].key,则交换R[j+1]和R[j]的内容。
         第一趟扫描完毕时,"最轻"的气泡就飘浮到该区间的顶部,即关键字最小的记录被放在最高位置R[1]上。

    (3)第二趟扫描

         扫描R[2..n]。扫描完毕时,"次轻"的气泡飘浮到R[2]的位置上……
         最后,经过n-1 趟扫描可得到有序区R[1..n]
      注意:
         第i趟扫描时,R[1..i-1]和R[i..n]分别为当前的有序区和无序区。扫描仍是从无序区底部向上直至该区顶部。扫描完毕时,该区中最轻气泡飘浮到顶部位置R[i]上,结果是R[1..i]变为新的有序区。
    排序算法
    (1)分析
         因为每一趟排序都使有序区增加了一个气泡,在经过n-1趟排序之后,有序区中就有n-1个气泡,而无序区中气泡的重量总是大于等于有序区中气泡的重量,所以整个冒泡排序过程至多需要进行n-1趟排序。
         若在某一趟排序中未发现气泡位置的交换,则说明待排序的无序区中所有气泡均满足轻者在上,重者在下的原则,因此,冒泡排序过程可在此趟排序后终止。为此,在下面给出的算法中,引入一个布尔量exchange,在每趟排序开始前,先将其置为FALSE。若排序过程中发生了交换,则将其置为TRUE。各趟排序结束时检查exchange,若未曾发生过交换则终止算法,不再进行下一趟排序。

    (2)具体算法

      void BubbleSort(SeqList R)
       { //R(l..n)是待排序的文件,采用自下向上扫描,对R做冒泡排序
         int i,j;
         Boolean exchange; //交换标志
         for(i=1;i<n;i++){ //最多做n-1趟排序
           exchange=FALSE; //本趟排序开始前,交换标志应为假
           for(j=n-1;j>=i;j--) //对当前无序区R[i..n]自下向上扫描
            if(R[j+1].key<R[j].key){//交换记录
              R[0]=R[j+1]; //R[0]不是哨兵,仅做暂存单元
              R[j+1]=R[j];
              R[j]=R[0];
              exchange=TRUE; //发生了交换,故将交换标志置为真
             }
           if(!exchange) //本趟排序未发生交换,提前终止算法
                 return;
         } //endfor(外循环)
        } //BubbleSort
  • ssh总结

    2009-08-18 15:32:00

    SSH是英文Secure Shell的简写形式。通过使用SSH,你可以把所有传输的数据进行加密,这样"中间人"这种攻击方式就不可能实现了,而且也能够防止DNS欺骗和IP欺骗。使用SSH,还有一个额外的好处就是传输的数据是经过压缩的,所以可以加快传输的速度。SSH有很多功能,它既可以代替Telnet,又可以为FTP、Pop、甚至为PPP提供一个安全的"通道"。

      很多情况是由于服务器提供了Telnet服务引起的。的确,对于UNIX系统,如果要远程管理它,必定要使用远程终端,而要使用远程终端,自然要在服务器上启动Telnet服务。但是Telnet服务有一个致命的弱点——它以明文的方式传输用户名及口令,所以,很容易被别有用心的人窃取口令。

     

     

    所谓“中间人”的攻击方式,就是“中间人”冒充真正的服务器接收你传给服务器的数据,然后再冒充你把数据传给真正的服务器。服务器和你之间的数据传送被“中间人”转手后做了手脚之后,就会出现很严重的问题。

    定义: DNS欺骗就是攻击者冒充域名服务器的一种欺骗行为。

    原理:如果可以冒充域名服务器,然后把查询的IP地址设为攻击者的IP地址,这样的话,用户上网就只能看到攻击者的主页,而不是用户想要取得的网站的主页了,这就是DNS欺骗的基本原理。DNS欺骗其实并不是真的“黑掉”了对方的网站,而是冒名顶替、招摇撞骗罢了。

    ip欺骗是基于IP地址的。第一步需要IP地址。而SSH传输的信息是加密的,不能被识别,所以无从下手。

    什么是IP spoof?  

    IP欺骗由若干步骤组成,这里先简要地描述一下,随后再做详尽 地解释。先做以下假定:首先,目标主机已经选定。其次,信任模式 已被发现,并找到了一个被目标主机信任的主机。黑客为了进行IP欺 骗,进行以下工作:使得被信任的主机丧失工作能力,同时采样目标 主机发出的TCP 序列号,猜测出它的数据序列号。然后,伪装成 被信任的主机,同时建立起与目标主机基于地址验证的应用连接。如 果成功,黑客可以使用一种简单的命令放置一个系统后门,以进行非 授权操作。

             IP spoof即IP 电子欺骗,我们可以说是一台主机设备冒充另外一台主机的IP地址,与其它设备通信,从而达到某种目的技术。
     

    IP是网络层的一个非面向连接的协议, IP数据包的主要内容由源IP地址,目地IP地址,所传数据构成, 
          IP的任务就是根据每个数据报文的目的地址,路由完成报文从源地址到目的地址的传送。至于报文在传送过程中是否丢失或出现差错, 
          IP不会考虑。对IP来讲,源设备与目的设备没有什么关系,它们是相互独立的。IP包只是根据数据报文中的目的地址发送,因此借助高层协议的应用程序来伪造IP地址是比较容易实现的。  
     

    2、SSH协议的内容
      
        SSH协议是建立在应用层和传输层基础上的安全协议,它主要由以下三部分组成,共同实现SSH的安全保密机制。
        传输层协议,它提供诸如认证、信任和完整性检验等安全措施,此外它还可以任意地提供数据压缩功能。通常情况下,这些传输层协议都建立在面向连接的TCP数据流之上。
        用户认证协议层,用来实现服务器的跟客户端用户之间的身份认证,它运行在传输层协议之上。
        连接协议层,分配多个加密通道至一些逻辑通道上,它运行在用户认证层协议之上。
        
        当安全的传输层连接建立之后,客户端将发送一个服务请求。当用户认证层连接建立之后将发送第二个服务请求。这就允许新定义的协议可以和以前的协议共存。连接协议提供可用作多种目的通道,为设置安全交互Shell会话和传输任意的TCP/IP端口和X11连接提供标准方法。
      
      
      
      3、SSH的安全验证
      
        从客户端来看,SSH提供两种级别的安全验证。
        
        第一种级别(基于口令的安全验证),只要你知道自己的帐号和口令,就可以登录到远程主机,并且所有传输的数据都会被加密。但是,这种验证方式不能保证你正在连接的服务器就是你想连接的服务器。可能会有别的服务器在冒充真正的服务器,也就是受到"中间人"这种攻击方式的攻击。
        
        第二种级别(基于密匙的安全验证),需要依靠密匙,也就是你必须为自己创建一对密匙,并把公有密匙放在需要访问的服务器上。如果你要连接到SSH服务器上,客户端软件就会向服务器发出请求,请求用你的密匙进行安全验证。服务器收到请求之后,先在你在该服务器的用户根目录下寻找你的公有密匙,然后把它和你发送过来的公有密匙进行比较。如果两个密匙一致,服务器就用公有密匙加密"质询"(challenge)并把它发送给客户端软件。客户端软件收到"质询"之后就可以用你的私人密匙解密再把它发送给服务器。
        与第一种级别相比,第二种级别不需要在网络上传送用户口令。另外,第二种级别不仅加密所有传送的数据,而"中间人"这种攻击方式也是不可能的(因为他没有你的私人密匙)。但是整个登录的过程可能慢一些。
      
      
      
      4、SSH的应用
      
        首先,SSH最常见的应用就是,用它来取代传统的Telnet、FTP等网络应用程序,通过SSH登录到远方机器执行你想进行的工作与命令。在不安全的网路通讯环境中,它提供了很强的验证(authentication)机制与非常安全的通讯环境。实际上,SSH开发者的原意是设计它来取代原UNIX系统上的rcp、rlogin、rsh等指令程序的;但经过适当包装后,发现它在功能上完全可以取代传统的Telnet、FTP等应用程序。
        传统 BSD 风格的 r 系列指令(如 rcp,rsh,rlogin)往往都被视为不安全的,很容易就被各种网络攻击手段所破解,几乎所有找得到有关UNIX安全的书或文件,都会一而再、再而三地警告系统管理者,留心r系列指令的设定,甚至要求系统管理者将r系列指令通通关闭。
        而用来替代r系列指令的SSH,则在安全方面做了极大的强化,不但对通讯内容可以进行极为安全的加密保护,同时也强化了对身份验证的安全机制,它应用了在密码学(Cryptography)中已发展出来的数种安全加密机制,如 Symmetric Key Cryptography,Asymmetric Key Cryptography, One-way Hash Function,Random-number Generation等,来加强对于身份验证与通讯内容的安全保护。通讯时资料的加密有IDEA,three-key triple DES,DES,RC4-128,TSS,Blowfish 等数种多种安全加密算法可供选择,加密的key则是通过 RSA 进行交换的。资料的加密可以对抗IP spoofing,RSA这种非对称性的加密机制则可用来对抗DNS spoofing与IP routing spoofing,同时RSA也可以进行对主机身份的验证。
        其次,通过使用用SSH可以在本地主机和远程服务器之间设置"加密通道",并且这样设置的"加密通道"可以跟常见的Pop应用程序、X应用程序、Linuxconf应用程序相结合,提供安全保障。
        SSH的"加密通道"是通过"端口转发"来实现的。你可以在本地端口(没有用到的)和在远程服务器上运行的某个服务的端口之间建立"加密通道"。然后只要连接到本地端口。所有对本地端口的请求都被SSH加密并且转发到远程服务器的端口。当然只有远程服务器上运行SSH服务器软件的时候"加密通道"才能工作。

    配置思路:

    super password level 3 simple super

    #

     local-user adm password simple adm

     local-user adm service-type ssh

     local-user adm level 0

    #

    rsa peer-public-key p1

      public-key-code begin

       308186

         028180

           91ADC5A6 7C855676 2958E6E9 960559D6 3F606C86 5BE1C74C EA313F81 BAC7437D

           297A422C 8A0D9C9E AAC8276D E0DC21B9 DCA937C2 846AFFDF 987AEFE1 6204CC63

           0C881FC1 7848297C 82B0B443 5EEDA260 27A7B744 3280B68E 84194DCD 78D89B9E

           35EF76C2 B382A538 80DBBA80 60219F04 E5034168 60EEC72A 53598B6F FB3A5365

         0201

           25                                

      public-key-code end

     peer-public-key end

    #

    rsa local-key-pair create

    #

    ssh user adm assign rsa-key p1

    ssh user adm authentication-type rsa

    #

    user-interface vty 0 4

      authentication-mode local

    protocol inbound ssh

    创建SSH用户,并配置权限:

    local-user huawei service-type administrator ssh password simple 3com

    local-user adm service-type operator ssh password simple adm

    # 设置系统所支持的远程登录协议SSH及最大连接数5[0-5可选,并可选择附加acl规则]

        protocol inbound ssh 5

    # 产生本地RSA密钥对,但是disp current-configuration此命令是不显示的。

    rsa local-key-pair create

    # 进入公共密钥视图,配置客户端产生的公钥,p1是名字,可以任意指定,密钥产生见下章

    # 配置的顺序一定不能颠倒,此处的密钥是采用ssh 软件的公钥生成的对应密钥,将内容粘贴后即可。

      rsa peer-public-key p1

        public-key-code begin

         hex 308186

           hex 028180

             hex 91ADC5A6 7C855676 2958E6E9 960559D6 3F606C86 5BE1C74C EA313F81

             hex BAC7437D 297A422C 8A0D9C9E AAC8276D E0DC21B9 DCA937C2 846AFFDF

             hex 987AEFE1 6204CC63 0C881FC1 7848297C 82B0B443 5EEDA260 27A7B744

             hex 3280B68E 84194DCD 78D89B9E 35EF76C2 B382A538 80DBBA80 60219F04

             hex E5034168 60EEC72A 53598B6F FB3A5365

           hex 0201

             hex 25

        public-key-code end

    配置SSH用户的验证方式为RSA方式,all同时包含了RSA和password方式

       ssh user adm authentication-type rsa

       ssh user huawei authentication-type all

    #AAA需要打开

     aaa-enable

    Quidway] user-interface vty 0 4

    [Quidway-ui-vty0-4] authentication-mode scheme

    [Quidway-ui-vty0-4] protocol inbound ssh

    [Quidway] local-user client001

    [Quidway-luser-client001] password simple huawei

    [Quidway-luser-client001] service-type ssh

    [Quidway] ssh user client001 authentication-type password

  • dhcp + web 认证

    2009-08-13 16:09:07

    DHCP协议是动态主机配置协议。它工作在OSI的应用层,是一种帮助计算机从指定的DHCP服务器获取它们的配置信息的自举协议。DHCP最重要的功能就是动态分配。DHCP采用客户端--服务器模式,请求配置信息的为客户端,提供信息的是服务器。

    DHCP为客户分配地址的方法有3种:手工分配,自动分配和动态分配。

    手工分配是通过网络管理员进行配置的。自动分配和动态分配的相同点都是通过DHCP SERVER分配IP地址。;两者的区别是:

    自动分配没有租期,一旦分配,永久使用;动态分配有租期要求,同一地址可以在租期到了分配给其他设备。

    流程:

    1 发现阶段。 客户端初始化时,发出DHCPDISCOVER 的广播报文,请求获取IP地址及其它配置信息。包含字段:request paramater list 中包含想要获得的参数。其中四个IP地址字段都是0。

    2 提供阶段  因为是广播报文,DHCP服务器都会收到,所有的DHCP服务器都会响应一个DHCPOFFER报文。将your IP address 字段填写为自己分配给客户端的IP地址。同时在选项字段中填写DHCP SERVER的IP地址。,以便client 区分不同的server 。(server id code=54 ,length=IP地址长度。value= server 的ip地址)

    3 选择阶段 客户端会接收很多报文。原则上收到的第一个DHCPOFFER报文后,将进行处理。客户端发送DHCPREQUEST广播报文,在选项字段填写自己希望获得的IP地址,以及选中的DHCP SERVER的IP地址。

    4 响应阶段 收到DHCPREQUEST报文的服务器,将把选项中的IP地址是否和自己相同比,不相同不做任何处理,如果发送过DHCPOFFER报文,清除响应的IP地址记录。如果选项字段中的IP地址和自己相同,就发送DHCPACK报文,信息和DHCPREQUEST基本一致,同时添加租期。

    5 client 收到DHCPACK报文后,会检查DHCPSERVER分配的IP地址是否可以使用。在以太网中,可以发送免费的ARP请求,确定DHCPSERVER分配的IP地址是否被使用。如果可以使用,则DHCP 客户端成功获得IP地址,并根据IP地址使用租期自动启动延续程序。

    6 如果client 发现IP地址已经被使用,则会发送DHCPDECLINE报文,通知DHCPSERVER禁止使用这个IP地址,以免引起冲突。同时重新寻找DHCPSERVER的过程,从第一步开始。

    7 在租期的50%时间点,DHCPCLIENT发送单播的DHCPREQUEST报文,请求服务器续租。如果收到DHCPACK报文,client 续租成功,租期从新计时。如果失败,client继续使用这个地址。         

     在租期的87.5%的时间点,DHCPCLIENT发送广播的DHCPREQUEST报文,请求续租服务。如果收到DHCPACK报文,client 续租成功,租期从新计时。如果失败,client继续使用这个地址。 

    在租期到期后,客户端ip地址被服务器收回,客户端重新从第一步开始发现DHCP服务器。

    8 在client 端成功获取IP地址后,可以随时发送DHCPRELEASE 报文释放IP地址,服务器端将会收回IP地址,以便重新分配。

    DHCP重要字段的说明:

    op操作字段 ---1--请求 2- 应答

    Td---- 随机数,匹配请求和应答

    flags---广播响应标识位 标志位,只用了第一位,第一位是1 表示只能接受广播,不能接受单播。

    ciaddr --客户端IP地址

    yiaddr server --给客户端分配的IP地址
    chaddr ---client 端的实际硬件地址内容。

    OP(1)

    Htype(1)

    Hlen(1)

    Hops(1)

    Transaction  ID(4)

    Seconds(2)

    Flags(2)

    Ciaddr4

    Yiaddr4

    Siaddr4

    Giaddr4

    Chaddr16

    Sname64

    File128

    Optionsvariable

    (图1   DHCP 报文格式)

     

     

    每个字段的含义:

    l      OP:标识是请求还是响应,1为请求,2为响应;

    Htype :硬件地址类型。表示链路地址

    Hlen :硬件地址长度。

    Hops :跳数。经过的DHCP relay 的数目。最大不能超过16 。

    Transaction ID : 事务ID 。是个随机数,用于客户端和服务器之间匹配请求和相应消息。

    seconds :用于计算经过的秒数。

     

    Flags :广播报文标志。最左端一位是1表示只能接收广播报文。

     

    Ciaddr :用户IP地址。

    l      Yiaddr:客户IP地址;

    l      Siaddr用于bootstrap过程中的IP地址

    l      Giaddr:转发代理(网关)IP地址;

    l      Chaddrclient的硬件地址;

    l      Sname:可选server的名称,以0x00结尾;

    l      File:启动文件名;

    l      Options:,厂商标识,可选的参数字段

     

    dhcp报文类型(选项53)取值的含义:

       类型为1:dhcpdiscover 此为client开始DHCP过程中的第一个请求报文

       类型为2:dhcpoffer 此为server对dhcpdiscover报文的响应

       类型为3:dhcprequest 此为client对dihcpoffer报文的响应

       类型为4:dhcpdecline 此为当client发现server分配给它的IP地址无法使用,如IP地址发生冲突时, 将发出此报文让 server 禁止使用这次分配的 IP 地址。

      类型为5:dhcpack 此为server对 dhcprequst报文的响应,client收到此报文后才真正获得了IP地 址和相关配置信息。

      类型为6:dhcpnak 此为server对client的dhcprequst报文的拒绝响应,client收到此报文后,一般 会重新开始DHCP过程。

      类型为 7 : dhcprelease 此报文是 client 主动释放 IP 地址,当 server 收到此报文后就可以收回 IP 地址 分配给其他的client.

      类型为 8 : dhcpinform. 此为如果客户通过别的手段获得了网络地址,它可以使用 DHCPINFORM. 请求获 得其它配置参数,服务器接收到 DHCPINFORM. 包,并建立一个 DHCPACK 消息,在其中包括一些合适客 户的配置参数,只是不包括分配网络地址,检查现有的绑定,在信息中不填充'yiaddr'字段或租用时间参数。 服务器取得 DHCPINFORM. 包内的 'ciaddr' 地址,而返回 DHCPACK 包。

     

      WEB认证方式
      WEB认证需要与DHCP Server和Portal server配合使用,WEB认证的主要过程描述如下:
      (1)用户登陆认证页面,在该页面中,用户输入帐号和口令,并单击"log in"按钮,也可不输入由帐号和口令,直接单击"Log in"按钮;
      (2)由认证页面将用户信息(IP地址,帐号和口令)送给网络中心设备BAS;
      (3)BAS利用IP地址得到用户的二层地址、物理端口号(如Vlan ID, ADSL PVC ID,PPP session ID),利用这些信息,对用户的合法性进行检查,

               如果用户输入了帐号,则认为是卡号用户,使用用户输入的帐号和口令到Radius server对用户进行认证,

               如果用户未输入帐号,则认为用户是固定用户,网络设备利用Vlan ID(或PVC ID)查用户表得到用户的帐号和口令,将帐号送到Radius server进行认证;
      (4)Radius Server返回认证结果给BAS;
      (5)认证通过后,BAS修改该用户的ACL,用户可以访问外部因特网或特定的网络服务;
      (6)用户离开网络前,连接到portal server上,单击"断开网络"按钮,系统停止计费,删除用户的ACL和转发信息,限制用户不能访问外部网络;
      (7)在以上过程中,要注意检测用户非正常离开网络的情况,如用户主机死机,网络断掉,直接关机等。

  • AAA认证与radius 协议

    2009-08-13 07:58:08

     

     

    1.
    AAA 及RADIUS 协议配置
    一、aaa 及radius 协议简介

        1. aaa 的功能

        aaa 是authentication(认证)、authorization(授权)和accounting(计费)的简称。它提供对用户进行认证、授权和计费三种安全功能。具体如下:

        a、认证(authentication):认证用户是否可以获得访问权,确定哪些用户可以访问网络。

        b、授权(authorization):授权用户可以使用哪些服务。

        c、计费(accounting):记录用户使用网络资源的情况。

        aaa 一般采用客户/服务器结构,客户端运行于被管理的资源侧,服务器上则集中存放用户信息。这种结构既具有良好的可扩展性,又便于用户信息的集中管理。

        计费网关主要使用aaa 中的认证功能对终端用户进行认证管理。

        2. radius 协议

        (1) radius 简介

        radius 是remote authentication dial-in user service(远程认证拨号用户服务)的简称,最初由livingston enterprise 公司开发,作为一种分布式的客户机/服务器系统,能提供aaa 功能。radius 技术可以保护网络不受未授权访问的干扰,常被用在既要求较高安全性、又要求维持远程用户访问的各种网络环境中(如用来管理使用串口和调制解调器的大量分散拨号用户)。

        radius 服务包括三个组成部分:

        a、协议:rfc2865、2866 协议基于udp/ip 层定义了radius 帧格式及消息传输机制,并定义了1812 作为认证端口,1813 作为计费端口。

        b、服务器:radius 服务器运行在中心计算机或工作站上,包含了相关的用户认证和网络服务访问信息。

        c、客户端:位于拨号访问服务器nas(network access server)侧,可以遍布整个网络。

        radius 基于客户/服务器模型,nas(如路由器)作为radius 客户端,负责传输用户信息到指定的radius 服务器,然后根据从服务器返回的信息进行相应处理(如接入/挂断用户)。radius 服务器负责接收用户连接请求,认证用户,然后给nas返回所有需要的信息。

        radius 服务器通常要维护三个数据库:第一个数据库“users”用于存储用户信息(如用户名、口令以及使用的协议、ip 地址等配置),第二个数据库“clients”用于存储radius 客户端的信息(如共享密钥),第三个数据库“dictionary”存储的信息用于解释radius 协议中的属性和属性值的含义。如下图所示:

       

        图5-1 radius 服务器的组成

        另外,radius 服务器还能够作为其他aaa 服务器的客户端进行代理认证或计费。radius 服务器支持多种方法来认证用户,如基于ppp 的pap、chap 认证、基于unix 的login 等。

        (2) radius 的基本消息交互流程

        radius 服务器对用户的认证过程通常需要利用nas 等设备的代理认证功能,radius 客户端和radius 服务器之间通过共享密钥认证相互间交互的消息,用户密码采用密文方式在网络上传输,增强了安全性。radius 协议合并了认证和授权过程,即响应报文中携带了授权信息。操作流程图和步骤如下所示:

       

        图5-2 radius 的基本消息交互流程

        基本交互步骤如下:

        a、用户输入用户名和口令;

        b、radius 客户端根据获取的用户名和口令,向radius 服务器发送认证请求包(access-request)。

        c、radius 服务器将该用户信息与users 数据库信息进行对比分析,如果认证成功,则将用户的权限信息以认证响应包(access-accept)发送给radius 客户端;如果认证失败,则返回access-reject 响应包。

        d、radius 客户端根据接收到的认证结果接入/拒绝用户,如果可以接入用户,则radius 客户端向radius 服务器发送计费开始请求包(accounting-request),status-type 取值为start;

        e、radius 服务器返回计费开始响应包(accounting-response);

        f、radius 客户端向radius 服务器发送计费停止请求包(accounting-request),status-type 取值为stop;

        g、radius 服务器返回计费结束响应包(accounting-response)。

        (3) radius 协议的报文结构

        radius 采用udp 传输消息,通过定时器管理机制、重传机制、备用服务器机制,确保radius 服务器和客户端之间交互消息正确收发。radius 报文结构如下:

       

        图5-3 radius 报文结构

        其中identifier 域用于匹配请求包和响应包,随着attribute 域改变、接收到有效响应包而不断变化,而在重传时保持不变化。authenticator域(16字节)用于验证radius服务器传输回来的请求,同时用于密码隐藏算法上,分为request authenticator 和response authenticator。

        a、request authenticator 采用16 字节的随机码。

        b、response authenticator 以对code identifier、request authenticator、length、attribute 和共享密钥进行md5 算法后的结果。

        由code 域决定radius 报文的类型,主要包括:

        表5-8 code 域主要取值的说明

       

        attribute 域携带专门的认证、授权和计费信息,提供请求和响应报文的配置细节,该域采用(type、length、value)三元组的形式提供,rfc 中定义的标准attribute域大致包括:

        表5-9 attribute 域主要取值的说明

       

        radius 协议具有良好的可扩展性,协议中定义的26 号属性(vender-specific)可以被方便地扩展以支持用户自己定义的扩展属性,报文结构如下图所示:

       

        图5-4 包括扩展属性的radius 报文片断

        (4) radius 的特点

        radius 使用udp 作为传输协议,具有良好的实时性;同时也支持重传机制和备用服务器机制,从而有较好的可靠性。radius 的实现比较简单,适用于大用户量时服务器端的多线程结构。正因为如此,radius 协议得到了广泛的应用。
     
    重传机制的原因:
    如果NAS向某个RADIUS服务器提交请求没有收到返回信息,那么可以要求备份RADIUS服务器重传。由于有多个备份RADIUS服务器,因此NAS进行重传的时候,可以采用轮询的方法。如果备份RADIUS服务器的密钥和以前RADIUS服务器的密钥不同,则需要重新进行认证。
     
     
     
     
    请简述RADIUS报文为何采用UDP协议传输,如何保证计费的可靠性?
    1. NAS和Radius服务器之间传递的是几十上百个字节长度的数据,用户对于认证等待时间要求不是很严格。

    2. 当处理大量用户时服务器端采用多线程,TCP是必须成功建立连接后才能进行数据传输的,UDP简化了服务器端的实现过程,实时性好。

    3. Radius要有重传机制和备用服务器机制,它所采用的定时,TCP不能很好的满足;
    4. Radius依靠自身协议保证报文重传和服务器备份机制以确保计费可靠性.

     

     
  • NTP网络时钟协议

    2009-08-04 10:11:50

    网络时间协议(NTP)简介


    NTP概念简介

    Network Time Protocol(NTP)是用

    来使计算机时间同步化的一种协议,它可

    以使计算机对其服务器或时钟源(如石英

    钟,GPS等等)做同步化,它可以提供高精

    准度的时间校正(LAN上与标准间差小于1

    毫秒,WAN上几十毫秒),且可介由加密

    确认的方式来防止恶毒的协议攻击。


    NTP如何工作

    NTP提供准确时间,首先要有准确的时间

    来源,这一时间应该是国际标准时间UTC。

     NTP获得UTC的时间来源可以是原子钟、

    天文台、卫星,也可以从Internet上

    获取。这样就有了准确而可靠的时间源。

    时间按NTP服务器的等级传播。按照离

    外部UTC 源的远近将所有服务器归入

    不同的Stratun(层)中。Stratum-1

    在顶层,有外部UTC接入,而Stratum-2

    则从Stratum-1获取时间,Stratum-3

    从Stratum-2获取时间,以此类推,但

    Stratum层的总数限制在15以内。

    所有这些服务器在逻辑上形成阶梯式的架构

    相互连接,而Stratum-1的时间服务器是

    整个系统的基础。

    计算机主机一般同多个时间服务器连接,

    利用统计学的算法过滤来自不同服务器的

    时间,以选择最佳的路径和来源来校正主

    机时间。即使主机在长时间无法与某一时

    间服务器相联系的情况下,NTP服务依然

    有效运转。

    为防止对时间服务器的恶意破坏,NTP使

    用了识别(Authentication)机制,检

    查来对时的信息是否是真正来自所宣称

    的服务器并检查资料的返回路径,以提

    供对抗干扰的保护机制。


    网络校时协议(NTP)的实现


    时间服务器可以利用以下三种方式与其

    他服务器对时:

    broadcast/multicast
    client/server
    symmetric

    broadcast/multicast方式主要适

    用于局域网的环境,时间服务器周期

    性的以广播的方式,将时间信息传送

    给其他网路中的时间服务器,其时间

    仅会有少许的延迟,而且配置非常的

    简单。但是此方式的精确度并不高,

    对时间精确度要求不是很高的情况下

    可以采用。

    symmetric的方式得一台服务器可以

    从远端时间服务器获取时钟,如果需

    要也可提供时间信息给远端的时间服

    务器。此一方式适用于配置冗余的时

    间服务器,可以提供更高的精确度给

    主机。

    client/server方式与symmetric

    方式比较相似,只是不提供给其他时

    间服务器时间信息,此方式适用于一

    台时间服务器接收上层时间服务器的

    时间信息,并提供时间信息给下层的

    用户。

    上述三种方式,时间信息的传输都使

    用UDP协议。每一个时间包内包含最

    近一次的事件的时间信息、包括上次

    事件的发送与接收时间、传递现在事

    件的当地时间、及此包的接收时间。

    在收到上述包后即可计算出时间的偏

    差量与传递资料的时间延迟。时间服

    务器利用一个过滤演算法,及先前八

    个校时资料计算出时间参考值,判断

    后续校时包的精确性,一个相对较高

    的离散程度,表示一个对时资料的可

    信度比较低。仅从一个时间服务器获

    得校时信息,不能校正通讯过程所造

    成的时间偏差,而同时与许多时间服

    务器通信校时,就可利用过滤算法找

    出相对较可靠的时间来源,然后采用

    它的时间来校时。

    SNTPV4从NTP改版,用来同步因特网中的时钟。是对NTP的改进,支持一种简单的无远

    程过程调用模式执行精准而可靠的操作。适用于同步子网末端的情况,服务器位于子网

    根部,没有其他sntp 服务器。
     

     网络延时与时钟偏差的测量

    Timestamp Name             ID        When Generated
    Originate Timestamp       T1        time request sent by client
    Receive Timestamp         T2        time request received at server
    Transmit Timestamp        T3        time reply sent by server
    Destination Timestamp   T4        time reply received at client
    t 为服务器和客户端之间的时间偏差;
    d 为两者之间的往返时间

    ∵ T2 = T1 + t + d/2; ∴ T2 - T1 = t + d/2;
    ∵ T4 = T3 - t + d/2;  ∴ T3 - T4 = t - d/2;
    ∴ d = (T2 - T1) + (T4 - T3); t = [(T2 - T1) + (T3 - T4)] / 2;

     

    4,识别机制抗干扰和恶意破坏
    为防止对时间服务器的恶意破坏,NTP使用了识别(Authentication)机制,检查来对时的信息是否是真正来自所宣称的服务器并检查资料的返回路径,以提供对抗干扰的保护机制。

     

  • TCL脚本学习记录

    2009-07-27 11:26:14

    对于TCL脚本,摘录后进行分析:注释部分是自己填写,希望有所收获:

    proc ping_all {ip} {
    if {[regexp "(!!)" [exec "ping $ip"]]} {

    #regexp ?switchs? ?--? exp  string ?matchVar?\ ?subMatchVar #subMatchVar...?

    # regexp 用于判断正则表达式是否全部或者部分匹配string 部分,匹配返回1,不匹配返回0;


    set counter 0 

    #counter是计数器
    exec "term len 0"
    set hostname [lindex [exec rsh $ip "sho run | include hostname"] 1]

    # 设置用户名是执行了命令 sho run 命令后结果中返回值中包含hostname 的第一项元素。
    set int [exec rsh $ip "show ip int brief"]

    # int 是执行这个命令的结果。ip地址

    set length [llength $int]

    返回int (IP地址)的元素长度length

    while {$counter<=$length} {
    set tmp [lindex $int $counter]

    #返回ip地址的第counter 个元素。也就是第几个IP地址。

    if {[regexp "(^\[0-9]+\.\[0-9]+\.\[0-9]+\.\[0-9]+)" $tmp ]} {

    #对tmp的ip地址进行多次匹配,匹配成功返回1. ”.“表示匹配任意单个字

    #符。'^"表示从头进行匹配。
      puts "\n"
      puts "**********************************"
      puts "* Ping $hostname [lindex $int [expr $counter - 1]]"

    #ping 下一个IP地址。
      puts "**********************************"
      exec "ping $tmp"
      }
    incr counter
    }
    } else {
      puts "\n\n"
      puts "IP address $ip is not reachable\n"
      set route [exec "show ip route $ip"]
      puts "Output from the show ip route command\n"
      puts "[exec "show ip route $ip"]"
    }
    }

    Script. Breakdown :
    The script. reads in the IP address of the device you want to
    test reachability to. The script. then tests to ensure that is
    can reach that particular IP address by trying to ping the IP
    address. If the ping is unsucessfull an error message is
    displayed like below:

    脚本读取测试可达性的设备IP地址。然后通过ping IP地址检测是否可达。如果ping失败,出现的错误如下所示:

    Rack1R1#ping_all 150.1.4.4


    IP address 150.1.4.4 is not reachable

    Output from the show ip route command

    % Subnet not in table

    Rack1R1#

    If the ping is sucessful the script. RSH's to the remote device
    and discovers it's hostname along with all the IP addresses that
    are assigned to the interfaces of the remote device. Next the
    script. attempts to ping the IP addresses of the remote router from
    the local router.

    如果PING成功。rsh远程,发现主机名,和在远程设备各个端口的IP地址。下一步,试图通过本地路由器ping 远程路由器。

    Implementation:

    Rack1R1#tclsh
    Rack1R1(tcl)#
    Rack1R1(tcl)#proc ping_all {ip} {
    +>
    +> if {[regexp "(!!)" [exec "ping $ip"]]} {
    +>
    +>   set counter 0
    +>   exec "term len 0"
    +>   set hostname [lindex [exec rsh $ip "sho run | include hostname"] 1]
    +>   set int [exec rsh $ip "show ip int brief"]
    +>   set length [llength $int]
    +>
    +>   while {$counter<=$length} {
    +>     set tmp [lindex $int $counter]
    +>
    +>     if {[regexp "(^\[0-9]+\.\[0-9]+\.\[0-9]+\.\[0-9]+)" $tmp ]} {
    +>       puts "\n\n"
    +>       puts "**********************************"
    +>       puts "*  Ping $hostname [lindex $int [expr $counter - 1]]"
    +>       puts "**********************************"
    +>       exec "ping $tmp"
    +>     }
    +>     incr counter
    +>   }
    +> } else {
    +>          puts "\n"
    +>          puts "IP address $ip is not reachable\n"
    +>          set route [exec "show ip route $ip"]
    +>          puts "Output from the show ip route command\n"
    +>          puts "[exec "show ip route $ip"]"
    +> }
    +>}

    Rack1R1(tcl)#ping_all 150.1.2.2



    **********************************
    *  Ping Rack1R2 Ethernet0/0
    **********************************

    Type escape sequence to abort.
    Sending 5, 100-byte ICMP Echos to 10.1.1.2, timeout is 2 seconds:
    !!!!!
    Success rate is 100 percent (5/5), round-trip min/avg/max = 1/2/4 ms


    **********************************
    *  Ping Rack1R2 Loopback0
    **********************************

    Type escape sequence to abort.
    Sending 5, 100-byte ICMP Echos to 150.1.2.2, timeout is 2 seconds:
    !!!!!
    Success rate is 100 percent (5/5), round-trip min/avg/max = 1/2/4 ms
    Rack1R1(tcl)#

  • TCL/EXPECT资源收集

    2009-07-27 10:00:01

    本贴主要收集一些我看到过的TCL/EXPECT方面的资源,以及关于自动测试方面的资源。

    TCL语言中文网:http://www.tclchina.com/
        关于TCL语言的中文网站,里面有不少资料,还有TCL和EXPECT的论坛。

    寒蝉退士的Bolg:http://mhss.cublog.cn/
        里面有很多作者翻译的文档、手册等,其中有几篇是关于TCL的。

    Tcl Developer Xchange:http://www.tcl.tk/
        熟悉英文的朋友可以看一下。

    Tcl FAQ:http://psg.com/~joem/tcl/faq.html
        TCL的FAQ,也许有帮助。

    本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/easwy/archive/2006/05/29/760880.aspx

  • TCL/EXPECT自动化测试脚本实例七 --- 构造报文测试

    2009-07-27 09:58:16

    前面提到过使用nemesis构造报文进行测试的思路,今天介绍一个这样的脚本。
    这个脚本的功能是构造并发送不同源MAC地址的报文,通过这样一个脚本,我们就可以测试交换机每端口最大能学习到的MAC地址的数目。

    简单说一下nemesis,它运行在linux上,也可以在windows上运行。在linux上,需要拥有root权限才能构造报文。
    它可以用来构造arp, enternet, ip, icmp, igmp, dns, tcp, ospf, rip等类型的报文。实际上,用户可以使用一个文件做为它所构造的报文的内容,从这个角度上讲,它可以用来构造任何类型的报文。
    另外,由于它是基于命令行的一组工具,所以能够非常好的和TCL/EXPECT结合使用,完成自动化测试。

    这个脚本仍旧由前面介绍的test.exp脚本调用,调用方式是:
    ./test.exp -ssrc_mac_attack.exp script

    此脚本文件的内容(src_mac_attack.exp)如下:

    # $Id$
    # Construct different source MAC address packets, and send them to switch.

    proc src_mac_attack {mac} {
        set rc [exec echo "src MAC attack packet $mac" \
            | nemesis ethernet -M 00:01:02:03:04:05 -H $mac -T 0x0800 -P -]
        return $rc
    }


    for {set i 1} {$i < 256} {incr i} {
        set mac [constructMac $i]
        src_mac_attack $mac
    }

    脚本很简单,只有一个循环,不断生成新MAC,然后构造报文发送。
    简单介绍一下proc src_mac_attack,这个函数中,使用TCL的exec命令来执行linux下的命令。在这里执行的linux命令就是:
      echo "src MAC attack packet $mac" \
              | nemesis ethernet -M 00:01:02:03:04:05 -H $mac -T 0x0800 -P -
    其中,echo命令的输出通过管道,被送给nemesis命令做输入,echo命令显示的内容将做为所构造的以太报文的内容;
    nemesis ethernet命令表明所构造的是以太报文,-M、-H、-T分别指明报文的目的地址、源地址,报文类型。“-P -”则指明报文的内容由标准输入获得,在此例中就是echo命令的输出。

    脚本中调用了另外一个自定义函数,这个函数放在commonLib.exp中,用来生成MAC地址(最多可生成65535个不重复的MAC地址),函数内容如下,比较简单,不再赘述:

    #************************************************
    # Construct MAC address
    #
    # @PARAMS
    #    rawMac --- raw MAC address, integer
    #
    # @RETURN
    #    the MAC address string
    #************************************************
    proc constructMac {rawMac} {
        set mac "00:00:00:00"
        set j [expr "($rawMac >> 8) & 0xFF"]
        set k [format "%x" $j]
        set mac "$mac:$k"
        set j [expr "$rawMac & 0xFF"]
        set k [format "%x" $j]
        set mac "$mac:$k"

        dbgLog "rawMac = $rawMac, mac = $mac"
        return $mac
    }


  • TCL/EXPECT自动化测试脚本实例六 --- SNMP community长度测试

    2009-07-27 09:57:27

    下面通过一个测试SNMP community最大长度的脚本,介绍一下net-snmp工具。

    net-snmp是一组基于命令行的snmp manager工具,可以在命令行下进行snmp get, snmp set, snmp walk等操作,支持snmp v1/v2c/v3。原来的名字叫做ucd-snmp,也已经被移植到windows NT上。
    它的主页在http://net-snmp.sourceforge.net/

    由于它可以在命令行下进行SNMP操作,所以可以和TCL/expect很好的结合,完成自动化测试的功能。
    下面的脚本(snmp.exp),不断的增加SNMP community,长度从1到256,每增加一个community,就调用snmp-get来进行SNMP get操作,如果get成功,说明此community有效;反之,就说明community已经超出了设备支持的最大长度。
    这个脚本使用前面讲到的test.exp调用,调用方法是:
    ./test.exp -ssnmp.exp script
    对它稍加修改,也可以直接在命令行中调用,此处不再赘述。

    代码如下:
    # $Id$

    proc snmpCommTest {comm} {
        global g_devip

        spawn snmpget -c $comm -v 2c -r 2 $g_devip system.sysUpTime.0
        expect {
            "system.sysUpTime.0*" {
                return 1
            }
            "*Timeout*" {
                return 0
            }
        }

        return 1
    }

    set spawn_id [login $g_devip $g_user $g_passwd]
    if {$spawn_id == 0} {
        errLog "login error\n"
        return 0
    }

    set cmdCommAdd "create snmp community %s rw\n"
    set cmdCommDel "delete snmp community %s\n"
    set cmdHostAdd "create snmp host ip 192.168.1.2 community %s\n"
    set cmdHostDel "delete snmp host ip 192.168.1.2 community %s\n"
    set comm ""

    for {set i 1} {$i < 256} {incr i} {
        set comm "a$comm"
        set cmd [format $cmdCommAdd $comm]
        exp_send $cmd
        expect {
            "Error*" {
                errLog "create comm len $i error"
                continue
            }
            timeout {
                errLog "create comm len $i timeout"
                continue
            }
            "Entry Created"
        }
        set cmd [format $cmdHostAdd $comm]
        exp_send $cmd
        expect {
            "Error*" {
                errLog "create host error"
                continue
            }
            timeout {
                errLog "create host timeout"
                continue
            }
            "Entry Created"
        }

        set rc [snmpCommTest $comm]
        if {$rc == 0} {
            errLog "community len $i failed"
        }

        set cmd [format $cmdHostDel $comm]
        exp_send $cmd
        expect "Entry Deleted"
        set cmd [format $cmdCommDel $comm]
        exp_send $cmd
        expect "Entry Deleted"
    }


  • TCL/EXPECT自动化测试脚本实例五 --- 由文件中读取一行

    2009-07-27 09:56:37

    TCL/EXPECT自动化测试脚本实例五 --- 由文件中读取一行
    代码见下,比较简单,就不再分析了。调用实例见前面的文章。

    #************************************************
    # get a line from file, skip blank lines and
    # comment lines, return the reading line in
    # parameter 'line'.
    #
    # @PARAMS
    # fd     - file fd
    # line   - var used to return the line
    #
    # @RETURN
    # return 1 if read successfully, otherwise 0
    #************************************************
    proc getLine {fd line} {
        upvar $line ln

        # read a line from fd
        while {[set lineLen [gets $fd ln]] >= 0} {
            # blank line
            if { $lineLen == 0 } continue
     
            # trim whitespace
            set ln [string trim $ln]
            if { [string length $ln] == 0 } continue

            # skip comment
            if { [string index $ln 0] == "#" } continue

            # success
            return 1
        }

        return 0
    }


  • TCL/EXPECT自动化测试脚本实例四 --- 批命令执行

    2009-07-27 09:55:51

    在测试过程中,在具体测试某一个功能点时,往往需要为此进行大量的配置。为了简化测试过程,我们可以把所有的配置命令放在一个文本文件中,然后使用测试脚本来执行这些命令。这样就不需要再手工进行配置了,费时费力。
    基于如上考虑,编写了下面的脚本tCmd.exp。这个脚本被我们前面介绍过的test.exp脚本调用。

    # $Id$

    # This file is used to execute specific commands list in a file

    proc execCmdFile {cmdFile} {
        global g_dbgFlag g_prompt

        # enable debug
        set g_dbgFlag 1

        # login
        set spawn_id [login $g_devip $g_user $g_passwd]
        if {$spawn_id == 0} {
            errLog "login $g_devip failed"
            return 0
        }

        # open cmdFile
        set cmdFd [open $cmdFile r]

        while true {
            # get a line
            if {![getLine $cmdFd line]} {
                dbgLog "reached eof"
                break
            }

            # split the line
            set ln [split $line ","]
            set cmd [string trim [lindex $ln 0]]
            set out [string trim [lindex $ln 1]]

            if {$cmd == ""} continue
            if {$out == ""} set out $g_prompt

            # send cmd line
            exp_send "$cmd\n"
            dbgLog "send $cmd"

            # expect output
            dbgLog "expect $out"
            expect {
                timeout {
                    errLog "TIMEOUT: while exec \"$cmd\""
                    continue
                }
                -ex "$out" {
                    continue
                }
            } ;# end expect
        }

        # close cmdFile
        close $cmdFd
    }

    # if no cmdFile, use default
    if {$cmdFile == ""} {
        set cmdFile "cmdFile.txt"
    }

    execCmdFile $cmdFile

    有了这个脚本,我们可以使用"./test.exp -cinterface.txt cmd"来执行interface.txt中的命令。

  • TCL/EXPECT自动化测试脚本实例三 --- 全局变量

    2009-07-27 09:55:12

    下面是global.exp文件的内容,只是定义一些全局变量,供其它文件使用。

    # $Id$

    # global variables
    set g_dbgFlag   1                ;# Debug flag
    set g_bLogFd    0                ;# Error Log FD
    set g_devip     "192.168.1.222" ;# Default device IP address
    set g_prompt    "$"              ;# CLI prompt
    set g_user      "root"           ;# login account name
    set g_passwd    "root"           ;# login password
    set g_usrPrompt "*ogin:"         ;# login prompt
    set g_pwdPrompt "*assword:"      ;# login password prompt


  • TCL/EXPECT自动化测试脚本实例二 --- 主程序

    2009-07-27 09:54:19

    现在介绍一下测试主程序: test.exp。
    为了方便加入新的测试项目,主程序采用了一种灵活的机制,它根据需要通过source命令调用相应的子测试程序。这样一来,每个测试点都可以单独放到一个文件中,然后被主程序引用。
    先看一下代码:

    #! /usr/bin/expect --

    # $Id$
    # Usage:
    #    ./test [-uuser] [-ppassward] [-iip_address]  test_001 ...
    # or ./test [-uuser] [-ppassward] [-iip_address] [-ccommand_file] cmd
    # or ./test [-uuser] [-ppassward] [-iip_address] [-sscript_file] script

    source global.exp
    source commonLib.exp

    # initialize variables
    set cmdFile ""
    set tList $argv
    set execScript. ""

    # process options
    set endOptIndex -1
    foreach arg $argv {
        if {![string match "-\[a-zA-Z]*" $arg]} {
            break
        }

        # inc end option index
        incr endOptIndex

        # get option flag and option value
        set optFlg [string range $arg 1 1]
        set optVal [string range $arg 2 end]
        dbgLog "$optFlg $optVal"
        if {$optVal == ""} {
            dbgLog "option value is null: -$optFlg"
            return -1
        }

        switch $optFlg {
            "u" {
                set g_user $optVal
                dbgLog "user: $g_user"
            }
            "p" {
                set g_passwd $optVal
                dbgLog "password: $g_passwd"
            }
            "i" {
                set g_devip $optVal
                dbgLog "devip: $g_devip"
            }
            "c" {
                set cmdFile $optVal
                dbgLog "cmdFile: $cmdFile"
            }
            "s" {
                set execScript. $optVal
                dbgLog "execScript. $execScript"
            }
            default {
                puts "unknown option: -$optFlg"
                return -1
            }
        } ;# end switch
    } ;# end foreach

    # remove options from list
    if {$endOptIndex != -1} {
        set tList [lreplace $argv 0 $endOptIndex]
    }

    dbgLog "tList is: $tList"

    # create log dir
    if { ![file exist "log"] || ![file isdirectory "log"] } {
        puts "please create directory \"log\""
        return -1
    }

    # read current time
    set clicks [clock clicks]
    set tstr [clock format $clicks -format "%y%m%d%I%M%S"]

    # open log file
    log_file "log/vLog$tstr.log"

    # open brief log file
    set g_bLogFd [open "log/bLog.log" w]

    # start testing
    foreach tItem $tList {
        switch $tItem {
            "sys_001" { ;# test group sys_001
                source snmp.exp
            }
            "cmd" { ;# exec cmd file
                source tCmd.exp
            }
            "script" { ;# exec script. file
                if {$execScript. == ""} {
                    puts "Please specify script. name using -s option"
                    return -1
                }
                source $execScript
            }

            default {
                puts "do you want to test \"$tItem\"\?"
            }
        }
    }

    close $g_bLogFd


    在程序开始,通过source导入两个文件,其中global.exp中主要存放了一些全局变量的定义,因为这些全局变量对每台测试设备可能各不相同,所以把它们提取出来。commonLib.exp文件中存放着一些通用子程序,可供各测试程序调用。我们前面介绍过的login子程序,就放在此文件中。
    接下来,分析命令行参数,首先提取出所有的选项参数,目前支持的命令行选项包括:
    -u :此选项用来更改登录的用户名
    -p :此选项用来更改登录的密码
    -i :此选项用来更改telnet的IP地址
    -c :此选项用来指明批处理文件的文件名,用法在后面描述
    -s :此选项用来指明脚本文件的文件名,用法在后面描述

    最后,命令行参数中所有非选项的部分,都被做为测试项,分别对这些测试项进行测试。
    例如测试项test_001,会使用source命令调用snmp.exp脚本,进行snmp community方面的测试。
    可以根据需要自行添加测试项目。

    有两个特别的测试项名称,分别为cmd和script。
    cmd测试项,会调用cmd.exp脚本,这个脚本在后面介绍,它的主要功能是执行一个文本文件里的所有命令。文本文件名由-c选项提供。
    script测试项,它会调用source命令,执行$execScript脚本。可以使用-s选项为$execScript变量赋值。

    这个测试脚本提供了两种日志,一种是详细的日志(vLog*),包括了telnet的所有交互过程;另外一种是简单的日志,只包含程序中使用errLog输出的信息。日志文件被放在子目录log中,其文件名中包含了脚本执行的时间,方便查找。
    本脚本中使用dbgLog,以及以后将用到的errLog,都是定义在commonLib.exp文件中的子函数,代码如下:

    #************************************************
    # debug output routine
    #
    # @PARAMS
    # arg - variable length arguments
    #************************************************
    proc dbgLog arg {
        global g_dbgFlag

        if {$g_dbgFlag} {
            puts $arg
        }
    }

    #************************************************
    # error output routine
    #
    # @PARAMS
    # arg - variable length arguments
    #************************************************
    proc errLog arg {
        global g_bLogFd
        global g_dbgFlag

        if {$g_dbgFlag} {
            puts $arg
        }

        if { $g_bLogFd != 0 } {
            puts $g_bLogFd $arg
        }
    }


  • TCL/EXPECT自动化测试脚本实例一 --- telnet到目标机器

    2009-07-27 09:53:28



    我的自动化测试脚本运行在debian linux下,使用/usr/bin/expect进行解释执行。为了简化处理,把一些常用的功能编写成函数,放在commonLib.exp文件中,其它脚本文件可以使用source commonLib.exp命令引用这些函数。
    下面的函数完成telenet到目标机器并login。从其实现上大家可以看到tcl/expect编写测试脚本的简洁。
    这个函数带有三个参数,分别是目标机器的IP地址ipaddr,登录用户名user和登录密码,telenet的端口号采用默认的23端口。
    函数中使用了三个全局变量,g_prompt,g_usrPrompt和g_pwdPrompt,分别表示登录后的命令提示符,提示用户名输入的提示符,以及提示密码输入的提示符,这三个全局变量定义在global.exp中。之所以采用全局变量,是因为这些值使用比较广泛,但在不同设备中都不相同。使用全局变量可以方便修改。

    代码如下:

    #************************************************ 全部用#在开头标识,表示#不可执行部分
    # telnet login routine
    #
    # @PARAMS                               参数:
    # ipaddr - remote device ip address
    # user   - user name to login in
    # passwd - login password
    #
    # @RETURN
    # spawn_id if login success, otherwise 0
    #************************************************
    proc login {ipaddr user passwd} {

    proc add {x y } {expr $x+$y}

    proc命令的第一个参数是你要定义的过程的名字,第二个参数是过程的参数列表,参数之间用空格隔开,第三个参数是一个TCL脚本,代表过程体。

    proc生成一个新的命令,可以象固有命令一样调用:

        global g_prompt g_usrPrompt g_pwdPrompt
    全局变量:分别表示登录后的命令提示符,提示用户名输入的提示符,以及提示密码输入的提示符,
        spawn telnet $ipaddr    telnet 方式登陆到目标ip地址上
        expect {
            "$g_usrPrompt" {        提示输入用户名
                exp_send "$user\r\n"  发送用户名
                exp_continue         程序继续
            }
            "$g_pwdPrompt" {         提示密码输入的提示符
                exp_send "$passwd\r\n" 发送密码
                exp_continue           程序继续
            }
            -ex "$g_prompt" {            登录后的命令提示符  exec 命令用于显式地执行外部命令
                dbgLog "Login Successful\n" 显示日志信息,登陆成功
                return $spawn_id           
            }
            timeout {                     超时处理
                send_user "timeout"       发送超时信息
                return 0                  习惯上 return (0); 表示程序运行正常,别的值表示不正常

    在定义过程时,你可以利用return命令在任何地方返回你想要的值。 return命令迅速中断过程,并把它的参数作为过程的结果。


            }
        }
    }


  • spirrent testcenter & expect

    2009-07-27 09:52:12

    这一段时间一直在做使用tcl脚本控制testcenter的工作,同时还需要远程登陆到几台linux主机进行一些测试操作,相关的资料太少了,努力啃英文资料,总算有一点进展。
        说说在这个过程中遇到的一些问题吧。
        1.测试环境:
        window2000下使用komodo调试程序,安装testcenter自带的tcl包后,然后把ActiveTcl8.4.15.0.280619-win32-ix86-threaded自带的expect库文件copy到testcenter安装的目录下,这样tclsh就可以同时导入expect与SpirentTestCenter这两个package了。
        不知道有没有别的更好的方法,呵呵。如果在xp pack2或3下面想使用expect,需要更新系统system32下面的一个debughelp.dll文件。

  • tcl学习笔记(2)-expect实现telnet和ssh

    2009-07-27 09:51:02

     

    这个两个功能在以后的工作中可以以函数实现,完成特定功能。

     

    1.SSH到linux主机上查看linux内核版本号

     

    #!/usr/expect/bin/expect

     

    set HOSTIP [lindex $argv 0]

    set LOGIN [lindex $argv 1]

    set PASS [lindex $argv 2]

     

    set timeout 1

    set cmd {uname -a}

     

    if {$argc<3} {

            puts stderr "Usage:$argv0 hostip login password.\n"

            exit 1

    }

     

    send_user "argv0:  $argv0\n"

    send_user "argv:  $argv\n "

     

    spawn ssh $LOGIN@$HOSTIP

    expect_after eof { exit 0 }

     

    expect "yes/no" { send "yes\r" }

    expect "password:" { send "$PASS\r" }

    expect "#"

    send "$cmd\r"

    expect "*\r"

    send "exit\r"

     

     

     

    2.telnet到3750上添加一条静态路由

     

    #!/usr/expect/bin/expect

     

    spawn telnet 10.255.255.240

    expect "Username:"

    send "admin\n"

    expect "Password:"

    send "XXXXXX\n"

    expect "3750>"

    send "en\n"

    expect "Password:"

    send "XXXXXX\n"

    expect "3750#"

    send "ping 192.168.100.100\n"

    expect "3750#"

    send "config t\n"

    expect "#"

    send "ip route 123.2.1.1 255.255.255.255 null0\n"

    expect "#"

     

    send_user "\n\nOver\n\n"

  • 转贴学习: tcl学习笔记(1)-安装tcl&expect

    2009-07-27 09:49:37

    tcl学习笔记(1)-安装tcl&expect

    创建Tcl

     

    目前最新版本的Tcl8.6.0,但是Expect还没有跟上脚步,如果没有选择好版本会导致安装失败。我使用的是tcl8.4.19-src.tar.gzexpect-5.39.0.tar.gz,把两个软件包放在/tmp/tcl目录下。

     

    Tcl下载:http://sourceforge.net/project/showfiles.php?group_id=10894&package_id=10452

    expect 下载: http://expect.nist.gov/src/

    Expect 补丁下载:http://www.linuxfromscratch.org/patches/downloads/expect/

     

    解压缩源代码包,并进入源代码目录:

     

        #tar -zvxf tcl8.4.19-src.tar.gz

        #cd tcl8.4.19

     

    现在为创建Tcl作准备工作:

     

        #cd unix

        #./configure --prefix=/usr/tcl

     

    开始创建:

     

        #make

     

    安装:

     

        #make install

     

    安装完毕以后,进入tcl源代码的根目录,把子目录unix下面的tclUnixPort.h copy到子目录generic中。暂时不要删除tcl源代码,因为expect的安装过程还需要用。

     

     

    创建Expect

     

        首先解压缩源代码,进入源代码目录:

     

        #tar -zvxf expect-5.39.0.tar.gz

        #cd expect-5.39

     

    打补丁,修Bug

     

        #patch -Np1 -i ../expect-5.39.0-spawn-1.patch

     

    作准备工作:

     

        #./configure --prefix=/usr/expect --with-tcl=/usr/tcl/lib --with-x=no --with-tclinclude=/tmp/tcl/tcl8.4.19/generic/

     

    各选项的含义是:

     

        --with-tcl=/usr/tcl/lib

        告诉configure脚本,Tcl解释器在哪里。这里要用刚刚创建的Tcl,否则就会使用你系统的Tcl了。

     

        --with-tclinclude=/tmp/tcl/tcl8.4.19/generic

        告诉configure脚本,Tcl的头文件位置。

     

        --with-x=no

        不使用X图形系统支持,因为没有TkTcl的图形用户界面组件)。

     

    开始创建:

     

        #make

     

    安装:

     

        #make install

  • ARP 协议总结

    2009-07-26 16:29:54

    ARP是地址解析协议。在交换网中,主机之间的通信使用MAC地址,而不是IP地址。

    因此,每台主机都需要维护一张ARP表。保存了IP地址和MAC地址的对应关系。

  • PPPoE协议

    2009-07-23 15:52:34

    PPPoE协议是一种点到点的链路协议,它提供了点到点的一种封装,传递数据的一种方法。

    以太网是一种广播网,本身不能提供身份验证的功能。ppp协议提供了通信双方身份验证的功能,但是PPP协议是一种是一种点对点协议,通信双方没有提供地址信息。如果PPPoE应用在以太网链路上,必须进行又一次封装,PPPoE提供了在以太网广播链路上进行点对点通讯的能力。

    ppp协议包含LCP协议,认证阶段(pap或者CHAP),NCP协议。

    另一种说法是ppp协议包含LCP协议,NCP协议。和ppp的扩展协议

    LCP协议用于协商ppp协议的参数选项;NCP协议网络控制协议,常用IPCP,用来通信双方的网络地址。

    lcp协议包含三类报文:链路配置报文,链路终止报文,链路维护报文。

    链路配置报文用于协商一些报文可选参数选项。是sp还是mp、验证方式和最大传输单元等

    链路终止报文用于终止一条链路 引起链路终止的原因很多:载波丢失、认证失败、链路质量失败、空闲周期定时器期满、或者管理员关闭链路。

    链路维护报文用于测试和调试ppp链路。

    lcp 协议中Config-request报文中,认证配置选项可以选择其一。

    PAP(密码认证协议)认证:采用2次握手。认证方向被验证方发送Config-Request 报文中含有认证配置选项,参数数据为0XC023.

    完成链路建立阶段之后,对等结点持续重复发送 ID/ 密码给验证者,直至认证得到响应或连接终止。

    CHAP(挑战握手协议)认证是3次握手。

    1 由验证方发出一段随机数和验证方的主机名A。

    2 被验证方收到后,将随机数,报文ID以及本机上主机名A下对应的密钥,经过MD5加密算法之后,生成应答,随后将应答和自己的主机名B填写好,送回信息

    3 验证方查找到被验证方的主机名B,然后用名下的密钥,保留报文ID和随机报文用MD5加密算法生成结果。

    4 验证方将刚刚生成的结果和被验证方的比较,如果计算结果一致,返回ACK信息,否则返回NAK信息。

    PPPoE协议

    PPPoE流程:

    1 从PPPoE客户端向PPPoE服务器发送PADI(PPPOE Active Discovery Initiation)广播报文,用于寻找PPPoE服务器,请求PPPoE接入。

    2 PPPoE服务器向PPPoE客户端发送PADO(PPPOE Active Discovery Offer)报文。

    3 客户端根据回应,向PPPoE服务器发送PADR(PPPOE Active Discovery Request)请求。

    4 PPPoE服务器产生一个session id ,通过PADS(PPPOE Active Discovery Session-confirmation)发送给客户端。

    5、PADT(PPPOE Active Discovery Terminate)报文
    当用户或者服务器需要终止会话时,可以发送这种PADT报文。

    5 客户端和PPPoE服务器之间进行PPP的LCP协商,建立LCP通信。同时,确定认证模式是CHAP模式。

    6 由PPPoE服务器向客户端发送一个随机数,成为chanllage.

    7 客户端接收后,把随机数、session id 以及存放在客户端本地的服务器名称下的密钥,用MD5算法加密后,发送给PPPoE服务器。

    8 服务器把客户端用户名下的密钥,随机数和保留ID一起送到Rdius服务器进行验证。

    9 Radius服务器根据用户信息进行验证,如果验证通过,就连同配置信息一起发送给PPPoE服务器。如果认证失败,流程到此结束。

    10 PPPoE服务器将认证结果返回给客户端。

    11 用户进行NCP(如IPNP)协商,通过PPPoE服务器获取到规划的IP地址等参数。

    ncp协商支持ipcp和ipxcp协商,ipcp协商主要包括双方的ip地址,ipxcp协商主要包括双方的网络号和节点号。通过ncp协商来选择和配置一个或多个网络层协议。每个选中的网络层协议配置成功后,该网络层协议就可通过这条链路发送报文了。

    12 如果认证通过,PPPoE服务器向Radius服务器发送计费开始请求。

    13 Radius服务器向用户发送计费回应。

    14用户此时通过认证,并且获得合法权限,可以展开网络业务。

    用户下线业务:包含用户正常下线和用户意外下线。正常下线流程:

    1 用户向PPPoE服务器发送下线申请。

    2 服务器响应客户端信息。

    3 服务器向AAA服务器发送计费终止请求

    4 AAA服务器终止计费,同时返回计费终止响应。

    意外下线:

    1 PPPoE服务器检测到PPPoE客户端已经不在线。

    3 服务器向AAA服务器发送计费终止请求

    4 AAA服务器终止计费,同时返回计费终止响应。

     

     

  • 转载学习:PPPOE宽带接入技术及常见故障分析

    2009-07-23 14:07:35

     

    目前各地广电建设数据网主要是以太网,广电作为运营商来说,除建立一个稳定可靠的网络外,选择一个好的宽带接入方式也尤为重要。一个好的接入方式不仅能够使网络安全稳定地运营,也能使运营商方便地开展各种业务,实现灵活的计费,更好地对用户进行管理。目前以太网接入方式主要有3种:固定IP,DHCP,PPPOE,而PPPOE+VLAN是一种比较理想的宽带接入方式。
      1、宽带接入网需要实现的基本功能
      宽带接入网需要实现的基本功能可以归纳为以下几个方面:
      (1)用户管理
      掌握用户的信息,在用户进行通信时对用户进行认证、授权,使合法用户方便快捷地接入网中,杜绝非法用户接入,防止非法用户占用网络资源。
      (2)安全管理
      合法用户在通信时要保障其数据的安全性,隔离带有用户个人信息的数据包,对于主要的网络设备防止其受到攻击而造成网络瘫痪。由于用户终端是以普通网卡与网络设备相连,在通信时会发送一些广播地址的帧(如ARP,DHCP消息等),而这些消息会携带用户的个人信息(如用户的MAC地址),如不隔离这些消息让其他用户接收到,容易发生MAC/IP地址的仿冒,影响合法用户上网。对于运营商来说,保护其系统设备的安全性,防止恶意攻击是十分重要的。
      (3)业务管理
      需要为保证QoS提供一定的手段。为了保证业务的QoS,网管人员根据具体情况为用户提供一定的带宽控制能力,例如保证用户的最低接入速率,限制用户的最高接入速率等。
      (4)计费管理
      接入网要能够对用户进行灵活的计费,根据用户类别、使用时长、用户流量等数据进行计费。
      2、固定IP,DHCP,PPPOE 3种宽带接入方式的比较
      2.1用户管理和开销方面
      固定IP方式:对IP地址管理不易,用户恶意更改或者尝试自行设置自己的IP地址,都会造成管理上的麻烦,增加运营商的额外开销。
      DHCP方式:一方面DHCP存在较多的广播开销,对于用户量较多的城域网会造成网络运行效率下降和配置困难;另一方面,仍然无法解决用户自行配置IP地址的问题。
      PPPOE:由于采用动态分配IP地址方式,用户拨号后无需自行配置IP地址、网关、域名等,它们均是自动生成,不存在用户自行更改IP地址的问题,对用户管理方便,而且PPPOE协议是在包头和用户数据之间插入PPPOE和PPP封装,这两个封装加起来也只有8个字节,广播开销很小。
      2.2计费策略方面
      固定IP和DHCP方式的计费策略不灵活,一般采用包月制,如要实现流量计费功能则必须要有相应的流量监视或采集系统,或在高端路由器上启动记账功能,然后应用SNMP进行计费,这有可能使路由器运行效率下降。
      PPPOE可以实现对用户的灵活计费,可以按时长、流量计费,也可采用包月制。
      2.3用户服务策略定制方面
      固定IP和DHCP方式只能配合IP地址转换和地址访问列表控制来制定简单的服务,如果要实现按特定用户进行流量控制,必须购买流量控制设备。
      PPPOE支持业务QoS保证,可方便地对用户进行实时流量控制。
      2.4信息安全方面
      固定IP,DHCP和PPPOE都可以采用细化VLAN的方式来解决用户信息的安全问题,将局域网交换机的每个端口配置成独立的VLAN,利用VLAN 可以隔离ARP,DHCP等携带用户信息的广播消息,从而使用户数据安全性得到提高。固定IP地址方式为了识别用户的合法性必须将IP地址和端口VID进行绑定,因为每个用户处于逻辑上独立的网内,所以对每个用户要配置一个子网的4个IP地址:子网地址、网关地址、子网广播地址和用户主机地址,这样会造成地址利用率降低,而PPPOE采用认证、授权的方式不存在这个问题。
      2.5第三层广播风暴
      固定IP和DHCP方式都不能解决第三层广播风暴问题,第三层广播风暴影响同一IP子网所有用户的使用质量。而PPPOE方式由于采用二层隧道认证,所有链路设备都工作在第二层,不存在第三层广播风暴问题。
      从以上的比较可以看出,PPPOE同其他两种接入方式相比具有较大的优势,因此PPPOE目前被各大运营商普遍采用。
      3、PPPOE的认证
      PPPOE认证首先要在客户机上安装PPPOE协议的驱动软件,在前端由BRAS服务器配合RADIUS服务器实现对用户的认证、计费。
      认证过程:用户拨号发出请求,经过网络传送到BRAS服务器,BRAS服务器接到请求后向RADIUS服务器发出ACCESS REQUEST请求包,其中含有用户的账号、密码、端口类型等,经RADIUS服务器核实后,向BRAS回送ACCESS REPONSE响应包,其中包含用户的合法性和一些设置,如用户IP地址、掩码、网关、域名、用户可使用的带宽等。用户接收到这些信息后就可以上网,上网期间BRAS不断地向RADIUS发送计费信息,这些信息包括用户的上网时间、用户流量、用户下网时间等,以便RADIUS准确计费。
      从 PPPOE认证过程可以看出,BRAS服务器在整个链路中起到关键的作用,因此BRAS服务器也要实现大而全的功能,包括认证、连接、终接、安全管理、计费业务汇聚、收敛等功能,设备复杂。由于建立连接后数据必须经过BRAS,BRAS很容易成为“瓶颈”,最易出问题,堵塞严重时用户连接速度慢或根本连接不上,解决的办法是在前端采用多台BRAS并接或将多台BRAS放到各中继机房,采用分布认证方法。
      4、PPPOE常见故障代码及分析
      (1)645故障描述:拨号适配器未装
      这种情况主要针对Windows ME和Windows98而言,解决办法是在Windows98下添加拨号适配器组件即可。对Windows ME而言,因为它没有直接添加拨号适配器的选项,所以必须在控制面板中先删除拨号网络组件,再添加拨号网络组件完成适配器的添加。
      (2)691/629故障描述:不能通过验证
      可能的原因是用户的账户或者密码输入错误,或用户的账户余额不足,用户在使用时未正常退出而造成用户账号驻留,可等待几分钟或重新启动后再拨号。
      (3)630故障描述:无法拨号,没有合适的网卡和驱动
      可能的原因是网卡未安装好、网卡驱动不正常或网卡损坏。检查网卡是否工作正常或更新网卡驱动。
      (4)633故障描述:找不到电话号码簿,没有找到拨号连接
      这可能是没有正确安装PPPOE驱动或者驱动程序已遭损坏,或者Windows系统有问题。建议删除已安装的PPPOE驱动程序,重新安装PPPOE驱动,同时检查网卡是否工作正常。如仍不能解决问题,可能是系统有问题,建议重装系统后再添加PPPOE驱动。
      (5)720故障描述:不支持PPPOE连接
      它是Windows 2000特有的故障,建议重新启动后再进行连接,如仍不能排除故障,建议重装系统。
      (6)697故障描述:网卡禁用
      只要在设备管理中重新启用网卡即可。
      (7)769故障描述:拨号时报769错误
      在Windows XP系统中网卡被禁用、系统检测不到网卡或者拨号软件故障,有时会报769错误。重新启用网卡、检查网卡工作是否正常或重装拨号软件即可解决。
      (8)678故障描述:无法建立连接
      这个故障比较复杂,用户和BRAS链路中任何一个环节有问题,都可能导致678故障,应根据不同的情况作相应处理。
      5、结语
      PPPOE宽带接入方式对于用户管理的方便性、计费的灵活性都有一定的优势,但也有它的不足,需要在客户机上安装客户端软件,增加了调试、维修的工作量,而且PPPOE是点到点的接入方式,不支持组播功能。目前Windows XP系统本身已提供了对PPPOE协议的支持,可以在不另外安装客户端软件的情况下实现对PPPOE的接入,解决了用户安装PPPOE软件的问题。 PPPOE宽带接入是一种技术成熟、运营管理方便的接入方式,目前已被包括广电在内的各运营商普遍采用。
321/212>
Open Toolbar