ipv6

前言

最近发现家里的宽带有公网ipv6地址,虽然没有ipv4地址那么方便,但是有总比没有强。有了公网ip就可以在家里搭建许多服务,比如可以给NAS配置公网ip实现远程访问,可以在电脑搭建一个web服务分享给朋友使用等等。家庭宽带的ipv6地址是动态的,配置一个动态域名解析服务就可以很方便的使用。各DNS服务商都提供了域名解析的相关api和文档,实现起来也很简单。下面记录一下折腾的具体步骤。

准备

ipv6环境准备

现在一般的宽带都会分配ipv6地址,但由于光猫或者路由器的配置导致获取不到ipv6地址。我们可以首先在test-ipv6上测试一下当前网络的地址。

image-20220611204059161

就算测试没有通过也不代表没有ipv6地址,有可能是光猫的设置或者路由器的设置问题。

配置

光猫配置

关于光猫在路由模式下有关ipv6的相关配置可以自行百度。在这里强烈建议将光猫改为桥接模式,大多数光猫的处理器性能比较一般,把路由任务交给路由器网络访问速度也会有所提升。

桥接模式下光猫只负责光电信号转换,拨号、路由等功能由路由器负责。

注意:部分光猫配置可能需要登录超级管理员账号进行修改,可自行百度。光猫配置时最好提前备份配置,或者在修改前先记录修改前的具体配置,否则修改错误无法还原可能会导致网络连接发生错误。

路由器配置

家里的路由器是水星的D191G,不同品牌的路由器后台系统可能有所不同,但配置基本类似。

检查路由器ipv6功能

大多数新款路由器都有ipv6功能,在路由器的功能菜单中查看路由器ipv6连接情况。

image-20220611210214716

我这里是采用光猫桥接,路由器拨号的方式连接网络,ipv6会复用ipv4连接获取网络。

若之前未获取到ipv6地址,路由器ipv6连接完成后可以再次在test-ipv6上测试一下当前网络ipv6的连接情况。

若仍获取失败,检查路由器与光猫的具体配置,大概率是配置问题。

配置内网虚拟服务器

路由和光猫都有防火墙,所以当获取到ipv6地址也无法通过ip访问服务,因此需要为路由器配置虚拟服务器。(若光猫为路由模式,也需要在光猫中做相应配置)。

image-20220611211515079

在路由器的虚拟服务器功能中定义局域网内服务ip以及内部外部端口。外部端口是从公网访问的端口,内部端口是路由器转发到本地服务器的端口。需要注意的是,家庭宽带的80端口一般都是被运营商封锁的,所以外部端口尽量定义一些较大的临时端口号防止与主机上的其他服务冲突。

测试

写一个flask接口,使用ipv6访问进行测试。

1
2
3
4
5
6
7
8
9
from flask import Flask

app = Flask(__name__)

@app.route('/')
def index():
return "hello world!"
if __name__ == "__main__":
app.run(host="::", port=8000)

使用在test-ipv6上获取到的地址在浏览器上尝试访问。(ipv6地址访问格式http://[ipv6地址]:端口)

image-20220611215139842

域名解析

我的域名是在腾讯云上购买的,所以以腾讯云为例,实现动态域名解析。

添加解析记录

首先在解析列表中添加一条解析记录。

image-20220611222002003

生成代码

获取参数

通过调用获取域名解析记录获取到之前添加的记录的RecordId,复制下来。

image-20220611222602472

填写参数

域名解析的api文档可以在腾讯云的云api查看,选择DNSPOD->修改记录可以自动生成代码,填入必填参数。

  • Domain填写主域名
  • RecordType填写AAAA
  • RecordLine填写默认
  • value填写ipv6地址
  • RecordId填写刚才复制的值

image-20220611222110983

获取签名串

在访问管理->访问密钥中获取秘钥

image-20220611223710255

生成代码

pip安装腾讯云sdk

1
pip install --upgrade tencentcloud-sdk-python

获取当前ipv6地址和修改解析记录我封装了两个函数。吧SecretId, SecretKey修改成刚才的密钥,请求参数修改成自己的参数以后就可以直接调用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import json
from tencentcloud.common import credential
from tencentcloud.common.profile.client_profile import ClientProfile
from tencentcloud.common.profile.http_profile import HttpProfile
from tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException
from tencentcloud.dnspod.v20210323 import dnspod_client, models
import requests


def get_ipv6_address():
ipv6 = requests.get("https://ipv6.vm3.test-ipv6.com/ip/?callback=?").text
ipv6 = ipv6[16:55]
return ipv6


def modify_dns_record(ipv6: str):
try:
cred = credential.Credential("SecretId", "SecretKey")
httpProfile = HttpProfile()
httpProfile.endpoint = "dnspod.tencentcloudapi.com"

clientProfile = ClientProfile()
clientProfile.httpProfile = httpProfile
client = dnspod_client.DnspodClient(cred, "", clientProfile)

req = models.ModifyRecordRequest()
# 请求参数
params = {
"Domain": "xxxx.xxx",
"SubDomain": "ipv6",
"RecordType": "AAAA",
"RecordLine": "默认",
"Value": ipv6,
"RecordId": xxxxxxx
}
req.from_json_string(json.dumps(params))

resp = client.ModifyRecord(req)
print(resp.to_json_string())

except TencentCloudSDKException as err:
print(err)

反向代理与重定向

配置好域名解析以后可以实现http://域名:端口形式的访问,但是这种访问方式还是很不美观,如果我们手里正好有一台有公网ip的服务器的话,那么就可以使用反向代理或301重定向实现域名直接访问。

  • 反向代理

    若服务器支持ipv6的话可以直接将当前DDNS的域名用另一个域名进行反向代理,那么直接可以使用代理后的域名访问,由于我服务器没有ipv6网络,理论可行但没有办法具体实施。

  • 重定向

    该方法主要针对云服务器不支持ipv6的情况,通过配置nginx实现域名重定向。但是这种方式最后域名还是会跳转至http://域名:端口形式。个人感觉这种方式使用体验与带端口方式差别不大。

    image-20220612102302581

结语

上述代码可以根据实际需要进一步完善,比如加入定时检测,当检测到当前ipv6地址变化以后就修改域名解析记录等,具体的实现逻辑可以根据需要自行编写。修改记录后可能需要延迟10分钟左右更新才能生效,但在使用过程中影响不大。