Fail2ban 聯動 Aliyun CLI 將 IP 直接錄入安全組

For AWS:

https://www.cloudar.be/awsblog/integrating-fail2ban-with-aws-network-acls/

注意,本文中的做法需要先在系統中配置好 aliyun-cli,
具體做法請參考:https://github.com/aliyun/aliyun-cli

在 jail.d 的配置文件中添加:

action = aliyun[name=%(__name__)s, bantime="%(bantime)s", port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"]

然後在 action.d 文件夾中添加 aliyun.conf 配置:

[INCLUDES]

before = iptables-blocktype.conf

[Definition]

actionstart = aliyun configure set --profile ecsRamRoleProfile --mode EcsRamRole --ram-role-name <替換為 RAM Role 名稱> --region <替換為安全組地域>
              iptables -N fail2ban-<name>
              iptables -A fail2ban-<name> -j RETURN
              iptables -I <chain> -p <protocol> --dport <port> -j fail2ban-<name>

actionstop = iptables -D <chain> -p <protocol> --dport <port> -j fail2ban-<name>
             iptables -F fail2ban-<name>
             iptables -X fail2ban-<name>

actioncheck = iptables -n -L <chain> | grep -q 'fail2ban-<name>[ \t]'

actionban = /usr/local/bin/aliyun ecs AuthorizeSecurityGroup --SecurityGroupId <替換為安全組 ID> --SourceCidrIp <ip>/32 --IpProtocol ALL --PortRange=-1/-1 --NicType intranet --Policy Drop

actionunban = /usr/local/bin/aliyun ecs RevokeSecurityGroup --SecurityGroupId <替換為安全組 ID> --SourceCidrIp <ip>/32 --IpProtocol ALL --PortRange=-1/-1 --NicType intranet --Policy Drop

[Init]

使用 Fail2ban 封殺主動探測 IP

我們想要封殺的主動探測行為:

0000-00-00 00:00:00 WARNING common.py:238 unsupported addrtype 69, maybe wrong password or encryption method
0000-00-00 00:00:00 WARNING tcprelay.py:521 Protocol ERROR, TCP ogn data 160301008b0100008703037b1d113cae353743a96141532263f238e4fef85f16f4280234332b7662a5f40300001ac02fc02bc011c007c013c009c014c00a0005002f0035c012000a0100004400000012001000000d34372e35322e3235322e313030000500050100000000000a00080006001700180019000b00020100000d000a00080401040302010203ff01000100 from ::ffff:119.96.105.1:50522 via port 443 by UID 443
0000-00-00 00:00:00 ERROR tcprelay.py:1097 can not parse header when handling connection from ::ffff:119.96.105.1:50522

安裝 Fail2ban:

yum -y install epel-release
yum -y install fail2ban

添加 Filter:(e.g. /etc/fail2ban/filter.d/ssr.conf

[INCLUDES]
before = common.conf

[Definition]

failregex = ^.+ERROR.+can not parse header when handling connection from +<HOST>

ignoreregex =

添加 Jail:(e.g. /etc/fail2ban/jail.d/01-ssr.conf

[ssr]
enabled = true
port = 0:65535
logpath = (Log to watch)
maxretry = 1
bantime = 86400
findtime = 300

(可選)禁用 FirewallD,使用 iptables 進行封禁:(個人覺得 f2b 跟 iptables 更合得來)

mv /etc/fail2ban/jail.d/00-firewalld.conf /etc/fail2ban/jail.d/00-firewalld.disabled

啟動 Fail2ban:

systemctl enable fail2ban
systemctl start fail2ban

查看 Jail 規則狀態:

fail2ban-client status ssr

如何正確給 Docker 配置 firewalld,以及 Docker 強行覆蓋 iptables 的安全隱患

業務上使用 Docker 也算有一年了,但一直以來 Docker 的容器都是跑在 AWS 雲服務上面,不需要自己配置防火牆服務,firewalld 也從來不需要在主機上啟用,這個週末在普通 VPS 上折騰 Docker + firewalld,哪知一腳掉進了泥水坑。

TL;DR,Docker 會在啟動時自動幫你完成綁定端口的操作,但問題出在,它寫的規則是把端口對所有人開放,而無視你在 firewalld 其他 zone 寫的 IP 限制。

感謝以下文章:

无视系统防火墙的docker https://www.binss.me/blog/docker-pass-through-system-firewall/

firewall-cmd –reload on centos 7.4.1708 removes the DOCKER-USER iptables chain https://github.com/moby/moby/issues/35043#issuecomment-356036671

Docker and iptables https://docs.docker.com/network/iptables/

Configuring iptables to let Docker containers access out https://serverfault.com/a/883184

廢話少說,直接切去重點,經過調查,得知:

  1. Docker 寫的規則是直接寫入 iptables CHAIN 的,不受 firewalld zone 設定的影響
  2. Docker 有一個啟動選項 `–iptables=false`,但這樣子的話 Docker 內網的轉發都要自己加上去了,我懶我不幹
  3. Docker 提供另一個選項,CHAIN `DOCKER-USER`,可以覆蓋 Docker 啟動時的 CHAIN 設定,這次就拿它開刀

以下為最終設置腳本:

> 首先我們讓 firewalld 移除掉 DOCKER-USER 並新建一個(這步非常重要,即便 DOCKER-USER 已經存在,你也需要執行刪除,不然不生效,原因我也沒搞懂)

firewall-cmd --permanent --direct --remove-chain ipv4 filter DOCKER-USER
firewall-cmd --permanent --direct --remove-rules ipv4 filter DOCKER-USER
firewall-cmd --permanent --direct --add-chain ipv4 filter DOCKER-USER

> 下一步,加上你想要的規則,注意 REJECT 規則一定要在最後執行,同時注意不建議多個 IP 地址寫在同一條規則,格式上沒有問題,但不知道為什麼通過 iptables -L 確認時,順序會打亂,導致先被 REJECT

firewall-cmd --permanent --direct --add-rule ipv4 filter DOCKER-USER 0 -i docker0 -j ACCEPT -m comment --comment "allows incoming from docker"
firewall-cmd --permanent --direct --add-rule ipv4 filter DOCKER-USER 0 -i docker0 -o eth0 -j ACCEPT -m comment --comment "allows docker to eth0"
firewall-cmd --permanent --direct --add-rule ipv4 filter DOCKER-USER 0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -m comment --comment "allows docker containers to connect to the outside world"
firewall-cmd --permanent --direct --add-rule ipv4 filter DOCKER-USER 0 -j RETURN -s 172.18.0.0/16 -m comment --comment "allow internal docker communication"
firewall-cmd --permanent --direct --add-rule ipv4 filter DOCKER-USER 0 -s 1.1.1.1/32 -j ACCEPT # 你可以直接允許來自特定 IP 的所有流量
firewall-cmd --permanent --direct --add-rule ipv4 filter DOCKER-USER 0 -p tcp -m multiport --dports 1,2:3 -s 2.2.2.2/32 -j ACCEPT # 你也可以指定端口,這裡僅為示例
firewall-cmd --permanent --direct --add-rule ipv4 filter DOCKER-USER 0 -j REJECT --reject-with icmp-host-unreachable -m comment --comment "reject all other traffic"

> 最後,重啟 firewalld 並通過 iptables -L 和其他 IP 地址確認是否正確生效

firewall-cmd --reload

當時白菜價買來的騰訊雲成都 AMD 系列服務器,1核1G1Mbps,買回來之後吃了半年灰,今天正好有個主意拿來做網站在線率監控,於是回去折騰了一下,發現這機子還真是不錯,入網帶寬沒有什麼限制,所以不用擔心 1Mbps 隨便下載點什麼都要爆炸,機子的性能表現也沒有什麼遲緩的感覺,整體而言,如果你想要一台 Linux 學習機,我還是很推薦的,現在 3 年 607 元。

https://cloud.tencent.com/act/mid-year?from=10815#cvm

今天得到的教訓是,一個不會寫 Ruby 的人,就不應該去寫生產環境的 Ruby …

原寫法

for ip in ec2_urls do
puts("#{ip}")
end

$ ruby api.rb
10.24.1.177
10.24.2.93
10.24.1.177
10.24.2.93

指正後

ec2_urls.each do |ip|
puts("#{ip}")
end

$ ruby api.rb
10.24.1.177
10.24.2.93