Skip to content
This repository has been archived by the owner on May 6, 2022. It is now read-only.

Commit

Permalink
🚀 Add ZeroTier, arm64 support, and some QOL fixes
Browse files Browse the repository at this point in the history
- Adds ZeroTier support within the container (currently not toggleable).
- Add arm64 support.
- Removes the need for a configuration file.
- Migrates Corefile into /app, as it's now more generic (while still
  supporting same name-resolution features).
- Move to port 5053 exposure so that it doesn't conflict with built-in
  DNS services.
- Move from hand-built ZeroTier API to ZTC, a project by one of
  ZeroTier's founders to access ZeroTier Central's API.
  - TODO: figure out how to lessen the bloat from node.js app.
- Migrate from `invoke` to `click` for CLI interface.
  • Loading branch information
jmuchovej committed Feb 25, 2021
1 parent eb68b62 commit ed2d694
Show file tree
Hide file tree
Showing 19 changed files with 195 additions and 194 deletions.
92 changes: 56 additions & 36 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,51 +1,71 @@
FROM ghcr.io/linuxserver/baseimage-ubuntu:focal
# Build ZeroTier -----------------------------------------------------------------------
FROM --platform=$TARGETPLATFORM lsiodev/ubuntu:focal as zerotier
ARG ZeroTier

RUN apt-get update -y && apt-get install -y git make gcc g++
RUN git clone https://github.com/zerotier/ZeroTierOne /src
WORKDIR /src

RUN commit="$(git log ${ZeroTier} -n1 | head -1 | cut -d ' ' -f 2)" \
git reset --quiet --hard ${commit}
RUN make -f make-linux.mk
RUN chmod +x zerotier-one

# Build CoreDNS ------------------------------------------------------------------------
FROM --platform=$TARGETPLATFORM lsiodev/ubuntu:focal as coredns
ARG CoreDNS

RUN apt-get update -y && apt-get install -y git make golang
RUN git clone https://github.com/coredns/coredns /src
WORKDIR /src

RUN commit="$(git log ${CoreDNS} -n1 | head -1 | cut -d ' ' -f 2)" \
git reset --quiet --hard ${commit}
RUN make
RUN chmod +x coredns

# Setup ZeroDNS ------------------------------------------------------------------------
FROM --platform=$TARGETPLATFORM lsiodev/ubuntu:focal as zerodns

# set version label
ARG BUIL_DATE
ARG BUILD_DATE
ARG ZeroDNS
ARG CoreDNS
ARG CoreDNSpkg
LABEL build_version="DNS.zt version:- ${ZeroDNS} Build-date:- ${BUILD_DATE}"
LABEL maintainer="ionlights"
ARG ZeroTier
LABEL build_version="ZeroDNS version:- ${ZeroDNS} Build-date:- ${BUILD_DATE}"
LABEL maintainer="jmuchovej"
LABEL vCoreDNS="${CoreDNS}"
LABEL vZeroDNS="${ZeroDNS}"
LABEL vZeroTier="${ZeroTier}"

# environment settings
ARG DEBIAN_FRONTEND="noninteractive"
ENV HOME="/config" \
XDG_CONFIG_HOME="/config" \
XDG_DATA_HOME="/config"

# add dependencies
RUN echo "*** install packages ***" && \
apt-get update && \
apt-get install -y \
ca-certificates \
python3 \
python3-pip

# install CoreDNS
RUN echo "*** install CoreDNS ***" && \
curl -fsSL ${CoreDNSpkg} -o /tmp/coredns.tgz && \
tar -xzf /tmp/coredns.tgz && \
mv coredns /usr/bin/coredns && \
chmod +x /usr/bin/coredns

# install Invoke
COPY requirements.txt /tmp
RUN echo "*** install Invoke ***" && \
pip3 install -r /tmp/requirements.txt

RUN echo "*** cleanup ***" && \
apt-get clean && \
rm -rf \
/tmp/* \
/var/lib/apt/lists/* \
/var/tmp/*

# add local files
COPY root/ /
COPY --from=zerotier /src/zerotier-one /usr/sbin/
COPY --from=coredns /src/coredns /usr/bin/

# add dependencies (this bloats the image quite a bit)
RUN echo "*** install ZeroDNS ***" \
&& apt-get update -y \
&& apt-get install -y ca-certificates python3 python3-pip npm nodejs iputils-ping net-tools \
&& pip3 install -r /app/requirements.txt \
&& npm install -g @laduke/zerotier-central-cli

RUN mkdir -p /var/lib/zerotier-one \
&& ln -s /usr/sbin/zerotier-one /usr/sbin/zerotier-idtool \
&& ln -s /usr/sbin/zerotier-one /usr/sbin/zerotier-cli

# cleanup installation artifacts
RUN echo "*** cleanup ***" \
&& apt-get clean \
&& rm -rf \
/tmp/* \
/var/lib/apt/lists/* \
/var/tmp/*


# ports and volumes
EXPOSE 53 53/udp
EXPOSE 5053 5053/udp
VOLUME /config
4 changes: 0 additions & 4 deletions requirements.txt

This file was deleted.

10 changes: 10 additions & 0 deletions root/app/Corefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
.:5053 {
errors
log
hosts /config/hosts {
reload 15m
fallthrough
}
forward . /etc/resolv.conf
reload 15m
}
3 changes: 0 additions & 3 deletions root/app/inv

This file was deleted.

3 changes: 3 additions & 0 deletions root/app/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
click>=1.4
pandas>=1.0
word2number>=1.1
6 changes: 0 additions & 6 deletions root/app/tasks/__init__.py

This file was deleted.

9 changes: 0 additions & 9 deletions root/app/tasks/templates/Corefile.j2

This file was deleted.

71 changes: 0 additions & 71 deletions root/app/tasks/ztapi.py

This file was deleted.

56 changes: 0 additions & 56 deletions root/app/tasks/ztdns.py

This file was deleted.

5 changes: 5 additions & 0 deletions root/app/update-networks
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env bash

mkdir /var/lib/zerotier-one/networks.d > /dev/null 2> /dev/null
cd /config
find *.conf | xargs -I {} ln -sf /config/{} /var/lib/zerotier-one/networks.d/{}
60 changes: 60 additions & 0 deletions root/app/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
from typing import Union
import io
import re
import subprocess
import shlex
import functools
from pathlib import Path

import pandas as pd
from word2number import w2n


shell = functools.partial(subprocess.Popen, stdout=subprocess.PIPE)


def ztc_get_networks(network: str) -> str:
cmd = shlex.split(f"ztc network:get {network} --columns=name --no-header")
with shell(cmd) as proc:
return proc.stdout.read().decode("utf-8").strip()


def ztc_to_csv(network: str, tld: str) -> pd.DataFrame:
cmd = shlex.split(f"ztc member:list --csv {network}")
with shell(cmd) as proc:
members = io.StringIO(proc.stdout.read().decode("utf-8"))

df = pd.read_csv(members)
df = df[df["Authorized"]]
df = df[["IP-Assignments", "Node-ID", "Name"]]
df["Network"] = network
df["TLD"] = tld

df = df.rename(columns={"IP-Assignments": "IP", "Node-ID": "Node"})
return df


def add_host(ip: str, aliases: list) -> str:
assert type(aliases) == list
return f"{ip.strip():15s} {' '.join(aliases)}\n"


def member_to_host(row) -> list:
aliases = host_abbr(f"{row.Name}.{row.TLD}")
aliases += [row.Name, row.Node, f"{row.Node}.{row.Network}"]
return add_host(row.IP, aliases)


def host_abbr(hostname: str):
split = re.split(r" |-", hostname.split(".")[0])
alias = ""

for s in split:
try:
alias += str(w2n.word_to_num(s))
except ValueError:
alias += s[0]

tld = ".".join(hostname.split(".")[1:])
return [str(hostname), f"{alias}.{tld}"]

40 changes: 40 additions & 0 deletions root/app/zerodns
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#!/usr/bin/env python3
from pathlib import Path
from collections import namedtuple

import click
import pandas as pd

import utils


@click.group()
@click.pass_context
def zerodns(ctx: click.Context) -> None:
network_hexids = Path("/config").glob("*.conf")
network_hexids = list(filter(lambda x: "local" not in x.stem, network_hexids))
network_hexids = list(map(lambda x: x.stem, network_hexids))

network_humans = [utils.ztc_get_networks(network) for network in network_hexids]

tlds = ["com"] * len(network_humans)
domains = [f"{network}.{tld}" for network, tld in zip(network_humans, tlds)]

ZeroDNS = namedtuple("ZeroDNS", ("domains", "networks", "readable"))
ctx.obj = ZeroDNS(domains, network_hexids, network_humans)


@zerodns.command()
@click.pass_context
def update_hosts(ctx: click.Context) -> None:
hosts = [utils.add_host(ip="127.0.0.1", aliases=["localhost"])]
for net, tld in zip(ctx.obj.networks, ctx.obj.domains):
members = utils.ztc_to_csv(net, tld)
hosts += members.apply(utils.member_to_host, axis=1).tolist()

with open("/config/hosts", "w") as zthosts:
zthosts.writelines(hosts)


if __name__ == "__main__":
zerodns()
4 changes: 4 additions & 0 deletions root/etc/cont-init.d/40-cp-networks
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/usr/bin/with-contenv bash

# Link ZeroTier <network>.conf files to the right location
/app/update-networks
Loading

0 comments on commit ed2d694

Please sign in to comment.