FRP内网穿透如何避免SSH暴力破解(二)——指定地区允许访问

2024-02-06 16:20

本文主要是介绍FRP内网穿透如何避免SSH暴力破解(二)——指定地区允许访问,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

背景

上篇文章说到,出现了试图反复通过FRP的隧道,建立外网端口到内网服务器TCP链路的机器人,同时试图暴力破解ssh。这些连接造成了流量的浪费和不必要的通信开销。考虑到服务器使用者主要分布在A、B、C地区和国家,我打算对上一篇文章获取的建立连接的ip再过滤一遍,把其他地区的ip加以封禁,确保服务器不被恶意访问骚扰。

思路

在FRP服务端写一个python程序,每个小时查询一次已连接ip的清单,只允许指定区域的ip访问内网的指定端口。本文国家/地区列表我设置为中国大陆、香港、新加坡、马来西亚、美国。

获取地区&检查是否是目标区域

# 设置允许访问地区列表
target_countries = ('China', 'Hong Kong', 'Singapore', 'Malaysia', 'United States')def get_ip_location(ip_address):response = requests.get(f'https://ipapi.co/{ip_address}/json/').json()country_name = response.get("country_name")# print(country_name)return country_namedef check_ip_location(ip_address):country_name = get_ip_location(ip_address)if country_name in target_countries:# print('ok')return 'ok'else:return 'no'

封禁服务区域外的ip

def ban_ip(ip_address):# 检查IP是否已经被封禁if is_ip_banned(ip_address):print(f"IP {ip_address} is already banned.")returntry:# 封禁IP地址subprocess.run(['sudo', 'iptables', '-A', 'INPUT', '-s', ip_address, '-j', 'DROP'], check=True)# 记录到文件with open('/home/user/ban_ip_no_cn.txt', 'a') as file:ban_time = datetime.datetime.now()unban_time = ban_time + datetime.timedelta(days=1)file.write(f"{ban_time}, {ip_address}, {unban_time}\n")print(f"IP {ip_address} has been banned.")except Exception as e:print(f"Error banning IP {ip_address}: {e}")

封禁时间限制

每天运行一次脚本ban_ip_no_cn.sh,检查是否到了解封时间。

BAN_FILE="/home/user/ban_ip_no_cn.txt"
TEMP_FILE="/tmp/temp_ban_ip_no_cn.txt"while IFS=, read -r ban_time ip_address unban_time; docurrent_time=$(date +%Y-%m-%d' '%H:%M:%S)if [[ "$current_time" > "$unban_time" ]]; thensudo iptables -D INPUT -s $ip_address -j DROPelseecho "$line" >> $TEMP_FILEfi
done < $BAN_FILEmv $TEMP_FILE $BAN_FILE

定期清理连接建立记录

# 已建立连接ip的清单‘establishment_ip.txt’,每三天释放一次from datetime import datetime, timedelta
import osdef delete_old_entries(file_path):cutoff_date = datetime.now().date() - timedelta(days=1)temp_file_path = file_path + ".tmp"with open(file_path, 'r') as read_file, open(temp_file_path, 'w') as write_file:for line in read_file:line_date_str = line.split(' ')[0]  # Extract only the date partline_date = datetime.strptime(line_date_str, '%Y-%m-%d').date()if line_date >= cutoff_date:write_file.write(line)os.replace(temp_file_path, file_path)# Path to the establishment_ip.txt file
file_path = '/home/peter/establishment_ip.txt'
delete_old_entries(file_path)

注意

establishment_ip.txt文件的格式如下,通过ss -anp | grep ":port"(port切换为你的frps开放的port)命令获取。

2024-02-06 07:36:52.541687: Established connection from IP 203.145.18.60 on port 23
2024-02-06 07:36:52.578422: Established connection from IP 203.145.18.60 on port 23
2024-02-06 07:40:01.597133: Established connection from IP 56.101.207.179 on port 24
2024-02-06 07:40:01.597341: Established connection from IP 203.145.18.60 on port 24
2024-02-06 07:40:01.633414: Established connection from IP 203.145.18.60 on port 24
2024-02-06 07:40:36.380221: Established connection from IP 203.145.18.60 on port 24

效果:

  1. ip_ban_no_cn.log输出打印
    ip_ban_no_cn.log输出
  2. ban_ip_no_cn.txt的被封禁ip记录
    在这里插入图片描述

完整Python代码 (注意修改路径)

# 每小时运行一次,从已建立连接ip的清单查询,封禁所有不欢迎ip
# 已建立连接ip的清单‘establishment_ip.txt’,每三天释放一次import re
import requests
import subprocess
import datetime# 更新国家列表
target_countries = ('China', 'Hong Kong', 'Singapore', 'Malaysia', 'United States')def get_ip_location(ip_address):response = requests.get(f'https://ipapi.co/{ip_address}/json/').json()country_name = response.get("country_name")# print(country_name)return country_namedef check_ip_location(ip_address):country_name = get_ip_location(ip_address)if country_name in target_countries:# print('ok')return 'ok'else:return 'no'def is_ip_banned(ip_address):try:with open('/home/{user}/ban_ip_no_cn.txt', 'r') as file:for line in file:if ip_address in line:return Trueexcept FileNotFoundError:# 如果文件不存在,意味着没有IP被封禁return Falsereturn Falsedef ban_ip(ip_address):# 检查IP是否已经被封禁if is_ip_banned(ip_address):print(f"IP {ip_address} is already banned.")returntry:# 封禁IP地址subprocess.run(['sudo', 'iptables', '-A', 'INPUT', '-s', ip_address, '-j', 'DROP'], check=True)# 记录到文件with open('/home/{user}/ban_ip_no_cn.txt', 'a') as file:ban_time = datetime.datetime.now()unban_time = ban_time + datetime.timedelta(days=1)file.write(f"{ban_time}, {ip_address}, {unban_time}\n")print(f"IP {ip_address} has been banned.")except Exception as e:print(f"Error banning IP {ip_address}: {e}")def main():log_file_path = '/home/{user}/establishment_ip.txt'ip_pattern = re.compile(r'\b(?:\d{1,3}\.){3}\d{1,3}\b')current_time = datetime.datetime.now()try:with open(log_file_path, 'r') as file:for line in file:# 尝试解析每行的时间戳parts = line.split(": Established connection from IP ")if len(parts) > 1:timestamp_str = parts[0].strip()# print(timestamp_str)try:timestamp = datetime.datetime.strptime(timestamp_str, '%Y-%m-%d %H:%M:%S.%f')# 检查时间是否在最近2小时内# print(timestamp)if (current_time - timestamp) <= datetime.timedelta(hours=2):search_result = ip_pattern.search(line)# print((current_time - timestamp))if search_result:ip_address = search_result.group(0)if check_ip_location(ip_address) == 'no':ban_ip(ip_address)except ValueError:# 如果时间戳格式不正确,跳过这一行continueexcept FileNotFoundError:print(f"File {log_file_path} not found.")except Exception as e:print(f"An error occurred: {e}")if __name__ == '__main__':main()

Crontab运行的脚本

# Run ban_ip_no_cn.sh every 24 hours and log output
0 0 * * * /home/user/ban_ip_no_cn.sh > /home/user/log_temp/ban_ip_no_cn.log 2>&1# Run ip_ban_no_cn.py every hour and log output
0 * * * * python3 /home/user/ip_ban_no_cn.py > /home/user/log_temp/ip_ban_no_cn.log 2>&1# Run ip_ban_delete_old.py every 24 hours and log output
0 0 * * * python3 /home/user/ip_ban_delete_old.py > /home/user/log_temp/ip_ban_delete_old.log 2>&1

总结

代码写完才发现,早就有大神写了个复杂版本。呜呼哀哉,就好像论文idea被抢发了一样:https://github.com/zngw/frptables

这篇关于FRP内网穿透如何避免SSH暴力破解(二)——指定地区允许访问的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/684879

相关文章

本地搭建DeepSeek-R1、WebUI的完整过程及访问

《本地搭建DeepSeek-R1、WebUI的完整过程及访问》:本文主要介绍本地搭建DeepSeek-R1、WebUI的完整过程及访问的相关资料,DeepSeek-R1是一个开源的人工智能平台,主... 目录背景       搭建准备基础概念搭建过程访问对话测试总结背景       最近几年,人工智能技术

Ollama整合open-webui的步骤及访问

《Ollama整合open-webui的步骤及访问》:本文主要介绍如何通过源码方式安装OpenWebUI,并详细说明了安装步骤、环境要求以及第一次使用时的账号注册和模型选择过程,需要的朋友可以参考... 目录安装环境要求步骤访问选择PjrIUE模型开始对话总结 安装官方安装地址:https://docs.

C#多线程编程中导致死锁的常见陷阱和避免方法

《C#多线程编程中导致死锁的常见陷阱和避免方法》在C#多线程编程中,死锁(Deadlock)是一种常见的、令人头疼的错误,死锁通常发生在多个线程试图获取多个资源的锁时,导致相互等待对方释放资源,最终形... 目录引言1. 什么是死锁?死锁的典型条件:2. 导致死锁的常见原因2.1 锁的顺序问题错误示例:不同

解读静态资源访问static-locations和static-path-pattern

《解读静态资源访问static-locations和static-path-pattern》本文主要介绍了SpringBoot中静态资源的配置和访问方式,包括静态资源的默认前缀、默认地址、目录结构、访... 目录静态资源访问static-locations和static-path-pattern静态资源配置

使用Python合并 Excel单元格指定行列或单元格范围

《使用Python合并Excel单元格指定行列或单元格范围》合并Excel单元格是Excel数据处理和表格设计中的一项常用操作,本文将介绍如何通过Python合并Excel中的指定行列或单... 目录python Excel库安装Python合并Excel 中的指定行Python合并Excel 中的指定列P

Java访问修饰符public、private、protected及默认访问权限详解

《Java访问修饰符public、private、protected及默认访问权限详解》:本文主要介绍Java访问修饰符public、private、protected及默认访问权限的相关资料,每... 目录前言1. public 访问修饰符特点:示例:适用场景:2. private 访问修饰符特点:示例:

Python将大量遥感数据的值缩放指定倍数的方法(推荐)

《Python将大量遥感数据的值缩放指定倍数的方法(推荐)》本文介绍基于Python中的gdal模块,批量读取大量多波段遥感影像文件,分别对各波段数据加以数值处理,并将所得处理后数据保存为新的遥感影像... 本文介绍基于python中的gdal模块,批量读取大量多波段遥感影像文件,分别对各波段数据加以数值处

通过C#获取PDF中指定文本或所有文本的字体信息

《通过C#获取PDF中指定文本或所有文本的字体信息》在设计和出版行业中,字体的选择和使用对最终作品的质量有着重要影响,然而,有时我们可能会遇到包含未知字体的PDF文件,这使得我们无法准确地复制或修改文... 目录引言C# 获取PDF中指定文本的字体信息C# 获取PDF文档中用到的所有字体信息引言在设计和出

Python 标准库time时间的访问和转换问题小结

《Python标准库time时间的访问和转换问题小结》time模块为Python提供了处理时间和日期的多种功能,适用于多种与时间相关的场景,包括获取当前时间、格式化时间、暂停程序执行、计算程序运行时... 目录模块介绍使用场景主要类主要函数 - time()- sleep()- localtime()- g

使用Python实现批量访问URL并解析XML响应功能

《使用Python实现批量访问URL并解析XML响应功能》在现代Web开发和数据抓取中,批量访问URL并解析响应内容是一个常见的需求,本文将详细介绍如何使用Python实现批量访问URL并解析XML响... 目录引言1. 背景与需求2. 工具方法实现2.1 单URL访问与解析代码实现代码说明2.2 示例调用