Unix课程设计 基于Linux内核的防火墙的分析与设计

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unix课程设计 基于Linux内核的防火墙的分析与设计相关的知识,希望对你有一定的参考价值。

课程设计的题目是 基于Linux内核的防火墙的分析与设计
下个星期就要交了,急用,各位帮帮忙
大哥们,这资料未必也太少了吧,我这是搞课程设计,这点资料怎么够用,有没完整点的啊

一、什么是状态机
有限状态机是一种用来进行对象行为建模的工具,其作用主要是描述对象在它的生命周期内所经历的状态序列,以及如何响应来自外界的各种事件。在面向对象的软件系统中,一个对象无论多么简单或者多么复杂,都必然会经历一个从开始创建到最终消亡的完整过程,这通常被称为对象的生命周期。一般说来,对象在其生命期内是不可能完全孤立的,它必须通过发送消息来影响其它对象,或者通过接受消息来改变自身。在大多数情况下,这些消息都只不过是些简单的、同步的方法调用而已。例如,在银行客户管理系统中,客户类(Customer)的实例在需要的时候,可能会调用帐户(Account)类中定义的getBalance()方法。在这种简单的情况下,类Customer并不需要一个有限状态机来描述自己的行为,主要原因在于它当前的行为并不依赖于过去的某个状态。

遗憾的是并不是所有情况都会如此简单,事实上许多实用的软件系统都必须维护一两个非常关键的对象,它们通常具有非常复杂的状态转换关系,而且需要对来自外部的各种异步事件进行响应。例如,在VoIP电话系统中,电话类(Telephone)的实例必须能够响应来自对方的随机呼叫,来自用户的按键事件,以及来自网络的信令等。在处理这些消息时,类Telephone所要采取的行为完全依赖于它当前所处的状态,因而此时使用状态机就将是一个不错的选择。

游戏引擎是有限状态机最为成功的应用领域之一,由于设计良好的状态机能够被用来取代部分的人工智能算法,因此游戏中的每个角色或者器件都有可能内嵌一个状态机。考虑RPG游戏中城门这样一个简单的对象,它具有打开(Opened)、关闭(Closed)、上锁(Locked)、解锁(Unlocked)四种状态,如图1所示。当玩家到达一个处于状态Locked的门时,如果此时他已经找到了用来开门的钥匙,那么他就可以利用它将门的当前状态转变为Unlocked,进一步还可以通过旋转门上的把手将其状态转变为Opened,从而成功地进入城内。

图1 控制城门的状态机

在描述有限状态机时,状态、事件、转换和动作是经常会碰到的几个基本概念。

状态(State) 指的是对象在其生命周期中的一种状况,处于某个特定状态中的对象必然会满足某些条件、执行某些动作或者是等待某些事件。"
事件(Event) 指的是在时间和空间上占有一定位置,并且对状态机来讲是有意义的那些事情。事件通常会引起状态的变迁,促使状态机从一种状态切换到另一种状态。
转换(Transition) 指的是两个状态之间的一种关系,表明对象将在第一个状态中执行一定的动作,并将在某个事件发生同时某个特定条件满足时进入第二个状态。
动作(Action) 指的是状态机中可以执行的那些原子操作,所谓原子操作指的是它们在运行的过程中不能被其他消息所中断,必须一直执行下去。

二、手工编写状态机
与其他常用的设计模式有所不同,程序员想要在自己的软件系统中加入状态机时,必须再额外编写一部分用于逻辑控制的代码,如果系统足够复杂的话,这部分代码实现和维护起来还是相当困难的。在实现有限状态机时,使用switch语句是最简单也是最直接的一种方式,其基本思路是为状态机中的每一种状态都设置一个case分支,专门用于对该状态进行控制。下面的代码示范了如何运用switch语句,来实现图1中所示的状态机:

switch (state)

// 处理状态Opened的分支
case (Opened):
// 执行动作Open
open();
// 检查是否有CloseDoor事件
if (closeDoor())
// 当前状态转换为Closed
changeState(Closed)

break;


// 处理状态Closed的分支
case (Closed):
// 执行动作Close
close();
// 检查是否有OpenDoor事件
if (openDoor())
// 当前状态转换为Opened
changeState(Opened);

// 检查是否有LockDoor事件
if (lockDoor())
// 当前状态转换为Locked
changeState(Locked);

break;


// 处理状态Locked的分支
case (Locked):
// 执行动作Lock
lock();
// 检查是否有UnlockDoor事件
if (unlockDoor())
// 当前状态转换为Unlocked
changeState(Unlocked);

break;


// 处理状态Unlocked的分支
case (Unlocked):
// 执行动作Unlock
unlock();
// 检查是否有LockDoor事件
if (lockDoor())
// 当前状态转换为Locked
changeState(Locked)

// 检查是否有OpenDoor事件
if (openDoor())
// 当前状态转换为Opened
changeSate(Opened);

break;



使用switch语句实现的有限状态机的确能够很好地工作,但代码的可读性并不十分理想,主要原因是在实现状态之间的转换时,检查转换条件和进行状态转换都是混杂在当前状态中来完成的。例如,当城门处于Opened状态时,需要在相应的case中调用closeDoor()函数来检查是否有必要进行状态转换,如果是的话则还需要调用changeState()函数将当前状态切换到Closed。显然,如果在每种状态下都需要分别检查多个不同的转换条件,并且需要根据检查结果让状态机切换到不同的状态,那么这样的代码将是枯燥而难懂的。从代码重构的角度来讲,此时更好的做法是引入checkStateChange()和performStateChange()两个函数,专门用来对转换条件进行检查,以及激活转换时所需要执行的各种动作。这样一来,程序结构将变得更加清晰:
switch (state)

// 处理状态Opened的分支
case (Opened):
// 执行动作Open
open();
// 检查是否有激发状态转换的事件产生
if (checkStateChange())
// 对状态机的状态进行转换
performStateChange();

break;


// 处理状态Closed的分支
case (Closed):
// 执行动作Close
close();
// 检查是否有激发状态转换的事件产生
if (checkStateChange())
// 对状态机的状态进行转换
performStateChange();

break;


// 处理状态Locked的分支
case (Locked):
// 执行动作Lock
lock();
// 检查是否有激发状态转换的事件产生
if (checkStateChange())
// 对状态机的状态进行转换
performStateChange();

break;


// 处理状态Unlocked的分支
case (Unlocked):
// 执行动作Lock
unlock();
// 检查是否有激发状态转换的事件产生
if (checkStateChange())
// 对状态机的状态进行转换
performStateChange();

break;



但checkStateChange()和performStateChange()这两个函数本身依然会在面对很复杂的状态机时,内部逻辑变得异常臃肿,甚至可能是难以实现。

在很长一段时期内,使用switch语句一直是实现有限状态机的唯一方法,甚至像编译器这样复杂的软件系统,大部分也都直接采用这种实现方式。但之后随着状态机应用的逐渐深入,构造出来的状态机越来越复杂,这种方法也开始面临各种严峻的考验,其中最令人头痛的是如果状态机中的状态非常多,或者状态之间的转换关系异常复杂,那么简单地使用switch语句构造出来的状态机将是不可维护的。

三、自动生成状态机
为实用的软件系统编写状态机并不是一件十分轻松的事情,特别是当状态机本身比较复杂的时候尤其如此,许多有过类似经历的程序员往往将其形容为"毫无创意"的过程,因为他们需要将大量的时间与精力倾注在如何管理好状态机中的各种状态上,而不是程序本身的运行逻辑。作为一种通用的软件设计模式,各种软件系统的状态机之间肯定会或多或少地存在着一些共性,因此人们开始尝试开发一些工具来自动生成有限状态机的框架代码,而在Linux下就有一个挺不错的选择——FSME(Finite State Machine Editor)。

图2 可视化的FSME

FSME是一个基于Qt的有限状态机工具,它能够让用户通过图形化的方式来对程序中所需要的状态机进行建模,并且还能够自动生成用C 或者Python实现的状态机框架代码。下面就以图1中城门的状态机为例,来介绍如何利用FSME来自动生成程序中所需要的状态机代码。

3.1状态机建模
首先运行fsme命令来启动状态机编辑器,然后单击工具栏上" "New"按钮来创建一个新的状态机。FSME中用于构建状态机的基本元素一共有五种:事件(Event)、输入(Input)、输出(Output)、状态(State)和转换(Transition),在界面左边的树形列表中可以找到其中的四种。

状态建模
在FSME界面左边的树形列表中选择"States"项,然后按下键盘上的Insert键来插入一个新的状态,接着在右下方的"Name"文本框中输入状态的名称,再在右上方的绘图区域单击该状态所要放置的位置,一个新的状态就创建好了。用同样的办法可以添加状态机所需要的所有状态,如图3所示。

图3 状态建模

事件建模

在FSME界面左边的树形列表中选" "Events"项,然后按下键盘上的Insert键来添加一个新的事件,接着在右下方的"Name"文本框中输入事件的名称,再单击"Apply"按钮,一个新的事件就创建好了。用同样的办法可以添加状态机所需要的所有事件,如图4所示。

图4 事件建模

转换建模

状态转换是整个建模过程中最重要的一个部分,它用来定义有限状态机中的一个状态是如何切换到另一个状态的。例如,当用来控制城门的状态机处于Opened状态时,如果此时有Close事件产生,那么状态机的当前状态将切换到Closed状态,这样一个完整的过程在状态机模型中可以用closeDoor这样一个转换来进行描述。

要在FSME中添加这样一个转换,首先需要在界面左边的树形列表中选" "States"下的"Opened"项,然后按下键盘上的Insert键来添加一个新的转换,接着在右下角的"Name"文本框中输入转换的名字"closeDoor",在"Condition"文本框中输入"Close"表明触发该转换的条件是事件Close的产生,在"Target"下拉框中选择"Closed"项表明该转换发生后状态机将被切换到Closed状态,最后再单击"Apply"按钮,一个新的状态转换关系就定义好了,如图5所示。用同样的办法可以添加状态机所需要的所有转换。

图5 转换建模

3.2" 生成状态机框架
使用FSME不仅能够进行可视化的状态机建模,更重要的是它还可以根据得到的模型自动生成用C 或者Python实现的状态机框架。首先在FSME界面左边的树形列表中选择"Root"项,然后在右下角的"Name"文本框中输入状态机的名字"DoorFSM",再从"Initial State"下拉列表中选择状态"Opened"作为状态机的初始化状态,如图6所示。

图6 设置初始属性

在将状态机模型保存为door.fsm文件之后,使用下面的命令可以生成包含有状态机定义的头文件:
$ fsmc door.fsm -d -o DoorFSM.
进一步还可以生成包含有状态机实现的框架代码:
$ fsmc door.fsm -d -impl DoorFSM.h -o DoorFSM.cpp

如果想对生成的状态机进行验证,只需要再手工编写一段用于测试的代码就可以了:
/*
* TestFSM.cpp
* 测试生成的状态机框架
*/

#include "DoorFSM.h"

int main()

DoorFSM door;
door.A(DoorFSM::Close);
door.A(DoorFSM::Lock);
door.A(DoorFSM::Unlock);
door.A(DoorFSM::Open);

有限状态机是由事件来进行驱动的,在FSME生成的状态机框架代码中,方法A()可以被用来向状态机发送相应的事件,从而提供状态机正常运转所需要的"动力"。状态机负责在其内部维护一个事件队列,所有到达的事件都会先被放到事件队列中进行等候,从而能够保证它们将按照到达的先后顺序被依次处理。在处理每一个到达的事件时,状态机都会根据自己当前所处的状态,检查与该状态对应的转换条件是否已经被满足,如果满足的话则激活相应的状态转换过程。

使用下面的命令能够将生成的状态机框架和测试代码编译成一个可执行文件:
$ g DoorFSM.cpp TestFSM.cpp -o fsm

由于之前在用fsmc命令生成状态机代码时使用了-d选项,生成的状态机框架中会包含一定的调试信息,包括状态机中每次状态转换时的激活事件、转换前的状态、所经历的转换、转换后的状态等,如下所示:

$ ./fsm
DoorFSM:event:'Close'
DoorFSM:state:'Opened'
DoorFSM:transition:'closeDoor'
DoorFSM:new state:'Closed'
DoorFSM:event:'Lock'
DoorFSM:state:'Closed'
DoorFSM:transition:'lockDoor'
DoorFSM:new state:'Locked'
DoorFSM:event:'Unlock'
DoorFSM:state:'Locked'
DoorFSM:transition:'unlockDoor'
DoorFSM:new state:'Unlocked'
DoorFSM:event:'Open'
DoorFSM:state:'Unlocked'
DoorFSM:transition:'openDoor'
DoorFSM:new state:'Opened'

3.3 定制状态机
目前得到的状态机已经能够响应来自外部的各种事件,并适当地调整自己当前所处的状态,也就是说已经实现了状态机引擎的功能,接下来要做的就是根据应用的具体需求来进行定制,为状态机加入与软件系统本身相关的那些处理逻辑。在FSME中,与具体应用相关的操作称为输出(Output),它们实际上就是一些需要用户给出具体实现的虚函数,自动生成的状态机引擎负责在进入或者退出某个状态时调用它们。

仍然以控制城门的那个状态机为例,假设我们希望在进入每个状态时都添加一部分处理逻辑。首在FSME界面左边的树形列表选择"Outputs"项,然后按下键盘上的Insert键来添加一个新的输出,接着在右下方的"Name"文本框中输入相应的名称,再单击"Apply"按钮,一个新的输出就创建好了,如图7所示。用同样的办法可以添加状态机所需要的所有输出。

图7 添加输出

当所有的输出都定义好之后,接下来就可以为状态机中的每个状态绑定相应的输出。首先在FSME界面左侧的"States"项中选择相应的状态,然后从右下角的"Available"列表框中选择与该状态对应的输出,再单击"<"按钮将其添加到"In"列表中,如图8所示。用同样的办法可以为状态机中的所有状态设置相应的输出,同一个状态可以对应有多个输出,其中In列表中的输出会在进入该状态时被调用,而Out列表中的输出则会在退出该状态时被调用,输出调用的顺序是与其在In或者Out列表中的顺序相一致的。

图8 为状态设置输出

由于对状态机模型进行了修改,我们需要再次生成状态机的框架代码,不过这次不需要加上-d参数:

$ fsmc door.fsm -o DoorFSM.h
$ fsmc door.fsm -d -impl DoorFSM.h -o DoorFSM.cpp

我们在新的状态机模型中添加了enterOpend、enterClosed、enterLocked和enterUnlocked四个输出,因此生成的类DoorFSM中会包含如下几个纯虚函数

virtual void enterOpened() = 0;
virtual void enterLocked() = 0;
virtual void enterUnlocked() = 0;
virtual void enterClosed() = 0;
显然,此时生成的状态机框架不能够再被直接编译了,我们必须从类DoorFSM派生出一个子类,并提供对这几个纯虚函数的具体实现:
/*
* DoorFSMLogic.h
* 状态机控制逻辑的头文件
*/
#include "DoorFSM.h"

class DoorFSMLogic : public DoorFSM


protected:
virtual void enterOpened();
virtual void enterLocked();
virtual void enterUnlocked();
virtual void enterClosed();
;

正如前面所提到过的,这几个函数实际上代表的正是应用系统的处理逻辑,作为例子我们只是简单地输出一些提示信息:
/*
* DoorFSMLogic.cpp
* 状态机控制逻辑的实现文件
*/
#include "DoorFSMLogic.h"
#include <iostream>

void DoorFSMLogic::enterOpened()

std::cout << "Enter Opened state." << std::endl;


void DoorFSMLogic::enterClosed()

std::cout << "Enter Closed state." << std::endl;


void DoorFSMLogic::enterLocked()

std::cout << "Enter Locked state." << std::endl;


void DoorFSMLogic::enterUnlocked()

std::cout << "Enter Unlocked state." << std::endl;

同样,为了对生成的状态机进行验证,我们还需要手工编写一段测试代码:
/*
* TestFSM.cpp
* 测试状态机逻辑
*/
#include "DoorFSMLogic.h"

int main()

DoorFSMLogic door;
door.A(DoorFSM::Close);
door.A(DoorFSM::Lock);
door.A(DoorFSM::Unlock);
door.A(DoorFSM::Open);

使用下面的命令能够将生成的状态机框架和测试代码编译成一个可执行文件:
$ g DoorFSM.cpp DoorFSMLogic.cpp TestLogic.cpp -o logic

运行结果如下所示:
$ ./logic
Enter Closed state.
Enter Locked state.
Enter Unlocked state.
Enter Opened state.

四、小结
在面向对象的软件系统中,有些对象具有非常复杂的生命周期模型,使用有限状态机是描述这类对象最好的方法。作为一种软件设计模式,有限状态机的概念虽然不算复杂,实现起来也并不困难,但它的问题是当状态机的模型复杂到一定的程度之后,会带来实现和维护上的困难。Linux下的FSME是一个可视化的有限状态机建模工具,而且支持状态机框架代码的自动生成,借助它可以更加轻松地构建基于有限状态机的应用系统。
参考技术A 1。介绍
本文将介绍如何利用LINUX来建立一个更具有实用意义的防火墙.
在当前,Internet越来越普遍的在企业,学校中使用,而安全问题也越来
越得到重视,如何能让内部的用户使用INTERNET而又能保护内部服务器以及
外部发布公共信息服务器的安全,这种需求使得防火墙广泛的在企业中得到
广泛的使用。但是,这种类型的防火墙是需要大量的经费的,如CISCO的IPX,
CHECK POINT的FIRWALL-I等。利用一个稳定内核的LINUX,同样也能做到一个
功能齐备的防火墙,而它的费用也只是其他同类防火墙的几十分只一。
感谢LINUX,它让我们用简单的步骤实现我们的目标。
本文可以自由转载,只要不破坏以及修改本文即可。
2。概念
在开始创建防火墙之前,我们有几个概念需要明白。
1。防火墙(Firewall),它是利用网络层的ip包过滤程序以及一些规则
来保护内部网的一种策略,有硬件实现,以及软件的实现。
2。停火区(非军事区),也称为DMZ,是一个公布信息的区域,外部
INTERNET以及内部INTRANET可以自由的访问该区。
3。内部网(Intranet,or Private Network),是企业或学校内部使用
的网络,可能重要的不对外公开的服务器都在其中。
4。外部网,可以说是INTERNET,是一个不安全的网络,存在大量有用的
信息以及一些可能有恶意攻击内部网的人。
5。地址转换,内部网的任何机器通过防火墙时,源地址均被设置成防火墙的
外部地址。即在外部看来,内部的机器均是一个地址。
下面是一个图例:
-----------------
| Internet |192.168.2.0/24
-----------------
| DMZ(停火区)
|192.168.2.1 ------
--- | |
| |192.168.1.1 | | 192.168.1.0/24
防火墙 | |------------------| |
| | | |
------- ------
|192.168.0.1
|
| Intranet(内部网)192.168.0.0/24
-----------------------------------
| | |
------------------------------------
注:以上IP的设置不是真实的,这需要结合您本地的需要来重新设置。
外部网侧的网卡是192.168.2.1
内部网侧的网卡是192.168.0.1
DMZ侧的网卡是:192.168.1.1
假定停火区中有一台机器(192.168.1.8)提供 80端口的WWW服务。
并假定内部网到外部需要进行NAT(地址转换的功能)

3。目标
防火墙要实现的目标如下:
1。内部无限制的访问INTERNET以及DMZ(停火区)。
2。外部可以访问DMZ的机器的公开的端口。在本例中是80.
3。外部不能访问到内部以及防火墙。
4。DMZ不可以访问内部。
通过这个目标,您就可以实现了一个防火墙的需求:
1。保护内部网络。
2。保护DMZ中的某些存在BUG的端口。只公布它需要提供的端口。

4。构建步骤
1。硬件:需要配好有3张网卡的机器。RAM越大越好。CPU越快越好。:-))
2。软件:当然是linux啦。我用的是redhat 5.0,5.1也可以。
3。内核:要打开ip-firewall,ip-masqurade(如果您想实现地址转换功能的话).....
具体可以看Firewall-HOWTO.
4。配置网卡,网上有很多配置的方法啦。
一般是先配好一张网卡,如果剩下的两张是跟原来是不同型号的
,需要配置
一下/etc/conf.modules.加上网卡的类型模块。如果是同类型的
网卡,就在
lilo.conf中加入append="ether=irq,iobase,eth0 ether=irq,iobase,eth1,ether=irq,iobase,eth2.
5。配置网卡的路由。
6。配置规则。也就是ipfwadm的规则啦。
有对ipfwadm不了解的可以看man ipfwadm or man ipfw.
#-----------------
ipfwadm -I -p deny
ipfwadm -O -p deny
ipfwadm -F -p deny
#------------------------------
# deny ip spoof.
ipfwadm -I -a deny -V 192.168.2.1 -S 192.168.0.0/24
ipfwadm -O -a deny -V 192.168.2.1 -D 192.168.0.0/24
# deny outside access intranet
ipfwadm -I -a deny -V 192.168.2.1 -D 192.168.0.0/24
ipfwadm -O -a deny -V 192.168.2.1 -S 192.168.0.0/24 -k
# allow firewall access outside
ipfwadm -I -a accept -V 192.168.2.1 -D 192.168.2.1 -k
ipfwadm -O -a accept -V 192.168.2.1 -S 192.168.2.1
# deny outside access firewall
ipfwadm -I -a deny -V 192.168.2.1 -D 192.168.1.1
ipfwadm -I -a deny -V 192.168.2.1 -D 192.168.2.1
# allow inside access outside.
ipfwadm -O -a accept -V 192.168.0.1 -D 192.168.0.0/24 -k
ipfwadm -I -a accept -V 192.168.0.1 -S 192.168.0.0/24

# allow outside access DMZ.
ipfwadm -O -a accept -P tcp -V 192.168.1.1 -D 192.168.1.8 80
ipfwadm -I -a accept -P tcp -V 192.168.1.1 -S 192.168.1.8 80 -k

# IP FORWARD。。
ipfwadm -F -a m -S 192.168.0.0/24
ipfwadm -F -a accept -S 192.168.1.0/24
ipfwadm -F -a accept -D 192.168.1.0/24

4。测试
现在,您可以通过测试来查看规则设置得是否正确。
1。从内部网访问外部INTERNEt,以及DMZ。
2. 从外部访问DMZ,看是否可以访问到80端口,以及是否可以访问其他端口。
3。从外部访问内部。看是否可以访问到。--不可以。

5。结论
这是一种简单的防火墙的配置方法。更复杂的配置还包括限制内部
用户对外部IP的访问。
现有的产品有清华得实的NETST防火墙,它提供图形化的配置界面和
更加细致的访问 控制以及针对IP的记费方案。
(详情请致电010-62771617,62771618,62771619,62771620)
6。感谢
感谢清华得实的李智鹏,是他给了我一个从事防火墙开发的机会,
以及许多的建议和帮助。
感谢NCIC的赵鹏,是他提供了完成本文的机器。
感谢我的女友,是她给了我在工作上的支持和鼓励。

感谢LINUX,它让我们用简单的步骤实现我们的目标。
出处:http://www.baofojiao.cn/aiwen/2007/0119/13374.html

参考资料:http://www.baofojiao.cn/aiwen/2007/0119/13374.html

参考技术B 那你就去搜集关于UNIX系统的防火墙的资料啊,然后自己总结分析。 参考技术C 书上有详细的介绍,多看点书.也可以在网上找到的,很方便的. 参考技术D 你去搜集关于UNIX系统的防火墙的资料吧!
总结分析饿!

以上是关于Unix课程设计 基于Linux内核的防火墙的分析与设计的主要内容,如果未能解决你的问题,请参考以下文章

Linux内核设计第三周学习总结 跟踪分析Linux内核的启动过程

Linux内核设计第六周学习总结 分析Linux内核创建一个新进程的过程

苹果的mac os是基于linux内核编写的吗?

hadoop课程设计

《Linux内核设计与实现》读书笔记Linux内核简介

《Linux内核设计与实现》读书笔记Linux内核简介