1
0
mirror of https://github.com/juanfont/headscale.git synced 2025-08-10 13:46:46 +02:00

Merge branch 'main' into doc-dev

This commit is contained in:
XN 2023-05-11 10:02:10 +08:00 committed by GitHub
commit 6e8e5bd390
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
147 changed files with 1942 additions and 3180 deletions

View File

@ -6,19 +6,24 @@ labels: ["bug"]
assignees: ""
---
<!-- Headscale is a multinational community across the globe. Our common language is English. Please consider raising the bug report in this language. -->
<!--
Before posting a bug report, discuss the behaviour you are expecting with the Discord community
to make sure that it is truly a bug.
The issue tracker is not the place to ask for support or how to set up Headscale.
**Bug description**
Bug reports without the sufficient information will be closed.
Headscale is a multinational community across the globe. Our language is English.
All bug reports needs to be in English.
-->
## Bug description
<!-- A clear and concise description of what the bug is. Describe the expected bahavior
and how it is currently different. If you are unsure if it is a bug, consider discussing
it on our Discord server first. -->
**To Reproduce**
<!-- Steps to reproduce the behavior. -->
**Context info**
## Environment
<!-- Please add relevant information about your system. For example:
- Version of headscale used
@ -28,3 +33,20 @@ assignees: ""
- The relevant config parameters you used
- Log output
-->
- OS:
- Headscale version:
- Tailscale version:
<!--
We do not support running Headscale in a container nor behind a (reverse) proxy.
If either of these are true for your environment, ask the community in Discord
instead of filing a bug report.
-->
- [ ] Headscale is behind a (reverse) proxy
- [ ] Headscale runs in a container
## To Reproduce
<!-- Steps to reproduce the behavior. -->

View File

@ -6,12 +6,21 @@ labels: ["enhancement"]
assignees: ""
---
<!-- Headscale is a multinational community across the globe. Our common language is English. Please consider raising the feature request in this language. -->
<!--
We typically have a clear roadmap for what we want to improve and reserve the right
to close feature requests that does not fit in the roadmap, or fit with the scope
of the project, or we actually want to implement ourselves.
**Feature request**
Headscale is a multinational community across the globe. Our language is English.
All bug reports needs to be in English.
-->
<!-- A clear and precise description of what new or changed feature you want. -->
## Why
<!-- Please include the reason, why you would need the feature. E.g. what problem
<!-- Include the reason, why you would need the feature. E.g. what problem
does it solve? Or which workflow is currently frustrating and will be improved by
this? -->
## Description
<!-- A clear and precise description of what new or changed feature you want. -->

View File

@ -1,30 +0,0 @@
---
name: "Other issue"
about: "Report a different issue"
title: ""
labels: ["bug"]
assignees: ""
---
<!-- Headscale is a multinational community across the globe. Our common language is English. Please consider raising the issue in this language. -->
<!-- If you have a question, please consider using our Discord for asking questions -->
**Issue description**
<!-- Please add your issue description. -->
**To Reproduce**
<!-- Steps to reproduce the behavior. -->
**Context info**
<!-- Please add relevant information about your system. For example:
- Version of headscale used
- Version of tailscale client
- OS (e.g. Linux, Mac, Cygwin, WSL, etc.) and version
- Kernel version
- The relevant config parameters you used
- Log output
-->

View File

@ -1,3 +1,15 @@
<!--
Headscale is "Open Source, acknowledged contribution", this means that any
contribution will have to be discussed with the Maintainers before being submitted.
This model has been chosen to reduce the risk of burnout by limiting the
maintenance overhead of reviewing and validating third-party code.
Headscale is open to code contributions for bug fixes without discussion.
If you find mistakes in the documentation, please submit a fix to the documentation.
-->
<!-- Please tick if the following things apply. You… -->
- [ ] read the [CONTRIBUTING guidelines](README.md#contributing)

26
.github/renovate.json vendored
View File

@ -6,31 +6,27 @@
"onboarding": false,
"extends": ["config:base", ":rebaseStalePrs"],
"ignorePresets": [":prHourlyLimit2"],
"enabledManagers": ["dockerfile", "gomod", "github-actions","regex" ],
"enabledManagers": ["dockerfile", "gomod", "github-actions", "regex"],
"includeForks": true,
"repositories": ["juanfont/headscale"],
"platform": "github",
"packageRules": [
{
"matchDatasources": ["go"],
"groupName": "Go modules",
"groupSlug": "gomod",
"separateMajorMinor": false
"matchDatasources": ["go"],
"groupName": "Go modules",
"groupSlug": "gomod",
"separateMajorMinor": false
},
{
"matchDatasources": ["docker"],
"groupName": "Dockerfiles",
"groupSlug": "dockerfiles"
}
"matchDatasources": ["docker"],
"groupName": "Dockerfiles",
"groupSlug": "dockerfiles"
}
],
"regexManagers": [
{
"fileMatch": [
".github/workflows/.*.yml$"
],
"matchStrings": [
"\\s*go-version:\\s*\"?(?<currentValue>.*?)\"?\\n"
],
"fileMatch": [".github/workflows/.*.yml$"],
"matchStrings": ["\\s*go-version:\\s*\"?(?<currentValue>.*?)\"?\\n"],
"datasourceTemplate": "golang-version",
"depNameTemplate": "actions/go-version"
}

View File

@ -1,35 +0,0 @@
name: Integration Test CLI
on: [pull_request]
jobs:
integration-test-cli:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 2
- name: Set Swap Space
uses: pierotofy/set-swap-space@master
with:
swap-size-gb: 10
- name: Get changed files
id: changed-files
uses: tj-actions/changed-files@v34
with:
files: |
*.nix
go.*
**/*.go
integration_test/
config-example.yaml
- uses: cachix/install-nix-action@v16
if: steps.changed-files.outputs.any_changed == 'true'
- name: Run CLI integration tests
if: steps.changed-files.outputs.any_changed == 'true'
run: nix develop --command -- make test_integration_cli

View File

@ -43,7 +43,7 @@ jobs:
--volume /var/run/docker.sock:/var/run/docker.sock \
--volume $PWD/control_logs:/tmp/control \
golang:1 \
go test ./... \
go run gotest.tools/gotestsum@latest -- ./... \
-tags ts2019 \
-failfast \
-timeout 120m \

View File

@ -43,7 +43,7 @@ jobs:
--volume /var/run/docker.sock:/var/run/docker.sock \
--volume $PWD/control_logs:/tmp/control \
golang:1 \
go test ./... \
go run gotest.tools/gotestsum@latest -- ./... \
-tags ts2019 \
-failfast \
-timeout 120m \

View File

@ -43,7 +43,7 @@ jobs:
--volume /var/run/docker.sock:/var/run/docker.sock \
--volume $PWD/control_logs:/tmp/control \
golang:1 \
go test ./... \
go run gotest.tools/gotestsum@latest -- ./... \
-tags ts2019 \
-failfast \
-timeout 120m \

View File

@ -43,7 +43,7 @@ jobs:
--volume /var/run/docker.sock:/var/run/docker.sock \
--volume $PWD/control_logs:/tmp/control \
golang:1 \
go test ./... \
go run gotest.tools/gotestsum@latest -- ./... \
-tags ts2019 \
-failfast \
-timeout 120m \

View File

@ -43,7 +43,7 @@ jobs:
--volume /var/run/docker.sock:/var/run/docker.sock \
--volume $PWD/control_logs:/tmp/control \
golang:1 \
go test ./... \
go run gotest.tools/gotestsum@latest -- ./... \
-tags ts2019 \
-failfast \
-timeout 120m \

View File

@ -43,7 +43,7 @@ jobs:
--volume /var/run/docker.sock:/var/run/docker.sock \
--volume $PWD/control_logs:/tmp/control \
golang:1 \
go test ./... \
go run gotest.tools/gotestsum@latest -- ./... \
-tags ts2019 \
-failfast \
-timeout 120m \

View File

@ -43,7 +43,7 @@ jobs:
--volume /var/run/docker.sock:/var/run/docker.sock \
--volume $PWD/control_logs:/tmp/control \
golang:1 \
go test ./... \
go run gotest.tools/gotestsum@latest -- ./... \
-tags ts2019 \
-failfast \
-timeout 120m \

View File

@ -43,7 +43,7 @@ jobs:
--volume /var/run/docker.sock:/var/run/docker.sock \
--volume $PWD/control_logs:/tmp/control \
golang:1 \
go test ./... \
go run gotest.tools/gotestsum@latest -- ./... \
-tags ts2019 \
-failfast \
-timeout 120m \

View File

@ -43,7 +43,7 @@ jobs:
--volume /var/run/docker.sock:/var/run/docker.sock \
--volume $PWD/control_logs:/tmp/control \
golang:1 \
go test ./... \
go run gotest.tools/gotestsum@latest -- ./... \
-tags ts2019 \
-failfast \
-timeout 120m \

View File

@ -43,7 +43,7 @@ jobs:
--volume /var/run/docker.sock:/var/run/docker.sock \
--volume $PWD/control_logs:/tmp/control \
golang:1 \
go test ./... \
go run gotest.tools/gotestsum@latest -- ./... \
-tags ts2019 \
-failfast \
-timeout 120m \

View File

@ -43,7 +43,7 @@ jobs:
--volume /var/run/docker.sock:/var/run/docker.sock \
--volume $PWD/control_logs:/tmp/control \
golang:1 \
go test ./... \
go run gotest.tools/gotestsum@latest -- ./... \
-tags ts2019 \
-failfast \
-timeout 120m \

View File

@ -43,7 +43,7 @@ jobs:
--volume /var/run/docker.sock:/var/run/docker.sock \
--volume $PWD/control_logs:/tmp/control \
golang:1 \
go test ./... \
go run gotest.tools/gotestsum@latest -- ./... \
-tags ts2019 \
-failfast \
-timeout 120m \

View File

@ -43,7 +43,7 @@ jobs:
--volume /var/run/docker.sock:/var/run/docker.sock \
--volume $PWD/control_logs:/tmp/control \
golang:1 \
go test ./... \
go run gotest.tools/gotestsum@latest -- ./... \
-tags ts2019 \
-failfast \
-timeout 120m \

View File

@ -43,7 +43,7 @@ jobs:
--volume /var/run/docker.sock:/var/run/docker.sock \
--volume $PWD/control_logs:/tmp/control \
golang:1 \
go test ./... \
go run gotest.tools/gotestsum@latest -- ./... \
-tags ts2019 \
-failfast \
-timeout 120m \

View File

@ -43,7 +43,7 @@ jobs:
--volume /var/run/docker.sock:/var/run/docker.sock \
--volume $PWD/control_logs:/tmp/control \
golang:1 \
go test ./... \
go run gotest.tools/gotestsum@latest -- ./... \
-tags ts2019 \
-failfast \
-timeout 120m \

View File

@ -43,7 +43,7 @@ jobs:
--volume /var/run/docker.sock:/var/run/docker.sock \
--volume $PWD/control_logs:/tmp/control \
golang:1 \
go test ./... \
go run gotest.tools/gotestsum@latest -- ./... \
-tags ts2019 \
-failfast \
-timeout 120m \

View File

@ -43,7 +43,7 @@ jobs:
--volume /var/run/docker.sock:/var/run/docker.sock \
--volume $PWD/control_logs:/tmp/control \
golang:1 \
go test ./... \
go run gotest.tools/gotestsum@latest -- ./... \
-tags ts2019 \
-failfast \
-timeout 120m \

View File

@ -43,7 +43,7 @@ jobs:
--volume /var/run/docker.sock:/var/run/docker.sock \
--volume $PWD/control_logs:/tmp/control \
golang:1 \
go test ./... \
go run gotest.tools/gotestsum@latest -- ./... \
-tags ts2019 \
-failfast \
-timeout 120m \

View File

@ -43,7 +43,7 @@ jobs:
--volume /var/run/docker.sock:/var/run/docker.sock \
--volume $PWD/control_logs:/tmp/control \
golang:1 \
go test ./... \
go run gotest.tools/gotestsum@latest -- ./... \
-tags ts2019 \
-failfast \
-timeout 120m \

View File

@ -43,7 +43,7 @@ jobs:
--volume /var/run/docker.sock:/var/run/docker.sock \
--volume $PWD/control_logs:/tmp/control \
golang:1 \
go test ./... \
go run gotest.tools/gotestsum@latest -- ./... \
-tags ts2019 \
-failfast \
-timeout 120m \

View File

@ -43,7 +43,7 @@ jobs:
--volume /var/run/docker.sock:/var/run/docker.sock \
--volume $PWD/control_logs:/tmp/control \
golang:1 \
go test ./... \
go run gotest.tools/gotestsum@latest -- ./... \
-tags ts2019 \
-failfast \
-timeout 120m \

View File

@ -43,7 +43,7 @@ jobs:
--volume /var/run/docker.sock:/var/run/docker.sock \
--volume $PWD/control_logs:/tmp/control \
golang:1 \
go test ./... \
go run gotest.tools/gotestsum@latest -- ./... \
-tags ts2019 \
-failfast \
-timeout 120m \

View File

@ -43,7 +43,7 @@ jobs:
--volume /var/run/docker.sock:/var/run/docker.sock \
--volume $PWD/control_logs:/tmp/control \
golang:1 \
go test ./... \
go run gotest.tools/gotestsum@latest -- ./... \
-tags ts2019 \
-failfast \
-timeout 120m \

View File

@ -43,7 +43,7 @@ jobs:
--volume /var/run/docker.sock:/var/run/docker.sock \
--volume $PWD/control_logs:/tmp/control \
golang:1 \
go test ./... \
go run gotest.tools/gotestsum@latest -- ./... \
-tags ts2019 \
-failfast \
-timeout 120m \

View File

@ -43,7 +43,7 @@ jobs:
--volume /var/run/docker.sock:/var/run/docker.sock \
--volume $PWD/control_logs:/tmp/control \
golang:1 \
go test ./... \
go run gotest.tools/gotestsum@latest -- ./... \
-tags ts2019 \
-failfast \
-timeout 120m \

View File

@ -43,7 +43,7 @@ jobs:
--volume /var/run/docker.sock:/var/run/docker.sock \
--volume $PWD/control_logs:/tmp/control \
golang:1 \
go test ./... \
go run gotest.tools/gotestsum@latest -- ./... \
-tags ts2019 \
-failfast \
-timeout 120m \

View File

@ -43,7 +43,7 @@ jobs:
--volume /var/run/docker.sock:/var/run/docker.sock \
--volume $PWD/control_logs:/tmp/control \
golang:1 \
go test ./... \
go run gotest.tools/gotestsum@latest -- ./... \
-tags ts2019 \
-failfast \
-timeout 120m \

View File

@ -43,7 +43,7 @@ jobs:
--volume /var/run/docker.sock:/var/run/docker.sock \
--volume $PWD/control_logs:/tmp/control \
golang:1 \
go test ./... \
go run gotest.tools/gotestsum@latest -- ./... \
-tags ts2019 \
-failfast \
-timeout 120m \

View File

@ -43,7 +43,7 @@ jobs:
--volume /var/run/docker.sock:/var/run/docker.sock \
--volume $PWD/control_logs:/tmp/control \
golang:1 \
go test ./... \
go run gotest.tools/gotestsum@latest -- ./... \
-tags ts2019 \
-failfast \
-timeout 120m \

View File

@ -43,7 +43,7 @@ jobs:
--volume /var/run/docker.sock:/var/run/docker.sock \
--volume $PWD/control_logs:/tmp/control \
golang:1 \
go test ./... \
go run gotest.tools/gotestsum@latest -- ./... \
-tags ts2019 \
-failfast \
-timeout 120m \

View File

@ -43,7 +43,7 @@ jobs:
--volume /var/run/docker.sock:/var/run/docker.sock \
--volume $PWD/control_logs:/tmp/control \
golang:1 \
go test ./... \
go run gotest.tools/gotestsum@latest -- ./... \
-tags ts2019 \
-failfast \
-timeout 120m \

View File

@ -43,7 +43,7 @@ jobs:
--volume /var/run/docker.sock:/var/run/docker.sock \
--volume $PWD/control_logs:/tmp/control \
golang:1 \
go test ./... \
go run gotest.tools/gotestsum@latest -- ./... \
-tags ts2019 \
-failfast \
-timeout 120m \

View File

@ -43,7 +43,7 @@ jobs:
--volume /var/run/docker.sock:/var/run/docker.sock \
--volume $PWD/control_logs:/tmp/control \
golang:1 \
go test ./... \
go run gotest.tools/gotestsum@latest -- ./... \
-tags ts2019 \
-failfast \
-timeout 120m \

View File

@ -2,6 +2,14 @@
## 0.23.0 (2023-XX-XX)
### BREAKING
- Code reorganisation, a lot of code has moved, please review the following PRs accordingly [#1444](https://github.com/juanfont/headscale/pull/1444)
### Changes
## 0.22.2 (2023-05-10)
### Changes
- Add environment flags to enable pprof (profiling) [#1382](https://github.com/juanfont/headscale/pull/1382)
@ -9,8 +17,11 @@
- Fix systemd service file location in `.deb` packages [#1391](https://github.com/juanfont/headscale/pull/1391)
- Improvements on Noise implementation [#1379](https://github.com/juanfont/headscale/pull/1379)
- Replace node filter logic, ensuring nodes with access can see eachother [#1381](https://github.com/juanfont/headscale/pull/1381)
- Disable (or delete) both exit routes at the same time [#1428](https://github.com/juanfont/headscale/pull/1428)
- Ditch distroless for Docker image, create default socket dir in `/var/run/headscale` [#1450](https://github.com/juanfont/headscale/pull/1450)
- Updated docker related doc, added example docker compose file [#1421](https://github.com/juanfont/headscale/pull/1421)
## 0.22.1 (2023-04-20)
### Changes

View File

@ -14,10 +14,12 @@ RUN strip /go/bin/headscale
RUN test -e /go/bin/headscale
# Production image
FROM gcr.io/distroless/base-debian11
FROM docker.io/debian:bullseye-slim
COPY --from=build /go/bin/headscale /bin/headscale
ENV TZ UTC
RUN mkdir -p /var/run/headscale
EXPOSE 8080/tcp
CMD ["headscale"]

View File

@ -18,6 +18,8 @@ FROM docker.io/golang:1.20.0-bullseye
COPY --from=build /go/bin/headscale /bin/headscale
ENV TZ UTC
RUN mkdir -p /var/run/headscale
# Need to reset the entrypoint or everything will run as a busybox script
ENTRYPOINT []
EXPOSE 8080/tcp

View File

@ -24,21 +24,9 @@ build:
dev: lint test build
test:
@go test $(TAGS) -short -coverprofile=coverage.out ./...
gotestsum -- $(TAGS) -short -coverprofile=coverage.out ./...
test_integration: test_integration_cli test_integration_derp test_integration_v2_general
test_integration_cli:
docker network rm $$(docker network ls --filter name=headscale --quiet) || true
docker network create headscale-test || true
docker run -t --rm \
--network headscale-test \
-v ~/.cache/hs-integration-go:/go \
-v $$PWD:$$PWD -w $$PWD \
-v /var/run/docker.sock:/var/run/docker.sock golang:1 \
go run gotest.tools/gotestsum@latest -- $(TAGS) -failfast -timeout 30m -count=1 -run IntegrationCLI ./...
test_integration_v2_general:
test_integration:
docker run \
-t --rm \
-v ~/.cache/hs-integration-go:/go \

View File

@ -32,21 +32,18 @@ organisation.
## Design goal
`headscale` aims to implement a self-hosted, open source alternative to the Tailscale
control server. `headscale` has a narrower scope and an instance of `headscale`
implements a _single_ Tailnet, which is typically what a single organisation, or
home/personal setup would use.
Headscale aims to implement a self-hosted, open source alternative to the Tailscale
control server.
Headscale's goal is to provide self-hosters and hobbyists with an open-source
server they can use for their projects and labs.
It implements a narrow scope, a single Tailnet, suitable for a personal use, or a small
open-source organisation.
`headscale` uses terms that maps to Tailscale's control server, consult the
## Support
## Supporting Headscale
If you like `headscale` and find it useful, there is a sponsorship and donation
buttons available in the repo.
If you would like to sponsor features, bugs or prioritisation, reach out to
one of the maintainers.
## Features
- Full "base" support of Tailscale's features
@ -78,17 +75,11 @@ one of the maintainers.
## Running headscale
**Please note that we do not support nor encourage the use of reverse proxies
and container to run Headscale.**
Please have a look at the [`documentation`](https://headscale.net/).
## Graphical Control Panels
Headscale provides an API for complete management of your Tailnet.
These are community projects not directly affiliated with the Headscale project.
| Name | Repository Link | Description | Status |
| --------------- | ---------------------------------------------------- | ------------------------------------------------------ | ------ |
| headscale-webui | [Github](https://github.com/ifargle/headscale-webui) | A simple Headscale web UI for small-scale deployments. | Alpha |
## Talks
- Fosdem 2023 (video): [Headscale: How we are using integration testing to reimplement Tailscale](https://fosdem.org/2023/schedule/event/goheadscale/)
@ -96,11 +87,23 @@ These are community projects not directly affiliated with the Headscale project.
## Disclaimer
1. We have nothing to do with Tailscale, or Tailscale Inc.
1. This project is not associated with Tailscale Inc.
2. The purpose of Headscale is maintaining a working, self-hosted Tailscale control panel.
## Contributing
Headscale is "Open Source, acknowledged contribution", this means that any
contribution will have to be discussed with the Maintainers before being submitted.
This model has been chosen to reduce the risk of burnout by limiting the
maintenance overhead of reviewing and validating third-party code.
Headscale is open to code contributions for bug fixes without discussion.
If you find mistakes in the documentation, please submit a fix to the documentation.
### Requirements
To contribute to headscale you would need the lastest version of [Go](https://golang.org)
and [Buf](https://buf.build)(Protobuf generator).
@ -108,8 +111,6 @@ We recommend using [Nix](https://nixos.org/) to setup a development environment.
be done with `nix develop`, which will install the tools and give you a shell.
This guarantees that you will have the same dev env as `headscale` maintainers.
PRs and suggestions are welcome.
### Code style
To ensure we have some consistency with a growing number of contributions,

View File

@ -64,7 +64,7 @@ jobs:
--volume /var/run/docker.sock:/var/run/docker.sock \
--volume $PWD/control_logs:/tmp/control \
golang:1 \
go test ./... \
go run gotest.tools/gotestsum@latest -- ./... \
-tags ts2019 \
-failfast \
-timeout 120m \

View File

@ -5,8 +5,8 @@ import (
"strconv"
"time"
"github.com/juanfont/headscale"
v1 "github.com/juanfont/headscale/gen/go/headscale/v1"
"github.com/juanfont/headscale/hscontrol"
"github.com/prometheus/common/model"
"github.com/pterm/pterm"
"github.com/rs/zerolog/log"
@ -83,7 +83,7 @@ var listAPIKeys = &cobra.Command{
}
tableData = append(tableData, []string{
strconv.FormatUint(key.GetId(), headscale.Base10),
strconv.FormatUint(key.GetId(), hscontrol.Base10),
key.GetPrefix(),
expiration,
key.GetCreatedAt().AsTime().Format(HeadscaleDateTimeFormat),

View File

@ -3,8 +3,8 @@ package cli
import (
"fmt"
"github.com/juanfont/headscale"
v1 "github.com/juanfont/headscale/gen/go/headscale/v1"
"github.com/juanfont/headscale/hscontrol"
"github.com/rs/zerolog/log"
"github.com/spf13/cobra"
"google.golang.org/grpc/status"
@ -93,7 +93,7 @@ var createNodeCmd = &cobra.Command{
return
}
if !headscale.NodePublicKeyRegex.Match([]byte(machineKey)) {
if !hscontrol.NodePublicKeyRegex.Match([]byte(machineKey)) {
err = errPreAuthKeyMalformed
ErrorOutput(
err,

View File

@ -9,8 +9,8 @@ import (
"time"
survey "github.com/AlecAivazis/survey/v2"
"github.com/juanfont/headscale"
v1 "github.com/juanfont/headscale/gen/go/headscale/v1"
"github.com/juanfont/headscale/hscontrol"
"github.com/pterm/pterm"
"github.com/spf13/cobra"
"google.golang.org/grpc/status"
@ -529,7 +529,7 @@ func nodesToPtables(
var machineKey key.MachinePublic
err := machineKey.UnmarshalText(
[]byte(headscale.MachinePublicKeyEnsurePrefix(machine.MachineKey)),
[]byte(hscontrol.MachinePublicKeyEnsurePrefix(machine.MachineKey)),
)
if err != nil {
machineKey = key.MachinePublic{}
@ -537,7 +537,7 @@ func nodesToPtables(
var nodeKey key.NodePublic
err = nodeKey.UnmarshalText(
[]byte(headscale.NodePublicKeyEnsurePrefix(machine.NodeKey)),
[]byte(hscontrol.NodePublicKeyEnsurePrefix(machine.NodeKey)),
)
if err != nil {
return nil, err
@ -596,7 +596,7 @@ func nodesToPtables(
}
nodeData := []string{
strconv.FormatUint(machine.Id, headscale.Base10),
strconv.FormatUint(machine.Id, hscontrol.Base10),
machine.Name,
machine.GetGivenName(),
machineKey.ShortString(),

View File

@ -5,7 +5,7 @@ import (
"os"
"runtime"
"github.com/juanfont/headscale"
"github.com/juanfont/headscale/hscontrol"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"github.com/spf13/cobra"
@ -38,18 +38,18 @@ func initConfig() {
cfgFile = os.Getenv("HEADSCALE_CONFIG")
}
if cfgFile != "" {
err := headscale.LoadConfig(cfgFile, true)
err := hscontrol.LoadConfig(cfgFile, true)
if err != nil {
log.Fatal().Caller().Err(err).Msgf("Error loading config file %s", cfgFile)
}
} else {
err := headscale.LoadConfig("", false)
err := hscontrol.LoadConfig("", false)
if err != nil {
log.Fatal().Caller().Err(err).Msgf("Error loading config")
}
}
cfg, err := headscale.GetHeadscaleConfig()
cfg, err := hscontrol.GetHeadscaleConfig()
if err != nil {
log.Fatal().Caller().Err(err)
}
@ -64,7 +64,7 @@ func initConfig() {
zerolog.SetGlobalLevel(zerolog.Disabled)
}
if cfg.Log.Format == headscale.JSONLogFormat {
if cfg.Log.Format == hscontrol.JSONLogFormat {
log.Logger = log.Output(os.Stdout)
}

View File

@ -6,8 +6,8 @@ import (
"net/netip"
"strconv"
"github.com/juanfont/headscale"
v1 "github.com/juanfont/headscale/gen/go/headscale/v1"
"github.com/juanfont/headscale/hscontrol"
"github.com/pterm/pterm"
"github.com/spf13/cobra"
"google.golang.org/grpc/status"
@ -277,7 +277,7 @@ func routesToPtables(routes []*v1.Route) pterm.TableData {
continue
}
if prefix == headscale.ExitRouteV4 || prefix == headscale.ExitRouteV6 {
if prefix == hscontrol.ExitRouteV4 || prefix == hscontrol.ExitRouteV6 {
isPrimaryStr = "-"
} else {
isPrimaryStr = strconv.FormatBool(route.IsPrimary)

View File

@ -4,8 +4,8 @@ import (
"fmt"
survey "github.com/AlecAivazis/survey/v2"
"github.com/juanfont/headscale"
v1 "github.com/juanfont/headscale/gen/go/headscale/v1"
"github.com/juanfont/headscale/hscontrol"
"github.com/pterm/pterm"
"github.com/rs/zerolog/log"
"github.com/spf13/cobra"
@ -21,7 +21,7 @@ func init() {
}
const (
errMissingParameter = headscale.Error("missing parameters")
errMissingParameter = hscontrol.Error("missing parameters")
)
var userCmd = &cobra.Command{

View File

@ -8,8 +8,8 @@ import (
"os"
"reflect"
"github.com/juanfont/headscale"
v1 "github.com/juanfont/headscale/gen/go/headscale/v1"
"github.com/juanfont/headscale/hscontrol"
"github.com/rs/zerolog/log"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
@ -22,8 +22,8 @@ const (
SocketWritePermissions = 0o666
)
func getHeadscaleApp() (*headscale.Headscale, error) {
cfg, err := headscale.GetHeadscaleConfig()
func getHeadscaleApp() (*hscontrol.Headscale, error) {
cfg, err := hscontrol.GetHeadscaleConfig()
if err != nil {
return nil, fmt.Errorf(
"failed to load configuration while creating headscale instance: %w",
@ -31,7 +31,7 @@ func getHeadscaleApp() (*headscale.Headscale, error) {
)
}
app, err := headscale.NewHeadscale(cfg)
app, err := hscontrol.NewHeadscale(cfg)
if err != nil {
return nil, err
}
@ -39,8 +39,8 @@ func getHeadscaleApp() (*headscale.Headscale, error) {
// We are doing this here, as in the future could be cool to have it also hot-reload
if cfg.ACL.PolicyPath != "" {
aclPath := headscale.AbsolutePathFromConfigPath(cfg.ACL.PolicyPath)
err = app.LoadACLPolicy(aclPath)
aclPath := hscontrol.AbsolutePathFromConfigPath(cfg.ACL.PolicyPath)
err = app.LoadACLPolicyFromPath(aclPath)
if err != nil {
log.Fatal().
Str("path", aclPath).
@ -53,7 +53,7 @@ func getHeadscaleApp() (*headscale.Headscale, error) {
}
func getHeadscaleCLIClient() (context.Context, v1.HeadscaleServiceClient, *grpc.ClientConn, context.CancelFunc) {
cfg, err := headscale.GetHeadscaleConfig()
cfg, err := hscontrol.GetHeadscaleConfig()
if err != nil {
log.Fatal().
Err(err).
@ -74,7 +74,7 @@ func getHeadscaleCLIClient() (context.Context, v1.HeadscaleServiceClient, *grpc.
address := cfg.CLI.Address
// If the address is not set, we assume that we are on the server hosting headscale.
// If the address is not set, we assume that we are on the server hosting hscontrol.
if address == "" {
log.Debug().
Str("socket", cfg.UnixSocket).
@ -98,7 +98,7 @@ func getHeadscaleCLIClient() (context.Context, v1.HeadscaleServiceClient, *grpc.
grpcOptions = append(
grpcOptions,
grpc.WithTransportCredentials(insecure.NewCredentials()),
grpc.WithContextDialer(headscale.GrpcSocketDialer),
grpc.WithContextDialer(hscontrol.GrpcSocketDialer),
)
} else {
// If we are not connecting to a local server, require an API key for authentication

View File

@ -7,7 +7,7 @@ import (
"strings"
"testing"
"github.com/juanfont/headscale"
"github.com/juanfont/headscale/hscontrol"
"github.com/spf13/viper"
"gopkg.in/check.v1"
)
@ -50,7 +50,7 @@ func (*Suite) TestConfigFileLoading(c *check.C) {
}
// Load example config, it should load without validation errors
err = headscale.LoadConfig(cfgFile, true)
err = hscontrol.LoadConfig(cfgFile, true)
c.Assert(err, check.IsNil)
// Test that config file was interpreted correctly
@ -64,7 +64,7 @@ func (*Suite) TestConfigFileLoading(c *check.C) {
c.Assert(viper.GetString("tls_letsencrypt_challenge_type"), check.Equals, "HTTP-01")
c.Assert(viper.GetStringSlice("dns_config.nameservers")[0], check.Equals, "1.1.1.1")
c.Assert(
headscale.GetFileMode("unix_socket_permission"),
hscontrol.GetFileMode("unix_socket_permission"),
check.Equals,
fs.FileMode(0o770),
)
@ -93,7 +93,7 @@ func (*Suite) TestConfigLoading(c *check.C) {
}
// Load example config, it should load without validation errors
err = headscale.LoadConfig(tmpDir, false)
err = hscontrol.LoadConfig(tmpDir, false)
c.Assert(err, check.IsNil)
// Test that config file was interpreted correctly
@ -107,7 +107,7 @@ func (*Suite) TestConfigLoading(c *check.C) {
c.Assert(viper.GetString("tls_letsencrypt_challenge_type"), check.Equals, "HTTP-01")
c.Assert(viper.GetStringSlice("dns_config.nameservers")[0], check.Equals, "1.1.1.1")
c.Assert(
headscale.GetFileMode("unix_socket_permission"),
hscontrol.GetFileMode("unix_socket_permission"),
check.Equals,
fs.FileMode(0o770),
)
@ -137,10 +137,10 @@ func (*Suite) TestDNSConfigLoading(c *check.C) {
}
// Load example config, it should load without validation errors
err = headscale.LoadConfig(tmpDir, false)
err = hscontrol.LoadConfig(tmpDir, false)
c.Assert(err, check.IsNil)
dnsConfig, baseDomain := headscale.GetDNSConfig()
dnsConfig, baseDomain := hscontrol.GetDNSConfig()
c.Assert(dnsConfig.Nameservers[0].String(), check.Equals, "1.1.1.1")
c.Assert(dnsConfig.Resolvers[0].Addr, check.Equals, "1.1.1.1")
@ -172,7 +172,7 @@ noise:
writeConfig(c, tmpDir, configYaml)
// Check configuration validation errors (1)
err = headscale.LoadConfig(tmpDir, false)
err = hscontrol.LoadConfig(tmpDir, false)
c.Assert(err, check.NotNil)
// check.Matches can not handle multiline strings
tmp := strings.ReplaceAll(err.Error(), "\n", "***")
@ -201,6 +201,6 @@ tls_letsencrypt_hostname: example.com
tls_letsencrypt_challenge_type: TLS-ALPN-01
`)
writeConfig(c, tmpDir, configYaml)
err = headscale.LoadConfig(tmpDir, false)
err = hscontrol.LoadConfig(tmpDir, false)
c.Assert(err, check.IsNil)
}

View File

@ -58,11 +58,12 @@ noise:
# List of IP prefixes to allocate tailaddresses from.
# Each prefix consists of either an IPv4 or IPv6 address,
# and the associated prefix length, delimited by a slash.
# While this looks like it can take arbitrary values, it
# needs to be within IP ranges supported by the Tailscale
# client.
# It must be within IP ranges supported by the Tailscale
# client - i.e., subnets of 100.64.0.0/10 and fd7a:115c:a1e0::/48.
# See below:
# IPv6: https://github.com/tailscale/tailscale/blob/22ebb25e833264f58d7c3f534a8b166894a89536/net/tsaddr/tsaddr.go#LL81C52-L81C71
# IPv4: https://github.com/tailscale/tailscale/blob/22ebb25e833264f58d7c3f534a8b166894a89536/net/tsaddr/tsaddr.go#L33
# Any other range is NOT supported, and it will cause unexpected issues.
ip_prefixes:
- fd7a:115c:a1e0::/48
- 100.64.0.0/10
@ -256,7 +257,7 @@ dns_config:
# Unix socket used for the CLI to connect without authentication
# Note: for production you will want to set this to something like:
unix_socket: /var/run/headscale.sock
unix_socket: /var/run/headscale/headscale.sock
unix_socket_permission: "0770"
#
# headscale supports experimental OpenID connect support,

View File

@ -14,6 +14,8 @@ If the node is already registered, it can advertise exit capabilities like this:
$ sudo tailscale set --advertise-exit-node
```
To use a node as an exit node, IP forwarding must be enabled on the node. Check the official [Tailscale documentation](https://tailscale.com/kb/1019/subnets/?tab=linux#enable-ip-forwarding) for how to enable IP fowarding.
## On the control server
```console

53
docs/faq.md Normal file
View File

@ -0,0 +1,53 @@
---
hide:
- navigation
---
# Frequently Asked Questions
## What is the design goal of headscale?
`headscale` aims to implement a self-hosted, open source alternative to the [Tailscale](https://tailscale.com/)
control server.
`headscale`'s goal is to provide self-hosters and hobbyists with an open-source
server they can use for their projects and labs.
It implements a narrow scope, a _single_ Tailnet, suitable for a personal use, or a small
open-source organisation.
## How can I contribute?
Headscale is "Open Source, acknowledged contribution", this means that any
contribution will have to be discussed with the Maintainers before being submitted.
Headscale is open to code contributions for bug fixes without discussion.
If you find mistakes in the documentation, please also submit a fix to the documentation.
## Why is 'acknowledged contribution' the chosen model?
Both maintainers have full-time jobs and families, and we want to avoid burnout. We also want to avoid frustration from contributors when their PRs are not accepted.
We are more than happy to exchange emails, or to have dedicated calls before a PR is submitted.
## When/Why is Feature X going to be implemented?
We don't know. We might be working on it. If you want to help, please send us a PR.
Please be aware that there are a number of reasons why we might not accept specific contributions:
- It is not possible to implement the feature in a way that makes sense in a self-hosted environment.
- Given that we are reverse-engineering Tailscale to satify our own curiosity, we might be interested in implementing the feature ourselves.
- You are not sending unit and integration tests with it.
## Do you support Y method of deploying Headscale?
We currently support deploying `headscale` using our binaries and the DEB packages. Both can be found in the
[GitHub releases page](https://github.com/juanfont/headscale/releases).
In addition to that, there are semi-official RPM packages by the Fedora infra team https://copr.fedorainfracloud.org/coprs/jonathanspw/headscale/
For convenience, we also build Docker images with `headscale`. But **please be aware that we don't officially support deploying `headscale` using Docker**. We have a [Discord channel](https://discord.com/channels/896711691637780480/1070619770942148618) where you can ask for Docker-specific help to the community.
## Why is my reverse proxy not working with Headscale?
We don't know. We don't use reverse proxies with `headscale` ourselves, so we don't have any experience with them. We have [community documentation](https://headscale.net/reverse-proxy/) on how to configure various reverse proxies, and a dedicated [Discord channel](https://discord.com/channels/896711691637780480/1070619818346164324) where you can ask for help to the community.

View File

@ -4,9 +4,40 @@ hide:
- toc
---
# headscale documentation
# headscale
This site contains the official and community contributed documentation for `headscale`.
`headscale` is an open source, self-hosted implementation of the Tailscale control server.
If you are having trouble with following the documentation or get unexpected results,
please ask on [Discord](https://discord.gg/c84AZQhmpx) instead of opening an Issue.
This page contains the documentation for the latest version of headscale. Please also check our [FAQ](/faq/).
Join our [Discord](https://discord.gg/c84AZQhmpx) server for a chat and community support.
## Design goal
Headscale aims to implement a self-hosted, open source alternative to the Tailscale
control server.
Headscale's goal is to provide self-hosters and hobbyists with an open-source
server they can use for their projects and labs.
It implements a narrower scope, a single Tailnet, suitable for a personal use, or a small
open-source organisation.
## Supporting headscale
If you like `headscale` and find it useful, there is a sponsorship and donation
buttons available in the repo.
## Contributing
Headscale is "Open Source, acknowledged contribution", this means that any
contribution will have to be discussed with the Maintainers before being submitted.
This model has been chosen to reduce the risk of burnout by limiting the
maintenance overhead of reviewing and validating third-party code.
Headscale is open to code contributions for bug fixes without discussion.
If you find mistakes in the documentation, please submit a fix to the documentation.
## About
`headscale` is maintained by [Kristoffer Dalby](https://kradalby.no/) and [Juan Font](https://font.eu).

14
docs/web-ui.md Normal file
View File

@ -0,0 +1,14 @@
# Headscale web interface
!!! warning "Community contributions"
This page contains community contributions. The projects listed here are not
maintained by the Headscale authors and are written by community members.
| Name | Repository Link | Description | Status |
| --------------- | ------------------------------------------------------- | ------------------------------------------------------------------------- | ------ |
| headscale-webui | [Github](https://github.com/ifargle/headscale-webui) | A simple Headscale web UI for small-scale deployments. | Alpha |
| headscale-ui | [Github](https://github.com/gurucomputing/headscale-ui) | A web frontend for the headscale Tailscale-compatible coordination server | Alpha |
| HeadscaleUi | [GitHub](https://github.com/simcu/headscale-ui) | A static headscale admin ui, no backend enviroment required | Alpha |
You can ask for support on our dedicated [Discord channel](https://discord.com/channels/896711691637780480/1105842846386356294).

View File

@ -36,7 +36,7 @@
# When updating go.mod or go.sum, a new sha will need to be calculated,
# update this if you have a mismatch after doing a change to thos files.
vendorSha256 = "sha256-cmDNYWYTgQp6CPgpL4d3TbkpAe7rhNAF+o8njJsgL7E=";
vendorSha256 = "sha256-IOkbbFtE6+tNKnglE/8ZuNxhPSnloqM2sLgTvagMmnc=";
ldflags = [ "-s" "-w" "-X github.com/juanfont/headscale/cmd/headscale/cli.Version=v${version}" ];
};

View File

@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.28.1
// protoc-gen-go v1.29.1
// protoc (unknown)
// source: headscale/v1/apikey.proto

View File

@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.28.1
// protoc-gen-go v1.29.1
// protoc (unknown)
// source: headscale/v1/device.proto

View File

@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.28.1
// protoc-gen-go v1.29.1
// protoc (unknown)
// source: headscale/v1/headscale.proto

View File

@ -1,6 +1,6 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.2.0
// - protoc-gen-go-grpc v1.3.0
// - protoc (unknown)
// source: headscale/v1/headscale.proto
@ -18,6 +18,34 @@ import (
// Requires gRPC-Go v1.32.0 or later.
const _ = grpc.SupportPackageIsVersion7
const (
HeadscaleService_GetUser_FullMethodName = "/headscale.v1.HeadscaleService/GetUser"
HeadscaleService_CreateUser_FullMethodName = "/headscale.v1.HeadscaleService/CreateUser"
HeadscaleService_RenameUser_FullMethodName = "/headscale.v1.HeadscaleService/RenameUser"
HeadscaleService_DeleteUser_FullMethodName = "/headscale.v1.HeadscaleService/DeleteUser"
HeadscaleService_ListUsers_FullMethodName = "/headscale.v1.HeadscaleService/ListUsers"
HeadscaleService_CreatePreAuthKey_FullMethodName = "/headscale.v1.HeadscaleService/CreatePreAuthKey"
HeadscaleService_ExpirePreAuthKey_FullMethodName = "/headscale.v1.HeadscaleService/ExpirePreAuthKey"
HeadscaleService_ListPreAuthKeys_FullMethodName = "/headscale.v1.HeadscaleService/ListPreAuthKeys"
HeadscaleService_DebugCreateMachine_FullMethodName = "/headscale.v1.HeadscaleService/DebugCreateMachine"
HeadscaleService_GetMachine_FullMethodName = "/headscale.v1.HeadscaleService/GetMachine"
HeadscaleService_SetTags_FullMethodName = "/headscale.v1.HeadscaleService/SetTags"
HeadscaleService_RegisterMachine_FullMethodName = "/headscale.v1.HeadscaleService/RegisterMachine"
HeadscaleService_DeleteMachine_FullMethodName = "/headscale.v1.HeadscaleService/DeleteMachine"
HeadscaleService_ExpireMachine_FullMethodName = "/headscale.v1.HeadscaleService/ExpireMachine"
HeadscaleService_RenameMachine_FullMethodName = "/headscale.v1.HeadscaleService/RenameMachine"
HeadscaleService_ListMachines_FullMethodName = "/headscale.v1.HeadscaleService/ListMachines"
HeadscaleService_MoveMachine_FullMethodName = "/headscale.v1.HeadscaleService/MoveMachine"
HeadscaleService_GetRoutes_FullMethodName = "/headscale.v1.HeadscaleService/GetRoutes"
HeadscaleService_EnableRoute_FullMethodName = "/headscale.v1.HeadscaleService/EnableRoute"
HeadscaleService_DisableRoute_FullMethodName = "/headscale.v1.HeadscaleService/DisableRoute"
HeadscaleService_GetMachineRoutes_FullMethodName = "/headscale.v1.HeadscaleService/GetMachineRoutes"
HeadscaleService_DeleteRoute_FullMethodName = "/headscale.v1.HeadscaleService/DeleteRoute"
HeadscaleService_CreateApiKey_FullMethodName = "/headscale.v1.HeadscaleService/CreateApiKey"
HeadscaleService_ExpireApiKey_FullMethodName = "/headscale.v1.HeadscaleService/ExpireApiKey"
HeadscaleService_ListApiKeys_FullMethodName = "/headscale.v1.HeadscaleService/ListApiKeys"
)
// HeadscaleServiceClient is the client API for HeadscaleService service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
@ -64,7 +92,7 @@ func NewHeadscaleServiceClient(cc grpc.ClientConnInterface) HeadscaleServiceClie
func (c *headscaleServiceClient) GetUser(ctx context.Context, in *GetUserRequest, opts ...grpc.CallOption) (*GetUserResponse, error) {
out := new(GetUserResponse)
err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/GetUser", in, out, opts...)
err := c.cc.Invoke(ctx, HeadscaleService_GetUser_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
@ -73,7 +101,7 @@ func (c *headscaleServiceClient) GetUser(ctx context.Context, in *GetUserRequest
func (c *headscaleServiceClient) CreateUser(ctx context.Context, in *CreateUserRequest, opts ...grpc.CallOption) (*CreateUserResponse, error) {
out := new(CreateUserResponse)
err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/CreateUser", in, out, opts...)
err := c.cc.Invoke(ctx, HeadscaleService_CreateUser_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
@ -82,7 +110,7 @@ func (c *headscaleServiceClient) CreateUser(ctx context.Context, in *CreateUserR
func (c *headscaleServiceClient) RenameUser(ctx context.Context, in *RenameUserRequest, opts ...grpc.CallOption) (*RenameUserResponse, error) {
out := new(RenameUserResponse)
err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/RenameUser", in, out, opts...)
err := c.cc.Invoke(ctx, HeadscaleService_RenameUser_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
@ -91,7 +119,7 @@ func (c *headscaleServiceClient) RenameUser(ctx context.Context, in *RenameUserR
func (c *headscaleServiceClient) DeleteUser(ctx context.Context, in *DeleteUserRequest, opts ...grpc.CallOption) (*DeleteUserResponse, error) {
out := new(DeleteUserResponse)
err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/DeleteUser", in, out, opts...)
err := c.cc.Invoke(ctx, HeadscaleService_DeleteUser_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
@ -100,7 +128,7 @@ func (c *headscaleServiceClient) DeleteUser(ctx context.Context, in *DeleteUserR
func (c *headscaleServiceClient) ListUsers(ctx context.Context, in *ListUsersRequest, opts ...grpc.CallOption) (*ListUsersResponse, error) {
out := new(ListUsersResponse)
err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/ListUsers", in, out, opts...)
err := c.cc.Invoke(ctx, HeadscaleService_ListUsers_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
@ -109,7 +137,7 @@ func (c *headscaleServiceClient) ListUsers(ctx context.Context, in *ListUsersReq
func (c *headscaleServiceClient) CreatePreAuthKey(ctx context.Context, in *CreatePreAuthKeyRequest, opts ...grpc.CallOption) (*CreatePreAuthKeyResponse, error) {
out := new(CreatePreAuthKeyResponse)
err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/CreatePreAuthKey", in, out, opts...)
err := c.cc.Invoke(ctx, HeadscaleService_CreatePreAuthKey_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
@ -118,7 +146,7 @@ func (c *headscaleServiceClient) CreatePreAuthKey(ctx context.Context, in *Creat
func (c *headscaleServiceClient) ExpirePreAuthKey(ctx context.Context, in *ExpirePreAuthKeyRequest, opts ...grpc.CallOption) (*ExpirePreAuthKeyResponse, error) {
out := new(ExpirePreAuthKeyResponse)
err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/ExpirePreAuthKey", in, out, opts...)
err := c.cc.Invoke(ctx, HeadscaleService_ExpirePreAuthKey_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
@ -127,7 +155,7 @@ func (c *headscaleServiceClient) ExpirePreAuthKey(ctx context.Context, in *Expir
func (c *headscaleServiceClient) ListPreAuthKeys(ctx context.Context, in *ListPreAuthKeysRequest, opts ...grpc.CallOption) (*ListPreAuthKeysResponse, error) {
out := new(ListPreAuthKeysResponse)
err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/ListPreAuthKeys", in, out, opts...)
err := c.cc.Invoke(ctx, HeadscaleService_ListPreAuthKeys_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
@ -136,7 +164,7 @@ func (c *headscaleServiceClient) ListPreAuthKeys(ctx context.Context, in *ListPr
func (c *headscaleServiceClient) DebugCreateMachine(ctx context.Context, in *DebugCreateMachineRequest, opts ...grpc.CallOption) (*DebugCreateMachineResponse, error) {
out := new(DebugCreateMachineResponse)
err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/DebugCreateMachine", in, out, opts...)
err := c.cc.Invoke(ctx, HeadscaleService_DebugCreateMachine_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
@ -145,7 +173,7 @@ func (c *headscaleServiceClient) DebugCreateMachine(ctx context.Context, in *Deb
func (c *headscaleServiceClient) GetMachine(ctx context.Context, in *GetMachineRequest, opts ...grpc.CallOption) (*GetMachineResponse, error) {
out := new(GetMachineResponse)
err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/GetMachine", in, out, opts...)
err := c.cc.Invoke(ctx, HeadscaleService_GetMachine_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
@ -154,7 +182,7 @@ func (c *headscaleServiceClient) GetMachine(ctx context.Context, in *GetMachineR
func (c *headscaleServiceClient) SetTags(ctx context.Context, in *SetTagsRequest, opts ...grpc.CallOption) (*SetTagsResponse, error) {
out := new(SetTagsResponse)
err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/SetTags", in, out, opts...)
err := c.cc.Invoke(ctx, HeadscaleService_SetTags_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
@ -163,7 +191,7 @@ func (c *headscaleServiceClient) SetTags(ctx context.Context, in *SetTagsRequest
func (c *headscaleServiceClient) RegisterMachine(ctx context.Context, in *RegisterMachineRequest, opts ...grpc.CallOption) (*RegisterMachineResponse, error) {
out := new(RegisterMachineResponse)
err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/RegisterMachine", in, out, opts...)
err := c.cc.Invoke(ctx, HeadscaleService_RegisterMachine_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
@ -172,7 +200,7 @@ func (c *headscaleServiceClient) RegisterMachine(ctx context.Context, in *Regist
func (c *headscaleServiceClient) DeleteMachine(ctx context.Context, in *DeleteMachineRequest, opts ...grpc.CallOption) (*DeleteMachineResponse, error) {
out := new(DeleteMachineResponse)
err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/DeleteMachine", in, out, opts...)
err := c.cc.Invoke(ctx, HeadscaleService_DeleteMachine_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
@ -181,7 +209,7 @@ func (c *headscaleServiceClient) DeleteMachine(ctx context.Context, in *DeleteMa
func (c *headscaleServiceClient) ExpireMachine(ctx context.Context, in *ExpireMachineRequest, opts ...grpc.CallOption) (*ExpireMachineResponse, error) {
out := new(ExpireMachineResponse)
err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/ExpireMachine", in, out, opts...)
err := c.cc.Invoke(ctx, HeadscaleService_ExpireMachine_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
@ -190,7 +218,7 @@ func (c *headscaleServiceClient) ExpireMachine(ctx context.Context, in *ExpireMa
func (c *headscaleServiceClient) RenameMachine(ctx context.Context, in *RenameMachineRequest, opts ...grpc.CallOption) (*RenameMachineResponse, error) {
out := new(RenameMachineResponse)
err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/RenameMachine", in, out, opts...)
err := c.cc.Invoke(ctx, HeadscaleService_RenameMachine_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
@ -199,7 +227,7 @@ func (c *headscaleServiceClient) RenameMachine(ctx context.Context, in *RenameMa
func (c *headscaleServiceClient) ListMachines(ctx context.Context, in *ListMachinesRequest, opts ...grpc.CallOption) (*ListMachinesResponse, error) {
out := new(ListMachinesResponse)
err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/ListMachines", in, out, opts...)
err := c.cc.Invoke(ctx, HeadscaleService_ListMachines_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
@ -208,7 +236,7 @@ func (c *headscaleServiceClient) ListMachines(ctx context.Context, in *ListMachi
func (c *headscaleServiceClient) MoveMachine(ctx context.Context, in *MoveMachineRequest, opts ...grpc.CallOption) (*MoveMachineResponse, error) {
out := new(MoveMachineResponse)
err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/MoveMachine", in, out, opts...)
err := c.cc.Invoke(ctx, HeadscaleService_MoveMachine_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
@ -217,7 +245,7 @@ func (c *headscaleServiceClient) MoveMachine(ctx context.Context, in *MoveMachin
func (c *headscaleServiceClient) GetRoutes(ctx context.Context, in *GetRoutesRequest, opts ...grpc.CallOption) (*GetRoutesResponse, error) {
out := new(GetRoutesResponse)
err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/GetRoutes", in, out, opts...)
err := c.cc.Invoke(ctx, HeadscaleService_GetRoutes_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
@ -226,7 +254,7 @@ func (c *headscaleServiceClient) GetRoutes(ctx context.Context, in *GetRoutesReq
func (c *headscaleServiceClient) EnableRoute(ctx context.Context, in *EnableRouteRequest, opts ...grpc.CallOption) (*EnableRouteResponse, error) {
out := new(EnableRouteResponse)
err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/EnableRoute", in, out, opts...)
err := c.cc.Invoke(ctx, HeadscaleService_EnableRoute_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
@ -235,7 +263,7 @@ func (c *headscaleServiceClient) EnableRoute(ctx context.Context, in *EnableRout
func (c *headscaleServiceClient) DisableRoute(ctx context.Context, in *DisableRouteRequest, opts ...grpc.CallOption) (*DisableRouteResponse, error) {
out := new(DisableRouteResponse)
err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/DisableRoute", in, out, opts...)
err := c.cc.Invoke(ctx, HeadscaleService_DisableRoute_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
@ -244,7 +272,7 @@ func (c *headscaleServiceClient) DisableRoute(ctx context.Context, in *DisableRo
func (c *headscaleServiceClient) GetMachineRoutes(ctx context.Context, in *GetMachineRoutesRequest, opts ...grpc.CallOption) (*GetMachineRoutesResponse, error) {
out := new(GetMachineRoutesResponse)
err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/GetMachineRoutes", in, out, opts...)
err := c.cc.Invoke(ctx, HeadscaleService_GetMachineRoutes_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
@ -253,7 +281,7 @@ func (c *headscaleServiceClient) GetMachineRoutes(ctx context.Context, in *GetMa
func (c *headscaleServiceClient) DeleteRoute(ctx context.Context, in *DeleteRouteRequest, opts ...grpc.CallOption) (*DeleteRouteResponse, error) {
out := new(DeleteRouteResponse)
err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/DeleteRoute", in, out, opts...)
err := c.cc.Invoke(ctx, HeadscaleService_DeleteRoute_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
@ -262,7 +290,7 @@ func (c *headscaleServiceClient) DeleteRoute(ctx context.Context, in *DeleteRout
func (c *headscaleServiceClient) CreateApiKey(ctx context.Context, in *CreateApiKeyRequest, opts ...grpc.CallOption) (*CreateApiKeyResponse, error) {
out := new(CreateApiKeyResponse)
err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/CreateApiKey", in, out, opts...)
err := c.cc.Invoke(ctx, HeadscaleService_CreateApiKey_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
@ -271,7 +299,7 @@ func (c *headscaleServiceClient) CreateApiKey(ctx context.Context, in *CreateApi
func (c *headscaleServiceClient) ExpireApiKey(ctx context.Context, in *ExpireApiKeyRequest, opts ...grpc.CallOption) (*ExpireApiKeyResponse, error) {
out := new(ExpireApiKeyResponse)
err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/ExpireApiKey", in, out, opts...)
err := c.cc.Invoke(ctx, HeadscaleService_ExpireApiKey_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
@ -280,7 +308,7 @@ func (c *headscaleServiceClient) ExpireApiKey(ctx context.Context, in *ExpireApi
func (c *headscaleServiceClient) ListApiKeys(ctx context.Context, in *ListApiKeysRequest, opts ...grpc.CallOption) (*ListApiKeysResponse, error) {
out := new(ListApiKeysResponse)
err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/ListApiKeys", in, out, opts...)
err := c.cc.Invoke(ctx, HeadscaleService_ListApiKeys_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
@ -426,7 +454,7 @@ func _HeadscaleService_GetUser_Handler(srv interface{}, ctx context.Context, dec
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/headscale.v1.HeadscaleService/GetUser",
FullMethod: HeadscaleService_GetUser_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(HeadscaleServiceServer).GetUser(ctx, req.(*GetUserRequest))
@ -444,7 +472,7 @@ func _HeadscaleService_CreateUser_Handler(srv interface{}, ctx context.Context,
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/headscale.v1.HeadscaleService/CreateUser",
FullMethod: HeadscaleService_CreateUser_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(HeadscaleServiceServer).CreateUser(ctx, req.(*CreateUserRequest))
@ -462,7 +490,7 @@ func _HeadscaleService_RenameUser_Handler(srv interface{}, ctx context.Context,
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/headscale.v1.HeadscaleService/RenameUser",
FullMethod: HeadscaleService_RenameUser_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(HeadscaleServiceServer).RenameUser(ctx, req.(*RenameUserRequest))
@ -480,7 +508,7 @@ func _HeadscaleService_DeleteUser_Handler(srv interface{}, ctx context.Context,
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/headscale.v1.HeadscaleService/DeleteUser",
FullMethod: HeadscaleService_DeleteUser_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(HeadscaleServiceServer).DeleteUser(ctx, req.(*DeleteUserRequest))
@ -498,7 +526,7 @@ func _HeadscaleService_ListUsers_Handler(srv interface{}, ctx context.Context, d
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/headscale.v1.HeadscaleService/ListUsers",
FullMethod: HeadscaleService_ListUsers_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(HeadscaleServiceServer).ListUsers(ctx, req.(*ListUsersRequest))
@ -516,7 +544,7 @@ func _HeadscaleService_CreatePreAuthKey_Handler(srv interface{}, ctx context.Con
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/headscale.v1.HeadscaleService/CreatePreAuthKey",
FullMethod: HeadscaleService_CreatePreAuthKey_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(HeadscaleServiceServer).CreatePreAuthKey(ctx, req.(*CreatePreAuthKeyRequest))
@ -534,7 +562,7 @@ func _HeadscaleService_ExpirePreAuthKey_Handler(srv interface{}, ctx context.Con
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/headscale.v1.HeadscaleService/ExpirePreAuthKey",
FullMethod: HeadscaleService_ExpirePreAuthKey_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(HeadscaleServiceServer).ExpirePreAuthKey(ctx, req.(*ExpirePreAuthKeyRequest))
@ -552,7 +580,7 @@ func _HeadscaleService_ListPreAuthKeys_Handler(srv interface{}, ctx context.Cont
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/headscale.v1.HeadscaleService/ListPreAuthKeys",
FullMethod: HeadscaleService_ListPreAuthKeys_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(HeadscaleServiceServer).ListPreAuthKeys(ctx, req.(*ListPreAuthKeysRequest))
@ -570,7 +598,7 @@ func _HeadscaleService_DebugCreateMachine_Handler(srv interface{}, ctx context.C
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/headscale.v1.HeadscaleService/DebugCreateMachine",
FullMethod: HeadscaleService_DebugCreateMachine_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(HeadscaleServiceServer).DebugCreateMachine(ctx, req.(*DebugCreateMachineRequest))
@ -588,7 +616,7 @@ func _HeadscaleService_GetMachine_Handler(srv interface{}, ctx context.Context,
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/headscale.v1.HeadscaleService/GetMachine",
FullMethod: HeadscaleService_GetMachine_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(HeadscaleServiceServer).GetMachine(ctx, req.(*GetMachineRequest))
@ -606,7 +634,7 @@ func _HeadscaleService_SetTags_Handler(srv interface{}, ctx context.Context, dec
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/headscale.v1.HeadscaleService/SetTags",
FullMethod: HeadscaleService_SetTags_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(HeadscaleServiceServer).SetTags(ctx, req.(*SetTagsRequest))
@ -624,7 +652,7 @@ func _HeadscaleService_RegisterMachine_Handler(srv interface{}, ctx context.Cont
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/headscale.v1.HeadscaleService/RegisterMachine",
FullMethod: HeadscaleService_RegisterMachine_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(HeadscaleServiceServer).RegisterMachine(ctx, req.(*RegisterMachineRequest))
@ -642,7 +670,7 @@ func _HeadscaleService_DeleteMachine_Handler(srv interface{}, ctx context.Contex
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/headscale.v1.HeadscaleService/DeleteMachine",
FullMethod: HeadscaleService_DeleteMachine_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(HeadscaleServiceServer).DeleteMachine(ctx, req.(*DeleteMachineRequest))
@ -660,7 +688,7 @@ func _HeadscaleService_ExpireMachine_Handler(srv interface{}, ctx context.Contex
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/headscale.v1.HeadscaleService/ExpireMachine",
FullMethod: HeadscaleService_ExpireMachine_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(HeadscaleServiceServer).ExpireMachine(ctx, req.(*ExpireMachineRequest))
@ -678,7 +706,7 @@ func _HeadscaleService_RenameMachine_Handler(srv interface{}, ctx context.Contex
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/headscale.v1.HeadscaleService/RenameMachine",
FullMethod: HeadscaleService_RenameMachine_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(HeadscaleServiceServer).RenameMachine(ctx, req.(*RenameMachineRequest))
@ -696,7 +724,7 @@ func _HeadscaleService_ListMachines_Handler(srv interface{}, ctx context.Context
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/headscale.v1.HeadscaleService/ListMachines",
FullMethod: HeadscaleService_ListMachines_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(HeadscaleServiceServer).ListMachines(ctx, req.(*ListMachinesRequest))
@ -714,7 +742,7 @@ func _HeadscaleService_MoveMachine_Handler(srv interface{}, ctx context.Context,
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/headscale.v1.HeadscaleService/MoveMachine",
FullMethod: HeadscaleService_MoveMachine_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(HeadscaleServiceServer).MoveMachine(ctx, req.(*MoveMachineRequest))
@ -732,7 +760,7 @@ func _HeadscaleService_GetRoutes_Handler(srv interface{}, ctx context.Context, d
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/headscale.v1.HeadscaleService/GetRoutes",
FullMethod: HeadscaleService_GetRoutes_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(HeadscaleServiceServer).GetRoutes(ctx, req.(*GetRoutesRequest))
@ -750,7 +778,7 @@ func _HeadscaleService_EnableRoute_Handler(srv interface{}, ctx context.Context,
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/headscale.v1.HeadscaleService/EnableRoute",
FullMethod: HeadscaleService_EnableRoute_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(HeadscaleServiceServer).EnableRoute(ctx, req.(*EnableRouteRequest))
@ -768,7 +796,7 @@ func _HeadscaleService_DisableRoute_Handler(srv interface{}, ctx context.Context
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/headscale.v1.HeadscaleService/DisableRoute",
FullMethod: HeadscaleService_DisableRoute_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(HeadscaleServiceServer).DisableRoute(ctx, req.(*DisableRouteRequest))
@ -786,7 +814,7 @@ func _HeadscaleService_GetMachineRoutes_Handler(srv interface{}, ctx context.Con
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/headscale.v1.HeadscaleService/GetMachineRoutes",
FullMethod: HeadscaleService_GetMachineRoutes_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(HeadscaleServiceServer).GetMachineRoutes(ctx, req.(*GetMachineRoutesRequest))
@ -804,7 +832,7 @@ func _HeadscaleService_DeleteRoute_Handler(srv interface{}, ctx context.Context,
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/headscale.v1.HeadscaleService/DeleteRoute",
FullMethod: HeadscaleService_DeleteRoute_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(HeadscaleServiceServer).DeleteRoute(ctx, req.(*DeleteRouteRequest))
@ -822,7 +850,7 @@ func _HeadscaleService_CreateApiKey_Handler(srv interface{}, ctx context.Context
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/headscale.v1.HeadscaleService/CreateApiKey",
FullMethod: HeadscaleService_CreateApiKey_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(HeadscaleServiceServer).CreateApiKey(ctx, req.(*CreateApiKeyRequest))
@ -840,7 +868,7 @@ func _HeadscaleService_ExpireApiKey_Handler(srv interface{}, ctx context.Context
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/headscale.v1.HeadscaleService/ExpireApiKey",
FullMethod: HeadscaleService_ExpireApiKey_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(HeadscaleServiceServer).ExpireApiKey(ctx, req.(*ExpireApiKeyRequest))
@ -858,7 +886,7 @@ func _HeadscaleService_ListApiKeys_Handler(srv interface{}, ctx context.Context,
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/headscale.v1.HeadscaleService/ListApiKeys",
FullMethod: HeadscaleService_ListApiKeys_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(HeadscaleServiceServer).ListApiKeys(ctx, req.(*ListApiKeysRequest))

View File

@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.28.1
// protoc-gen-go v1.29.1
// protoc (unknown)
// source: headscale/v1/machine.proto

View File

@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.28.1
// protoc-gen-go v1.29.1
// protoc (unknown)
// source: headscale/v1/preauthkey.proto

View File

@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.28.1
// protoc-gen-go v1.29.1
// protoc (unknown)
// source: headscale/v1/routes.proto

View File

@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.28.1
// protoc-gen-go v1.29.1
// protoc (unknown)
// source: headscale/v1/user.proto

View File

@ -1,4 +1,4 @@
package headscale
package hscontrol
import (
"encoding/json"
@ -59,8 +59,8 @@ const (
var featureEnableSSH = envknob.RegisterBool("HEADSCALE_EXPERIMENTAL_FEATURE_SSH")
// LoadACLPolicy loads the ACL policy from the specify path, and generates the ACL rules.
func (h *Headscale) LoadACLPolicy(path string) error {
// LoadACLPolicyFromPath loads the ACL policy from the specify path, and generates the ACL rules.
func (h *Headscale) LoadACLPolicyFromPath(path string) error {
log.Debug().
Str("func", "LoadACLPolicy").
Str("path", path).
@ -72,37 +72,42 @@ func (h *Headscale) LoadACLPolicy(path string) error {
}
defer policyFile.Close()
var policy ACLPolicy
policyBytes, err := io.ReadAll(policyFile)
if err != nil {
return err
}
log.Debug().
Str("path", path).
Bytes("file", policyBytes).
Msg("Loading ACLs")
switch filepath.Ext(path) {
case ".yml", ".yaml":
log.Debug().
Str("path", path).
Bytes("file", policyBytes).
Msg("Loading ACLs from YAML")
return h.LoadACLPolicyFromBytes(policyBytes, "yaml")
}
err := yaml.Unmarshal(policyBytes, &policy)
return h.LoadACLPolicyFromBytes(policyBytes, "hujson")
}
func (h *Headscale) LoadACLPolicyFromBytes(acl []byte, format string) error {
var policy ACLPolicy
switch format {
case "yaml":
err := yaml.Unmarshal(acl, &policy)
if err != nil {
return err
}
log.Trace().
Interface("policy", policy).
Msg("Loaded policy from YAML")
default:
ast, err := hujson.Parse(policyBytes)
ast, err := hujson.Parse(acl)
if err != nil {
return err
}
ast.Standardize()
policyBytes = ast.Pack()
err = json.Unmarshal(policyBytes, &policy)
acl = ast.Pack()
err = json.Unmarshal(acl, &policy)
if err != nil {
return err
}

View File

@ -1,4 +1,4 @@
package headscale
package hscontrol
import (
"errors"
@ -15,17 +15,26 @@ import (
)
func (s *Suite) TestWrongPath(c *check.C) {
err := app.LoadACLPolicy("asdfg")
err := app.LoadACLPolicyFromPath("asdfg")
c.Assert(err, check.NotNil)
}
func (s *Suite) TestBrokenHuJson(c *check.C) {
err := app.LoadACLPolicy("./tests/acls/broken.hujson")
acl := []byte(`
{
`)
err := app.LoadACLPolicyFromBytes(acl, "hujson")
c.Assert(err, check.NotNil)
}
func (s *Suite) TestInvalidPolicyHuson(c *check.C) {
err := app.LoadACLPolicy("./tests/acls/invalid.hujson")
acl := []byte(`
{
"valid_json": true,
"but_a_policy_though": false
}
`)
err := app.LoadACLPolicyFromBytes(acl, "hujson")
c.Assert(err, check.NotNil)
c.Assert(err, check.Equals, errEmptyPolicy)
}
@ -49,12 +58,161 @@ func (s *Suite) TestParseInvalidCIDR(c *check.C) {
}
func (s *Suite) TestRuleInvalidGeneration(c *check.C) {
err := app.LoadACLPolicy("./tests/acls/acl_policy_invalid.hujson")
acl := []byte(`
{
// Declare static groups of users beyond those in the identity service.
"groups": {
"group:example": [
"user1@example.com",
"user2@example.com",
],
},
// Declare hostname aliases to use in place of IP addresses or subnets.
"hosts": {
"example-host-1": "100.100.100.100",
"example-host-2": "100.100.101.100/24",
},
// Define who is allowed to use which tags.
"tagOwners": {
// Everyone in the montreal-admins or global-admins group are
// allowed to tag servers as montreal-webserver.
"tag:montreal-webserver": [
"group:montreal-admins",
"group:global-admins",
],
// Only a few admins are allowed to create API servers.
"tag:api-server": [
"group:global-admins",
"example-host-1",
],
},
// Access control lists.
"acls": [
// Engineering users, plus the president, can access port 22 (ssh)
// and port 3389 (remote desktop protocol) on all servers, and all
// ports on git-server or ci-server.
{
"action": "accept",
"src": [
"group:engineering",
"president@example.com"
],
"dst": [
"*:22,3389",
"git-server:*",
"ci-server:*"
],
},
// Allow engineer users to access any port on a device tagged with
// tag:production.
{
"action": "accept",
"src": [
"group:engineers"
],
"dst": [
"tag:production:*"
],
},
// Allow servers in the my-subnet host and 192.168.1.0/24 to access hosts
// on both networks.
{
"action": "accept",
"src": [
"my-subnet",
"192.168.1.0/24"
],
"dst": [
"my-subnet:*",
"192.168.1.0/24:*"
],
},
// Allow every user of your network to access anything on the network.
// Comment out this section if you want to define specific ACL
// restrictions above.
{
"action": "accept",
"src": [
"*"
],
"dst": [
"*:*"
],
},
// All users in Montreal are allowed to access the Montreal web
// servers.
{
"action": "accept",
"src": [
"group:montreal-users"
],
"dst": [
"tag:montreal-webserver:80,443"
],
},
// Montreal web servers are allowed to make outgoing connections to
// the API servers, but only on https port 443.
// In contrast, this doesn't grant API servers the right to initiate
// any connections.
{
"action": "accept",
"src": [
"tag:montreal-webserver"
],
"dst": [
"tag:api-server:443"
],
},
],
// Declare tests to check functionality of ACL rules
"tests": [
{
"src": "user1@example.com",
"accept": [
"example-host-1:22",
"example-host-2:80"
],
"deny": [
"exapmle-host-2:100"
],
},
{
"src": "user2@example.com",
"accept": [
"100.60.3.4:22"
],
},
],
}
`)
err := app.LoadACLPolicyFromBytes(acl, "hujson")
c.Assert(err, check.NotNil)
}
func (s *Suite) TestBasicRule(c *check.C) {
err := app.LoadACLPolicy("./tests/acls/acl_policy_basic_1.hujson")
acl := []byte(`
{
"hosts": {
"host-1": "100.100.100.100",
"subnet-1": "100.100.101.100/24",
},
"acls": [
{
"action": "accept",
"src": [
"subnet-1",
"192.168.1.0/24"
],
"dst": [
"*:22,3389",
"host-1:*",
],
},
],
}
`)
err := app.LoadACLPolicyFromBytes(acl, "hujson")
c.Assert(err, check.IsNil)
rules, err := app.aclPolicy.generateFilterRules([]Machine{}, false)
@ -411,7 +569,27 @@ func (s *Suite) TestValidTagInvalidUser(c *check.C) {
}
func (s *Suite) TestPortRange(c *check.C) {
err := app.LoadACLPolicy("./tests/acls/acl_policy_basic_range.hujson")
acl := []byte(`
{
"hosts": {
"host-1": "100.100.100.100",
"subnet-1": "100.100.101.100/24",
},
"acls": [
{
"action": "accept",
"src": [
"subnet-1",
],
"dst": [
"host-1:5400-5500",
],
},
],
}
`)
err := app.LoadACLPolicyFromBytes(acl, "hujson")
c.Assert(err, check.IsNil)
rules, err := app.aclPolicy.generateFilterRules([]Machine{}, false)
@ -425,7 +603,48 @@ func (s *Suite) TestPortRange(c *check.C) {
}
func (s *Suite) TestProtocolParsing(c *check.C) {
err := app.LoadACLPolicy("./tests/acls/acl_policy_basic_protocols.hujson")
acl := []byte(`
{
"hosts": {
"host-1": "100.100.100.100",
"subnet-1": "100.100.101.100/24",
},
"acls": [
{
"Action": "accept",
"src": [
"*",
],
"proto": "tcp",
"dst": [
"host-1:*",
],
},
{
"Action": "accept",
"src": [
"*",
],
"proto": "udp",
"dst": [
"host-1:53",
],
},
{
"Action": "accept",
"src": [
"*",
],
"proto": "icmp",
"dst": [
"host-1:*",
],
},
],
}
`)
err := app.LoadACLPolicyFromBytes(acl, "hujson")
c.Assert(err, check.IsNil)
rules, err := app.aclPolicy.generateFilterRules([]Machine{}, false)
@ -439,7 +658,27 @@ func (s *Suite) TestProtocolParsing(c *check.C) {
}
func (s *Suite) TestPortWildcard(c *check.C) {
err := app.LoadACLPolicy("./tests/acls/acl_policy_basic_wildcards.hujson")
acl := []byte(`
{
"hosts": {
"host-1": "100.100.100.100",
"subnet-1": "100.100.101.100/24",
},
"acls": [
{
"Action": "accept",
"src": [
"*",
],
"dst": [
"host-1:*",
],
},
],
}
`)
err := app.LoadACLPolicyFromBytes(acl, "hujson")
c.Assert(err, check.IsNil)
rules, err := app.aclPolicy.generateFilterRules([]Machine{}, false)
@ -455,7 +694,19 @@ func (s *Suite) TestPortWildcard(c *check.C) {
}
func (s *Suite) TestPortWildcardYAML(c *check.C) {
err := app.LoadACLPolicy("./tests/acls/acl_policy_basic_wildcards.yaml")
acl := []byte(`
---
hosts:
host-1: 100.100.100.100/32
subnet-1: 100.100.101.100/24
acls:
- action: accept
src:
- "*"
dst:
- host-1:*
`)
err := app.LoadACLPolicyFromBytes(acl, "yaml")
c.Assert(err, check.IsNil)
rules, err := app.aclPolicy.generateFilterRules([]Machine{}, false)
@ -493,9 +744,27 @@ func (s *Suite) TestPortUser(c *check.C) {
}
app.db.Save(&machine)
err = app.LoadACLPolicy(
"./tests/acls/acl_policy_basic_user_as_user.hujson",
)
acl := []byte(`
{
"hosts": {
"host-1": "100.100.100.100",
"subnet-1": "100.100.101.100/24",
},
"acls": [
{
"action": "accept",
"src": [
"testuser",
],
"dst": [
"host-1:*",
],
},
],
}
`)
err = app.LoadACLPolicyFromBytes(acl, "hujson")
c.Assert(err, check.IsNil)
machines, err := app.ListMachines()
@ -538,7 +807,33 @@ func (s *Suite) TestPortGroup(c *check.C) {
}
app.db.Save(&machine)
err = app.LoadACLPolicy("./tests/acls/acl_policy_basic_groups.hujson")
acl := []byte(`
{
"groups": {
"group:example": [
"testuser",
],
},
"hosts": {
"host-1": "100.100.100.100",
"subnet-1": "100.100.101.100/24",
},
"acls": [
{
"action": "accept",
"src": [
"group:example",
],
"dst": [
"host-1:*",
],
},
],
}
`)
err = app.LoadACLPolicyFromBytes(acl, "hujson")
c.Assert(err, check.IsNil)
machines, err := app.ListMachines()

View File

@ -1,4 +1,4 @@
package headscale
package hscontrol
import (
"encoding/json"

View File

@ -1,4 +1,4 @@
package headscale
package hscontrol
import (
"bytes"

View File

@ -1,4 +1,4 @@
package headscale
package hscontrol
import (
"time"

View File

@ -1,4 +1,4 @@
package headscale
package hscontrol
import (
"fmt"

View File

@ -1,4 +1,4 @@
package headscale
package hscontrol
import (
"time"

View File

@ -1,4 +1,4 @@
package headscale
package hscontrol
import (
"context"
@ -21,6 +21,7 @@ import (
"github.com/gorilla/mux"
grpcMiddleware "github.com/grpc-ecosystem/go-grpc-middleware"
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
"github.com/juanfont/headscale"
v1 "github.com/juanfont/headscale/gen/go/headscale/v1"
"github.com/patrickmn/go-cache"
zerolog "github.com/philip-bui/grpc-zerolog"
@ -507,8 +508,10 @@ func (h *Headscale) createRouter(grpcMux *runtime.ServeMux) *mux.Router {
router.HandleFunc("/windows", h.WindowsConfigMessage).Methods(http.MethodGet)
router.HandleFunc("/windows/tailscale.reg", h.WindowsRegConfig).
Methods(http.MethodGet)
router.HandleFunc("/swagger", SwaggerUI).Methods(http.MethodGet)
router.HandleFunc("/swagger/v1/openapiv2.json", SwaggerAPIv1).
// TODO(kristoffer): move swagger into a package
router.HandleFunc("/swagger", headscale.SwaggerUI).Methods(http.MethodGet)
router.HandleFunc("/swagger/v1/openapiv2.json", headscale.SwaggerAPIv1).
Methods(http.MethodGet)
if h.cfg.DERP.ServerEnabled {
@ -758,7 +761,7 @@ func (h *Headscale) Serve() error {
if h.cfg.ACL.PolicyPath != "" {
aclPath := AbsolutePathFromConfigPath(h.cfg.ACL.PolicyPath)
err := h.LoadACLPolicy(aclPath)
err := h.LoadACLPolicyFromPath(aclPath)
if err != nil {
log.Error().Err(err).Msg("Failed to reload ACL policy")
}

View File

@ -1,4 +1,4 @@
package headscale
package hscontrol
import (
"net/netip"

View File

@ -1,4 +1,4 @@
package headscale
package hscontrol
import (
"errors"
@ -16,6 +16,7 @@ import (
"github.com/rs/zerolog/log"
"github.com/spf13/viper"
"go4.org/netipx"
"tailscale.com/net/tsaddr"
"tailscale.com/tailcfg"
"tailscale.com/types/dnstype"
)
@ -174,7 +175,7 @@ func LoadConfig(path string, isFile bool) error {
viper.SetDefault("derp.server.enabled", false)
viper.SetDefault("derp.server.stun.enabled", true)
viper.SetDefault("unix_socket", "/var/run/headscale.sock")
viper.SetDefault("unix_socket", "/var/run/headscale/headscale.sock")
viper.SetDefault("unix_socket_permission", "0o770")
viper.SetDefault("grpc_listen_addr", ":50443")
@ -515,6 +516,29 @@ func GetHeadscaleConfig() (*Config, error) {
if err != nil {
panic(fmt.Errorf("failed to parse ip_prefixes[%d]: %w", i, err))
}
if prefix.Addr().Is4() {
builder := netipx.IPSetBuilder{}
builder.AddPrefix(tsaddr.CGNATRange())
ipSet, _ := builder.IPSet()
if !ipSet.ContainsPrefix(prefix) {
log.Warn().
Msgf("Prefix %s is not in the %s range. This is an unsupported configuration.",
prefixInConfig, tsaddr.CGNATRange())
}
}
if prefix.Addr().Is6() {
builder := netipx.IPSetBuilder{}
builder.AddPrefix(tsaddr.TailscaleULARange())
ipSet, _ := builder.IPSet()
if !ipSet.ContainsPrefix(prefix) {
log.Warn().
Msgf("Prefix %s is not in the %s range. This is an unsupported configuration.",
prefixInConfig, tsaddr.TailscaleULARange())
}
}
parsedPrefixes = append(parsedPrefixes, prefix)
}

View File

@ -1,4 +1,4 @@
package headscale
package hscontrol
import (
"context"

View File

@ -1,4 +1,4 @@
package headscale
package hscontrol
import (
"context"

View File

@ -1,4 +1,4 @@
package headscale
package hscontrol
import (
"context"

View File

@ -1,4 +1,4 @@
package headscale
package hscontrol
import (
"fmt"

View File

@ -1,4 +1,4 @@
package headscale
package hscontrol
import (
"fmt"

View File

@ -1,5 +1,5 @@
// nolint
package headscale
package hscontrol
import (
"context"

View File

@ -1,4 +1,4 @@
package headscale
package hscontrol
import "testing"

View File

@ -1,6 +1,6 @@
//go:build ts2019
package headscale
package hscontrol
import (
"net/http"

View File

@ -1,6 +1,6 @@
//go:build !ts2019
package headscale
package hscontrol
import "github.com/gorilla/mux"

View File

@ -1,4 +1,4 @@
package headscale
package hscontrol
import (
"database/sql/driver"

View File

@ -1,4 +1,4 @@
package headscale
package hscontrol
import (
"fmt"
@ -1212,7 +1212,31 @@ func TestHeadscale_generateGivenName(t *testing.T) {
}
func (s *Suite) TestAutoApproveRoutes(c *check.C) {
err := app.LoadACLPolicy("./tests/acls/acl_policy_autoapprovers.hujson")
acl := []byte(`
{
"tagOwners": {
"tag:exit": ["test"],
},
"groups": {
"group:test": ["test"]
},
"acls": [
{"action": "accept", "users": ["*"], "ports": ["*:*"]},
],
"autoApprovers": {
"exitNode": ["tag:exit"],
"routes": {
"10.10.0.0/16": ["group:test"],
"10.11.0.0/16": ["test"],
}
}
}
`)
err := app.LoadACLPolicyFromBytes(acl, "hujson")
c.Assert(err, check.IsNil)
user, err := app.CreateUser("test")

View File

@ -1,4 +1,4 @@
package headscale
package hscontrol
import (
"fmt"

View File

@ -1,4 +1,4 @@
package headscale
package hscontrol
import (
"net/netip"

View File

@ -1,4 +1,4 @@
package headscale
package hscontrol
import (
"github.com/prometheus/client_golang/prometheus"

View File

@ -1,4 +1,4 @@
package headscale
package hscontrol
import (
"encoding/binary"

View File

@ -1,4 +1,4 @@
package headscale
package hscontrol
import (
"bytes"

View File

@ -1,4 +1,4 @@
package headscale
package hscontrol
import (
"bytes"

View File

@ -1,4 +1,4 @@
package headscale
package hscontrol
import (
"crypto/rand"

View File

@ -1,4 +1,4 @@
package headscale
package hscontrol
import (
"time"

View File

@ -1,4 +1,4 @@
package headscale
package hscontrol
import (
"encoding/json"

View File

@ -1,4 +1,4 @@
package headscale
package hscontrol
import (
"context"

View File

@ -1,4 +1,4 @@
package headscale
package hscontrol
import (
"encoding/binary"

View File

@ -1,6 +1,6 @@
//go:build ts2019
package headscale
package hscontrol
import (
"io"

Some files were not shown because too many files have changed in this diff Show More