Skip to content

Commit

Permalink
Merge pull request #3 from ninech/custom-dns-domain
Browse files Browse the repository at this point in the history
allow for custom domain in k8s-nameserver
  • Loading branch information
thirdeyenick authored Dec 3, 2024
2 parents ae9ec47 + 1658054 commit 36903c2
Show file tree
Hide file tree
Showing 6 changed files with 32 additions and 6 deletions.
16 changes: 10 additions & 6 deletions cmd/k8s-nameserver/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ package main
import (
"context"
"encoding/json"
"flag"
"fmt"
"log"
"net"
Expand All @@ -26,9 +27,12 @@ import (
"tailscale.com/util/dnsname"
)

var (
// domain is the DNS domain that this nameserver has registered a handler for.
domain = flag.String("domain", "ts.net", "the DNS domain to serve records for")
)

const (
// tsNetDomain is the domain that this DNS nameserver has registered a handler for.
tsNetDomain = "ts.net"
// addr is the the address that the UDP and TCP listeners will listen on.
addr = ":1053"

Expand All @@ -40,7 +44,7 @@ const (
)

// nameserver is a simple nameserver that responds to DNS queries for A records
// for ts.net domain names over UDP or TCP. It serves DNS responses from
// for the names of the given domain over UDP or TCP. It serves DNS responses from
// in-memory IPv4 host records. It is intended to be deployed on Kubernetes with
// a ConfigMap mounted at /config that should contain the host records. It
// dynamically reconfigures its in-memory mappings as the contents of the
Expand Down Expand Up @@ -78,11 +82,11 @@ func main() {
// reset when the configuration changes.
ns.runRecordsReconciler(ctx)

// Register a DNS server handle for ts.net domain names. Not having a
// Register a DNS server handle for names of the domain. Not having a
// handle registered for any other domain names is how we enforce that
// this nameserver can only be used for ts.net domains - querying any
// this nameserver can only be used for the given domain - querying any
// other domain names returns Rcode Refused.
dns.HandleFunc(tsNetDomain, ns.handleFunc())
dns.HandleFunc(*domain, ns.handleFunc())

// Listen for DNS queries over UDP and TCP.
udpSig := make(chan os.Signal)
Expand Down
5 changes: 5 additions & 0 deletions cmd/k8s-operator/deploy/crds/tailscale.com_dnsconfigs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,11 @@ spec:
required:
- nameserver
properties:
domain:
description: |-
Domain is the domain for which DNS entries will be resolved. If left
empty, the default of the k8s-nameserver will be used.
type: string
nameserver:
description: |-
Configuration for a nameserver that can resolve ts.net DNS names
Expand Down
5 changes: 5 additions & 0 deletions cmd/k8s-operator/deploy/manifests/operator.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,11 @@ spec:
More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
properties:
domain:
description: |-
Domain is the domain for which DNS entries will be resolved. If left
empty, the default of the k8s-nameserver will be used.
type: string
nameserver:
description: |-
Configuration for a nameserver that can resolve ts.net DNS names
Expand Down
7 changes: 7 additions & 0 deletions cmd/k8s-operator/nameserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,9 @@ func (a *NameserverReconciler) maybeProvision(ctx context.Context, tsDNSCfg *tsa
if tsDNSCfg.Spec.Nameserver.Image != nil && tsDNSCfg.Spec.Nameserver.Image.Tag != "" {
dCfg.imageTag = tsDNSCfg.Spec.Nameserver.Image.Tag
}
if tsDNSCfg.Spec.Domain != "" {
dCfg.domain = tsDNSCfg.Spec.Domain
}
for _, deployable := range []deployable{saDeployable, deployDeployable, svcDeployable, cmDeployable} {
if err := deployable.updateObj(ctx, dCfg, a.Client); err != nil {
return fmt.Errorf("error reconciling %s: %w", deployable.kind, err)
Expand Down Expand Up @@ -207,6 +210,7 @@ type deployConfig struct {
labels map[string]string
ownerRefs []metav1.OwnerReference
namespace string
domain string
}

var (
Expand All @@ -227,6 +231,9 @@ var (
return fmt.Errorf("error unmarshalling Deployment yaml: %w", err)
}
d.Spec.Template.Spec.Containers[0].Image = fmt.Sprintf("%s:%s", cfg.imageRepo, cfg.imageTag)
if cfg.domain != "" {
d.Spec.Template.Spec.Containers[0].Args = []string{"-domain", cfg.domain}
}
d.ObjectMeta.Namespace = cfg.namespace
d.ObjectMeta.Labels = cfg.labels
d.ObjectMeta.OwnerReferences = cfg.ownerRefs
Expand Down
1 change: 1 addition & 0 deletions k8s-operator/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ _Appears in:_
| Field | Description | Default | Validation |
| --- | --- | --- | --- |
| `nameserver` _[Nameserver](#nameserver)_ | Configuration for a nameserver that can resolve ts.net DNS names<br />associated with in-cluster proxies for Tailscale egress Services and<br />Tailscale Ingresses. The operator will always deploy this nameserver<br />when a DNSConfig is applied. | | |
| `domain` _string_ | Domain is the domain for which DNS entries will be resolved. If left<br />empty, the default of the k8s-nameserver will be used. | | |


#### DNSConfigStatus
Expand Down
4 changes: 4 additions & 0 deletions k8s-operator/apis/v1alpha1/types_tsdnsconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,10 @@ type DNSConfigSpec struct {
// Tailscale Ingresses. The operator will always deploy this nameserver
// when a DNSConfig is applied.
Nameserver *Nameserver `json:"nameserver"`
// Domain is the domain for which DNS entries will be resolved. If left
// empty, the default of the k8s-nameserver will be used.
// +optional
Domain string `json:"domain"`
}

type Nameserver struct {
Expand Down

0 comments on commit 36903c2

Please sign in to comment.