CentOS / Redhat Iptables 防火墙配置教程
Netfilter 是一款适用于 Linux 操作系统的基于主机的防火墙。它包含在 Linux 发行版中,默认情况下处于激活状态。此防火墙由名为 iptables 的程序控制。Netfilter 过滤在内核级别进行,在程序处理来自网络数据包的数据之前。
教程详细信息 | |
---|---|
难度等级 | 先进的 |
Root 权限 | 是的 |
要求 | Linux 终端 |
类别 | 防火墙 |
先决条件 | RHEL 或 CentOS v5.x/6.x |
操作系统兼容性 | CentOS • Linux • RHEL |
预计阅读时间 | 10 分钟 |
Iptables 配置文件
RHEL / CentOS / Fedora Linux 的默认配置文件是:- /etc/sysconfig/iptables – 通过读取此文件来激活防火墙的系统脚本。
任务:显示默认规则
键入以下命令:
iptables --line-numbers -n -L
示例输出:
Chain INPUT (policy ACCEPT) num target prot opt source destination 1 RH-Firewall-1-INPUT all -- 0.0.0.0/0 0.0.0.0/0 Chain FORWARD (policy ACCEPT) num target prot opt source destination 1 RH-Firewall-1-INPUT all -- 0.0.0.0/0 0.0.0.0/0 Chain OUTPUT (policy ACCEPT) num target prot opt source destination Chain RH-Firewall-1-INPUT (2 references) num target prot opt source destination 1 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 2 ACCEPT icmp -- 0.0.0.0/0 0.0.0.0/0 icmp type 255 3 ACCEPT udp -- 0.0.0.0/0 224.0.0.251 udp dpt:5353 4 ACCEPT udp -- 0.0.0.0/0 0.0.0.0/0 udp dpt:53 5 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED 6 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22 7 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:53 8 REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
任务:打开防火墙
输入以下两个命令来打开防火墙:
chkconfig iptables on service iptables start # restart the firewall service iptables restart # stop the firewall service iptables stop
了解防火墙
总共有 4 条链:
- INPUT – 默认链用于发往系统的数据包。使用它来打开或关闭传入端口(例如 80、25 和 110 等)和 IP 地址/子网(例如 202.54.1.20/29)。
- OUTPUT – 当系统生成数据包时使用默认链。使用此链打开或关闭传出端口和 IP 地址/子网。
- FORWARD – 当数据包通过另一个接口发送时,使用默认链。通常在将 Linux 设置为路由器时使用。例如,eth0 连接到 ADSL/Cable 调制解调器,eth1 连接到本地 LAN。使用 FORWARD 链从 LAN 向 Internet 发送和接收流量。
- RH-Firewall-1-INPUT – 这是用户定义的自定义链。它由 INPUT、OUTPUT 和 FORWARD 链使用。
数据包匹配规则
- 每个数据包都从链中的第一个规则开始。
- 数据包将继续运行,直到与规则匹配为止。
- 如果找到匹配项,则控制将跳转到指定的目标(例如 REJECT、ACCEPT、DROP)。
目标含义
- 目标ACCEPT表示允许数据包。
- 目标REJECT表示丢弃数据包并向远程主机发送错误消息。
- 目标DROP表示丢弃数据包并且不向远程主机或发送主机发送错误消息。
/etc/sysconfig/iptables
编辑/etc/sysconfig/iptables,输入:
# vi /etc/sysconfig/iptables
你将看到如下默认规则:
*filter :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0] :RH-Firewall-1-INPUT - [0:0] -A INPUT -j RH-Firewall-1-INPUT -A FORWARD -j RH-Firewall-1-INPUT -A RH-Firewall-1-INPUT -i lo -j ACCEPT -A RH-Firewall-1-INPUT -p icmp --icmp-type any -j ACCEPT -A RH-Firewall-1-INPUT -p udp --dport 5353 -d 224.0.0.251 -j ACCEPT -A RH-Firewall-1-INPUT -p udp -m udp --dport 53 -j ACCEPT -A RH-Firewall-1-INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT -A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT -A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 53 -j ACCEPT -A RH-Firewall-1-INPUT -j REJECT --reject-with icmp-host-prohibited COMMIT
丢弃所有流量
查找行:
*filter :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0]
更新如下,将 INPUT 和 FORWARD 内置链的默认策略从 ACCEPT 更改为 DROP:
:INPUT DROP [0:0] :FORWARD DROP [0:0]
记录并删除欺骗源地址
在最后的 COMMIT 行之前附加以下行:
-A INPUT -i eth0 -s 10.0.0.0/8 -j LOG --log-prefix "IP DROP SPOOF " -A INPUT -i eth0 -s 172.16.0.0/12 -j LOG --log-prefix "IP DROP SPOOF " -A INPUT -i eth0 -s 192.168.0.0/16 -j LOG --log-prefix "IP DROP SPOOF " -A INPUT -i eth0 -s 224.0.0.0/4 -j LOG --log-prefix "IP DROP MULTICAST " -A INPUT -i eth0 -s 240.0.0.0/5 -j LOG --log-prefix "IP DROP SPOOF " -A INPUT -i eth0 -d 127.0.0.0/8 -j LOG --log-prefix "IP DROP LOOPBACK " -A INPUT -i eth0 -s 169.254.0.0/16 -j LOG --log-prefix "IP DROP MULTICAST " -A INPUT -i eth0 -s 0.0.0.0/8 -j LOG --log-prefix "IP DROP " -A INPUT -i eth0 -s 240.0.0.0/4 -j LOG --log-prefix "IP DROP " -A INPUT -i eth0 -s 255.255.255.255/32 -j LOG --log-prefix "IP DROP " -A INPUT -i eth0 -s 168.254.0.0/16 -j LOG --log-prefix "IP DROP " -A INPUT -i eth0 -s 248.0.0.0/5 -j LOG --log-prefix "IP DROP "
记录并丢弃所有流量
找到以下行:
-A RH-Firewall-1-INPUT -j REJECT --reject-with icmp-host-prohibited
COMMIT
更新如下:
-A RH-Firewall-1-INPUT -j LOG -A RH-Firewall-1-INPUT -j DROP COMMIT
开放端口
要打开端口 80(Http 服务器),请在 COMMIT 行之前添加以下内容:
-A RH-Firewall-1-INPUT -m tcp -p tcp --dport 80 -j ACCEPT
要打开端口 53(DNS 服务器),请在 COMMIT 行之前添加以下内容:
-A RH-Firewall-1-INPUT -m tcp -p tcp --dport 53 -j ACCEPT -A RH-Firewall-1-INPUT -m udp -p tcp --dport 53 -j ACCEPT
要打开端口 443(Https 服务器),请在 COMMIT 行之前添加以下内容:
-A RH-Firewall-1-INPUT -m tcp -p tcp --dport 443 -j ACCEPT
要打开端口 25(smtp 服务器),请在 COMMIT 行之前添加以下内容:
-A RH-Firewall-1-INPUT -m tcp -p tcp --dport 25 -j ACCEPT
仅允许来自 192.168.1.0/24 的 SSH 流量
-A RH-Firewall-1-INPUT -s 192.168.1.0/24 -m state --state NEW -p tcp --dport 22 -j ACCEPT
启用 192.168.1.0/24 的打印访问
-A RH-Firewall-1-INPUT -s 192.168.1.0/24 -p udp -m udp --dport 631 -j ACCEPT -A RH-Firewall-1-INPUT -s 192.168.1.0/24 -p tcp -m tcp --dport 631 -j ACCEPT
允许合法 NTP 客户端访问服务器
-A RH-Firewall-1-INPUT -s 192.168.1.0/24 -m state --state NEW -p udp --dport 123 -j ACCEPT
打开 FTP 端口 21 (FTP)
-A RH-Firewall-1-INPUT -m state --state NEW -p tcp --dport 21 -j ACCEPT
保存并关闭文件。编辑 /etc/sysconfig/iptables-config,输入:
# vi /etc/sysconfig/iptables-config
确保 ftp 模块已加载,并以空格分隔的模块列表:
IPTABLES_MODULES="ip_conntrack_ftp"
要重新启动防火墙,请输入以下命令:
# service iptables restart
# iptables -vnL --line-numbers
编辑 /etc/sysctl.conf 以实现 DoS 和 Syn 保护
编辑 /etc/sysctl.conf 来防御某些类型的攻击,并附加/更新如下内容:
net.ipv4.conf.all.log_martians = 1 net.ipv4.conf.default.accept_source_route = 0 net.ipv4.conf.default.accept_redirects = 0 net.ipv4.conf.default.secure_redirects = 0 net.ipv4.icmp_echo_ignore_broadcasts = 1 #net.ipv4.icmp_ignore_bogus_error_messages = 1 net.ipv4.tcp_syncookies = 1 net.ipv4.conf.all.rp_filter = 1 net.ipv4.conf.default.rp_filter = 1
有关更多详细信息,请参阅前面的常见问题解答“ Linux 内核 /etc/sysctl.conf安全强化”。
备用配置选项
您可以跳过 /etc/sysconfig/iptables 文件并从头开始创建一个 shell 脚本,如下所示:
#!/bin/bash # A sample firewall shell script IPT="/sbin/iptables" SPAMLIST="blockedip" SPAMDROPMSG="BLOCKED IP DROP" SYSCTL="/sbin/sysctl" BLOCKEDIPS="/root/scripts/blocked.ips.txt" # Stop certain attacks echo "Setting sysctl IPv4 settings..." $SYSCTL net.ipv4.ip_forward=0 $SYSCTL net.ipv4.conf.all.send_redirects=0 $SYSCTL net.ipv4.conf.default.send_redirects=0 $SYSCTL net.ipv4.conf.all.accept_source_route=0 $SYSCTL net.ipv4.conf.all.accept_redirects=0 $SYSCTL net.ipv4.conf.all.secure_redirects=0 $SYSCTL net.ipv4.conf.all.log_martians=1 $SYSCTL net.ipv4.conf.default.accept_source_route=0 $SYSCTL net.ipv4.conf.default.accept_redirects=0 $SYSCTL net.ipv4.conf.default.secure_redirects=0 $SYSCTL net.ipv4.icmp_echo_ignore_broadcasts=1 #$SYSCTL net.ipv4.icmp_ignore_bogus_error_messages=1 $SYSCTL net.ipv4.tcp_syncookies=1 $SYSCTL net.ipv4.conf.all.rp_filter=1 $SYSCTL net.ipv4.conf.default.rp_filter=1 $SYSCTL kernel.exec-shield=1 $SYSCTL kernel.randomize_va_space=1 echo "Starting IPv4 Firewall..." $IPT -F $IPT -X $IPT -t nat -F $IPT -t nat -X $IPT -t mangle -F $IPT -t mangle -X # load modules modprobe ip_conntrack [ -f "$BLOCKEDIPS" ] && BADIPS=$(egrep -v -E "^#|^$" "${BLOCKEDIPS}") # interface connected to the Internet PUB_IF="eth0" #Unlimited traffic for loopback $IPT -A INPUT -i lo -j ACCEPT $IPT -A OUTPUT -o lo -j ACCEPT # DROP all incomming traffic $IPT -P INPUT DROP $IPT -P OUTPUT DROP $IPT -P FORWARD DROP if [ -f "${BLOCKEDIPS}" ]; then # create a new iptables list $IPT -N $SPAMLIST for ipblock in $BADIPS do $IPT -A $SPAMLIST -s $ipblock -j LOG --log-prefix "$SPAMDROPMSG " $IPT -A $SPAMLIST -s $ipblock -j DROP done $IPT -I INPUT -j $SPAMLIST $IPT -I OUTPUT -j $SPAMLIST $IPT -I FORWARD -j $SPAMLIST fi # Block sync $IPT -A INPUT -i ${PUB_IF} -p tcp ! --syn -m state --state NEW -m limit --limit 5/m --limit-burst 7 -j LOG --log-level 4 --log-prefix "Drop Sync" $IPT -A INPUT -i ${PUB_IF} -p tcp ! --syn -m state --state NEW -j DROP # Block Fragments $IPT -A INPUT -i ${PUB_IF} -f -m limit --limit 5/m --limit-burst 7 -j LOG --log-level 4 --log-prefix "Fragments Packets" $IPT -A INPUT -i ${PUB_IF} -f -j DROP # Block bad stuff $IPT -A INPUT -i ${PUB_IF} -p tcp --tcp-flags ALL FIN,URG,PSH -j DROP $IPT -A INPUT -i ${PUB_IF} -p tcp --tcp-flags ALL ALL -j DROP $IPT -A INPUT -i ${PUB_IF} -p tcp --tcp-flags ALL NONE -m limit --limit 5/m --limit-burst 7 -j LOG --log-level 4 --log-prefix "NULL Packets" $IPT -A INPUT -i ${PUB_IF} -p tcp --tcp-flags ALL NONE -j DROP # NULL packets $IPT -A INPUT -i ${PUB_IF} -p tcp --tcp-flags SYN,RST SYN,RST -j DROP $IPT -A INPUT -i ${PUB_IF} -p tcp --tcp-flags SYN,FIN SYN,FIN -m limit --limit 5/m --limit-burst 7 -j LOG --log-level 4 --log-prefix "XMAS Packets" $IPT -A INPUT -i ${PUB_IF} -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP #XMAS $IPT -A INPUT -i ${PUB_IF} -p tcp --tcp-flags FIN,ACK FIN -m limit --limit 5/m --limit-burst 7 -j LOG --log-level 4 --log-prefix "Fin Packets Scan" $IPT -A INPUT -i ${PUB_IF} -p tcp --tcp-flags FIN,ACK FIN -j DROP # FIN packet scans $IPT -A INPUT -i ${PUB_IF} -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP # Allow full outgoing connection but no incomming stuff $IPT -A INPUT -i ${PUB_IF} -m state --state ESTABLISHED,RELATED -j ACCEPT $IPT -A OUTPUT -o ${PUB_IF} -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT # Allow ssh $IPT -A INPUT -i ${PUB_IF} -p tcp --destination-port 22 -j ACCEPT # Allow http / https (open port 80 / 443) $IPT -A INPUT -i ${PUB_IF} -p tcp --destination-port 80 -j ACCEPT #$IPT -A INPUT -o ${PUB_IF} -p tcp --destination-port 443 -j ACCEPT # allow incomming ICMP ping pong stuff $IPT -A INPUT -i ${PUB_IF} -p icmp --icmp-type 8 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT #$IPT -A OUTPUT -o ${PUB_IF} -p icmp --icmp-type 0 -m state --state ESTABLISHED,RELATED -j ACCEPT # Allow port 53 tcp/udp (DNS Server) $IPT -A INPUT -i ${PUB_IF} -p udp --dport 53 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT #$IPT -A OUTPUT -o ${PUB_IF} -p udp --sport 53 -m state --state ESTABLISHED,RELATED -j ACCEPT $IPT -A INPUT -i ${PUB_IF} -p tcp --destination-port 53 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT #$IPT -A OUTPUT -o ${PUB_IF} -p tcp --sport 53 -m state --state ESTABLISHED,RELATED -j ACCEPT # Open port 110 (pop3) / 143 $IPT -A INPUT -i ${PUB_IF} -p tcp --destination-port 110 -j ACCEPT $IPT -A INPUT -i ${PUB_IF} -p tcp --destination-port 143 -j ACCEPT ##### Add your rules below ###### # # ##### END your rules ############ # Do not log smb/windows sharing packets - too much logging $IPT -A INPUT -p tcp -i ${PUB_IF} --dport 137:139 -j REJECT $IPT -A INPUT -p udp -i ${PUB_IF} --dport 137:139 -j REJECT # log everything else and drop $IPT -A INPUT -j LOG $IPT -A FORWARD -j LOG $IPT -A INPUT -j DROP exit 0
推荐阅读:
- 查看所有与 iptables 相关的常见问题解答、教程和 shell 脚本。
- Ip6tables(IPv6)防火墙配置。
- 使用 man 命令阅读 iptables 和 sysctl 手册页:
man iptables
man ip6tables
man sysctl