原文:https://post.smzdm.com/p/akk0k4g4/2022-11-08 459点赞 5199收藏 209评论
一、折腾由来
上半年,有一朋友拿个赚钱宝要我帮他刷系统,我刷了个OPENWRT,但没过几天就死机了,怎么也进不去,后又帮他刷了个armbian,但也没过几天死机了,后来来回回折腾几次还是没几天就死机进不了系统,最后判断闪存坏了,不能正常使用。如果故事就这样,可能就结束了。
但是在折腾这段时间他拿到联通的公网IP,也觉得NAS很方便。国庆后就买了个N5105的小电脑,装了个win2019(因为win有桌面对普通人比较友好),我给他装了个可道云、PHP目录列表、µTorrent、jellyfin。
但是好景不长,11月2号他的公网IP被联通回收了。打电话到客服、投诉…… 能想的手段都用上了,最后得到一个答复:“你换电信宽带吧,电信有公网IP"。
折腾从这开始了……
导航页
二、VPN访问(已弃用)
我首先想到的办法是在我家搞个VPN服务器,朋友的服务器用VPN拨号进入我家内网,我再把他的WEB服务代理出来。
这个方法开机好像不能自动连接VPN,这就导致每次开机还要手动连接VPN,而且朋友也觉得走我家宽带会影响我家的网速。最后放弃了这个方法。
三、cloudflare(有改进)
朋友先想到的方法有frp,还有花生棒。我觉得吧用这些还不如用我家VPN,免费还稳定。
最后我看到一篇文章:https://post.smzdm.com/p/awxlgpvk/,最后就整了这个方案
1、查看宽带是否支持IPV6
查看是否支持IPV6:https://ipw.cn/ipv6/这个网址可以查看你电脑有支持IPV6(现在的移动联通电信的宽带都支持IPV6,其它家就不太清楚了)。如果不支持IPV6,首先看你路由器是否支持IPV6,路由器是否开启了IPV6。
没有开启IPV6
路由器没有开启IPV6
开启IPV6,我的小米路由器截图
开启IPV6,朋友TP路由器截图
IPV6一般有两种模式:一种Native(TP里面叫和宽带拨号上网),这种适合光猫做桥接用路由器拨号的情况。别一种叫NAT6(TP里面叫桥接模式),这种适合用光猫拨号路由器做二级路由的情况。
开通IPV6
2、关路由器防火墙
ping不通自己的IPV6地址,有防火墙
可以ping通的情况
在https://ipw.cn/ipv6ping/这里ping一下自己的IPV6地址如果显示 PingFailed。就是路由器开通的IPV6防火墙(也有可能是电脑系统禁止了ping,系统默认是不会开启,所以不考虑这种情况)。但是有些路由器是不提供IPV6防火墙开关的,比如我的小米路由器(有部分小米路由器支持关闭IPV6防火墙)、我朋友的TP路由器(也有部分支持)。
我朋友的路由器也不支持关闭IPV6防火墙,我建设他用光猫拨号再把TP路由器改成桥接模式,最后他修改光猫没有成功。由于当时是晚上,我想就要他明天打电话到联通客服。
没想到他后面发邮件给TP客服说明IPV6防火墙的问题,第二天客服不但回了邮件还附带发给他一个不带IPV6防火墙的路由器固件,还说这是官方的下个版本固件,到此防火墙的事情解决了。
3、购买域名
在腾迅云,购买一个CN域名。(因为以前用的是TP路由器,用的是TP的二级域名。用我家VPN时用的是我的二级域名)。购买CN域名要实名认证并上传身份证图片。
注册的域名
4、把域名的DNS服务器改成cloudflare的DNS
今天不知道为什么cloudflare一样不能登录,所以在网络上找了两张图。
查看cloudflare的DNS服务器
在腾讯云修改DNS服务器为cloudflare的
5、在cloudflare增加@和*两个AAAA解析
选择AAAA类型,代理状态为代理
因为今天不能登录cloudflare借用其它用户图片。增加两个AAAA解析记录,一个@,一个*,都解析到自己服务器的IPV6地址。@解析的是 XXXX.cn,前面有没有xx.的。*是解析所有子域名,比如www.XXXX.cn、xxx.XXXX.cn。
6.写脚本自动更新域名的IP
根据cloudflare的API文档编写PHP脚本。
<?PHP
//define('URI','https://api.cloudflare.com/client/v4/zones/');
//define('ZONEID','22222222333333'); //Zone ID
//define('DNSRECORDS','dns_records');
define('URI','https://api.cloudflare.com/client/v4/zones/22222222333333/dns_records');
/////22222222333333 改为成自己的Zone ID
$fl_key='XXXXX2222222XXXXXXX22222'; //API Tokens,改成自己的API Tokens
function crul_url($url,$accessToken =false,$data=[],$quest='GET'){
$data = json_encode($data);
$ch = curl_init(); //初始化CURL句柄
$headers[]="Accept:application/json";
if($accessToken){
$headers[] = "Authorization: Bearer ". $accessToken;
}
curl_setopt($ch, CURLOPT_URL, $url); //设置请求的URL
curl_setopt ($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1); //设为TRUE把curl_exec()结果转化为字串,而不是直接输出
curl_setopt($ch, CURLOPT_CUSTOMREQUEST,$quest); //设置请求方式
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);//设置提交的字符串
$output = curl_exec($ch);
curl_close($ch);
return $output;
}
function updaterecord($fl_key,$fl_dome_id,$ip,$type=false,$name=false,$ttl=false){
$updatedata['content']=$ip;
if($name) $updatedata['name']=$name;
if($type) $updatedata['type']=$type;
if($ttl) $updatedata['$ttl']=$ttl;
$url=URI.'/'.$fl_dome_id;
$str=crul_url($url,$fl_key,$updatedata,'PATCH');
$return=json_decode($str,true);
if($return && $return['success']){
return true;
}else{
return false;
}
}
function getipv4(){
$str=crul_url('http://ipv4.lookup.test-ipv6.com/ip/?asn=1&testdomain=test-ipv6.com&testname=test_asn4');
$arr=json_decode($str,true);
return $arr['ip'];
}
function getipv6(){
$str=crul_url('http://ipv6.lookup.test-ipv6.com/ip/?asn=1&testdomain=test-ipv6.com&testname=test_asn6');
$arr=json_decode($str,true);
return $arr['ip'];
}
function echoerr($str=''){
echo($str);
exit();
}
$ipv4=false;
$ipv6=getipv6();
if(!$ipv6) echoerr('错误:获取不到IPV6地址。');
$strs=crul_url(URI,$fl_key);
$records=json_decode($strs,true);
if(!$records || !$records['success']){
echoerr('错误:获取不到域名解析记录。');
}
foreach ($records['result'] as $result){
if($result['type']=='AAAA'){ //只更新IPV6域名
$type='AAAA';
$ip=$ipv6;
if($ip==$result['content']){
echo('不用更新此域名'.$result['name']."rn");
}elseif(updaterecord($fl_key,$result['id'],$ip,$type)){
echo('更新'.$result['name'].'成功'."rn");
};
}
}
?>
Zone ID
申请API Tokens
申请API Tokens
7、到此外网的IPV4和IPV6都可访问服务器的WEB服务。
可道云、PHP目录列表、µTorrent、jellyfin这几个服务都用ngix反向代理到子目录。cloudflare支持端口 HTTP:80,8080,8880,2052,2082,2086,2095,HTTPS:443,2053,2083,2087,2096,8443,因为国内环境80和443端口都被封,所以无法启用HTTPS(如果有哪位大神HTTPS启用成功了,我向他请教一下)。其实应该就是反向代理服务。
可正常访问网站,
其它服务全反向代理到子目录
五、IPV6优化:设置IPV6客户端不经过cloudflare代理
这个设置很简单,在导航页判断客户端是否支持IPV6,如果支持就跳转到不经过代理的域名。
添加一个v6的AAAA记录,把代理状态关闭
现设置一个v6.xxxx.cn为IPV6的专用域名,再在导航页最前面加入下列代码。
<!!!script!!!>
function _jqjsp(data) {
var v6url='http://v6.xxxx.cn:8880'; //修改为自己的IPV6专用域名地址
if(data && data.type && data.type=='ipv6' && window.location.href.substr(0,v6url.length)!=v6url){
window.location.href=v6url;
}
}
<!!!/script!!!>
<!!!script src="http://ipv6.lookup.test-ipv6.com/ip/?callback=_jqjsp&asn=1&testdomain=test-ipv6.com&testname=test_asn6"!!!><!!!/script!!!>
上面的代码要把三个一起的感叹号(!!!)全删除,下面载张图。
修改后的导航页源码
这样只要支持IPV6的客户访问就会跳到v6.xxxx.cn:8880。
六、IPV4优化:把域名DNS转入到腾讯云,域名解析到cloudflare的IP
https://zhuanlan.zhihu.com/p/570911722 cloudflare自选指定IP节点教程 找出cloudflare延时最低的IPV4节点。把域名的A记录解析到这个IP,可以分别找出电信联通移动 ping值最低掉包最少的节点,记住IP。比如电信最稳定IP为:172.67.209.188,联通最稳定IP为:162.159.160.222
把域名DNS转入腾讯云,但是cloudflare里面的解析和修改不用更改。
把域名DNS转回腾讯云
把域名@和*的A记录解析到前面获取的cloudflareIP上
可以分别设置电信联通移动解析的IP,这样就可优化不同营运商访问到最佳的cloudflare节点。
在这要注意把cloudflare上的v6.xxxx.cn的AAAA解析记录删除,还要把导航页在第五段的跳转脚本删除。
七:IPV6优化2:把域名的AAAA记录解析到服务器的IPV6地址
把@和*的AAAA记录全解析到服务器的IPV6地址
把@和*的AAAA记录全解析到服务器的IPV6地址
写脚本自动更新所有域名的AAAA记录。
代码不知道为什么发到文章就不能保存,先截张图。
自动更新解析代码
ID和Token获取方法见官方文档:https://docs.dnspod.cn/account/dnspod-token/
<?
define('URI','https://dnsapi.cn/');
$satcdata=[
'login_token'=>'ID,Token', //比如 ID 为:13490,ToKen为:6b5976c68aba5b14a0558b77c17c3932。即完整的 Token 为:13490,6b5976c68aba5b14a0558b77c17c3932 。
'format'=>'json',
'lang'=>'cn',
'error_on_empty'=>'no',
'domain'=>'XXXX.cn'
];
function recordlist($data){
$url=URI.'Record.List';
$return=json_decode(curl_dnspod($url,$data),true);
return $return;
}
function recordModify($data){
$url=URI.'Record.Modify';
$return=json_decode(curl_dnspod($url,$data),true);
return $return;
}
function curl_dnspod($url,$data=[]){
$ch = curl_init ();
curl_setopt ( $ch, CURLOPT_URL, $url );
curl_setopt ( $ch, CURLOPT_POST, 1 );
curl_setopt ( $ch, CURLOPT_HEADER, 0 );
curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, 1 );
curl_setopt ( $ch, CURLOPT_POSTFIELDS, $data );
$return = curl_exec ( $ch );
curl_close ( $ch );
return $return;
}
function recordlupdate($data,$ip){
$data['record_type']='AAAA'; //只查询AAAA记录的IPV6解析
$recordlist=recordlist($data);
if($recordlist && $recordlist['status'] && $recordlist['status']['code']=="1" && $recordlist['records']){
foreach ($recordlist['records'] as $record){
if($ip==$record['value']){
echo('不用更新此域名'.$record['name'].'.'.$data['domain']."rn");
}else{
$redata=$data;
$redata['record_id']=$record['id'];
$redata['sub_domain']=$record['name'];
$redata['record_line_id']=$record['line_id'];
$redata['value'] = $ip;
$retrun=recordModify($redata);
if($recordlist && $recordlist['status'] && $recordlist['status']['code']=="1"){
echo('更新域名成功:'.$record['name'].'.'.$data['domain']."rn");
}else{
echo('更新域名失败:'.$retrun['status']['message'].':'.$record['name'].'.'.$data['domain']."rn");
}
}
}
}elseif($recordlist && $recordlist['status']){
echo('查询域名失败:'.$retrun['status']['message'].':'.$data['domain']."rn");
}
}
function getipv6(){
$str=curl_dnspod('http://ipv6.lookup.test-ipv6.com/ip/?asn=1&testdomain=test-ipv6.com&testname=test_asn6');
$str=trim($str);
$arr=json_decode($str,true);
if($arr['ip']){
return $arr['ip'];
}else{
return false;
}
}
$ipv6=getipv6();
if($ipv6){
recordlupdate($satcdata,$ip);
}else{
echo("没有获取到IPV6地址。rn");
}
代码终于发出来了。
现在可以实现IPV6直接访问服务器,IPV4用cloudflare反向代理访问,还可根据营运商访问不同的cloudflare节点,实现快速稳定访问服务器。
作者声明本文无利益相关,欢迎值友理性交流,和谐讨论~