基于阿里云 API 实现 DDNS 内网穿透功能展开目录
硬件拓扑场景展开目录
实现前提展开目录
- 具备阿里云注册的域名
- 内网运营商给你的对外 IP 是公网(动态的)
网络结构调整展开目录
获取超级管理账户展开目录
由于光猫本身的路由功能有限,建议使用路由器的拨号上网功能,光猫使用桥接模式。
在修改光猫的 WAN 模式前,需要获取光猫的超级管理员账号,可以咨询客服获取,或者参考如下方法自行获取(适用于天翼 2.0 的网关猫 型号是烽火 HG2201T):
假设管理地址是 192.168.1.1 (光猫铭牌上有)
- 普通用户登录后台 光猫铭牌上有普通用户账号信息
- 登录后访问 http://192.168.1.1:8080/cgi-bin/baseinfoSet.cgi
获取如下信息:
超密一般就是 telecomadmin + 八位数字,所以后面 8 组数字就代表 8 为数字 从 48 到 57 就是 0 到 9。因此只需要解析后面八组数字就可以拿到管理密码
修改光猫的宽带设置展开目录
超级管理账户登录光猫后台,选择网络宽带配置,修改前确保你已截图备份路由模式下的配置,并知晓宽带账号级密码
备份工作后,修改连接模式为桥接,保存即可
为防止与之前的配置冲突,建议修改 DHCP 配置,选择用户侧管理 - IPv4 设置,将 IP 地址修改为与之前不一样的,注意同步修改 DHCP 网段
使用路由器进行拨号上网展开目录
确保路由器已经连接光猫,连接路由器的无线,登录后台,此处使用的路由器为华为 AX3
如下图配置即可,宽带账号修改为自己的
配置后保存,正常即可连上网络
配置 DMZ 主机暴露自己的内网服务器展开目录
也可以使用 NAT 服务配置端口映射实现单端口的外网访问
至此你可以使用你的动态公网 IP 访问到你的内网服务器了展开目录
内网服务器配置 (树莓派 4B 为例) 展开目录
配置服务器静态 IP 展开目录
vi /etc/dhcpcd.conf
# 使用 vi 编辑文件,增加下列配置项
# 指定接口 eth0 (无线连接则是wlan0)
interface eth0
# 指定静态IP,/24表示子网掩码为 255.255.255.0
static ip_address=192.168.3.11/24
# 路由器/网关IP地址
static routers=192.168.3.1
# 手动自定义DNS服务器
static domain_name_servers=114.114.114.114 8.8.8.8 223.5.5.5 223.6.6.6 192.168.3.1
# 修改完成后,按esc键后输入 :wq 保存。重启树莓派就生效了
sudo reboot
配置阿里云域名解析记录展开目录
Python 调用阿里云 SDK 更新解析记录展开目录
首先,要确定一个准备用于外网访问的域名,并将此域名转入到阿里云的云解析服务来解析。如图所示,添加需要管理的域名。
转入后,在解析设置中,设置一下 A 记录解析,解析的 IP 地址可以填当前的公网 IP。如果不知道自己的公网 IP,在 CentOS 系统下,可以输入使用以下命令获取当前的公网 IP。
脚本原理展开目录
- 获取主机的外网 IP
- 调用接口获取域名解析配置并比对当前外网 IP 与域名解析配置中的 IP 是否一致
- IP 不一致则调用域名解析配置更新接口更新为当前的公网 IP,否则不操作
- 使用 Linux 定时任务每天执行一次(可根据实际情况调整频率)
安装依赖展开目录
sudo apt-get install python3-pip
sudo apt-get install build-essential libssl-dev libffi-dev python3-dev
pip3 install aliyun-python-sdk-core -i http://mirrors.aliyun.com/pypi/simple
pip3 install aliyun-python-sdk-alidns -i http://mirrors.aliyun.com/pypi/simple
脚本展开目录
/root/ddns/aliyunApiForDDNS.py 内容如下:
#!/usr/bin/env python3
# coding=utf-8
import json
from urllib.request import urlopen
from aliyunsdkalidns.request.v20150109 import DescribeDomainRecordsRequest
from aliyunsdkalidns.request.v20150109 import UpdateDomainRecordRequest
from aliyunsdkcore.client import AcsClient
class DnsHandler:
# 从阿里云开发者后台获取Access_Key_Id和Access_Key_Secret
access_key_id = '你自己的key'
access_key_secret = '你自己的secret'
region_id = 'cn-hangzhou'
# 域名
domain_name = "mikuai.tech"
# 填入二级域名的RR值
rr_keyword = "www"
# 解析记录类型,一般为A记录
record_type = "A"
# 用于储存解析记录的文件名
file_name = ".ip_addr"
client = None
record = None
current_ip = '117.83.29.186'
# 初始化,获取client实例
def __init__(self):
self.client = AcsClient(
self.access_key_id,
self.access_key_secret,
self.region_id
)
self.record = self.get_record()
self.current_ip = self.get_current_ip()
# 如果公网IP发生变化,则自动修改阿里云解析记录
def reset(self):
if self.current_ip != self.get_record_value():
print(self.update_record(self.current_ip))
self.get_record()
# 获取阿里云域名解析完整记录
def get_record(self):
"""
未做记录为空判断,要求阿里云域名对应记录存在
:return: 域名记录字典
"""
request = DescribeDomainRecordsRequest.DescribeDomainRecordsRequest()
request.set_PageSize(10)
request.set_action_name("DescribeDomainRecords")
request.set_DomainName(self.domain_name)
request.set_RRKeyWord(self.rr_keyword)
request.set_TypeKeyWord(self.record_type)
r = self.client.do_action_with_exception(request)
return json.loads(r)
# 获取阿里云域名解析记录ID
def get_record_id(self):
return self.record["DomainRecords"]["Record"][0]["RecordId"]
# 获取当前域名解析记录
def get_record_value(self):
return self.record["DomainRecords"]["Record"][0]["Value"]
# 修改阿里云解析记录
def update_record(self, value):
request = UpdateDomainRecordRequest.UpdateDomainRecordRequest()
request.set_action_name("UpdateDomainRecord")
request.set_RecordId(self.get_record_id())
request.set_Type(self.record_type)
request.set_RR(self.rr_keyword)
request.set_Value(value)
return self.client.do_action_with_exception(request)
# 获取当前公网IP
def get_current_ip(self):
return json.load(urlopen('https://ipv4.jsonip.com/'))['ip']
# 实例化类并启动更新程序
dns = DnsHandler()
dns.reset()
设置定时任务展开目录
sudo -s
crontab -e
# 添加如下配置
00 03 * * * /usr/bin/python3 /root/ddns/aliyunApiForDDNS.py
# 重启服务
systemctl restart cron
测试展开目录
# 树莓派安装nginx
sudo apt-get install nginx
# 启动nginx
systemctl start nginx
# 修改默认访问端口为8888
sudo nano /etc/nginx/sites-available/default
# 重启nginx
systemctl restart nginx
访问你的域名 + 端口 8888
结果如下即成功: