
旧电脑+IPv6+阿里云DDNS:零成本搭建公网环境
家里的旧电脑还在吃灰?代码一上线就趴窝?仅需简单3个步骤将闲置旧设备利用起来,搭建博客、测试环境、NAS都不在话下。
演示环境
网络:中国移动宽带+移动烽火路由器
笔记本电脑:2核4线程CPU+16G内存+500G固态硬盘
系统:win10企业版+
虚拟机内系统:VMware+rocky Linux 9.6
域名:阿里云+DNS解析
脚本环境:Python 3.11.9
详细步骤
1. 网络准备
1.1 启用公网ipv6
登录路由器后台启用ipv6,我这里是移动的网络,默认管理地址是192.168.1.1,账户和密码在路由器背面。移动路由器需要admin账号才有权限修改,获取移动路由器admin账号见文末。
登录 -> 网络 -> 带宽设置 -> 网络连接:选择4_INTERNET_R_VID_41勾选ipv6并保存。
注:不同路由器启用IPv6的路径各不相同,比如小米路由器只需要在网络里勾选ipv6即可。
1.2 测试公网地址
在路由器上启用ipv6后只需重启电脑即可获取公网ipv6地址。
重启后通过WIN+R输入cmd并回车打开终端,在终端输入ipconfig
并回车即可查看公网ipv6地址。
如图2409开头的IPv6地址就是公网地址,尽量不要使用临时IPv6地址,临时的变更频率比较快。
复制地址后在另一台主机上连接手机热点使用ping ipv6地址
来测试是否能ping通。(ping前确保被访问主机防火墙ICMP服务为放行状态)
注:如无法访问建议关掉路由器ipv6防火墙,有一定风险,自行斟酌。
2. DDNS解析
2.1 域名解析
获取到公网ipv6地址后前往阿里云官网 -> 控制台 -> 云解析DNS -> 点击对应域名的解析设置 -> 添加记录:记录类型AAAA、主机记录根据需求配置,可设置一个二级域名或使用主域名、记录值为你的公网IPv6地址 -> 确定。
注:确保你已经在阿里云购买或已经拥有一个域名。
2.2 新建RAM用户
鼠标放在阿里云右上角头像上会弹出窗口 -> 访问控制 -> 用户 -> 创建用户 -> 填写账户名并勾选 使用永久 AccessKey 访问 -> 确认并保存账户和密码,一定要保存好,否则需要重新创建 -> 找到刚刚新建的用户添加权限 -> 勾选只读访问云解析(DNS)的权限、管理云解析(DNS)的权限 -> 确定。
2.3 配置脚本
在这之前确保你拥有Python环境和阿里云sdk,文末有教程。在桌面新建txt文件,将下方Python脚本复制到txt文件内,修改配置区域的对应配置,将文件保存为ddnsUpData.py,文件名不要紧,后缀一定要是.py。将文件放到在你找得到的地方,方便使用。以上都配置好后就可以双击脚本文件测试是否正常运行。
# -*- coding: utf-8 -*-
import subprocess
import re
import socket
from aliyunsdkcore.client import AcsClient
from aliyunsdkcore.acs_exception.exceptions import ClientException
from aliyunsdkalidns.request.v20150109 import DescribeDomainRecordsRequest, UpdateDomainRecordRequest
import json
# ==================== 配置区域 ====================
ACCESS_KEY_ID = 'RAM用户id'
ACCESS_SECRET = 'RAM用户SECRET'
DOMAIN_NAME = '主域名,如example.com'
RECORD_TYPE = 'AAAA'
RECORD_LINE = 'default'
HOST_RECORD = '主机记录(例如设置为www则解析www.example.com)'
# ==================== 配置区域 ====================
def is_public_ipv6(ip):
"""判断是否是公网 IPv6 地址(排除 fe80::/10 和 ::1)"""
return not ip.startswith("fe80") and not ip.startswith("::1")
def get_public_ip(ipv6=True):
"""
获取公网 IPv6 地址(优先获取固定 IPv6 地址)
如果没有固定 IPv6,则尝试使用临时 IPv6
如果都没有,则回退到 IPv4
"""
if ipv6:
try:
result = subprocess.check_output(['ipconfig'], stderr=subprocess.STDOUT, stdin=subprocess.DEVNULL, text=True)
lines = result.splitlines()
fixed_ipv6 = None
temp_ipv6 = None
for i, line in enumerate(lines):
# 匹配 IPv6 地址(中英文兼容)
ipv6_match = re.search(r"(IPv6 Address|IPv6 地址)[\. ]+: ([0-9a-fA-F:]+%?\d*)", line)
if ipv6_match:
ip = ipv6_match.group(2)
# 判断是否是公网地址
if not is_public_ipv6(ip):
continue
# 判断当前行是否是 "临时 IPv6 地址"
is_temp = re.search(r"(Temporary IPv6 Address|临时 IPv6 地址)", line)
if is_temp:
if temp_ipv6 is None:
temp_ipv6 = ip
print(f"[信息] 找到临时IPv6地址: {ip}")
else:
if fixed_ipv6 is None:
fixed_ipv6 = ip
print(f"[信息] 找到固定公网IPv6地址: {ip}")
# 优先返回固定公网IPv6地址
if fixed_ipv6:
print(f"[信息] 使用固定公网IPv6地址: {fixed_ipv6}")
return fixed_ipv6
# 如果没有固定地址,尝试使用临时地址
if temp_ipv6:
print(f"[信息] 使用临时IPv6地址作为备用: {temp_ipv6}")
return temp_ipv6
print("[警告] 未找到公网IPv6地址,尝试获取IPv4地址...")
except Exception as e:
print(f"[错误] 获取IPv6地址失败({e}),尝试获取IPv4地址...")
# 回退到 IPv4
return get_public_ipv4()
def get_public_ipv4():
"""获取公网IPv4地址"""
try:
addresses = socket.getaddrinfo(socket.gethostname(), None, socket.AF_INET)
for addr in addresses:
ip = addr[4][0]
if ip != "127.0.0.1":
print(f"[信息] 检测到IPv4地址: {ip}")
return ip
print("[错误] 未找到有效的IPv4地址")
return None
except Exception as e:
print(f"[错误] 获取IPv4地址失败: {e}")
return None
def get_record_id(client):
request = DescribeDomainRecordsRequest.DescribeDomainRecordsRequest()
request.set_DomainName(DOMAIN_NAME)
request.set_Type(RECORD_TYPE)
request.set_RRKeyWord(HOST_RECORD)
try:
response = client.do_action_with_exception(request)
result = json.loads(response.decode('utf-8'))
records = result.get('DomainRecords', {}).get('Record', [])
for record in records:
if record['RR'] == HOST_RECORD and record['Type'] == RECORD_TYPE:
return record['RecordId'], record['Value']
print(f"[警告] 未找到匹配的DNS记录,请检查配置")
return None, None
except Exception as e:
print(f"[错误] 阿里云API调用失败: {e}")
return None, None
def update_dns_record(client, record_id, new_ip):
request = UpdateDomainRecordRequest.UpdateDomainRecordRequest()
request.set_RecordId(record_id)
request.set_RR(HOST_RECORD)
request.set_Type(RECORD_TYPE)
request.set_Value(new_ip)
request.set_Line(RECORD_LINE)
try:
response = client.do_action_with_exception(request)
result = json.loads(response.decode('utf-8'))
if result.get('RecordId') == record_id:
print(f"[成功] DNS记录已更新为: {new_ip}")
return True
return False
except Exception as e:
print(f"[错误] 更新DNS记录失败: {e}")
return False
def main():
client = AcsClient(ACCESS_KEY_ID, ACCESS_SECRET, 'cn-hangzhou')
current_ip = get_public_ip(ipv6=True)
if not current_ip:
print("[错误] 无法获取公网IP地址")
return
# 可选:去掉 IPv6 地址中的 %11 网卡标识符
current_ip = current_ip.split("%")[0]
print(f"[信息] 当前公网IP地址: {current_ip}")
record_id, old_ip = get_record_id(client)
if not record_id:
print("[错误] 无法获取DNS记录ID")
return
print(f"[信息] 当前DNS记录值: {old_ip}")
if current_ip == old_ip:
print("[信息] IP地址未发生变化,无需更新")
return
if update_dns_record(client, record_id, current_ip):
print("[完成] DNS更新成功")
else:
print("[失败] DNS更新失败")
if __name__ == '__main__':
main()
2.4 定期启动脚本更新ip地址
如果脚本正常运行则使用“任务计划程序”进行定期执行:windows搜索并打开“任务计划程序” -> 创建任务 -> 勾选使用最高权限运行和不管用户是否登录运行 -> 触发器勾选重复任务间隔30分钟,持续期限无限期,勾选启用并确认 ->点击操作,选择启动程序,选择刚刚脚本所在位置并确定 ->设置好后点击 确定 -> 点击刚刚创建的任务,选择运行,查看脚本是否运行成功。可以在历史记录里看每是否运行。
到这里,你已经拥有了一个公网地址,只需要通过域名放即可,远程桌面等也可以直接使用域名。(记得防火墙放行)
3. 准备服务器环境(可选)
3.1 安装虚拟机系统
根据个人爱好选择vm或vb虚拟机都可以,具体安装步骤和系统的选择这里就不讲了,图形化界面很简单,不会的百度很多教程。
3.2 设置ipv6地址端口转发
由于vm或vb虚拟机目前都不支持ipv6的nat地址转换,同时虚拟机的桥接模式无法获取路由器下发的ipv6前缀,所以这里使用cmd命令设置,将本机的公网ipv6地址端口映射到虚拟机ipv4局域网地址的对应端口。
netsh interface portproxy add v6tov4 listenaddress=:: listenport=主机的ipv6地址的端口 connectaddress=虚拟机局域网地址 connectport=虚拟机端口
# 查看现以设置的所有端口代理规则
netsh interface portproxy show all
# 删除指定规则
netsh interface portproxy delete v6tov4 listenaddress=:: listenport=要删除规则的主机的ipv6地址的端口
注:由于大部分家庭宽带的80、443、22、8080等端口都处于封禁状态,建议避开这几个端口,如果有需求,可以使用公网服务器的反向代理进行访问。
4.3 访问测试
基本完成,可自行安装web服务器进行访问测试。
其他问题解答
1. 获取移动路由器admin账号
由于移动路由器必须使用admin才能修改ipv6设置,这里讲解如何获取admin账户和密码。
首先查看路由器背面的mac地址如:AA-BB-CC-DD-EE-FF,将其“-”去掉获得:AABBCCDDEEFF。
浏览器输入http:/192.168.1.1/cgi-bin/telnetenable.cgi?telnetenable=1&key=自行替换为去掉-的mac地址
并回车,这时会看到telnet开启等字样,现在打开cmd终端输入telnet 192.168.1.1并回车,按提示输入admin账户,密码为Fh@mac地址后6位,如Fh@DDEEFF。
先输入load_cli factory
其次输入show admin_name
获取账户名
再输入show admin_pwd
获取密码,这个密码是临时的。
使用获取的账户名和密码登录并进行配置修改。
2. Python脚本环境准备
去官网下载Python官网下载python并安装https://www.python.org/downloads/windows/
使用cmd终端执行以下命令安装aliyunSDK
pip install aliyun-python-sdk-core
pip install aliyun-python-sdk-alidns
缺一不可。