Skip to content

Instantly share code, notes, and snippets.

@lainbo
Last active February 22, 2026 07:41
Show Gist options
  • Select an option

  • Save lainbo/40c7fd52611bbdc13c271b5a7535137a to your computer and use it in GitHub Desktop.

Select an option

Save lainbo/40c7fd52611bbdc13c271b5a7535137a to your computer and use it in GitHub Desktop.
Debian 系,网络优化脚本,开启 bbr,增大 open files 参数等
#!/bin/bash
# ==============================================================================
# Debian/Ubuntu 代理服务器优化脚本 (v2025.12-fixed)
#
# 适用场景: <100 用户的代理服务及小型网站,注重弱网环境下的性能与稳定性。
# 核心优化: 开启 BBRv1, 优化 TCP 参数, 调整文件句柄, 禁用 IPv6。
# 特点: 安全、幂等 (可重复运行)、智能验证、有详细注释。
# 修复: 自动加载 nf_conntrack 模块,避免 sysctl 参数应用失败
# ==============================================================================
# --- 配置变量 (可根据需要调整) ---
# 文件/进程限制 (100用户 * 200连接/用户 * 6倍冗余 ≈ 120k, 取2^17)
LIMIT_COUNT=131072
# TCP 连接跟踪表大小 (LIMIT_COUNT * 2)
CONNTRACK_MAX=262144
# --- 脚本环境设置 ---
set -e # 任何命令失败则立即退出
set -o pipefail # 管道中任何一个命令失败,整个管道视为失败
# --- 颜色定义 ---
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m' # No Color
# --- 脚本执行 ---
main() {
check_root
check_kernel
echo -e "${GREEN}开始执行服务器网络与系统限制优化...${NC}"
backup_configs
configure_limits
load_kernel_modules # 新增:在应用 sysctl 之前加载必要的内核模块
configure_sysctl
apply_and_verify
echo -e "${GREEN}=====================================================${NC}"
echo -e "${GREEN} 🎉 所有优化配置已成功应用! 🎉 ${NC}"
echo -e "${GREEN}=====================================================${NC}"
echo -e "${YELLOW}重要: 文件限制等部分系统级配置需要重启或重新登录后才能完全生效。${NC}"
prompt_reboot
}
# --- 功能函数 ---
check_root() {
if [[ "$EUID" -ne 0 ]]; then
echo -e "${RED}错误: 此脚本必须以 root 权限运行。${NC}"
exit 1
fi
}
check_kernel() {
local kernel_version
kernel_version=$(uname -r | cut -d- -f1)
if dpkg --compare-versions "$kernel_version" "lt" "4.9"; then
echo -e "${YELLOW}警告: 当前内核版本 ($kernel_version) 低于 4.9,原生不支持 BBR。${NC}"
echo -e "${YELLOW}脚本将继续执行,但 BBR 可能无法启用。请考虑升级内核。${NC}"
read -n 1 -s -r -p "按任意键继续..."
echo
fi
}
backup_configs() {
local backup_time
backup_time=$(date +%Y%m%d_%H%M%S)
local backup_dir="/root/config_backups/${backup_time}"
mkdir -p "$backup_dir"
echo "-> 备份原始配置文件到 ${backup_dir}"
cp /etc/sysctl.conf "$backup_dir/" 2>/dev/null || true
cp /etc/security/limits.conf "$backup_dir/" 2>/dev/null || true
cp /etc/pam.d/common-session "$backup_dir/" 2>/dev/null || true
cp /etc/pam.d/common-session-noninteractive "$backup_dir/" 2>/dev/null || true
cp /etc/systemd/system.conf "$backup_dir/" 2>/dev/null || true
}
configure_limits() {
echo "-> 配置系统文件/进程限制为 ${LIMIT_COUNT}"
cat > /etc/security/limits.conf <<EOF
# Auto-generated by optimization script
* soft nofile ${LIMIT_COUNT}
* hard nofile ${LIMIT_COUNT}
* soft nproc ${LIMIT_COUNT}
* hard nproc ${LIMIT_COUNT}
root soft nofile ${LIMIT_COUNT}
root hard nofile ${LIMIT_COUNT}
root soft nproc ${LIMIT_COUNT}
root hard nproc ${LIMIT_COUNT}
EOF
# 配置PAM,确保limits.conf生效 (幂等操作)
for pam_file in /etc/pam.d/common-session /etc/pam.d/common-session-noninteractive; do
if ! grep -q "^session required pam_limits.so" "$pam_file"; then
echo "session required pam_limits.so" >> "$pam_file"
fi
done
# 配置systemd的默认限制 (幂等操作)
if grep -q "^#\?DefaultLimitNOFILE=" /etc/systemd/system.conf; then
sed -i "s/^#\?DefaultLimitNOFILE=.*/DefaultLimitNOFILE=${LIMIT_COUNT}/" /etc/systemd/system.conf
else
echo "DefaultLimitNOFILE=${LIMIT_COUNT}" >> /etc/systemd/system.conf
fi
}
# 新增函数:加载必要的内核模块
load_kernel_modules() {
echo "-> 检查并加载必要的内核模块..."
# 加载 nf_conntrack 模块 (连接跟踪,代理服务器必需)
if ! lsmod | grep -q "^nf_conntrack"; then
echo " 正在加载 nf_conntrack 模块..."
if modprobe nf_conntrack 2>/dev/null; then
echo -e "${GREEN} ✓ nf_conntrack 模块已加载${NC}"
else
echo -e "${YELLOW} 警告: 无法加载 nf_conntrack 模块,conntrack 相关参数将被跳过${NC}"
return 0
fi
else
echo -e "${GREEN} ✓ nf_conntrack 模块已存在${NC}"
fi
# 设置开机自动加载 (幂等操作)
if [ -f /etc/modules ]; then
if ! grep -q "^nf_conntrack$" /etc/modules; then
echo "nf_conntrack" >> /etc/modules
echo " 已设置 nf_conntrack 开机自动加载"
fi
elif [ -d /etc/modules-load.d ]; then
if [ ! -f /etc/modules-load.d/nf_conntrack.conf ] || ! grep -q "^nf_conntrack$" /etc/modules-load.d/nf_conntrack.conf; then
echo "nf_conntrack" > /etc/modules-load.d/nf_conntrack.conf
echo " 已设置 nf_conntrack 开机自动加载"
fi
fi
}
configure_sysctl() {
echo "-> 配置内核参数 (BBR + 代理网络优化)"
cat > /etc/sysctl.conf <<EOF
# Auto-generated by optimization script
# --- 文件系统 ---
fs.file-max = ${LIMIT_COUNT}
# --- 网络核心优化 ---
net.core.somaxconn = 32768
net.core.netdev_max_backlog = 32768
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.default_qdisc = fq
# --- TCP BBR 拥塞控制 ---
net.ipv4.tcp_congestion_control = bbr
# --- TCP 内存与缓冲区优化 (针对小内存VPS和代理场景) ---
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
net.ipv4.tcp_adv_win_scale = -2 # 预留更多内核内存给socket,适合转发
net.ipv4.tcp_notsent_lowat = 131072 # 降低发送延迟
net.ipv4.udp_rmem_min = 8192
net.ipv4.udp_wmem_min = 8192
# --- TCP 连接行为优化 ---
net.ipv4.tcp_slow_start_after_idle = 0 # 关闭空闲后的慢启动
net.ipv4.tcp_fastopen = 3 # 开启 TFO, 减少握手延迟
net.ipv4.tcp_mtu_probing = 1 # 开启 MTU 探测
# --- TIME_WAIT 连接管理 (安全方式) ---
net.ipv4.tcp_fin_timeout = 30 # 缩短 FIN-WAIT-2 状态超时
net.ipv4.tcp_max_tw_buckets = 10000 # 增加 TIME_WAIT bucket 数量
# net.ipv4.tcp_tw_reuse = 1 # 在NAT环境下不安全,不建议开启
# --- 安全与连接队列 ---
net.ipv4.tcp_syncookies = 1 # 防御 SYN flood 攻击
net.ipv4.tcp_max_syn_backlog = 8192
net.ipv4.tcp_rfc1337 = 1
# --- 连接跟踪 (对代理/NAT重要) ---
net.netfilter.nf_conntrack_max = ${CONNTRACK_MAX}
net.netfilter.nf_conntrack_tcp_timeout_established = 7200
# --- 禁用 IPv6 ---
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1
EOF
}
apply_and_verify() {
echo "-> 应用内核参数并验证..."
# 改进的错误处理:捕获输出和退出码,但不让脚本退出
set +e # 临时关闭 errexit
local sysctl_output
sysctl_output=$(sysctl -p 2>&1)
local sysctl_exitcode=$?
set -e # 重新启用 errexit
# 如果有错误,显示但继续执行
if [ $sysctl_exitcode -ne 0 ]; then
echo -e "${YELLOW}部分参数应用时遇到问题:${NC}"
echo "$sysctl_output" | grep -E "cannot stat|No such file|error" | sed 's/^/ /' || true
echo -e "${YELLOW}这些参数将被忽略,脚本继续执行...${NC}"
fi
echo ""
echo "--- 验证结果 ---"
# 验证 BBR
local current_cc
current_cc=$(sysctl -n net.ipv4.tcp_congestion_control)
if [[ "$current_cc" == "bbr" ]]; then
local bbr_mode="内置于内核"
if lsmod | grep -q bbr; then
bbr_mode="作为内核模块加载"
fi
echo -e "${GREEN}✓ TCP 拥塞控制算法: bbr (${bbr_mode})${NC}"
else
echo -e "${RED}✗ TCP 拥塞控制算法: ${current_cc} (非 bbr)${NC}"
local available_cc
available_cc=$(cat /proc/sys/net/ipv4/tcp_available_congestion_control)
if [[ "$available_cc" =~ "bbr" ]]; then
echo -e "${YELLOW} -> 诊断: 'bbr' 可用但未生效,请检查/etc/sysctl.conf中是否有冲突配置。${NC}"
else
echo -e "${YELLOW} -> 诊断: 'bbr' 在此内核中不可用,请升级内核。${NC}"
fi
fi
# 验证队列调度
local current_qdisc
current_qdisc=$(sysctl -n net.core.default_qdisc)
if [[ "$current_qdisc" == "fq" ]]; then
echo -e "${GREEN}✓ 默认队列调度: fq${NC}"
else
echo -e "${RED}✗ 默认队列调度: ${current_qdisc} (非 fq)${NC}"
fi
# 验证 conntrack 配置
if [ -f /proc/sys/net/netfilter/nf_conntrack_max ]; then
local conntrack_max
conntrack_max=$(sysctl -n net.netfilter.nf_conntrack_max)
echo -e "${GREEN}✓ 连接跟踪表大小: ${conntrack_max}${NC}"
else
echo -e "${YELLOW}⚠ 连接跟踪模块未启用 (非关键,但建议启用)${NC}"
fi
# 验证文件句柄限制
local file_max
file_max=$(sysctl -n fs.file-max)
echo -e "${GREEN}✓ 系统最大文件句柄: ${file_max}${NC}"
}
prompt_reboot() {
echo ""
echo -e "${YELLOW}服务器将在 3 秒后重启...${NC}"
sleep 3
reboot
}
# --- 脚本启动 ---
main
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment