言成言成啊 | Kit Chen's Blog

CentOS7定时任务及实践

发布于2023-01-03 01:01:35,更新于2024-09-30 15:38:18,标签:devops nginx  文章会持续修订,转载请注明来源地址:https://meethigher.top/blog

简单记录CentOS7中的crontab使用,以及使用crontab实现Nginx服务器自动封禁ip

一、定时任务

crontab,用来提交和管理用户的需要周期性执行的任务。与windows下的计划任务类似,当安装完成操作系统后,默认会安装此服务工具,并且会自动启动crond进程,crond进程每分钟会定期检查是否有要执行的任务,如果有要执行的任务,则自动执行该任务。

1.1 语法

服务相关命令

1
systemctl [status|start|stop|restart|enable|disable] crond

基本语法

crontab [选项] [参数]

1.) 选项

  1. -e 编辑该用户的定时任务
  2. -l 列出该用户的定时任务
  3. -r 删除该用户的定时任务
  4. -u <user> 指定定时任务所属的用户

2.) 参数,即包含待执行任务的crontab文件。

1.2 编辑任务

输入crontab -e即可进入任务编辑,如图

二、应用保活

老板写的微服务转发应用有两个重大严重Bug

  1. JVM崩溃,会生成hs_err_pid.log日志。
  2. 大量close_wait导致程序假死。

目前我也没时间排查解决,故采取最蠢的办法解决最复杂的问题。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#!/bin/bash

jar="test.jar"
jarPath="/opt/project"
jarExecute="nohup java -jar $jar --spring.config.location=bootstrap.yml >/dev/null 2>&1 &"
logFile="/var/log/test.log"
maxSize=1024000 # 单位byte
backupCount=5
count=$(netstat -ano|grep 8080|wc -l)
echo "$(date): $jar $count" >> $logFile
if [ "$count" -eq 0 ] || [ "$count" -gt 350 ]; then
netsta -ano|grep tcp > "$jarPath/netstat$(date +%Y%m%d%H%M).log"
echo "$(date): $jar needs to restart " >> $logFile
pkill -9 -f $jar
echo "$(date): $jar is killed" >> $logFile
cd $jarPath
eval $jarExecute
echo "$(date): $jar is restarted, pid is $!" >> $logFile
else
echo "$(date): $jar is running normally " >> $logFile
fi

if [ -f "$logFile" ]; then
fileSize=$(stat -c%s "$logFile")
if [ "$fileSize" -ge "$maxSize" ]; then
for((i=$backupCount; i>0; i--)); do
if [ -f "$logFile.$i" ]; then
mv "$logFile.$i" "$logFile.$((i+1))"
fi
done
mv "$logFile" "$logFile.1"
touch $logFile
fi
fi

三、Nginx封IP

以下内容,都是抄袭来的,经过自己简单修改。

参考地址在致谢参考里

nginx中在server下面,配置deny即可实现封禁ip

deny的配置比较灵活,既可以在server下面配置,也可以在server下具体到某个location配置。

3.1 实现封禁ip的脚本

先配置nginx.conf,添加配置

1
include blockip.conf;

进入到目录/usr/local/nginx/logs/,创建bash脚本ip-block

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#!/bin/bash
# 配置变量
NGINX_CONF="/usr/local/nginx/conf/nginx.conf"
IP_BLACKLIST="/usr/local/nginx/conf/blockip.conf"
LOG_FILE="/usr/local/nginx/logs/access.log"
# 在指定时间内允许的最大请求数
THRESHOLD=500
# 时间间隔(秒)
TIME_INTERVAL=60
# 设置为 true 开启调试模式
DEBUG=false

# 检查是否以root权限运行
if [ "$(id -u)" != "0" ]; then
#echo "此脚本必须以root权限运行" 1>&2
exit 1
fi

# 确保IP黑名单文件存在
touch $IP_BLACKLIST

# 调试函数
debug() {
if [ "$DEBUG" = true ]; then
echo "[DEBUG] $1" >&2
fi
}

clear_old_block() {
#不能把别人IP一直封着吧,这里就清除掉了
echo "" >"$IP_BLACKLIST"
}

# 分析日志并封锁IP
analyze_and_block() {
debug "开始分析日志并封锁IP..."

# 获取当前时间戳
current_time=$(date +%s)
debug "当前时间戳: $current_time"

# 使用awk分析日志,找出在指定时间内请求次数超过阈值的IP
suspicious_ips=$(awk -v interval="$TIME_INTERVAL" -v threshold="$THRESHOLD" -v current_time="$current_time" -v debug="$DEBUG" '
function parse_time(time_string) {
gsub(/[\[\]]/, "", time_string)
split(time_string, a, "[/: ]")
months["Jan"]=1; months["Feb"]=2; months["Mar"]=3; months["Apr"]=4; months["May"]=5; months["Jun"]=6;
months["Jul"]=7; months["Aug"]=8; months["Sep"]=9; months["Oct"]=10; months["Nov"]=11; months["Dec"]=12;
timestamp = mktime(a[3] " " months[a[2]] " " a[1] " " a[4] " " a[5] " " a[6])
return timestamp
}

function debug_print(message) {
if (debug == "true") {
print "[DEBUG] " message > "/dev/stderr"
}
}

{
ip = $1
log_time = parse_time($4)
debug_print("$4: " $4 " IP: " ip ", Log Time: " log_time ", Current Time: " current_time ", Difference: " (current_time - log_time) " seconds")

if (current_time - log_time <= interval) {
count[ip]++
debug_print("IP: " ip ", Count: " count[ip])
if (count[ip] == threshold) {
print ip
debug_print("IP " ip " has reached the threshold")
}
}
}' "$LOG_FILE")

debug "可疑IP列表: $suspicious_ips"

# 封锁可疑IP
if [ -n "$suspicious_ips" ]; then
echo "$suspicious_ips" | while IFS= read -r ip; do
# debug "处理IP: $ip"
if ! grep -q "deny $ip;" "$IP_BLACKLIST"; then
echo "deny $ip;" >>"$IP_BLACKLIST"
debug "已封锁IP: $ip"
else
debug "IP $ip 已在黑名单中"
fi
done
else
debug "没有发现需要封锁的IP"
fi
}

# 重新加载Nginx配置
reload_nginx() {
# 该操作会导致nginx先stop再start,如果是流式下载就会断开重新下载了
# systemctl restart nginx
# 使用reload可以保证只重载配置文件
/usr/local/nginx/sbin/nginx -s reload
}

# 主函数
main() {
clear_old_block
analyze_and_block
reload_nginx
}

# 运行主函数
main

3.2 定时任务每分钟执行封禁脚本

添加定时任务

1
crontab -e

直接输入内容

1
* * * * * sh /usr/local/nginx/logs/ip-block

crontab中的cron表达式可以使用在线模拟解析Crontab表达式执行时间 - ToolTT在线工具箱进行测试。

重启定时服务

1
systemctl restart crond

四、致谢参考

CentOS7必备技能下的定时任务 crontab的使用_佞臣888的博客-CSDN博客

服务又被攻击?Nginx + 简单脚本,轻松拦截

发布:2023-01-03 01:01:35
修改:2024-09-30 15:38:18
链接:https://meethigher.top/blog/2023/crontab/
标签:devops nginx 
付款码 打赏 分享
Shift+Ctrl+1 可控制工具栏