← 返回 TimeAmber
logo NodeSeekbeta

PortChannel Zero (Po0 腾讯云) — 从开机到配置 nftables 专线转发全流程教程(小白向)

前言:关于 Po0

Po0(PortChannel Zero)是RFC陈总推出的广州、上海腾讯云CCN服务器。可利用 腾讯云 CCN(云联网)RFCHOST T1 的内网互通,搭建 低延迟、高稳定性 的商业级专线,中转流量至 RFCHOST 落地机。
可能是目前MJJ能买得起的最强专线 xhj026


🛒 产品传送门(带AFF):

• 腾讯云广州 - Spring Special
• 腾讯云华东(上海) - Spring Special

  • 需通过腾讯云接口实名
  • 配置:独立IP 2C 2G 200M 500G单向流量,1188元/年
  • 另有众多月付套餐可供选择,,用券后最低仅79元/月起,月付优惠码:「常驻九折优惠券」

核心原理

  • 入口:腾讯云 12 线 BGP(国内互联性极佳)
  • 出口:RFCHOST HK.T1 / JP.T1
    (可通过RFC 内网可延伸至 SG T1 / US T1(画饼中))

Nftables中转方式:通过 DNAT + SNAT

  • 入站:将访问 PO0 中转端口的流量内网转发(陈总神秘黑科技)至落地机
  • 出站:强制使用腾讯云 RFCHOST 内网路由,绕开公网拥堵

预期表现

路径 延迟(参考)
广州 → RFC HK T1 ~6ms
广州 → RFC JP T1 ~50ms
上海 → RFC HK T1 ~24ms
上海 → RFC JP T1 ~30ms

SLA:腾讯云级别稳定性,理论0掉线率0丢包


准备工作

  • 已购买RFC HK或JP T1落地机(目前HK CO和JP CO也通PO0);已购买PO0上海或广州机器
  • 已完成 落地机配置
  • 已完成 落地ss协议搭建
  • 为避免触犯论坛规则,这里不对落地机配置作具体展开

第一阶段:安全加固(SSH 密钥登录 & 修改端口)

  • 默认系统:Debian 12

1. 本地生成 SSH 密钥

  • Windows (PowerShell) / Mac / Linux:
    打开终端,输入以下命令(一路回车即可):
ssh-keygen -t ed25519 -C "po0_key"

查看并复制公钥:

cat ~/.ssh/id_ed25519.pub

2. 服务器写入公钥

# 创建目录
mkdir -p ~/.ssh
chmod 700 ~/.ssh
# 写入公钥
echo "ssh-ed25519 AAAA...你的公钥内容... po0_key" >> ~/.ssh/authorized_keys
# 设置权限
chmod 600 ~/.ssh/authorized_keys

3. 修改 SSH 配置

# 编辑配置文件:
nano /etc/ssh/sshd_config
# 找到以下配置项并修改(如果找不到,可在文件末尾添加):
# 1. 修改默认端口 (防止简单扫描)
Port 12956(自行修改)
# 2. 禁止密码登录 (强制使用密钥)
PasswordAuthentication no
# 3. 允许密钥登录
PubkeyAuthentication yes

重启 SSH 服务

systemctl restart ssh

第二阶段:Debian 12 初始化

1. 更新系统

apt update && apt upgrade -y

2. 开启 IP 转发(必做)

echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
sysctl -p

3. 安装 Nftables(debian12系统内已默认安装,这步可省略)

apt install nftables -y

第三阶段:部署 Nftables 专线转发

编辑配置文件(清空原内容):

nano /etc/nftables.conf

如果仅有一台落地机需要转发:

#!/usr/sbin/nft -f
# =======================================================
# 📝 变量定义区 (务必根据实际情况修改)
# =======================================================
define DEST_IP       = 82.40.xx.xx # 1. RFCHOST 落地机公网 IP
define DEST_PORT_OUT = 33333       # 2. RFCHOST 落地机服务端口
define RELAY_PORT_IN = 10086       # 3. PO0中转端口
define RELAY_LAN_IP  = 10.100.xx.xx  # 4. PO0内网 IP
# =======================================================
# 清空旧规则
flush ruleset

# --- 核心转发逻辑 (NAT表) ---
table ip nat {
    # 1. 入站转发 (DNAT)
    # 目的: 将访问PO0 10086端口 的流量仍给落地机
    chain prerouting {
        type nat hook prerouting priority dstnat; policy accept;
        
        # 同时转发 TCP 和 UDP 
        meta l4proto { tcp, udp } th dport $RELAY_PORT_IN dnat to $DEST_IP:$DEST_PORT_OUT
    }

    # 2. 出站伪装 (SNAT) - 专线核心
    # 目的: 将源地址改为内网 IP,强制流量走腾讯云-RFCHOST的内网路由
    chain postrouting {
        type nat hook postrouting priority srcnat; policy accept;
        
        # 仅匹配发往落地机的流量,执行 SNAT
        ip daddr $DEST_IP meta l4proto { tcp, udp } th dport $DEST_PORT_OUT snat to $RELAY_LAN_IP
    }
}

# --- 性能优化逻辑 (Filter表) ---
# 目的: 防止 MTU 不匹配导致的断流
table ip filter {
    chain forward {
        type filter hook forward priority 0; policy accept;
        
        # 调整 TCP MSS,解决某些情况下速度慢/断流”的问题
        ip daddr $DEST_IP tcp flags syn tcp option maxseg size set 1452
    }
}

如果有两台落地机需要转发:

#!/usr/sbin/nft -f
# =======================================================
# 📝 变量定义区 (务必根据实际情况修改)
# =======================================================
# --- 公共配置 ---
define RELAY_LAN_IP  = 10.100.xx.xx  # PO0内网 IP

# --- 线路 1 配置 (例如RFC HK T1) ---
define PORT_IN_1     = 10086       # 中转端口 1
define DEST_IP_1     = 172.81.xx.xx  # 1号落地机 IP
define DEST_PORT_1   = 33333       # 1号落地机端口

# --- 线路 2 配置 (例如RFC JP CO) ---
define PORT_IN_2     = 20086       # 中转端口 2
define DEST_IP_2     = 82.40.xx.xx   # 2号落地机 IP 
define DEST_PORT_2   = 44444         # 2号落地机端口
# =======================================================
# 清空旧规则
flush ruleset

# --- 核心转发逻辑 (NAT表) ---
table ip nat {
    # --- 入站转发 (DNAT) ---
    chain prerouting {
        type nat hook prerouting priority dstnat; policy accept;
        
        # [线路 1] 流量进入端口1 -> 转给落地机1
        meta l4proto { tcp, udp } th dport $PORT_IN_1 dnat to $DEST_IP_1:$DEST_PORT_1
        
        # [线路 2] 流量进入端口2 -> 转给落地机2
        meta l4proto { tcp, udp } th dport $PORT_IN_2 dnat to $DEST_IP_2:$DEST_PORT_2
    }

    # --- 出站伪装 (SNAT) ---
    chain postrouting {
        type nat hook postrouting priority srcnat; policy accept;
        
        # [线路 1] 发往落地机1的流量 -> 改源IP为内网IP (走专线)
        ip daddr $DEST_IP_1 meta l4proto { tcp, udp } th dport $DEST_PORT_1 snat to $RELAY_LAN_IP
        
        # [线路 2] 发往落地机2的流量 -> 改源IP为内网IP (走专线)
        ip daddr $DEST_IP_2 meta l4proto { tcp, udp } th dport $DEST_PORT_2 snat to $RELAY_LAN_IP
    }
}

# --- 性能优化逻辑 (Filter表) ---
# 目的: 防止 MTU 不匹配导致的断流
table ip filter {
    chain forward {
        type filter hook forward priority 0; policy accept;
        
        # 调整 TCP MSS,解决某些情况下速度慢/断流”的问题
        ip daddr { $DEST_IP_1, $DEST_IP_2 } tcp flags syn tcp option maxseg size set 1452
    }
}

如果有三台及以上落地机需要转发,则自行再增加n组定义变量,复制 dnat 和 snat 的那两行规则,修改变量即可,这里不再展开阐述。 xhj009

应用并自启:

# 检查语法 (无输出则为正常)
nft -c -f /etc/nftables.conf

# 应用配置
nft -f /etc/nftables.conf

# 设置开机自启
systemctl enable nftables
systemctl restart nftables

第四阶段:验证

ss客户端配置:

  • Address:PO0 公网 IP
  • Port:PO0 中转端口
  • 其余参数:保持落地机一致

到此教程结束,在此感谢RyanZ董事长的教程参考 xhj009
下单地址

  • 用Claude写了一个脚本 可以自动化部署 大家可以参考一下

    https://www.nodeseek.com/post-615707-1

    #!/bin/bash
    # ============================================================
    # PO0 中转机 nftables 端口转发一键部署
    # IPv4 nftables 内核态转发 + 防火墙
    #
    # 适用: Ubuntu 22.04 / 24.04
    # 用法: bash setup-relay.sh
    # ============================================================
    set -e
    
    # ==================== 自动检测 ====================
    WAN_IF=$(ip -4 route show default | awk '{print $5; exit}')
    if [ -z "$WAN_IF" ]; then
      echo "❌ 无法检测默认网卡"; exit 1
    fi
    
    RELAY_LAN_IP=$(ip -4 addr show "$WAN_IF" | awk '/inet /{print $2}' | cut -d/ -f1 | head -1)
    if [ -z "$RELAY_LAN_IP" ]; then
      echo "❌ 无法获取内网 IP"; exit 1
    fi
    
    random_port() {
      echo $(( RANDOM % 50000 + 10000 ))
    }
    
    echo ""
    echo "============================================"
    echo "  PO0 中转机端口转发部署"
    echo "============================================"
    echo ""
    echo "  自动检测:"
    echo "    网卡:   $WAN_IF"
    echo "    内网IP: $RELAY_LAN_IP"
    echo ""
    
    # ==================== 用户输入 ====================
    read -rp "  落地机数量 [1]: " LINE_COUNT
    LINE_COUNT=${LINE_COUNT:-1}
    
    if ! [[ "$LINE_COUNT" =~ ^[0-9]+$ ]] || [ "$LINE_COUNT" -lt 1 ] || [ "$LINE_COUNT" -gt 20 ]; then
      echo "❌ 数量无效 (1-20)"; exit 1
    fi
    
    declare -a DEST_IPS DEST_PORTS RELAY_PORTS LINE_NAMES
    
    for i in $(seq 1 "$LINE_COUNT"); do
      echo ""
      if [ "$LINE_COUNT" -gt 1 ]; then
        echo "  --- 线路 $i ---"
        read -rp "  线路名称 (如 HK-T1, JP-CO) [线路${i}]: " name
        LINE_NAMES[$i]=${name:-"线路${i}"}
      else
        LINE_NAMES[$i]="默认线路"
      fi
    
      read -rp "  落地机 IP: " dest_ip
      if [ -z "$dest_ip" ]; then
        echo "❌ IP 不能为空"; exit 1
      fi
      DEST_IPS[$i]=$dest_ip
    
      read -rp "  落地机端口: " dest_port
      if [ -z "$dest_port" ]; then
        echo "❌ 端口不能为空"; exit 1
      fi
      DEST_PORTS[$i]=$dest_port
    
      rp=$(random_port)
      read -rp "  中转端口 [${rp}]: " relay_port
      RELAY_PORTS[$i]=${relay_port:-$rp}
    done
    
    # ==================== 确认 ====================
    echo ""
    echo "  ========== 转发规则 =========="
    for i in $(seq 1 "$LINE_COUNT"); do
      echo "  [${LINE_NAMES[$i]}] :${RELAY_PORTS[$i]} -> ${DEST_IPS[$i]}:${DEST_PORTS[$i]}"
    done
    echo "  ==============================="
    echo ""
    read -rp "  确认部署? [Y/n]: " CONFIRM
    CONFIRM=${CONFIRM:-Y}
    if [[ ! "$CONFIRM" =~ ^[Yy]$ ]]; then
      echo "已取消"; exit 0
    fi
    echo ""
    
    # --------------------------------------------------
    echo "[1/4] 内核参数"
    # --------------------------------------------------
    sudo tee /etc/sysctl.d/99-relay.conf >/dev/null <<'EOF'
    net.ipv4.ip_forward=1
    net.core.default_qdisc=fq
    net.ipv4.tcp_congestion_control=bbr
    net.netfilter.nf_conntrack_max=65536
    EOF
    sudo sysctl --system >/dev/null
    echo "  转发 + BBR + conntrack ✓"
    
    # --------------------------------------------------
    echo "[2/4] 禁用 UFW"
    # --------------------------------------------------
    if systemctl is-active --quiet ufw 2>/dev/null; then
      sudo systemctl disable --now ufw
    fi
    echo "  ✓"
    
    # --------------------------------------------------
    echo "[3/4] 生成 nftables 规则"
    # --------------------------------------------------
    
    NFT_VARS="define RELAY_LAN_IP = $RELAY_LAN_IP\n"
    for i in $(seq 1 "$LINE_COUNT"); do
      NFT_VARS+="define DEST_IP_${i}   = ${DEST_IPS[$i]}\n"
      NFT_VARS+="define DEST_PORT_${i} = ${DEST_PORTS[$i]}\n"
      NFT_VARS+="define PORT_IN_${i}   = ${RELAY_PORTS[$i]}\n"
    done
    
    if [ "$LINE_COUNT" -eq 1 ]; then
      INPUT_PORTS="\$PORT_IN_1"
    else
      INPUT_PORTS="\$PORT_IN_1"
      for i in $(seq 2 "$LINE_COUNT"); do
        INPUT_PORTS+=", \$PORT_IN_${i}"
      done
    fi
    
    NFT_DNAT=""
    for i in $(seq 1 "$LINE_COUNT"); do
      NFT_DNAT+="        # [${LINE_NAMES[$i]}]\n"
      NFT_DNAT+="        meta l4proto { tcp, udp } th dport \$PORT_IN_${i} dnat to \$DEST_IP_${i}:\$DEST_PORT_${i}\n"
    done
    
    NFT_SNAT=""
    for i in $(seq 1 "$LINE_COUNT"); do
      NFT_SNAT+="        # [${LINE_NAMES[$i]}]\n"
      NFT_SNAT+="        ip daddr \$DEST_IP_${i} meta l4proto { tcp, udp } th dport \$DEST_PORT_${i} snat to \$RELAY_LAN_IP\n"
    done
    
    NFT_FWD=""
    for i in $(seq 1 "$LINE_COUNT"); do
      NFT_FWD+="        ip daddr \$DEST_IP_${i} meta l4proto { tcp, udp } th dport \$DEST_PORT_${i} accept\n"
    done
    
    if [ "$LINE_COUNT" -eq 1 ]; then
      MSS_MATCH="ip daddr \$DEST_IP_1"
    else
      MSS_SET="\$DEST_IP_1"
      for i in $(seq 2 "$LINE_COUNT"); do
        MSS_SET+=", \$DEST_IP_${i}"
      done
      MSS_MATCH="ip daddr { ${MSS_SET} }"
    fi
    
    sudo tee /etc/nftables.conf >/dev/null <<EOF
    #!/usr/sbin/nft -f
    # ============================================================
    # PO0 中转机 nftables 规则
    # 生成时间: $(date '+%Y-%m-%d %H:%M:%S')
    # ============================================================
    flush ruleset
    
    $(echo -e "$NFT_VARS")
    # --- 防火墙 ---
    table inet filter {
        chain input {
            type filter hook input priority 0; policy drop;
            ct state { established, related } accept
            iif "lo" accept
            ip protocol icmp accept
    
            # SSH 防扫描: 新连接限速 10/分钟
            tcp dport 22 ct state new limit rate 10/minute burst 5 packets accept
            tcp dport 22 ct state established accept
    
            # 中转端口
            iifname "$WAN_IF" meta l4proto { tcp, udp } th dport { ${INPUT_PORTS} } accept
        }
    
        chain forward {
            type filter hook forward priority 0; policy drop;
            ct state { established, related } accept
    $(echo -e "$NFT_FWD")
        }
    
        chain output {
            type filter hook output priority 0; policy accept;
        }
    }
    
    # --- NAT 转发 ---
    table ip nat {
        chain prerouting {
            type nat hook prerouting priority dstnat; policy accept;
    $(echo -e "$NFT_DNAT")
        }
    
        chain postrouting {
            type nat hook postrouting priority srcnat; policy accept;
    $(echo -e "$NFT_SNAT")
        }
    }
    
    # --- MSS 优化 (防止 MTU 不匹配导致断流) ---
    table ip mangle {
        chain forward {
            type filter hook forward priority mangle; policy accept;
            ${MSS_MATCH} tcp flags syn tcp option maxseg size set 1452
        }
    }
    EOF
    
    sudo nft -c -f /etc/nftables.conf && sudo nft -f /etc/nftables.conf
    sudo systemctl enable nftables
    echo "  nftables ✓"
    
    # --------------------------------------------------
    echo "[4/4] 安装 conntrack"
    # --------------------------------------------------
    sudo apt install -y conntrack >/dev/null 2>&1
    echo "  ✓"
    
    # --------------------------------------------------
    echo ""
    echo "============================================"
    echo "  ✅ 部署完成"
    echo "============================================"
    echo ""
    for i in $(seq 1 "$LINE_COUNT"); do
      echo "  [${LINE_NAMES[$i]}] :${RELAY_PORTS[$i]} -> ${DEST_IPS[$i]}:${DEST_PORTS[$i]}"
    done
    echo ""
    echo "  防火墙: policy drop"
    echo "    开放: SSH(22, 限速防扫描) + 中转端口"
    echo "    其余入站全部丢弃"
    echo "  BBR: 已开启"
    echo "  MSS clamp: 1452"
    echo "  conntrack max: 65536"
    echo ""
    echo "  常用命令:"
    echo "    sudo nft list ruleset             # 查看规则"
    echo "    sudo nft -a list ruleset          # 带 handle 查看"
    echo "    sudo conntrack -C                 # 当前连接数"
    echo "    sudo conntrack -L -d <落地机IP>    # 查看转发连接"
    echo "============================================"
    
  • 多出口的情况下, # 调整 TCP MSS下,$DEST_IP 需要分别改成对应的 $DEST_IP_1和$DEST_IP_2

    本人小菜鸡,什么都不懂

  • 多出口的配置下最后一行有虫子,前面定义的是DEST_IP1和DEST_IP2,建议改为:

    
    ip daddr { $DEST_IP_1, $DEST_IP_2 } tcp flags syn tcp option maxseg size set 1452
    
    
  • 学习。

  • 专业!

  • 思路差不多.学习

  • ??? 我表示买不起 xhj007

    可能是目前MJJ能买得起的最强专线

  • 感觉还是realm方便,多端口nft转发修改起来麻烦

  • 先收藏慢慢看

  • 很专业,但我没有。就此为你颂诗一首

    有心无相,相由心生;有相无心,相由心灭。

  • @Kedaya #5 一股脑全丢给ai直接生成配置文件也挺方便的其实

  • 手动设置 /etc/nftables.conf 和 ufw 是冲突的吧 xhj009
    nftables.conf 里面一 flush ruleset 直接把 ufw 规则都冲掉了
    要么不用 ufw,要么得把规则写到 /etc/ufw/before.rules 里面

  • @n0p1nt3 #9 哈哈哈确实,把这忘了,我去掉

内容
预览
对照
AC娘
洋葱头
小黄鸡
Fluent
App