现在IPV4地址越来越枯竭了,普通家庭宽带想获取公网ip也越来越难了,被逼无奈,又不想花钱租公网服务器,就想用IPV6来进行远程连接。
前提条件
1、服务端有IPV6公网地址。现在家庭宽带应该都有,没有的让运营商开下应该就行。
2、光猫或路由器启用IPV6。现在新的路由器基本都支持IPV6的,但一般默认是关掉IPV6的,可以设置开启。如果是光猫接路由,然后服务端主机连路由的,光猫需要设置为桥接模式,使用路由器拨号,经过NAT转换的是不能用公网IPV6的。
3、客户端也需有IPV6地址。用手机流量是有IPV6的,如果是WiFi,那跟服务端一样,需要光猫或路由器启用IPV6。
查看IPV6地址
windows上通过ipconfig -all命令可以查看本机所有网卡的信息,包括IPV6地址。
注意公网IPV6是以240开头的,fe80开头的是内网地址。
IPV6的公网地址可能有好几个,有DHCP动态获取的,有手动配置的,有通过MAC地址计算获得的,有随机生成的临时地址。
这里可以先随便找个非临时的地址,尝试进行连接。
比如windows的远程桌面服务,是会同时监听IPV4和IPV6的3389端口的,直接用240开头的公网IPV6地址就可以连接了。
上传IPV6地址
因为路由器重新拨号或运营商强制重新拨号等原因,IPV6的地址前缀会变动,所以我们需要做一个自动检测IP变化并让客户端可以获取的功能。
这里使用腾讯云的COS来存储当前服务IP地址,对普通用户来讲是完全免费的,因为使用量是达不到收费标准的。
编写ps1脚本:
$url = "https://xxxx.cos.ap-xxxx.myqcloud.com/"
$file = "ip.txt"
$response = (Invoke-WebRequest -Uri ($url + $file))
$curip = $response.Content.Trim()
while(1)
{
$ips = Get-NetIPAddress -AddressFamily IPv6
Foreach($ip in $ips)
{
if($ip.IPAddress.StartsWith("240") -and $ip.SuffixOrigin -ceq "Link") #使用根据MAC计算出来的IPV6,相对比较固定
{
if($ip.IPAddress -cne $curip)
{
Write-Host $ip.IPAddress
$ip.IPAddress | Out-File -Encoding ascii $file
.\coscli -c .\.cos.yaml cp $file cos://mycos/
$response = Invoke-WebRequest -Uri ($url + $file)
$curip = $response.Content.Trim()
}
break
}
}
Sleep 60
}
这里就是每60秒检测一次当前的IPV6地址,如果与当前记录的IP地址不一致,就把当前IPV6地址通过coscli.exe工具上传到腾讯云COS,coscli.exe可以在上面链接的官方网站下载,coscli需要配置文件.cos.yaml,可参考官方说明。以下为.cos.yaml示例:
cos:
base:
secretid: XXXXX
secretkey: XXXXX
sessiontoken: XXXX
protocol: https
buckets:
- name: XXXXX
alias: mycos
region: ""
endpoint: cos.ap-XXXX.myqcloud.com
ofs: false
下载IPV6地址
因为IP会变,每次重新输入那一长串IP地址也不舒服,所以可以将ip地址转为固定的域名。
当然了,我们的口号是免费,申请域名或者动态域名之类的事是不会去做的。当然也不全是因为免费的事,我的概念是尽量少依赖第三方,那些都是不稳定的因素。
电脑上可以从腾讯云COS中下载最新IP地址并写入hosts文件。如果是手机就没办法了,毕竟手机上没root过的是没有写hosts文件的权限的。
如果只是用手机端的远程桌面,可以在ip变化后用浏览器打开cos地址获取最新ip,再复制粘贴到手机远程桌面app就行了,也不算很麻烦,毕竟ip变化也不是很频繁。
如果是自己开发的客户端,比如游戏客户端,可以直接在客户端代码里从cos获取服务器ip地址。
以下是windows中自动获取ip地址并写入hosts的ps1脚本:
$hostname = "myhost"
$response = Invoke-WebRequest -uri https://xxxx.cos.ap-xxxx.myqcloud.com/ip.txt
$ip = $response.Content.Trim()
if(!$ip.StartsWith("240")) {
echo $ip
exit
}
$newline = "$ip $hostname"
$content = ""
$hasold = 0
foreach($line in Get-Content C:\Windows\System32\drivers\etc\hosts) {
if($line -match $hostname){
$content = $content+$newline+"`n"
$hasold = 1
}else{
$content = $content+$line+"`n"
}
}
if ($hasold -eq 0){
$content = $content + $newline
}else{
$content = $content.Substring(0, $content.Length - 1)
}
$content | Out-File -Encoding ascii C:\Windows\System32\drivers\etc\hosts
echo 已将$newline"写入hosts文件"
cmd /c pause
这里给服务器起了别名myhost,也就是直接使用myhost作为地址就可以访问服务器了。
服务代理
windows的远程桌面服务、linux的ssh服务等都是默认同时监听IPV4和IPV6的,都没问题。但是很多服务是只支持IPV4的,这里就需要进行端口转发,将IPV6端口收到的消息转发给IPV4端口。
1、nginx可以实现端口转发功能,以下是nginx的配置示例:
stream{
upstream ssh{
server 192.168.1.7:22; #监听IPV6的22端口转发到局域网192.168.1.7上的ssh服务
}
server {
listen [::]:22;
proxy_pass ssh;
}
upstream web{
server 127.0.0.1:80; #监听IPV6的81端口转发到本机IPV4的80端口
}
server {
listen [::]:81;
proxy_pass web;
}
}
2、windows上还有个自带的端口转发服务更简单,使用管理员运行powershell:
#添加端口转发
netsh interface portproxy add v6tov4 listenaddress=* listenport=81 connectaddress=127.0.0.1 connectport=80 protocol=tcp
#删除端口转发
netsh interface portproxy delete v6tov4 listenport=22
#查看所有端口转发
netsh interface portproxy show all
这里添加端口转发后重启后也是会自动生效的。
大功告成!