首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 更多程式設計知識

Linux 端口轉發神器 rinetd:安裝配置、系統服務化、iptables 替代方案完整指南

     編輯:更多程式設計知識

Linux 端口轉發 (Port Forwarding/Mapping) 常見於內網服務暴露、多服務共用公網 IP、開發測試環境代理等場景。rinetd 是一款極輕量 (約 50KB)、單執行緒、基於 TCP 的端口轉發工具,配置極簡單、效能極高、支援存取控制與日誌。本文涵蓋原始碼編譯安裝、配置詳解、systemd 服務化、iptables 原生替代方案、Docker 容器化部署與效能調優。

為什麼選 rinetd?

工具類型優點缺點適用場景
rinetd用戶態 TCP 轉發極輕量、配置簡單、單執行緒無鎖競爭、支援 ACL/日誌僅 TCP、無 UDP、無加密、單執行緒高併發有上限簡單 TCP 端口映射、開發測試、輕量代理
iptables DNAT/SNAT核心態 Netfilter效能最高、支援 TCP/UDP、無用戶態切換、系統內建配置複雜、需 root、規則持久化麻煩、除錯困難生產環境高效能轉發、防火牆整合
socat多功能網路工具支援 TCP/UDP/Unix Socket/SSL/Proxy、極靈活語法複雜、資源佔用較大複雜協定轉換、SSL 終結、Socket 代理
nginx stream反向代理 (Layer 4)支援負載均衡、健康檢查、SSL、多核心配置相對複雜、記憶體佔用較大生產級 TCP/UDP 負載均衡、SSL 卸載
ssh -L/-R/-DSSH 隧道加密、認證、無需額外部署、臨時性強單連接、效能較低、不適合長期服務開發臨時隧道、跳板機存取內網

rinetd 安裝與部署

1. 套件管理器安裝 (推薦)

# CentOS/RHEL (EPEL)
yum -y install epel-release
yum -y install rinetd

# Debian/Ubuntu
apt -y update && apt -y install rinetd

# Fedora
dnf -y install rinetd

2. 原始碼編譯安裝 (原文方式、無套件時)

# 安裝編譯工具鏈
yum -y install gcc make glibc-devel

# 下載編譯
wget https://www.boutell.com/rinetd/http/rinetd.tar.gz
tar zxvf rinetd.tar.gz
cd rinetd
make
# 編譯產出 rinetd 二進位檔
cp rinetd /usr/local/sbin/
mkdir -p /etc/rinetd

配置檔詳解 (/etc/rinetd.conf)

# 格式: bindaddress bindport connectaddress connectport
# 0.0.0.0 表示監聽所有介面

# 範例: 將本機 8080 轉發到內網 Web 伺服器 80
0.0.0.0 8080 192.168.1.100 80

# 範例: 多對多映射 (原文範例)
1.1.1.1 11 2.2.2.1 3389   # 公網 IP:11 → 內網 RDP
1.1.1.1 12 2.2.2.2 3389   # 公網 IP:12 → 另一台 RDP
1.1.1.1 13 2.2.2.3 22     # 公網 IP:13 → SSH
1.1.1.1 14 2.2.2.4 80     # 公網 IP:14 → HTTP

# 存取控制 (allow/deny 順序生效,預設允許所有)
allow 192.168.1.0/24      # 僅允許內網存取
# allow *.*.*.*            # 允許所有 (預設)

# 日誌設定
logfile /var/log/rinetd.log
# logcommon                # 通用日誌格式 (可選)

systemd 服務化 (生產環境標準)

# /etc/systemd/system/rinetd.service
[Unit]
Description=rinetd TCP Port Redirector
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
ExecStart=/usr/local/sbin/rinetd -c /etc/rinetd.conf -f
# -f: 前景執行 (systemd 需要)
# -c: 指定配置檔
Restart=on-failure
RestartSec=5
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=rinetd

# 安全強化
User=nobody
Group=nobody
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ReadWritePaths=/var/log/rinetd.log

[Install]
WantedBy=multi-user.target
# 啟用服務
systemctl daemon-reload
systemctl enable --now rinetd
systemctl status rinetd
journalctl -u rinetd -f  # 查看日誌

啟動/停止/狀態檢查 (傳統方式)

# 啟動
rinetd -c /etc/rinetd.conf

# 停止
pkill rinetd
# 或
killall rinetd

# 檢查監聽端口
netstat -antup | grep rinetd
ss -antlp | grep rinetd

# 查看日誌
tail -f /var/log/rinetd.log

開機自啟 (傳統 rc.local 方式)

echo "rinetd -c /etc/rinetd.conf" >> /etc/rc.local
chmod +x /etc/rc.local
# 注意: 現代 systemd 系統建議用上述服務單元

iptables 原生替代方案 (高效能、無額外進程)

# 變數定義
WAN_IP="202.106.0.20"      # 公網 IP
LAN_WEB="192.168.1.88"     # 內網 Web 伺服器

# 1. DNAT: 入站流量 公網:2533 → 內網:80
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 2533 -j DNAT --to-destination $LAN_WEB:80

# 2. SNAT: 回程流量 內網:80 → 公網:2533 (確保回應封包源 IP 正確)
iptables -t nat -A POSTROUTING -o eth0 -s $LAN_WEB -p tcp --sport 80 -j SNAT --to-source $WAN_IP:2533

# 3. 若轉發目標非本機,需開啟核心轉發
echo 1 > /proc/sys/net/ipv4/ip_forward
# 永久生效: echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf && sysctl -p

# 4. 允許 FORWARD 鏈通過 (若預設 DROP)
iptables -A FORWARD -i eth0 -o eth1 -p tcp --dport 80 -d $LAN_WEB -j ACCEPT
iptables -A FORWARD -i eth1 -o eth0 -p tcp --sport 80 -s $LAN_WEB -j ACCEPT

# 5. 持久化 (CentOS/RHEL)
service iptables save
# 或 Debian/Ubuntu
iptables-save > /etc/iptables/rules.v4

iptables 關鍵點解析:

  • PREROUTING DNAT:在路由決策前修改目標 IP:Port,將流量導向內網。
  • POSTROUTING SNAT:在封包送出介面前修改來源 IP:Port,確保內網伺服器回應能正確路由回客戶端 (否則客戶端收到來源 IP 是內網 IP 會丟棄)。
  • ip_forward=1:核心層面啟用 IP 轉發功能,否則封包不會在介面間轉發。
  • FORWARD 鏈:控制是否允許封包通過本機轉發。

Docker 容器化部署 (現代化、可移植)

# Dockerfile
FROM alpine:3.18
RUN apk add --no-cache rinetd
COPY rinetd.conf /etc/rinetd.conf
EXPOSE 11 12 13 14
ENTRYPOINT ["rinetd", "-c", "/etc/rinetd.conf", "-f"]

# 建構映像
docker build -t my-rinetd .

# 執行 (宿主機網路模式效能最佳)
docker run -d --name rinetd \
  --network host \
  --restart unless-stopped \
  -v /etc/rinetd.conf:/etc/rinetd.conf:ro \
  my-rinetd

效能調優與限制

參數預設/限制調優建議
單執行緒單核心處理所有連線單實例 ~10k-20k 並發連線;高併發啟動多實例綁定不同 CPU (taskset) 或改用 iptables/nginx
TCP 緩衝區系統預設大流量調大 /proc/sys/net/core/rmem_max wmem_max
檔案描述符ulimit -n 1024ulimit -n 65535 或 systemd LimitNOFILE=65535
日誌 I/O同步寫入高流量關閉日誌或用 logcommon 簡潔格式,改用 syslog 非同步
UDP 支援不支援需 UDP 用 socat/iptables/nginx stream

常見問題排查

  • 連線被拒絕:檢查 allow/deny 規則順序、防火牆 (iptables/firewalld) 是否放行監聽端口、目標服務是否啟動。
  • 轉發後客戶端 IP 丟失:rinetd 為全代理,目標端看到來源 IP 是 rinetd 所在主機 IP。需應用層支援 Proxy Protocol 或用 iptables DNAT 保持原始來源 IP。
  • 高併發下延遲飆升:單執行緒瓶頸。啟用多實例 + CPU 親和性,或遷移至 iptables/nginx stream。
  • 配置修改不生效:rinetd 需重啟載入新配置 (systemctl restart rinetd 或 pkill -HUP rinetd 不支援熱載入)。

最佳實務總結

  1. 簡單 TCP 映射、開發測試、低併發:rinetd (配置最簡單、資源最輕)。
  2. 生產環境高併發、需 UDP、需保持客戶端真實 IP:iptables DNAT/SNAT (核心態、效能最強)。
  3. 需負載均衡、健康檢查、SSL 終結、多協定:nginx stream 或 HAProxy。
  4. 臨時開發隧道:ssh -L/-R (加密、免部署)。
  5. 容器化微服務:Docker 封裝 rinetd 或直接用 Kubernetes Service/Ingress (Layer 4/7)。

理解各種端口轉發工具的定位與權衡,能讓你在從「開發機快速映射」到「生產集群流量治理」的完整光譜中,精準選擇最適合的方案,避免過度工程或效能瓶頸。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved