支持ARM系统,支持update (#145)

* stash

* no sense

* support arm

* refactorcode

* upgrade

* refactorcode

* format code

---------

Co-authored-by: xubiaolin <xubiaolin2014>
Co-authored-by: Your Name <>
This commit is contained in:
Markxu 2024-05-19 21:50:59 +08:00 committed by GitHub
parent 23856d8ff4
commit b3930029d3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 560 additions and 280 deletions

View File

@ -5,9 +5,9 @@ ARG TAG=main
ENV TAG=${TAG} ENV TAG=${TAG}
WORKDIR /app WORKDIR /app
ADD ./entrypoint.sh /app/entrypoint.sh ADD ./patch/entrypoint.sh /app/entrypoint.sh
ADD ./http_server.js /app/http_server.js ADD ./patch/http_server.js /app/http_server.js
ADD ./mkmoonworld-x86_64 /app/mkmoonworld-x86_64 ADD ./patch/mkworld_custom.cpp /app/patch/mkworld_custom.cpp
# init tool # init tool
RUN set -x\ RUN set -x\
@ -29,7 +29,15 @@ RUN set -x\
&& echo "make success!"\ && echo "make success!"\
; zerotier-one -d \ ; zerotier-one -d \
; sleep 5s && ps -ef |grep zerotier-one |grep -v grep |awk '{print $1}' |xargs kill -9\ ; sleep 5s && ps -ef |grep zerotier-one |grep -v grep |awk '{print $1}' |xargs kill -9\
&& echo "zerotier-one init success!" && echo "zerotier-one init success!"\
&& cd ./attic/world \
&& cp /app/patch/mkworld_custom.cpp .\
&& mv mkworld.cpp mkworld.cpp.bak \
&& mv mkworld_custom.cpp mkworld.cpp \
&& sh build.sh \
&& mv mkworld /var/lib/zerotier-one\
&& echo "mkworld build success!"
#make ztncui #make ztncui
@ -53,7 +61,7 @@ ENV ZT_PORT=9994
ENV API_PORT=3443 ENV API_PORT=3443
ENV FILE_SERVER_PORT=3000 ENV FILE_SERVER_PORT=3000
ENV GH_MIRROR="https://ghproxy.imoyuapp.win/" ENV GH_MIRROR="https://mirror.ghproxy.com/"
ENV FILE_KEY='' ENV FILE_KEY=''
ENV TZ=Asia/Shanghai ENV TZ=Asia/Shanghai
@ -63,9 +71,8 @@ COPY --from=builder /var/lib/zerotier-one /bak/zerotier-one
COPY --from=builder /app/ZeroTierOne/zerotier-one /usr/sbin/zerotier-one COPY --from=builder /app/ZeroTierOne/zerotier-one /usr/sbin/zerotier-one
COPY --from=builder /app/entrypoint.sh /app/entrypoint.sh COPY --from=builder /app/entrypoint.sh /app/entrypoint.sh
COPY --from=builder /app/http_server.js /app/http_server.js COPY --from=builder /app/http_server.js /app/http_server.js
COPY --from=builder /app/mkmoonworld-x86_64 /app/mkmoonworld-x86_64
RUN set -x ;sed -i 's/dl-cdn.alpinelinux.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apk/repositories \ RUN set -x \
&& apk update \ && apk update \
&& apk add --no-cache npm curl jq openssl\ && apk add --no-cache npm curl jq openssl\
&& mkdir /app/config -p && mkdir /app/config -p
@ -73,4 +80,4 @@ RUN set -x ;sed -i 's/dl-cdn.alpinelinux.org/mirrors.tuna.tsinghua.edu.cn/g' /et
VOLUME [ "/app/dist","/app/ztncui","/var/lib/zerotier-one","/app/config"] VOLUME [ "/app/dist","/app/ztncui","/var/lib/zerotier-one","/app/config"]
CMD ["/bin/sh","/app/entrypoint.sh"] CMD ["/bin/sh","/app/entrypoint.sh"]

View File

@ -1,3 +1,11 @@
#!/bin/bash #!/bin/bash
docker build --build-arg TAG=1.12.2 -t xubiaolin/zerotier-planet:latest . USER=zerotier
REPO=ZeroTierOne
latest_tag=$(curl -s "https://api.github.com/repos/$USER/$REPO/tags" | jq -r '.[].name' | grep -E "^[0-9]+\.[0-9]+\.[0-9]+$" | sort -V | tail -n 1)
echo "Latest tag for $USER/$REPO matching latest is: $latest_tag"
docker build --build-arg TAG="$latest_tag" -t "xubiaolin/zerotier-planet:$latest_tag" .
docker tag "xubiaolin/zerotier-planet:$latest_tag" "xubiaolin/zerotier-planet:latest"

341
deploy.sh
View File

@ -1,116 +1,131 @@
#!/bin/bash #!/bin/bash
CONTAINER_NAME=myztplanet
# 如果是centos 且内核版本小于5.*,提示内核版本太低 CONTAINER_NAME="myztplanet"
kernel_check(){ ZEROTIER_PATH="$(pwd)/data/zerotier"
os_name=$(cat /etc/os-release | grep ^ID= | cut -d'=' -f2) CONFIG_PATH="${ZEROTIER_PATH}/config"
DIST_PATH="${ZEROTIER_PATH}/dist"
ZTNCUI_PATH="${ZEROTIER_PATH}/ztncui"
DOCKER_IMAGE="xubiaolin/zerotier-planet:latest"
print_message() {
local message=$1
local color_code=$2
echo -e "\033[${color_code}m${message}\033[0m"
}
# 检查内核版本
kernel_check() {
os_name=$(grep ^ID= /etc/os-release | cut -d'=' -f2 | tr -d '"')
kernel_version=$(uname -r | cut -d'.' -f1) kernel_version=$(uname -r | cut -d'.' -f1)
if [[ "$kernel_version" -lt 5 ]]; then if ((kernel_version < 5)); then
if [[ "$os_name" == "\"centos\"" ]]; then if [[ "$os_name" == "centos" ]]; then
echo -e "\033[31m内核版本太低,请在菜单中选择CentOS内核升级\033[0m" print_message "内核版本太低,请在菜单中选择CentOS内核升级" "31"
exit 1
else else
echo -e "\033[31m请自行升级系统内核到5.*及其以上版本\033[0m" print_message "请自行升级系统内核到5.*及其以上版本" "31"
exit 1
fi fi
exit 1
else else
echo "当前内核版本为:$kernel_version" print_message "系统和内核版本检查通过,当前内核版本为:$kernel_version" "32"
echo -e "\033[32m系统和内核版本检查通过。\033[0m"
fi fi
} }
update_centos_kernal(){ # 升级CentOS内核
update_centos_kernel() {
echo "请注意备份数据,升级内核有风险" echo "请注意备份数据,升级内核有风险"
read -p "是否继续升级内核?(y/n)" continue_update read -p "是否继续升级内核?(y/n) " continue_update
continue_update=${continue_update:-n}
if [[ "$continue_update" =~ ^[Yy]$ ]]; then if [[ "$continue_update" =~ ^[Yy]$ ]]; then
echo "如果配置较低,可能升级时间较长,请耐心等待!开始升级内核..." echo "升级时间较长,请耐心等待!开始升级内核..."
yum update -y yum update -y
rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
yum install https://www.elrepo.org/elrepo-release-7.el7.elrepo.noarch.rpm -y yum install -y https://www.elrepo.org/elrepo-release-7.el7.elrepo.noarch.rpm
yum --disablerepo="*" --enablerepo="elrepo-kernel" list available yum --disablerepo="*" --enablerepo="elrepo-kernel" install -y kernel-lt-devel kernel-lt
yum --enablerepo=elrepo-kernel install kernel-lt-devel kernel-lt -y
sudo awk -F\' '$1=="menuentry " {print i++ " : " $2}' /etc/grub2.cfg sudo awk -F\' '$1=="menuentry " {print i++ " : " $2}' /etc/grub2.cfg
grub2-set-default 0 grub2-set-default 0
grub2-mkconfig -o /boot/grub2/grub.cfg grub2-mkconfig -o /boot/grub2/grub.cfg
read -p "内核升级完成,请重启系统,是否立刻重启?(y/n) " reboot
read -p "内核升级完成,请重启系统,是否立刻重启?(y/n)" reboot
reboot=${reboot:-n}
if [[ "$reboot" =~ ^[Yy]$ ]]; then if [[ "$reboot" =~ ^[Yy]$ ]]; then
reboot now reboot now
else else
echo "已取消重启" echo "已取消重启"
exit 0 exit 0
fi fi
echo "内核升级完成,请重启系统"
exit 0
else else
echo "已取消升级内核" echo "已取消升级内核"
exit 0 exit 0
fi fi
} }
# 安装lsof工具
install_lsof() { install_lsof() {
if [ ! -f "/usr/bin/lsof" ]; then if ! command -v lsof &>/dev/null; then
echo "开始安装lsof工具..." echo "开始安装lsof工具..."
[ -f "/usr/bin/apt" ] && ( if command -v apt &>/dev/null; then
apt update apt update && apt install -y lsof
apt install -y lsof elif command -v yum &>/dev/null; then
) yum install -y lsof
[ -f "/usr/bin/yum" ] && yum install -y lsof fi
fi fi
} }
# 检查端口是否被占用
check_port() { check_port() {
local port=$1 local port=$1
if [ $(lsof -i:${port} | wc -l) -gt 0 ]; then if lsof -i:${port} &>/dev/null; then
echo "端口${port}已被占用,请重新输入" echo "端口${port}已被占用,请重新输入"
exit 1 exit 1
fi fi
} }
# 读取端口号
read_port() { read_port() {
local port local port
local prompt=$1 local prompt=$1
read -p "${prompt}" port while :; do
while [[ ! "$port" =~ ^[0-9]+$ ]]; do read -p "${prompt}" port
read -p "端口号必须是数字,请重新输入: " port [[ "$port" =~ ^[0-9]+$ ]] && break
echo "端口号必须是数字,请重新输入: "
done done
check_port $port check_port $port
echo $port echo $port
} }
# 获取IP地址
configure_ip() {
ipv4=$(curl -s https://ipv4.icanhazip.com/)
ipv6=$(curl -s https://ipv6.icanhazip.com/)
echo "获取到的IPv4地址为: $ipv4"
echo "获取到的IPv6地址为: $ipv6"
}
# 安装zerotier-planet
install() { install() {
kernel_check kernel_check
echo "开始安装如果你已经安装了将会删除旧的数据10s后开始安装..." if docker inspect ${CONTAINER_NAME} &>/dev/null; then
echo "容器${CONTAINER_NAME}已经存在"
read -p "是否更新版本?(y/n) " update_version
if [[ "$update_version" =~ ^[Yy]$ ]]; then
upgrade
exit 0
fi
fi
echo "开始安装如果你已经安装了将会删除旧的数据10秒后开始安装..."
sleep 10 sleep 10
install_lsof install_lsof
docker rm -f ${CONTAINER_NAME} docker rm -f ${CONTAINER_NAME} || true
rm -rf $(pwd)/data/zerotier rm -rf ${ZEROTIER_PATH}
ZT_PORT=$(read_port "请输入zerotier-planet要使用的端口号,例如9994: ") ZT_PORT=$(read_port "请输入zerotier-planet要使用的端口号例如9994: ")
API_PORT=$(read_port "请输入zerotier-planet的API端口号,例如3443: ") API_PORT=$(read_port "请输入zerotier-planet的API端口号例如3443: ")
FILE_PORT=$(read_port "请输入zerotier-planet的FILE端口号,例如3000: ") FILE_PORT=$(read_port "请输入zerotier-planet的FILE端口号例如3000: ")
configure_ip() { read -p "是否自动获取公网IP地址?(y/n) " use_auto_ip
ipv4=$(curl -s https://ipv4.icanhazip.com/)
ipv6=$(curl -s https://ipv6.icanhazip.com/)
echo "获取到的IPv4地址为: $ipv4"
echo "获取到的IPv6地址为: $ipv6"
}
read -p "是否自动获取公网IP地址?(y/n)" use_auto_ip
use_auto_ip=${use_auto_ip:-y}
if [[ "$use_auto_ip" =~ ^[Yy]$ ]]; then if [[ "$use_auto_ip" =~ ^[Yy]$ ]]; then
configure_ip configure_ip
read -p "是否使用上面获取到的IP地址?(y/n) " use_auto_ip_result
read -p "是否使用上面获取到的IP地址?(y/n)" use_auto_ip_result
use_auto_ip_result=${use_auto_ip_result:-y}
if [[ "$use_auto_ip_result" =~ ^[Nn]$ ]]; then if [[ "$use_auto_ip_result" =~ ^[Nn]$ ]]; then
read -p "请输入IPv4地址: " ipv4 read -p "请输入IPv4地址: " ipv4
read -p "请输入IPv6地址(可留空): " ipv6 read -p "请输入IPv6地址(可留空): " ipv6
@ -139,32 +154,17 @@ install() {
-e ZT_PORT=${ZT_PORT} \ -e ZT_PORT=${ZT_PORT} \
-e API_PORT=${API_PORT} \ -e API_PORT=${API_PORT} \
-e FILE_SERVER_PORT=${FILE_PORT} \ -e FILE_SERVER_PORT=${FILE_PORT} \
-v $(pwd)/data/zerotier/dist:/app/dist \ -v ${DIST_PATH}:/app/dist \
-v $(pwd)/data/zerotier/ztncui:/app/ztncui \ -v ${ZTNCUI_PATH}:/app/ztncui \
-v $(pwd)/data/zerotier/one:/var/lib/zerotier-one -v $(pwd)/data/zerotier/config:/app/config --restart unless-stopped xubiaolin/zerotier-planet:latest -v ${ZEROTIER_PATH}/one:/var/lib/zerotier-one \
-v ${CONFIG_PATH}:/app/config \
if [ $? -ne 0 ]; then --restart unless-stopped \
echo "安装失败" ${DOCKER_IMAGE}
exit 1
fi
sleep 10 sleep 10
retrieve_keys() { KEY=$(docker exec -it ${CONTAINER_NAME} sh -c 'cat /app/config/file_server.key' | tr -d '\r')
KEY=$(docker exec -it ${CONTAINER_NAME} sh -c 'cat /app/config/file_server.key') MOON_NAME=$(docker exec -it ${CONTAINER_NAME} sh -c 'ls /app/dist | grep moon' | tr -d '\r')
MOON_NAME=$(docker exec -it ${CONTAINER_NAME} sh -c 'ls /app/dist | grep moon')
}
retrieve_keys
clean_vars() {
ipv4=$(echo $ipv4 | tr -d '\r')
FILE_PORT=$(echo $FILE_PORT | tr -d '\r')
KEY=$(echo $KEY | tr -d '\r')
MOON_NAME=$(echo $MOON_NAME | tr -d '\r')
}
clean_vars
echo "安装完成" echo "安装完成"
echo "---------------------------" echo "---------------------------"
@ -173,26 +173,23 @@ install() {
echo "默认密码password" echo "默认密码password"
echo "请及时修改密码" echo "请及时修改密码"
echo "---------------------------" echo "---------------------------"
echo "moon配置和planet配置在 ${DIST_PATH} 目录下"
echo "moon配置和planet配置在 $(pwd)/data/zerotier/dist 目录下" echo "moons 文件下载: http://${ipv4}:${FILE_PORT}/${MOON_NAME}?key=${KEY} "
echo -e "moons 文件下载: http://${ipv4}:${FILE_PORT}/${MOON_NAME}?key=${KEY} " echo "planet文件下载 http://${ipv4}:${FILE_PORT}/planet?key=${KEY} "
echo -e "planet文件下载 http://${ipv4}:${FILE_PORT}/planet?key=${KEY} "
echo "---------------------------" echo "---------------------------"
echo "请放行以下端口${ZT_PORT}/tcp,${ZT_PORT}/udp${API_PORT}/tcp${FILE_PORT}/tcp" echo "请放行以下端口:${ZT_PORT}/tcp,${ZT_PORT}/udp${API_PORT}/tcp${FILE_PORT}/tcp"
echo "---------------------------" echo "---------------------------"
} }
info() { install_from_config() {
docker inspect ${CONTAINER_NAME} >/dev/null 2>&1 if [ ! -d "${CONFIG_PATH}" ] || [ ! "$(ls -A ${CONFIG_PATH})" ]; then
if [ $? -ne 0 ]; then echo "配置文件目录不存在或为空,请先上传配置文件"
echo "容器${CONTAINER_NAME}不存在,请先安装"
exit 1 exit 1
fi fi
extract_config() { extract_config() {
local config_name=$1 local config_name=$1
docker exec -it ${CONTAINER_NAME} sh -c "cat /app/config/${config_name}" | tr -d '\r' cat ${CONFIG_PATH}/${config_name} | tr -d '\r'
} }
ipv4=$(extract_config "ip_addr4") ipv4=$(extract_config "ip_addr4")
@ -201,21 +198,96 @@ info() {
FILE_PORT=$(extract_config "file_server.port") FILE_PORT=$(extract_config "file_server.port")
ZT_PORT=$(extract_config "zerotier-one.port") ZT_PORT=$(extract_config "zerotier-one.port")
KEY=$(extract_config "file_server.key") KEY=$(extract_config "file_server.key")
MOON_NAME=$(ls ${DIST_PATH}/ | grep moon | tr -d '\r')
MOON_NAME=$(docker exec -it ${CONTAINER_NAME} sh -c "ls /app/dist | grep moon" | tr -d '\r')
echo "---------------------------" echo "---------------------------"
echo "以下端口的tcp和udp协议请放行${ZT_PORT}${API_PORT}${FILE_PORT}" echo "ipv4:${ipv4}"
echo "ipv6:${ipv6}"
echo "API_PORT:${API_PORT}"
echo "FILE_PORT:${FILE_PORT}"
echo "ZT_PORT:${ZT_PORT}"
echo "KEY:${KEY}"
echo "MOON_NAME:${MOON_NAME}"
echo "---------------------------"
docker run -d \
--name ${CONTAINER_NAME} \
-p ${ZT_PORT}:${ZT_PORT} \
-p ${ZT_PORT}:${ZT_PORT}/udp \
-p ${API_PORT}:${API_PORT} \
-p ${FILE_PORT}:${FILE_PORT} \
-e IP_ADDR4=${ipv4} \
-e IP_ADDR6=${ipv6} \
-e ZT_PORT=${ZT_PORT} \
-e API_PORT=${API_PORT} \
-e FILE_SERVER_PORT=${FILE_PORT} \
-v ${DIST_PATH}:/app/dist \
-v ${ZTNCUI_PATH}:/app/ztncui \
-v ${ZEROTIER_PATH}/one:/var/lib/zerotier-one \
-v ${CONFIG_PATH}:/app/config \
--restart unless-stopped \
${DOCKER_IMAGE}
}
upgrade() {
if ! docker inspect ${CONTAINER_NAME} &>/dev/null; then
echo "容器${CONTAINER_NAME}不存在,请先安装"
exit 1
fi
docker pull ${DOCKER_IMAGE}
new_image_id=$(docker inspect ${DOCKER_IMAGE} --format='{{.Id}}')
old_image_id=$(docker inspect ${CONTAINER_NAME} --format='{{.Image}}')
if [ "$new_image_id" == "$old_image_id" ]; then
print_message "当前版本已经是最新版本" "32"
exit 0
else
echo "发现新版本,开始升级...new_image_id:${new_image_id},old_image_id:${old_image_id}"
echo "更新可能存在风险请手动备份data目录中的数据,谨慎操作"
read -p "是否继续升级?(y/n) " continue_upgrade
if [[ ! "$continue_upgrade" =~ ^[Yy]$ ]]; then
echo "已取消升级"
exit 0
fi
fi
echo "开始升级将会删除旧的容器10秒后开始升级..."
sleep 10
docker rm -f ${CONTAINER_NAME} || true
install_from_config
}
info() {
if ! docker inspect ${CONTAINER_NAME} &>/dev/null; then
echo "容器${CONTAINER_NAME}不存在,请先安装"
exit 1
fi
extract_config() {
local config_name=$1
cat ${CONFIG_PATH}/${config_name} | tr -d '\r'
}
ipv4=$(extract_config "ip_addr4")
ipv6=$(extract_config "ip_addr6")
API_PORT=$(extract_config "ztncui.port")
FILE_PORT=$(extract_config "file_server.port")
ZT_PORT=$(extract_config "zerotier-one.port")
KEY=$(extract_config "file_server.key")
MOON_NAME=$(ls ${DIST_PATH}/ | grep moon | tr -d '\r')
echo "---------------------------"
print_message "以下端口的tcp和udp协议请放行${ZT_PORT}${API_PORT}${FILE_PORT}" "32"
echo "---------------------------" echo "---------------------------"
echo "请访问 http://${ipv4}:${API_PORT} 进行配置" echo "请访问 http://${ipv4}:${API_PORT} 进行配置"
echo "默认用户名admin" echo "默认用户名admin"
echo "默认密码password" echo "默认密码password"
echo "请及时修改密码" echo "请及时修改密码"
echo "---------------------------" echo "---------------------------"
echo "moon配置和planet配置在 $(pwd)/data/zerotier/dist 目录下" print_message "moon配置和planet配置在 ${DIST_PATH} 目录下" "32"
echo "" print_message "planet文件下载 http://${ipv4}:${FILE_PORT}/planet?key=${KEY} " "32"
echo "planet文件下载 http://${ipv4}:${FILE_PORT}/planet?key=${KEY} " print_message "moon文件下载 http://${ipv4}:${FILE_PORT}/${MOON_NAME}?key=${KEY} " "32"
echo "moon文件下载 http://${ipv4}:${FILE_PORT}/${MOON_NAME}?key=${KEY} "
} }
uninstall() { uninstall() {
@ -223,71 +295,16 @@ uninstall() {
docker stop ${CONTAINER_NAME} docker stop ${CONTAINER_NAME}
docker rm ${CONTAINER_NAME} docker rm ${CONTAINER_NAME}
docker rmi xubiaolin/zerotier-planet:latest docker rmi ${DOCKER_IMAGE}
read -p "是否删除数据?(y/n)" delete_data read -p "是否删除数据?(y/n) " delete_data
delete_data=${delete_data:-n}
if [[ "$delete_data" =~ ^[Yy]$ ]]; then if [[ "$delete_data" =~ ^[Yy]$ ]]; then
rm -rf $(pwd)/data/zerotier rm -rf ${ZEROTIER_PATH}
fi fi
echo "卸载完成" echo "卸载完成"
} }
# update() {
# docker inspect ${CONTAINER_NAME} >/dev/null 2>&1
# if [ $? -ne 0 ]; then
# echo "容器${CONTAINER_NAME}不存在,请先安装"
# exit 1
# fi
# echo "如果用于生产环境请先备份数据不建议直接更新10s后开始更新..."
# sleep 10
# if [ ! -d "$(pwd)/data/zerotier" ]; then
# echo "目录$(pwd)/data/zerotier不存在无法更新"
# exit 0
# fi
# extract_config() {
# local config_name=$1
# docker exec -it ${CONTAINER_NAME} sh -c "cat /app/config/${config_name}" | tr -d '\r'
# }
# ipv4=$(extract_config "ip_addr4")
# ipv6=$(extract_config "ip_addr6")
# API_PORT=$(extract_config "ztncui.port")
# FILE_PORT=$(extract_config "ztncui.port")
# ZT_PORT=$(extract_config "zerotier-one.port")
# echo "---------------------------"
# echo "ipv4地址为${ipv4}"
# echo "ipv6地址为${ipv6}"
# echo "API端口号为${API_PORT}"
# echo "FILE端口号为${FILE_PORT}"
# echo "ZT端口号为${ZT_PORT}"
# docker stop ${CONTAINER_NAME}
# docker rm ${CONTAINER_NAME}
# docker pull xubiaolin/zerotier-planet:latest
# docker run -d --name ${CONTAINER_NAME} -p ${ZT_PORT}:${ZT_PORT} \
# -p ${ZT_PORT}:${ZT_PORT}/udp \
# -p ${API_PORT}:${API_PORT} \
# -p ${FILE_PORT}:${FILE_PORT} \
# -e IP_ADDR4=${ipv4} \
# -e IP_ADDR6=${ipv6} \
# -e ZT_PORT=${ZT_PORT} \
# -e API_PORT=${API_PORT} \
# -e FILE_SERVER_PORT=${FILE_PORT} \
# -v $(pwd)/data/zerotier/dist:/app/dist \
# -v $(pwd)/data/zerotier/ztncui:/app/ztncui \
# -v $(pwd)/data/zerotier/one:/var/lib/zerotier-one \
# -v $(pwd)/data/zerotier/config:/app/config \
# --restart unless-stopped \
# xubiaolin/zerotier-planet:latest
# }
resetpwd() { resetpwd() {
docker exec -it ${CONTAINER_NAME} sh -c 'cp /app/ztncui/src/etc/default.passwd /app/ztncui/src/etc/passwd' docker exec -it ${CONTAINER_NAME} sh -c 'cp /app/ztncui/src/etc/default.passwd /app/ztncui/src/etc/passwd'
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
@ -311,21 +328,21 @@ menu() {
echo "欢迎使用zerotier-planet脚本请选择需要执行的操作" echo "欢迎使用zerotier-planet脚本请选择需要执行的操作"
echo "1. 安装" echo "1. 安装"
echo "2. 卸载" echo "2. 卸载"
# echo "3. 更新" echo "3. 更新"
echo "4. 查看信息" echo "4. 查看信息"
echo "5. 重置密码" echo "5. 重置密码"
echo "6. CentOS内核升级" echo "6. CentOS内核升级"
echo "0. 退出" echo "0. 退出"
read -p "请输入数字:" num read -p "请输入数字:" num
case "$num" in case "$num" in
[1]) install ;; 1) install ;;
[2]) uninstall ;; 2) uninstall ;;
# [3]) update ;; 3) upgrade ;;
[4]) info ;; 4) info ;;
[5]) resetpwd ;; 5) resetpwd ;;
[6]) update_centos_kernal ;; 6) update_centos_kernel ;;
[0]) exit ;; 0) exit ;;
*) echo "请输入正确数字 [1-5]" ;; *) echo "请输入正确数字 [0-6]" ;;
esac esac
} }

View File

@ -1,109 +0,0 @@
#!/bin/sh
set -x
function start() {
echo "start ztncui and zerotier"
cd /var/lib/zerotier-one && ./zerotier-one -p$(cat /app/config/zerotier-one.port) -d || exit 1
nohup node /app/http_server.js &> /app/server.log &
cd /app/ztncui/src && npm start || exit 1
}
function check_file_server(){
if [ ! -f "/app/config/file_server.port" ]; then
echo "file_server.port is not exist, generate it"
echo "${FILE_SERVER_PORT}" >/app/config/file_server.port
echo "${FILE_SERVER_PORT}"
else
echo "file_server.port is exist, read it"
FILE_SERVER_PORT=$(cat /app/config/file_server.port)
echo "${FILE_SERVER_PORT}"
fi
}
function check_zerotier() {
mkdir -p /var/lib/zerotier-one
if [ "$(ls -A /var/lib/zerotier-one)" ]; then
echo "/var/lib/zerotier-one is not empty, start directly"
else
mkdir -p /app/config
echo "/var/lib/zerotier-one is empty, init data"
echo "${ZT_PORT}" >/app/config/zerotier-one.port
cp -r /bak/zerotier-one/* /var/lib/zerotier-one/
cd /var/lib/zerotier-one
echo "start mkmoonworld"
openssl rand -hex 16 > authtoken.secret
./zerotier-idtool generate identity.secret identity.public
./zerotier-idtool initmoon identity.public >moon.json
if [ -z "$IP_ADDR4" ]; then IP_ADDR4=$(curl -s https://ipv4.icanhazip.com/); fi
if [ -z "$IP_ADDR6" ]; then IP_ADDR6=$(curl -s https://ipv6.icanhazip.com/); fi
echo "IP_ADDR4=$IP_ADDR4"
echo "IP_ADDR6=$IP_ADDR6"
ZT_PORT=$(cat /app/config/zerotier-one.port)
echo "ZT_PORT=$ZT_PORT"
if [ -z "$IP_ADDR4" ]; then stableEndpoints="[\"$IP_ADDR6/${ZT_PORT}\"]"; fi
if [ -z "$IP_ADDR6" ]; then stableEndpoints="[\"$IP_ADDR4/${ZT_PORT}\"]"; fi
if [ -n "$IP_ADDR4" ] && [ -n "$IP_ADDR6" ]; then stableEndpoints="[\"$IP_ADDR4/${ZT_PORT}\",\"$IP_ADDR6/${ZT_PORT}\"]"; fi
if [ -z "$IP_ADDR4" ] && [ -z "$IP_ADDR6" ]; then
echo "IP_ADDR4 and IP_ADDR6 are both empty!"
exit 1
fi
echo "$IP_ADDR4">/app/config/ip_addr4
echo "$IP_ADDR6">/app/config/ip_addr6
echo "stableEndpoints=$stableEndpoints"
jq --argjson newEndpoints "$stableEndpoints" '.roots[0].stableEndpoints = $newEndpoints' moon.json >temp.json && mv temp.json moon.json
./zerotier-idtool genmoon moon.json && mkdir -p moons.d && cp ./*.moon ./moons.d
cp /app/mkmoonworld-x86_64 ./mkmoonworld-x86_64
chmod +x ./mkmoonworld-x86_64
./mkmoonworld-x86_64 moon.json
if [ $? -ne 0 ]; then
echo "mkmoonworld failed!"
exit 1
fi
mkdir -p /app/dist/
mv world.bin /app/dist/planet
cp *.moon /app/dist/
echo -e "mkmoonworld success!\n"
fi
}
function check_ztncui() {
mkdir -p /app/ztncui
if [ "$(ls -A /app/ztncui)" ]; then
echo "${API_PORT}" >/app/config/ztncui.port
echo "/app/ztncui is not empty, start directly"
else
echo "/app/ztncui is empty, init data"
cp -r /bak/ztncui/* /app/ztncui/
echo "config ztncui"
mkdir -p /app/config
echo "${API_PORT}" >/app/config/ztncui.port
cd /app/ztncui/src
echo "HTTP_PORT=${API_PORT}" >.env &&
echo 'NODE_ENV=production' >>.env &&
echo 'HTTP_ALL_INTERFACES=true' >>.env &&
echo "ZT_ADDR=localhost:${ZT_PORT}" >>.env && echo "${ZT_PORT}" >/app/config/zerotier-one.port &&
cp -v etc/default.passwd etc/passwd && TOKEN=$(cat /var/lib/zerotier-one/authtoken.secret) &&
echo "ZT_TOKEN=$TOKEN" >>.env &&
echo "make ztncui success!"
fi
}
check_file_server
check_zerotier
check_ztncui
start

Binary file not shown.

125
patch/entrypoint.sh Executable file
View File

@ -0,0 +1,125 @@
#!/bin/sh
set -x
# 配置路径和端口
ZEROTIER_PATH="/var/lib/zerotier-one"
APP_PATH="/app"
CONFIG_PATH="${APP_PATH}/config"
BACKUP_PATH="/bak"
ZTNCUI_PATH="${APP_PATH}/ztncui"
ZTNCUI_SRC_PATH="${ZTNCUI_PATH}/src"
# 启动 ZeroTier 和 ztncui
function start() {
echo "Start ztncui and zerotier"
cd $ZEROTIER_PATH && ./zerotier-one -p$(cat ${CONFIG_PATH}/zerotier-one.port) -d || exit 1
nohup node ${APP_PATH}/http_server.js &> ${APP_PATH}/server.log &
cd $ZTNCUI_SRC_PATH && npm start || exit 1
}
# 检查文件服务器端口配置文件
function check_file_server() {
if [ ! -f "${CONFIG_PATH}/file_server.port" ]; then
echo "file_server.port does not exist, generating it"
echo "${FILE_SERVER_PORT}" > ${CONFIG_PATH}/file_server.port
else
echo "file_server.port exists, reading it"
FILE_SERVER_PORT=$(cat ${CONFIG_PATH}/file_server.port)
fi
echo "${FILE_SERVER_PORT}"
}
# 初始化 ZeroTier 数据
function init_zerotier_data() {
echo "Initializing ZeroTier data"
echo "${ZT_PORT}" > ${CONFIG_PATH}/zerotier-one.port
cp -r ${BACKUP_PATH}/zerotier-one/* $ZEROTIER_PATH
cd $ZEROTIER_PATH
openssl rand -hex 16 > authtoken.secret
./zerotier-idtool generate identity.secret identity.public
./zerotier-idtool initmoon identity.public > moon.json
IP_ADDR4=${IP_ADDR4:-$(curl -s https://ipv4.icanhazip.com/)}
IP_ADDR6=${IP_ADDR6:-$(curl -s https://ipv6.icanhazip.com/)}
echo "IP_ADDR4=$IP_ADDR4"
echo "IP_ADDR6=$IP_ADDR6"
ZT_PORT=$(cat ${CONFIG_PATH}/zerotier-one.port)
echo "ZT_PORT=$ZT_PORT"
if [ -n "$IP_ADDR4" ] && [ -n "$IP_ADDR6" ]; then
stableEndpoints="[\"$IP_ADDR4/${ZT_PORT}\",\"$IP_ADDR6/${ZT_PORT}\"]"
elif [ -n "$IP_ADDR4" ]; then
stableEndpoints="[\"$IP_ADDR4/${ZT_PORT}\"]"
elif [ -n "$IP_ADDR6" ]; then
stableEndpoints="[\"$IP_ADDR6/${ZT_PORT}\"]"
else
echo "IP_ADDR4 and IP_ADDR6 are both empty!"
exit 1
fi
echo "$IP_ADDR4" > ${CONFIG_PATH}/ip_addr4
echo "$IP_ADDR6" > ${CONFIG_PATH}/ip_addr6
echo "stableEndpoints=$stableEndpoints"
jq --argjson newEndpoints "$stableEndpoints" '.roots[0].stableEndpoints = $newEndpoints' moon.json > temp.json && mv temp.json moon.json
./zerotier-idtool genmoon moon.json && mkdir -p moons.d && cp ./*.moon ./moons.d
./mkworld
if [ $? -ne 0 ]; then
echo "mkmoonworld failed!"
exit 1
fi
mkdir -p ${APP_PATH}/dist/
mv world.bin ${APP_PATH}/dist/planet
cp *.moon ${APP_PATH}/dist/
echo "mkmoonworld success!"
}
# 检查并初始化 ZeroTier
function check_zerotier() {
mkdir -p $ZEROTIER_PATH
if [ "$(ls -A $ZEROTIER_PATH)" ]; then
echo "$ZEROTIER_PATH is not empty, starting directly"
else
init_zerotier_data
fi
}
# 初始化 ztncui 数据
function init_ztncui_data() {
echo "Initializing ztncui data"
cp -r ${BACKUP_PATH}/ztncui/* $ZTNCUI_PATH
echo "Configuring ztncui"
mkdir -p ${CONFIG_PATH}
echo "${API_PORT}" > ${CONFIG_PATH}/ztncui.port
cd $ZTNCUI_SRC_PATH
echo "HTTP_PORT=${API_PORT}" > .env
echo 'NODE_ENV=production' >> .env
echo 'HTTP_ALL_INTERFACES=true' >> .env
echo "ZT_ADDR=localhost:${ZT_PORT}" >> .env
cp -v etc/default.passwd etc/passwd
TOKEN=$(cat ${ZEROTIER_PATH}/authtoken.secret)
echo "ZT_TOKEN=$TOKEN" >> .env
echo "ztncui configuration successful!"
}
# 检查并初始化 ztncui
function check_ztncui() {
mkdir -p $ZTNCUI_PATH
if [ "$(ls -A $ZTNCUI_PATH)" ]; then
echo "${API_PORT}" > ${CONFIG_PATH}/ztncui.port
echo "$ZTNCUI_PATH is not empty, starting directly"
else
init_ztncui_data
fi
}
check_file_server
check_zerotier
check_ztncui
start

232
patch/mkworld_custom.cpp Normal file
View File

@ -0,0 +1,232 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
/*
* 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <nlohmann/json.hpp>
#include <string>
#include <vector>
#include <algorithm>
#include <node/Constants.hpp>
#include <node/World.hpp>
#include <node/C25519.hpp>
#include <node/Identity.hpp>
#include <node/InetAddress.hpp>
#include <osdep/OSUtils.hpp>
using namespace ZeroTier;
using json = nlohmann::json;
void printHelp() {
printf("Usage: mkworld [options]\n");
printf("Options:\n");
printf(" -h, --help Display this help message\n");
printf(" -j, --json2bin Convert from JSON file to world.bin\n");
printf(" -b, --bin2json Convert from world.bin to JSON format\n");
}
int jsonToBinary() {
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<World::Root> roots;
const uint64_t id = ZT_WORLD_ID_EARTH;
const uint64_t ts = 1567191349589ULL; // August 30th, 2019
std::string fileContent;
if (!OSUtils::readFile("moon.json", fileContent)) {
fprintf(stderr, "Failed to open config file." ZT_EOL_S);
return 1;
}
// 解析JSON数据
json config = json::parse(fileContent);
for (auto& root : config["roots"]) {
roots.push_back(World::Root());
roots.back().identity = Identity(root["identity"].get<std::string>().c_str());
for (auto& endpoint : root["stableEndpoints"]) {
roots.back().stableEndpoints.push_back(InetAddress(endpoint.get<std::string>().c_str()));
}
}
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<ZT_WORLD_MAX_SERIALIZED_LENGTH> 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 < outtmp.size(); ++i) {
const unsigned char* d = (const unsigned char*)outtmp.data();
if (i > 0)
fprintf(stdout, ",");
fprintf(stdout, "0x%.2x", (unsigned int)d[i]);
}
fprintf(stdout, "};" ZT_EOL_S);
return 0;
}
void binaryToJson() {
// Read world.bin file into memory
std::string binContent;
if (!OSUtils::readFile("world.bin", binContent)) {
fprintf(stderr, "Failed to open world.bin file." ZT_EOL_S);
return;
}
// Deserialize the binary data into a World object
Buffer<ZT_WORLD_MAX_SERIALIZED_LENGTH> binBuffer(binContent.data(), binContent.size());
World world;
if (!world.deserialize(binBuffer, 0)) {
fprintf(stderr, "Failed to deserialize world.bin content." ZT_EOL_S);
return;
}
// Create a JSON object to store the world data
json worldJson;
// Add roots array to the JSON object
json rootsJson;
for (const auto& root : world.roots()) {
json rootJson;
// Add identity to the root JSON object
char identityStr[ZT_IDENTITY_STRING_BUFFER_LENGTH];
root.identity.toString(true, identityStr); // Include private key
rootJson["identity"] = identityStr;
// Add stableEndpoints array to the root JSON object
json stableEndpointsJson;
for (const auto& endpoint : root.stableEndpoints) {
char ipStr[64];
endpoint.toString(ipStr);
stableEndpointsJson.push_back(ipStr);
}
rootJson["stableEndpoints"] = stableEndpointsJson;
rootsJson.push_back(rootJson);
}
worldJson["roots"] = rootsJson;
std::string jsonStr = worldJson.dump(4);
printf("World JSON:\n%s\n", jsonStr.c_str());
if (!OSUtils::writeFile("config.json", jsonStr.c_str(), jsonStr.size())) {
fprintf(stderr, "Failed to write JSON data to config.json." ZT_EOL_S);
}
else {
printf("JSON data successfully written to config.json." ZT_EOL_S);
}
}
int main(int argc, char** argv)
{
bool json2bin = false;
bool bin2json = false;
for (int i = 1; i < argc; ++i) {
std::string arg = argv[i];
if (arg == "-h" || arg == "--help") {
printHelp();
return 0;
}
else if (arg == "-j" || arg == "--json2bin") {
json2bin = true;
}
else if (arg == "-b" || arg == "--bin2json") {
bin2json = true;
}
}
if (!(json2bin || bin2json)) {
// Default behavior: convert from JSON to world.bin
json2bin = true;
}
if (json2bin && bin2json) {
printf("Error: Cannot specify both JSON to binary and binary to JSON conversion options.\n");
printHelp();
return 1;
}
if (json2bin) {
jsonToBinary();
}
else if (bin2json) {
binaryToJson();
}
return 0;
}