< 自用文 主机 USC 记录:> 发现正在被攻击 后的自救
环境:
一台 VPS,之前文章推荐过 $1/月
OS: Ubuntu
内存:961MB
CPU: 1CORE
上面都是学习 Python 时写的应用,这些应用在 CSDN 都有原码,只是时间久了,自用的有修复bugs,还有些功能升级。 以前是运行在家里的 NAS 上,现在移到了 Internet,事儿就来了。
当前运行的应用:
- 当收藏夹用的 Portal
- 看正经与“正经”新闻的两个花钱订阅的报刊新闻组:(不能写名字,不然文章发不出来,一个名字里有“华尔街”,另一个含“经济”+人)
- 用浏览器修切图片的应用
- 过滤几个电报X新闻组,取出精华看财经新闻用的。
- 以上是 WEB 应用
- 还有 nginx fail2ban ufw 另外两带V不能提名字,你知道的。
- Claude Code, GeminiCLI 这上面都可以跑,就是慢点,用得很少。
- 用了 GITHUB 项目,可以从浏览器使用 Claude Code,是那这台用的,虽然没运行 Claude Code,但 Nginx site 还在。
- 解释:6 中提到的 nginx, 它来支持 web 访问与后面的应用连接,这里用 nignx + SSL + Python/V 一起做“网站”。
现象:
- 用 SSH 工具连接 VPS 等了十几秒,以为主机挂
- V 工具反应很慢
- SSH 登录后,敲字母,比叫猫过来还慢。
- 使用 top 命令 那个 v开头的进程,CPU 使用率在60%-93%
解决过程:
1 看 top 输出发呆
看着可用内存 < 60MB... 好在是有加 swap。下面是已经加入过滤运行超过半小时后的截屏:
那时 CPU 内存占用已经降下来一些。
看了看 v 的日志:
没有不正常使用的记录。
2 思考与瞎猜
个人认为那个 v 不是根源。回到文章开头在: “当前运行的应用” 中,有提 v 前面是 NGINX。应该是它的原因。 按这个思路去?找问题
3 过程
1)停止不必须的服务
到 /var/log/nginx 扫了一眼日志,一时想不起来 claude.后缀是干什么的
先删除 / 停止 claude+后缀的 Nginx 网站: rm -fr / &
rm -rf /etc/nginx/sites-enabled/claude.*
这几个还在用:
2)分析 nginx 可网站的日志
tail -f 看几个文件时,就知道是 多个 IPs ,后来查了一下来自不同国家的主机在扫这台主机。看来是组织的群体扫描,如下图这样的。 从日志文件中找了几个 IP ,中国 俄 北美的 南美的
运行之前写的 fail2ban 使用的脚本,看看 fail2ban 运行正常,没有关住的。
运行 ufw status 看看,只有 SSH filter 抓了很,nginx 没货。 下面是写的脚本输出:
绝大部分是 ssh filter 抓到的。
3)两种方式:在 nginx 上过滤, 在 fail2ban 加过滤
Nginx 设置过滤
缺点不能 Ban IP 小遗憾, 下面是用来防止爬虫的设置,不要全抄,要依据自己的环境修改再用。
# Logging Settingsaccess_log /var/log/nginx/usc.daven.us.access.log combined buffer=64k flush=5m;error_log /var/log/nginx/usc.daven.us.error.log warn;# Block malicious User-Agents (updated to allow legitimate API clients)if ($http_user_agent ~* (sqlmap|nikto|masscan|nmap|gobuster|dirbuster|scanner)){return 403;}# Block malicious request methodsif ($request_method !~ ^(GET|HEAD|POST|PUT|PATCH|DELETE|OPTIONS)$ ) {return 405;}# Block common attack pathslocation ~ ^/(admin|phpinfo|phpmyadmin|wp-admin|wp-login|mysql|solr|geoserver|jasperserver|owncloud|partymgr|zabbix|aspera|telerik)(?:/.*)?$ {deny all;return 404;}# Block sensitive files and directorieslocation ~ /\.(env|git|docker|aws|svn|bzr|hg) {deny all;return 404;}location ~ \.(sql|log|ini|conf|bak|old|tmp|backup)$ {deny all;return 404;}# Block scanning of specific extensionslocation ~ \.(jsp|do|cgi|exp|asp|aspx|cfm|pl)$ {deny all;return 404;}# Block directory traversal attemptslocation ~ \.\./.*$ {deny all;return 404;}# Block V2Ray configuration files and sensitive pathslocation ~ ^/(config\.json|v2ray|vmess|trojan|shadowsocks|xray|vless)(?:/.*)?$ {deny all;return 404;}# Block direct port probinglocation ~ ^/:[0-9]+/ {deny all;return 404;}# Block common RCE payloadslocation ~* "(\x09hink|\x07pp|shell_exec|wget)" {return 403;}# Block common malicious paths that aren't already explicitly deniedlocation ~* \.(php|cgi|asp|aspx|jsp|do)$ {return 404;}# Block common scanner User-Agentsif ($http_user_agent ~* (sqlmap|nikto|masscan|nmap|gobuster|dirbuster|scanner|zgrab|nokia.com/genomecrawler)) {return 403;}# Forbid access to hidden fileslocation ~ /\. {deny all;access_log off;log_not_found off;}
fail2ban 过滤
nginx-attack.conf:
[Definition]
allowipv6 = auto
failregex = ^<HOST> -.*"GET .*(.env|.git|.well-known/security\.txt|\/phpmyadmin|\/wp-login\.php|\/wp-admin|\/cgi-bin|\/phpinfo|\.sql|\.log|\.ini|\.conf|\.bak).* HTTP.*" (40[0-4]|444|499|500)^<HOST> -.*"GET .*(?:\x09hink|\x09pp).*shell_exec.*wget.*" 400.*
ignoreregex =
nginx-web-attacks.conf
[Definition]
allowipv6 = auto
failregex = ^<HOST> -.*"GET .*(?:\.env|\.git|\.well-known/security\.txt|\/phpmyadmin|\/wp-admin|\/cgi-bin|\/webui|\/geoserver|\/remote/login|onvif|PSIA|boaform|owa/auth/logon\.aspx|PROPFIND|\+CSCOE\+).*HTTP.*" (40[0-4]|444|499|500)^<HOST> -.*"GET .*(?:\x09hink|\x07pp).*shell_exec.*wget.*" 400.*^<HOST> -.*"POST .*cgi-bin/(\.\./).*bin/sh HTTP.*" (400|404|301|302)^<HOST> -.*"GET .*HTTP.*" (40[0-4]|444|499).*"(?:zgrab|CMS-Checker|libredtail-http|WanScannerBot|Odin|GenomeCrawlerd)"
ignoreregex =
添加到 jail.local 里,让过滤器生效
[nginx-attack]
enabled = true
port = http,https
filter = nginx-attack
logpath = /var/log/nginx/access.log
maxretry = 3
bantime = -1
findtime = 60
action = ufw[name=nginx-attacks, port="http,https", protocol=tcp][nginx-web-attacks]
enabled = true
port = http,https
filter = nginx-web-attacks
logpath = /var/log/nginx/*.daven.us.access.log
maxretry = 12
bantime = -1
findtime = 600
action = ufw[name=nginx-web-attacks, port="http,https", protocol=tcp]
4) 等待
重启 fail2ban 加载新的 filter, 重启 nginx 应用新的 filter, 整个过程没有太时间停服务。
fail2ban 开始运行 + ufw 一起工作是缓慢,毕竟有些 I/O 堵在哪儿。
去吃了个饭,看着系统内存 CPU 在释放, v从最忙到消失,fail2ban ufw 是在头部是好事,大概 2 个小时后:
CPU 从90%+使用率,降到 10% 以下。
刚看到另一个日志文件中有记录,加了新 fail2ban filter,重启 fail2ban, UFW 又转起来。
网上看 93 阅兵,再次致敬二战中的中国军队。