如何动态获取 GitHub 的 IP 并添加到 IPTables

在使用 GitHub Webhooks 时,为了保证服务器安全,可以仅允许 GitHub 的授权 IP 访问您的应用程序。GitHub 提供了一个 API,可以动态获取这些 IP 范围。本文将展示如何获取 GitHub 的 IP 并自动更新服务器的 iptables 规则。


环境要求

  1. 系统工具

    • curl:用于发送 HTTP 请求。
    • jq:用于解析 JSON 响应。

    使用以下命令安装:

    1
    2
    sudo apt update
    sudo apt install -y curl jq
  2. 管理员权限

    • 您需要 root 权限或 sudo 权限来修改 iptables 规则。

第一步:了解 GitHub Meta API

GitHub 提供了一个元数据 API 端点,其中包括 GitHub Webhooks 使用的 IP 范围:

API 地址:

1
https://api.github.com/meta

返回数据中的 hooks 字段包含 Webhooks 请求所需的 IP 范围。


第二步:编写脚本

以下是一个 Bash 脚本,用于动态获取 GitHub 的 IP 范围并更新 iptables

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

# 定义日志目录和文件
LOG_DIR="/var/log/github_ip_updates"
TIMESTAMP=$(date '+%Y%m%d_%H%M%S')
LOG_FILE="$LOG_DIR/github_ips_$TIMESTAMP.txt"

# 创建日志目录(如果不存在)
mkdir -p "$LOG_DIR"

# 定义 GitHub Meta API URL
GITHUB_META_URL="https://api.github.com/meta"

# 定义允许的端口(例如 GitHub Webhook 的端口)
WEBHOOK_PORT=9000

# 从 GitHub Meta API 获取 IP 范围
echo "正在从 $GITHUB_META_URL 获取 GitHub IP 地址..."
IP_RANGES=$(curl -s $GITHUB_META_URL | jq -r '.hooks[]')

# 检查是否成功获取 IP 范围
if [[ -z "$IP_RANGES" ]]; then
echo "无法从 GitHub 获取 IP 范围,脚本退出。"
exit 1
fi

# 将 IP 范围保存到日志文件
echo "$IP_RANGES" > "$LOG_FILE"
echo "已将 IP 范围保存到 $LOG_FILE。"

# 将 IP 范围添加到 iptables
for IP_RANGE in $IP_RANGES; do
# 检查规则是否已存在
if ! iptables -C INPUT -p tcp --dport $WEBHOOK_PORT -s "$IP_RANGE" -j ACCEPT &>/dev/null; then
echo "正在将 IP 范围 $IP_RANGE 添加到 iptables..."
iptables -A INPUT -p tcp --dport $WEBHOOK_PORT -s "$IP_RANGE" -j ACCEPT
else
echo "IP 范围 $IP_RANGE 已存在于 iptables 中。"
fi
done

echo "GitHub IP 地址已成功添加到 iptables。"

第三步:自动化脚本

为了确保 iptables 规则保持最新,您可以通过 cron 定期运行此脚本:

添加 Cron 任务

  1. 编辑 crontab:

    1
    crontab -e
  2. 添加以下行,每天午夜运行脚本:

    1
    0 0 * * * /path/to/update_github_ips.sh

确保脚本有执行权限

确保脚本可执行:

1
chmod +x /path/to/update_github_ips.sh

执行结果

第四步:增强安全性

为提高安全性:

  1. 默认策略: 设置默认的 iptables 策略为 DROP

    1
    iptables -P INPUT DROP
  2. 限制端口: 仅允许 GitHub Webhook 的 IP 访问必要端口(如 9000)。

  3. 清理旧规则: 定期检查并清理过时的 iptables 规则。


日志和故障排查

  • 日志保存到 /var/log/github_ip_updates/,带有时间戳。
  • 检查 IP 范围是否正确添加:
    1
    iptables -L -v
  • 如果 API 调用失败,确保网络连接正常并检查 GitHub API 端点是否可用。

结论

此方法通过动态更新服务器的 iptables 规则,确保 GitHub Webhook 的 IP 范围得到及时更新,提升了安全性,并实现了自动化,无需手动干预。