家里的宽带获取的是公网ip地址,带宽很高,相比现在带宽苟且的云服务器,很多需求在家里会更方便使用 家中机器配置较高,于是搭建了私有网盘Nextcloud和各种环境的虚拟机,比如k8s集群的虚拟机 加上路由器vpn, 在公司时,登录vpn能随时访问家中虚拟机

实现动态DDNS

主要就是依靠阿里云api,shell或者python脚本先获取到路由器出口ip,然后去调用api修改域名解析

shell脚本实现分析

  • shell脚本实现操作阿里云api在一般的Linux发行版来说,问题不大,网上有很多类似的脚本
  • 但是在路由器上使用shell去操作时,路由器系统一般是busybox,很多bash shell的命令不支持
  • 为了解决一个base64的算法,需要自己手写,然后手写的函数里面又依赖其他命令
  • 很遗憾,其他命令在路由器这个busybox中又没有,因此,此方式太过于繁琐
  • 最适合的方式是路由器上尽可能的运行简单的命令,比如wget或者curl之类的,间隔几秒运行一次
  • 服务器接收这个curl请求,判断来源ip,然后修改dns解析

路由器上的shell脚本

admin@RT-AC51U:/tmp/home/root# cat /jffs/etc/route.sh
while true
do
        wget -q -O - http://212.xx.79.59:9999/kwen/route?token=xxxxxx-123
        sleep 1800
done

因为busybox上没有curl命令,故使用wget -q -O - 代替curl命令,其实就是去请求一下服务端

服务器上阿里云DNS解析

这里使用的是github上的alidns工具,安装后,用命令行方式操作域名解析

安装: 
  pip install alidns
配置: 
  alidns config  <key> <key-secret> <domain>
列出: 
  alidns list
添加或更新域名: 
  alidns add     [-r=<record>] [-v=<ip>] [-t=<type>] [--ttl=<ttl>]

服务器上的python脚本

调用上一步的命令行工具去更新解析

[root@Tencent-host readme]# cat /data/route/route.py
from flask import Flask, abort, Response, request
import os


app = Flask(__name__)
app.config["DEBUG"] = True

value='home'
global DOMAIN
DOMAIN = 'kkwen.cn'
URI = '/kwen/route'
QUERY = 'token'


def get_dns():
    command = "alidns list | grep '[[:space:]]" + value + ".kkwen.cn' | awk '{print $4}'"
    ip = os.popen(command)
    return ip.read().rstrip()


def update_host(address, doamin=DOMAIN):
    t = os.popen('alidns add -r {} -v {} -t A &> /dev/null'.format(value, address))


@app.route(URI, methods=['GET'])
def get_route_ip():
    try:
        token = request.args.get(QUERY, '')
        if token != 'xxxxxx-123':
            return Response('')
        else:
            if get_dns() != request.remote_addr:
                update_host(request.remote_addr)
        return Response('')
    except Exception as e:
        print(e)
        abort(404)


if __name__ == '__main__':
    app.run(host='0.0.0.0', port=9999)

使用uwsgi部署flask app

[root@Tencent-host route]# cat uwsgi.ini 
[uwsgi]
http=0.0.0.0:9999
wsgi-file=/data/route/route.py
callable=app
#touch-reload=/data/route/
~]# nohup uwsgi --ini /data/route/uwsgi.ini &

结语

到此,已经自己实现DDNS