-
Notifications
You must be signed in to change notification settings - Fork 106
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实现。
安装官方的OpenSSH即可,没有额外的要求。
创建文件/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
从软件仓库安装natmap和luci-app-natmap软件包。
或命令行
opkg install natmap luci-app-natmap
从项目发布页下载匹配的版本: https://github.com/heiher/natmap/releases
- 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
将如下内容写入 /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
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
下载并安装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 .