悠米是只猫

悠米是只猫

使用 GitHub Actions 自动化过滤 IP 地址并更新到仓库

2025-01-11

引言

随着网络应用的不断扩展,IP 地址管理变得越来越重要。特别是在需要根据不同国家和地区进行流量控制或安全策略的情况下,自动化处理 IP 地址列表是一个高效的方法。本文将介绍如何使用 GitHub Actions 自动化过滤 IP 地址,并将其更新到 GitHub 仓库中。

目标

我们的目标是创建一个 GitHub Actions 工作流,该工作流将:

  1. 每天凌晨两点(中国时间)自动运行。

  2. 使用 Python 脚本过滤特定国家的 IP 地址。

  3. 将过滤后的 IP 地址列表提交到 GitHub 仓库。

步骤概述

  1. 创建工作流文件

  2. 设置定时任务

  3. 配置 Python 环境

  4. 编写脚本

  5. 检查和提交更改

  6. 处理未提交的更改

1. 创建工作流文件

首先,在你的 GitHub 仓库中创建一个新的工作流文件。通常,这些文件位于 .github/workflows 目录下。我们将创建一个名为 filter-ip-addresses.yml 的文件。

name: Filter IP Addresses for Country

on:
  schedule:
    - cron: '0 18 * * *' # 每天下午六点 UTC 运行,对应中国时间每天凌晨两点
  workflow_dispatch: # 手动触发

jobs:
  run-script:
    runs-on: ubuntu-latest
    permissions:
      contents: write

    steps:
    - name: Checkout repository
      uses: actions/checkout@v3

    - name: Set up Python
      uses: actions/setup-python@v4
      with:
        python-version: '3.x'

    - name: Install dependencies
      run: |
        echo "Upgrading pip..."
        python -m pip install --upgrade pip
        echo "Installing requests library..."
        pip install requests

    - name: Run script
      run: |
        echo "Running the filtering script..."
        python filter_iplist_for_country.py

    - name: Check if changes are present
      id: check_changes
      run: |
        echo "Checking for changes in the repository..."
        git status
        if [[ $(git diff-index --quiet HEAD || echo "modified") == "modified" ]]; then
          echo "changed=true" >> $GITHUB_ENV
        fi
      shell: bash

    - name: Commit and push changes
      if: env.changed == 'true'
      run: |
        echo "Adding new files to staging area..."
        git add all_cn.txt all_cn_ipv6.txt delegated-apnic-latest
        echo "Configuring Git user information..."
        git config user.name "JinkaiNiu"
        git config user.email "niujinkai@vip.qq.com"
        echo "Committing changes..."
        git commit -m "Update IP lists"
        echo "Pushing changes to repository..."
        git push origin ${{ github.ref }}
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

    - name: Log completion
      run: echo "Workflow completed successfully."

2. 设置定时任务

在上面的工作流文件中,我们设置了定时任务 cron: '0 18 * * *',这表示每天下午六点 UTC 运行一次。由于 UTC 时间比中国时间晚八小时,因此这个时间对应于中国时间每天凌晨两点。

3. 配置 Python 环境

Set up Python 步骤中,我们使用 actions/setup-python@v4 动作来安装 Python 3.x 版本。接下来,我们在 Install dependencies 步骤中升级 pip 并安装所需的库 requests

4. 编写脚本

假设你已经有一个名为 filter_iplist_for_country.py 的脚本,用于过滤 IP 地址并将结果保存到 all_cn.txtall_cn_ipv6.txt 文件中。你可以根据需要调整这个脚本。

import requests

def download_file(url, filename, max_retries=3):
    retries = 0
    while retries < max_retries:
        print("开始下载文件...")
        response = requests.get(url)
        if response.status_code == 200:
            with open(filename, 'wb') as file:
                file.write(response.content)
            print(f"文件下载成功: {filename}")
            return True
        else:
            retries += 1
            print(f"文件下载失败,状态码: {response.status_code},正在重试({retries}/{max_retries})")
    print("达到最大重试次数,放弃下载")
    return False

def filter_ip_addresses_for_country(input_filename, output_v4_filename, output_v6_filename, country_code='CN'):
    print("开始筛选IP地址...")
    ipv4_addresses = []
    ipv6_addresses = []

    try:
        with open(input_filename, 'r') as file:
            for line in file:
                parts = line.strip().split('|')
                if len(parts) > 6 and parts[1] == country_code:
                    if parts[2] == 'ipv4':
                        start_ip = parts[3]
                        num_ips = int(parts[4])
                        prefix_length = 32 - (num_ips).bit_length() + 1
                        ipv4_addresses.append(f"{start_ip}/{prefix_length}")
                    elif parts[2] == 'ipv6':
                        start_ip = parts[3]
                        prefix_length = parts[4]
                        ipv6_addresses.append(f"{start_ip}/{prefix_length}")

    except FileNotFoundError:
        print(f"文件未找到: {input_filename}")
        return

    # Write IPv4 addresses to the output file
    with open(output_v4_filename, 'w') as file:
        for address in ipv4_addresses:
            file.write(address + '\n')

    # Write IPv6 addresses to the separate output file
    with open(output_v6_filename, 'w') as file:
        for address in ipv6_addresses:
            file.write(address + '\n')

    print(f"筛选完成,结果已保存到: {output_v4_filename} 和 {output_v6_filename}")

if __name__ == "__main__":
    url = "http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest"
    input_filename = "delegated-apnic-latest"
    output_v4_filename = "all_cn.txt"
    output_v6_filename = "all_cn_ipv6.txt"

    if download_file(url, input_filename):
        filter_ip_addresses_for_country(input_filename, output_v4_filename, output_v6_filename)

5. 检查和提交更改

Check if changes are present 步骤中,我们使用 git status 检查仓库的状态,并通过环境变量 changed 记录是否有变更。

6. 处理未提交的更改

Commit and push changes 步骤中,我们只在检测到有变更时才执行添加、提交和推送操作。这样可以避免不必要的空提交。

总结

通过本文的步骤,你已经成功创建了一个 GitHub Actions 工作流,该工作流能够自动化过滤特定国家的 IP 地址,并将结果定期更新到 GitHub 仓库中。这种方法不仅提高了效率,还减少了手动操作的错误率。

希望这篇文章对你有所帮助!如果你有任何问题或建议,请随时留言交流。


希望这篇博客文章能满足你的需求。如果有任何进一步的修改或补充,请告诉我!