防火墙(Firewall),也称防护墙,是由Check Point创立者Gil Shwed于1993年发明并引入国际互连网(US5606668(A)1993-12-15)。它是一项信息安全的防护系统,依照特定的规则,允许或是限制传输的数据通过。
分类:
基本上,依據防火牆管理的範圍,我們可以將防火牆區分為網域型與單一主機型的控管。
在單一主機型的控管方面, 主要的防火牆有封包過濾型的 Netfilter 與依據服務軟體程式作為分析的 TCP Wrappers 兩種。
若以區域型的防火牆而言, 由於此類防火牆都是當作路由器角色,因此防火牆類型主要則有封包過濾的 Netfilter 與利用代理伺服器 (proxy server) 進行存取代理的方式了。
说明:
netfilter (封包過濾機制)
所謂的封包過濾,亦即是分析進入主機的網路封包,將封包的表頭資料捉出來進行分析,以決定該連線為放行或抵擋的機制。 由於這種方式可以直接分析封包表頭資料,所以包括硬體位址(MAC), 軟體位址 (IP), TCP, UDP, ICMP 等封包的資訊都可以進行過濾分析的功能,因此用途非常的廣泛。(其實主要分析的是 OSI 七層協定的 2, 3, 4 層)在 Linux 上面我們使用核心內建的 Netfilter 這個機制,而 Netfilter 提供了 iptables 這個軟體來作為防火牆封包過濾的指令。由於 Netfilter 是核心內建的功能,因此他的效率非常的高! 非常適合於一般小型環境的設定呢!Netfilter 利用一些封包過濾的規則設定,來定義出什麼資料可以接收, 什麼資料需要剔除,以達到保護主機的目的.
TCP Wrappers (程式控管)
另一種抵擋封包進入的方法,為透過伺服器程式的外掛 (tcpd) 來處置的!與封包過濾不同的是, 這種機制主要是分析誰對某程式進行存取,然後透過規則去分析該伺服器程式誰能夠連線、誰不能連線。 由於主要是透過分析伺服器程式來控管,因此與啟動的埠口無關,只與程式的名稱有關。 舉例來說,我們知道 FTP 可以啟動在非正規的 port 21 進行監聽,當你透過 Linux 內建的 TCP wrappers 限制 FTP 時, 那麼你只要知道 FTP 的軟體名稱 (vsftpd) ,然後對他作限制,則不管 FTP 啟動在哪個埠口,都會被該規則管理的。
Proxy (代理伺服器)
其實代理伺服器是一種網路服務,它可以『代理』使用者的需求,而代為前往伺服器取得相關的資料。就有點像底下這個圖示吧:
在客服机与网络之间增加代理来对传输的数据做出管理。
Version 2.0:使用 ipfwadm
Version 2.2:使用 ipchains ;
Version 2.4 ~ 2.6 :主要是使用 iptables
基本原理
如下图所示,当报文来到时先进行拆包然后逐一匹配设置的规则,匹配上时执行规则对应的动作,需要注意的是规则的处理顺序:如果在某个规则匹配后将包丢弃是不会进行后面的处理的。
但实际上netfilter的处理流程更为复杂。
实际流程
如下图所示, 根据防火墙规则的特性分类,将规则使用Filter, Mangle, nat 和自定义等三个不同的表分别管理起来。
filter:主要跟進入 Linux 本機的封包有關,這個是預設的 table
INPUT:主要與想要進入我們 Linux 本機的封包有關;
OUTPUT:主要與我們 Linux 本機所要送出的封包有關;
FORWARD:和本机处理无关,与nat有较多关联,用于转包
nat : 是 Network Address Translation 的縮寫, 這個表格主要在進行來源與目的之 IP 或 port 的轉換,與 Linux 本機較無關,主要與 Linux 主機後的區域網路內電腦較有相關。
PREROUTING:在進行路由判斷之前所要進行的規則(DNAT/REDIRECT)
POSTROUTING:在進行路由判斷之後所要進行的規則(SNAT/MASQUERADE)
OUTPUT:與發送出去的封包有關
mangle :這個表格主要是與特殊的封包的路由旗標有關, 早期僅有 PREROUTING 及 OUTPUT 鏈,不過從 kernel 2.4.18 之後加入了 INPUT 及 FORWARD 鏈。 由於這個表格與特殊旗標相關性較高,所以像咱們這種單純的環境當中,較少使用 mangle 這個表格。
当包来到时的处理流程如下
封包進入 Linux 主機使用資源 (路徑 A): 在路由判斷後確定是向 Linux 主機要求資料的封包,主要就會透過 filter 的 INPUT 鏈來進行控管;
封包經由 Linux 主機的轉遞,沒有使用主機資源,而是向後端主機流動 (路徑 B): 在路由判斷之前進行封包表頭的修訂作業後,發現到封包主要是要透過防火牆而去後端,此時封包就會透過路徑 B 來跑動。 也就是說,該封包的目標並非我們的 Linux 本機。主要經過的鏈是 filter 的 FORWARD 以及 nat 的 POSTROUTING, PREROUTING。 這路徑 B 的封包流向使用情況。
封包由 Linux 本機發送出去 (路徑 C): 例如回應用戶端的要求,或者是 Linux 本機主動送出的封包,都是透過路徑 C 來跑的。先是透過路由判斷, 決定了輸出的路徑後,再透過 filter 的 OUTPUT 鏈來傳送的!當然,最終還是會經過 nat 的 POSTROUTING 鏈。
iptables [-t tables] [-L] [-nv]選項與參數:
-t :後面接 table ,例如 nat 或 filter ,若省略此項目,則使用預設的 filter
-L :列出目前的 table 的規則
-n :不進行 IP 與 HOSTNAME 的反查,顯示訊息的速度會快很多!
-v :列出更多的資訊,包括通過該規則的封包總位元數、相關的網路介面等
範例: 列出 filter table 三條鏈的規則 [root@www ~]# iptables -L -nChain INPUT (policy ACCEPT) <==針對 INPUT 鏈,且預設政策為可接受 target prot opt source destination <==說明欄 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED <==第 1 條規則 ACCEPT icmp -- 0.0.0.0/0 0.0.0.0/0 <==第 2 條規則 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 <==第 3 條規則 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22 <==以下類推 REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited Chain FORWARD (policy ACCEPT) <==針對 FORWARD 鏈,且預設政策為可接受target prot opt source destinationREJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibitedChain OUTPUT (policy ACCEPT) <==針對 OUTPUT 鏈,且預設政策為可接受target prot opt source destination範例:列出 nat table 三條鏈的規則[root@www ~]# iptables -t nat -L -nChain PREROUTING (policy ACCEPT) target prot opt source destination Chain POSTROUTING (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination
iptables [-t tables] [-FXZ]选项与参数: -F :清除所有的已订定的规则; -X :杀掉所有使用者 "自定义" 的 chain (应该说的是 tables ); -Z :将所有的 chain 的计数与流量统计都归零范例:清除本机防火墙 (filter) 的所有规则
iptables [-t nat] -P [INPUT,OUTPUT,FORWARD] [ACCEPT,DROP]选项与参数: 当你的封包不在你设定的规则之内时,则该封包的通过与否,是以 Policy 的设定为准.-P :定义政策( Policy )。注意,这个 P 为大写啊! ACCEPT :该封包可接受 DROP :该封包直接丢弃,不会让 client 端知道为何被丢弃。
iptables [-AI 链名] [-io 网络接口] [-p 协议] \> [-s 来源IP/网域] [-d 目标IP/网域] -j [ACCEPT|DROP|REJECT|LOG]选项与参数: -AI 链名:针对某的链进行规则的 "插入" 或 "累加" -A :新增加一条规则,该规则增加在原本规则的最后面。例如原本已经有四条规则, 使用 -A 就可以加上第五条规则! -I :插入一条规则。如果没有指定此规则的顺序,默认是插入变成第一条规则。 例如原本有四条规则,使用 -I 则该规则变成第一条,而原本四条变成 2~5 号 链 :有 INPUT, OUTPUT, FORWARD 等,此链名称又与 -io 有关,请看底下。 -io 网络接口:设定封包进出的接口规范 -i :封包所进入的那个网络接口,例如 eth0, lo 等接口。需与 INPUT 链配合; -o :封包所传出的那个网络接口,需与 OUTPUT 链配合; -p 协定:设定此规则适用于哪种封包格式 主要的封包格式有: tcp, udp, icmp 及 all 。 -s 来源 IP/网域:设定此规则之封包的来源项目,可指定单纯的 IP 或包括网域,例如: IP :192.168.0.100 网域:192.168.0.0/24, 192.168.0.0/255.255.255.0 均可。 若规范为『不许』时,则加上 ! 即可,例如: -s ! 192.168.100.0/24 表示不许 192.168.100.0/24 之封包来源; -d 目标 IP/网域:同 -s ,只不过这里指的是目标的 IP 或网域。 -j :后面接动作,主要的动作有接受(ACCEPT)、丢弃(DROP)、拒绝(REJECT)及记录(LOG)
iptables [-AI 链] [-io 网络接口] [-p tcp,udp] [-s 来源IP/网域] [--sport 埠口范围] [-d 目标IP/网域] [--dport 埠口范围] -j [ACCEPT|DROP|REJECT]选项与参数: --sport 埠口范围:限制来源的端口号码,端口号码可以是连续的,例如 1024:65535 --dport 埠口范围:限制目标的端口号码。
iptables -A INPUT [-m state] [--state 状态]选项与参数: -m :一些 iptables 的外挂模块,主要常见的有: state :状态模块 mac :网络卡硬件地址 (hardware address) --state :一些封包的状态,主要有: INVALID :无效的封包,例如数据破损的封包状态 ESTABLISHED:已经联机成功的联机状态; NEW :想要新建立联机的封包状态; RELATED :这个最常用!表示这个封包是与我们主机发送出去的封包有关 最典型的就是ftp连接,当ftp的数据通道(20端口)的第一个包来时,就会被认为是RELATED,因为它和处于ETABLISHED状态的命令通道(21端口)的连接有关系。
示例:
只要已建立或相关封包就予以通过,只要是不合法封包就丢弃 iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT iptables -A INPUT -m state --state INVALID -j DROP
针对局域网络内的 aa:bb:cc:dd:ee:ff 主机开放其联机 iptables -A INPUT -m mac --mac-source aa:bb:cc:dd:ee:ff -j ACCEP T选项与参数: --mac-source :就是来源主机的 MAC
iptables -A INPUT [-p icmp] [--icmp-type 类型] -j ACCEPT 选项与参数: --icmp-type :后面必须要接 ICMP 的封包类型,也可以使用代号, 例如 8 代表 echo request 的意思。
/usr/share/doc/kernel-doc-2.6.32/Documentation/networking/ip-sysctl.txt
我们在前一章谈到所谓的阻断式服务 (DoS) 攻击法当中的一种方式,就是利用 TCP 封包的 SYN 三向交握原理所达成的, 这种方式称为 SYN Flooding 。那如何预防这种方式的攻击呢?我们可以启用核心的 SYN Cookie 模块啊! 这个 SYN Cookie 模块可以在系统用来启动随机联机的埠口 (1024:65535) 即将用完时自动启动。
当启动 SYN Cookie 时,主机在发送 SYN/ACK 确认封包前,会要求 Client 端在短时间内回复一个序号,这个序号包含许多原本 SYN 封包内的信息,包括 IP、port 等。若 Client 端可以回复正确的序号,那么主机就确定该封包为可信的,因此会发送 SYN/ACK 封包,否则就不理会此一封包。
透过此一机制可以大大的降低无效的 SYN 等待端口,而避免 SYN Flooding 的 DoS 攻击说! 那么如何启动这个模块呢?很简单,这样做即可:
echo "1" > /proc/sys/net/ipv4/tcp_syncookies
但是这个设定值由于违反 TCP 的三向交握 (因为主机在发送 SYN/ACK 之前需要先等待 client 的序号响应), 所以可能会造成某些服务的延迟现象,例如 SMTP (mail server)。 不过总的来说,这个设定值还是不错用的! 只是不适合用在负载已经很高的服务器内喔! 因为负载太高的主机有时会让核心误判遭受 SYN Flooding 的攻击呢。
如果是为了系统的 TCP 封包联机优化,则可以参考 tcp_max_syn_backlog, tcp_synack_retries, tcp_abort_on_overflow 这几个设定值的意义。
阻断式服务常见的是 SYN Flooding ,不过,我们知道系统其实可以接受使用 ping 的响应, 而 ping 的封包数据量是可以给很大的!想象一个状况, 如果有个搞破坏的人使用 1000 台主机传送 ping 给你的主机,而且每个 ping 都高达数百 K bytes时, 你的网络带宽会怎样?要嘛就是带宽被吃光,要嘛可能系统会当机! 这种方式分别被称为 ping flooding (不断发 ping) 及 ping of death (发送大的 ping 封包)。
那如何避免呢?取消 ICMP 类型 8 的 ICMP 封包回应就是了。我们可以透过防火墙来抵挡, 这也是比较建议的方式。当然也可以让核心自动取消 ping 的响应。不过你必须要了解, 某些局域网络内常见的服务 (例如动态 IP 分配 DHCP 协议) 会使用 ping 的方式来侦测是否有重复的 IP ,所以你最好不要取消所有的 ping 响应比较好。
核心取消 ping 回应的设定值有两个,分别是:/proc/sys/net/ipv4 内的 icmp_echo_ignore_broadcasts (仅有 ping broadcast 地址时才取消 ping 的回应) 及 icmp_echo_ignore_all (全部的 ping 都不回应)。鸟哥建议设定 icmp_echo_ignore_broadcasts 就好了。 你可以这么做:
echo "1" > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
咱们的核心还可以针对不同的网络接口进行不一样的参数设定喔!网络接口的相关设定放置在 /proc/sys/net/ipv4/conf/ 当中,每个接口都以接口代号做为其代表,例如 eth0 接口的相关设定数据在 /proc/sys/net/ipv4/conf/eth0/ 内。那么网络接口的设定数据有哪些比较需要注意的呢? 大概有底下这几个:
rp_filter:称为逆向路径过滤 (Reverse Path Filtering), 可以藉由分析网络接口的路由信息配合封包的来源地址,来分析该封包是否为合理。举例来说,你有两张网卡,eth0 为 192.168.1.10/24 ,eth1 为 public IP 。那么当有一个封包自称来自 eth1 ,但是其 IP 来源为 192.168.1.200 , 那这个封包就不合理,应予以丢弃。这个设定值建议可以启动的。
log_martians:这个设定数据可以用来启动记录不合法的 IP 来源, 举例来说,包括来源为 0.0.0.0、127.x.x.x、及 Class E 的 IP 来源,因为这些来源的 IP 不应该应用于 Internet 啊。 记录的数据默认放置到核心放置的登录档 /var/log/messages
accept_source_route:或许某些路由器会启动这个设定值, 不过目前的设备很少使用到这种来源路由,你可以取消这个设定值。
accept_redirects:当你在同一个实体网域内架设一部路由器, 但这个实体网域有两个 IP 网域,例如 192.168.0.0/24, 192.168.1.0/24。此时你的 192.168.0.100 想要向 192.168.1.100 传送讯息时,路由器可能会传送一个 ICMP redirect 封包告知 192.168.0.100 直接传送数据给 192.168.1.100 即可,而不需透过路由器。因为 192.168.0.100 与 192.168.1.100确实是在同一个实体线路上 (两者可以直接互通),所以路由器会告知来源 IP 使用最短路径去传递数据。但那两部主机在不同的 IP 段,却是无法实际传递讯息的!这个设定也可能会产生一些轻微的安全风险,所以建议关闭他。
send_redirects:与上一个类似,只是此值为发送一个 ICMP redirect 封包。 同样建议关闭。(事实上,鸟哥就曾经为了这个 ICMP redirect 的问题伤脑筋!其实关闭 redirect 的这两个项目即可啊!)
开启路由功能
echo "1" > /proc/sys/net/ipv4/ip_forward
当我们使用-m state模块功能的时候,iptables除了装载xt_state.ko模块外,还装载ip_conntrack.ko,接着它会建立
/proc/net/ip_conntrack数据库
保存各种超时的文件在 /proc/sys/net/ipv4/netfilter/*
如
ip_conntrack_tcp_timeout_syn_sent 120s ip_conntrack_tcp_timeout_syn_recv 60s ip_conntrack_tcp_timeout_syn_established 432000s ip_conntrack_udp_timeout 30s ip_conntrack_udp_timeout_stream 180s ip_conntrack_ICMP_timeout 30s
追踪的最大连接数 /proc/sys/net/ipv4/ip_conntrack_max
系统默认为 最大内存(K)/16K/(系统位数/32),若 512M内存,则默认的最大连接数为 32768
要修改这个限制,必须以手动方式加载 ip_contrack模块,命令为:
modprobe ip_conntrack hashsize=16384
每个hashsize可容纳8条连接,那么修改后连接数为16384*8=131072
每条连接消耗内存为228B,可以查看/var/log/message ip_conntrack加载日志
131072*228/(1024*1024)=28.5M
可以使用raw table功能来取消某些连接的追踪功能,如下
iptables -t raw -A PREROUTING -i eth0 -o eth1 -p tcp --dport 25 -j NOTRACK iptables -t raw -A PREROUTING -i eth1 -o eth0 -p tcp --sport 25 -j NOTRACK
这样将使包跳过NAT和ip_contrack模块,造成不能NAT功能;
对于复杂的通讯协议,必须加载扩展模块,如ftp,必须加载
modprobe ip_conntrack_ftp
modprobe ip_nat_ftp
虽然你可以使用『 echo "1" > /proc/sys/net/ipv4/conf/???/rp_filter 』之类的方法来启动这个项目,不过, 鸟哥比较建议修改系统设定值,那就是 /etc/sysctl.conf 这个档案!假设我们仅有 eth0 这个以太接口,而且上述的功能要通通启动, 那你可以这样做:
vim /etc/sysctl.conf# Adding by VBird 2011/01/28 net.ipv4.tcp_syncookies = 1 net.ipv4.icmp_echo_ignore_broadcasts = 1 net.ipv4.conf.all.rp_filter = 1 net.ipv4.conf.default.rp_filter = 1 net.ipv4.conf.eth0.rp_filter = 1 net.ipv4.conf.lo.rp_filter = 1