Giter Site home page Giter Site logo

gurucomputing / headscale-ui Goto Github PK

View Code? Open in Web Editor NEW
1.5K 14.0 104.0 2.4 MB

A web frontend for the headscale Tailscale-compatible coordination server

License: BSD 3-Clause "New" or "Revised" License

JavaScript 3.39% CSS 0.87% HTML 0.28% Svelte 88.66% Shell 5.18% TypeScript 1.61%
sveltekit tailwindcss vpn-service web-frontend

headscale-ui's Introduction

Headscale-UI

A web frontend for the 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 juanfont/headscale#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:

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.

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 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 juanfont/headscale#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 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 container> 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 for details

Development

see development for details

Style Guide

see style for details

Architecture

See architecture for details

headscale-ui's People

Contributors

adrum avatar bonusplay avatar fedefreue avatar niek avatar routerino avatar xzzpig avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

headscale-ui's Issues

enable device routes fail when change advertise-routes in tailscale client

** Supporting Details **
Provide the following:

  • Browser Version:
    edge
  • Headscale Version:
    0.16.4
  • Any Browser Errors (control+shift+i in chrome to see)

Describe the bug
A clear and concise description of what the bug is. Screenshots if applicable

This happend when a tailscale client changes its advertise-routes using 'tailscale up --advertise-routes xxx --rest'.
The web browser can correctly shows device routes but cannot enable nor disable one of the device routes.
Seems like the list of device routes in headscale-ui server were not update after we changed 'advertise-routes' settings. And reboot the headscale-ui docker server can fix this problem.

Add Auth Login Page to UI

Could you add a login page in front the /web page? And maybe add 2FA or OAuth Support? I was experimenting with this on a cloud VPS, and I was thinking about how to protect it since I'm hosting Headscale and the UI remotely

Rework docker container to be more flexible

There's been a couple requests now for port options and http vs https options when using the docker container. While I'd like to enforce HTTPS by default, it's understandable that people want alternatives.

Will rework the docker container to allow multiple ports and optionally provide HTTP.

Can't rename device

When i try to update a device name, I got this 501 error:
{"code":12, "message":"Method Not Allowed", "details":[]}

HAProxy over OPNSense - how to set it up?

Hello there!

Here my config:

version: '3.5'
services:
  headscale:
    image: headscale/headscale:latest-alpine
    container_name: headscale
    volumes:
      - type: bind
        source: /home/vamp/headscale/container-config
        target: /etc/headscale
      - type: bind
        source: /home/vamp/headscale/container-data/data
        target: /var/lib/headscale

    ports:
      - 16666:8080
    command: headscale serve
    restart: unless-stopped
  headscale-ui:
    image: ghcr.io/gurucomputing/headscale-ui:latest
    restart: unless-stopped
    container_name: headscale-ui
    ports:
      - 16667:80

I use OPNSense firewall with HAProxy.

Here the settings:

Set two backend, one of assign to my docker host port 16666, the other to the 16667. I create one Frontend (TLS certificated) on my firewall port 443. Create conditions and rules, that this domain names redirect to the correct backend:

it work well, i access both site. The problem is the CORS ... i never set it up with HAproxy and not found any documentation that fit to HAProxy plugin with OPNSense (only "vanilla" HAproxy)

So anybody successfully set it up above similar configuration on OPNSense?

device list, arrow cannot be closed

** Supporting Details **
Provide the following:

  • Browser Version:
    Chrome 94.0.4606.61
  • Headscale Version:
    *0.17.1+
  • Any Browser Errors (control+shift+i in chrome to see)
    _page.svelte-8213986a.js:formatted:1085 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'length')
    at Object.p (_page.svelte-8213986a.js:formatted:1085)
    at Ot (index-4a5d41f3.js:formatted:483)
    at ft (index-4a5d41f3.js:formatted:458)

Describe the bug
The right-up side arrow does not work. It cannot be closed.
image

Sort by ID doesn't sort numerically

When you have more than 9 nodes, the sort by ID looks like it is not sorting correctly. E.g.: ID 3 ends up after ID 25.

Example screenshot:

image

(thanks for making this UI!)

Docker container port

Hi there.

I am using the container on k8s with security policies enabled. In order to run it I have to shut of some of the basic kubernetes security enforcements. think the container requires higher privileges then it actually needs due to the fact that it starts caddy on 443. If the port was above 1024 lets say 8443 or something like it, it could start without requiring root to do so.

Or should I maybe just overwrite the caddyfile? That would probably be a good alternative since it's behind an ingress anyway. I haven't tried it yet.

Any suggestions on how to run the container without requiring root privileges?

Thank you!

Add an authentication

As headscale's admin console, I recommend that you add authentication before entering the console page, as this will make the service insecure if it is exposed to the public.

Move Dev/Prod build images from node current to node LTS

I suspect some of the weirder issues I'm encountering with svelte are due to the github actions build channel not following LTS, will shift to LTS channel and provide any further fixes to stop warnings cropping up during build stage.

fatal: unable to access 'https://github.com/gurucomputing/headscale-ui/'

** Supporting Details **
Provide the following:

  • Browser Version: chrome 104.0.5112.102
  • Headscale Version: 0.16.4-alpine
  • Any Browser Errors (control+shift+i in chrome to see)

Describe the bug
A clear and concise description of what the bug is. Screenshots if applicable

version: '3.5'
services:
  headscale:
    image: headscale/headscale:0.16.4-alpine
    container_name: headscale1
    volumes:
      - /data/headscale1/config:/etc/headscale
      - /data/headscale1/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 container have error and the web ui can not access

root@ubuntu-vm:/data/scripts# docker logs -f headscale-ui
-- Fresh Install detected, setting up your dev environment --
-- Installing Source --
Cloning into 'headscale-ui'...
fatal: unable to access 'https://github.com/gurucomputing/headscale-ui/': GnuTLS recv error (-110): The TLS connection was non-properly terminated.
/staging/scripts/2-initialise.sh: 42: cd: can't cd to headscale-ui
npm ERR! code ENOENT
npm ERR! syscall open
npm ERR! path /data/package.json
npm ERR! errno -2
npm ERR! enoent ENOENT: no such file or directory, open '/data/package.json'
npm ERR! enoent This is related to npm not being able to find a file.
npm ERR! enoent 

npm ERR! A complete log of this run can be found in:
npm ERR!     /data/home/.npm/_logs/2022-08-27T05_21_24_122Z-debug-0.log
Server bound to 0.0.0.0:3000 (IPv4)
Extension host agent listening on 3000

Ignoring option 'connection-token': Value must not be empty.
Web UI available at http://localhost:3000/?tkn=27eb12f2-4fda-4c77-b3fe-df5cc75322af
[05:21:24] Extension host agent started.

notes: my network not really good for accesss github,

Exception in device view

Running headscale-ui 2022.08.13-beta, when navigating to the device view, I'm greeted with a broken page and this error in the console:

devices.html.svelte-b457f55c.js:1 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'length')
    at ul (devices.html.svelte-b457f55c.js:1:20977)
    at Ee (index-e1cee4d8.js:4:5046)
    at new dl (devices.html.svelte-b457f55c.js:1:22367)
    at Al (devices.html.svelte-b457f55c.js:1:39173)
    at Ee (index-e1cee4d8.js:4:5046)
    at new Il (devices.html.svelte-b457f55c.js:1:41561)
    at Ct (devices.html.svelte-b457f55c.js:1:49316)
    at At (devices.html.svelte-b457f55c.js:1:49600)
    at St (devices.html.svelte-b457f55c.js:1:47088)
    at Object.p (devices.html.svelte-b457f55c.js:1:46456)

Other views (including user view) work fine. There are devices in my tailnet, so this is probably not a case of the list of devices being empty.

Thanks!

Headscale API Key Length too short?

So I have setup a working headscale server to play with and generated a working api key that is 48 chars in length yet when trying to add it to the settings page on the web-ui is complains that I need a 54 char api key? The key length that my headscale is generating is only 48 chars long. Not sure what I may be missing.

Please match the requested format

When trying to add the server it says 'Please match the requested format' my domain is https://headscale.domain.network. Is .network not considered a TLD in the code?

Latest Headscale Beta API breaks Headscale-UI

** Supporting Details **
Provide the following:

  • Browser Version: Google Chrome
  • Headscale Version: 0.18-beta1
  • Any Browser Errors (control+shift+i in chrome to see)
Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'length')
    at Object.p (_page.svelte-8213986a.js:1:15519)
    at Ot (index-4a5d41f3.js:4:1456)
    at ft (index-4a5d41f3.js:4:1142)

Describe the bug
If I try to open a Device with the dropdown button or just pressing on the row, I get a console error and the UI stops working. Only a refresh can make the UI working again.

Improve documentation to explain how to create an API key and save it in the settings

Trying to stand this up and am not able to connect ui to headscale. Receiving the following in log out

headscale | 2022-08-03T14:06:35Z ERR go/src/headscale/app.go:348 > missing "Bearer " prefix in "Authorization" header client_address=172.27.0.1:34438

Maybe this has to do with my nginx proxy settings, but am not sure.

Not sure how to process, any ideas?

nginx config example

I presume headscale-ui could be run via nginx, so any possibility of a config example?

Compatibility Documentation

Update the documentation to reflect what headscale-ui gets tested against:

  • The latest version of headscale (16.2)
  • Chrome/Chrome Mobile
  • Firefox/Firefox Mobile

Some questions and suggestions about headscale-ui

Question 1:
The ip of the docker network name cannot be obtained, and the format is incorrect.
The network inside the virtual machine is actually accessible by direct name

PING headscale (172.30.0.2): 56 data bytes
64 bytes from 172.30.0.2: seq=0 ttl=42 time=0.081 ms
64 bytes from 172.30.0.2: seq=1 ttl=42 time=0.058 ms

PING headscale-ui (172.30.0.3): 56 data bytes
64 bytes from 172.30.0.3: seq=0 ttl=42 time=0.033 ms
64 bytes from 172.30.0.3: seq=1 ttl=42 time=0.037 ms

Can you consider supporting formats like http://headscale:8080?

Question 2:
http://172.30.0.2:8080 and the apikey is filled in, the verification cannot be passed
Request supports local authentication and http authentication

Question 3:
Can headscale-ui support output on port 80?
My signature is hung on nginx and then proxied back, and I don't need headscale-ui to have its own signature.

Many thanks.

Trim tailing slash in `Headscale URL` field

Minor issue: if Headscale URL is filled to include a trailing /, this causes the requests to Headscale to be of the form https://server//api/... which returns 404s.

Options:

  • Assuming that headscale-ui is indeed served from /web/ and heascale's API is at /, this could be auto-configured;
  • The UI should hint that trailing /s are probably unnecessary, or
  • The trailing / should be trimmed automatically

Thanks!

Sidebar does not float

If the main container is long enough, it will outpace the sidebar. The sidebar should float.

Clean up API functions

The API functions are getting a bit unwieldy, doing a lot more than just API calls. Need to separate out the functions.

Traefik working config & suggestion against default HTTPS

A working traefik configuration may look like the following and you may add to your documentation:

  headscale:
    image: headscale/headscale:latest
    container_name: headscale
    restart: unless-stopped
    networks:
      - traefik_proxy
    command: headscale serve
    volumes:
      - $DOCKERDIR/headscale/config:/etc/headscale
    labels:
      - "traefik.enable=true"
      ## HTTP Routers
      - "traefik.http.routers.headscale-rtr.entrypoints=https"
      - "traefik.http.routers.headscale-rtr.rule=Host(`hs.${DOMAIN_PUBLIC}`)"
      ## Middlewares
      - "traefik.http.routers.headscale-rtr.middlewares=chain-no-auth@file"
      ## HTTP Services
      - "traefik.http.routers.headscale-rtr.service=headscale-svc"
      - "traefik.http.services.headscale-svc.loadbalancer.server.port=8080"

  headscale-ui:
    image: ghcr.io/gurucomputing/headscale-ui:latest
    container_name: headscale-ui
    restart: unless-stopped
    networks:
      - traefik_proxy
    labels:
      - "traefik.enable=true"
      ## HTTP Routers
      - "traefik.http.routers.headscale_ui-rtr.entrypoints=https"
      - "traefik.http.routers.headscale_ui-rtr.rule=Host(`hs.${DOMAIN_PUBLIC}`) && PathPrefix(`/web`)"
      ## Middlewares
      - "traefik.http.routers.headscale_ui-rtr.middlewares=chain-no-auth@file"
      ## HTTP Services
      - "traefik.http.routers.headscale_ui-rtr.service=headscale_ui-svc"
      - "traefik.http.services.headscale_ui-svc.loadbalancer.server.port=443"
      - "traefik.http.services.headscale_ui-svc.loadbalancer.server.scheme=https"
      - "traefik.http.services.headscale_ui-svc.loadbalancer.serversTransport=disableSSLCheck@file"

And an additional config file whatevername.yml:

http:
  serversTransports:
    disableSSLCheck:
      insecureSkipVerify: true

Since we are using a reverse proxy anyways, is the internal HTTPS with a self-signed certificate really necessary? I really dislike having to add an additional insecureSkipVerify configuration to either Caddy or traefik. I see that the service really is served via 127.0.0.1:2019 - why not expose that port to 0.0.0.0? What's the benefit of having Caddy inside the container?

I would happily forward the reverse proxy to <container>:2019 without having to deal with the self-signed certificate.

Visual Indicator for last login period

A visual indicator should show when a device was last seen, with "green" within a day, "yellow" within a week, and "gray" older than that. A textual indicator of the last time should show on hover over.

Implement Searching for Users and Devices

Searching for all the things, plus the ability to optionally narrow the search scope.

architecture considerations

  • Should search parameters be persistent? Immediate thought is no, people will leave them on and get confused. Maybe semi persistent as a store, so it goes away on a refresh but stays during page routing.
  • should search be presented as tags? My thought is yes, makes it easy to make advanced search parameters. Maybe reuse the tagging already present in devices.
  • maybe fuzzy search instead of tags? Something like fuse.js to auto parse searches. Less work and potentially better searching, but must be mindful of dependency creep.

Update Development Image

Development Image isn't on an auto update cycle (doesn't really need to be), but needs the occasional manual update.

Reorganise Common Lib Folder

Would like to split out apiFunctions, searching, and sorting into their respective lib folders (devices, users, groups).

Alert and Nav can go into a layout specific lib folder

Stores and classes can stay in common as they are relatively global scope

Automatic warning for API Key expiry

Create the capability to warn when an API key is about to expire. Create a button in the server settings to roll over an API key automatically. Create a toggle to show or hide the api key.

Rename default page to "users" and autoredirect

The default page is called index.html, when really it's the group of user components. Will set up an auto redirect from the base page and rename to users to keep consistency in the code base.

Use caddy as certificate manager

So apparently there's a way to use caddy with headscale as certificate manager so certificates can automatically be issued for service.

I do think this would interfere with the headscale-ui caddy configuration as if I'm understanding it correctly, to use this feature, headscale would need to be enabled to issue let's encrypt certificates or it won't work.

I might be mistaken but I do think this would require an alternative deployment/configuration of headscale-ui to make this work?

ACL Work - Create Group Page

Starting the task of making up a GUI for the ACL in anticipation of the API getting updated.

Starting work needed:

  • New store and class to hold the ACL object
  • Feature flag to hide/show relevant pages in the settings
  • Group page
    * that can add/delete users (separate issue)
    * Searching and Sorting for group page (separate issue)

Research needed:

  • Need to figure out how to create a selection menu in sveltekit that allows for searching, as a normal selection menu won't cut it after a certain size. could use something like svelecte, but given that I already have fuse.js searching I might just see if I can build one first. Will tackle this separately in #54

Write Unit Tests

Need to develop a test mode that lets me fake a headscale server, so I can put in dummy data and test different use cases in the API.

  • Create a test flag in the settings (maybe sub flags for different test varities)
  • Create a test document that prefills the stores with various data
  • Add test checks in the API functions to perform dummy changes on existing data

Let the site setting be optional

In the most common configuration, the site sits on the same domain as headscale. In this configuration the site is optional, as the way the urls get encoded allow for relative paths.

Let's allow for adding an API key without needing a site URL as it's not necessary some of the time.

Container Farm for UI Testing

I've been running a small lab environment for testing, but it's not good for testing at scale. Want to set up a 20-30 container test bench for some real testing, and maybe pick up any scaling issues.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.