#!/bin/bash # ============================================================ # 摄像头 RTSP 端口转发 (板子本地端口 -> 摄像头 RTSP) # 供花生壳等内网穿透映射外网访问 # 用法: bash scripts/rtsp_forward.sh start|stop|status # ============================================================ set -u # 映射表: "本地端口:摄像头IP" 手机APP用 rtsp://<外网域名>:<本地端口>/Streaming/Channels/101 MAP=( "8551:192.168.1.121" "8552:192.168.1.122" "8553:192.168.1.123" "8554:192.168.1.124" "8555:192.168.1.125" "8556:192.168.1.126" ) CAM_PORT=554 start() { sysctl -w net.ipv4.ip_forward=1 >/dev/null 2>&1 for entry in "${MAP[@]}"; do lport="${entry%%:*}" cip="${entry##*:}" # 外部进入的流量 iptables -t nat -C PREROUTING -p tcp --dport "$lport" \ -j DNAT --to-destination "$cip:$CAM_PORT" 2>/dev/null || \ iptables -t nat -A PREROUTING -p tcp --dport "$lport" \ -j DNAT --to-destination "$cip:$CAM_PORT" # 本机自身访问 iptables -t nat -C OUTPUT -p tcp --dport "$lport" \ -j DNAT --to-destination "$cip:$CAM_PORT" 2>/dev/null || \ iptables -t nat -A OUTPUT -p tcp --dport "$lport" \ -j DNAT --to-destination "$cip:$CAM_PORT" # 回程伪装 iptables -t nat -C POSTROUTING -p tcp -d "$cip" --dport "$CAM_PORT" \ -j MASQUERADE 2>/dev/null || \ iptables -t nat -A POSTROUTING -p tcp -d "$cip" --dport "$CAM_PORT" \ -j MASQUERADE echo "[Forward] $lport -> $cip:$CAM_PORT" done echo "[Forward] 已启动 (6路 RTSP 转发)" echo "[Forward] 手机APP拉流: rtsp://<花生壳域名>:<外网端口>/Streaming/Channels/101" echo "[Forward] 注意: 必须用 TCP 模式 (rtsp_transport=tcp), 否则RTP动态端口无法穿透" } stop() { for entry in "${MAP[@]}"; do lport="${entry%%:*}" cip="${entry##*:}" iptables -t nat -D PREROUTING -p tcp --dport "$lport" \ -j DNAT --to-destination "$cip:$CAM_PORT" 2>/dev/null iptables -t nat -D OUTPUT -p tcp --dport "$lport" \ -j DNAT --to-destination "$cip:$CAM_PORT" 2>/dev/null iptables -t nat -D POSTROUTING -p tcp -d "$cip" --dport "$CAM_PORT" \ -j MASQUERADE 2>/dev/null echo "[Forward] 移除 $lport" done echo "[Forward] 已停止" } status() { echo "=== 端口转发规则 ===" iptables -t nat -L PREROUTING -n --line-numbers 2>/dev/null | grep -E "dpt:(855[0-9])" || echo "(无)" echo "=== 转发连通性 (用本机实际IP, 回环不走NAT) ===" local myip myip=$(ip -4 addr show eth0 2>/dev/null | grep -oP 'inet \K[\d.]+' | head -1) myip="${myip:-127.0.0.1}" for entry in "${MAP[@]}"; do lport="${entry%%:*}" cip="${entry##*:}" # RTSP端口连通即认为正常(用timeout连socket) if timeout 2 bash -c "exec 3<>/dev/tcp/$myip/$lport" 2>/dev/null; then echo " $myip:$lport -> $cip:$CAM_PORT OK" else echo " $myip:$lport -> $cip:$CAM_PORT 失败" fi done } case "${1:-}" in start) start ;; stop) stop ;; status) status ;; *) echo "用法: $0 start|stop|status"; exit 1 ;; esac