first commit
This commit is contained in:
commit
b5269d2826
130
README.md
Normal file
130
README.md
Normal file
@ -0,0 +1,130 @@
|
||||
```markdown
|
||||
# 阿里云安全组动态IP更新工具(CentOS 7.9 适用)
|
||||
|
||||

|
||||

|
||||
|
||||
用于动态更新阿里云安全组规则的自动化脚本,特别适配 CentOS 7.9 系统环境。
|
||||
|
||||
## 核心功能
|
||||
|
||||
- ✅ 自动检测公网IP变动
|
||||
- ✅ 批量更新多安全组规则
|
||||
- ✅ 智能迁移旧IP规则到新IP
|
||||
- ✅ 严格验证协议和端口规则
|
||||
- ✅ 自动记录IP变更历史
|
||||
|
||||
## 系统要求
|
||||
|
||||
- CentOS 7.9 操作系统
|
||||
- 已配置阿里云API访问权限
|
||||
- 基础工具:`curl`、`jq`
|
||||
|
||||
## 安装指南
|
||||
|
||||
### 1. 安装基础依赖
|
||||
```bash
|
||||
sudo yum install -y curl jq
|
||||
```
|
||||
|
||||
### 2. 安装阿里云CLI(二进制方式)
|
||||

|
||||
```bash
|
||||
# 解压安装包
|
||||
tar -zxvf aliyun-cli-linux-latest-amd64.tgz -C /usr/local/bin/
|
||||
|
||||
# 设置执行权限
|
||||
chmod +x /usr/local/bin/aliyun
|
||||
|
||||
# 验证安装
|
||||
aliyun --version
|
||||
```
|
||||
|
||||
### 3. 配置阿里云CLI
|
||||
```bash
|
||||
aliyun configure
|
||||
```
|
||||
按照提示输入:
|
||||
- AccessKey ID
|
||||
- AccessKey Secret
|
||||
- 默认地域ID(如 `cn-beijing`)
|
||||
- 输出格式选择 `json`
|
||||
|
||||
## 脚本配置
|
||||
|
||||
编辑 `alisg.sh` 修改以下参数:
|
||||
|
||||
```bash
|
||||
# 必填配置
|
||||
REGION="cn-beijing" # 您的阿里云地域
|
||||
SECURITY_GROUP_IDS=("sg-2zebj4i9uydml05xwejg") # 安全组ID数组
|
||||
LOG_FILE="/var/log/ip-update.log" # 推荐使用绝对路径
|
||||
|
||||
# 可选调试参数
|
||||
# _LAST_IP="142.171.168.162" # 手动指定旧IP
|
||||
# _CURRENT_IP="115.171.170.151" # 手动指定新IP
|
||||
```
|
||||
|
||||
## 使用方法
|
||||
|
||||
### 首次运行(测试模式)
|
||||
```bash
|
||||
chmod +x alisg.sh
|
||||
./alisg.sh
|
||||
```
|
||||
|
||||
### 生产环境建议
|
||||
```bash
|
||||
# 1. 创建专用目录
|
||||
sudo mkdir -p /opt/aliyun_sg
|
||||
sudo cp alisg.sh /opt/aliyun_sg/
|
||||
sudo chown root:root /opt/aliyun_sg/alisg.sh
|
||||
|
||||
# 2. 设置定时任务(每小时检查)
|
||||
echo "0 * * * * root /opt/aliyun_sg/alisg.sh >> /var/log/ip-update.log 2>&1" | sudo tee /etc/cron.d/aliyun_sg_update
|
||||
```
|
||||
|
||||
## 日志监控
|
||||
|
||||
建议定期检查日志文件:
|
||||
```bash
|
||||
tail -f /var/log/ip-update.log
|
||||
```
|
||||
|
||||
典型成功日志示例:
|
||||
```
|
||||
[2023-11-15 14:00:01] 检测到IP变更
|
||||
旧IP:142.171.168.162
|
||||
新IP:115.171.170.151
|
||||
安全组 sg-2zebj4i9uydml05xwejg 处理完成:
|
||||
- 已移除 TCP/22/22 规则
|
||||
- 已添加 TCP/22/22 规则(新IP)
|
||||
IP日志已更新
|
||||
```
|
||||
|
||||
## 安全建议
|
||||
|
||||
1. 限制日志文件权限:
|
||||
```bash
|
||||
sudo chmod 600 /var/log/ip-update.log
|
||||
```
|
||||
|
||||
2. 使用最小权限的AccessKey
|
||||
|
||||
3. 定期备份安全组规则:
|
||||
```bash
|
||||
aliyun ecs DescribeSecurityGroupAttribute --RegionId $REGION --SecurityGroupId $SG_ID > sg_backup.json
|
||||
```
|
||||
|
||||
## 故障排除
|
||||
|
||||
| 错误现象 | 解决方案 |
|
||||
|---------|----------|
|
||||
| `aliyun: command not found` | 检查PATH或使用完整路径 `/usr/local/bin/aliyun` |
|
||||
| 权限拒绝错误 | 使用 `sudo` 或检查AccessKey权限 |
|
||||
| JSON解析错误 | 安装正确版本的 `jq` 工具 |
|
||||
|
||||
## 许可证
|
||||
|
||||
MIT License - 自由使用和修改
|
||||
```
|
||||
162
alisg.sh
Normal file
162
alisg.sh
Normal file
@ -0,0 +1,162 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 定义一些常量
|
||||
REGION="cn-beijing" # 设置区域
|
||||
SECURITY_GROUP_IDS=("sg-2zebj4i9uydml05xwejg") # 设置你的安全组ID列表使用空格分隔,例如("sg-2zebj4i9uydml05xwejg" "sg-3jd9dkjs99ddjfksssdqe")
|
||||
LOG_FILE="ip-beijing.log" # 存储当前外网IP的日志文件
|
||||
|
||||
# 允许用户在脚本上方指定 last_ip 和 current_ip,如果为空则使用脚本自动获取(last_ip从LOG_FILE获取,current_ip从公网出口获取)
|
||||
_LAST_IP=""
|
||||
_CURRENT_IP=""
|
||||
|
||||
# 获取当前外网IP
|
||||
get_current_ip() {
|
||||
if [[ -z "$_CURRENT_IP" ]]; then
|
||||
_CURRENT_IP=$(curl -s ipinfo.io | grep -oP "[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}")
|
||||
fi
|
||||
echo "$_CURRENT_IP"
|
||||
}
|
||||
|
||||
# 获取上次保存的外网IP
|
||||
get_last_ip() {
|
||||
if [[ -z "$_LAST_IP" ]]; then
|
||||
if [[ -f "$LOG_FILE" ]]; then
|
||||
_LAST_IP=$(cat "$LOG_FILE")
|
||||
else
|
||||
echo "没有找到历史IP,无法比较, 请把需要修改的历史IP加入变量“_LAST_IP”或者写入${LOG_FILE}" >&2
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
echo "$_LAST_IP"
|
||||
}
|
||||
|
||||
# 更新日志文件,保存当前外网IP
|
||||
update_ip_log() {
|
||||
echo "$1" > "$LOG_FILE"
|
||||
}
|
||||
|
||||
# 获取当前安全组的所有IP规则
|
||||
get_security_group_rules() {
|
||||
aliyun ecs DescribeSecurityGroupAttribute \
|
||||
--RegionId "$REGION" \
|
||||
--SecurityGroupId "$1" \
|
||||
--NicType "internet" \
|
||||
--Direction "ingress" | jq -r '.Permissions.Permission[] | {IpProtocol, SourceCidrIp, PortRange, Description}'
|
||||
}
|
||||
|
||||
# 验证IpProtocol值是否合法
|
||||
is_valid_ip_protocol() {
|
||||
local protocol=$1
|
||||
case "$protocol" in
|
||||
"TCP" | "UDP" | "ICMP" | "GRE" | "All") return 0 ;;
|
||||
*) return 1 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
# 验证PortRange格式是否合法
|
||||
is_valid_port_range() {
|
||||
local port_range=$1
|
||||
if [[ "$port_range" =~ ^[0-9]+/[0-9]+$ ]]; then
|
||||
local start_port=$(echo "$port_range" | cut -d'/' -f1)
|
||||
local end_port=$(echo "$port_range" | cut -d'/' -f2)
|
||||
if [[ "$start_port" -le 65535 && "$end_port" -le 65535 ]]; then
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
# 移除指定的IP规则
|
||||
remove_ip_rule() {
|
||||
aliyun ecs RevokeSecurityGroup \
|
||||
--RegionId "$REGION" \
|
||||
--SecurityGroupId "$1" \
|
||||
--SourceCidrIp "$2" \
|
||||
--IpProtocol "$3" \
|
||||
--NicType "internet" \
|
||||
--PortRange "$4"
|
||||
}
|
||||
|
||||
# 添加新的IP规则
|
||||
add_ip_rule() {
|
||||
aliyun ecs AuthorizeSecurityGroup \
|
||||
--RegionId "$REGION" \
|
||||
--SecurityGroupId "$1" \
|
||||
--SourceCidrIp "$2" \
|
||||
--IpProtocol "$3" \
|
||||
--NicType "internet" \
|
||||
--PortRange "$4" \
|
||||
--Description "$5"
|
||||
}
|
||||
|
||||
# 主程序
|
||||
|
||||
# 如果用户没有指定 last_ip 或 current_ip,自动获取
|
||||
if [[ -z "$last_ip" ]]; then
|
||||
last_ip=$(get_last_ip)
|
||||
fi
|
||||
if [[ -z "$current_ip" ]]; then
|
||||
current_ip=$(get_current_ip)
|
||||
fi
|
||||
|
||||
# 如果IP发生变化
|
||||
if [[ "$current_ip" != "$last_ip" ]]; then
|
||||
echo "修改后IP:$current_ip"
|
||||
echo "修改前IP:$last_ip"
|
||||
[ -z $last_ip ] && exit
|
||||
# 遍历所有安全组ID并更新规则
|
||||
for sg_id in "${SECURITY_GROUP_IDS[@]}"; do
|
||||
# 获取当前安全组的规则
|
||||
rules=$(get_security_group_rules "$sg_id")
|
||||
|
||||
# 查找并移除旧的IP规则
|
||||
if [[ -z "$rules" ]]; then
|
||||
echo "没有找到任何安全组规则,无需处理"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
found_rules=false
|
||||
for rule in $(echo "$rules" | jq -r '.SourceCidrIp + "," + .IpProtocol + "," + .PortRange + "," + .Description' | grep $last_ip); do
|
||||
# 获取规则中的SourceCidrIp, IpProtocol 和 PortRange
|
||||
source_ip=$(echo "$rule" | awk -F',' '{print $1}')
|
||||
ip_protocol=$(echo "$rule" | awk -F',' '{print $2}')
|
||||
port_range=$(echo "$rule" | awk -F',' '{print $3}')
|
||||
description=$(echo "$rule" | awk -F',' '{print $4}')
|
||||
# 如果该规则的 IP 是旧 IP,则移除它
|
||||
if [[ "$source_ip" == "$last_ip/32" || "$source_ip" == "$last_ip" ]]; then
|
||||
# 验证IpProtocol和PortRange的合法性
|
||||
if is_valid_ip_protocol "$ip_protocol" && is_valid_port_range "$port_range"; then
|
||||
echo "移除旧规则:$source_ip $ip_protocol $port_range $description"
|
||||
remove_ip_rule "$sg_id" "$source_ip" "$ip_protocol" "$port_range" | jq '.RequestId'
|
||||
else
|
||||
echo "无效的规则:$source_ip $ip_protocol $port_range"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ "$found_rules" == false ]]; then
|
||||
echo "没有找到匹配 $last_ip 的旧规则,无需操作"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# 添加新的IP规则
|
||||
for rule in $(echo "$rules" | jq -r '.SourceCidrIp + "," + .IpProtocol + "," + .PortRange + "," + .Description' | grep $last_ip); do
|
||||
ip_protocol=$(echo "$rule" | awk -F',' '{print $2}')
|
||||
port_range=$(echo "$rule" | awk -F',' '{print $3}')
|
||||
description=$(echo "$rule" | awk -F',' '{print $4}')
|
||||
# 验证IpProtocol和PortRange的合法性
|
||||
if is_valid_ip_protocol "$ip_protocol" && is_valid_port_range "$port_range"; then
|
||||
echo "添加新的规则:$current_ip $current_ip/32 $ip_protocol $port_range $description"
|
||||
add_ip_rule "$sg_id" "$current_ip/32" "$ip_protocol" "$port_range" "$description" | jq '.RequestId'
|
||||
else
|
||||
echo "无效的规则:$current_ip $ip_protocol $port_range"
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
||||
# 更新日志文件,保存当前IP
|
||||
update_ip_log "$current_ip"
|
||||
else
|
||||
echo "IP没有变化,脚本不会进行任何操作"
|
||||
fi
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user