Compare commits

...

31 Commits

Author SHA1 Message Date
Kristoffer Dalby
6aeaff43aa Fix checkboxes in PR template 2022-03-08 07:21:04 +00:00
Kristoffer Dalby
b0ae3240fd Merge pull request #387 from restanrm/fix-magic-dns-and-uppercase-letters
Fix magic dns and uppercase letters
2022-03-08 07:17:45 +00:00
Adrien Raffin-Caboisse
41efe98953 fix: apply fmt and fix missing name changes 2022-03-07 23:20:30 +01:00
Adrien Raffin-Caboisse
2b68c90778 chore: update changelog 2022-03-07 23:14:39 +01:00
Adrien Raffin-Caboisse
f19c048569 fix: change normalization function name 2022-03-07 22:55:54 +01:00
Adrien Raffin-Caboisse
6cc8bbc24f feat(api): add normalisation at machine register step 2022-03-07 22:46:29 +01:00
Adrien Raffin-Caboisse
1114449601 change: update name of method to check and normalize Domain name 2022-03-06 20:46:17 +01:00
Juan Font
dcf3ea567c Merge branch 'main' into fix-magic-dns-and-uppercase-letters 2022-03-06 17:37:48 +01:00
Kristoffer Dalby
435ee36d78 Merge pull request #394 from juanfont/renovateaction/dockerfiles 2022-03-05 00:41:22 +00:00
Renovate Bot
35efd8f95a chore(deps): update dependency docker.io/golang to v1.17.8 2022-03-05 00:09:36 +00:00
Kristoffer Dalby
60655c5242 Merge pull request #393 from juanfont/update-contributors 2022-03-04 12:30:20 +00:00
github-actions[bot]
a70669fca7 docs(README): update contributors 2022-03-04 11:04:12 +00:00
Kristoffer Dalby
0720473033 Merge pull request #392 from e-zk/windows-endpoint 2022-03-04 11:03:33 +00:00
Kristoffer Dalby
e799307e74 Merge branch 'main' into windows-endpoint 2022-03-04 10:47:52 +00:00
e-zk
575f33d183 docs: fix comments to comply with golangci-lint 2022-03-04 20:35:09 +10:00
e-zk
d69dada8ff feat(windows): rename apple_mobileconfig.go => platform_config.go
rename apple_mobileconfig.go to platform_config.go since the file
includes configuration info for multiple platforms now.
2022-03-04 20:03:49 +10:00
e-zk
f9e0c13890 docs: update CHANGELOG 2022-03-04 19:53:57 +10:00
e-zk
12a50ac8ac feat(windows): add /windows endpoint for Windows configuration
- registry file /windows/tailscale.reg is generated, filling in the
  associated control server URL
- also includes CLI instructions
- fix /apple incorrect template: 'Url' is supposed to be '.URL'
2022-03-04 19:53:44 +10:00
e-zk
b342cf0240 feat(windows): cleanup /apple endpoint
- rename the gin function to AppleConfigMessage
- use <pre> + <code> for code blocks
- add headscale heading
- reword some sections
2022-03-04 19:53:29 +10:00
Kristoffer Dalby
e3ff87b7ef Merge pull request #389 from e-zk/main 2022-03-04 07:26:35 +00:00
zakaria
745696b310 docs: fix mistake in ACME challenge type comment 2022-03-04 12:11:43 +10:00
Adrien Raffin-Caboisse
6f172a6e4c fix(acls): remove dead error code 2022-03-03 23:53:08 +01:00
Adrien Raffin-Caboisse
44a5372c53 fix(poll): Normalize hostname
This function is called often. Normalization of the hostname will be written in database.
2022-03-03 23:52:25 +01:00
Kristoffer Dalby
f2ea6fb30f Merge pull request #384 from restanrm/fix-issue-with-empty-namespace-and-acl-evaluation 2022-03-03 08:43:37 +00:00
Adrien Raffin-Caboisse
4a4952899b feat(acls): add some logs and skip error
logs looks like the following
```
2022-03-02T20:43:08Z DBG Expanding alias=app-test
2022-03-02T20:43:08Z DBG Expanding alias=kube-test
2022-03-02T20:43:08Z DBG Expanding alias=test
2022-03-02T20:43:08Z WRN No IPs found with the alias test
2022-03-02T20:43:08Z DBG Expanding alias=prod
2022-03-02T20:43:08Z WRN No IPs found with the alias prod
2022-03-02T20:43:08Z DBG Expanding alias=prod
2022-03-02T20:43:08Z WRN No IPs found with the alias prod
```
2022-03-02 21:54:43 +01:00
Kristoffer Dalby
b72a8aa7d1 Merge pull request #381 from juanfont/update-contributors 2022-03-02 14:18:09 +00:00
github-actions[bot]
e301d0d1df docs(README): update contributors 2022-03-02 13:44:26 +00:00
Kristoffer Dalby
75ca91b0f7 Merge pull request #380 from juanfont/update-contributors
docs(README): update contributors
2022-03-02 13:43:53 +00:00
github-actions[bot]
e208ccc982 docs(README): update contributors 2022-03-02 13:42:25 +00:00
Kristoffer Dalby
71a62697aa Merge pull request #379 from juanfont/kradalby-patch-1
Second contributor attempt
2022-03-02 13:41:50 +00:00
Kristoffer Dalby
f9c0597875 Second contributor attempt 2022-03-02 13:40:37 +00:00
16 changed files with 226 additions and 71 deletions

View File

@@ -1,10 +1,10 @@
<!-- Please tick if the following things apply. You… -->
- [] read the [CONTRIBUTING guidelines](README.md#user-content-contributing)
- [] raised a GitHub issue or discussed it on the projects chat beforehand
- [] added unit tests
- [] added integration tests
- [] updated documentation if needed
- [] updated CHANGELOG.md
- [ ] read the [CONTRIBUTING guidelines](README.md#user-content-contributing)
- [ ] raised a GitHub issue or discussed it on the projects chat beforehand
- [ ] added unit tests
- [ ] added integration tests
- [ ] updated documentation if needed
- [ ] updated CHANGELOG.md
<!-- If applicable, please reference the issue using `Fixes #XXX` and add tests to cover your new code. -->

View File

@@ -17,6 +17,10 @@ jobs:
run: git push origin --delete update-contributors
- name: Create up-to-date contributors branch
run: git checkout -B update-contributors
- name: Push empty contributors branch
run: git push origin update-contributors
- name: Switch back to main
run: git checkout main
- uses: BobAnkh/add-contributors@v0.2.2
with:
CONTRIBUTOR: "## Contributors"

View File

@@ -18,6 +18,7 @@
- Add support for writing ACL files with YAML [#359](https://github.com/juanfont/headscale/pull/359)
- Users can now use emails in ACL's groups [#372](https://github.com/juanfont/headscale/issues/372)
- Add shorthand aliases for commands and subcommands [#376](https://github.com/juanfont/headscale/pull/376)
- Add `/windows` endpoint for Windows configuration instructions + registry file download [#392](https://github.com/juanfont/headscale/pull/392)
### Changes
@@ -26,6 +27,7 @@
- Nodes are now only written to database if they are registrated successfully
- Fix a limitation in the ACLs that prevented users to write rules with `*` as source [#374](https://github.com/juanfont/headscale/issues/374)
- Reduce the overhead of marshal/unmarshal for Hostinfo, routes and endpoints by using specific types in Machine [#371](https://github.com/juanfont/headscale/pull/371)
- Apply normalization function to FQDN on hostnames when hosts registers and retrieve informations [#363](https://github.com/juanfont/headscale/issues/363)
## 0.14.0 (2022-02-24)

View File

@@ -1,5 +1,5 @@
# Builder image
FROM docker.io/golang:1.17.7-bullseye AS build
FROM docker.io/golang:1.17.8-bullseye AS build
ENV GOPATH /go
WORKDIR /go/src/headscale

View File

@@ -1,5 +1,5 @@
# Builder image
FROM docker.io/golang:1.17.7-alpine AS build
FROM docker.io/golang:1.17.8-alpine AS build
ENV GOPATH /go
WORKDIR /go/src/headscale

View File

@@ -1,5 +1,5 @@
# Builder image
FROM docker.io/golang:1.17.7-bullseye AS build
FROM docker.io/golang:1.17.8-bullseye AS build
ENV GOPATH /go
WORKDIR /go/src/headscale

View File

@@ -161,6 +161,13 @@ make build
<sub style="font-size:14px"><b>Juan Font</b></sub>
</a>
</td>
<td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0">
<a href=https://github.com/restanrm>
<img src=https://avatars.githubusercontent.com/u/4344371?v=4 width="100;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=Adrien Raffin-Caboisse/>
<br />
<sub style="font-size:14px"><b>Adrien Raffin-Caboisse</b></sub>
</a>
</td>
<td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0">
<a href=https://github.com/cure>
<img src=https://avatars.githubusercontent.com/u/149135?v=4 width="100;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=Ward Vandewege/>
@@ -176,12 +183,14 @@ make build
</a>
</td>
<td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0">
<a href=https://github.com/restanrm>
<img src=https://avatars.githubusercontent.com/u/4344371?v=4 width="100;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=Adrien Raffin-Caboisse/>
<a href=https://github.com/arch4ngel>
<img src=https://avatars.githubusercontent.com/u/11574161?v=4 width="100;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=Justin Angel/>
<br />
<sub style="font-size:14px"><b>Adrien Raffin-Caboisse</b></sub>
<sub style="font-size:14px"><b>Justin Angel</b></sub>
</a>
</td>
</tr>
<tr>
<td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0">
<a href=https://github.com/ItalyPaleAle>
<img src=https://avatars.githubusercontent.com/u/43508?v=4 width="100;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=Alessandro (Ale) Segala/>
@@ -189,8 +198,13 @@ make build
<sub style="font-size:14px"><b>Alessandro (Ale) Segala</b></sub>
</a>
</td>
</tr>
<tr>
<td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0">
<a href=https://github.com/e-zk>
<img src=https://avatars.githubusercontent.com/u/58356365?v=4 width="100;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=e-zk/>
<br />
<sub style="font-size:14px"><b>e-zk</b></sub>
</a>
</td>
<td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0">
<a href=https://github.com/unreality>
<img src=https://avatars.githubusercontent.com/u/352522?v=4 width="100;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=unreality/>
@@ -198,6 +212,13 @@ make build
<sub style="font-size:14px"><b>unreality</b></sub>
</a>
</td>
<td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0">
<a href=https://github.com/reynico>
<img src=https://avatars.githubusercontent.com/u/715768?v=4 width="100;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=Nico/>
<br />
<sub style="font-size:14px"><b>Nico</b></sub>
</a>
</td>
<td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0">
<a href=https://github.com/negbie>
<img src=https://avatars.githubusercontent.com/u/20154956?v=4 width="100;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=Eugen Biegler/>
@@ -212,6 +233,8 @@ make build
<sub style="font-size:14px"><b>Aaron Bieber</b></sub>
</a>
</td>
</tr>
<tr>
<td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0">
<a href=https://github.com/fdelucchijr>
<img src=https://avatars.githubusercontent.com/u/69133647?v=4 width="100;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=Fernando De Lucchi/>
@@ -233,8 +256,6 @@ make build
<sub style="font-size:14px"><b>Michael G.</b></sub>
</a>
</td>
</tr>
<tr>
<td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0">
<a href=https://github.com/ptman>
<img src=https://avatars.githubusercontent.com/u/24669?v=4 width="100;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=Paul Tötterman/>
@@ -256,6 +277,8 @@ make build
<sub style="font-size:14px"><b>Silver Bullet</b></sub>
</a>
</td>
</tr>
<tr>
<td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0">
<a href=https://github.com/majst01>
<img src=https://avatars.githubusercontent.com/u/410110?v=4 width="100;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=Stefan Majer/>
@@ -264,10 +287,10 @@ make build
</a>
</td>
<td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0">
<a href=https://github.com/lachy-2849>
<img src=https://avatars.githubusercontent.com/u/98844035?v=4 width="100;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=lachy-2849/>
<a href=https://github.com/lachy2849>
<img src=https://avatars.githubusercontent.com/u/98844035?v=4 width="100;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=lachy2849/>
<br />
<sub style="font-size:14px"><b>lachy-2849</b></sub>
<sub style="font-size:14px"><b>lachy2849</b></sub>
</a>
</td>
<td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0">
@@ -277,8 +300,6 @@ make build
<sub style="font-size:14px"><b>thomas</b></sub>
</a>
</td>
</tr>
<tr>
<td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0">
<a href=https://github.com/aberoham>
<img src=https://avatars.githubusercontent.com/u/586805?v=4 width="100;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=Abraham Ingersoll/>
@@ -300,6 +321,8 @@ make build
<sub style="font-size:14px"><b>Arthur Woimbée</b></sub>
</a>
</td>
</tr>
<tr>
<td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0">
<a href=https://github.com/stensonb>
<img src=https://avatars.githubusercontent.com/u/933389?v=4 width="100;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=Bryan Stenson/>
@@ -321,8 +344,6 @@ make build
<sub style="font-size:14px"><b>Felix Yan</b></sub>
</a>
</td>
</tr>
<tr>
<td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0">
<a href=https://github.com/JJGadgets>
<img src=https://avatars.githubusercontent.com/u/5709019?v=4 width="100;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=JJGadgets/>
@@ -344,6 +365,8 @@ make build
<sub style="font-size:14px"><b>Jim Tittsler</b></sub>
</a>
</td>
</tr>
<tr>
<td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0">
<a href=https://github.com/piec>
<img src=https://avatars.githubusercontent.com/u/781471?v=4 width="100;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=Pierre Carru/>
@@ -365,8 +388,6 @@ make build
<sub style="font-size:14px"><b>Ryan Fowler</b></sub>
</a>
</td>
</tr>
<tr>
<td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0">
<a href=https://github.com/shaananc>
<img src=https://avatars.githubusercontent.com/u/2287839?v=4 width="100;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=Shaanan Cohney/>
@@ -388,6 +409,8 @@ make build
<sub style="font-size:14px"><b>Teteros</b></sub>
</a>
</td>
</tr>
<tr>
<td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0">
<a href=https://github.com/gitter-badger>
<img src=https://avatars.githubusercontent.com/u/8518239?v=4 width="100;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=The Gitter Badger/>
@@ -409,8 +432,6 @@ make build
<sub style="font-size:14px"><b>Tjerk Woudsma</b></sub>
</a>
</td>
</tr>
<tr>
<td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0">
<a href=https://github.com/zekker6>
<img src=https://avatars.githubusercontent.com/u/1367798?v=4 width="100;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=Zakhar Bessarab/>
@@ -432,13 +453,8 @@ make build
<sub style="font-size:14px"><b>derelm</b></sub>
</a>
</td>
<td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0">
<a href=https://github.com/e-zk>
<img src=https://avatars.githubusercontent.com/u/58356365?v=4 width="100;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=e-zk/>
<br />
<sub style="font-size:14px"><b>e-zk</b></sub>
</a>
</td>
</tr>
<tr>
<td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0">
<a href=https://github.com/ignoramous>
<img src=https://avatars.githubusercontent.com/u/852289?v=4 width="100;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=ignoramous/>
@@ -453,8 +469,6 @@ make build
<sub style="font-size:14px"><b>lion24</b></sub>
</a>
</td>
</tr>
<tr>
<td align="center" style="word-wrap: break-word; width: 150.0; height: 150.0">
<a href=https://github.com/pernila>
<img src=https://avatars.githubusercontent.com/u/12460060?v=4 width="100;" style="border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px" alt=pernila/>

21
acls.go
View File

@@ -17,12 +17,11 @@ import (
)
const (
errEmptyPolicy = Error("empty policy")
errInvalidAction = Error("invalid action")
errInvalidUserSection = Error("invalid user section")
errInvalidGroup = Error("invalid group")
errInvalidTag = Error("invalid tag")
errInvalidPortFormat = Error("invalid port format")
errEmptyPolicy = Error("empty policy")
errInvalidAction = Error("invalid action")
errInvalidGroup = Error("invalid group")
errInvalidTag = Error("invalid tag")
errInvalidPortFormat = Error("invalid port format")
)
const (
@@ -230,6 +229,10 @@ func expandAlias(
return []string{"*"}, nil
}
log.Debug().
Str("alias", alias).
Msg("Expanding")
if strings.HasPrefix(alias, "group:") {
namespaces, err := expandGroup(aclPolicy, alias, stripEmailDomain)
if err != nil {
@@ -293,7 +296,9 @@ func expandAlias(
return []string{cidr.String()}, nil
}
return ips, errInvalidUserSection
log.Warn().Msgf("No IPs found with the alias %v", alias)
return ips, nil
}
// excludeCorrectlyTaggedNodes will remove from the list of input nodes the ones
@@ -439,7 +444,7 @@ func expandGroup(
errInvalidGroup,
)
}
grp, err := NormalizeNamespaceName(group, stripEmailDomain)
grp, err := NormalizeToFQDNRules(group, stripEmailDomain)
if err != nil {
return []string{}, fmt.Errorf(
"failed to normalize group %q, err: %w",

15
api.go
View File

@@ -134,6 +134,19 @@ func (h *Headscale) RegistrationHandler(ctx *gin.Context) {
return
}
hname, err := NormalizeToFQDNRules(
req.Hostinfo.Hostname,
h.cfg.OIDC.StripEmaildomain,
)
if err != nil {
log.Error().
Caller().
Str("func", "RegistrationHandler").
Str("hostinfo.name", req.Hostinfo.Hostname).
Err(err)
return
}
// The machine did not have a key to authenticate, which means
// that we rely on a method that calls back some how (OpenID or CLI)
@@ -141,7 +154,7 @@ func (h *Headscale) RegistrationHandler(ctx *gin.Context) {
// happens
newMachine := Machine{
MachineKey: machineKeyStr,
Name: req.Hostinfo.Hostname,
Name: hname,
NodeKey: NodePublicKeyStripPrefix(req.NodeKey),
LastSeen: &now,
Expiry: &time.Time{},

4
app.go
View File

@@ -456,8 +456,10 @@ func (h *Headscale) createRouter(grpcMux *runtime.ServeMux) *gin.Engine {
router.POST("/machine/:id", h.RegistrationHandler)
router.GET("/oidc/register/:mkey", h.RegisterOIDC)
router.GET("/oidc/callback", h.OIDCCallback)
router.GET("/apple", h.AppleMobileConfig)
router.GET("/apple", h.AppleConfigMessage)
router.GET("/apple/:platform", h.ApplePlatformConfig)
router.GET("/windows", h.WindowsConfigMessage)
router.GET("/windows/tailscale.reg", h.WindowsRegConfig)
router.GET("/swagger", SwaggerUI)
router.GET("/swagger/v1/openapiv2.json", SwaggerAPIv1)

View File

@@ -123,7 +123,7 @@ tls_client_auth_mode: relaxed
tls_letsencrypt_cache_dir: /var/lib/headscale/cache
# Type of ACME challenge to use, currently supported types:
# HTTP-01 or TLS_ALPN-01
# HTTP-01 or TLS-ALPN-01
# See [docs/tls.md](docs/tls.md) for more information
tls_letsencrypt_challenge_type: HTTP-01
# When HTTP-01 challenge is chosen, letsencrypt must set up a

View File

@@ -41,7 +41,7 @@ type Namespace struct {
// CreateNamespace creates a new Namespace. Returns error if could not be created
// or another namespace already exists.
func (h *Headscale) CreateNamespace(name string) (*Namespace, error) {
err := CheckNamespaceName(name)
err := CheckForFQDNRules(name)
if err != nil {
return nil, err
}
@@ -104,7 +104,7 @@ func (h *Headscale) RenameNamespace(oldName, newName string) error {
if err != nil {
return err
}
err = CheckNamespaceName(newName)
err = CheckForFQDNRules(newName)
if err != nil {
return err
}
@@ -150,7 +150,7 @@ func (h *Headscale) ListNamespaces() ([]Namespace, error) {
// ListMachinesInNamespace gets all the nodes in a given namespace.
func (h *Headscale) ListMachinesInNamespace(name string) ([]Machine, error) {
err := CheckNamespaceName(name)
err := CheckForFQDNRules(name)
if err != nil {
return nil, err
}
@@ -169,7 +169,7 @@ func (h *Headscale) ListMachinesInNamespace(name string) ([]Machine, error) {
// SetMachineNamespace assigns a Machine to a namespace.
func (h *Headscale) SetMachineNamespace(machine *Machine, namespaceName string) error {
err := CheckNamespaceName(namespaceName)
err := CheckForFQDNRules(namespaceName)
if err != nil {
return err
}
@@ -237,9 +237,9 @@ func (n *Namespace) toProto() *v1.Namespace {
}
}
// NormalizeNamespaceName will replace forbidden chars in namespace
// NormalizeToFQDNRules will replace forbidden chars in namespace
// it can also return an error if the namespace doesn't respect RFC 952 and 1123.
func NormalizeNamespaceName(name string, stripEmailDomain bool) (string, error) {
func NormalizeToFQDNRules(name string, stripEmailDomain bool) (string, error) {
name = strings.ToLower(name)
name = strings.ReplaceAll(name, "'", "")
atIdx := strings.Index(name, "@")
@@ -263,7 +263,7 @@ func NormalizeNamespaceName(name string, stripEmailDomain bool) (string, error)
return name, nil
}
func CheckNamespaceName(name string) error {
func CheckForFQDNRules(name string) error {
if len(name) > labelHostnameLength {
return fmt.Errorf(
"Namespace must not be over 63 chars. %v doesn't comply with this rule: %w",

View File

@@ -233,7 +233,7 @@ func (s *Suite) TestGetMapResponseUserProfiles(c *check.C) {
c.Assert(found, check.Equals, true)
}
func TestNormalizeNamespaceName(t *testing.T) {
func TestNormalizeToFQDNRules(t *testing.T) {
type args struct {
name string
stripEmailDomain bool
@@ -310,10 +310,10 @@ func TestNormalizeNamespaceName(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := NormalizeNamespaceName(tt.args.name, tt.args.stripEmailDomain)
got, err := NormalizeToFQDNRules(tt.args.name, tt.args.stripEmailDomain)
if (err != nil) != tt.wantErr {
t.Errorf(
"NormalizeNamespaceName() error = %v, wantErr %v",
"NormalizeToFQDNRules() error = %v, wantErr %v",
err,
tt.wantErr,
)
@@ -321,13 +321,13 @@ func TestNormalizeNamespaceName(t *testing.T) {
return
}
if got != tt.want {
t.Errorf("NormalizeNamespaceName() = %v, want %v", got, tt.want)
t.Errorf("NormalizeToFQDNRules() = %v, want %v", got, tt.want)
}
})
}
}
func TestCheckNamespaceName(t *testing.T) {
func TestCheckForFQDNRules(t *testing.T) {
type args struct {
name string
}
@@ -366,8 +366,8 @@ func TestCheckNamespaceName(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := CheckNamespaceName(tt.args.name); (err != nil) != tt.wantErr {
t.Errorf("CheckNamespaceName() error = %v, wantErr %v", err, tt.wantErr)
if err := CheckForFQDNRules(tt.args.name); (err != nil) != tt.wantErr {
t.Errorf("CheckForFQDNRules() error = %v, wantErr %v", err, tt.wantErr)
}
})
}

View File

@@ -253,7 +253,7 @@ func (h *Headscale) OIDCCallback(ctx *gin.Context) {
return
}
namespaceName, err := NormalizeNamespaceName(
namespaceName, err := NormalizeToFQDNRules(
claims.Email,
h.cfg.OIDC.StripEmaildomain,
)

View File

@@ -11,26 +11,118 @@ import (
"github.com/rs/zerolog/log"
)
// AppleMobileConfig shows a simple message in the browser to point to the CLI
// Listens in /register.
func (h *Headscale) AppleMobileConfig(ctx *gin.Context) {
// WindowsConfigMessage shows a simple message in the browser for how to configure the Windows Tailscale client.
func (h *Headscale) WindowsConfigMessage(ctx *gin.Context) {
winTemplate := template.Must(template.New("windows").Parse(`
<html>
<body>
<h1>headscale</h1>
<h2>Windows registry configuration</h2>
<p>
This page provides Windows registry information for the official Windows Tailscale client.
<p>
<p>
The registry file will configure Tailscale to use <code>{{.URL}}</code> as its control server.
<p>
<h3>Caution</h3>
<p>You should always download and inspect the registry file before installing it:</p>
<pre><code>curl {{.URL}}/windows/tailscale.reg</code></pre>
<h2>Installation</h2>
<p>Headscale can be set to the default server by running the registry file:</p>
<p>
<a href="/windows/tailscale.reg" download="tailscale.reg">Windows registry file</a>
</p>
<ol>
<li>Download the registry file, then run it</li>
<li>Follow the prompts</li>
<li>Install and run the official windows Tailscale client</li>
<li>When the installation has finished, start Tailscale, and log in by clicking the icon in the system tray</li>
</ol>
<p>Or</p>
<p>Open command prompt with Administrator rights. Issue the following commands to add the required registry entries:</p>
<pre>
<code>REG ADD "HKLM\Software\Tailscale IPN" /v UnattendedMode /t REG_SZ /d always
REG ADD "HKLM\Software\Tailscale IPN" /v LoginURL /t REG_SZ /d "{{.URL}}"</code></pre>
<p>
Restart Tailscale and log in.
<p>
</body>
</html>
`))
config := map[string]interface{}{
"URL": h.cfg.ServerURL,
}
var payload bytes.Buffer
if err := winTemplate.Execute(&payload, config); err != nil {
log.Error().
Str("handler", "WindowsRegConfig").
Err(err).
Msg("Could not render Windows index template")
ctx.Data(
http.StatusInternalServerError,
"text/html; charset=utf-8",
[]byte("Could not render Windows index template"),
)
return
}
ctx.Data(http.StatusOK, "text/html; charset=utf-8", payload.Bytes())
}
// WindowsRegConfig generates and serves a .reg file configured with the Headscale server address.
func (h *Headscale) WindowsRegConfig(ctx *gin.Context) {
config := WindowsRegistryConfig{
URL: h.cfg.ServerURL,
}
var content bytes.Buffer
if err := windowsRegTemplate.Execute(&content, config); err != nil {
log.Error().
Str("handler", "WindowsRegConfig").
Err(err).
Msg("Could not render Apple macOS template")
ctx.Data(
http.StatusInternalServerError,
"text/html; charset=utf-8",
[]byte("Could not render Windows registry template"),
)
return
}
ctx.Data(
http.StatusOK,
"text/x-ms-regedit; charset=utf-8",
content.Bytes(),
)
}
// AppleConfigMessage shows a simple message in the browser to point the user to the iOS/MacOS profile and instructions for how to install it.
func (h *Headscale) AppleConfigMessage(ctx *gin.Context) {
appleTemplate := template.Must(template.New("apple").Parse(`
<html>
<body>
<h1>Apple configuration profiles</h1>
<h1>headscale</h1>
<h2>Apple configuration profiles</h2>
<p>
This page provides <a href="https://support.apple.com/guide/mdm/mdm-overview-mdmbf9e668/web">configuration profiles</a> for the official Tailscale clients for <a href="https://apps.apple.com/us/app/tailscale/id1470499037?ls=1">iOS</a> and <a href="https://apps.apple.com/ca/app/tailscale/id1475387142?mt=12">macOS</a>.
</p>
<p>
The profiles will configure Tailscale.app to use {{.Url}} as its control server.
The profiles will configure Tailscale.app to use <code>{{.URL}}</code> as its control server.
</p>
<h3>Caution</h3>
<p>You should always inspect the profile before installing it:</p>
<p>You should always download and inspect the profile before installing it:</p>
<!--
<p><code>curl {{.Url}}/apple/ios</code></p>
<pre><code>curl {{.URL}}/apple/ios</code></pre>
-->
<p><code>curl {{.Url}}/apple/macos</code></p>
<pre><code>curl {{.URL}}/apple/macos</code></pre>
<h2>Profiles</h2>
@@ -192,6 +284,10 @@ func (h *Headscale) ApplePlatformConfig(ctx *gin.Context) {
)
}
type WindowsRegistryConfig struct {
URL string
}
type AppleMobileConfig struct {
UUID uuid.UUID
URL string
@@ -203,6 +299,14 @@ type AppleMobilePlatformConfig struct {
URL string
}
var windowsRegTemplate = textTemplate.Must(
textTemplate.New("windowsconfig").Parse(`Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Tailscale IPN]
"UnattendedMode"="always"
"LoginURL"="{{.URL}}"
`))
var commonTemplate = textTemplate.Must(
textTemplate.New("mobileconfig").Parse(`<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">

13
poll.go
View File

@@ -83,7 +83,18 @@ func (h *Headscale) PollNetMapHandler(ctx *gin.Context) {
Str("machine", machine.Name).
Msg("Found machine in database")
machine.Name = req.Hostinfo.Hostname
hname, err := NormalizeToFQDNRules(
req.Hostinfo.Hostname,
h.cfg.OIDC.StripEmaildomain,
)
if err != nil {
log.Error().
Caller().
Str("func", "handleAuthKey").
Str("hostinfo.name", req.Hostinfo.Hostname).
Err(err)
}
machine.Name = hname
machine.HostInfo = HostInfo(*req.Hostinfo)
machine.DiscoKey = DiscoPublicKeyStripPrefix(req.DiscoKey)
now := time.Now().UTC()