先说说需求
公有存储限制太多,一直考虑用家里的闲置机器做个远程文件服务器,这样在外面可以直接把手机的文件传到家里的服务器,没有中间商搞事情。家里有个 2011 版的 MAC mini,静息功耗 10W,刚好合适,文件服务器的搭建不在这里研究,先考虑一些网络问题。
- 问题1:怎么从外网访问内网服务器?咨询了一下宽带公司,可以调整我的 IP 为动态公网 IP,调整后在路由上配置了 PortMap 从外网访问成功。Done。
- 问题2:公网 IP 租期到了 IP 会发生改变,我怎么能及时感知 IP 的变化?第一想法就是找花生壳这样的专业应用,不过查了一圈发现这个服务只免费一年,域名可以绑定自己喜欢的,不过得加钱。路由器自带的 DDNS 配置也是非常非常的难用,提供的几个服务商的配置都有问题。关键是使用了他们的服务后总感觉会变成肉鸡。结合我的资源情况,决定在自己的文件服务器上写段代码,获取最新的公网IP ,然后调用域名服务商的 API 更新解析记录,完成 DDNS 的功能。
前期准备
-
申请一个喜欢的域名(我原来就有一个,可以直接用)
-
新建一个二级域名 比如 file.xxxx.com,IP 指向路由器最新分配的 IP,也可以指向 127.0.0.1,反正测试代码的时候会改。
-
在文件服务器上安装 Python3 及 SDK
- 建立 Python 虚环境
bashpython3 -m venv /opt/script source /opt/script/bin/activate
- 安装 SDK (虚环境)
-
腾讯云
bashpip install tencentcloud-sdk-python-dnspod
-
阿里云 (虚环境)
bashpip install alibabacloud_alidns20150109==3.5.6
-
-
获取 API 密钥
-
腾讯云
访问管理 => API密钥管理 => 新建密钥
-
阿里云
权限与安全 => AccessKey => 创建 AccessKey
-
编写更新 DNS 解析的代码
关键代码
- 腾讯云
python
req = models.ModifyRecordRequest()
params = {
"Domain": v_dn,
"RecordType": "A",
"RecordLine": "默认",
"Value": ip,
"RecordId": recordid,
"SubDomain": v_rr
}
req.from_json_string(json.dumps(params))
- 阿里云
python
@staticmethod
def main(
args: List[str],
) -> None:
client = Sample.create_client()
v_rr = 'file' # 改成自己的二级域名前缀
v_dn = 'xxxx.com' #改成自己的一级域名
update_domain_record_request = alidns_20150109_models.UpdateDomainRecordRequest(
rr=v_rr,
type='A',
value=args[0],
record_id=Sample.get_record_id(v_dn,v_rr)
)
runtime = util_models.RuntimeOptions()
try:
ret = client.update_domain_record_with_options(update_domain_record_request, runtime)
print(ret)
except Exception as error:
# 错误 message
print(error.message)
# 诊断地址
print(error.data.get("Recommend"))
UtilClient.assert_as_string(error.message)
完整代码
https://download.csdn.net/download/usoa/89936067
配置定时计划
每小时获取最新的 公网IP 通过
bash
vi /opt/script/updateddns.sh
#!/bin/bash
source /opt/script/bin/activate && python /opt/script/dnspod_ddns.py `curl -4 -s ifconfig.me` && deactivate
bash
crontab -e
0 * * * * bash /opt/script/updateddns.sh >> /tmp/cron.log 2>&1