iptables傳輸數據包的過程:
1. 當一個數據包進入網卡時,它首先進入PREROUTING鏈,內核根據數據包目的IP判斷是否需要轉送出去。
2. 如果數據包就是進入本機的,它就會沿着圖向下移動,到達INPUT鏈。數據包到了INPUT鏈后,任何進程都會收到它。本機上運行的程序可以發送數據包,這些數據包會經過OUTPUT鏈,然后到達POSTROUTING鏈輸出。
3. 如果數據包是要轉發出去的,且內核允許轉發,數據包就會如圖所示向右移動,經過FORWARD鏈,然后到達POSTROUTING鏈輸出。
第一部分:常用顯示模塊介紹
注意:本文所有實例都是在默認規則為DROP下。
# 開放ssh服務端口 iptables -A INPUT -p tcp --dport 22 -j ACCEPT iptables -A INPUT -p tcp --sport 22 -j ACCEPT # 修改默認規則為DROP iptables -P INPUT DROP iptables -P OUTPUT DROP
1. multiport: 多端口匹配
可用於匹配非連續或連續端口;最多指定15個端口;
實例
iptables -A INPUT -p tcp -m multiport --dport 22,80 -j ACCEPT iptables -A OUTPUT -p tcp -m multiport --sport 22,80 -j ACCEPT
2. iprange: 匹配指定范圍內的地址
匹配一段連續的地址而非整個網絡時有用
實例:
iptables -A INPUT -p tcp -m iprange --src-range 192.168.118.0-192.168.118.60 --dport 22 -j ACCEPT iptables -A OUTPUT -p tcp -m iprange --dst-range 192.168.118.0-192.168.118.60 --sport 22 -j ACCEPT
3. string: 字符串匹配,能夠檢測報文應用層中的字符串
字符匹配檢查高效算法:kmp, bm
能夠屏蔽非法字符
實例:
# 注意該條規則需要添加到OUTPUT鏈,當服務端返回數據報文檢查到有關鍵字"sex"時,則丟棄該報文,可用於web敏感詞過濾 iptables -A OUTPUT -p tcp --dport 80 -m string --algo kmp --string "sex" -j DROP
4. connlimit: 連接數限制,對每IP所能夠發起並發連接數做限制;
實例:
# 默認INPUT 為 DROP. 每個ip對ssh服務的訪問最大為3個並發連接,超過則丟棄 iptables -A INPUT -p tcp --dport 22 -m connlimit ! --connlimit-above 3 -j ACCEPT
5. limit: 速率限制
limit-burst: 設置默認閥值
# 默認放行10個,當到達limit-burst閥值后,平均6秒放行1個 iptables -A INPUT -p icmp -m limit --limit 10/minute --limit-burst 10 -j ACCEPT
6. state: 狀態檢查
連接追蹤中的狀態:
NEW: 新建立一個會話
ESTABLISHED:已建立的連接
RELATED: 有關聯關系的連接
INVALID: 無法識別的連接
# 放行ssh的首次連接狀態 iptables -A INPUT -p tcp --dport 22 -m state --state NEW -j ACCEPT
第二部分:編寫常用規則
編寫iptables注意:做默認規則drop的時候一定要先開放ssh端口,否則就杯具了。
# 清空自建規則 iptables -F iptables -X # 在INPUT鏈上,tcp為RELATED,ESTABLISHED的數據包為放行 iptables -A INPUT -p tcp -m state --state RELATED,ESTABLISHED -j ACCEPT # 在INPUT鏈上,tcp為NEW而且端口為22,80的數據包放行 iptables -A INPUT -p tcp -m state --state NEW -m multiport 22,80 -j ACCEPT # 在OUTPUT鏈上,tcp為ESTABLISHED都放行 iptables -A OUTPUT -p tcp -m state --state ESTABLISHED -j ACCEPT # INPUT鏈和OUTPUT鏈默認規則都為DROP狀態 iptables -P INPUT DROP iptables -P OUTPUT DROP # 打開本地回環地址 iptables -A INPUT -i lo -j ACCEPT iptables -A OUTPUT -o lo -j ACCEPT # 允許服務器ping對端主機而不允許對端主機ping服務器 iptables -A OUTPUT -p icmp --icmp-type 8 -j ACCEPT iptables -A INPUT -p icmp --icmp-type 0 -j ACCEPT # 開放主機對dns的訪問 iptables -A INPUT -p udp --sport 53 -j ACCEPT iptables -A OUTPUT -p udp --dport 53 -j ACCEPT
第三部分:針對特定的服務定制相關規則
1. 對ssh進行管控,1小時內最多發起5個連接,防止黑客暴力破解ssh
# 清空默認規則 iptables -F iptables -X # 添加已建立的連接規則 iptables -A INPUT -p tcp -m state --state ESTABLISHED -j ACCEPT iptables -A OUTPUT -p tcp -m state --state ESTABLISHED -j ACCEPT # 設置默認規則 iptables -P INPUT DROP iptables -P OUTPUT DROP # 設置iptables記錄匹配ssh規則 iptables -I INPUT 2 -p tcp --syn -m state --state NEW -j LOG --log-level 5 --log-prefix "[SSH Login]:" # 使用recent顯示模塊限定每小時最多匹配到2次,超過則丟棄。(每小時建立超過2次 ssh 請求連接,每次ssh連接有三次密碼驗證,2次也就是輸入超過6次密碼) iptables -I INPUT -p tcp --dport 22 -m connlimit --connlimit-above 2 -j DROP
iptables -I INPUT -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH
iptables -I INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 3600 --hitcount 2 --name SSH -j DROP
2. 對web服務進行並發管控,防止Ddos
# 清空默認規則 iptables -F iptables -X # 添加已建立的連接規則 iptables -A INPUT -p tcp -m state --state ESTABLISHED -j ACCEPT iptables -A OUTPUT -p tcp -m state --state ESTABLISHED -j ACCEPT # 設置默認規則 iptables -P INPUT DROP iptables -P OUTPUT DROP # 每個ip的並發連接請求最大50,超過則丟棄,建議調大值,容易誤傷nat上網用戶 iptables -A INPUT -p tcp --syn --dport 80 -m state --state NEW -m connlimit ! --connlimit-above 50 -j DROP
3. 對icmp進行流控,防止icmp攻擊
# 清空默認規則 iptables -F iptables -X # 添加已建立的連接規則 iptables -A INPUT -p tcp -m state --state ESTABLISHED -j ACCEPT iptables -A OUTPUT -p tcp -m state --state ESTABLISHED -j ACCEPT # 設置默認規則 iptables -P INPUT DROP iptables -P OUTPUT DROP # 利用limit模塊限制icmp速率,閥值為10個,當到達10個后,限速每秒鍾1個 iptables -A INPUT -p icmp --icmp-type 0 -m limit --limit 1/s --limit-burst 10 -j ACCEPT
第四部分:NAT 常用規則
站在服務器的角度:
當內網服務器要訪問外網時,需要做源地址轉換;
# 打開轉發功能 sysctl -w net.ipv4.ip_forward=1 # 把 192.168.1.0 網段流出的數據的 source ip address 修改成為 10.0.0.11: iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -j SNAT --to-source 10.0.0.11
當外網主機要訪問內網服務器服務時,需要做目標地址轉換;
# 打開轉發功能 sysctl -w net.ipv4.ip_forward=1 # 把訪問 10.0.0.11:2222 的訪問轉發到 192.168.1.11:22 上:: iptables -t nat -A PREROUTING -d 10.0.0.11 -p tcp --dport 2222 -j DNAT --to-destination 192.168.1.11:22
單純的將訪問本機80端口的請求轉發到8080上
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080
補充:
iptables 獨立日志配置:
當在iptables中啟用日志記錄時,會被當做系統日志記錄到/var/log/message里面,如果想要獨立日志配置如下:
grep -r 'iptables' /etc/rsyslog.conf kern.* /var/log/iptables.log
systemctl restart rsyslog
在 /etc/rsyslog.conf 中添加一條規則,並重啟服務。