通过定时任务,不断轮训ip,对比ip是否变更,然后通过脚本更新moon节点文件,实现动态ip搭建moon节点

环境

  • Debian 11

网络测试

使用前建议使用iperf3测试服务器端口映射是否有问题

  1. 服务器
    iperf3 -s -p 端口
  2. 客户端
    # 测试tcp链接
    iperf3-darwin -c 服务器ip -b 7M -p 端口

    # 客户端发udp包,服务器端接收
    iperf3-darwin -u -c 服务器ip -b 7M -p 端口

    # 客户端接收,服务器端发udp包
    iperf3-darwin -u -c 服务器ip -b 7M -p 端口 -R

自定义端口

便于后面脚本截取ip做对比

服务器端

编辑脚本

通过dns查询获取公网ip(或者curl获取),对比本地配置文件,发现ip变更就更新moon节点文件

#!/bin/bash

# 通过dig获取公网ip,先检查截取的是否为ip
ip=$(dig +short 域名 114.114.114.114 | tail -n 1)

# 本地moon节点配置文件
ip_file="/var/lib/zerotier-one/moon.json"

# 判断ip是否变更
if [ -f $ip_file ]; then
# 截取moon.json文件ip字段
old_ip=$(awk -F'[][/]' '/"stableEndpoints"/ {gsub(/"/, "", $2); print $2}' $ip_file)
if [ -n "$old_ip" ] && [ $ip == $old_ip ]; then
echo "IP has not changed."
exit 0
fi
fi

# 生成moon节点配置文件
rm -rf $ip_file
/usr/sbin/zerotier-idtool initmoon /var/lib/zerotier-one/identity.public >> $ip_file

# 替换ip,生成节点文件,并重启。10109为自定义端口
sed -i '/stableEndpoints/s/\[\]/\[\"'$ip'\/10109\"\]/g' $ip_file
/usr/sbin/zerotier-idtool genmoon $ip_file
mkdir /var/lib/zerotier-one/moons.d/
cp 000000* /var/lib/zerotier-one/moons.d/
systemctl restart zerotier-one

# 可选,scp拉取文件路径
#mv 000000* /scpread/usrname/download
echo $ip

开启定时执行,crontab -e

* * * * * /root/.tool/zt_tool.sh > /root/.tool/zt_log

客户端

方法1:通过命令加入moon

通过查询ip,和本地moons的ip对比,通过zerotier-cli orbit 加入moon

#!/bin/bash

# 通过dig获取公网ip,先检查截取的是否为ip
ip=$(dig +short 域名 114.114.114.114 | tail -n 1)
ip_file="/root/.tool/moons"

# 通过zerotier-cli命令,获取当前moons的信息
docker exec zerotier zerotier-cli listmoons > $ip_file

# 对比ip是否变更
if [ -f $ip_file ]; then

# 截取文件ip字段,10109为自定义端口
old_ip=$(awk -F'/10109"' '/10109"/ {gsub(/"/, "", $1);gsub(/ /, "", $1); print $1}' $ip_file)
rm -rf $ip_file
if [ -n "$old_ip" ] && [ $ip == $old_ip ]; then
echo "IP has not changed."
exit 0
fi
fi

# ip变更了,通过命令行加入moon
docker exec zerotier zerotier-cli deorbit xxxxxx
docker exec zerotier zerotier-cli orbit xxxxxx xxxxxx
echo $ip

方法2:scp/sftp拉取moon节点文件

通过scp/sftp拉取服务器端moon节点文件,和本地节点文件对比,如果不同,就更新本地moon节点文件

#!/bin/bash
# 定义moon节点文件路径
old_moon="/mnt/disk/docker/zerotier-one/moons.d/000000xxxxxx.moon"
new_moon="./000000xxxxxx.moon"

# scp拉取文件
#scp -i .ssh/id_rsa -P 端口 user@hostname:~/download/000000xxxxxx.moon ./

# sftp拉取文件名
sftp -i .ssh/id_rsa -P 端口 user@hostname << EOF
get download/000000xxxxxx.moon
exit
EOF

# 检测文件是否已经拉取,并对比文件是否变更
if [ -f $new_moon ]; then
if [ -f $old_moon ]; then
result=$(cmp $old_moon $new_moon)
# 对比结果为空,说明文件没有变更
if [ -z "$result" ]; then
echo "file has not changed."
rm $new_moon
exit 0
fi
fi

# 执行更新操作
echo "file has changed."
mv $new_moon $old_moon
docker restart zerotier
fi

配置只读scp/sftp(可选)

禁止ssh登录,只开启scp/sftp

  1. 添加禁止登录用户
    # 添加用户
    useradd -d /scpread/usrname -s /sbin/nologin usrname

    # 修改密码
    passwd usrname

    # 创建用户文件夹
    mkdir -p /scpread/usrname
  2. 添加ssh key校验
    # 创建文件夹和文件
    mkdir /scpread/usrname/.ssh
    vim /scpread/usrname/.ssh/authorized_keys

    # 设置权限
    chown usrname:usrname /scpread/usrname/.ssh/
    chown usrname:usrname /scpread/usrname/.ssh/authorized_keys
  3. 修改sshd配置文件/etc/ssh/sshd_config
    #Subsystem	sftp	/usr/lib/openssh/sftp-server
    Subsystem sftp internal-sftp
    Match User usrname
    ChrootDirectory /scpread/usrname

开启定时执行,crontab -e

* * * * * /root/.tool/zt_moons.sh > /root/.tool/zt_log

参考