alisg/alisg.sh
2025-04-13 10:07:12 +08:00

163 lines
5.6 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/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