juanfont / headscale

An open source, self-hosted implementation of the Tailscale control server
BSD 3-Clause "New" or "Revised" License
20.96k stars 1.16k forks source link

Any WEB UI planned? #234

Open lion24 opened 2 years ago

lion24 commented 2 years ago

Hi there,

First, very nice project 😊 Testing it right now and works rock solid.

Do you have any planned to integrate a Web UI like the Tailscale one?

Screenshot 2021-11-23 at 12 36 18

I guess for that TLS would need to be enforce, but I guess this is doable. The WebUI can talk to the backend API and automatically register new nodes one the user is logged in.

I think this would be very handy and provide an experience really close to what Tailscale is doing 😊

The UI itself should be fairly quick to create, it's more the interaction with the backend that could be challenging I guess.

Let me know what's your plan.

Kr.

kradalby commented 2 years ago

We are currently adding a HTTP API, so making this will become possible within a couple of releases.

That said I dont have any concrete plans to add a web ui other than "down the line".

My priorities are driven by my need and I might work on Terraform provider first. Of course if someone would be willing to sponsor the feature, then the priorities could shift.

fdelucchijr commented 2 years ago

We are currently adding an HTTP API, so making this will become possible within a couple of releases.

That said I don't have any concrete plans to add a web UI other than "down the line".

My priorities are driven by my need and I might work on Terraform provider first. Of course, if someone would be willing to sponsor the feature, then the priorities could shift.

I’m a Flutter(Android, iOS, Web) developer in my company (actually I’m because of funds and economy of the company a FullStack (the only) developer in a microservices backend and an event-driven mobile app 🤣). I'll be happy to sponsor this feature. If the UI is made in Flutter it can take less than a week (and can be exported as a Windows/macOS app), if prefer a proper web framework can take a little longer because of MVC and management of components.

kradalby commented 2 years ago

@fdelucchijr we would appreciate help. I have some concerns with using Flutter, which is mainly that it would mean that the current maintainers would have to learn a new language (Dart) and Flutter as a framework.

But I am happy to have a chat and be convinced :)

Other than that I would probably opt for Elm + TailwindCSS as that is what I know. I assume using something like Typescript + Vue would make it accessible for contributors.

fdelucchijr commented 2 years ago

@kradalby I have been thinking about this since I wrote the previous message. Flutter Web is good for web apps, but I feel that for the classic control panel it doesn't make much sense, Is some sort of overpowered. At some point, I will make a control panel with flutter just to be able to control the headscale server from my cell phone or without exposing the WebGUI (LoL 🤣).

Elm looks super interesting! I would love to learn it, but it is true that with typescript there would be more flexibility for contributors. Tailwind I think is a very good option, in combination with Vue it can be perfect to make maintenance and development easiest possible.

The following steps should understand which usecases should go into the screens, and make a mockup of the layout. (At this point we don't need to choose a language yet, nor the complete API, just understand what the webpage should cover)

Is the conversation on this topic ok here? or is it preferred by a special chat?

cgrs commented 2 years ago

What about just having a Web UI completely decoupled from the server? That way anyone who wants to have different UIs can develop them or use them on their own, being in Flutter, Elm or Vue.

fdelucchijr commented 2 years ago

Sounds good, but I think would make a lot more variable the development and if theres no "oficial" web gui gonna come up a lot of unmantained or incompatible versions of the same panel.

@kradalby Say is in development an api. I think with proper docs should be enough for anybody to make a external webgui, and adding a bool parameter to deactivate the internal is more like a'cherry on top (for my idea of a Flutter mobile app this would be awesome).

Obviously this isn't my choice, as implies a handful of definitions in the complete project approach.

Deploy a headscale container with all the components and other with just the server with a companion container for the webgui is something interesting for k8s, tho.

kradalby commented 2 years ago

The API might be available as beta and "subject to change" in the version after next. It will support OpenAPI so client code can be generated.

The API will open for anyone to make a WebUI, so @cgrs, feel free :)

I would assume that at some point we might include one, and having a collected effort might make more sense.

Also having everything in the same binary would be neat and easy to ship around.

srdjanrosic commented 2 years ago

Might be an unpopular opinion, or .. not..

... but, how about not making a web APP at all... and instead, just having the server render some simple html with current status to start with, ... and then maybe adding a few endpoints that can take form submissions to change things down the line.

By this I mean, how about just using go templates for showing a mix of current config and state, and having a few blue links and buttons scattered around to do some common things and move around, ... and relying on simple re-rendering of a page for any complicated UX transitions.

... how it looks can be prettied up well enough with some basic CSS, ... and you could even do things like show/hide and tabs using CSS, ... if that's where things go (spoiler, radio-buttons are mutually exclusive like tabs and can be made to look like so).


Reason I'm leaning toward this solution (over any of the javascript/typescript/wasm + framework-du-jour), is because I think:

a) majority of tailscale (by proxy headscale) users, myself included, would probably appreciate simplicity in their stack b) we'd end up not fragmenting or burdening end users with different UIs that are a potential source of confusion / analysis-paralysis during adoption phase, and a potential support / maintenance burden or a distraction down the road. c) requires very little no additional dependencies or toolchain changes d) requires very little to no additional cognitive load to maintain / build / run .. and extend with new features, as they appear on the back end.


None of that would be necessarily exclusive to having a well thought out API as well ... but having the info laid out in a browser would be a bit more friendly to casual users (folks who don't manage VPNs for a living or as part of their critical role at a company or similar).

Security wise, beyond basic TLS, we'd probably be mostly good with just some basic cryptographic xsrf tokens stuffed in form fields and some explicit http headers (CSP, x-frame-options, that kind of stuff).... not sure how we'd think about identity in the web ui in the first place ... oauth?


development process wise - a good start would be to expose just the read-only status somehow safely, before allowing state mutations through the webui.

bohtho commented 2 years ago

I'm just a weekend code (w)hacker but am a Tailscale (UI/coordinator) user, and my 2p go to a decoupled UI as a simple but modern web gui (precompiled js please). How about something based on Svelte (or Svelte Kit) which is succinct and easy to grok for new developers? Then you smart lot can concentrate on the API and coordinator itself.

klvnptr commented 2 years ago

I suggest using some straightforward decoupled React +Tailwind UI. It is very popular and it is easier to recruit contributors :)

fdelucchijr commented 2 years ago

@kradalby, sorry because of my hiatus, the holidays have been a mess. There's news on the API progress? I've already made a Figma board and started a mood board of different self-hosted solutions to make a wireframe of the UI.

Seen that there's still a debate on how to implement the WebUI at a technical level, I will stick to the conceptual level for now. Probably will drop the Figma board here when I have some of the modules ready.

I will maintain my opinion in a Tailwind-Vue combo, and really don't care much about the coupling in the server-client, but I really think there's a need for a Headscale officially maintained WebUI that at least show the state of the service and allow the admin to configure some settings (the more the better). This will expand the project as the best self-hosted VPN solution for regular users out there.

gedw99 commented 2 years ago

The Tailscale gui for iOS and android is built using gio

i used to use flutter and changed to gio because it’s golang and you don’t get road blocked for doing low level aspects as much as you do with flutter.

We could quite quickly build the web , task tray, desktop and mobile clients using gio I feel .

also because it’s golang it makes it easier because the frontend and backend are all in golang so the same team can work on both.

we can base on

https://github.com/tailscale/tailscale-android

they use https://github.com/tailscale/walk to build their windows desktop gui.

At the time gio was not mature enough for windows compile targets. That’s maybe why they did not use it. It definitely is now.

Gio uses the standard golang build tags to include OS specific golang code .

i have GRPC and GRPC-web working between a gio frontend and go backend too. It just uses a slight fork of the improbable GRPC lib to use a slightly different web socket lib that works with WASM ( which is what gio web builds as ).

using GRPC makes forward engineering happen and supports schema evolution so that if the API on the server changes the clients will not break at runtime . Use buf to manage GRPC and we are good !!

kradalby commented 2 years ago

@fdelucchijr I have not been working on this for a bit, had a break so no news atm. I can see myself starting to play around with headscale in a bit, but not yet.

As for my opinion/decision towards WebUI:

I have decided that if I will work on it, be involved and do possibly a good batch of the work, I will write it in Elm + TailwindCSS (or something like F#/Fable).

The reasoning for this is that I am doing this project for fun, and if I am to enjoy doing this, I cannot use JavaScript/Typescript/Vue/React as I do not find it fun to work with. I do enjoy working with Elm.

I do not intend to mandate that the project is done in Elm, this is mostly to make it clear that if I start it, or am to contribute, that will be the language. If anyone feel strongly about choosing more mainstream tech, that is fine, but then they better start working on it before I get to it and uphold a good enough quality (whatever-that-means).

I have no timeline for when I will consider diving into this as I don't personally need a WebUI for headscale.

As for other implementation details, I think for a WebUI to be viable, it must be embedded in the binary and served without any extra setup. Luckily Go is reasonably good at this.

endigma commented 2 years ago

Is there an HTTP API planned? If there was one I'd make a webui.

gedw99 commented 2 years ago

Is there a link to the Figma screens ?

would be great to have a look at it

artemklevtsov commented 2 years ago

@endigma HTTP API already introduced (see #204).

endigma commented 2 years ago

@endigma HTTP API already introduced (see #204).

docs for routes/payloads anywhere?

artemklevtsov commented 2 years ago

docs for routes/payloads anywhere?

May by here: https://github.com/juanfont/headscale/tree/main/gen/openapiv2/headscale/v1

endigma commented 2 years ago

Cool, I'm probably gonna make a webui then. will post updates when there's something to look at.

artemklevtsov commented 2 years ago

Also could be useful: https://github.com/juanfont/headscale/blob/73497382b7002050b85f6e919f2fc6b9616b4c80/app.go#L415-L434

kradalby commented 2 years ago

This is the relevant part: https://github.com/juanfont/headscale/issues/234#L433.

Before we set of in multiple different directions, what is your idea of what you would like to achieve with the UI @endigma ?

endigma commented 2 years ago

@kradalby

My plan is to re-implement what's in the official tailscale UI likely with Svelte/Tailwind or Pico. If the limitation is in endpoints I'd likely yield feature wise until they are completed. I don't have the time to really dig into learning the whole headscale codebase, but I can handle a front-end.

kradalby commented 2 years ago

ok, just be aware, the API is not stable, and we will change it a fair amount in the upcoming releases.

0.13.0-beta3 is the first release with the API available. But we already have plans to change it quite a bit based on #311.

It supports OpenAPI v2, so if you are planning to contribute it, find a code generator for the API so we get in all the consistency :)

endigma commented 2 years ago

I'll look into code generation, may be able to use swagger to generate a stub client.

kradalby commented 2 years ago

Sounds about right, OpenAPI is what swagger was renamed into. Feel free to reach out to me on Discord if you want to discuss something.

fdelucchijr commented 2 years ago

@kradalby

My plan is to re-implement what's in the official tailscale UI likely with Svelte/Tailwind or Pico. If the limitation is in endpoints I'd likely yield feature wise until they are completed. I don't have the time to really dig into learning the whole headscale codebase, but I can handle a front-end.

If you start a repo prease add me. Or if you gonna add a PR, mention me, I will happily help you. I have had a complete JS to TS migration in the past 2 weeks but in the following time I will be fully able to help. I think my project in Figma gonna be saved until there's a usable UI so we can design with peace of mind and usage experience. In the past few days, I add some ideas such as Netmaker's node view to the management screen.

kradalby commented 2 years ago

Actually, before we set out in many different directions, can we please take a step back and write up a proposal on design and requirements so we don't do double work and ensure it is maintainable?

A bit like #311

@endigma @fdelucchijr

endigma commented 2 years ago

@fdelucchijr @kradalby

I'm happy to tackle this solo as a separate project but if you want to be a part of it you can find my contact info on my website. Reach out and we can discuss working as a team.

One thing that's set in stone is it's definitely not going to be part of this repo, merging a full ts/js/svelte project into an existing go repo sounds like a nightmare.

I'm also in the discord under @endigma4426 if you don't have telegram.

marie6324 commented 2 years ago

Following up on this to see if there's been any movement from anyone involved

routerino commented 1 year ago

Following up on this to see if there's been any movement from anyone involved

A sveltekit/tailwind based web UI is now available, can be found here.

Barring anyone else coming up with their own implementation, what needs to be asked now is the appetite to integrate (or not integrate) this web UI into headscale itself. Here's some considerations that need to be thought out before charging ahead:

(Programming) Language Considerations

There's a bit of talk in this whole thread about sticking to minimal raw HTML/CSS, which I initially tried with alpinejs and htmx. This concept was abandoned, as I (like most people) learned the hard way why all the popular frameworks are compiled javascript languages. Basic things like type checking (typescript), modular css (postcss), and scope management is nearly impossible in vanilla javascript, and makes any serious project quickly become spaghetti.

So the web ui is a mix of svelte-kit (framework), tailwind/daisyui (css) and typescript, compiled down to static html/js/css. This is a good middle ground with low dependencies and meeting the core requirement (being able to be hosted statically). Speaking of which:

Integration with Headscale

Right now it's a bit tricky to use the UI, as it needs to be hosted separately, and CORS needs injection if the hosting isn't on the same subdomain. The CORS issue is fixable, but anything further will depend on the headscale maintainer's appetite to integrate a separate project. So I can see three options with integration:

Authentication

The current system saves an API key to the browser local storage, which isn't ideal, but works. Doing so can potentially be exploited by XSS, but XSS protections are in place with CSP enabled on build. It's a good enough solution, but eventually it would be nice if headscale could be an OIDC relying party for the site, same way it works with tailscale. How this will work with the app is something I haven't investigated and will probably need cooperation with the headscale maintainers if it's a wanted feature.

ACL management

ACL Management is a hard concept to gui-fy, but it's on my immediate radar. The big stopping block is that there is no way to update ACLs via the API, which will be required for this feature to exist. I can start some of that work, but it'll be a big task to manage.

Source code management

There were rumblings about putting the web source into the same repo, which I wouldn't necessarily recommend. If it was all static HTML/CSS/JS, that would be a strong possibility, but not for anything compiled. However if the headscale maintainers want to fork it, I can potentially move development off my own repo.

Thoughts? Many of these considerations need the headscale folks to be on board for implementation, so it's a question of how much they want to get tied to using this UI (if at all).

endigma commented 1 year ago

Now that the API is clearly in a workable state I may take a proper stab at my own UI, not to stomp on the one routerino made though, just my own take.

I'm working professionally with SK/TW now which means I'll probably ironically take the approach routerino abandoned and try low-JS-ing it using some serverside work.

May never go anywhere but I'll post here when/if there's anything to see.

samson4649 commented 1 year ago

I like the idea of a headscale UI for those that need to use a UI to configuration the server. However, it should be separated from the headscale server itself. The server works, and many users dont need or want the extra bloat of a UI they arent going to use.

Additionally, if the built UI artefacts are loaded from a directory, why bundle that into another service? Host the files with a service designed to do that. Something like an nginx container receiving proxy connections for the UI route (i.e /ui/).

routerino commented 1 year ago

I like the idea of a headscale UI for those that need to use a UI to configuration the server. However, it should be separated from the headscale server itself. The server works, and many users dont need or want the extra bloat of a UI they arent going to use.

Additionally, if the built UI artefacts are loaded from a directory, why bundle that into another service? Host the files with a service designed to do that. Something like an nginx container receiving proxy connections for the UI route (i.e /ui/).

Just to be clear 'bloat' is a very subjective term here. The site is 60kb large when compressed and does not use any server resources beyond the download when requested.

kinghat commented 1 year ago

I like the idea of a headscale UI for those that need to use a UI to configuration the server. However, it should be separated from the headscale server itself. The server works, and many users dont need or want the extra bloat of a UI they arent going to use.

id argue the reason all these wg abstractions are popular is because of the ux and user friendly interfaces. otherwise we would all still be doing it from the cli.

kradalby commented 1 year ago

My plan for this would be "Full integration", this means that the UI is bundled with the binary, so it is all shipped together. If you dont want it, there can be a flag to disable it.

However, I do not want it to be presented with the UX we currently have for API keys etc, so it would be a fair amount of backend changes to allow for both or:

This will be fully transparent for the users and provide a smooth user experience. In addition, it would open for machines in the "correct" namespace/user to have only access to their own stuff etc.

I do not have a specific plan on how to achieve this yet, and it will require quite a bit of work, some sort of ACL for user/api access.

x86dev commented 1 year ago

@kradalby Congrats of being hired by the Tailscale team! Can you elaborate how / if this going to have any impact of Headscale's UI work? Thanks!

kradalby commented 1 year ago

Thanks @x86dev :)

This will likely not impact the UI work in the future, I will continue (or get back to) optimise correctness/performance, testing and code cleanup and mostly work on improving the server as what it is. I might extend the API as I see fit to make it more features available, but I don't think I will actively work on the UI.

I am however fully prepared to work with other contributors like @routerino whom is working on it to see if we can get it more integrated if we find the maintenance burden acceptable. We dont want to add the UI and then have it become an unmaintained part of the codebase.

x86dev commented 1 year ago

Sounds good, thanks for the update!

linxd commented 1 year ago

no access control (login) for web-ui now ?

juanfont commented 1 year ago

We could serve this from a tailscale-as-lib-exposed endpoint in headscale, available only from the tailnet.

Like they have https://hello.ts.net/ in the SaaS.

On Sat, Aug 13, 2022, 13:23 Kristoffer Dalby @.***> wrote:

My plan for this would be "Full integration", this means that the UI is bundled with the binary, so it is all shipped together. If you dont want it, there can be a flag to disable it.

However, I do not want it to be presented with the UX we currently have for API keys etc, so it would be a fair amount of backend changes to allow for both or:

This will be fully transparent for the users and provide a smooth user experience. In addition, it would open for machines in the "correct" namespace/user to have only access to their own stuff etc.

I do not have a specific plan on how to achieve this yet, and it will require quite a bit of work, some sort of ACL for user/api access.

— Reply to this email directly, view it on GitHub https://github.com/juanfont/headscale/issues/234#issuecomment-1214141143, or unsubscribe https://github.com/notifications/unsubscribe-auth/AABMGQ4VUK326SL7VH4FRMTVY6ARTANCNFSM5ITJX3FQ . You are receiving this because you are subscribed to this thread.Message ID: @.***>

iFargle commented 1 year ago

I made a front-end for Headscale, available here if anyone is interested: https://git.sysctl.io/albert/headscale-webui/

If there's interest I can move the code to Github. Just created this account to let anyone who might want to use it know. FYI I'm not a programmer by any stretch of the word. This maybe janky but it works for my needs!

anjomro commented 1 year ago

@iFargle This looks very promising and shiny! :tada: I started tweaking it a bit, maybe I can help? My additions can be found here: https://github.com/anjomro/headscale-webui

gps949 commented 1 year ago

anybody wanna look at this? https://github.com/gps949/Mirage D662EC60-DC29-4DED-809D-148C9F564D07 3036847C-C64E-4E3A-93B0-D497C1970EB2 1668F936-5ADB-480C-A7B9-F573BF85896D

ptman commented 1 year ago

@iFargle don't sell yourself short. If you created that then you definitely are a programmer by any stretch.

evenh commented 1 year ago

@iFargle I'm agreeing heavily with @ptman here (it also looks really awesome). I would think that bringing the code to GitHub would make it easier for others to contribute. I see that @anjomro has started bringing down the container image size in his fork already 🎉

iFargle commented 1 year ago

Alright I think I've figured it out... I've moved the repo here: https://github.com/iFargle/headscale-webui

I'm now mirroring it to my personal git instance instead of the other way around. @anjomro - I've added some of your changes. I think I got them all? Now that it's on GitHub it should be easier to work together on this 👍

kradalby commented 1 year ago

This is what I was going (hoping) for when I added the API, specially since I didnt have any immediate plans to make a UI, and now loads of time later, we have some good alternatives.

I think realistically, I will not do any work on a UI in the foreseeable future and I suggest that we add a section to the README with links to the two pure UI alternatives here from @routerino and @iFargle.

@gps949, I would be open to linking yours too, but currently it is a fork and not a UI, would you consider changing that? And we need to mark them with language support.

PRs to add them to the readme will be welcomed.

cloverzrg commented 1 year ago

anybody wanna look at this? https://github.com/gps949/Mirage D662EC60-DC29-4DED-809D-148C9F564D07 3036847C-C64E-4E3A-93B0-D497C1970EB2 1668F936-5ADB-480C-A7B9-F573BF85896D

前后端分离比较好, 把前端单独出来

xrain0610 commented 1 year ago

I made a ui with Angluar 15, it is a static web, credit save in localstorage. https://github.com/simcu/headscale-ui

gbraad commented 1 year ago

I am working on two Cockpit applications; one for the Tailscale client state and management. The other is to manage Headscale for user, node and routes management.


@kradalby the API is not the only way to interact, as with -o json it allows integration similarly as tailscale itself. How 'stable' are the data structures?