精华区 [关闭][返回]

当前位置:网易精华区>>讨论区精华>>电脑技术>>● FreeBSD>>OpenBSD 数据包过滤 PF FAQ中文版(转)-6

主题:OpenBSD 数据包过滤 PF FAQ中文版(转)-6
发信人: drillwater(灌水)
整理人: sungang(2004-11-15 10:15:50), 站内信件
(续上)

 
    pass in on $ext_if proto tcp from any to any port 21 keep state 
    pass in on $ext_if proto tcp from any to any port > 49151 \ 
       keep state 
 
如果需要可以调整上述端口范围。在OpenBSD的ftpd(8)环境下,可以通过sysctl(8)进行调整 net.inet.ip.porthifirst 和net.inet.ip.porthilast。 
 
使用NAT外部 PF防火墙保护FTP服务器 
 
这种情况下,防火墙必须将数据重定向到FTP服务器。为了讨论方便,我们假设该FTP服务器使用标准的OpenBSD ftpd(8),并使用默认端口范围。 
 
这里有个例子 
 
    ftp_server = "10.0.3.21" 
 
    rdr on $ext_if proto tcp from any to any port 21 -> $ftp_server \ 
       port 21 
    rdr on $ext_if proto tcp from any to any port 49152:65535 -> \ 
       $ftp_server port 49152:65535 
 
    # in on $ext_if 
    pass in quick on $ext_if proto tcp from any to $ftp_server \ 
       port 21 keep state 
    pass in quick on $ext_if proto tcp from any to $ftp_server \ 
       port > 49151 keep state 
 
    # out on $int_if 
    pass out quick on $int_if proto tcp from any to $ftp_server \ 
       port 21 keep state 
    pass out quick on $int_if proto tcp from any to $ftp_server \ 
       port > 49151 keep state 
FTP的更多信息 
过滤FTP和FTP如何工作的更多信息可以参考下面的白皮书。 
ftp reviewed!(原文有超级链接) 
------------------------------------------------------------------------------ 
$OpenBSD: ftp.html,v 1.14 2004/05/07 01:55:23 nick Exp $ 
============================================================================== 
 
PF: pf验证: 用Shell 进行网关验证 
 
------------------------------------------------------------------------------ 
 
目录 
 
  * 简介 
  * 配置 
      + 将authpf连入主策略集 
      + 配置加载的策略 
      + 访问控制列表 
      + 将authpf配置为用户shell 
  * 查看登陆者 
  * 更多信息 
  * 实例 
 
------------------------------------------------------------------------------ 
 
简介 
 
Authpf(8)是身份认证网关的用户shell。身份认证网关类似于普通网关,只不过用户必须在网关上通过身份验证后才能使用该网关。当用户shell被设置为/usr/sbin/authpf时(例如,代替了ksh(1),csh(1)等),并且用户通过SSH登录,authpf将对pf(4)策略集做必要的修改以便该用户的数据包可以通过过滤器或者(和)使用NAT、重定向功能。一旦用户退出登录或者连接被断开,authpf将移除加载到该用户上的所有策略,同时关闭该用户打开的所有会话。因此,只有当用户保持着他的SSH会话进程时他才具备透过防火墙发送数据包的能力。 
 
Authpf通过向附加到锚点的命名策略集增加策略来改变pf(4)的策略集。每次用户进行身份验证,authpf建立一个新的命名策略集,并将已经配置好的filter、nat、binat和rdr规则加载上去。被authpf所加载的策略可以被配置为针对单独的一个用户相关或者针对总体。 
 
Authpf可以应用在: 
 
  * 在允许用户访问因特网之前进行身份验证。 
  * 赋予特殊用户访问受限网络的权利,例如管理员。 
  * 只允许特定的无线网络用户访问特定的网络。 
  * 允许公司员工在任何时候访问公司网络,而公司之外的用户不能访问,并可以将这些用户重定向到特定的基于用户名的资源(例如他们自己的桌面)。 
  * 在类似图书馆这样的地方通过PF限制guest用户对因特网的访问。Authpf可以用来向已注册用户开放完全的因特网连接。 
 
Authpf通过syslogd(8)记录每一个成功通过身份验证用户的用户名、IP地址、开始结束时间。通过这些信息,管理员可以确定谁在何时登陆,也使得用户对其网络流量负责。 
 
配置 
 
配置authpf的基本步骤大致描述如下。详细的信息请查看man手册。 
 
将authpf连入主策略集 
 
通过使用锚点策略将authpf连入主策略集: 
 
    nat-anchor authpf 
    rdr-anchor authpf 
    binat-anchor authpf 
    anchor authpf 
 
锚点策略放入策略集的位置就是PF中断执行主策略集转为执行authpf策略的位置。上述4个锚点策略并不需要全部存在,例如,当authpf没有被设置加载任何nat策略时,nat-anchor策略可被省略。 
 
配置加载的策略 
 
Authpf通过下面两个文件之一加载策略: 
  
  * /etc/authpf/users/$USER/authpf.rules 
  * /etc/authpf/authpf.rules 
 
第一个文件包含只有当用户$USER(将被替换为具体的用户名)登录时才被加载的策略。当特殊用户(例如管理员)需要一系列不同于其他默认用户的策略集时可以使用每用户策略配置。第二个文件包含没定义自己的authpf.rules文件的用户所默认加载的策略。如果用户定义的文件存在,将覆盖默认文件。这两个文件至少存在其一,否则authpf将不会工作。 
 
过滤器和传输策略与其他的PF策略集语法一样,但有一点不同:authpf允许使用预先定义的宏: 
 
  * $user_ip – 登录用户的IP地址 
  * $user_id – 登录用户的用户名 
 
推荐使用宏$user_ip,只赋予通过身份验证的计算机透过防火墙的权限。 
 
访问控制列表 
 
可以通过在/etc/authpf/banned/目录下建立以用户名命名的文件来阻止该用户使用authpf。文件的内容将在authpf断开与该用户的连接之前显示给他,这为通知该用户被禁止访问的原因并告知他解决问题联系人提供了一个便捷的途径。 
 
相反,有可能只允许特定的用户访问,这时可以将这些用户的用户名写入/etc/authpf/authpf.allow文件。如果该文件不存在或者文件中输入了“*”,则authpf将允许任何成功通过SSH登录的用户进行访问(没有被明确禁止的用户)。 
 
如果authpf不能断定一个用户名是被允许还是禁止,它将打印一个摘要信息并断开该用户的连接。明确禁止将会使明确允许失效。 
 
将authpf配置为用户shell 
 
authpf必须作为用户的登录shell才能正常工作。当用户成功通过sshd(8)登录后,authpf将被作为用户的shell执行。它将检查该用户是否有权使用authpf,并从适当的文件中加载策略,等等。 
 
有两种途径将authpf设置为用户shell: 
 
 1.为每个用户手动使用chsh(1), vipw(8), useradd(8), usermod(8),等。 
 2.通过把一些用户分配到一个登录类,在文件/etc/login.conf中改变这个登录类的shell属性 
 
查看登陆者 
 
一旦用户成功登录,并且authpf调整了PF的策略,authpf将改变它的进程名以显示登录者的用户名和IP地址: 
 
    # ps -ax | grep authpf 
    23664 p0  Is+     0:00.11 -authpf: [email protected] (authpf) 
 
在这里用户chalie从IP地址为192.168.1.3的主机登录。用户可以通过向authpf进程发送SIGTERM信号退出登录。Authpf也将移除加载到该用户上的策略并关闭任何该用户打开的会话连接。 
 
    # kill -TERM 23664 
 
更多信息 
 
请查询man手册 
 
实例 
 
OpenBSD网关通过authpf对一个大型校园无线网的用户进行身份验证。一旦某个用户验证通过,假设他不在禁用列表中,他将被允许SSH并访问网页(包括安全网站https),也可以访问该校园的任一个DNS服务器。 
 
文件 /etc/authpf/authpf.rules包含下列策略: 
 
wifi_if = "wi0" 
dns_servers = "{ 10.0.1.56, 10.0.2.56 }" 
 
pass in quick on $wifi_if proto udp from $user_ip to $dns_servers \ 
   port domain keep state 
pass in quick on $wifi_if proto tcp from $user_ip to port { ssh, http, \ 
   https } flags S/SA keep state 
 
管理员charlie除了网页冲浪和使用SSH外还需要访问校园网的SMTP和POP3服务器。下列策略被配置在/etc/authpf/users/charlie/authpf.rules 中: 
 
 
wifi_if = "wi0" 
smtp_server = "10.0.1.50" 
pop3_server = "10.0.1.51" 
dns_servers = "{ 10.0.1.56, 10.0.2.56 }" 
 
pass in quick on $wifi_if proto udp from $user_ip to $dns_servers \ 
   port domain keep state 
pass in quick on $wifi_if proto tcp from $user_ip to $smtp_server \ 
   port smtp flags S/SA keep state 
pass in quick on $wifi_if proto tcp from $user_ip to $pop3_server \ 
   port pop3 flags S/SA keep state 
pass in quick on $wifi_if proto tcp from $user_ip to port { ssh, http, \ 
   https } flags S/SA keep state 
 
定义在/etc/pf.conf中的主策略集配置如下: 
 
# macros 
wifi_if = "wi0" 
ext_if  = "fxp0" 
 
scrub in all 
 
# filter 
block drop all 
 
pass out quick on $ext_if proto tcp from $wifi_if:network flags S/SA \ 
   modulate state 
pass out quick on $ext_if proto { udp, icmp } from $wifi_if:network \ 
   keep state 
 
pass in quick on $wifi_if proto tcp from $wifi_if:network to $wifi_if \ 
   port ssh flags S/SA keep state 
 
anchor authpf in on $wifi_if 
 
该策略集非常简单,作用如下: 
 
  * 阻断所有(默认拒绝)。 
  * 放行外部网卡接口上的来自无线网络并流向外部的TCP,UDP和ICMP数据包。 
  * 放行来自无线网络,目的地址为网关本身的SSH数据包。该策略是用户登录所必须的。 
  * 在无线网络接口上为流入数据建立锚点“authpf”。 
 
设计主策略集的主导思想为:阻断任何包并允许尽可能小的数据流通过。在外部接口上流出数据包是允许的,但是默认否策略阻断了由无线接口进入的数据包。用户一旦通过验证,他们的数据包被允许通过无线接口进入并穿过网关到达其他网络。 
 
------------------------------------------------------------------------------ 
$OpenBSD: authpf.html,v 1.7 2004/05/07 01:55:23 nick Exp $ 
============================================================================== 
实例:家庭和小型办公室防火墙 
PF: 实例:家庭和小型办公室防火墙 
 
------------------------------------------------------------------------------ 
 
目录 
 
  * 概况 
      + 网络 
      + 目标 
      + 准备 
  * 规则集 
      + 宏 
      + 选项 
      + 规格化 
      + NAT 
      + 重定向 
      + 过滤规则 
  * 完整规则集 
 
------------------------------------------------------------------------------ 
 
概况 
 
在这个例子中,PF作为防火墙和NAT网关运行在OpenBSD机器上,为家庭或办公室的小型网络提供服务。总的目标是向内部网提供因特网接入,允许从因特网到防火墙的限制访问。下面将详细描述: 
 
网络 
 
网络配置如下: 
 
  [ COMP1 ]    [ COMP3 ] 
      |            |                               ADSL 
   ---+------+-----+------- fxp0 [ OpenBSD ] ep0 -------- ( 因特网 ) 
             | 
         [ COMP2 ] 
 
 
内部网有若干机器,图中只划出了3台,这些机器除了COMP3之外主要进行网页冲浪、电子邮件、聊天等;COMP3运行一个小型web服务器。内部网使用192.168.0.0/24网段。 
 
OpenBSD网关运行在 Pentium 100计算机上,装有两块网卡:一个3com 3c509B(ep0),另一个Intel EtherExpress Pro/100(fxp0)。该网关通过ADSL连接到因特网,同时通过NAT向内网共享因特网连接。外部网卡的IP地址动态分配。 
 
目标 
 
  * 向内部网络的每台计算机提供无限制的因特网接入。 
  * 启用一条“默认拒绝”策略。 
  * 允许下列来自因特网的请求访问防火墙: 
      + SSH (TCP 端口 22): 用来远程维护防火墙。 
      + Auth/Ident (TCP 端口 113): SMTP和IRC服务用到的端口。 
      + ICMP Echo Requests: ping(8)用到的ICMP包类型。 
  * 重定向访问80端口(访问web的请求)的请求到计算机COMP3,同时,允许指向COMP3计算机的80端口的数据流过防火墙。 
  * 记录外部网卡接口上的过滤日志。 
  * 默认为阻断的包返回一个 TCP RST 或者 ICMP Unreachable 信息。 
  * 尽量保持策略集简单并易于维护。 
 
准备 
 
这里假设作为网关的OpenBSD主机已经配置完成,包括IP网络配置,因特网连接和设置net.inet.ip.forwarding 的值为1。 
 
规则集 
 
下面将逐步建立策略集以满足上诉要求。 
 
宏 
 
定义下列宏以增强策略集的可维护性和可读性: 
 
    int_if = "fxp0" 
    ext_if = "ep0" 
 
    tcp_services = "{ 22, 113 }" 
    icmp_types = "echoreq" 
 
    priv_nets = "{ 127.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8 }" 
 
    comp3 = "192.168.0.3" 
 
前两行定义了发生过滤的网络接口。第3、4行定义了向因特网开放的服务端口号(SSH和ident/auth)和允许访问防火墙的ICMP包类型。第5行定义了回送地址段和RFC1918定义的私有地址段。最后一行定义了主机COMP3的IP地址。 
 
注意:如果ADSL接入因特网需要PPPoE,则过滤和NAT将发生在tun0接口上而不是ep0接口。 
 
选项 
 
下列两个选项用来设置阻断后的默认操作为反馈,并在外部接口设置开启日志记录: 
 
    set block-policy return 
    set loginterface $ext_if 
 
流量整修 
 
没有理由不起用对所有进入防火墙的所有包进行规格化,因此只需要简单的一行: 
 
    scrub in all 
 
NAT(网络地址转换) 
 
为所有内部网启用NAT可以通过下列策略: 
 
    nat on $ext_if from $int_if:network to any -> ($ext_if) 
 
由于外部网卡的IP地址是动态获得的,因此在外部网卡接口处增加小括号以使当IP地址发生变化时PF可以自适应。 
 
重定向 
 
第一个需要重定向策略的是ftp-proxy(8),只有这样内部网上的FTP客户端才可以访问因特网上的FTP服务器。 
 
    rdr on $int_if proto tcp from any to any port 21 -> 127.0.0.1 port 8021 
 
注意这条策略只捕获到21端口的数据包,如果用户通过其他端口访问FTP服务器,则在定义目的端口时需要使用list(列表),例如: from any to any port { 21, 2121 }。 
 
第二个重定向策略捕获因特网上的用户访问防火墙80端口的数据包。用户试图访问网络的web服务器时将产生合法的访问该端口的数据包,这些连接请求需要重定向到主机COMP3: 
 
    rdr on $ext_if proto tcp from any to any port 80 -> $comp3 
 
过滤规则 
 
过滤规则第一行是默认否规则: 
 
    block all 
 
这时没有任何数据包可以流过防火墙,甚至来自内部网络的数据包。下面的规则将逐个依据上面提到的目标开启防火墙上的虚拟接口。 
 
每个Unix系统都有一个“loopback(回送)”接口,它是用于系统中应用程序间通信的虚拟网络接口。在OpenBSD中,回送接口是lo(4)。 
 
    pass quick on lo0 all 
 
下一步,由RFC 1918定义的私有地址将在外部网卡接口的进和出方向被阻断。这些地址不应该出现在公网上,通过阻断这些地址可以保证防火墙不向外部网泄漏内网地址,同时也阻断了来自外部网中源地址为这些私有地址的数据包流入内网。 
 
    block drop in  quick on $ext_if from $priv_nets to any 
    block drop out quick on $ext_if from any to $priv_nets 
 
这里block drop用来通知PF停止反馈TCP RST或者ICMP Unreachabel 数据包。因为RFC 1918规定的地址不会存在于因特网上,发往那些地址的数据包将没有意义。Quick 选项用来通知PF如果这条规则匹配则不再进行其他规则的匹配操作,来自或流向$priv_nets的数据包将被立即丢弃。 
 
现在将打开因特网上的一些服务所用到的端口: 
 
    pass in on $ext_if inet proto tcp from any to ($ext_if) \ 
       port $tcp_services flags S/SA keep state 
 
通过在宏$tcp_services中定义服务端口可以更方便的进行维护。开放UDP服务也可一模仿上述语句,只不过改为proto udp。 
 
已经有了一条rdr策略将web访问请求转发到主机COMP3上,我们必须建立另一条过滤规则使得这些访问请求可以通过防火墙: 
 
    pass in on $ext_if proto tcp from any to $comp3 port 80 \ 
        flags S/SA synproxy state 
 
考虑到安全问题,我们使用TCP SYN Proxy保护web服务器——synproxy state。 
 
现在将允许ICMP包通过防火墙: 
 
    pass in inet proto icmp all icmp-type $icmp_types keep state 
 
类似于宏$tcp_services,当需要增加允许进入防火墙的ICMP数据包类型时可以容易地编辑宏$icmp_types。注意这条策略将应用于所有网络接口。 
 
现在数据流必须可以正常出入内部网络。我们假设内网的用户清楚自己的所作所为并且确定不会导致麻烦。这并不是必然有效的假设,在某些环境下更具限制性的策略集会更适合。 
 
    pass in on $int_if from $int_if:network to any keep state 
 
上面的策略将允许内网中的任何计算机发送数据包穿过防火墙;然而,这并没有允许防火墙主动与内网的计算机建立连接。这是一种好的方法吗?评价这些需要依靠网络配置的一些细节。如果防火墙同时充当DHCP服务器,它需要在分配一个地址之前ping一下该地址以确认该地址没有被占用。允许防火墙访问内部网络同时也允许了在因特网上通过ssh控制防火墙的用户访问内网。请注意禁止防火墙直接访问内网并不能带来高安全性,因为如果一个用户可以访问防火墙,他也可以改变防火墙的策略。增加下列策略可以使防火墙具备访问内网的能力: 
 
    pass out on $int_if from any to $int_if:network keep state 
 
如果这些策略同时存在,则keep state选项将不是必须的;所有的数据包都可以流经内网接口,因为一条策略规定了双向放行数据包。然而,如果没有pass out这条策略时,pass in策略必须要有keep state选项。这也是keep state的有点所在:在执行策略匹配之前将先进行state表检查,如果state表中存在匹配记录,数据包将直接放行而不比再进行策略匹配。这将提高符合比较重的防火墙的效率。 
 
最后,允许流出外部网卡接口的数据包通过防火墙 
 
    pass out on $ext_if proto tcp all modulate state flags S/SA 
    pass out on $ext_if proto { udp, icmp } all keep state 
 
TCP, UDP, 和 ICMP数据包将被允许朝因特网的方向出防火墙。State信息将被保存,以保证反馈回来的数据包通过防火墙。 
 
完整规则集 
 
# macros 
int_if = "fxp0" 
ext_if = "ep0" 
 
tcp_services = "{ 22, 113 }" 
icmp_types = "echoreq" 
 
priv_nets = "{ 127.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8 }" 
 
comp3 = "192.168.0.3" 
 
# options 
set block-policy return 
set loginterface $ext_if 
 
# scrub 
scrub in all 
 
# nat/rdr 
nat on $ext_if from $int_if:network to any -> ($ext_if) 
rdr on $int_if proto tcp from any to any port 21 -> 127.0.0.1 \ 
   port 8021 
rdr on $ext_if proto tcp from any to any port 80 -> $comp3 
 
# filter rules 
block all 
 
pass quick on lo0 all 
 
block drop in  quick on $ext_if from $priv_nets to any 
block drop out quick on $ext_if from any to $priv_nets 
 
pass in on $ext_if inet proto tcp from any to ($ext_if) \ 
   port $tcp_services flags S/SA keep state 
 
pass in on $ext_if proto tcp from any to $comp3 port 80 \ 
   flags S/SA synproxy state 
 
pass in inet proto icmp all icmp-type $icmp_types keep state 
 
pass in  on $int_if from $int_if:network to any keep state 
pass out on $int_if from any to $int_if:network keep state 
 
pass out on $ext_if proto tcp all modulate state flags S/SA 
pass out on $ext_if proto { udp, icmp } all keep state 
 
------------------------------------------------------------------------------ 
$OpenBSD: example1.html,v 1.15 2004/05/15 02:34:02 nick Exp $ 
 

(完)

PDF文档下载:ftp://chinaunix:[email protected]/openbsd-pf-faq中文版本/pf-faq-cn.pdf


----
   

[关闭][返回]