diff --git a/README.md b/README.md index e9f7990f..c99b54d7 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,6 @@ Suggestions/PRs welcomed! Please have a look at the documentation under [`docs/`](docs/). - ## Disclaimer 1. We have nothing to do with Tailscale, or Tailscale Inc. @@ -70,7 +69,7 @@ To contribute to Headscale you would need the lastest version of [Go](https://go - Buf - Protobuf tools: -```shell +```shell make install-protobuf-plugins ``` @@ -81,6 +80,7 @@ Some parts of the project requires the generation of Go code from Protobuf (if c ```shell make generate ``` + **Note**: Please check in changes from `gen/` in a separate commit to make it easier to review. To run the tests: @@ -261,5 +261,3 @@ make build - - diff --git a/derp-example.yaml b/derp-example.yaml index bbf7cc8d..a9901bef 100644 --- a/derp-example.yaml +++ b/derp-example.yaml @@ -1,15 +1,15 @@ # If you plan to somehow use headscale, please deploy your own DERP infra: https://tailscale.com/kb/1118/custom-derp-servers/ -regions: +regions: 900: regionid: 900 regioncode: custom regionname: My Region nodes: - - name: 1a - regionid: 1 - hostname: myderp.mydomain.no - ipv4: 123.123.123.123 - ipv6: "2604:a880:400:d1::828:b001" - stunport: 0 - stunonly: false - derptestport: 0 + - name: 1a + regionid: 1 + hostname: myderp.mydomain.no + ipv4: 123.123.123.123 + ipv6: "2604:a880:400:d1::828:b001" + stunport: 0 + stunonly: false + derptestport: 0 diff --git a/docs/Running.md b/docs/Running.md index b784aba9..9969a614 100644 --- a/docs/Running.md +++ b/docs/Running.md @@ -1,6 +1,7 @@ # Running headscale ## Server configuration + 1. Download the headscale binary https://github.com/juanfont/headscale/releases, and place it somewhere in your $PATH or use the docker container ```shell @@ -18,10 +19,11 @@ ```shell mkdir config ``` - + 3. Get yourself a DB a) Get a Postgres DB running in docker + ```shell docker run --name headscale \ -e POSTGRES_DB=headscale @@ -30,7 +32,9 @@ -p 5432:5432 \ -d postgres ``` + or b) Prepare a SQLite DB file + ```shell touch config/db.sqlite ``` @@ -41,7 +45,7 @@ wg genkey > config/private.key cp config.yaml.[sqlite|postgres].example config/config.yaml - + cp derp-example.yaml config/derp.yaml ``` @@ -81,16 +85,19 @@ -p 127.0.0.1:8080:8080 \ headscale/headscale:x.x.x headscale serve ``` + ## Nodes configuration If you used tailscale.com before in your nodes, make sure you clear the tailscaled data folder - ```shell - systemctl stop tailscaled - rm -fr /var/lib/tailscale - systemctl start tailscaled - ``` +```shell +systemctl stop tailscaled +rm -fr /var/lib/tailscale +systemctl start tailscaled +``` + ### Adding node based on MACHINEKEY + 1. Add your first machine ```shell diff --git a/k8s/README.md b/k8s/README.md index 45574b48..78e9ef2c 100644 --- a/k8s/README.md +++ b/k8s/README.md @@ -24,6 +24,7 @@ Configure DERP servers by editing `base/site/derp.yaml` if needed. You'll somehow need to get `headscale:latest` into your cluster image registry. An easy way to do this with k3s: + - Reconfigure k3s to use docker instead of containerd (`k3s server --docker`) - `docker build -t headscale:latest ..` from here @@ -61,7 +62,7 @@ Use the wrapper script to remotely operate headscale to perform administrative tasks like creating namespaces, authkeys, etc. ``` -[c@nix-slate:~/Projects/headscale/k8s]$ ./headscale.bash +[c@nix-slate:~/Projects/headscale/k8s]$ ./headscale.bash headscale is an open source implementation of the Tailscale control server diff --git a/k8s/base/ingress.yaml b/k8s/base/ingress.yaml index a279bc1c..51da3427 100644 --- a/k8s/base/ingress.yaml +++ b/k8s/base/ingress.yaml @@ -6,13 +6,13 @@ metadata: kubernetes.io/ingress.class: traefik spec: rules: - - host: $(PUBLIC_HOSTNAME) - http: - paths: - - backend: - service: - name: headscale - port: - number: 8080 - path: / - pathType: Prefix + - host: $(PUBLIC_HOSTNAME) + http: + paths: + - backend: + service: + name: headscale + port: + number: 8080 + path: / + pathType: Prefix diff --git a/k8s/base/kustomization.yaml b/k8s/base/kustomization.yaml index 54d66e54..93278f7d 100644 --- a/k8s/base/kustomization.yaml +++ b/k8s/base/kustomization.yaml @@ -1,42 +1,42 @@ namespace: headscale resources: -- configmap.yaml -- ingress.yaml -- service.yaml + - configmap.yaml + - ingress.yaml + - service.yaml generatorOptions: disableNameSuffixHash: true configMapGenerator: -- name: headscale-site - files: - - derp.yaml=site/derp.yaml - envs: - - site/public.env -- name: headscale-etc - literals: - - config.json={} + - name: headscale-site + files: + - derp.yaml=site/derp.yaml + envs: + - site/public.env + - name: headscale-etc + literals: + - config.json={} secretGenerator: -- name: headscale - files: - - secrets/private-key + - name: headscale + files: + - secrets/private-key vars: -- name: PUBLIC_PROTO - objRef: - kind: ConfigMap - name: headscale-site - apiVersion: v1 - fieldRef: - fieldPath: data.public-proto -- name: PUBLIC_HOSTNAME - objRef: - kind: ConfigMap - name: headscale-site - apiVersion: v1 - fieldRef: - fieldPath: data.public-hostname -- name: CONTACT_EMAIL - objRef: - kind: ConfigMap - name: headscale-site - apiVersion: v1 - fieldRef: - fieldPath: data.contact-email + - name: PUBLIC_PROTO + objRef: + kind: ConfigMap + name: headscale-site + apiVersion: v1 + fieldRef: + fieldPath: data.public-proto + - name: PUBLIC_HOSTNAME + objRef: + kind: ConfigMap + name: headscale-site + apiVersion: v1 + fieldRef: + fieldPath: data.public-hostname + - name: CONTACT_EMAIL + objRef: + kind: ConfigMap + name: headscale-site + apiVersion: v1 + fieldRef: + fieldPath: data.contact-email diff --git a/k8s/base/service.yaml b/k8s/base/service.yaml index 7fdf738f..39e67253 100644 --- a/k8s/base/service.yaml +++ b/k8s/base/service.yaml @@ -8,6 +8,6 @@ spec: selector: app: headscale ports: - - name: http - targetPort: http - port: 8080 + - name: http + targetPort: http + port: 8080 diff --git a/k8s/postgres/deployment.yaml b/k8s/postgres/deployment.yaml index dd45d05b..661d87ed 100644 --- a/k8s/postgres/deployment.yaml +++ b/k8s/postgres/deployment.yaml @@ -13,66 +13,66 @@ spec: app: headscale spec: containers: - - name: headscale - image: "headscale:latest" - imagePullPolicy: IfNotPresent - command: ["/go/bin/headscale", "serve"] - env: - - name: SERVER_URL - value: $(PUBLIC_PROTO)://$(PUBLIC_HOSTNAME) - - name: LISTEN_ADDR - valueFrom: - configMapKeyRef: - name: headscale-config - key: listen_addr - - name: PRIVATE_KEY_PATH - value: /vol/secret/private-key - - name: DERP_MAP_PATH - value: /vol/config/derp.yaml - - name: EPHEMERAL_NODE_INACTIVITY_TIMEOUT - valueFrom: - configMapKeyRef: - name: headscale-config - key: ephemeral_node_inactivity_timeout - - name: DB_TYPE - value: postgres - - name: DB_HOST - value: postgres.headscale.svc.cluster.local - - name: DB_PORT - value: "5432" - - name: DB_USER - value: headscale - - name: DB_PASS - valueFrom: - secretKeyRef: - name: postgresql - key: password - - name: DB_NAME - value: headscale - ports: - - name: http - protocol: TCP - containerPort: 8080 - livenessProbe: - tcpSocket: - port: http - initialDelaySeconds: 30 - timeoutSeconds: 5 - periodSeconds: 15 - volumeMounts: - - name: config - mountPath: /vol/config - - name: secret - mountPath: /vol/secret - - name: etc - mountPath: /etc/headscale + - name: headscale + image: "headscale:latest" + imagePullPolicy: IfNotPresent + command: ["/go/bin/headscale", "serve"] + env: + - name: SERVER_URL + value: $(PUBLIC_PROTO)://$(PUBLIC_HOSTNAME) + - name: LISTEN_ADDR + valueFrom: + configMapKeyRef: + name: headscale-config + key: listen_addr + - name: PRIVATE_KEY_PATH + value: /vol/secret/private-key + - name: DERP_MAP_PATH + value: /vol/config/derp.yaml + - name: EPHEMERAL_NODE_INACTIVITY_TIMEOUT + valueFrom: + configMapKeyRef: + name: headscale-config + key: ephemeral_node_inactivity_timeout + - name: DB_TYPE + value: postgres + - name: DB_HOST + value: postgres.headscale.svc.cluster.local + - name: DB_PORT + value: "5432" + - name: DB_USER + value: headscale + - name: DB_PASS + valueFrom: + secretKeyRef: + name: postgresql + key: password + - name: DB_NAME + value: headscale + ports: + - name: http + protocol: TCP + containerPort: 8080 + livenessProbe: + tcpSocket: + port: http + initialDelaySeconds: 30 + timeoutSeconds: 5 + periodSeconds: 15 + volumeMounts: + - name: config + mountPath: /vol/config + - name: secret + mountPath: /vol/secret + - name: etc + mountPath: /etc/headscale volumes: - - name: config - configMap: - name: headscale-site - - name: etc - configMap: - name: headscale-etc - - name: secret - secret: - secretName: headscale + - name: config + configMap: + name: headscale-site + - name: etc + configMap: + name: headscale-etc + - name: secret + secret: + secretName: headscale diff --git a/k8s/postgres/kustomization.yaml b/k8s/postgres/kustomization.yaml index 8bd6c40c..e732e3b9 100644 --- a/k8s/postgres/kustomization.yaml +++ b/k8s/postgres/kustomization.yaml @@ -1,13 +1,13 @@ namespace: headscale bases: -- ../base + - ../base resources: -- deployment.yaml -- postgres-service.yaml -- postgres-statefulset.yaml + - deployment.yaml + - postgres-service.yaml + - postgres-statefulset.yaml generatorOptions: disableNameSuffixHash: true secretGenerator: -- name: postgresql - files: - - secrets/password + - name: postgresql + files: + - secrets/password diff --git a/k8s/postgres/postgres-service.yaml b/k8s/postgres/postgres-service.yaml index e2f486cc..6252e7f9 100644 --- a/k8s/postgres/postgres-service.yaml +++ b/k8s/postgres/postgres-service.yaml @@ -8,6 +8,6 @@ spec: selector: app: postgres ports: - - name: postgres - targetPort: postgres - port: 5432 + - name: postgres + targetPort: postgres + port: 5432 diff --git a/k8s/postgres/postgres-statefulset.yaml b/k8s/postgres/postgres-statefulset.yaml index 25285c5e..b81c9bf0 100644 --- a/k8s/postgres/postgres-statefulset.yaml +++ b/k8s/postgres/postgres-statefulset.yaml @@ -14,36 +14,36 @@ spec: app: postgres spec: containers: - - name: postgres - image: "postgres:13" - imagePullPolicy: IfNotPresent - env: - - name: POSTGRES_PASSWORD - valueFrom: - secretKeyRef: - name: postgresql - key: password - - name: POSTGRES_USER - value: headscale - ports: - name: postgres - protocol: TCP - containerPort: 5432 - livenessProbe: - tcpSocket: - port: 5432 - initialDelaySeconds: 30 - timeoutSeconds: 5 - periodSeconds: 15 - volumeMounts: - - name: pgdata - mountPath: /var/lib/postgresql/data + image: "postgres:13" + imagePullPolicy: IfNotPresent + env: + - name: POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + name: postgresql + key: password + - name: POSTGRES_USER + value: headscale + ports: + - name: postgres + protocol: TCP + containerPort: 5432 + livenessProbe: + tcpSocket: + port: 5432 + initialDelaySeconds: 30 + timeoutSeconds: 5 + periodSeconds: 15 + volumeMounts: + - name: pgdata + mountPath: /var/lib/postgresql/data volumeClaimTemplates: - - metadata: - name: pgdata - spec: - storageClassName: local-path - accessModes: ["ReadWriteOnce"] - resources: - requests: - storage: 1Gi + - metadata: + name: pgdata + spec: + storageClassName: local-path + accessModes: ["ReadWriteOnce"] + resources: + requests: + storage: 1Gi diff --git a/k8s/production-tls/ingress-patch.yaml b/k8s/production-tls/ingress-patch.yaml index 387c7364..9e6177fb 100644 --- a/k8s/production-tls/ingress-patch.yaml +++ b/k8s/production-tls/ingress-patch.yaml @@ -6,6 +6,6 @@ metadata: traefik.ingress.kubernetes.io/router.tls: "true" spec: tls: - - hosts: - - $(PUBLIC_HOSTNAME) - secretName: production-cert + - hosts: + - $(PUBLIC_HOSTNAME) + secretName: production-cert diff --git a/k8s/production-tls/kustomization.yaml b/k8s/production-tls/kustomization.yaml index f57cb540..d3147f5f 100644 --- a/k8s/production-tls/kustomization.yaml +++ b/k8s/production-tls/kustomization.yaml @@ -1,9 +1,9 @@ namespace: headscale bases: -- ../base + - ../base resources: -- production-issuer.yaml + - production-issuer.yaml patches: -- path: ingress-patch.yaml - target: - kind: Ingress + - path: ingress-patch.yaml + target: + kind: Ingress diff --git a/k8s/production-tls/production-issuer.yaml b/k8s/production-tls/production-issuer.yaml index 7ae9131a..f436090b 100644 --- a/k8s/production-tls/production-issuer.yaml +++ b/k8s/production-tls/production-issuer.yaml @@ -11,6 +11,6 @@ spec: # Secret resource used to store the account's private key. name: letsencrypt-production-acc-key solvers: - - http01: - ingress: - class: traefik + - http01: + ingress: + class: traefik diff --git a/k8s/sqlite/kustomization.yaml b/k8s/sqlite/kustomization.yaml index 5be451ca..ca799419 100644 --- a/k8s/sqlite/kustomization.yaml +++ b/k8s/sqlite/kustomization.yaml @@ -1,5 +1,5 @@ namespace: headscale bases: -- ../base + - ../base resources: -- statefulset.yaml + - statefulset.yaml diff --git a/k8s/sqlite/statefulset.yaml b/k8s/sqlite/statefulset.yaml index 9075e007..71077dad 100644 --- a/k8s/sqlite/statefulset.yaml +++ b/k8s/sqlite/statefulset.yaml @@ -14,66 +14,66 @@ spec: app: headscale spec: containers: - - name: headscale - image: "headscale:latest" - imagePullPolicy: IfNotPresent - command: ["/go/bin/headscale", "serve"] - env: - - name: SERVER_URL - value: $(PUBLIC_PROTO)://$(PUBLIC_HOSTNAME) - - name: LISTEN_ADDR - valueFrom: - configMapKeyRef: - name: headscale-config - key: listen_addr - - name: PRIVATE_KEY_PATH - value: /vol/secret/private-key - - name: DERP_MAP_PATH - value: /vol/config/derp.yaml - - name: EPHEMERAL_NODE_INACTIVITY_TIMEOUT - valueFrom: - configMapKeyRef: - name: headscale-config - key: ephemeral_node_inactivity_timeout - - name: DB_TYPE - value: sqlite3 - - name: DB_PATH - value: /vol/data/db.sqlite - ports: - - name: http - protocol: TCP - containerPort: 8080 - livenessProbe: - tcpSocket: - port: http - initialDelaySeconds: 30 - timeoutSeconds: 5 - periodSeconds: 15 - volumeMounts: - - name: config - mountPath: /vol/config - - name: data - mountPath: /vol/data - - name: secret - mountPath: /vol/secret - - name: etc - mountPath: /etc/headscale + - name: headscale + image: "headscale:latest" + imagePullPolicy: IfNotPresent + command: ["/go/bin/headscale", "serve"] + env: + - name: SERVER_URL + value: $(PUBLIC_PROTO)://$(PUBLIC_HOSTNAME) + - name: LISTEN_ADDR + valueFrom: + configMapKeyRef: + name: headscale-config + key: listen_addr + - name: PRIVATE_KEY_PATH + value: /vol/secret/private-key + - name: DERP_MAP_PATH + value: /vol/config/derp.yaml + - name: EPHEMERAL_NODE_INACTIVITY_TIMEOUT + valueFrom: + configMapKeyRef: + name: headscale-config + key: ephemeral_node_inactivity_timeout + - name: DB_TYPE + value: sqlite3 + - name: DB_PATH + value: /vol/data/db.sqlite + ports: + - name: http + protocol: TCP + containerPort: 8080 + livenessProbe: + tcpSocket: + port: http + initialDelaySeconds: 30 + timeoutSeconds: 5 + periodSeconds: 15 + volumeMounts: + - name: config + mountPath: /vol/config + - name: data + mountPath: /vol/data + - name: secret + mountPath: /vol/secret + - name: etc + mountPath: /etc/headscale volumes: - - name: config - configMap: - name: headscale-site - - name: etc - configMap: - name: headscale-etc - - name: secret - secret: - secretName: headscale + - name: config + configMap: + name: headscale-site + - name: etc + configMap: + name: headscale-etc + - name: secret + secret: + secretName: headscale volumeClaimTemplates: - - metadata: - name: data - spec: - storageClassName: local-path - accessModes: ["ReadWriteOnce"] - resources: - requests: - storage: 1Gi + - metadata: + name: data + spec: + storageClassName: local-path + accessModes: ["ReadWriteOnce"] + resources: + requests: + storage: 1Gi diff --git a/k8s/staging-tls/ingress-patch.yaml b/k8s/staging-tls/ingress-patch.yaml index f97974bd..5a1daf0c 100644 --- a/k8s/staging-tls/ingress-patch.yaml +++ b/k8s/staging-tls/ingress-patch.yaml @@ -6,6 +6,6 @@ metadata: traefik.ingress.kubernetes.io/router.tls: "true" spec: tls: - - hosts: - - $(PUBLIC_HOSTNAME) - secretName: staging-cert + - hosts: + - $(PUBLIC_HOSTNAME) + secretName: staging-cert diff --git a/k8s/staging-tls/kustomization.yaml b/k8s/staging-tls/kustomization.yaml index 931f27d5..0900c583 100644 --- a/k8s/staging-tls/kustomization.yaml +++ b/k8s/staging-tls/kustomization.yaml @@ -1,9 +1,9 @@ namespace: headscale bases: -- ../base + - ../base resources: -- staging-issuer.yaml + - staging-issuer.yaml patches: -- path: ingress-patch.yaml - target: - kind: Ingress + - path: ingress-patch.yaml + target: + kind: Ingress diff --git a/k8s/staging-tls/staging-issuer.yaml b/k8s/staging-tls/staging-issuer.yaml index 95325f6e..cf290415 100644 --- a/k8s/staging-tls/staging-issuer.yaml +++ b/k8s/staging-tls/staging-issuer.yaml @@ -11,6 +11,6 @@ spec: # Secret resource used to store the account's private key. name: letsencrypt-staging-acc-key solvers: - - http01: - ingress: - class: traefik + - http01: + ingress: + class: traefik