From be2c4b2d4d9d7bc3b35b30c7f7a378c1f40513a7 Mon Sep 17 00:00:00 2001 From: okxlin Date: Wed, 13 Dec 2023 23:07:00 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E6=B7=BB=E5=8A=A0headscale-ui=E5=88=B0?= =?UTF-8?q?=E5=88=97=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/headscale-ui/README.md | 128 ++++++++++++++++++++ apps/headscale-ui/data.yml | 20 +++ apps/headscale-ui/latest/.env.sample | 2 + apps/headscale-ui/latest/data.yml | 10 ++ apps/headscale-ui/latest/docker-compose.yml | 16 +++ apps/headscale-ui/logo.png | Bin 0 -> 2575 bytes 6 files changed, 176 insertions(+) create mode 100644 apps/headscale-ui/README.md create mode 100644 apps/headscale-ui/data.yml create mode 100644 apps/headscale-ui/latest/.env.sample create mode 100644 apps/headscale-ui/latest/data.yml create mode 100644 apps/headscale-ui/latest/docker-compose.yml create mode 100644 apps/headscale-ui/logo.png diff --git a/apps/headscale-ui/README.md b/apps/headscale-ui/README.md new file mode 100644 index 00000000..25cfcb7f --- /dev/null +++ b/apps/headscale-ui/README.md @@ -0,0 +1,128 @@ +# 使用说明 + +**Headscale 服务器地址,只能用经过域名反向代理的地址。** + +# 原始相关 +*** +# Headscale-UI +A web frontend for the [headscale](https://github.com/juanfont/headscale) Tailscale-compatible coordination server. + +## Installation +Headscale-UI is currently released as a static site: just take the release and host with your favorite web server. Headscale-UI expects to be served from the `/web` path to avoid overlap with headscale on the same domain. Note that due to CORS (see https://github.com/juanfont/headscale/issues/623), headscale UI *must* be served on the same subdomain, or CORS headers injected via reverse proxy. + +### Docker Installation +If you are using docker, you can install `headscale` alongside `headscale-ui`, like so: + +```yaml +version: '3.5' +services: + headscale: + image: headscale/headscale:latest + container_name: headscale + volumes: + - ./container-config:/etc/headscale + - ./container-data/data:/var/lib/headscale + # ports: + # - 27896:8080 + command: headscale serve + restart: unless-stopped + headscale-ui: + image: ghcr.io/gurucomputing/headscale-ui:latest + restart: unless-stopped + container_name: headscale-ui + # ports: + # - 9443:443 +``` + +Headscale UI serves on port 443 and uses a self signed cert by default. You will need to add a `config.yaml` file under your `container-config` folder so that `headscale` has all of the required settings declared. An example from the official `headscale` repo is [here](https://github.com/juanfont/headscale/blob/main/config-example.yaml). + +### Additional Docker Settings +The docker container lets you set the following settings: +| Variable | Description | Example | +|----|----|----| +| HTTP_PORT | Sets the HTTP port to an alternate value | `80` | +| HTTPS_PORT | Sets the HTTPS port to an alternate value | `443` | + +### Proxy Settings +You will need a reverse proxy to install `headscale-ui` on your domain. Here is an example [Caddy Config](https://caddyserver.com/) to achieve this: +``` +https://hs.yourdomain.com.au { + reverse_proxy /web* https://headscale-ui { + transport http { + tls_insecure_skip_verify + } + } + + reverse_proxy * http://headscale:8080 +} + + +``` + +### Cross Domain Installation +If you do not want to configure headscale-ui on the same subdomain as headscale, you must intercept headscale traffic via your reverse proxy to fix CORS (see https://github.com/juanfont/headscale/issues/623). Here is an example fix with Caddy, replacing your headscale UI domain with `hs-ui.yourdomain.com.au`: +``` +https://hs.yourdomain.com.au { + @hs-options { + host hs.yourdomain.com.au + method OPTIONS + } + @hs-other { + host hs.yourdomain.com.au + } + handle @hs-options { + header { + Access-Control-Allow-Origin https://hs-ui.yourdomain.au + Access-Control-Allow-Headers * + Access-Control-Allow-Methods "POST, GET, OPTIONS, DELETE" + } + respond 204 + } + handle @hs-other { + reverse_proxy http://headscale:8080 { + header_down Access-Control-Allow-Origin https://hs-ui.yourdomain.com.au + header_down Access-Control-Allow-Methods "POST, GET, OPTIONS, DELETE" + header_down Access-Control-Allow-Headers * + } + } +} + +``` + +### Other Configurations +See [Other Configurations](https://github.com/gurucomputing/headscale-ui/blob/master/documentation/configuration.md) for further proxy examples, such as Traefik + +## Versioning +The following versions correspond to the appropriate headscale version +| Headscale Version | HS-UI Version | +|-------------------|---------------| +| 19+ | 2023-01-30+ | +| <19 | <2023-01-30 | + +## Troubleshooting +Make sure you are using the latest version of headscale. Headscale-UI is only tested against: + +* The current stable version of headscale +* Chrome/Chrome Mobile +* Firefox/Firefox Mobile + +Note that while mobile is checked for functionality, the web experience is not mobile optimised. + +If you are getting errors about preflight checks, it's probably CORS related. Make sure your UI sits on the same subdomain as headscale or inject CORS headers. + +### Errors related to "Missing Bearer Prefix" +Your API key is either not saved or you haven't configured your reverse proxy. Create an API key in `headscale` (via command line) with `headscale apikeys create` or `docker exec headscale apikeys create` and save it in `settings`. + +HS-UI *has* to be ran on the same subdomain as headscale or you need to configure CORS. Yes you need to use a reverse proxy to do this. Use a reverse proxy. If you are trying to use raw IPs and ports, it *will* not work. + +## Security +see [security](https://github.com/gurucomputing/headscale-ui/blob/master/SECURITY.md) for details + +## Development +see [development](https://github.com/gurucomputing/headscale-ui/blob/master/documentation/development.md) for details + +## Style Guide +see [style](https://github.com/gurucomputing/headscale-ui/blob/master/documentation/style.md) for details + +## Architecture +See [architecture](https://github.com/gurucomputing/headscale-ui/blob/master/documentation/architecture.md) for details \ No newline at end of file diff --git a/apps/headscale-ui/data.yml b/apps/headscale-ui/data.yml new file mode 100644 index 00000000..414f80bd --- /dev/null +++ b/apps/headscale-ui/data.yml @@ -0,0 +1,20 @@ +name: Headscale-UI +tags: + - 工具 +title: Headscale 与 Tailscale 兼容的协调服务器的 Web 前端 +type: 工具 +description: Headscale 与 Tailscale 兼容的协调服务器的 Web 前端 +additionalProperties: + key: headscale-ui + name: Headscale-UI + tags: + - Tool + shortDescZh: Headscale 与 Tailscale 兼容的协调服务器的 Web 前端 + shortDescEn: A web frontend for the headscale Tailscale-compatible coordination server + type: tool + crossVersionUpdate: true + limit: 0 + recommend: 0 + website: https://github.com/gurucomputing/headscale-ui + github: https://github.com/gurucomputing/headscale-ui + document: https://github.com/gurucomputing/headscale-ui diff --git a/apps/headscale-ui/latest/.env.sample b/apps/headscale-ui/latest/.env.sample new file mode 100644 index 00000000..6c018e30 --- /dev/null +++ b/apps/headscale-ui/latest/.env.sample @@ -0,0 +1,2 @@ +CONTAINER_NAME="headscale-ui" +PANEL_APP_PORT_HTTPS="40182" diff --git a/apps/headscale-ui/latest/data.yml b/apps/headscale-ui/latest/data.yml new file mode 100644 index 00000000..be3b107d --- /dev/null +++ b/apps/headscale-ui/latest/data.yml @@ -0,0 +1,10 @@ +additionalProperties: + formFields: + - default: 40182 + edit: true + envKey: PANEL_APP_PORT_HTTPS + labelEn: Port + labelZh: 端口 + required: true + rule: paramPort + type: number diff --git a/apps/headscale-ui/latest/docker-compose.yml b/apps/headscale-ui/latest/docker-compose.yml new file mode 100644 index 00000000..dc5714fc --- /dev/null +++ b/apps/headscale-ui/latest/docker-compose.yml @@ -0,0 +1,16 @@ +version: '3' +services: + headscale-ui: + container_name: ${CONTAINER_NAME} + restart: always + networks: + - 1panel-network + ports: + - "${PANEL_APP_PORT_HTTPS}:443" + image: ghcr.io/gurucomputing/headscale-ui:latest + labels: + createdBy: "Apps" + +networks: + 1panel-network: + external: true diff --git a/apps/headscale-ui/logo.png b/apps/headscale-ui/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..52a476677e82f82af0b1a71884ca2417cf350a55 GIT binary patch literal 2575 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 L;A&rIOZ@3?EoHWf literal 0 HcmV?d00001