「本站原创工具&开源&网络安全」windows/linux 自动获取ip黑名单列表并自动地动态地更新防火墙黑名单

zsanjin 发布于 2024-03-17 154 次阅读


AI 摘要

通过使用IPBan,您可以像使用电网一样电死那些想要翻窗户进入的废物。它会自动封锁连续密码错误超过6次的IP,需要确保打开Windows防火墙才能生效。另外,您还可以获取一些公用的IP黑名单列表并将这些IP列入黑名单中。使用Python写的脚本能够从中国科技大学获取IP黑名单并加入防火墙列表,动态地更新黑名单以自动化更新防火墙IP黑名单。

这段时间远程桌面时发现经常会出现一下报错,提示“为安全考虑,已锁定该用户账户,原因是登录尝试或密码更改尝试过多”错误,端口已经改过很多次了依然还会被扫到,就像一个变态不停地在你家门口试钥匙,看了一下Windows安全日志,这些死妈玩意每隔几秒就试一下,虽然他们不可能复活他们死去的家人一样来试出正确密码,但是就觉得很恶心,必须要做出点行动了,不仅是windows这边是这样,linux那边的服务器也一样是重灾区。下面分别记录出windows上和linux上的一些简单有效的防护措施。

 

文章中的开源代码由zsanjin-p编写并遵循MIT协议,转载请申明出处:zsanjin.de

在windows上的一些防护措施

1、用IPBan,像用电网一样电死这些想翻到别人家里的废物:

https://github.com/DigitalRuby/IPBan/releases

Github-Card

下载相应的windows版本,然后双击运行DigitalRuby.IPBan.exe即可,默认设置下,他会自动封锁连续密码错误超6次的ip,必须打开windows防火墙才有效,打开防火墙之前务必放行远程桌面端口,或者安装其他远程桌面软件比如todesk、向日葵等。

2、提前做出正当防卫

可以获取一些公用的ip黑名单列表,然后提前把这些ip列入黑名单中,我用python简单地实现这个功能,这个脚本将从中国科技大学获取ip黑名单并加入防火墙列表阻止这些ip访问。由于ip不可能一直被滥用,长期封锁一个ip会导致误伤好人,所以不能简单地直接获取ip后就覆盖交叉地将这些ip拉入防火墙黑名单,思路是第一次获取到ip,对比第二次获取的ip,比较两者的ip变化情况,相应地更新ip黑名单和释放黑名单中的ip,配合计划任务程序,全自动化更新防火墙ip黑名单。

首先从python.org下载适用于你的系统版本的python,安装部分省略,安装额外的库,pip install request。习惯虚拟环境的可以用python -m venv myenv来使用,下面我都是按在使用名为myenv的虚拟环境的前提下的代码,然后用myenv\Scripts\activate激活虚拟环境(linux下用source myenv/bin/activate激活),在 myenv中安装request:

python -m venv myenv
myenv\Scripts\activate
pip install request

再建立一个名为ipban.py的文件,将以下代码复制进去,这个python会生成3个文件,一个是获取的最新ip黑名单,一个是增加封锁ip名单,最后一个是释放的ip名单:

import os
import urllib.request
import datetime

# Step 1: Download the latest blacklist,by zsanjin.de
url = "http://blackip.ustc.edu.cn/list.php?txt"
urllib.request.urlretrieve(url, "new.txt")

# Step 2: Compare new.txt with old.txt and generate banip.txt
if os.path.exists("old.txt"):
with open("old.txt", "r") as old_file, open("new.txt", "r") as new_file, open("banip.txt", "w") as ban_file:
old_ips = set(old_file.read().splitlines())
new_ips = set(new_file.read().splitlines())
banned_ips = new_ips - old_ips
ban_file.write("\n".join(banned_ips))
else:
with open("new.txt", "r") as new_file, open("banip.txt", "w") as ban_file:
ban_file.write(new_file.read())

# Step 3: Compare old.txt with new.txt and generate open.txt,by zsanjin.de
if os.path.exists("old.txt"):
with open("old.txt", "r") as old_file, open("new.txt", "r") as new_file, open("open.txt", "w") as open_file:
old_ips = set(old_file.read().splitlines())
new_ips = set(new_file.read().splitlines())
opened_ips = old_ips - new_ips
open_file.write("\n".join(opened_ips))

# Step 4: Rename old.txt and new.txt,by zsanjin.de
current_date = datetime.datetime.now().strftime("%Y-%m-%d")
if os.path.exists("old.txt"):
os.rename("old.txt", f"old_{current_date}.txt")
os.rename("new.txt", "old.txt")

 

然后新建一个名为windows自动任务.bat的批处理文件复制以下内容,注意路径我用的是C:\Users\Administrator\Desktop\banip\,这是刚才的python文件的工作目录,txt文件也生成在这里,根据自己实际情况修改:

@echo off

set SCRIPT_DIR=%~dp0
call "%SCRIPT_DIR%myenv\Scripts\activate.bat"
python "%SCRIPT_DIR%p.py"

rem 添加 IP 到防火墙黑名单
echo Adding IPs to Windows Firewall blacklist...
for /f "tokens=*" %%a in (C:\Users\Administrator\Desktop\banip\banip.txt) do (
netsh advfirewall firewall add rule name="Block IP %%a" dir=in interface=any action=block remoteip=%%a
)

rem 输出添加结果
echo Blacklist updated.

rem 删除 IP 从防火墙黑名单
echo Removing IPs from Windows Firewall blacklist...
for /f "tokens=*" %%a in (C:\Users\Administrator\Desktop\banip\open.txt) do (
netsh advfirewall firewall delete rule name="Block IP %%a"
)

rem 输出删除结果
echo IPs removed from Windows Firewall blacklist.

直接运行几次bat测试没问题后(old_日期.txt只保留一个,否则会报错,设计的目的就是一天运行一次),第一次运行时比较久,要一条一条地添加进去,把这个bat添加进任务计划程序中(claude3):
在Windows任务计划程序中设置工作目录的步骤如下:

1. 打开"任务计划程序"。你可以在开始菜单的搜索框中输入"任务计划程序"来打开它。

2. 在任务计划程序的导航窗格中,找到你想要设置工作目录的任务。

3. 右键单击该任务,然后选择"属性"。

4. 在任务属性对话框中,切换到"操作"选项卡。

5. 在"操作"窗格中,选中要设置工作目录的操作(通常是第一个操作)。

6. 点击"编辑"按钮。

7. 在"编辑操作"对话框中,切换到"开始于(B):"选项卡。

8. 这一步很重要 在"开始于(B):"文本框中,输入你希望该任务在执行时使用的工作目录路径。例如,如果你想设置工作目录为 C:\Users\Administrator\Desktop\banip,就输入这个路径。

9. 点击"确定"关闭"编辑操作"对话框。

10. 点击"确定"关闭任务属性对话框,保存更改。

设置好工作目录后,当任务执行时,它将使用你指定的那个目录作为当前工作目录。这可以确保你的批处理文件和Python脚本在正确的路径下运行,找到所需的文件。

 

至此,windows部分大概就完了,下面是linux部分,最后还有关于frp的。

 

在linux上的一些防护措施

1、同样用IPBan

没用宝塔面板的话,同样用IPBan,像用电网一样电死这些想翻到别人家里的废物:

https://github.com/DigitalRuby/IPBan/releases

Github-Card

linux一键安装命令(root用户):

bash <(wget -qO- https://raw.githubusercontent.com/DigitalRuby/IPBan/master/IPBanCore/Linux/Scripts/Install.sh)

2、Fail2ban

如果你用了宝塔面板,可以在商店中搜索Fail2ban,自动封锁和释放ip,不到5天,封了这么多废物,嘻嘻。

3、我先正当防卫

依然是将中国科技大学的ip黑名单来提前做好正当防卫,python文件和windows基本一致,同样需要安装request模块,pip install request,python代码如下:

import os
import urllib.request
import datetime

# 获取当前脚本所在目录的绝对路径
script_dir = os.path.dirname(os.path.abspath(__file__))

# Step 1: Download the latest blacklist,by zsanjin.de
url = "http://blackip.ustc.edu.cn/list.php?txt"
new_txt_path = os.path.join(script_dir, "new.txt")
urllib.request.urlretrieve(url, new_txt_path)

# Step 2: Compare new.txt with old.txt and generate banip.txt,by zsanjin.de
old_txt_path = os.path.join(script_dir, "old.txt")
banip_txt_path = os.path.join(script_dir, "banip.txt")

if os.path.exists(old_txt_path):
with open(old_txt_path, "r") as old_file, open(new_txt_path, "r") as new_file, open(banip_txt_path, "w") as ban_file:
old_ips = set(old_file.read().splitlines())
new_ips = set(new_file.read().splitlines())
banned_ips = new_ips - old_ips
ban_file.write("\n".join(banned_ips))
else:
with open(new_txt_path, "r") as new_file, open(banip_txt_path, "w") as ban_file:
ban_file.write(new_file.read())

# Step 3: Compare old.txt with new.txt and generate open.txt,by zsanjin.de
open_txt_path = os.path.join(script_dir, "open.txt")

if os.path.exists(old_txt_path):
with open(old_txt_path, "r") as old_file, open(new_txt_path, "r") as new_file, open(open_txt_path, "w") as open_file:
old_ips = set(old_file.read().splitlines())
new_ips = set(new_file.read().splitlines())
opened_ips = old_ips - new_ips
open_file.write("\n".join(opened_ips))

# Step 4: Rename old.txt and new.txt
current_date = datetime.datetime.now().strftime("%Y-%m-%d")
old_backup_path = os.path.join(script_dir, f"old_{current_date}.txt")

if os.path.exists(old_txt_path):
os.rename(old_txt_path, old_backup_path)

os.rename(new_txt_path, old_txt_path)

假设这个文件名为ip.python,你可以在文件目录下用以下命令任意之一测试一下是否正常运行:

python ip.py
python2 ip.py
python3 ip.py

现在有了ip名单,要和防火墙联动起来,因为我用的是宝塔面板,宝塔面板用的是ufw作为防火墙的控制前端,所以我们需要用ufw把ip黑名单添加进去,你可以用systemd命令看看ufw是否在运行

systemctl status ufw

ufw不能一次性添加整个文件,而是需要逐行读取文件添加ip规则。

现在做个脚本,自动任务来运行上面这个python文件获取ip黑名单&更新,并把更新的ip规则自动添加到ufw列表,注意,假设python文件,ip.py在/root/banip下,这个脚本文件名为run.sh同样也在这个目录下

#!/bin/bash

# 执行 Python 脚本,by zsanjin.de
echo "Running Python script..."
/usr/bin/python3 /root/banip/p.py

# 添加 IP 到黑名单,by zsanjin.de
echo "Adding IPs to blacklist..."
while IFS= read -r ip; do
sudo ufw deny from "$ip"
done < /root/banip/banip.txt

# 输出添加结果
echo "Blacklist updated."

# 删除 IP 从黑名单
echo "Removing IPs from blacklist..."
while IFS= read -r ip; do
sudo ufw delete deny from "$ip"
done < /root/banip/open.txt

# 输出删除结果
echo "IPs removed from blacklist."

最后用宝塔做了一个点击在宝塔面板左侧的计划任务,脚本内容就为/root/banip/run.sh,如下图保存即可

 

第一次运行的时候会添加大量的ip,会比较慢,慢慢等待,运行日志如图

 

4、宝塔面板导入ip规则

还有另外一种方法,就是宝塔面板的ip导入规则,不过缺陷也明显,没有api这样的方法,在导入过程中网络波动会导致中断,宝塔屏蔽的ip黑名单导入格式如下

1|drop|2a00:4c80::/29||2024-03-17 13:59:02|0||
2|drop|2405:b180::/32||2024-03-17 13:59:02|0||
3|drop|2001:620:618:1a6:1:80b2:a615:1||2024-03-17 13:59:02|0||
4|drop|2a0d:e7c7:ffff::/48||2024-03-17 13:59:02|0||
5|drop|2001:8d8:1801:740::1||2024-03-17 13:59:02|0||

然而大部分ip黑名单的格式都是ip一行一个,所以需要一个转换操作,我用python进行了一下简单转换,需要额外安装request库和certifi库,pip instatll request和pip install certifi   ,这个脚本主要是从中国科技大学那里获取ip黑名单,并且将它转为宝塔格式,输出文件名为日期.txt。习惯虚拟环境的可以用python -m venv myenv来使用,下面我都是按在使用名为myenv的虚拟环境的前提下的代码,在 myenv中安装request:pip install request,然后linux下用source myenv/bin/activate激活

python -m venv myenv
source myenv/bin/activate
pip install request
pip install certifi

将以下代码复制进名为banip.py的文件中

import urllib.request
import ssl
import certifi
from datetime import datetime

# Load certifi root certificates,by zsanjin.de
ssl_context = ssl.create_default_context(cafile=certifi.where())
url = "https://blackip.ustc.edu.cn/list.php?txt"

# Send the request with certificate validation
with urllib.request.urlopen(url, context=ssl_context) as response:
if response.status == 200:
# Split the response text into lines,by zsanjin.de
lines = response.read().decode('utf-8').split("\n")

# Open a new file with the current date as the name
filename = datetime.now().strftime("%Y-%m-%d.txt")
with open(filename, "w", encoding="utf-8") as file:
counter = 1 # Initialize a counter

# Iterate over the lines,by zsanjin.de
for line in lines:
# Check if the line is not empty
if line.strip():
# Split the line into IP address and other fields
ip_address = line.strip()

# Write the IP address in the target format
file.write(f"{counter}|drop|{ip_address}||{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}|0||\n")
counter += 1 # Increment the counter

else:
print(f"Failed to fetch the webpage: {response.status}")

然后在终端中运行后即可在当前文件夹生成当日日期的txt目标格式文件

python banip.py

如图,点击ip规则并将转换的目标格式txt导入进去即可,等待的时间很长,放着就行。

 

最后提frp中的问题,有很多人用frp来内网穿透ssh、远程桌面、ftp等等,如果是用樱花frp的话可以设置额外的访问密码提高安全性,但是普通的frp就只有基础的功能,这里建议开启日志文件,记录了frps的ip访问记录,可以查到哪些ip在恶意开锁,并自动/手动封禁它,自动封禁需要额外的程序与防火墙ufw联动实现,目前还没有时间去弄。

可以看到我的日志中有个废物在骚扰

frps.toml这样改,注意之前如果有设置过log.to = "console",记得把log.to = "console"删除,并添加以下设置

#  or real logFile path like ./frps.log
log.to = "./frps.log"
# trace, debug, info, warn, error
log.level = "info"
log.maxDays = 3
# disable log colors when log.to is console, default is false
log.disablePrintColor = false

 

至此,已经能基本有效的防止住一些恶意骚扰,另外定期更新系统修补安全漏洞也很有必要,系统更新不是你的敌人,而是你的朋友。

 

文章中的开源代码由zsanjin-p编写并遵循MIT协议,转载请申明出处:zsanjin.de

感谢请我吃辣条
感谢请我吃泡面
感谢请我喝奶茶