腾讯云服务器连接GitHub

2025-6-20·技术浅谈

1.起因

自从把博客迁移到了Next.js,我就把代码放在了GitHub,尽管我之前写了一套我自己的Devops,但是服务器有时候不能访问GitHub导致不能拉取仓库代码,所以我写了一个自动化脚本,用于服务器定时更新Host文件以确保我的服务器能正常访问GitHub

2.脚本内容

创建一个名为 update_github_hosts.sh 的脚本:

#!/bin/bash

# GitHub访问优化脚本
# 作者: 系统管理员
# 用途: 定期更新GitHub相关域名的hosts记录

HOSTS_FILE="/etc/hosts"
BACKUP_DIR="/etc/hosts_backups"
BACKUP_FILE="$BACKUP_DIR/hosts.backup.$(date +%Y%m%d_%H%M%S)"

# 创建备份目录
create_backup_dir() {
    if [ ! -d "$BACKUP_DIR" ]; then
        mkdir -p "$BACKUP_DIR"
    fi
}

# 备份hosts文件并管理备份数量
manage_backups() {
    create_backup_dir
    
    # 创建新备份
    cp "$HOSTS_FILE" "$BACKUP_FILE"
    echo "已备份hosts文件到: $BACKUP_FILE"
    
    # 只保留最新的3个备份文件
    cd "$BACKUP_DIR"
    ls -t hosts.backup.* 2>/dev/null | tail -n +4 | xargs rm -f 2>/dev/null
    
    echo "当前保留的备份文件:"
    ls -la "$BACKUP_DIR"/hosts.backup.* 2>/dev/null || echo "无备份文件"
}

# 获取IP地址函数
get_ip() {
    local domain=$1
    local ip=""
    
    # 尝试多个DNS服务器
    for dns in "8.8.8.8" "1.1.1.1" "114.114.114.114"; do
        ip=$(nslookup "$domain" "$dns" 2>/dev/null | grep -A 1 "Name:" | grep "Address:" | awk '{print $2}' | head -1)
        if [ -n "$ip" ] && [[ "$ip" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
            echo "$ip"
            return 0
        fi
    done
    
    # 如果nslookup失败,尝试dig
    ip=$(dig +short "$domain" @8.8.8.8 2>/dev/null | grep -E '^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$' | head -1)
    if [ -n "$ip" ]; then
        echo "$ip"
        return 0
    fi
    
    return 1
}

# GitHub相关域名列表
GITHUB_DOMAINS=(
    "github.com"
    "api.github.com"
    "www.github.com"
    "raw.githubusercontent.com"
    "gist.githubusercontent.com"
    "cloud.githubusercontent.com"
    "camo.githubusercontent.com"
    "avatars0.githubusercontent.com"
    "avatars1.githubusercontent.com"
    "avatars2.githubusercontent.com"
    "avatars3.githubusercontent.com"
    "avatars.githubusercontent.com"
    "github.githubassets.com"
    "assets-cdn.github.com"
)

main() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - 开始更新GitHub hosts记录"
    
    # 备份hosts文件并管理备份数量
    manage_backups
    
    # 移除旧的GitHub记录
    sed -i '/# GitHub Start/,/# GitHub End/d' "$HOSTS_FILE"
    
    # 添加新的GitHub记录
    echo "" >> "$HOSTS_FILE"
    echo "# GitHub Start - $(date)" >> "$HOSTS_FILE"
    
    local updated_count=0
    local failed_domains=()
    
    for domain in "${GITHUB_DOMAINS[@]}"; do
        echo "正在解析域名: $domain"
        ip=$(get_ip "$domain")
        
        if [ $? -eq 0 ] && [ -n "$ip" ]; then
            echo "$ip $domain" >> "$HOSTS_FILE"
            echo "成功更新: $ip $domain"
            ((updated_count++))
        else
            echo "警告: 无法解析域名 $domain"
            failed_domains+=("$domain")
        fi
        
        # 避免请求过于频繁
        sleep 1
    done
    
    echo "# GitHub End - $(date)" >> "$HOSTS_FILE"
    
    # 刷新DNS缓存
    if command -v systemctl &> /dev/null; then
        systemctl restart systemd-resolved 2>/dev/null || true
    fi
    
    # 输出统计信息
    echo "$(date '+%Y-%m-%d %H:%M:%S') - 更新完成! 成功更新 $updated_count 个域名"
    
    if [ ${#failed_domains[@]} -gt 0 ]; then
        echo "失败的域名: ${failed_domains[*]}"
    fi
    
    echo "GitHub hosts更新任务完成"
    echo "----------------------------------------"
}

# 检查是否为root用户
if [ "$EUID" -ne 0 ]; then
    echo "请使用root权限运行此脚本"
    exit 1
fi

# 执行主函数
main

3.安装和配置步骤

1. 创建脚本文件

sudo vim /usr/local/bin/update_github_hosts.sh

2. 赋予执行权限

sudo chmod +x /usr/local/bin/update_github_hosts.sh

3. 设置定时任务

编辑crontab:

sudo crontab -e

添加以下行(每天凌晨2点执行):

0 2 * * * /usr/local/bin/update_github_hosts.sh

或者每12小时执行一次:

0 2,14 * * * /usr/local/bin/update_github_hosts.sh

5. 手动测试脚本

sudo /usr/local/bin/update_github_hosts.sh

4.额外的优化脚本

如果你想要一个更简单的版本,这里还有一个轻量级的脚本:

#!/bin/bash
# 简化版GitHub hosts更新脚本

HOSTS_FILE="/etc/hosts"

# 移除旧记录
sed -i '/# GitHub/d' "$HOSTS_FILE"

# 获取并添加新记录
{
    echo "# GitHub - $(date)"
    echo "$(dig +short github.com @8.8.8.8) github.com"
    echo "$(dig +short api.github.com @8.8.8.8) api.github.com"
    echo "$(dig +short raw.githubusercontent.com @8.8.8.8) raw.githubusercontent.com"
} >> "$HOSTS_FILE"

echo "GitHub hosts已更新 - $(date)"

5.使用说明

  1. 日志查看:脚本运行日志保存在 /var/log/github_hosts_update.log
  2. 备份恢复:如果出现问题,可以从 /etc/hosts.backup.日期 恢复
  3. 手动执行:可以随时手动运行脚本进行更新
  4. 监控效果:可以通过 ping github.com 测试连接效果