From 2c413ed4e70e2c87e0d6a88804a97ebbfd189b57 Mon Sep 17 00:00:00 2001 From: root Date: Sun, 20 Feb 2022 20:25:08 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=8A=A0=E9=80=9F=E9=93=BE?= =?UTF-8?q?=E6=8E=A5=E4=BB=A5=E5=8F=8Aplanet=E7=9A=84bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 54 +++------- README.md | 190 +++++++++++++++++------------------ deploy.sh | 17 +++- gen_world.sh | 10 ++ init.sh | 21 ++++ linux_planet_ok.png | Bin 0 -> 15045 bytes patch/mkworld.cpp | 236 ++++++++++++++++++++++---------------------- patch/patch.json | 10 +- patch/patch.py | 102 +++++++++---------- server.sh | 6 -- win_planet_ok.png | Bin 0 -> 27783 bytes 11 files changed, 324 insertions(+), 322 deletions(-) mode change 100644 => 100755 deploy.sh create mode 100644 gen_world.sh create mode 100644 init.sh create mode 100644 linux_planet_ok.png delete mode 100644 server.sh create mode 100644 win_planet_ok.png diff --git a/Dockerfile b/Dockerfile index ef315cc..a76d3fb 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,42 +1,12 @@ -FROM alpine:latest - -ADD ./server.sh /app/ -ADD ./patch /opt/patch/ - -VOLUME ["/var/lib/zerotier-one/"] - - - -RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apk/repositories &&\ - apk update &&\ - apk add git python3 nodejs npm make g++ linux-headers zerotier-one &&\ - npm config set registry http://registry.npm.taobao.org &&\ - - # 安装ztncui - cd /opt && git clone https://github.91chi.fun/https://github.com/key-networks/ztncui.git &&\ - cd ztncui/src && npm install -g node-gyp && npm install &&\ - cp -pv ./etc/default.passwd ./etc/passwd &&\ - echo 'HTTP_PORT=3443' > .env&&\ - echo 'NODE_ENV=production' >> .env &&\ - echo 'HTTP_ALL_INTERFACES=true' >> .env &&\ - - # 添加补丁 - cd /opt && \ - git clone https://github.91chi.fun/https://github.com/zerotier/ZeroTierOne.git && \ - - cd /var/lib/zerotier-one && \ - zerotier-idtool generate identity.public identity.secret &&\ - zerotier-idtool initmoon identity.public >> moon.json &&\ - - cp /opt/patch/* . &&\ - python3 patch.py &&\ - zerotier-idtool genmoon moon.json &&\ - mkdir moons.d && cp ./*.moon ./moons.d &&\ - - rm /opt/ZeroTierOne/attic/world/mkworld.cpp &&\ - cp mkworld.cpp /opt/ZeroTierOne/attic/world/ &&\ - cd /opt/ZeroTierOne/attic/world/ && \ - sh build.sh - -WORKDIR /app/ -CMD ["sh","./server.sh"] +FROM alpine:latest + +ADD ./init.sh /app/ +ADD ./gen_world.sh /app/ +ADD ./patch /opt/patch/ + +VOLUME ["/var/lib/zerotier-one/"] + +RUN cd /app && sh init.sh + +WORKDIR /app/ +CMD /bin/sh -c "zerotier-one -d; cd /opt/ztncui/src;npm start" diff --git a/README.md b/README.md index 1158f94..76978f8 100644 --- a/README.md +++ b/README.md @@ -1,97 +1,93 @@ -# Docker-zerotier-planet -私有部署zeroteir-planet服务 - -zerotier是一个非常好用的私有组网的软件,但是官方提供的服务器离我们比较远,自建planet服务器可以帮我们解决很多与网络有关的问题 - - -# 准备条件 -- 具有公网ip的服务器(需要开放3443/tcp端口,9992/tcp端口,9992/udp端口) -- 安装docker - -# 开始 -## 1.下载项目源码 -``` -git clone https://github.com.cnpmjs.org/xubiaolin/docker-zerotier-planet.git -``` -## 2.修改项目中的patch/patch.json - -将其中的ip地址修改为你服务器的ip地址,端口保留不变即可 - - -## 3.在包含Dockerfile的目录下打包镜像 -如果您不是第一次使用该项目,您需要先执行以下命令 -``` -rm -rf /opt/zerotier-planet -docker stop zerotier-planet -docker rm zerotier-planet -docker rmi zerotier-planet -``` -打包镜像 -``` -docker build -t zerotier-planet:latest . -``` -打包预计需要2-5分钟,具体需要看网络与机型 - - -# 启动项目 - -启动服务 -``` -docker run -d --name zerotier-planet -p 3443:3443 -p 9992:9993 -p 9992:9993/udp -v /opt/zerotier-planet:/var/lib/zerotier-one --restart unless-stopped zerotier-planet:latest -``` - - -# 创建网络 -服务器需要开放3443端口 -然后访问http://ip:3443 即可进入管理后台 - -![ui](webui.png) - - -使用默认账号为:admin - -默认密码为:password - -进入后创建一个网络,可以得到一个网络ID -通过官方的app就可以直接连接这个网络ID了,下面的步骤为可选操作。 - -# 【可选】客户端配置 -首先将服务器/opt/zerotier-planet 目录下的planet文件下载到本地以备用 - -## linux 客户端配置 -安装zerotier-one客户端 -``` -curl -s https://install.zerotier.com | sudo bash -``` -进入/var/lib/zerotier-one目录下, -删除目录下的planet文件,然后把从服务器下载的planet文件替换过来 - -重启一下zerotier-one服务 -debian系使用命令 -``` -service zerotier-one restart -``` - -然后执行zerotier-cli join 网络ID - -成功后可以在管理后台上面看到一个新增的members,此时我们需要授权,否则将无法访问。 - -![auth](auth.png) - -其他客户端加入也是一样要进行授权操作操作 - -## windows 客户端配置 -windows -将planet文件覆盖粘贴到C:\ProgramData\ZeroTier\One中 - -windows搜索服务,并重启zeroiter-one - -powershell(admin)中执行zerotier-cli listpeers查看planet是否生效 - -## 安卓客户端配置 -[Zerotier 非官方安卓客户端发布:支持自建 Moon 节点 - V2EX](https://www.v2ex.com/t/768628) - -# 参考链接 -[zerotier-虚拟局域网详解](https://www.glimmer.ltd/2021/3299983056/) - -[五分钟自建 ZeroTier 的 Planet/Controller](https://v2ex.com/t/799623) +# Docker-zerotier-planet +私有部署 `zeroteir-planet` 服务 + +zerotier 是一个非常好用的私有组网的软件,但是官方提供的服务器离我们比较远,自建planet服务器可以帮我们解决很多与网络有关的问题 + + +# 一:准备条件 +- 具有公网ip的服务器(需要开放3443/tcp端口,9993/tcp端口,9993/udp端口) +- 安装docker + +# 二:开始 +## 1.下载项目源码 +``` +git clone http://github.markxu.vip/https://github.com/xubiaolin/docker-zerotier-planet.git +``` +## 2.修改配置 + +修改项目中的patch/patch.json,将其中的ip地址修改为你服务器的ip地址,端口保留不变即可 + +## 3.一键部署 +启动时会关闭9993端口的服务,请注意 +``` +cd docker-zerotier-planet +./deploy.sh +``` +打包预计需要3-5分钟,具体需要看网络与机型 + + +**防火墙需要开放 `3443/tcp, 9993/tcp, 9993/udp` 这三个端口** + +**planet 文件在`/opt/planet`, 客户端直连时需要替换客户端的planet** + +# 三:创建网络 +访问 http://ip:3443 即可进入controller页面 + +![ui](webui.png) + + +使用默认账号为:`admin` + +默认密码为:`password` + +进入后创建一个网络,可以得到一个网络ID +# 四:客户端配置 +首先将服务器 `/opt/zerotier-planet` 目录下的 planet 文件下载到本地以备用 + +## 4.1linux 客户端配置 +安装zerotier-one客户端 +``` +curl -s https://install.zerotier.com | sudo bash +``` +进入`/var/lib/zerotier-one`目录下, +删除目录下的planet文件,然后把从服务器下载的planet文件替换过来 + +重启一下zerotier-one服务 +debian系使用命令 +``` +service zerotier-one restart +``` + +执行 `zerotier-cli listpeers` 可以查看 peers + +![linux_ok](linux_planet_ok.png) + +如果和上图一样出现了PLANET字样,则表示成功了 + +---------------------------------------- + +执行`zerotier-cli join 网络ID`,可以加入到网络中, + +成功后可以在管理后台上面看到一个新增的 members ,此时我们需要授权,否则将无法访问。 + +![auth](auth.png) + +其他客户端加入也是一样要进行授权操作操作 + +## 4.2 windows 客户端配置 +windows +将 planet 文件覆盖粘贴到`C:\ProgramData\ZeroTier\One`中 + +windows 搜索服务,并重启 zeroiter-one + +powershell(admin)中执行`zerotier-cli listpeers`查看 planet 是否生效 +![win_ok](win_planet_ok.png) + + +## 4.3 安卓客户端配置 +[Zerotier 非官方安卓客户端发布:支持自建 Moon 节点 - V2EX](https://www.v2ex.com/t/768628) + +# 参考链接 +[zerotier-虚拟局域网详解](https://www.glimmer.ltd/2021/3299983056/) + +[五分钟自建 ZeroTier 的 Planet/Controller](https://v2ex.com/t/799623) diff --git a/deploy.sh b/deploy.sh old mode 100644 new mode 100755 index 409af6b..5f0b873 --- a/deploy.sh +++ b/deploy.sh @@ -1,15 +1,26 @@ #!/bin/sh imageName="zerotier-planet" +docker network create zerotier + echo "清除原有内容" -rm -rf /opt/$imageName +rm /opt/planet docker stop $imageName docker rm $imageName docker rmi $imageName + echo "打包镜像" -docker build -t $imageName:latest . +docker build --network zerotier -t $imageName . echo "启动服务" for i in $(lsof -i:9993 -t);do kill -2 $i;done -docker run -d --network host --name $imageName -p 3443:3443 -p 9993:9993 -p 9993:9993/udp -v /opt/$imageName:/var/lib/zerotier-one --restart unless-stopped $imageName:latest +docker run -d --network zerotier --name $imageName -p 3443:3443 -p 9993:9993 -p 9993:9993/udp --dns 223.5.5.5 --dns 223.6.6.6 --restart unless-stopped $imageName + +sleep 10s +echo "生成世界" +docker exec -it $imageName sh /app/gen_world.sh +docker cp $imageName:/opt/ZeroTierOne/attic/world/world.bin /opt/planet + +echo "------------------" +echo "现在已经配置好了,planet文件在/opt/planet, 客户端连接时需要替换该planet" \ No newline at end of file diff --git a/gen_world.sh b/gen_world.sh new file mode 100644 index 0000000..d86e9ce --- /dev/null +++ b/gen_world.sh @@ -0,0 +1,10 @@ +cd /var/lib/zerotier-one && zerotier-idtool initmoon identity.public > moon.json + +# 添加补丁 +cd /opt/patch && python3 patch.py +cd /var/lib/zerotier-one && zerotier-idtool genmoon moon.json && mkdir moons.d && cp ./*.moon ./moons.d + +# 生成世界 +cd /opt/ZeroTierOne/attic/world/ +sh build.sh +./mkworld \ No newline at end of file diff --git a/init.sh b/init.sh new file mode 100644 index 0000000..5571851 --- /dev/null +++ b/init.sh @@ -0,0 +1,21 @@ +sed -i 's/dl-cdn.alpinelinux.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apk/repositories +apk update +apk add git python3 nodejs npm make g++ linux-headers zerotier-one +npm config set registry http://registry.npm.taobao.org && npm install -g node-gyp + +echo "下载源码中,源码文件较大,请耐心等待;如果源码下载失败,请重新执行该脚本" +# 下载源码 +cd /opt && git clone http://github.markxu.vip/https://github.com/key-networks/ztncui.git +if [ "$?"-ne 0]; then echo "下载源码出错,请重试"; exit 1; fi + +cd /opt && git clone http://github.markxu.vip/https://github.com/zerotier/ZeroTierOne.git +if [ "$?"-ne 0]; then echo "下载源码出错,请重试"; exit 1; fi + +# 配置ztncui +cd /opt/ztncui/src && npm install +cp -pv ./etc/default.passwd ./etc/passwd +echo 'HTTP_PORT=3443' >.env +echo 'NODE_ENV=production' >>.env +echo 'HTTP_ALL_INTERFACES=true' >>.env + + diff --git a/linux_planet_ok.png b/linux_planet_ok.png new file mode 100644 index 0000000000000000000000000000000000000000..92ac5cd7f4e526efc1d0274010edd95e408e67e7 GIT binary patch literal 15045 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

VS_1(GlHt^jE_ZZb#&<4CV@SKWAnE_u1C}C=v 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 Cs13pZ literal 0 HcmV?d00001 diff --git a/patch/mkworld.cpp b/patch/mkworld.cpp index 49181a7..7f6a051 100644 --- a/patch/mkworld.cpp +++ b/patch/mkworld.cpp @@ -1,119 +1,119 @@ -/* - * ZeroTier One - Network Virtualization Everywhere - * Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/* - * This utility makes the World from the configuration specified below. - * It probably won't be much use to anyone outside ZeroTier, Inc. except - * for testing and experimentation purposes. - * - * If you want to make your own World you must edit this file. - * - * When run, it expects two files in the current directory: - * - * previous.c25519 - key pair to sign this world (key from previous world) - * current.c25519 - key pair whose public key should be embedded in this world - * - * If these files do not exist, they are both created with the same key pair - * and a self-signed initial World is born. - */ - -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -using namespace ZeroTier; - -int main(int argc,char **argv) -{ - std::string previous,current; - if ((!OSUtils::readFile("previous.c25519",previous))||(!OSUtils::readFile("current.c25519",current))) { - C25519::Pair np(C25519::generate()); - previous = std::string(); - previous.append((const char *)np.pub.data,ZT_C25519_PUBLIC_KEY_LEN); - previous.append((const char *)np.priv.data,ZT_C25519_PRIVATE_KEY_LEN); - current = previous; - OSUtils::writeFile("previous.c25519",previous); - OSUtils::writeFile("current.c25519",current); - fprintf(stderr,"INFO: created initial world keys: previous.c25519 and current.c25519 (both initially the same)" ZT_EOL_S); - } - - if ((previous.length() != (ZT_C25519_PUBLIC_KEY_LEN + ZT_C25519_PRIVATE_KEY_LEN))||(current.length() != (ZT_C25519_PUBLIC_KEY_LEN + ZT_C25519_PRIVATE_KEY_LEN))) { - fprintf(stderr,"FATAL: previous.c25519 or current.c25519 empty or invalid" ZT_EOL_S); - return 1; - } - C25519::Pair previousKP; - memcpy(previousKP.pub.data,previous.data(),ZT_C25519_PUBLIC_KEY_LEN); - memcpy(previousKP.priv.data,previous.data() + ZT_C25519_PUBLIC_KEY_LEN,ZT_C25519_PRIVATE_KEY_LEN); - C25519::Pair currentKP; - memcpy(currentKP.pub.data,current.data(),ZT_C25519_PUBLIC_KEY_LEN); - memcpy(currentKP.priv.data,current.data() + ZT_C25519_PUBLIC_KEY_LEN,ZT_C25519_PRIVATE_KEY_LEN); - - // ========================================================================= - // EDIT BELOW HERE - - std::vector roots; - - const uint64_t id = ZT_WORLD_ID_EARTH; - const uint64_t ts = 1567191349589ULL; // August 30th, 2019 - - //__PATCH_REPLACE__ - - // END WORLD DEFINITION - // ========================================================================= - - fprintf(stderr,"INFO: generating and signing id==%llu ts==%llu" ZT_EOL_S,(unsigned long long)id,(unsigned long long)ts); - - World nw = World::make(World::TYPE_PLANET,id,ts,currentKP.pub,roots,previousKP); - - Buffer outtmp; - nw.serialize(outtmp,false); - World testw; - testw.deserialize(outtmp,0); - if (testw != nw) { - fprintf(stderr,"FATAL: serialization test failed!" ZT_EOL_S); - return 1; - } - - OSUtils::writeFile("world.bin",std::string((const char *)outtmp.data(),outtmp.size())); - fprintf(stderr,"INFO: world.bin written with %u bytes of binary world data." ZT_EOL_S,outtmp.size()); - - fprintf(stdout,ZT_EOL_S); - fprintf(stdout,"#define ZT_DEFAULT_WORLD_LENGTH %u" ZT_EOL_S,outtmp.size()); - fprintf(stdout,"static const unsigned char ZT_DEFAULT_WORLD[ZT_DEFAULT_WORLD_LENGTH] = {"); - for(unsigned int i=0;i 0) - fprintf(stdout,","); - fprintf(stdout,"0x%.2x",(unsigned int)d[i]); - } - fprintf(stdout,"};" ZT_EOL_S); - - return 0; +/* + * ZeroTier One - Network Virtualization Everywhere + * Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/ + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/* + * This utility makes the World from the configuration specified below. + * It probably won't be much use to anyone outside ZeroTier, Inc. except + * for testing and experimentation purposes. + * + * If you want to make your own World you must edit this file. + * + * When run, it expects two files in the current directory: + * + * previous.c25519 - key pair to sign this world (key from previous world) + * current.c25519 - key pair whose public key should be embedded in this world + * + * If these files do not exist, they are both created with the same key pair + * and a self-signed initial World is born. + */ + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +using namespace ZeroTier; + +int main(int argc,char **argv) +{ + std::string previous,current; + if ((!OSUtils::readFile("previous.c25519",previous))||(!OSUtils::readFile("current.c25519",current))) { + C25519::Pair np(C25519::generate()); + previous = std::string(); + previous.append((const char *)np.pub.data,ZT_C25519_PUBLIC_KEY_LEN); + previous.append((const char *)np.priv.data,ZT_C25519_PRIVATE_KEY_LEN); + current = previous; + OSUtils::writeFile("previous.c25519",previous); + OSUtils::writeFile("current.c25519",current); + fprintf(stderr,"INFO: created initial world keys: previous.c25519 and current.c25519 (both initially the same)" ZT_EOL_S); + } + + if ((previous.length() != (ZT_C25519_PUBLIC_KEY_LEN + ZT_C25519_PRIVATE_KEY_LEN))||(current.length() != (ZT_C25519_PUBLIC_KEY_LEN + ZT_C25519_PRIVATE_KEY_LEN))) { + fprintf(stderr,"FATAL: previous.c25519 or current.c25519 empty or invalid" ZT_EOL_S); + return 1; + } + C25519::Pair previousKP; + memcpy(previousKP.pub.data,previous.data(),ZT_C25519_PUBLIC_KEY_LEN); + memcpy(previousKP.priv.data,previous.data() + ZT_C25519_PUBLIC_KEY_LEN,ZT_C25519_PRIVATE_KEY_LEN); + C25519::Pair currentKP; + memcpy(currentKP.pub.data,current.data(),ZT_C25519_PUBLIC_KEY_LEN); + memcpy(currentKP.priv.data,current.data() + ZT_C25519_PUBLIC_KEY_LEN,ZT_C25519_PRIVATE_KEY_LEN); + + // ========================================================================= + // EDIT BELOW HERE + + std::vector roots; + + const uint64_t id = ZT_WORLD_ID_EARTH; + const uint64_t ts = 1567191349589ULL; // August 30th, 2019 + + //__PATCH_REPLACE__ + + // END WORLD DEFINITION + // ========================================================================= + + fprintf(stderr,"INFO: generating and signing id==%llu ts==%llu" ZT_EOL_S,(unsigned long long)id,(unsigned long long)ts); + + World nw = World::make(World::TYPE_PLANET,id,ts,currentKP.pub,roots,previousKP); + + Buffer outtmp; + nw.serialize(outtmp,false); + World testw; + testw.deserialize(outtmp,0); + if (testw != nw) { + fprintf(stderr,"FATAL: serialization test failed!" ZT_EOL_S); + return 1; + } + + OSUtils::writeFile("world.bin",std::string((const char *)outtmp.data(),outtmp.size())); + fprintf(stderr,"INFO: world.bin written with %u bytes of binary world data." ZT_EOL_S,outtmp.size()); + + fprintf(stdout,ZT_EOL_S); + fprintf(stdout,"#define ZT_DEFAULT_WORLD_LENGTH %u" ZT_EOL_S,outtmp.size()); + fprintf(stdout,"static const unsigned char ZT_DEFAULT_WORLD[ZT_DEFAULT_WORLD_LENGTH] = {"); + for(unsigned int i=0;i 0) + fprintf(stdout,","); + fprintf(stdout,"0x%.2x",(unsigned int)d[i]); + } + fprintf(stdout,"};" ZT_EOL_S); + + return 0; } \ No newline at end of file diff --git a/patch/patch.json b/patch/patch.json index a5476b0..73081d7 100644 --- a/patch/patch.json +++ b/patch/patch.json @@ -1,5 +1,5 @@ -{ - "stableEndpoints": [ - "82.157.68.236/9993" - ] -} +{ + "stableEndpoints": [ + "82.157.68.236/9993" + ] +} diff --git a/patch/patch.py b/patch/patch.py index f171fb4..8eeafdb 100644 --- a/patch/patch.py +++ b/patch/patch.py @@ -1,51 +1,51 @@ -import os -import json - - -def patch_moon(): - patch_data = dict() - with open("patch.json", "r") as f: - patch_data = json.load(f) - - moon = dict() - with open("moon.json", "r") as f: - moon = json.load(f) - - endpoint_patch = patch_data.get("stableEndpoints", []) - if len(endpoint_patch) == 0: - print("请配置endpoint!") - exit(1) - - moon["roots"][0]["stableEndpoints"] = endpoint_patch - - with open("moon.json", "w+") as f: - f.write(json.dumps(moon)) - - -def patch_world(): - moon = dict() - - file_moon = open("moon.json", "r") - moon = json.load(file_moon) - file_moon.close() - - middle = ''' - //China - roots.push_back(World::Root()); - roots.back().identity = Identity("{}");'''.format(moon["roots"][0]["identity"]) - - for i in moon["roots"][0]["stableEndpoints"]: - middle += '\n roots.back().stableEndpoints.push_back(InetAddress("{}"));'.format(i) - - with open("mkworld.cpp", "r") as cpp: - code = "".join(cpp.readlines()) - - with open("mknewworld.cpp", "w+") as cpp: - code = code.replace(" //__PATCH_REPLACE__", middle) - print(code) - cpp.write(code) - - -if __name__ == '__main__': - patch_moon() - patch_world() +import os +import json +from re import M + + +def get_moon(): + with open("/var/lib/zerotier-one/moon.json", "r") as f: + moon = json.load(f) + return moon + + +def get_patch(): + with open("/opt/patch/patch.json", "r") as f: + return json.load(f) + + +def patch(): + moon = get_moon() + patch = get_patch() + + identity = moon["roots"][0]["identity"] + moon["roots"][0]["stableEndpoints"] = patch["stableEndpoints"] + + # 修改moon + with open("/var/lib/zerotier-one/moon.json", "w") as f: + f.write(json.dumps(moon,sort_keys=True, indent=2)) + + print("修改后的moon") + print(moon) + + # 修改world + moon["roots"][0]["stableEndpoints"] = get_patch()["stableEndpoints"] + text = f"""// Los Angeles + roots.push_back(World::Root()); + roots.back().identity = Identity("{identity}"); +""" + + for i in get_patch()["stableEndpoints"]: + text += f'\n roots.back().stableEndpoints.push_back(InetAddress("{i}"));' + + # 生成文件 + with open("/opt/patch/mkworld.cpp", "r") as cpp: + world = "".join(cpp.readlines()) + world = world.replace("//__PATCH_REPLACE__", text) + + with open("/opt/ZeroTierOne/attic/world/mkworld.cpp", "w") as cpp: + cpp.write(world) + + +if __name__ == '__main__': + patch() diff --git a/server.sh b/server.sh deleted file mode 100644 index 0060a73..0000000 --- a/server.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh -echo "开始执行" -zerotier-one -d - -cd /opt/ztncui/src -npm start diff --git a/win_planet_ok.png b/win_planet_ok.png new file mode 100644 index 0000000000000000000000000000000000000000..fdd6b850e975d869cf6d9847109ed58edc8f63a5 GIT binary patch literal 27783 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