igozhang

——

    网络聚合命令

    网络配置命令(IP/网关/DNS/NTP/聚合)

    逻辑:备份 → 写配置文件 → NTP → 重启网络生效 → 输出。不读旧配置内容。
    网口IFACE='*' 自动探测(优先 bond/team > eth > ens/enp,排除 docker/k8s 等);已有 IP 优先,无 IP 时选 UP 物理口
    Ubuntu netplan:备份后重写原 yaml(含该网口的文件,否则取第一个),删除其余 yaml 避免冲突。
    CentOS/Rocky:写最小 ifcfg(仅 IP/网关/DNS)→ 配 NTP → 生效。CentOS 7 优先 nmcli device reapply 读 ifcfg;无 NM 时用 restart network;兜底用 ip 命令。
    DNS:默认留空,空时自动使用 GW 作为 DNS。
    说明:以下四条命令均 ≤2000 字符,可直接复制;IP/GW 各一行,其余参数共一行。

    1. Ubuntu/Debian 单网口(netplan)

    sudo ip link set ens18 up && sudo ip addr add 10.129.240.33/24 dev ens18 && sudo ip route replace default via 10.129.240.254 dev ens18
    
    sudo bash <<'EOF'
    IP='10.10.10.10'
    GW='10.10.10.254'
    DNS='';NTP='';MASK='24';IF='*'
    [ -z "$DNS" ]&&DNS=$GW
    P(){ r=$(ip -br -4 a|awk '$1!~"^(lo|docker|veth|kube|cni|br-|flannel)"&&$2=="UP"&&$3~/\//{print($1~/^bond/?100:$1~/^eth/?90:$1~/^(ens|enp)/?80:10),$1}'|sort -rn|head -1|awk '{print $2}');[ -n "$r" ]&&echo "$r"||ip -br link|awk '$1!~"^(lo|docker|veth|kube|cni|br-|bond|team|flannel)"&&$2=="UP"{print($1~/^eth/?90:$1~/^(ens|enp)/?80:10),$1}'|sort -rn|head -1|awk '{print $2}'; }
    [ "$IF"="*" ]&&IF=$(P);[ -n "$IF" ]||{ echo FAIL:iface;exit 1; }
    echo "CFG: $IF $IP/$MASK gw=$GW dns=$DNS${NTP:+ ntp=$NTP}"
    D=/root/nb-$(date +%Y%m%d%H%M%S);mkdir -p $D;cp -a /etc/netplan $D/ 2>/dev/null&&echo OK:backup:$D||echo FAIL:backup
    shopt -s nullglob;Y=(/etc/netplan/*.yaml);T=$(printf '%s\n' "${Y[@]}"|sort|head -1)
    for f in "${Y[@]}";do grep -q " $IF:" "$f"&&T=$f;done;[ -z "$T" ]&&T=/etc/netplan/01-netcfg.yaml
    R=$(grep -h renderer: $D/netplan/*.yaml 2>/dev/null|awk '{print $2}'|head -1);R=${R:-networkd}
    for f in /etc/netplan/*.yaml;do [ "$f"!="$T" ]&&rm -f "$f";done;shopt -u nullglob
    cat>$T<<E
    network:
      version: 2
      renderer: $R
      ethernets:
        $IF:
          dhcp4: no
          addresses: [$IP/$MASK]
          routes: [{to: default, via: $GW}]
          nameservers: {addresses: [$DNS]}
    E
    echo OK:file:$T
    [ -n "$NTP" ]&&{ grep -q '^\[Time\]' /etc/systemd/timesyncd.conf||echo '[Time]'>>/etc/systemd/timesyncd.conf; sed -i "s/^NTP=.*/NTP=$NTP/" /etc/systemd/timesyncd.conf 2>/dev/null||sed -i "/^\[Time\]/a NTP=$NTP" /etc/systemd/timesyncd.conf; systemctl restart systemd-timesyncd 2>/dev/null; systemctl is-active systemd-timesyncd&>/dev/null&&echo OK:ntp||echo FAIL:ntp; }||echo SKIP:ntp
    netplan apply&&echo OK:apply||{ echo FAIL:apply;exit 1; }
    a=$(ip -4 -o a show dev $IF|awk '{print $4}'|head -1);g=$(ip route show default|awk '{print $3}'|head -1)
    [ "$a"="$IP/$MASK" ]&&echo OK:ip||echo FAIL:ip:$a;[ "$g"="$GW" ]&&echo OK:gw||echo FAIL:gw:$g
    EOF
    

    2. CentOS/Rocky 单网口(ifcfg)

    sudo nmcli con mod eth0 ipv4.addresses 10.129.240.33/24 ipv4.gateway 10.129.240.254 ipv4.method manual && sudo nmcli con up eth0
    
    sudo bash <<'EOF'
    IP='10.10.10.10'
    GW='10.10.10.254'
    DNS='';NTP='';MASK='24';IF='*'
    [ -z "$DNS" ]&&DNS=$GW
    P(){ r=$(ip -br -4 a|awk '$1!~"^(lo|docker|veth|kube|cni|br-|flannel)"&&$2=="UP"&&$3~/\//{print($1~/^bond/?100:$1~/^team/?100:$1~/^eth/?90:$1~/^(ens|enp)/?80:10),$1}'|sort -rn|head -1|awk '{print $2}');[ -n "$r" ]&&echo "$r"||ip -br link|awk '$1!~"^(lo|docker|veth|kube|cni|br-|bond|team|flannel)"&&$2=="UP"{print($1~/^eth/?90:$1~/^(ens|enp)/?80:10),$1}'|sort -rn|head -1|awk '{print $2}'; }
    [ "$IF"="*" ]&&IF=$(P);[ -n "$IF" ]||{ echo FAIL:iface;exit 1; }
    echo "CFG: $IF $IP/$MASK gw=$GW dns=$DNS${NTP:+ ntp=$NTP}"
    D=/root/nb-$(date +%Y%m%d%H%M%S);mkdir -p $D /etc/sysconfig/network-scripts;cp -a /etc/sysconfig/network-scripts/ifcfg-* $D/ 2>/dev/null;echo OK:backup:$D
    cat>/etc/sysconfig/network-scripts/ifcfg-$IF<<C
    DEVICE=$IF
    ONBOOT=yes
    BOOTPROTO=none
    IPADDR=$IP
    PREFIX=$MASK
    GATEWAY=$GW
    DNS1=$DNS
    C
    echo OK:file:ifcfg-$IF
    [ -n "$NTP" ]&&{ mkdir -p /etc/chrony.d;echo "server $NTP iburst">/etc/chrony.d/99-custom.conf;systemctl restart chronyd 2>/dev/null; pgrep chronyd&>/dev/null&&echo OK:ntp||echo FAIL:ntp; }||echo SKIP:ntp
    if nmcli dev status&>/dev/null;then nmcli con reload 2>/dev/null;(nmcli con up $IF||nmcli con up "System $IF")&>/dev/null;else systemctl restart network&>/dev/null;fi
    a=$(ip -4 -o a show dev $IF|awk '{print $4}'|head -1);g=$(ip route show default|awk '{print $3}'|head -1)
    [ "$a"="$IP/$MASK" ]&&echo OK:apply||echo FAIL:apply;[ "$a"="$IP/$MASK" ]&&echo OK:ip||echo FAIL:ip:$a;[ "$g"="$GW" ]&&echo OK:gw||echo FAIL:gw:$g
    EOF
    

    3. Ubuntu/Debian 双网口聚合 bond0(netplan)

    sudo bash <<'EOF'
    IP='10.10.10.10'
    GW='10.10.10.254'
    DNS='';NTP='';MASK='24';S1='*';S2='*';BO=bond0
    [ -z "$DNS" ]&&DNS=$GW
    L(){ { ip -br -4 a|awk '$1!~"^(lo|docker|veth|kube|cni|br-|bond|team|flannel)"&&$2=="UP"&&$3~/\//{print($1~/^eth/?90:$1~/^(ens|enp)/?80:50)+50,$1}'; ip -br link|awk '$1!~"^(lo|docker|veth|kube|cni|br-|bond|team|flannel)"&&$2=="UP"{print($1~/^eth/?90:$1~/^(ens|enp)/?80:50),$1}'; }|awk '!s[$2]||$1+0>s[$2]{s[$2]=$1+0} END{for(i in s)print s[i],i}'|sort -rn|awk '{print $2}'; }
    if [ "$S1"="*" ];then
     [ -r /sys/class/net/$BO/bonding/slaves ]&&read S1 S2 _ </sys/class/net/$BO/bonding/slaves
     [ -z "$S1" ]&&{ A=($(L));S1=${A[0]};S2=${A[1]}; }
     [ -n "$S1" ]&&[ -n "$S2" ]||{ echo FAIL:iface;exit 1; }
    fi
    echo "CFG: $BO($S1+$S2) $IP/$MASK gw=$GW dns=$DNS${NTP:+ ntp=$NTP}"
    D=/root/nb-$(date +%Y%m%d%H%M%S);mkdir -p $D;cp -a /etc/netplan $D/ 2>/dev/null&&echo OK:backup:$D||echo FAIL:backup
    shopt -s nullglob;Y=(/etc/netplan/*.yaml);T=$(printf '%s\n' "${Y[@]}"|sort|head -1)
    for f in "${Y[@]}";do grep -qE "bonds:| $BO:" "$f"&&T=$f;done
    R=$(grep -h renderer: $D/netplan/*.yaml 2>/dev/null|awk '{print $2}'|head -1);R=${R:-networkd}
    for f in /etc/netplan/*.yaml;do [ "$f"!="$T" ]&&rm -f "$f";done;shopt -u nullglob
    cat>$T<<E
    network:
      version: 2
      renderer: $R
      ethernets:
        $S1: {dhcp4: no}
        $S2: {dhcp4: no}
      bonds:
        $BO:
          dhcp4: no
          interfaces: [$S1, $S2]
          parameters: {mode: active-backup}
          addresses: [$IP/$MASK]
          routes: [{to: default, via: $GW}]
          nameservers: {addresses: [$DNS]}
    E
    echo OK:file:$T
    [ -n "$NTP" ]&&{ grep -q '^\[Time\]' /etc/systemd/timesyncd.conf||echo '[Time]'>>/etc/systemd/timesyncd.conf; sed -i "s/^NTP=.*/NTP=$NTP/" /etc/systemd/timesyncd.conf 2>/dev/null||sed -i "/^\[Time\]/a NTP=$NTP" /etc/systemd/timesyncd.conf; systemctl restart systemd-timesyncd 2>/dev/null; systemctl is-active systemd-timesyncd&>/dev/null&&echo OK:ntp||echo FAIL:ntp; }||echo SKIP:ntp
    netplan apply&&echo OK:apply||{ echo FAIL:apply;exit 1; }
    a=$(ip -4 -o a show dev $BO|awk '{print $4}'|head -1);g=$(ip route show default|awk '{print $3}'|head -1)
    [ "$a"="$IP/$MASK" ]&&echo OK:ip||echo FAIL:ip:$a;[ "$g"="$GW" ]&&echo OK:gw||echo FAIL:gw:$g
    EOF
    

    4. CentOS/Rocky 双网口聚合 team0(ifcfg)

    前置:yum install -y teamd NetworkManager-team

    sudo bash <<'EOF'
    IP='10.10.10.10'
    GW='10.10.10.254'
    DNS='';NTP='';MASK='24';S1='*';S2='*';TM=team0
    [ -z "$DNS" ]&&DNS=$GW
    L(){ { ip -br -4 a|awk '$1!~"^(lo|docker|veth|kube|cni|br-|bond|team|flannel)"&&$2=="UP"&&$3~/\//{print($1~/^eth/?90:$1~/^(ens|enp)/?80:50)+50,$1}'; ip -br link|awk '$1!~"^(lo|docker|veth|kube|cni|br-|bond|team|flannel)"&&$2=="UP"{print($1~/^eth/?90:$1~/^(ens|enp)/?80:50),$1}'; }|awk '!s[$2]||$1+0>s[$2]{s[$2]=$1+0} END{for(i in s)print s[i],i}'|sort -rn|awk '{print $2}'; }
    if [ "$S1"="*" ];then
     [ -d /sys/class/net/$TM ]&&{ A=($(ls /sys/class/net/$TM/lower_* 2>/dev/null|xargs -n1 basename|sed 's/^lower_//')); S1=${A[0]};S2=${A[1]}; }
     [ -z "$S1" ]&&{ A=($(L));S1=${A[0]};S2=${A[1]}; }
     [ -n "$S1" ]&&[ -n "$S2" ]||{ echo FAIL:iface;exit 1; }
    fi
    echo "CFG: $TM($S1+$S2) $IP/$MASK gw=$GW dns=$DNS${NTP:+ ntp=$NTP}"
    D=/root/nb-$(date +%Y%m%d%H%M%S);mkdir -p $D;cp -a /etc/sysconfig/network-scripts/ifcfg-* $D/ 2>/dev/null&&echo OK:backup:$D||echo FAIL:backup
    cat>/etc/sysconfig/network-scripts/ifcfg-$TM<<C
    DEVICE=$TM
    DEVICETYPE=Team
    TEAM_CONFIG={"runner": {"name": "activebackup"}}
    BOOTPROTO=none
    ONBOOT=yes
    IPADDR=$IP
    PREFIX=$MASK
    GATEWAY=$GW
    DNS1=$DNS
    C
    for S in $S1 $S2;do cat>/etc/sysconfig/network-scripts/ifcfg-$S<<C
    DEVICE=$S
    DEVICETYPE=TeamPort
    TEAM_MASTER=$TM
    BOOTPROTO=none
    ONBOOT=yes
    C
    done
    echo OK:file:ifcfg-$TM,$S1,$S2
    [ -n "$NTP" ]&&{ mkdir -p /etc/chrony.d;echo "server $NTP iburst">/etc/chrony.d/99-custom.conf;systemctl restart chronyd 2>/dev/null; pgrep chronyd&>/dev/null&&echo OK:ntp||echo FAIL:ntp; }||echo SKIP:ntp
    if nmcli dev status&>/dev/null;then nmcli con reload 2>/dev/null;nmcli con up $TM 2>/dev/null||nmcli dev reapply $TM 2>/dev/null;else systemctl restart network 2>/dev/null;fi
    a=$(ip -4 -o a show dev $TM|awk '{print $4}'|head -1);g=$(ip route show default|awk '{print $3}'|head -1)
    [ "$a"!="$IP/$MASK" ]&&{ ip link set $TM up;ip addr flush dev $TM 2>/dev/null;ip addr add $IP/$MASK dev $TM;ip route replace default via $GW dev $TM;a=$IP/$MASK;g=$GW; }
    [ "$a"="$IP/$MASK" ]&&echo OK:apply||echo FAIL:apply;[ "$a"="$IP/$MASK" ]&&echo OK:ip||echo FAIL:ip:$a;[ "$g"="$GW" ]&&echo OK:gw||echo FAIL:gw:$g
    EOF
    

    主机与网络信息查看命令

    一键输出主机 OS、物理机/虚拟机、网卡类型,以及业务网卡的 IP、掩码、网关、DNS、NTP、MAC 等网络配置,用于现场排查或填写网络工单。自动识别业务网卡(优先 bond > eth > ens/enp),排除 Docker、K8s、Flannel 等内部网卡;

    sudo -E timeout 10 bash <<'EOF'
    IFACE='*'
    _o(){ . /etc/os-release 2>/dev/null&&echo "${PRETTY_NAME:-$NAME}"||uname -sr;}
    _h(){ v=$(systemd-detect-virt 2>/dev/null|head -1|tr -d ' \t\r\n');[ "$v" = none -o -z "$v" ]&&echo physical||echo "VM($v)";}
    _n(){ [ -r /sys/class/net/$1/bonding/slaves ]&&{ echo bond;return;}
      d=$(sudo ethtool -i $1 2>/dev/null|awk '/driver:/{print $2;exit}')
      case $d in virtio*|vmxnet3|veth|tap|tun) echo "virtual($d)";;""|unknown) echo unknown;;*) echo "physical($d)";; esac;}
    _p(){ ip -br -4 a 2>/dev/null|awk '$1!~"^(lo|docker|cni|flannel|nodelocaldns|veth|kube|calico|tun|tap|virbr|br-|podman)"&&$2=="UP"&&$3~/\//{
      ip=$3;sub(/\/.*/,"",ip);if(ip~/^10\.|^192\.168\.|^172\.(1[6-9]|2[0-9]|3[0-1])\./)print ($1~/^bond/?100:$1~/^eth/?90:$1~/^(ens|enp)/?80:10),$1,$3}'|sort -rn|head -1|awk '{print $2,$3}';}
    _d(){ if=$1;n=;command -v nmcli&>/dev/null&&n=$(nmcli -t -f IP4.DNS dev show "$if" 2>/dev/null|awk -F: '$2~/^[0-9]/{print $2}')
      [ -z "$n" ]&&[ -f /etc/sysconfig/network-scripts/ifcfg-$if ]&&n=$(grep -E '^DNS[0-9]+=' /etc/sysconfig/network-scripts/ifcfg-$if|cut -d= -f2)
      [ -z "$n" ]&&command -v resolvectl&>/dev/null&&n=$(resolvectl dns "$if" 2>/dev/null|grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}')
      [ -z "$n" ]&&n=$(awk '/^nameserver /{print $2}' /etc/resolv.conf 2>/dev/null|grep -Ev '^127\.');echo "$n"|sort -u|paste -sd ', ' -;}
    _t(){ s=$(grep -Erh '^(server|pool) ' /etc/chrony.conf /etc/chrony/chrony.conf /etc/chrony.d/ /etc/ntp.conf 2>/dev/null|
      grep -v '^#'|awk '{print $2}'|grep -E '^[0-9a-zA-Z]'|sort -u|paste -sd ', ' -)
      [ -z "$s" ]&&[ -f /etc/systemd/timesyncd.conf ]&&s=$(awk -F= '/^(NTP|FallbackNTP)=/{gsub(/ /,"",$2);if($2)print $2}' /etc/systemd/timesyncd.conf|
      tr ' ' '\n'|grep -E '^[0-9a-zA-Z]'|paste -sd ', ' -);echo "${s:-—}";}
    
    if [ "$IFACE" = '*' ];then read IF CIDR _ < <(_p);else
      CIDR=$(ip -br -4 a show dev "$IFACE" 2>/dev/null|awk '$2=="UP"{print $3;exit}');IF=$IFACE;fi
    [ -n "${IF:-}" -a -n "${CIDR:-}" ]||{ echo;echo "[ERROR] no business NIC found";exit 1;}
    ADDR=${CIDR%%/*};PFX=${CIDR#*/}
    MASK=$(awk -v p=$PFX 'BEGIN{for(i=0;i<4;i++){n=p-i*8;if(n>=8)m[i]=255;else if(n<=0)m[i]=0;else m[i]=256-2^(8-n)}printf "%d.%d.%d.%d",m[0],m[1],m[2],m[3]}')
    GW=$(ip -4 route show default dev "$IF" 2>/dev/null|awk '{print $3;exit}');GW=${GW:-$(ip -4 route show default 2>/dev/null|awk '{print $3;exit}')};GW=${GW:-—}
    MAC=$(cat /sys/class/net/$IF/address 2>/dev/null||echo —);DNS=$(_d "$IF");NTP=$(_t);[ -z "$DNS" ]&&DNS=—
    
    echo
    echo "=== Host ==="
    echo "OS:       $(_o)"
    echo "Type:     $(_h)"
    echo "Hostname: $(hostname -f 2>/dev/null||hostname)"
    echo
    echo "=== Business NIC ($IF) ==="
    echo "NIC:      $(_n "$IF")"
    echo "MAC:      $MAC"
    echo "IPv4:     $ADDR"
    echo "Netmask:  $MASK (/$PFX)"
    echo "Gateway:  $GW"
    echo "DNS:      $DNS"
    echo "NTP:      $NTP"
    EOF
    

    ping 网段可用 IP 探测命令

    在内网服务器上快速探测本机所在私网 /24 网段中哪些 IP 可能可用,用于申请或分配 IP 前的初步筛选。

    • 自动识别业务网卡(优先 bond > eth > ens/enp),排除 Docker、K8s、Flannel 等内部网卡
    • 仅探测与本机同 /24 网段(.1–.254),避免跨网段误扫
    • 有 ping 响应 → 已占用;无响应 → 可能可用(目标可能禁 ping,需二次确认)
    • 输出 OS、物理机/虚拟机、网卡类型;连续 IP 合并显示(如 10.129.243.31-40
    • 整段上限 10s,25 路并行,单包等待 1s;非 root 可用 sudo 执行

    判读: In Use 已占用 | Possibly Free 可能可用(需二次确认)

    sudo -E bash <<'EOF'
    T=10; W=1; P=${PRL:-25}
    _os(){ . /etc/os-release 2>/dev/null; echo "${PRETTY_NAME:-$(uname -s)} | $(uname -r)"; }
    _hv(){ v=$(systemd-detect-virt 2>/dev/null|head -1|tr -d ' \t\r\n');[ "$v" = none -o -z "$v" ]&&echo physical||echo "VM($v)"; }
    _nc(){ d=$(sudo ethtool -i "$1" 2>/dev/null|awk '/^driver:/{print $2;exit}');
      [ -r "/sys/class/net/$1/bonding/slaves" ]&&echo "$1|bond"||echo "$1|${d:-unknown}"; }
    _pk(){ ip -br -4 a 2>/dev/null|awk '
      $1!~"^(lo|docker|cni|flannel|veth|kube|calico|tun|tap|virbr|br-|podman)"&&$2=="UP"&&$3~/\/24$/{
        sub(/\/.*/,"",$3); if($3~/^10\.|^192\.168\.|^172\.(1[6-9]|2[0-9]|3[0-1])\./)
          print ($1~/^bond/?100:$1~/^eth/?90:$1~/^(ens|enp)/?80:10),$1,$3
      }'|sort -rn|head -1|awk '{print $2,$3}'; }
    _rg(){ awk -F. 'function r(a,b,p,q){split(a,p,".");split(b,q,".");if(p[3]==q[3])return a"-"q[4];return a"-"b}
      {n++;o[n]=$4+0;i[n]=$0} END{if(!n){print"(none)";exit}s=1;for(j=2;j<=n;j++)if(o[j]!=o[j-1]+1){
      if(s==j-1)print i[s];else print r(i[s],i[j-1]);s=j} if(s==n)print i[s];else print r(i[s],i[n])}'; }
    read IF IP _ <<<"$(_pk)"; [ -n "$IF" ]||{ echo "[ERR] no private /24 iface"; exit 1; }
    IFS=. read -r a b c _ <<<"$IP"; S="$a.$b.$c"; f=$(mktemp); trap 'rm -f "$f"' EXIT
    echo "=== Host Info ==="
    echo "OS: $(_os)"
    echo "Type: $(_hv)"
    echo "NIC: $(_nc "$IF") ($IP/24)"
    echo
    echo "=== Ping Scan (${T}s, ${P} parallel, ${W}s/pkt) ==="
    timeout "$T" bash -c 'seq 1 254|xargs -P '"$P"' -I{} sh -c '\''
      ip="'"$S"'.$1"; ping -c1 -W'"$W"' -q "$ip" >/dev/null 2>&1 && echo u "$ip" || echo f "$ip"'\'' _ {}' >"$f" || true
    sort -t. -k4 -n "$f" -o "$f"
    u=$(grep -c '^u ' "$f" 2>/dev/null||echo 0); v=$(grep -c '^f ' "$f" 2>/dev/null||echo 0)
    echo
    echo "=== In Use ($u) ==="
    grep '^u ' "$f" 2>/dev/null|awk '{print $2}'|_rg||echo "(none)"
    echo
    echo "=== Possibly Free ($v) ==="
    grep '^f ' "$f" 2>/dev/null|awk '{print $2}'|_rg||echo "(none)"
    echo
    echo "=== Summary ==="
    echo "In use: $u | Possibly free: $v | Scanned: $((u+v))/254"
    [ "$((u+v))" -lt 254 ]&&echo "Note: ${T}s timeout; partial scan"
    EOF
    

    系统内核优化(CentOS 7 / Ubuntu 20 通用)

    逻辑:备份 → 写 sysctl / limits / systemd 配置 → 立即生效 → 校验输出。
    范围:仅通用项(句柄数、进程数、TCP 连接/端口/超时/保活、连接队列、基础内核参数)。
    不含:BBR、网卡中断绑核、透明大页、swap 等场景化或争议项。
    说明:复制整段执行;新 SSH 会话ulimit -n 才反映 limits 变更;已运行服务需重启后生效。

    sudo bash <<'EOF'
    set -e
    
    # ========== 可调参数(按需修改) ==========
    NOFILE=1048576          # 单进程最大打开文件数(句柄)| 默认1024 | 调大 | 每连接占1句柄,防too many open files
    NPROC=65535             # 单用户最大进程数 | 默认4096~16384 | 调大 | 多进程/线程服务防上限
    FILE_MAX=2097152        # 系统级文件句柄上限 | 默认约10万级 | 调大 | 系统总句柄池,支撑高并发
    SOMAXCONN=65535         # accept队列长度 | 默认128~4096 | 调大 | 握手完成待accept,防连接被拒
    PORT_MIN=1024           # 本地端口范围下限 | 默认32768 | 调小 | 扩大可用临时端口下限
    PORT_MAX=65535          # 本地端口范围上限 | 默认60999 | 调大 | 出站短连接多,防端口耗尽
    TCP_FIN_TIMEOUT=30      # FIN_WAIT2超时(秒)| 默认60 | 调小 | 异常关闭时更快释放FIN_WAIT2
    TCP_KEEPALIVE_TIME=600  # 无数据时首次发keepalive(秒)| 默认7200 | 调小 | 空闲连接更早探测,穿透NAT/LB
    TCP_KEEPALIVE_INTVL=30  # keepalive探测间隔(秒)| 默认75 | 调小 | 缩短探测间隔,加快发现死连接
    TCP_KEEPALIVE_PROBES=3  # 判定断开前探测次数 | 默认9 | 调小 | 减少无效探测,更快判定断开
    
    # ========== 0. 环境检查 ==========
    [ "$(id -u)" -eq 0 ] || { echo FAIL:root; exit 1; }
    if [ -f /etc/os-release ]; then
      . /etc/os-release
      OS_ID=${ID:-unknown}
      OS_VER=${VERSION_ID:-}
    else
      OS_ID=unknown; OS_VER=
    fi
    case "$OS_ID" in
      centos|rhel|rocky|almalinux) OS_FAMILY=rhel ;;
      ubuntu|debian)               OS_FAMILY=debian ;;
      *)                           OS_FAMILY=other ;;
    esac
    echo "=== OS: ${PRETTY_NAME:-$OS_ID $OS_VER} (family=$OS_FAMILY) ==="
    
    TS=$(date +%Y%m%d%H%M%S)
    BK=/root/ko-bak-$TS
    mkdir -p "$BK"
    cp -a /etc/sysctl.conf "$BK/" 2>/dev/null || true
    cp -a /etc/sysctl.d "$BK/" 2>/dev/null || true
    cp -a /etc/security/limits.conf "$BK/" 2>/dev/null || true
    cp -a /etc/security/limits.d "$BK/" 2>/dev/null || true
    cp -a /etc/systemd/system.conf "$BK/" 2>/dev/null || true
    cp -a /etc/systemd/system.conf.d "$BK/" 2>/dev/null || true
    echo OK:backup:$BK
    
    # ========== 1. sysctl 内核网络/句柄参数 ==========
    SYSCTL_F=/etc/sysctl.d/99-common-kernel-tuning.conf
    cat >"$SYSCTL_F" <<S
    # common kernel tuning - generated $(date '+%F %T')
    # fs / process
    fs.file-max = $FILE_MAX
    fs.nr_open = $FILE_MAX
    kernel.pid_max = 4194304
    
    # connection queue
    net.core.somaxconn = $SOMAXCONN
    net.core.netdev_max_backlog = $SOMAXCONN
    net.ipv4.tcp_max_syn_backlog = $SOMAXCONN
    
    # tcp port / orphan / recycle
    net.ipv4.ip_local_port_range = $PORT_MIN $PORT_MAX
    net.ipv4.tcp_max_orphans = 262144
    net.ipv4.tcp_tw_reuse = 1
    net.ipv4.tcp_fin_timeout = $TCP_FIN_TIMEOUT
    net.ipv4.tcp_slow_start_after_idle = 0
    
    # tcp keepalive
    net.ipv4.tcp_keepalive_time = $TCP_KEEPALIVE_TIME
    net.ipv4.tcp_keepalive_intvl = $TCP_KEEPALIVE_INTVL
    net.ipv4.tcp_keepalive_probes = $TCP_KEEPALIVE_PROBES
    
    # tcp retry / syncookie
    net.ipv4.tcp_syn_retries = 2
    net.ipv4.tcp_synack_retries = 2
    net.ipv4.tcp_retries2 = 5
    net.ipv4.tcp_syncookies = 1
    
    # socket buffer (conservative universal)
    net.core.rmem_max = 16777216
    net.core.wmem_max = 16777216
    net.ipv4.tcp_rmem = 4096 87380 16777216
    net.ipv4.tcp_wmem = 4096 65536 16777216
    S
    echo OK:file:$SYSCTL_F
    
    if sysctl --system &>/dev/null; then
      sysctl --system &>/dev/null && echo OK:sysctl-apply || { echo FAIL:sysctl-apply; exit 1; }
    else
      sysctl -p "$SYSCTL_F" &>/dev/null && echo OK:sysctl-apply || { echo FAIL:sysctl-apply; exit 1; }
    fi
    
    # ========== 2. limits 句柄 / 进程数 ==========
    LIMITS_F=/etc/security/limits.d/99-common-nofile.conf
    cat >"$LIMITS_F" <<L
    # common limits - generated $(date '+%F %T')
    * soft nofile $NOFILE
    * hard nofile $NOFILE
    * soft nproc  $NPROC
    * hard nproc  $NPROC
    root soft nofile $NOFILE
    root hard nofile $NOFILE
    root soft nproc  $NPROC
    root hard nproc  $NPROC
    L
    echo OK:file:$LIMITS_F
    
    # ========== 3. systemd 默认 limits(两发行版均适用) ==========
    mkdir -p /etc/systemd/system.conf.d
    SD_F=/etc/systemd/system.conf.d/99-common-limits.conf
    cat >"$SD_F" <<D
    [Manager]
    DefaultLimitNOFILE=$NOFILE
    DefaultLimitNPROC=$NPROC
    D
    echo OK:file:$SD_F
    if command -v systemctl &>/dev/null; then
      systemctl daemon-reexec 2>/dev/null && echo OK:systemd-reexec || echo WARN:systemd-reexec
    fi
    
    # ========== 4. 校验输出 ==========
    echo
    echo "=== Verify (runtime) ==="
    printf "fs.file-max          = %s (expect %s)\n" "$(sysctl -n fs.file-max 2>/dev/null)" "$FILE_MAX"
    printf "net.core.somaxconn   = %s (expect %s)\n" "$(sysctl -n net.core.somaxconn 2>/dev/null)" "$SOMAXCONN"
    printf "tcp_fin_timeout      = %s (expect %s)\n" "$(sysctl -n net.ipv4.tcp_fin_timeout 2>/dev/null)" "$TCP_FIN_TIMEOUT"
    printf "tcp_keepalive_time   = %s (expect %s)\n" "$(sysctl -n net.ipv4.tcp_keepalive_time 2>/dev/null)" "$TCP_KEEPALIVE_TIME"
    printf "ip_local_port_range  = %s (expect %s %s)\n" "$(sysctl -n net.ipv4.ip_local_port_range 2>/dev/null)" "$PORT_MIN" "$PORT_MAX"
    echo
    echo "=== Note ==="
    echo "limits 对新登录会话生效;已运行进程/服务需重启后应用新 nofile。"
    echo "回滚: 恢复 $BK 下文件后执行 sysctl --system"
    EOF
    

    五、出站 TCP 探测(15 站点)

    待测客户端或服务端执行,探测常用 yum/apt/k8s/docker/GitHub/Helm 等站点 80/443 TCP 是否可达(非 HTTP 内容检测)。每端口超时 3s,并行执行,整段上限 12s;无需 root。

    判读: OK 已连通 | refused 主动拒绝 | reset 连接被 RST | unreach 无路由 | timeout 超过 3s 无响应(多为防火墙 DROP)

    timeout 12 bash <<'EOF'
    cfn(){ e="$1"; c="$2"
      [ "$c" -eq 0 ] && echo OK && return
      [ "$c" -eq 124 ] && echo timeout && return
      e=$(printf '%s' "$e" | tr '\n' ' ' | sed 's/  */ /g;s/^bash: //g')
      echo "$e" | grep -qi refused  && echo refused  && return
      echo "$e" | grep -qi reset    && echo reset    && return
      echo "$e" | grep -qi unreachable && echo unreach && return
      echo "$e" | grep -qi 'no route' && echo unreach && return
      echo "$e" | grep -qi timeout  && echo timeout  && return
      printf 'err(%.28s)' "$e"
    }
    p(){ l="$1"; h="$2"; o=""
      for pt in 80 443; do
        e=$(timeout 3 bash -c "echo >/dev/tcp/${h}/${pt}" 2>&1); c=$?
        o="${o} ${pt}:$(cfn "$e" "$c")"
      done
      printf "%-14s %-28s%s\n" "$l" "$h" "$o"
    }
    echo "=== Egress TCP probe (80+443/host, 3s/port, parallel) ==="
    echo "Legend: OK=connected | refused=reject | reset=RST | unreach=no route | timeout=>3s no reply"
    echo ""
    while IFS='|' read -r l h; do p "$l" "$h" & done <<'T'
    Aliyun|mirrors.aliyun.com
    Tsinghua|mirrors.tuna.tsinghua.edu.cn
    Tencent-yum|mirrors.cloud.tencent.com
    Ubuntu-apt|archive.ubuntu.com
    Ubuntu-sec|security.ubuntu.com
    GitHub|github.com
    Google|www.google.com
    DockerHub|registry-1.docker.io
    Docker-pkg|download.docker.com
    K8s|pkgs.k8s.io
    Helm|get.helm.sh
    Quay|quay.io
    Debian|deb.debian.org
    GCS|storage.googleapis.com
    MS-pkg|packages.microsoft.com
    T
    wait
    echo ""
    echo "=== Done ==="
    EOF
    

    MP3