#!/bin/bash # ================================================== # TCP/UDP 网络深度调优脚本 # 版本: 1.0 # 用途: VPS / 代理服务器网络性能优化 # 使用: sudo bash tcp-tune.sh # ================================================== set -euo pipefail # --- 颜色定义 --- RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[0;33m' BLUE='\033[0;34m' CYAN='\033[0;36m' BOLD='\033[1m' NC='\033[0m' # --- 路径常量 --- SYSCTL_CONF="/etc/sysctl.d/99-tcp-tune.conf" LIMITS_CONF="/etc/security/limits.d/99-tcp-tune.conf" GAI_CONF="/etc/gai.conf" GAI_BACKUP="/etc/gai.conf.bak" # ================================================== # 工具函数 # ================================================== log_info() { echo -e "${GREEN}[INFO]${NC} $*"; } log_warn() { echo -e "${YELLOW}[WARN]${NC} $*"; } log_error() { echo -e "${RED}[ERROR]${NC} $*" >&2; } draw_line() { echo -e "${YELLOW}--------------------------------------------------${NC}"; } require_root() { if [ "$EUID" -ne 0 ]; then log_error "请使用 root 权限运行: sudo bash $0" exit 1 fi } # 安全执行 sysctl,只写入内核确实支持的参数 safe_sysctl_set() { local key="$1" local val="$2" if sysctl -n "$key" &>/dev/null; then sysctl -w "${key}=${val}" &>/dev/null && return 0 fi log_warn "内核不支持参数 $key,已跳过" return 0 } # 检测内核是否支持 BBR kernel_supports_bbr() { modprobe tcp_bbr &>/dev/null || true grep -q bbr /proc/sys/net/ipv4/tcp_available_congestion_control 2>/dev/null } # ================================================== # 功能模块 # ================================================== # --- 1. 设置 IPv4 优先解析 --- set_ipv4_priority() { echo -e "\n${BOLD}>>> 设置 IPv4 优先解析${NC}" # 确保 gai.conf 存在(某些极简系统没有) if [ ! -f "$GAI_CONF" ]; then log_warn "$GAI_CONF 不存在,将创建默认配置" cat > "$GAI_CONF" <<'EOF' label ::1/128 0 label ::/0 1 label 2002::/16 2 label ::/96 3 label ::ffff:0:0/96 4 precedence ::1/128 50 precedence ::/0 40 precedence 2002::/16 30 precedence ::/96 20 precedence ::ffff:0:0/96 10 EOF fi # 备份(幂等:只在首次备份) if [ ! -f "$GAI_BACKUP" ]; then cp "$GAI_CONF" "$GAI_BACKUP" log_info "已备份原始配置到 $GAI_BACKUP" fi # 追加 IPv4 优先规则(避免重复写入) if grep -q "^precedence ::ffff:0:0/96 100" "$GAI_CONF"; then log_info "IPv4 优先规则已存在,无需重复设置" else # 注释掉可能存在的旧规则,再追加新规则 sed -i 's/^precedence ::ffff:0:0\/96/#precedence ::ffff:0:0\/96/' "$GAI_CONF" echo "precedence ::ffff:0:0/96 100" >> "$GAI_CONF" log_info "IPv4 优先规则已写入 $GAI_CONF" fi echo -e "${GREEN}✅ IPv4 优先解析已激活${NC}" } # --- 2. 开启 BBR + FQ --- enable_bbr() { echo -e "\n${BOLD}>>> 开启 BBR + FQ 拥塞控制${NC}" if ! kernel_supports_bbr; then log_error "当前内核不支持 BBR,请升级内核(建议 4.9+)后重试" return 1 fi cat > /etc/sysctl.d/10-bbr.conf <<'EOF' net.core.default_qdisc = fq net.ipv4.tcp_congestion_control = bbr EOF sysctl --system &>/dev/null local cc cc=$(sysctl -n net.ipv4.tcp_congestion_control) local qd qd=$(sysctl -n net.core.default_qdisc) log_info "当前拥塞算法: ${GREEN}${cc}${NC}" log_info "当前队列调度: ${GREEN}${qd}${NC}" echo -e "${GREEN}✅ BBR + FQ 已启用${NC}" } # --- 3. 生产级内核调优 --- tune_sysctl() { echo -e "\n${BOLD}>>> 生产级内核参数调优${NC}" # 动态计算缓冲区大小(总内存的 5%,上限 512MB) local mem_kb mem_kb=$(grep MemTotal /proc/meminfo | awk '{print $2}') local buf_bytes=$(( mem_kb * 1024 / 20 )) # 5% local buf_max=$(( 512 * 1024 * 1024 )) # 512MB 上限 [ "$buf_bytes" -gt "$buf_max" ] && buf_bytes=$buf_max local cpu_count cpu_count=$(nproc) local mem_mb=$(( mem_kb / 1024 )) log_info "检测到: ${cpu_count} 核心 / ${mem_mb}MB 内存" log_info "动态缓冲区: $(( buf_bytes / 1024 / 1024 ))MB" # 写入配置文件 cat > "$SYSCTL_CONF" </dev/null; then log_info "内核参数已应用" else log_warn "部分参数应用失败,请检查内核版本兼容性" sysctl --system 2>&1 | grep -i error || true fi # 写入文件句柄限制 mkdir -p /etc/security/limits.d/ cat > "$LIMITS_CONF" <<'EOF' # 文件句柄限制 - 由 tcp-tune.sh 生成 * soft nofile 1048576 * hard nofile 1048576 * soft nproc 65535 * hard nproc 65535 EOF log_info "文件句柄限制已写入 $LIMITS_CONF(重新登录后生效)" # MSS Clamp(仅在 iptables 可用时设置) if command -v iptables &>/dev/null; then iptables -t mangle -D POSTROUTING -p tcp --tcp-flags SYN,RST SYN \ -j TCPMSS --clamp-mss-to-pmtu 2>/dev/null || true iptables -t mangle -A POSTROUTING -p tcp --tcp-flags SYN,RST SYN \ -j TCPMSS --clamp-mss-to-pmtu log_info "MSS Clamp 规则已设置" else log_warn "iptables 不可用,已跳过 MSS Clamp" fi echo -e "${GREEN}✅ 内核参数调优完成${NC}" echo -e "${CYAN}ℹ 配置已持久化: $SYSCTL_CONF${NC}" echo -e "${CYAN}ℹ 重启后仍然生效${NC}" } # --- 4. 网卡多队列均衡 (RPS) --- tune_nic_rps() { echo -e "\n${BOLD}>>> 网卡多队列均衡 (RPS/RFS)${NC}" local cpu_count cpu_count=$(nproc) # 生成 CPU 掩码:例如 4 核 = 0xf local rps_mask rps_mask=$(printf '%x' $(( (1 << cpu_count) - 1 ))) # 过滤虚拟/回环接口 local interfaces interfaces=$(ls /sys/class/net/ | grep -vE '^(lo|docker|veth|br-|bond|sit|tun|tap|wg|dummy)' || true) if [ -z "$interfaces" ]; then log_warn "未找到可优化的物理/虚拟以太网接口" return 0 fi for eth in $interfaces; do log_info "优化接口: $eth (RPS mask: 0x${rps_mask})" # RPS: 将软中断分发到所有 CPU for rps_file in /sys/class/net/$eth/queues/rx-*/rps_cpus; do [ -f "$rps_file" ] && echo "$rps_mask" > "$rps_file" done # RFS: 套接字流条目 for rfc_file in /sys/class/net/$eth/queues/rx-*/rps_flow_cnt; do [ -f "$rfc_file" ] && echo "4096" > "$rfc_file" done # 尝试扩大 Ring Buffer(ethtool 可选) if command -v ethtool &>/dev/null; then local max_rx max_rx=$(ethtool -g "$eth" 2>/dev/null \ | awk '/Pre-set maximums/{f=1} f && /^RX:/{print $2; exit}') if [ -n "$max_rx" ]; then ethtool -G "$eth" rx "$max_rx" tx "$max_rx" &>/dev/null || true log_info "$eth Ring Buffer -> RX/TX: $max_rx" fi fi done # 全局 RFS 流条目 safe_sysctl_set net.core.rps_sock_flow_entries 32768 echo -e "${GREEN}✅ 网卡多队列均衡已配置 (${cpu_count} 核心)${NC}" } # --- 5. 回退所有设置 --- rollback_all() { echo -e "\n${BOLD}${RED}>>> 回退所有调优设置${NC}" read -rp "确认回退?将清除所有配置文件并恢复默认参数 [y/N]: " confirm if [[ ! "$confirm" =~ ^[Yy]$ ]]; then log_info "已取消" return 0 fi # 清理配置文件 rm -f "$SYSCTL_CONF" "$LIMITS_CONF" /etc/sysctl.d/10-bbr.conf log_info "已删除调优配置文件" # 恢复 gai.conf if [ -f "$GAI_BACKUP" ]; then mv "$GAI_BACKUP" "$GAI_CONF" log_info "已从备份恢复 $GAI_CONF" else sed -i 's/^precedence ::ffff:0:0\/96 100/#precedence ::ffff:0:0\/96 100/' \ "$GAI_CONF" 2>/dev/null || true fi # 恢复内核内存参数 safe_sysctl_set net.ipv4.tcp_congestion_control cubic safe_sysctl_set net.core.default_qdisc pfifo_fast safe_sysctl_set net.core.rps_sock_flow_entries 0 # 清理 MSS Clamp if command -v iptables &>/dev/null; then iptables -t mangle -D POSTROUTING -p tcp --tcp-flags SYN,RST SYN \ -j TCPMSS --clamp-mss-to-pmtu 2>/dev/null || true fi # 清理 RPS local interfaces interfaces=$(ls /sys/class/net/ | grep -vE '^(lo|docker|veth|br-|bond|sit|tun|tap|wg|dummy)' || true) for eth in $interfaces; do for rps_file in /sys/class/net/$eth/queues/rx-*/rps_cpus; do [ -f "$rps_file" ] && echo "0" > "$rps_file" done done sysctl --system &>/dev/null log_info "内核参数已恢复默认" echo -e "${GREEN}✅ 回退完成${NC}" } # --- 6. 显示当前状态 --- show_status() { echo -e "\n${BOLD}>>> 当前系统网络状态${NC}" draw_line printf " %-24s : ${GREEN}%s${NC}\n" \ "拥塞算法" "$(sysctl -n net.ipv4.tcp_congestion_control 2>/dev/null)" printf " %-24s : ${GREEN}%s${NC}\n" \ "队列调度" "$(sysctl -n net.core.default_qdisc 2>/dev/null)" printf " %-24s : ${GREEN}%s${NC}\n" \ "TCP 缓冲区上限" "$(( $(sysctl -n net.core.rmem_max 2>/dev/null || echo 0) / 1024 / 1024 ))MB" printf " %-24s : ${GREEN}%s${NC}\n" \ "最大连接队列" "$(sysctl -n net.core.somaxconn 2>/dev/null)" printf " %-24s : ${GREEN}%s${NC}\n" \ "当前文件句柄上限" "$(ulimit -n)" printf " %-24s : ${GREEN}%s${NC}\n" \ "RPS 流条目" "$(sysctl -n net.core.rps_sock_flow_entries 2>/dev/null)" # IPv4 优先状态 if [ -f "$GAI_CONF" ] && grep -q "^precedence ::ffff:0:0/96 100" "$GAI_CONF"; then printf " %-24s : ${GREEN}%s${NC}\n" "IPv4 优先" "已激活" else printf " %-24s : ${RED}%s${NC}\n" "IPv4 优先" "未开启" fi # 配置文件持久化状态 if [ -f "$SYSCTL_CONF" ]; then printf " %-24s : ${GREEN}%s${NC}\n" "内核调优持久化" "已写入 $SYSCTL_CONF" else printf " %-24s : ${RED}%s${NC}\n" "内核调优持久化" "未配置" fi draw_line } # ================================================== # 主菜单 # ================================================== main_menu() { require_root while true; do # 实时检测状态 local s_ipv4 s_bbr s_sysctl s_nic if [ -f "$GAI_CONF" ] && grep -q "^precedence ::ffff:0:0/96 100" "$GAI_CONF"; then s_ipv4="${GREEN}[已激活]${NC}" else s_ipv4="${RED}[未开启]${NC}" fi if [ "$(sysctl -n net.ipv4.tcp_congestion_control 2>/dev/null)" = "bbr" ]; then s_bbr="${GREEN}[已激活]${NC}" else s_bbr="${RED}[未开启]${NC}" fi [ -f "$SYSCTL_CONF" ] && s_sysctl="${GREEN}[已激活]${NC}" || s_sysctl="${RED}[未开启]${NC}" if [ "$(sysctl -n net.core.rps_sock_flow_entries 2>/dev/null)" = "32768" ]; then s_nic="${GREEN}[已激活]${NC}" else s_nic="${RED}[未开启]${NC}" fi clear draw_line echo -e "${BOLD} TCP/UDP 网络深度调优面板${NC}" draw_line echo -e " 1. 设置 IPv4 优先解析 $s_ipv4" echo -e " 2. 开启 BBR + FQ 拥塞控制 $s_bbr" echo -e " 3. 生产级内核参数调优 $s_sysctl" echo -e " 4. 网卡多队列均衡 (RPS) $s_nic" echo -e " 5. 一键应用全部优化 (1-4)" echo -e " 6. 查看当前系统状态" echo -e " 7. 回退所有设置到默认" echo -e " 0. 退出" draw_line echo -e "算法: ${GREEN}$(sysctl -n net.ipv4.tcp_congestion_control 2>/dev/null)${NC} | 文件句柄: ${GREEN}$(ulimit -n)${NC}" draw_line read -rp "请选择 [0-7]: " opt case "$opt" in 1) set_ipv4_priority && read -rp "按回车继续..." ;; 2) enable_bbr && read -rp "按回车继续..." ;; 3) tune_sysctl && read -rp "按回车继续..." ;; 4) tune_nic_rps && read -rp "按回车继续..." ;; 5) set_ipv4_priority enable_bbr tune_sysctl tune_nic_rps read -rp "全部优化完成,按回车继续..." ;; 6) show_status && read -rp "按回车继续..." ;; 7) rollback_all && read -rp "按回车继续..." ;; 0) echo -e "${GREEN}已退出${NC}"; exit 0 ;; *) log_error "无效输入,请输入 0-7"; sleep 1 ;; esac done } main_menu