As a fan of nip.io
, I wanted to create my own version of it. So I did. This is a simple Rust application that can be deployed to Kubernetes to create a wildcard DNS resolver for your cluster. It’s a fun little project that I hope you’ll enjoy. It uses no external dependencies and is very lightweight, every DNS request and response is handled by the application itself, without any external libraries.
Wildcard DNS for any IP Address. RustyAlias allows you to map any IP Address to a hostname using the following formats (dot, dash or hex):
Without a name:
10.0.0.1.example.com
maps to 10.0.0.1192-168-1-250.example.com
maps to 192.168.1.250a000803.example.com
maps to 10.0.8.3
With a name:
app.10.8.0.1.example.com
maps to 10.8.0.1app-116-203-255-68.example.com
maps to 116.203.255.68app-c0a801fc.example.com
maps to 192.168.1.252customer1.app.10.0.0.1.example.com
maps to 10.0.0.1customer2-app-127-0-0-1.example.com
maps to 127.0.0.1customer3-app-7f000101.example.com
maps to 127.0.1.1
Prerequisites
- A Kubernetes cluster or a Podman/Docker installation
- A domain name or subdomain that you control
The domain name or subdomain needs to be specified in the GLUE_NAME
environment variable and the RustyAlias public IP in the GLUE_IP
. The SOA_NAME
and HOSTMASTER
environment variables are used to specify the SOA record and the hostmaster email address respectively.
They are needed so that the recursive DNS resolvers on the Internet follow the delegation to your DNS server, when recursively following a dot-notated domain name. For example, 1.ns.example.com -> SOA, 0.1.ns.example.com -> SOA, etc. All the way down to 127.0.0.1.ns.example.com -> A 127.0.0.1.
Installation
Please make sure that you have a domain name or subdomain that you control. You will need to create an NS record (just the one) for the domain or subdomain that points to the public IP address of the RustyAlias server.
Podman (or Docker)
podman run --rm -d \
--name rustyalias \
-p 53:5053/udp \
-e RUST_LOG=info \
-e GLUE_IP=[PUBLIC_IP] \
-e GLUE_NAME=ns.example.com \
-e SOA_NAME=ns.example.com \
-e HOSTMASTER=hostmaster.example.com \
ghcr.io/stenstromen/rustyalias:latest
Kubernetes
The Kubernetes deployment consists of a namespace, a deployment, and a service. The deployment uses the stenstromen/rustyalias
image from GitHub Container Registry. The deployment is configured to run a single replica of the RustyAlias server and expose it on port 53. The service is configured to expose the RustyAlias server on port 53.
Namespace
apiVersion: v1
kind: Namespace
metadata:
name: rustyalias
Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: rustyalias
namespace: rustyalias
spec:
progressDeadlineSeconds: 600
replicas: 1
revisionHistoryLimit: 1
selector:
matchLabels:
app: rustyalias
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
labels:
app: rustyalias
spec:
automountServiceAccountToken: false
containers:
- env:
- name: RUST_LOG
value: info
- name: GLUE_NAME
value: ns.example.com
- name: SOA_NAME
value: ns.example.com
- name: HOSTMASTER
value: hostmaster.example.com
- name: GLUE_IP
value: [PUBLIC_IP]
image: ghcr.io/stenstromen/rustyalias:v1.2.0
resources:
limits:
cpu: 100m
memory: 32Mi
requests:
cpu: 100m
memory: 32Mi
securityContext:
runAsUser: 65534
runAsGroup: 65534
privileged: false
runAsNonRoot: true
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
procMount: Default
capabilities:
drop: ["ALL"]
seccompProfile:
type: RuntimeDefault
imagePullPolicy: IfNotPresent
name: rustyalias
ports:
- containerPort: 5053
protocol: UDP
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
terminationGracePeriodSeconds: 30
Service
apiVersion: v1
kind: Service
metadata:
name: rustyalias-service
namespace: rustyalias
spec:
internalTrafficPolicy: Cluster
ipFamilies:
- IPv4
- IPv6
ipFamilyPolicy: RequireDualStack
ports:
- name: dns
protocol: UDP
port: 53
targetPort: 5053
selector:
app: rustyalias
type: LoadBalancer
Usage
Once the RustyAlias server is running and the NS record is created, you can start using it. You can use the RustyAlias server to resolve any domain name that matches the formats described above. Here are some examples:
dig app.127.0.0.1.ns.example.com -> A 127.0.0.1
dig app-127-0-0-1.ns.example.com -> A 127.0.0.1
dig app-7f000001.ns.example.com -> A 127.0.0.1
GitHub Repository
The source code for RustyAlias is available on GitHub at Stenstromen/rustyalias.