Skip to content
hev edited this page Apr 13, 2024 · 3 revisions

使用NATMap在NAT-1私网IP宽带上部署SSH服务

通过NATMap在运营商的NAT-1上打洞,分配私网IPv4的宽带可以部署SSH服务,并能像具有公网IP一样在其它外部主机上访问。

拓扑结构

                   SSHD                NATMap(on gateway)                SSHC

Internal:    (192.168.0.2:22) <-----> (100.65.11.55:2200)
                                               ^
                                               |
                                               v
External:                              (112.24.0.23:6348) <------------>
  • SSHD: SSH服务端运行在内网主机,侦听在192.168.0.2:22端口。
  • NATMap: NATMap运行在网关,侦听在100.65.11.55:2200端口,打洞使公网地址112.24.0.23:6348映射至100.65.11.55:2200,同时又将100.65.11.55:2200映射至192.168.0.2:22。从外部访问112.24.0.23:6348等同于访问192.168.0.2:22。
  • SSHC: SSH客户端运行在外部主机上,通过NATMap打洞获得的公网地址112.24.0.23:6348访问SSH服务。

域名访问

在具有动态公网IPv4的宽带上部署SSH服务,只有公网IPv4因为重新拨号是在动态变化的,而端口则是固定的。利用动态DNS则可以通过固定的域名作为入口实时解析到动态变化的IP,进而访问到服务。

在NAT-1私网IPv4的宽带上,情况稍微有些不同,不仅打洞后获得的运营商侧公网IPv4是动态变化的,端口同样也是动态变化的。为了同样能够使用固定的域名入口访问服务,推荐一种称为IP4P的方法,该方法利用DNS的AAAA类型记录,将公网IPv4地址和端口同时记录在域名解析记录中。SSH客户端识别到IP4P类型的域名解析结果后,则能获得实时的公网IPv4地址和端口。IP4P的方法需要客户端支持,这可以通过SSH的ProxyCommand实现。

安装部署

SSHD

安装官方的OpenSSH即可,没有额外的要求。

NATMap

安装

DDNS
Cloudflare

创建文件/usr/bin/ddns写入如下内容,并补充必要的变量值:

#!/bin/sh

ZONE=''
RECORD=''
EMAIL=''
AUTH=''
DOMAIN=''

IP4P=${3}

while true; do
    curl -X PUT "https://api.cloudflare.com/client/v4/zones/${ZONE}/dns_records/${RECORD}" \
        -H "X-Auth-Email: ${EMAIL}" \
        -H "Authorization: Bearer ${AUTH}" \
        -H "Content-Type:application/json" \
        --data "{\"type\":\"AAAA\",\"name\":\"${DOMAIN}\",\"content\":\"${IP4P}\",\"ttl\":60,\"proxied\":false}" > /dev/null 2> /dev/null
    if [ $? -eq 0 ]; then
        break
    fi
done

再增加可执行权限:

chmod +x /usr/bin/ddns
OpenWrt 22.03 or later

从软件仓库安装natmap和luci-app-natmap软件包。

或命令行

opkg install natmap luci-app-natmap
其它系统

从项目发布页下载匹配的版本: https://github.com/heiher/natmap/releases

运行

OpenWrt 22.03 or later
1. 登录OpenWrt管理页面,进入「服务」->「NATMap」页面:

2. 点击「Add」按钮,输入如下配置:
  • Protocol: TCP
  • Interface: wan
  • STUN server: turn.cloudflare.com
  • HTTP server: qq.com
  • Bind port: 2200
  • Forward mode: ☑
  • Forward target: 192.168.0.2
  • Forward target port: 22
  • Notify script: /usr/bin/ddns

3. 保存后NATMap会显示出打洞后的外部公网IPv4地址和端口记录:

4. 防火墙放行TCP协议目的端口2200的入站:

其它系统

将如下内容写入 /etc/rc.local 开机自动启动,或创建其它服务管理配置:

natmap -d -i pppoe-wan -s turn.cloudflare.com -h qq.com -b 2200 -t 192.168.0.2 -p 22 -e /usr/bin/ddns

防火墙放行TCP协议目的端口2200的入站。

访问测试

域名解析结果

比如域名为: ssh.hev.cc

nslookup ssh.hev.cc

当配置正确且运行正常时,应当能够解析类似如下结果:

Server:		192.168.0.1
Address:	192.168.0.1#53

Non-authoritative answer:
Name:	ssh.hev.cc
Address: 2001::18cc:7018:0017

SSH客户端访问

ProxyCommand

nssh实现了IP4P的逆转换,依赖dig和nc,配合ssh的ProxyCommand建立连接。创建文件/path/to/nssh写入如下内容:

#!/bin/sh

host=$1
raw=$(dig +short -t aaaa $host)
port=$((0x$(echo ${raw} | awk -F: '{ print $3 }')))
ipab=$((0x$(echo ${raw} | awk -F: '{ print $4 }')))
ipcd=$((0x$(echo ${raw} | awk -F: '{ print $5 }')))
ipa=$((${ipab} >> 8))
ipb=$((${ipab} & 0xff))
ipc=$((${ipcd} >> 8))
ipd=$((${ipcd} & 0xff))

exec nc -w1 ${ipa}.${ipb}.${ipc}.${ipd} ${port}

增加可执行权限:

chmod +x /path/to/nssh

再向~/.ssh/config中增加ssh配置:

Host ssh.hev.cc
    ProxyCommand /path/to/nssh %h
windows上的使用方法

下载并安装nmap: https://nmap.org/download.html#windows

创建powershell文件C:\Users\yourname\proxy.ps1,并写入以下内容:

param(
    [string]$sshhost
)

# 使用 Resolve-DnsName 获取 IPv6 地址
$raw = (Resolve-DnsName -Name $sshhost -Type AAAA).IPAddress

# 将 IPv6 地址的端口和地址部分提取出来
$port = [int]('0x'+($raw -split ':')[2])
$ipab = [int]('0x'+($raw -split ':')[3])
$ipcd = [int]('0x'+($raw -split ':')[4])

# 计算 IP 地址的各个部分
$ipa = $ipab -shr 8
$ipb = $ipab -band 0xFF
$ipc = $ipcd -shr 8
$ipd = $ipcd -band 0xFF

# 使用 ncat 进行连接
ncat "$ipa.$ipb.$ipc.$ipd" $port

再向~/.ssh/config中增加ssh配置:

Host ssh.hev.cc
    ProxyCommand powershell C:\Users\yourname\proxy.ps1 %h

使用域名访问

ssh ssh.hev.cc
sftp ssh.hev.cc
scp ssh.hev.cc:file .