Skip to content

Commit

Permalink
Support Caddy V2 to reverse gRPC.
Browse files Browse the repository at this point in the history
  • Loading branch information
fscarmen2 committed Dec 12, 2023
1 parent a4eca07 commit 05faae0
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 53 deletions.
11 changes: 3 additions & 8 deletions .github/workflows/Build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ on:
jobs:
Building:
runs-on: ubuntu-latest
name: "Build Argo-Nezha images"
name: "Build image"
env:
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
Expand Down Expand Up @@ -34,10 +34,5 @@ jobs:
uses: docker/[email protected]
with:
push: true
platforms: linux/amd64,linux/arm64,linux/arm/v7
tags: ${{ env.DOCKERHUB_REPOSITORY }}

- name: Upload to repository
uses: stefanzweifel/[email protected]
with:
commit_message: Push images ${{ env.VERSION }} by Github Actions, ${{ env.DATE }}
platforms: linux/amd64, linux/arm64, linux/arm/v7
tags: ${{ env.DOCKERHUB_REPOSITORY }}
13 changes: 7 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,11 @@ Documentation: [English version](https://github.com/fscarmen2/Argo-Nezha-Service
* Argo 隧道突破需要公网入口的限制 --- 传统的哪吒需要有两个公网端口,一个用于面板的访问,另一个用于客户端上报数据,本项目借用 Cloudflare Argo 隧道,使用内网穿透的办法
* IPv4 / v6 具备更高的灵活性 --- 传统哪吒需要处理服务端和客户端的 IPv4/v6 兼容性问题,还需要通过 warp 等工具来解决不对应的情况。然而,本项目可以完全不需要考虑这些问题,可以任意对接,更加方便和简便
* 一条 Argo 隧道分流多个域名和协议 --- 建立一条内网穿透的 Argo 隧道,即可分流三个域名(hostname)和协议(protocal),分别用于面板的访问(http),客户端上报数据(tcp)和 ssh(可选)
* GrpcWebProxy 反向代理的 gRPC 数据端口 --- 配上证书做 tls 终结,然后 Argo 的隧道配置用 https 服务指向这个反向代理,启用http2回源,grpc(nezha)->GrpcWebProxy->h2(argo)->cf cdn edge->agent
* Grpc 反向代理的 gRPC 数据端口 --- 配上证书做 tls 终结,然后 Argo 的隧道配置用 https 服务指向这个反向代理,启用http2回源,grpc(nezha)->Grpc Proxy->h2(argo)->cf cdn edge->agent
* 每天自动备份 --- 北京时间每天 4 时 0 分自动备份整个哪吒面板文件夹到指定的 github 私库,包括面板主题,面板设置,探针数据和隧道信息,备份保留近 5 天数据;鉴于内容十分重要,必须要放在私库
* 每天自动更新面板 -- 北京时间每天 4 时 0 分自动检测最新的官方面板版本,有升级时自动更新
* 每天自动更新面板和更新脚本 -- 北京时间每天 4 时 0 分自动检测最新的官方面板版本及备份还原脚本,有升级时自动更新
* 手/自一体还原备份 --- 每分钟检测一次在线还原文件的内容,遇到有更新立刻还原
* 默认内置本机探针 --- 能很方便的监控自身服务器信息
* 数据更安全 --- Argo 隧道使用TLS加密通信,可以将应用程序流量安全地传输到 Cloudflare 网络,提高了应用程序的安全性和可靠性。此外,Argo Tunnel也可以防止IP泄露和DDoS攻击等网络威胁

<img width="1609" alt="image" src="https://github.com/fscarmen2/Argo-Nezha-Service-Container/assets/92626977/4893c3cd-5055-468f-8138-6c5460bdd1e4">

Expand Down Expand Up @@ -100,7 +99,7 @@ Argo 隧道认证方式有 json 和 token,使用两个方式其中之一。推
| GH_REPO || 在 github 上备份哪吒服务端数据库文件的 github 库 |
| GH_EMAIL || github 的邮箱,用于备份的 git 推送到远程库 |
| GH_PAT || github 的 PAT |
| REVERSE_PROXY_MODE || 默认使用 nginx 应用来反代,这时可以不填写该变量;如需 gRPCwebProxy 反代,请设置该值为 `grpcwebproxy` |
| REVERSE_PROXY_MODE || 默认使用 Caddy 应用来反代,这时可以不填写该变量;如需 Nginx 或 gRPCwebProxy 反代,请设置该值为 `nginx ` `grpcwebproxy` |
| ARGO_AUTH || Json: 从 https://fscarmen.cloudflare.now.cc 获取的 Argo Json<br> Token: 从 Cloudflare 官网获取 |
| ARGO_DOMAIN || Argo 域名 |
| NO_AUTO_RENEW || 默认不需要该变量,即每天定时同步在线最新的备份和还原脚本。如不需要该功能,设置此变量,并赋值为 `1` |
Expand Down Expand Up @@ -137,7 +136,7 @@ docker run -dit \
-e ARGO_AUTH='<填获取的 Argo json 或者 token>' \
-e ARGO_DOMAIN=<填自定义的> \
-e GH_BACKUP_USER=<选填,选填,选填! 如与 GH_USER 一致,可以不要该环境变量> \
-e REVERSE_PROXY_MODE=<选填,选填,选填! 如想用 gRPCwebProxy 替代 nginx 反代的话,请设置该变量并赋值为 `grpcwebproxy`> \
-e REVERSE_PROXY_MODE=<选填,选填,选填! 如想用 Nginx 或 gRPCwebProxy 替代 Caddy 反代的话,请设置该变量并赋值为 `nginx` 或 `grpcwebproxy`> \
-e NO_AUTO_RENEW=<选填,选填,选填! 如果不需要自动在线同步最新的 backup.sh 和 restore.sh,请设置该变量并赋值为 `1`>
fscarmen/argo-nezha
```
Expand All @@ -161,7 +160,7 @@ services:
- ARGO_AUTH='<填获取的 Argo json 或者 token>'
- ARGO_DOMAIN=<填自定义的>
- GH_BACKUP_USER=<选填,选填,选填! 如与 GH_USER 一致,可以不要该环境变量>
- REVERSE_PROXY_MODE=<选填,选填,选填! 如想用 gRPCwebProxy 替代 nginx 反代的话,请设置该变量并赋值为 `grpcwebproxy`>
- REVERSE_PROXY_MODE=<选填,选填,选填! 如想用 Nginx 或 gRPCwebProxy 替代 Caddy 反代的话,请设置该变量并赋值为 `nginx` 或 `grpcwebproxy`>
- NO_AUTO_RENEW=<选填,选填,选填! 如果不需要自动在线同步最新的 backup.sh 和 restore.sh,请设置该变量并赋值为 `1`>
```

Expand Down Expand Up @@ -249,6 +248,8 @@ tar czvf dashboard.tar.gz /dashboard
|-- nezha.pem # SSL/TLS 证书文件
|-- cloudflared # Cloudflare Argo 隧道主程序
|-- grpcwebproxy # gRPC 反代主程序
|-- caddy # Caddy 主程序
|-- Caddyfile # Caddy 配置文件
`-- nezha-agent # 哪吒客户端,用于监控本地 localhost
```

Expand Down
13 changes: 7 additions & 6 deletions README_EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,11 @@ Documentation: English version | [中文版](https://github.com/fscarmen2/Argo-N
* Argo tunnel breaks through the restriction of requiring a public network portal --- The traditional Nezha requires two public network ports, one for panel visiting and the other for client reporting, this project uses Cloudflare Argo tunnels and uses intranet tunneling.
* IPv4 / v6 with higher flexibility --- The traditional Nezha needs to deal with IPv4/v6 compatibility between server and client, and also needs to resolve mismatches through tools such as warp. However, this project does not need to consider these issues at all, and can be docked arbitrarily, which is much more convenient and easy!
* One Argo tunnel for multiple domains and protocols --- Create an intranet-penetrating Argo tunnel for three domains (hostname) and protocols, which can be used for panel access (http), client reporting (tcp) and ssh (optional).
* GrpcWebProxy reverse proxy gRPC data port --- with a certificate for tls termination, then Argo's tunnel configuration with https service pointing to this reverse proxy, enable http2 back to the source, grpc(nezha)->GrpcWebProxy->h2(argo)->cf cdn edge->agent
* Grpc Proxy reverse proxy gRPC data port --- with a certificate for tls termination, then Argo's tunnel configuration with https service pointing to this reverse proxy, enable http2 back to the source, grpc(nezha)->Grpc Proxy->h2(argo)->cf cdn edge->agent
* Daily automatic backup --- every day at 04:00 BST, the entire Nezha panel folder is automatically backed up to a designated private github repository, including panel themes, panel settings, probe data and tunnel information, the backup retains nearly 5 days of data; the content is so important that it must be placed in the private repository.
* Automatic daily panel update -- the latest official panel version is automatically detected every day at 4:00 BST, and updated when there is an upgrade.
* Automatically update the control panel and scripts daily - Check for the latest official control panel version and backup/restore script at 04:00 every day. If an upgrade is available, perform an automatic update.
* Manual/automatic restore backup --- check the content of online restore file once a minute, and restore immediately when there is any update.
* Default built-in local probes --- can easily monitor their own server information
* More secure data --- Argo Tunnel uses TLS encrypted communication to securely transmit application traffic to the Cloudflare network, improving application security and reliability. In addition, Argo Tunnel protects against network threats such as IP leaks and DDoS attacks.

<img width="1609" alt="image" src="https://github.com/fscarmen2/Argo-Nezha-Service-Container/assets/92626977/4893c3cd-5055-468f-8138-6c5460bdd1e4">

Expand Down Expand Up @@ -100,7 +99,7 @@ Variables used
| GH_REPO | No | The github repository for backing up Nezha's server-side database files on github |
| GH_EMAIL | No | github's mailbox for git push backups to remote repositories |
| GH_PAT | No | github's PAT |
| REVERSE_PROXY_MODE | No | If you want to use gRPCwebProxy instead of nginx for reverse proxying, set this value to `grpcwebproxy` |
| REVERSE_PROXY_MODE | No | If you want to use Nginx or gRPCwebProxy instead of Caddy for reverse proxying, set this value to `nginx` or `grpcwebproxy` |
| ARGO_AUTH | Yes | Argo Json from https://fscarmen.cloudflare.now.cc<br>Argo token from Cloudflare official website |
| ARGO_DOMAIN | Yes | Argo domain |
| NO_AUTO_RENEW | No | The latest backup and restore scripts are synchronized online regularly every day. If you don't need this feature, set this variable and assign it a value of `1` |
Expand Down Expand Up @@ -137,7 +136,7 @@ docker run -dit \
-e ARGO_AUTH='<Fill in the fetched Argo json or token>' \
-e ARGO_DOMAIN=<fill in customized> \
-e GH_BACKUP_USER=<Optional, Optional, Optional! If it is consistent with GH_USER, you can leave it blank> \
-e REVERSE_PROXY_MODE=<Optional, Optional, Optional! If you want to use gRPCwebProxy instead of nginx for reverse proxying, set this value to `grpcwebproxy`> \
-e REVERSE_PROXY_MODE=<Optional, Optional, Optional! If you want to use Nginx or gRPCwebProxy instead of Caddy for reverse proxying, set this value to `nginx` or `grpcwebproxy`> \
-e NO_AUTO_RENEW=<Optional, Optional, Optional! If you don't need synchronized online, set this variable and assign it a value of `1`>
fscarmen/argo-nezha
```
Expand All @@ -161,7 +160,7 @@ services.
- ARGO_AUTH='<Fill in the fetched Argo json or token>'
- ARGO_DOMAIN=<fill in customized>
- GH_BACKUP_USER=<Optional, Optional, Optional! If it is consistent with GH_USER, you can leave it blank>
- REVERSE_PROXY_MODE=<Optional, Optional, Optional! If you want to use gRPCwebProxy instead of nginx for reverse proxying, set this value to `grpcwebproxy`>
- REVERSE_PROXY_MODE=<Optional, Optional, Optional! If you want to use Nginx or gRPCwebProxy instead of Caddy for reverse proxying, set this value to `nginx` or `grpcwebproxy>
- NO_AUTO_RENEW=<Optional, Optional, Optional! If you don't need synchronized online, set this variable and assign it a value of `1`>
```

Expand Down Expand Up @@ -251,6 +250,8 @@ tar czvf dashboard.tar.gz /dashboard
|-- nezha.pem # SSL/TLS certificate file.
|-- cloudflared # Cloudflare Argo tunnel main program.
|-- grpcwebproxy # gRPC reverse proxy main program.
|-- caddy # Caddy main program.
|-- Caddyfile # Caddy config file.
`-- nezha-agent # Nezha client, used to monitor the localhost.
```

Expand Down
67 changes: 47 additions & 20 deletions dashboard.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ GH_PROXY=https://mirror.ghproxy.com/
WORK_DIR='/opt/nezha/dashboard'
TEMP_DIR='/tmp/nezha'
START_PORT='5000'
NEED_PORTS=3 # web , gRPC , gRPC proxy
NEED_PORTS=4 # web , gRPC , gRPC proxy, caddy http

trap "rm -rf $TEMP_DIR; echo -e '\n' ;exit" INT QUIT TERM EXIT

Expand Down Expand Up @@ -87,8 +87,8 @@ E[36]="Downloading the \${FAILED[*]} failed. Installation aborted. Feedback: [ht
C[36]="下载 \${FAILED[*]} 失败,安装中止,问题反馈:[https://github.com/fscarmen2/Argo-Nezha-Service-Container/issues]"
E[37]="Install Nezha's official VPS or docker version (https://github.com/naiba/nezha)"
C[37]="安装哪吒官方 VPS 或 Docker 版本 (https://github.com/naiba/nezha)"
E[38]="Please choose gRPC proxy mode:\n 1. Nginx (default) \n 2. gRPCwebProxy"
C[38]="请选择 gRPC 代理模式:\n 1. Nginx (默认) \n 2. gRPCwebProxy"
E[38]="Please choose gRPC proxy mode:\n 1. Caddy (default)\n 2. Nginx\n 3. gRPCwebProxy"
C[38]="请选择 gRPC 代理模式:\n 1. Caddy (默认)\n 2. Nginx\n 3. gRPCwebProxy"
E[39]="To uninstall Nginx press [y], it is not uninstalled by default:"
C[39]="如要卸载 Nginx 请按 [y],默认不卸载:"
E[40]="Default: enable automatic online synchronization of the latest backup.sh and restore.sh scripts. If you do not want this feature, enter [n]:"
Expand Down Expand Up @@ -128,7 +128,7 @@ check_arch() {
esac
}

# 检查可用 port 函数,要求三个
# 检查可用 port 函数,要求4个
check_port() {
until [ "$START_PORT" -gt 65530 ]; do
if [ "$SYSTEM" = 'Alpine' ]; then
Expand All @@ -144,6 +144,7 @@ check_port() {
GRPC_PROXY_PORT=${FREE_PORT[0]}
WEB_PORT=${FREE_PORT[1]}
GRPC_PORT=${FREE_PORT[2]}
CADDY_HTTP_PORT=${FREE_PORT[3]}
else
error "\n $(text 33) \n"
fi
Expand All @@ -156,9 +157,9 @@ check_install() {
if [ "$STATUS" = "$(text 26)" ]; then
{ wget -qO $TEMP_DIR/cloudflared ${GH_PROXY}https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-$ARCH >/dev/null 2>&1 && chmod +x $TEMP_DIR/cloudflared >/dev/null 2>&1; }&
{ DASHBOARD_LATEST=$(wget -qO- "https://api.github.com/repos/naiba/nezha/releases/latest" | awk -F '"' '/"tag_name"/{print $4}' || echo 'v0.15.17')
wget -qO $TEMP_DIR/dashboard.zip ${GH_PROXY}https://github.com/naiba/nezha/releases/download/$DASHBOARD_LATEST/dashboard-linux-$ARCH.zip
wget -qO $TEMP_DIR/dashboard.zip ${GH_PROXY}https://github.com/naiba/nezha/releases/download/$DASHBOARD_LATEST/dashboard-linux-$ARCH.zip >/dev/null 2>&1
unzip -q $TEMP_DIR/dashboard.zip -d $TEMP_DIR 2>&1
mv -f $TEMP_DIR/dist/dashboard-linux-$ARCH $TEMP_DIR/app; }&
mv -f $TEMP_DIR/dist/dashboard-linux-$ARCH $TEMP_DIR/app >/dev/null 2>&1; }&
fi
}

Expand Down Expand Up @@ -285,9 +286,13 @@ dashboard_variables() {
ARGO_DOMAIN=$(sed 's/[ ]*//g; s/:[ ]*//' <<< "$ARGO_DOMAIN")
{ certificate; }&

# 用户选择使用 Nginx 还是 grpcwebproxy 作 gRPC 反代,默认为 Nginx
# # 用户选择使用 gRPC 反代方式: Nginx / Caddy / grpcwebproxy,默认为 Caddy
[ -z "$REVERSE_PROXY_MODE" ] && info "\n (6/11) $(text 38) \n" && reading " $(text 24) " REVERSE_PROXY_CHOOSE
[ "$REVERSE_PROXY_CHOOSE" = 2 ] && REVERSE_PROXY_MODE=grpcwebproxy || REVERSE_PROXY_MODE=nginx
case "$REVERSE_PROXY_CHOOSE" in
2 ) REVERSE_PROXY_MODE=nginx ;;
3 ) REVERSE_PROXY_MODE=grpcwebproxy ;;
* ) REVERSE_PROXY_MODE=caddy ;;
esac

[[ -z "$GH_USER" || -z "$GH_CLIENTID" || -z "$GH_CLIENTSECRET" || -z "$ARGO_AUTH" || -z "$ARGO_DOMAIN" ]] && error "\n $(text 18) "

Expand All @@ -311,8 +316,28 @@ install() {

hint "\n $(text 25) "

# 根据 grpcwebproxy 或 nginx 作处理
if [ "$REVERSE_PROXY_MODE" = 'nginx' ]; then
# 根据 caddy,grpcwebproxy 或 nginx 作处理
if [ "$REVERSE_PROXY_MODE" = 'caddy' ]; then
local CADDY_LATEST=$(wget -qO- "https://api.github.com/repos/caddyserver/caddy/releases/latest" | awk -F [v\"] '/"tag_name"/{print $5}' || echo '2.7.6')
wget -c ${GH_PROXY}https://github.com/caddyserver/caddy/releases/download/v${CADDY_LATEST}/caddy_${CADDY_LATEST}_linux_${ARCH}.tar.gz -qO- | tar xz -C $TEMP_DIR caddy >/dev/null 2>&1
GRPC_PROXY_RUN="$WORK_DIR/caddy run --config $WORK_DIR/Caddyfile --watch"
cat > $TEMP_DIR/Caddyfile << EOF
{
http_port $CADDY_HTTP_PORT
}
:$GRPC_PROXY_PORT {
reverse_proxy {
to localhost:$GRPC_PORT
transport http {
versions h2c 2
}
}
tls $WORK_DIR/nezha.pem $WORK_DIR/nezha.key
}
EOF

elif [ "$REVERSE_PROXY_MODE" = 'nginx' ]; then
[ ! $(type -p nginx) ] && ${PACKAGE_INSTALL[int]} nginx
GRPC_PROXY_RUN="nginx -c $WORK_DIR/nginx.conf"
cat > $TEMP_DIR/nginx.conf << EOF
Expand Down Expand Up @@ -358,13 +383,20 @@ EOF
for f in ${TEMP_DIR}/{cloudflared,app,nezha.key,nezha.csr,nezha.pem}; do
[ ! -s "$f" ] && FAILED+=("${f//${TEMP_DIR}\//}")
done
[ "$REVERSE_PROXY_MODE" = 'grpcwebproxy' ] && [ ! -s $TEMP_DIR/grpcwebproxy ] && FAILED+=("grpcwebproxy")
case "$REVERSE_PROXY_MODE" in
caddy ) [ ! -s $TEMP_DIR/caddy ] && FAILED+=("caddy") ;;
grpcwebproxy ) [ ! -s $TEMP_DIR/grpcwebproxy ] && FAILED+=("grpcwebproxy") ;;
esac
[ "${#FAILED[@]}" -gt 0 ] && error "\n $(text 36) "

# 从临时文件夹复制已下载的所有到工作文件夹
[ ! -d ${WORK_DIR}/data ] && mkdir -p ${WORK_DIR}/data
cp -r $TEMP_DIR/{app,cloudflared,nezha.*} $WORK_DIR
[ "$REVERSE_PROXY_MODE" = 'nginx' ] && cp -f $TEMP_DIR/nginx.conf $WORK_DIR || cp -f $TEMP_DIR/grpcwebproxy $WORK_DIR
case "$REVERSE_PROXY_MODE" in
caddy ) cp -f $TEMP_DIR/caddy $TEMP_DIR/Caddyfile $WORK_DIR ;;
nginx ) cp -f $TEMP_DIR/nginx.conf $WORK_DIR ;;
grpcwebproxy ) cp -f $TEMP_DIR/grpcwebproxy $WORK_DIR ;;
esac
rm -rf $TEMP_DIR

# 根据参数生成哪吒服务端配置文件
Expand Down Expand Up @@ -436,23 +468,18 @@ EOF
cat > ${WORK_DIR}/run.sh << EOF
#!/usr/bin/env bash
SYSTEM=$SYSTEM
REVERSE_PROXY_MODE=$REVERSE_PROXY_MODE
if [ "\$1" = 'start' ]; then
cd ${WORK_DIR}
$GRPC_PROXY_RUN
$GRPC_PROXY_RUN >/dev/null 2>&1 &
nohup ${WORK_DIR}/app >/dev/null 2>&1 &
${WORK_DIR}/app >/dev/null 2>&1 &
$ARGO_RUN
elif [ "\$1" = 'stop' ]; then
if [ "\$REVERSE_PROXY_MODE" = 'nginx' ]; then
[ "\$SYSTEM" = 'Alpine' ] && ps -ef | awk '/\/opt\/nezha\/dashboard\/(cloudflared|grpcwebproxy|app)/{print \$1}' | xargs kill -9 || ps -ef | awk '/\/opt\/nezha\/dashboard\/(cloudflared|grpcwebproxy|app)/{print \$2}' | xargs kill -9
elif [ "\$REVERSE_PROXY_MODE" = 'grpcwebproxy' ]; then
[ "\$SYSTEM" = 'Alpine' ] && ps -ef | awk '/\/opt\/nezha\/dashboard\/(cloudflared|app)/{print \$1}' | xargs kill -9 || ps -ef | awk '/\/opt\/nezha\/dashboard\/(cloudflared|app)/{print \$2}' | xargs kill -9
fi
[ "\$SYSTEM" = 'Alpine' ] && ps -ef | awk '/\/opt\/nezha\/dashboard\/(cloudflared|grpcwebproxy|caddy|app)/{print \$1}' | xargs kill -9 || ps -ef | awk '/\/opt\/nezha\/dashboard\/(cloudflared|grpcwebproxy|caddy|app)/{print \$2}' | xargs kill -9
fi
EOF

Expand Down
Loading

0 comments on commit 05faae0

Please sign in to comment.