├── .dockerfilelintrc
├── .dockerignore
├── .editorconfig
├── .env.example
├── .github
├── FUNDING.yml
└── workflows
│ ├── dnscrypt-server.yml
│ ├── doh-proxy.yml
│ ├── haproxy.yml
│ ├── m13253-doh.yml
│ ├── nsd.yml
│ └── unbound.yml
├── .gitignore
├── LICENSE
├── Readme.md
├── acme-cron-job.yml
├── acme-init-job.yml
├── build.sh
├── daemon.json
├── deploy.sh
├── dns-infra.afdesign
├── dns-infra.png
├── dnscrypt-server
├── Dockerfile
├── Readme.md
├── encrypted-dns.toml.in
├── entrypoint.sh
└── undelegated.txt
├── docker-compose.yml
├── docker-stack.yml
├── docker.md
├── doh-proxy
├── Dockerfile
├── doh-proxy-deployment.yml
├── doh-proxy-srv.yml
└── entrypoint.sh
├── haproxy
├── Dockerfile
├── entrypoint.sh
├── ffdhe2048.txt
├── haproxy-deployment.yml
├── haproxy-srv.yml
├── haproxy.conf
├── haproxy.sh
└── ocsp-updater.sh
├── kube.md
├── lint.sh
├── logo
├── horizonal.png
├── horizontal.svg
├── icon-transparent.png
├── icon-transparent.svg
├── icon.png
├── icon.svg
├── monochrome_horizontal.png
├── monochrome_horizontal.svg
├── monochrome_icon.png
├── monochrome_icon.svg
├── monochrome_vertical.png
├── monochrome_vertical.svg
├── verical.svg
└── vertical.png
├── m13253-doh
├── Dockerfile
├── doh-proxy-deployment.yml
├── doh-proxy-srv.yml
├── doh-server.conf
└── entrypoint.sh
├── namespace.yml
├── nsd
├── Dockerfile
├── entrypoint.sh
├── nsd-deployment.yml
├── nsd-srv.yml
├── nsd.conf
└── opennic.conf
├── package-lock.json
├── package.json
├── test-dog.sh
├── test-doggo.sh
├── test-infra.sh
├── test.sh
├── tests
├── dnscrypt.bats.old
├── doh.bats
├── dot.bats
├── opennic.bats
├── publicarray-au-doh.toml
├── publicarray-au.toml
├── publicarray-au2-doh.toml
├── publicarray-au2.toml
└── tls.bats
├── unbound
├── Dockerfile
├── entrypoint.sh
├── unbound-deployment.yml
├── unbound-srv.yml
├── unbound.conf
└── unbound.sh
└── yarn.lock
/.dockerfilelintrc:
--------------------------------------------------------------------------------
1 | rules:
2 | invalid_command: off
3 | latest_tag: off
4 |
--------------------------------------------------------------------------------
/.dockerignore:
--------------------------------------------------------------------------------
1 | **/.*
2 | **/*.md
3 | **/*.yml
4 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig is awesome: http://EditorConfig.org
2 |
3 | [*]
4 | indent_style = space
5 | indent_size = 4
6 | end_of_line = lf
7 | charset = utf-8
8 | trim_trailing_whitespace = true
9 | insert_final_newline = true
10 |
11 | [*.{yml,yaml}]
12 | indent_size = 2
13 |
14 | [*.md]
15 | trim_trailing_whitespace = false
16 |
--------------------------------------------------------------------------------
/.env.example:
--------------------------------------------------------------------------------
1 | # Global API
2 | CF_KEY=
3 | CF_EMAIL=
4 | # API v4 https://github.com/acmesh-official/acme.sh/wiki/dnsapi#1-cloudflare-option
5 | CF_TOKEN=
6 | CF_ACCOUNT_ID=
7 | CF_ZONE_ID=
8 | HEALTHCHECK=
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: [publicarray]
4 |
--------------------------------------------------------------------------------
/.github/workflows/dnscrypt-server.yml:
--------------------------------------------------------------------------------
1 | name: dnscrypt-server
2 | on:
3 | workflow_dispatch:
4 | push:
5 | paths:
6 | - 'dnscrypt-server/*'
7 | jobs:
8 | build:
9 | name: Build & Push dnscrypt-server Container
10 | runs-on: ubuntu-latest
11 | env:
12 | APP: dnscrypt-server
13 | steps:
14 | - uses: actions/checkout@v3
15 | with:
16 | persist-credentials: false
17 |
18 | - name: Set up QEMU
19 | uses: docker/setup-qemu-action@v2
20 | - name: Set up Docker Buildx
21 | uses: docker/setup-buildx-action@v2
22 |
23 | - name: Login to DockerHub
24 | uses: docker/login-action@v2
25 | with:
26 | username: ${{ secrets.DOCKER_USERNAME }}
27 | password: ${{ secrets.DOCKER_PASSWORD }}
28 |
29 | - name: Login to GitHub Packages
30 | uses: docker/login-action@v2
31 | with:
32 | registry: ghcr.io
33 | username: ${{ github.repository_owner }}
34 | password: ${{ secrets.GH_PACKAGE_TOKEN }}
35 |
36 | - name: Build and push
37 | uses: docker/build-push-action@v4
38 | with:
39 | context: ${{ env.APP }}
40 | file: ${{ env.APP }}/Dockerfile
41 | platforms: linux/amd64
42 | push: true
43 | tags: |
44 | ghcr.io/${{ github.repository }}/${{ env.APP }}:latest
45 | ${{ github.repository_owner }}/${{ env.APP }}:latest
46 |
--------------------------------------------------------------------------------
/.github/workflows/doh-proxy.yml:
--------------------------------------------------------------------------------
1 | name: doh-proxy
2 | on:
3 | workflow_dispatch:
4 | push:
5 | paths:
6 | - 'doh-proxy/*'
7 | jobs:
8 | build:
9 | name: Build & Push doh-proxy Container
10 | runs-on: ubuntu-latest
11 | env:
12 | APP: doh-proxy
13 | steps:
14 | - uses: actions/checkout@v3
15 | with:
16 | persist-credentials: false
17 |
18 | - name: Set up QEMU
19 | uses: docker/setup-qemu-action@v2
20 | - name: Set up Docker Buildx
21 | uses: docker/setup-buildx-action@v2
22 |
23 | - name: Login to DockerHub
24 | uses: docker/login-action@v2
25 | with:
26 | username: ${{ secrets.DOCKER_USERNAME }}
27 | password: ${{ secrets.DOCKER_PASSWORD }}
28 |
29 | - name: Login to GitHub Packages
30 | uses: docker/login-action@v2
31 | with:
32 | registry: ghcr.io
33 | username: ${{ github.repository_owner }}
34 | password: ${{ secrets.GH_PACKAGE_TOKEN }}
35 |
36 | - name: Build and push
37 | uses: docker/build-push-action@v4
38 | with:
39 | context: ${{ env.APP }}
40 | file: ${{ env.APP }}/Dockerfile
41 | platforms: linux/amd64
42 | push: true
43 | tags: |
44 | ghcr.io/${{ github.repository }}/${{ env.APP }}:latest
45 | ${{ github.repository_owner }}/${{ env.APP }}:latest
46 |
--------------------------------------------------------------------------------
/.github/workflows/haproxy.yml:
--------------------------------------------------------------------------------
1 | name: haproxy
2 | on:
3 | workflow_dispatch:
4 | push:
5 | paths:
6 | - 'haproxy/*'
7 | jobs:
8 | build:
9 | name: Build & Push haproxy Container
10 | runs-on: ubuntu-latest
11 | env:
12 | APP: haproxy
13 | steps:
14 | - uses: actions/checkout@v3
15 | with:
16 | persist-credentials: false
17 |
18 | - name: Set up QEMU
19 | uses: docker/setup-qemu-action@v2
20 | - name: Set up Docker Buildx
21 | uses: docker/setup-buildx-action@v2
22 |
23 | - name: Login to DockerHub
24 | uses: docker/login-action@v2
25 | with:
26 | username: ${{ secrets.DOCKER_USERNAME }}
27 | password: ${{ secrets.DOCKER_PASSWORD }}
28 |
29 | - name: Login to GitHub Packages
30 | uses: docker/login-action@v2
31 | with:
32 | registry: ghcr.io
33 | username: ${{ github.repository_owner }}
34 | password: ${{ secrets.GH_PACKAGE_TOKEN }}
35 |
36 | - name: Build and push
37 | uses: docker/build-push-action@v4
38 | with:
39 | context: ${{ env.APP }}
40 | file: ${{ env.APP }}/Dockerfile
41 | platforms: linux/386,linux/amd64,linux/arm64
42 | push: true
43 | tags: |
44 | ghcr.io/${{ github.repository }}/${{ env.APP }}:latest
45 | ${{ github.repository_owner }}/${{ env.APP }}:latest
46 |
--------------------------------------------------------------------------------
/.github/workflows/m13253-doh.yml:
--------------------------------------------------------------------------------
1 | name: m13253-doh
2 | on:
3 | workflow_dispatch:
4 | push:
5 | paths:
6 | - 'm13253-doh/*'
7 | jobs:
8 | build:
9 | name: Build & Push m13253-doh Container
10 | runs-on: ubuntu-latest
11 | env:
12 | APP: m13253-doh
13 | steps:
14 | - uses: actions/checkout@v3
15 | with:
16 | persist-credentials: false
17 |
18 | - name: Set up QEMU
19 | uses: docker/setup-qemu-action@v2
20 | - name: Set up Docker Buildx
21 | uses: docker/setup-buildx-action@v2
22 |
23 | - name: Login to DockerHub
24 | uses: docker/login-action@v2
25 | with:
26 | username: ${{ secrets.DOCKER_USERNAME }}
27 | password: ${{ secrets.DOCKER_PASSWORD }}
28 |
29 | - name: Login to GitHub Packages
30 | uses: docker/login-action@v2
31 | with:
32 | registry: ghcr.io
33 | username: ${{ github.repository_owner }}
34 | password: ${{ secrets.GH_PACKAGE_TOKEN }}
35 |
36 | - name: Build and push
37 | uses: docker/build-push-action@v4
38 | with:
39 | context: ${{ env.APP }}
40 | file: ${{ env.APP }}/Dockerfile
41 | platforms: linux/386,linux/amd64,linux/arm64
42 | push: true
43 | tags: |
44 | ghcr.io/${{ github.repository }}/${{ env.APP }}:latest
45 | ${{ github.repository_owner }}/${{ env.APP }}:latest
46 |
--------------------------------------------------------------------------------
/.github/workflows/nsd.yml:
--------------------------------------------------------------------------------
1 | name: nsd
2 | on:
3 | workflow_dispatch:
4 | push:
5 | paths:
6 | - 'nsd/*'
7 | jobs:
8 | build:
9 | name: Build & Push nsd Container
10 | runs-on: ubuntu-latest
11 | env:
12 | APP: nsd
13 | steps:
14 | - uses: actions/checkout@v3
15 | with:
16 | persist-credentials: false
17 |
18 | - name: Set up QEMU
19 | uses: docker/setup-qemu-action@v2
20 | - name: Set up Docker Buildx
21 | uses: docker/setup-buildx-action@v2
22 |
23 | - name: Login to DockerHub
24 | uses: docker/login-action@v2
25 | with:
26 | username: ${{ secrets.DOCKER_USERNAME }}
27 | password: ${{ secrets.DOCKER_PASSWORD }}
28 |
29 | - name: Login to GitHub Packages
30 | uses: docker/login-action@v2
31 | with:
32 | registry: ghcr.io
33 | username: ${{ github.repository_owner }}
34 | password: ${{ secrets.GH_PACKAGE_TOKEN }}
35 |
36 | - name: Build and push
37 | uses: docker/build-push-action@v4
38 | with:
39 | context: ${{ env.APP }}
40 | file: ${{ env.APP }}/Dockerfile
41 | platforms: linux/386,linux/amd64,linux/arm64
42 | push: true
43 | tags: |
44 | ghcr.io/${{ github.repository }}/${{ env.APP }}:latest
45 | ${{ github.repository_owner }}/${{ env.APP }}:latest
46 |
--------------------------------------------------------------------------------
/.github/workflows/unbound.yml:
--------------------------------------------------------------------------------
1 | name: unbound
2 | on:
3 | workflow_dispatch:
4 | push:
5 | paths:
6 | - 'unbound/*'
7 | jobs:
8 | build:
9 | name: Build & Push unbound Container
10 | runs-on: ubuntu-latest
11 | env:
12 | APP: unbound
13 | steps:
14 | - uses: actions/checkout@v3
15 | with:
16 | persist-credentials: false
17 |
18 | - name: Set up QEMU
19 | uses: docker/setup-qemu-action@v2
20 | - name: Set up Docker Buildx
21 | uses: docker/setup-buildx-action@v2
22 |
23 | - name: Login to DockerHub
24 | uses: docker/login-action@v2
25 | with:
26 | username: ${{ secrets.DOCKER_USERNAME }}
27 | password: ${{ secrets.DOCKER_PASSWORD }}
28 |
29 | - name: Login to GitHub Packages
30 | uses: docker/login-action@v2
31 | with:
32 | registry: ghcr.io
33 | username: ${{ github.repository_owner }}
34 | password: ${{ secrets.GH_PACKAGE_TOKEN }}
35 |
36 | - name: Build and push
37 | uses: docker/build-push-action@v4
38 | with:
39 | context: ${{ env.APP }}
40 | file: ${{ env.APP }}/Dockerfile
41 | platforms: linux/386,linux/amd64,linux/arm64
42 | push: true
43 | tags: |
44 | ghcr.io/${{ github.repository }}/${{ env.APP }}:latest
45 | ${{ github.repository_owner }}/${{ env.APP }}:latest
46 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | *secret*
3 | *backup
4 | *.pcap
5 | *.log
6 | node.yml
7 | .env
8 | data/acme/cron
9 |
--------------------------------------------------------------------------------
/Readme.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | # DNS Resolver Infrastructure
6 |
7 | ## Infrastructure Overview
8 |
9 |
10 | [](https://github.com/publicarray/dns-resolver-infra/actions?workflow=dnscrypt-server)
11 | [](https://github.com/publicarray/dns-resolver-infra/actions?workflow=doh-proxy)
12 | [](https://github.com/publicarray/dns-resolver-infra/actions?workflow=haproxy)
13 | [](https://github.com/publicarray/dns-resolver-infra/actions?workflow=m13253-doh)
14 | [](https://github.com/publicarray/dns-resolver-infra/actions?workflow=nsd)
15 | [](https://github.com/publicarray/dns-resolver-infra/actions?workflow=unbound)
16 |
17 |
18 |
19 | * [acme.sh](https://github.com/Neilpang/acme.sh) (TLS certificate generation for haproxy)
20 | * [nsd](https://www.nlnetlabs.nl/projects/nsd/) ([OpenNIC](https://www.opennic.org/)) [](https://hub.docker.com/r/publicarray/nsd/) [](https://microbadger.com/images/publicarray/nsd)
21 | * [unbound](https://unbound.nlnetlabs.nl/) (DNS Resolver) [](https://hub.docker.com/r/publicarray/unbound/) [](https://microbadger.com/images/publicarray/unbound)
22 | * [dnscrypt-server](https://github.com/jedisct1/encrypted-dns-server) (dnscrypt) [](https://hub.docker.com/r/publicarray/dnscrypt-server/) [](https://microbadger.com/images/publicarray/dnscrypt-server)
23 | * [doh-proxy](https://github.com/jedisct1/rust-doh) [](https://hub.docker.com/r/publicarray/doh-proxy/) [](https://microbadger.com/images/publicarray/doh-proxy) or [m13253-doh](https://github.com/m13253/dns-over-https) [](https://hub.docker.com/r/publicarray/m13253-doh/) 
24 | * [haproxy](http://www.haproxy.org/) (DNS-over-HTTPS) [](https://hub.docker.com/r/publicarray/haproxy/) [](https://microbadger.com/images/publicarray/haproxy)
25 | * [haproxy](http://www.haproxy.org/) (DNS-over-TLS) [](https://hub.docker.com/r/publicarray/haproxy/) [](https://microbadger.com/images/publicarray/haproxy)
26 |
27 | ## Getting started
28 |
29 | ### Quick start**
30 |
31 | ```sh
32 | pacman -S docker docker-composer docker-buildx
33 | git clone https://github.com/publicarray/dns-resolver-infra.git && cd dns-resolver-infra
34 | # Add Cloudflare cedentials for acme.sh / TLS certificates
35 | echo 'CF_TOKEN=xxxx' >> .env
36 | echo 'CF_ACCOUNT_ID=xxxx' >> .env
37 | echo 'CF_ZONE_ID=xxxx' >> .env
38 |
39 | ./deploy.sh
40 | ```
41 |
42 | ### Docker Compose
43 |
44 | ```sh
45 | # Build Images or pull them:
46 | docker-compose pull
47 |
48 | # Add Cloudflare cedentials for acme.sh / TLS certificates
49 | echo 'CF_TOKEN=xxxx' >> .env
50 | echo 'CF_ACCOUNT_ID=xxxx' >> .env
51 | echo 'CF_ZONE_ID=xxxx' >> .env
52 |
53 | # # Setup CA
54 | # docker-compose run acme --register-account -m my@example.com
55 | # # or
56 | # docker-compose run acme.sh --set-default-ca --server letsencrypt
57 |
58 | # Launch
59 | docker-compose up -d
60 | ```
61 |
62 | * [Usage with Docker-Swarm](docker.md)
63 | * [Usage with Kubernetes](kube.md)
64 |
65 | ### sysctl
66 |
67 | ```
68 | sysctl net.ipv4.tcp_congestion_control=bbr
69 | ```
70 |
71 |
72 | ### Tests
73 |
74 | ```
75 | npm i --legacy-peer-deps
76 | ./lint.sh
77 | npm run bats tests
78 | ./test.sh
79 | ```
80 |
81 | ###
--------------------------------------------------------------------------------
/acme-cron-job.yml:
--------------------------------------------------------------------------------
1 | apiVersion: batch/v1beta1
2 | kind: CronJob
3 | metadata:
4 | name: acme-cron-job
5 | spec:
6 | schedule: 30 03 01 */3 *
7 | jobTemplate:
8 | spec:
9 | template:
10 | spec:
11 | containers:
12 | - name: acme-init
13 | image: neilpang/acme.sh
14 | env:
15 | # - name: DOMAIN
16 | # value: doh.seby.io
17 | - name: CF_Email
18 | valueFrom:
19 | secretKeyRef:
20 | name: cloudflare
21 | key: username
22 | - name: CF_Key
23 | valueFrom:
24 | secretKeyRef:
25 | name: cloudflare
26 | key: password
27 | command:
28 | - acme.sh
29 | - --issue
30 | - --staging # remember to remove in production
31 | - --dns
32 | - dns_cf
33 | - --dnssleep
34 | - "60"
35 | - -d
36 | # - $(DOMAIN)
37 | - doh.seby.io
38 | # - -d
39 | # - www.$(DOMAIN)
40 | - --fullchain-file
41 | - /opt/ssl/fullchain.pem
42 | - --key-file
43 | - /opt/ssl/key.pem
44 | - --ca-file
45 | - /opt/ssl/ca.pem
46 | - --cert-file
47 | - /opt/ssl/cert.pem
48 | - --reloadcmd
49 | - 'cat /opt/ssl/key.pem > cat /opt/ssl/fullchain.pem > /opt/ssl/fullchain-key.pem'
50 | volumeMounts:
51 | - name: ssl
52 | mountPath: /opt/ssl
53 | restartPolicy: Never # OnFailure
54 | volumes:
55 | - name: ssl
56 | hostPath:
57 | path: /data/ssl
58 | type: DirectoryOrCreate
59 |
--------------------------------------------------------------------------------
/acme-init-job.yml:
--------------------------------------------------------------------------------
1 | apiVersion: batch/v1
2 | kind: Job
3 | metadata:
4 | name: acme-init
5 | spec:
6 | template:
7 | metadata:
8 | name: acme-init
9 | spec:
10 | # schedule: 30 03 01 */3 *
11 | containers:
12 | - name: acme-init
13 | image: neilpang/acme.sh
14 | env:
15 | # - name: DOMAIN
16 | # value: doh.seby.io
17 | - name: CF_Email
18 | valueFrom:
19 | secretKeyRef:
20 | name: cloudflare
21 | key: username
22 | - name: CF_Key
23 | valueFrom:
24 | secretKeyRef:
25 | name: cloudflare
26 | key: password
27 | command:
28 | - acme.sh
29 | - --issue
30 | - --staging # remember to remove in production
31 | - --dns
32 | - dns_cf
33 | - --dnssleep
34 | - "60"
35 | - -d
36 | # - $(DOMAIN)
37 | - doh.seby.io
38 | # - -d
39 | # - www.$(DOMAIN)
40 | - --fullchain-file
41 | - /opt/ssl/fullchain.pem
42 | - --key-file
43 | - /opt/ssl/key.pem
44 | - --ca-file
45 | - /opt/ssl/ca.pem
46 | - --cert-file
47 | - /opt/ssl/cert.pem
48 | - --reloadcmd
49 | - 'cat /opt/ssl/key.pem > cat /opt/ssl/fullchain.pem > /opt/ssl/fullchain-key.pem'
50 | volumeMounts:
51 | - name: ssl
52 | mountPath: /opt/ssl
53 | restartPolicy: Never # OnFailure
54 | volumes:
55 | - name: ssl
56 | hostPath:
57 | path: /data/ssl
58 | type: DirectoryOrCreate
59 |
--------------------------------------------------------------------------------
/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | set +x
4 |
5 | docker compose build
6 | docker compose push
7 |
--------------------------------------------------------------------------------
/daemon.json:
--------------------------------------------------------------------------------
1 | {
2 | "userns-remap": "dockerremap",
3 | "experimental": false,
4 | "live-restore": false,
5 | "ipv6": false,
6 | "icc": false,
7 | "no-new-privileges": true,
8 | "storage-driver": "overlay2"
9 | }
10 |
--------------------------------------------------------------------------------
/deploy.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | set +x
4 |
5 | # docker stack deploy dns --compose-file docker-stack.yml
6 | docker compose pull
7 | docker compose up -d --remove-orphans
8 |
--------------------------------------------------------------------------------
/dns-infra.afdesign:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/publicarray/dns-resolver-infra/c0f32be0b0956088d355361a204df5b1fce990ee/dns-infra.afdesign
--------------------------------------------------------------------------------
/dns-infra.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/publicarray/dns-resolver-infra/c0f32be0b0956088d355361a204df5b1fce990ee/dns-infra.png
--------------------------------------------------------------------------------
/dnscrypt-server/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM rustlang/rust:nightly AS encrypted-dns-build
2 | LABEL org.opencontainers.image.source https://github.com/publicarray/dns-resolver-infra
3 | ENV REVISION 2
4 | ENV VERSION 0.9.13
5 | SHELL ["/bin/sh", "-x", "-c"]
6 | ENV RUSTFLAGS "-C link-arg=-s"
7 | RUN cargo install encrypted-dns --version $VERSION && \
8 | strip --strip-all /usr/local/cargo/bin/encrypted-dns
9 |
10 | #------------------------------------------------------------------------------#
11 | FROM ubuntu:22.04
12 | LABEL org.opencontainers.image.source https://github.com/publicarray/dns-resolver-infra
13 | LABEL maintainer="publicarray"
14 | LABEL name="dnscrypt-server"
15 | LABEL description="https://github.com/jedisct1/encrypted-dns-server - Basically https://github.com/DNSCrypt/dnscrypt-server-docker minus unbound"
16 | SHELL ["/bin/sh", "-x", "-c"]
17 | WORKDIR /tmp
18 | ENV RUN_DEPS bash dnsutils coreutils findutils grep ca-certificates libevent-2.1 libssl3 expat
19 | RUN apt-get update && \
20 | apt-get install -qy --no-install-recommends $RUN_DEPS && \
21 | rm -fr /tmp/* /var/tmp/* /var/cache/apt/* /var/lib/apt/lists/* /var/log/apt/* /var/log/*.log
22 | RUN update-ca-certificates 2> /dev/null || true
23 |
24 | COPY --from=encrypted-dns-build /usr/local/cargo/bin/encrypted-dns /opt/encrypted-dns/sbin/encrypted-dns
25 | ENV PATH="/opt/encrypted-dns/sbin/:${PATH}"
26 |
27 | RUN mkdir -p /opt/encrypted-dns/empty && \
28 | groupadd _encrypted-dns && \
29 | useradd -g _encrypted-dns -s /etc -d /opt/encrypted-dns/empty _encrypted-dns && \
30 | mkdir -m 700 -p /opt/encrypted-dns/etc/keys && \
31 | mkdir -m 700 -p /opt/encrypted-dns/etc/lists && \
32 | chown _encrypted-dns:_encrypted-dns /opt/encrypted-dns/etc/keys && \
33 | mkdir -m 700 -p /opt/dnscrypt-wrapper/etc/keys && \
34 | mkdir -m 700 -p /opt/dnscrypt-wrapper/etc/lists && \
35 | chown _encrypted-dns:_encrypted-dns /opt/dnscrypt-wrapper/etc/keys
36 |
37 | COPY encrypted-dns.toml.in /opt/encrypted-dns/etc/
38 | COPY undelegated.txt /opt/encrypted-dns/etc/
39 | COPY entrypoint.sh /
40 |
41 | VOLUME ["/opt/encrypted-dns/etc/keys"]
42 |
43 | EXPOSE 443/udp 443/tcp 9100/tcp
44 |
45 | RUN /opt/encrypted-dns/sbin/encrypted-dns --version
46 |
47 | CMD ["/entrypoint.sh", "start"]
48 |
49 | ENTRYPOINT ["/entrypoint.sh"]
50 |
--------------------------------------------------------------------------------
/dnscrypt-server/Readme.md:
--------------------------------------------------------------------------------
1 | # Troubleshooting
2 |
3 | ```
4 | docker run --rm -it -v dns_dnscrypt:/opt/dnscrypt -v dns_dnscrypt-server:/opt/encrypted-dns publicarray/dnscrypt-server shell
5 | ```
6 |
--------------------------------------------------------------------------------
/dnscrypt-server/encrypted-dns.toml.in:
--------------------------------------------------------------------------------
1 | ####################################################
2 | # #
3 | # Encrypted DNS Server configuration #
4 | # #
5 | ####################################################
6 |
7 |
8 |
9 | ##################################
10 | # Global settings #
11 | ##################################
12 |
13 |
14 | ## IP addresses and ports to listen to, as well as their external IP
15 | ## If there is no NAT involved, `local` and `external` can be the same.
16 | ## As many addresses as needed can be configured here, IPv4 and/or IPv6.
17 | ## You should at least change the `external` IP address.
18 |
19 | ### Example with both IPv4 and IPv6 addresses:
20 | # listen_addrs = [
21 | # { local = "0.0.0.0:443", external = "198.51.100.1:443" },
22 | # { local = "[::]:443", external = "[2001:db8::1]:443" }
23 | # ]
24 |
25 | listen_addrs = [
26 | { local = "0.0.0.0:443", external = "@EXTERNAL_IPV4@" }
27 | ]
28 |
29 |
30 | ## Upstream DNS server and port
31 |
32 | upstream_addr = "@UPSTREAM_IPV4@:53"
33 |
34 |
35 | ## File name to save the state to
36 |
37 | state_file = "encrypted-dns.state"
38 |
39 |
40 | ## UDP timeout in seconds
41 |
42 | udp_timeout = 10
43 |
44 |
45 | ## TCP timeout in seconds
46 |
47 | tcp_timeout = 10
48 |
49 |
50 | ## Maximum active UDP sockets
51 |
52 | udp_max_active_connections = 1000
53 |
54 |
55 | ## Maximum active TCP connections
56 |
57 | tcp_max_active_connections = 100
58 |
59 |
60 | ## Optional IP address to connect to upstream servers from.
61 | ## Leave commented/undefined to automatically select it.
62 |
63 | # external_addr = "0.0.0.0"
64 |
65 |
66 | ## Built-in DNS cache capacity
67 |
68 | cache_capacity = 150000
69 |
70 |
71 | ## DNS cache: minimum TTL
72 |
73 | cache_ttl_min = 3600
74 |
75 |
76 | ## DNS cache: max TTL
77 |
78 | cache_ttl_max = 86400
79 |
80 |
81 | ## DNS cache: error TTL
82 |
83 | cache_ttl_error = 600
84 |
85 |
86 | ## DNS cache: to avoid bursts of traffic for popular queries when an
87 | ## RRSET expires, hold a TTL received from an upstream server for
88 | ## `client_ttl_holdon` seconds before decreasing it in client responses.
89 |
90 | client_ttl_holdon = 60
91 |
92 |
93 | ## Run as a background process
94 |
95 | daemonize = false
96 |
97 |
98 | ## Log file, when running as a background process
99 |
100 | # log_file = "/tmp/encrypted-dns.log"
101 |
102 |
103 | ## PID file
104 |
105 | # pid_file = "/tmp/encrypted-dns.pid"
106 |
107 |
108 | ## User name to drop privileges to, when started as root.
109 |
110 | user = "_encrypted-dns"
111 |
112 |
113 | ## Group name to drop privileges to, when started as root.
114 |
115 | group = "_encrypted-dns"
116 |
117 |
118 | ## Path to chroot() to, when started as root.
119 | ## The path to the state file is relative to the chroot base.
120 |
121 | # chroot = "/var/empty"
122 |
123 |
124 | ## Queries sent to that name will return the client IP address.
125 | ## This can be very useful for debugging, or to check that relaying works.
126 |
127 | my_ip = "my.ip"
128 |
129 |
130 | ####################################
131 | # DNSCrypt settings #
132 | ####################################
133 |
134 | [dnscrypt]
135 |
136 | ## Provider name (with or without the `2.dnscrypt-cert.` prefix)
137 |
138 | provider_name = "@PROVIDER_NAME@"
139 |
140 |
141 | ## Does the server support DNSSEC?
142 |
143 | dnssec = true
144 |
145 |
146 | ## Does the server always returns correct answers (no filtering, including ad blocking)?
147 |
148 | no_filters = true
149 |
150 |
151 | ## Set to `true` if the server doesn't keep any information that can be used to identify users
152 |
153 | no_logs = true
154 |
155 |
156 | ## Key cache capacity, per certificate
157 |
158 | key_cache_capacity = 10000
159 |
160 |
161 |
162 | ###############################
163 | # TLS settings #
164 | ###############################
165 |
166 | [tls]
167 |
168 | ## Where to proxy TLS connections to (e.g. DoH server)
169 |
170 | @TLS_PROXY_CONFIGURATION@
171 |
172 |
173 |
174 | #######################################
175 | # Server-side filtering #
176 | #######################################
177 |
178 | [filtering]
179 |
180 | ## List of domains to block, one per line
181 |
182 | # domain_blacklist = "/etc/domain_blacklist.txt"
183 |
184 |
185 | ## List of undelegated TLDs
186 | ## This is the list of nonexistent TLDs that queries are frequently observed for,
187 | ## but will never resolve to anything. The server will immediately return a
188 | ## synthesized NXDOMAIN response instead of hitting root servers.
189 |
190 | # undelegated_list = "/etc/undelegated.txt"
191 |
192 |
193 | ## Ignore A and AAAA queries for unqualified host names.
194 |
195 | # ignore_unqualified_hostnames = true
196 |
197 |
198 |
199 | #########################
200 | # Metrics #
201 | #########################
202 |
203 | # [metrics]
204 |
205 | # type = "prometheus"
206 | # listen_addr = "0.0.0.0:9100"
207 | # path = "/metrics"
208 |
209 |
210 |
211 | ################################
212 | # Anonymized DNS #
213 | ################################
214 |
215 | [anonymized_dns]
216 |
217 | # Enable relaying support for Anonymized DNS
218 |
219 | enabled = @ANONDNS_ENABLED@
220 |
221 |
222 | # Allowed upstream ports
223 | # This is a list of commonly used ports for encrypted DNS services
224 |
225 | allowed_ports = [ 443, 553, 853, 1443, 2053, 4343, 4434, 4443, 5353, 5443, 8443, 15353 ]
226 |
227 |
228 | # Allow all ports >= 1024 in addition to the list above
229 |
230 | allow_non_reserved_ports = false
231 |
232 |
233 | # Blacklisted upstream IP addresses
234 |
235 | blacklisted_ips = [ @ANONDNS_BLACKLISTED_IPS@ ]
236 |
237 |
238 |
239 |
240 | ################################
241 | # Access control #
242 | ################################
243 |
244 | [access_control]
245 |
246 | # Enable access control
247 |
248 | enabled = false
249 |
250 | # Only allow access to client queries including one of these random tokens
251 | # Tokens can be configured in the `query_meta` section of `dnscrypt-proxy` as
252 | # `query_meta = ["token:..."]` -- Replace ... with the token to use by the client.
253 | # Example: `query_meta = ["token:Y2oHkDJNHz"]`
254 |
255 | tokens = ["Y2oHkDJNHz", "G5zY3J5cHQtY", "C5zZWN1cmUuZG5z"]
256 |
--------------------------------------------------------------------------------
/dnscrypt-server/entrypoint.sh:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env bash
2 |
3 | set -e
4 |
5 | action="$1"
6 |
7 | LEGACY_KEYS_DIR="/opt/dnscrypt-wrapper/etc/keys"
8 | LEGACY_LISTS_DIR="/opt/dnscrypt-wrapper/etc/lists"
9 | LEGACY_STATE_DIR="${LEGACY_KEYS_DIR}/state"
10 | KEYS_DIR="/opt/encrypted-dns/etc/keys"
11 | STATE_DIR="${KEYS_DIR}/state"
12 | LISTS_DIR="/opt/encrypted-dns/etc/lists"
13 | CONF_DIR="/opt/encrypted-dns/etc"
14 | CONFIG_FILE="${CONF_DIR}/encrypted-dns.toml"
15 | CONFIG_FILE_TEMPLATE="${CONF_DIR}/encrypted-dns.toml.in"
16 |
17 | getServiceIP() {
18 | for arg; do
19 | dig "$arg" +short
20 | done
21 | }
22 | waitOrFail() {
23 | maxTries=24
24 | i=0
25 | while [ $i -lt $maxTries ]; do
26 | outStr="$($@)"
27 | if [ $? -eq 0 ]; then
28 | echo "$outStr"
29 | return
30 | fi
31 | i=$((i + 1))
32 | echo "==> waiting for a dependent service $i/$maxTries" >&2
33 | sleep 5
34 | done
35 | echo "Too many failed attempts" >&2
36 | exit 1
37 | }
38 |
39 | init() {
40 | if [ "$(is_initialized)" = yes ]; then
41 | start
42 | exit $?
43 | fi
44 |
45 | anondns_enabled="false"
46 | anondns_blacklisted_ips=""
47 | upstream_address="127.0.0.1"
48 | metrics_address="127.0.0.1:9100"
49 | tls_proxy_upstream_port="443"
50 |
51 | while getopts "h?N:E:d:T:P:AM:" opt; do
52 | case "$opt" in
53 | h | \?) usage ;;
54 | N) provider_name=$(echo "$OPTARG" | sed -e 's/^[ \t]*//' | tr A-Z a-z) ;;
55 | E) ext_address=$(echo "$OPTARG" | sed -e 's/^[ \t]*//' | tr A-Z a-z) ;;
56 | d) upstream_address=$(waitOrFail getServiceIP "$(echo "$OPTARG" | sed -e 's/^[ \t]*//' | tr A-Z a-z)") ;;
57 | T) tls_proxy_upstream_address=$(waitOrFail getServiceIP "$(echo "$OPTARG" | sed -e 's/^[ \t]*//' | tr A-Z a-z)") ;;
58 | P) tls_proxy_upstream_port=$(echo "$OPTARG" | sed -e 's/^[ \t]*//' | tr A-Z a-z) ;;
59 | A) anondns_enabled="true" ;;
60 | M) metrics_address=$(echo "$OPTARG" | sed -e 's/^[ \t]*//' | tr A-Z a-z) ;;
61 | esac
62 | done
63 | [ -z "$provider_name" ] && usage
64 | case "$provider_name" in
65 | .*) usage ;;
66 | 2.dnscrypt-cert.*) ;;
67 | *) provider_name="2.dnscrypt-cert.${provider_name}" ;;
68 | esac
69 |
70 | [ -z "$ext_address" ] && usage
71 | case "$ext_address" in
72 | .*) usage ;;
73 | 0.*)
74 | echo "Do not use 0.0.0.0, use an actual external IP address" >&2
75 | exit 1
76 | ;;
77 | esac
78 |
79 | tls_proxy_configuration=""
80 | if [ -n "$tls_proxy_upstream_address" ]; then
81 | tls_proxy_configuration="upstream_addr = \"${tls_proxy_upstream_address}:${tls_proxy_upstream_port}\""
82 | fi
83 |
84 | domain_blacklist_file="${LISTS_DIR}/blacklist.txt"
85 | domain_blacklist_configuration=""
86 | if [ -s "$domain_blacklist_file" ]; then
87 | chown _encrypted-dns:_encrypted_dns "$domain_blacklist_file"
88 | domain_blacklist_configuration="domain_blacklist = \"${domain_blacklist_file}\""
89 | fi
90 |
91 | echo "Provider name: [$provider_name]"
92 |
93 | echo "$provider_name" >"${KEYS_DIR}/provider_name"
94 | chmod 644 "${KEYS_DIR}/provider_name"
95 |
96 | sed \
97 | -e "s#@PROVIDER_NAME@#${provider_name}#" \
98 | -e "s#@EXTERNAL_IPV4@#${ext_address}#" \
99 | -e "s#@UPSTREAM_IPV4@#${upstream_address}#" \
100 | -e "s#@TLS_PROXY_CONFIGURATION@#${tls_proxy_configuration}#" \
101 | -e "s#@DOMAIN_BLACKLIST_CONFIGURATION@#${domain_blacklist_configuration}#" \
102 | -e "s#@ANONDNS_ENABLED@#${anondns_enabled}#" \
103 | -e "s#@ANONDNS_BLACKLISTED_IPS@#${anondns_blacklisted_ips}#" \
104 | -e "s#@METRICS_ADDRESS@#${metrics_address}#" \
105 | "$CONFIG_FILE_TEMPLATE" >"$CONFIG_FILE"
106 |
107 | mkdir -p -m 700 "${STATE_DIR}"
108 | chown _encrypted-dns:_encrypted-dns "${STATE_DIR}"
109 |
110 | if [ -f "${KEYS_DIR}/secret.key" ]; then
111 | echo "Importing the previous secret key [${KEYS_DIR}/secret.key]"
112 | /opt/encrypted-dns/sbin/encrypted-dns \
113 | --config "$CONFIG_FILE" \
114 | --import-from-dnscrypt-wrapper "${KEYS_DIR}/secret.key" \
115 | --dry-run >/dev/null || exit 1
116 | mv -f "${KEYS_DIR}/secret.key" "${KEYS_DIR}/secret.key.migrated"
117 | fi
118 |
119 | /opt/encrypted-dns/sbin/encrypted-dns \
120 | --config "$CONFIG_FILE" --dry-run |
121 | tee "${KEYS_DIR}/provider-info.txt"
122 |
123 | echo
124 | echo -----------------------------------------------------------------------
125 | echo
126 | echo "Congratulations! The container has been properly initialized."
127 | echo "Take a look up above at the way dnscrypt-proxy has to be configured in order"
128 | echo "to connect to your resolver. Then, start the container with the default command."
129 | }
130 |
131 | provider_info() {
132 | ensure_initialized
133 | echo
134 | cat "${KEYS_DIR}/provider-info.txt"
135 | echo
136 | }
137 |
138 | legacy_compat() {
139 | if [ -f "${KEYS_DIR}/provider-info.txt" ] && [ -f "${KEYS_DIR}/provider_name" ]; then
140 | return 0
141 | fi
142 | if [ -f "${LEGACY_KEYS_DIR}/provider-info.txt" ] && [ -f "${LEGACY_KEYS_DIR}/provider_name" ]; then
143 | echo "Using [${LEGACY_KEYS_DIR}] for keys" >&2
144 | mkdir -p "${KEYS_DIR}"
145 | mv -f "${KEYS_DIR}/provider-info.txt" "${KEYS_DIR}/provider-info.txt.migrated" 2>/dev/null || :
146 | ln -s "${LEGACY_KEYS_DIR}/provider-info.txt" "${KEYS_DIR}/provider-info.txt" 2>/dev/null || :
147 | mv -f "${KEYS_DIR}/provider_name" "${KEYS_DIR}/provider_name.migrated" 2>/dev/null || :
148 | ln -s "${LEGACY_KEYS_DIR}/provider_name" "${KEYS_DIR}/provider_name" 2>/dev/null || :
149 | mv -f "${KEYS_DIR}/secret.key" "${KEYS_DIR}/secret.key.migrated" 2>/dev/null || :
150 | ln -s "${LEGACY_KEYS_DIR}/secret.key" "${KEYS_DIR}/secret.key" 2>/dev/null || :
151 | mkdir -p -m 700 "${LEGACY_STATE_DIR}"
152 | chown _encrypted-dns:_encrypted-dns "${LEGACY_STATE_DIR}"
153 | mv -f "$STATE_DIR" "${STATE_DIR}.migrated" 2>/dev/null || :
154 | ln -s "$LEGACY_STATE_DIR" "${STATE_DIR}" 2>/dev/null || :
155 | fi
156 | if [ -f "${LEGACY_LISTS_DIR}/blacklist.txt" ]; then
157 | echo "Using [${LEGACY_LISTS_DIR}] for lists" >&2
158 | mkdir -p "${LISTS_DIR}"
159 | mv -f "${LISTS_DIR}/blacklist.txt" "${LISTS_DIR}/blacklist.txt.migrated" 2>/dev/null || :
160 | ln -s "${LEGACY_LISTS_DIR}/blacklist.txt" "${LISTS_DIR}/blacklist.txt" 2>/dev/null || :
161 | chown _encrypted-dns:_encrypted-dns "${LEGACY_LISTS_DIR}/blacklist.txt"
162 | fi
163 | }
164 |
165 | is_initialized() {
166 | if [ -f "$CONFIG_FILE" ] && [ -f "${STATE_DIR}/encrypted-dns.state" ] && [ -f "${KEYS_DIR}/provider-info.txt" ] && [ -f "${KEYS_DIR}/provider_name" ]; then
167 | echo yes
168 | else
169 | legacy_compat
170 | if [ -f "$CONFIG_FILE" ] && [ -f "${STATE_DIR}/encrypted-dns.state" ] && [ -f "${KEYS_DIR}/provider-info.txt" ] && [ -f "${KEYS_DIR}/provider_name" ]; then
171 | echo yes
172 | else
173 | echo no
174 | fi
175 | fi
176 | }
177 |
178 | ensure_initialized() {
179 | if [ "$(is_initialized)" = no ]; then
180 | if [ -d "$LEGACY_KEYS_DIR" ]; then
181 | echo "Please provide an initial configuration (init -N -E )" >&2
182 | fi
183 | exit 1
184 | fi
185 | }
186 |
187 | start() {
188 | ensure_initialized
189 | if [ -f "${KEYS_DIR}/secret.key" ]; then
190 | echo "Importing the previous secret key [${KEYS_DIR}/secret.key]"
191 | /opt/encrypted-dns/sbin/encrypted-dns \
192 | --config "$CONFIG_FILE" \
193 | --import-from-dnscrypt-wrapper "${KEYS_DIR}/secret.key" \
194 | --dry-run >/dev/null || exit 1
195 | mv -f "${KEYS_DIR}/secret.key" "${KEYS_DIR}/secret.key.migrated"
196 | fi
197 | /opt/encrypted-dns/sbin/encrypted-dns \
198 | --config "$CONFIG_FILE" --dry-run |
199 | tee "${KEYS_DIR}/provider-info.txt"
200 |
201 | if [ ! -f "${KEYS_DIR}/provider_name" ]; then
202 | exit 1
203 | fi
204 | exec /opt/encrypted-dns/sbin/encrypted-dns --config "$CONFIG_FILE"
205 | }
206 |
207 | shell() {
208 | exec /bin/bash
209 | }
210 |
211 | bin() {
212 | shift
213 | exec /opt/encrypted-dns/sbin/encrypted-dns "$@"
214 | }
215 |
216 | usage() {
217 | cat < -E :
222 | initialize the container for a server accessible at ip on port
223 | , for a provider named . This is required only once.
224 |
225 | If TLS connections to the same port have to be redirected to a HTTPS server
226 | (e.g. for DoH), add -T :
227 |
228 | To enable Anonymized DNS relaying, add -A.
229 |
230 | To use dns service discovery use -d of a resolver on port 53
231 |
232 | * start (default command): start the resolver and the dnscrypt server proxy.
233 | Ports 443/udp and 443/tcp have to be publicly exposed.
234 |
235 | * provider-info: prints the provider name and provider public key.
236 |
237 | * shell: run a shell.
238 |
239 | * bin: run the binary with custom arguments
240 |
241 | This container has a single volume that you might want to securely keep a
242 | backup of: /opt/encrypted-dns/etc/keys
243 | EOT
244 | exit 1
245 | }
246 |
247 | case "$action" in
248 | start) start ;;
249 | init)
250 | shift
251 | init "$@"
252 | ;;
253 | provider-info) provider_info ;;
254 | shell) shell ;;
255 | bin) bin "$@";;
256 | *) usage ;;
257 | esac
258 |
--------------------------------------------------------------------------------
/dnscrypt-server/undelegated.txt:
--------------------------------------------------------------------------------
1 | 0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa
2 | 0.in-addr.arpa
3 | 1
4 | 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa
5 | 10.in-addr.arpa
6 | 100.100.in-addr.arpa
7 | 100.51.198.in-addr.arpa
8 | 101.100.in-addr.arpa
9 | 102.100.in-addr.arpa
10 | 103.100.in-addr.arpa
11 | 104.100.in-addr.arpa
12 | 105.100.in-addr.arpa
13 | 106.100.in-addr.arpa
14 | 107.100.in-addr.arpa
15 | 108.100.in-addr.arpa
16 | 109.100.in-addr.arpa
17 | 110.100.in-addr.arpa
18 | 111.100.in-addr.arpa
19 | 112.100.in-addr.arpa
20 | 113.0.203.in-addr.arpa
21 | 113.100.in-addr.arpa
22 | 114.100.in-addr.arpa
23 | 115.100.in-addr.arpa
24 | 116.100.in-addr.arpa
25 | 117.100.in-addr.arpa
26 | 118.100.in-addr.arpa
27 | 119.100.in-addr.arpa
28 | 120.100.in-addr.arpa
29 | 121.100.in-addr.arpa
30 | 122.100.in-addr.arpa
31 | 123.100.in-addr.arpa
32 | 124.100.in-addr.arpa
33 | 125.100.in-addr.arpa
34 | 126.100.in-addr.arpa
35 | 127.100.in-addr.arpa
36 | 127.in-addr.arpa
37 | 16.172.in-addr.arpa
38 | 168.192.in-addr.arpa
39 | 17.172.in-addr.arpa
40 | 18.172.in-addr.arpa
41 | 19.172.in-addr.arpa
42 | 2.0.192.in-addr.arpa
43 | 20.172.in-addr.arpa
44 | 21.172.in-addr.arpa
45 | 22.172.in-addr.arpa
46 | 23.172.in-addr.arpa
47 | 24.172.in-addr.arpa
48 | 25.172.in-addr.arpa
49 | 254.169.in-addr.arpa
50 | 255.255.255.255.in-addr.arpa
51 | 26.172.in-addr.arpa
52 | 27.172.in-addr.arpa
53 | 28.172.in-addr.arpa
54 | 29.172.in-addr.arpa
55 | 30.172.in-addr.arpa
56 | 31.172.in-addr.arpa
57 | 64.100.in-addr.arpa
58 | 65.100.in-addr.arpa
59 | 66.100.in-addr.arpa
60 | 67.100.in-addr.arpa
61 | 68.100.in-addr.arpa
62 | 69.100.in-addr.arpa
63 | 70.100.in-addr.arpa
64 | 71.100.in-addr.arpa
65 | 72.100.in-addr.arpa
66 | 73.100.in-addr.arpa
67 | 74.100.in-addr.arpa
68 | 75.100.in-addr.arpa
69 | 76.100.in-addr.arpa
70 | 77.100.in-addr.arpa
71 | 78.100.in-addr.arpa
72 | 79.100.in-addr.arpa
73 | 8.b.d.0.1.0.0.2.ip6.arpa
74 | 8.e.f.ip6.arpa
75 | 80.100.in-addr.arpa
76 | 81.100.in-addr.arpa
77 | 82.100.in-addr.arpa
78 | 83.100.in-addr.arpa
79 | 84.100.in-addr.arpa
80 | 85.100.in-addr.arpa
81 | 86.100.in-addr.arpa
82 | 87.100.in-addr.arpa
83 | 88.100.in-addr.arpa
84 | 89.100.in-addr.arpa
85 | 9.e.f.ip6.arpa
86 | 90.100.in-addr.arpa
87 | 91.100.in-addr.arpa
88 | 92.100.in-addr.arpa
89 | 93.100.in-addr.arpa
90 | 94.100.in-addr.arpa
91 | 95.100.in-addr.arpa
92 | 96.100.in-addr.arpa
93 | 97.100.in-addr.arpa
94 | 98.100.in-addr.arpa
95 | 99.100.in-addr.arpa
96 | a.e.f.ip6.arpa
97 | airdream
98 | api
99 | b.e.f.ip6.arpa
100 | bbrouter
101 | belkin
102 | blinkap
103 | corp
104 | d.f.ip6.arpa
105 | davolink
106 | dearmyrouter
107 | dhcp
108 | dlink
109 | domain
110 | envoy
111 | example
112 | f.f.ip6.arpa
113 | grp
114 | gw==
115 | home
116 | hub
117 | internal
118 | intra
119 | intranet
120 | invalid
121 | ksyun
122 | lan
123 | loc
124 | local
125 | localdomain
126 | localhost
127 | localnet
128 | modem
129 | mynet
130 | myrouter
131 | novalocal
132 | onion
133 | openstacklocal
134 | priv
135 | private
136 | prv
137 | router
138 | telus
139 | test
140 | totolink
141 | wlan_ap
142 | workgroup
143 | zghjccbob3n0
144 |
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3.4'
2 | volumes:
3 | dnscrypt:
4 | dnscrypt-server:
5 | ssl:
6 | nsd:
7 | acme-sh:
8 | acme-acc:
9 | services:
10 | acme:
11 | image: docker.io/neilpang/acme.sh
12 | container_name: acme
13 | command: >
14 | /bin/sh -c "echo \"#!/bin/sh
15 |
16 | set -e
17 |
18 | acme.sh --set-default-ca --server letsencrypt
19 |
20 | if [ -n ${HEALTHCHECK} ]; then
21 |
22 | acme.sh --issue --dns dns_cf --dnssleep 60 --domain '${DOMAIN}' --keylength ec-384 --fullchain-file /opt/ssl/fullchain-ecc.pem --key-file /opt/ssl/key-ecc.pem --ca-file /opt/ssl/ca-ecc.pem --cert-file /opt/ssl/cert-ecc.pem --pre-hook 'curl -fsS -m 10 --retry 5 -o /dev/null https://hc-ping.com/${HEALTHCHECK}'
23 |
24 | else
25 |
26 | acme.sh --issue --dns dns_cf --dnssleep 60 --domain '${DOMAIN}' --keylength ec-384 --fullchain-file /opt/ssl/fullchain-ecc.pem --key-file /opt/ssl/key-ecc.pem --ca-file /opt/ssl/ca-ecc.pem --cert-file /opt/ssl/cert-ecc.pem
27 |
28 | fi
29 |
30 | acme.sh --deploy -d '${DOMAIN}' --ecc --deploy-hook docker
31 |
32 | \" > start.sh
33 | && chmod +x start.sh
34 | && ./start.sh"
35 | logging:
36 | driver: "json-file"
37 | options:
38 | max-size: "200k"
39 | max-file: "10"
40 | environment:
41 | - HEALTHCHECK=${HEALTHCHECK}
42 | - CF_Email=${CF_EMAIL}
43 | - CF_Key=${CF_KEY}
44 | - CF_Token=${CF_TOKEN}
45 | - CF_Account_ID=${CF_ACCOUNT_ID}
46 | - CF_Zone_ID=${CF_ZONE_ID}
47 | - DOMAIN=${DOMAIN}
48 | - DEPLOY_DOCKER_CONTAINER_LABEL=sh.acme.autoload.domain=${DOMAIN}
49 | - DEPLOY_DOCKER_CONTAINER_KEY_FILE=/opt/ssl/key-ecc.pem
50 | - DEPLOY_DOCKER_CONTAINER_CERT_FILE="/opt/ssl/cert-ecc.pem"
51 | - DEPLOY_DOCKER_CONTAINER_CA_FILE="/opt/ssl/ca-ecc.pem"
52 | - DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE="/opt/ssl/fullchain-ecc.pem"
53 | - DEPLOY_DOCKER_CONTAINER_RELOAD_CMD="cat /opt/ssl/key-ecc.pem > cat /opt/ssl/fullchain-ecc.pem > /opt/ssl/fullchain-key.pem.ecdsa; sv restart haproxy"
54 | volumes:
55 | - ssl:/opt/ssl
56 | - ./run/acmeout:/acme.sh
57 | - /var/run/docker.sock:/var/run/docker.sock
58 |
59 | acme-daemon:
60 | container_name: acme-daemon
61 | restart: on-failure:2
62 | image: docker.io/neilpang/acme.sh
63 | command: daemon
64 | logging:
65 | driver: "json-file"
66 | options:
67 | max-size: "200k"
68 | max-file: "10"
69 | volumes:
70 | - ssl:/opt/ssl
71 | - ./run/acmeout:/acme.sh
72 | - /var/run/docker.sock:/var/run/docker.sock
73 | environment:
74 | - DOMAIN=${DOMAIN}
75 | - HEALTHCHECK=${HEALTHCHECK}
76 | - DEPLOY_DOCKER_CONTAINER_LABEL=sh.acme.autoload.domain=${DOMAIN}
77 | - DEPLOY_DOCKER_CONTAINER_KEY_FILE=/opt/ssl/key-ecc.pem
78 | - DEPLOY_DOCKER_CONTAINER_CERT_FILE="/opt/ssl/cert-ecc.pem"
79 | - DEPLOY_DOCKER_CONTAINER_CA_FILE="/opt/ssl/ca-ecc.pem"
80 | - DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE="/opt/ssl/fullchain-ecc.pem"
81 | - DEPLOY_DOCKER_CONTAINER_RELOAD_CMD="cat /opt/ssl/key-ecc.pem > cat /opt/ssl/fullchain-ecc.pem > /opt/ssl/fullchain-key.pem.ecdsa; sv restart haproxy"
82 |
83 | nsd:
84 | container_name: nsd
85 | restart: on-failure:5
86 | build: nsd
87 | image: ghcr.io/publicarray/dns-resolver-infra/nsd
88 | logging:
89 | driver: "json-file"
90 | options:
91 | max-size: "200k"
92 | max-file: "10"
93 | volumes:
94 | - nsd:/etc/nsd/run
95 |
96 | unbound:
97 | container_name: unbound
98 | restart: on-failure:5
99 | depends_on:
100 | - nsd
101 | build: unbound
102 | image: ghcr.io/publicarray/dns-resolver-infra/unbound
103 | command: -d nsd
104 | logging:
105 | driver: "json-file"
106 | options:
107 | max-size: "200k"
108 | max-file: "10"
109 | # ports:
110 | # - target: 4949
111 | # published: 4949
112 | # protocol: tcp
113 | # mode: ingress
114 |
115 | m13253-doh:
116 | container_name: doh
117 | restart: on-failure:5
118 | depends_on:
119 | - unbound
120 | build: m13253-doh
121 | image: ghcr.io/publicarray/dns-resolver-infra/m13253-doh
122 | command: -d unbound
123 | logging:
124 | driver: "json-file"
125 | options:
126 | max-size: "200k"
127 | max-file: "10"
128 |
129 | # doh-proxy:
130 | # container_name: doh-proxy
131 | # restart: on-failure:5
132 | # depends_on:
133 | # - unbound
134 | # build: doh-proxy
135 | # image: ghcr.io/publicarray/dns-resolver-infra/doh-proxy
136 | # command: -d
137 |
138 | haproxy:
139 | container_name: haproxy
140 | restart: on-failure:5
141 | depends_on:
142 | - acme
143 | - m13253-doh
144 | - unbound
145 | labels:
146 | - sh.acme.autoload.domain=${DOMAIN}
147 | build: haproxy
148 | image: ghcr.io/publicarray/dns-resolver-infra/haproxy
149 | command: -d -r
150 | logging:
151 | driver: "json-file"
152 | options:
153 | max-size: "200k"
154 | max-file: "10"
155 | ports:
156 | - "443:443/tcp"
157 | - "853:853/tcp"
158 | - "443:443/udp"
159 | - "853:853/udp"
160 | volumes:
161 | - ssl:/opt/ssl
162 | environment:
163 | - DOMAIN=${DOMAIN}
164 |
165 | # dnscrypt-server:
166 | # container_name: dnscrypt-server
167 | # restart: on-failure:5
168 | # depends_on:
169 | # - unbound
170 | # - haproxy
171 | # image: ghcr.io/publicarray/dns-resolver-infra/dnscrypt-server
172 | # command:
173 | # - init
174 | # - -d unbound
175 | # - -N
176 | # - dns.seby.io
177 | # - -T
178 | # - haproxy
179 | # - -E
180 | # - 139.99.222.72:8443
181 | # - -A
182 | # logging:
183 | # driver: "json-file"
184 | # options:
185 | # max-size: "200k"
186 | # max-file: "10"
187 | # ports:
188 | # - "443:8443/tcp"
189 | # - "443:8443/udp"
190 | # volumes:
191 | # - dnscrypt:/opt/dnscrypt-wrapper
192 | # - dnscrypt-server:/opt/encrypted-dns
193 |
--------------------------------------------------------------------------------
/docker-stack.yml:
--------------------------------------------------------------------------------
1 | version: '3.4'
2 | volumes:
3 | dnscrypt:
4 | dnscrypt-server:
5 | ssl:
6 | nsd:
7 | acme-sh:
8 | acme-acc:
9 | services:
10 | acme:
11 | image: neilpang/acme.sh
12 | command: >
13 | /bin/sh -c "echo \"#!/bin/sh
14 |
15 | set -e
16 |
17 | # Check if certificate is still valid for the next 30 days, if so exit.
18 |
19 | if [ -f /opt/ssl/fullchain.pem ]; then
20 |
21 | if openssl x509 -checkend 2592000 -noout -in /opt/ssl/fullchain.pem; then
22 |
23 | echo 'Certificate is still valid!'
24 |
25 | exit 0
26 |
27 | else
28 | echo 'Certificate has expired or will do so within 30 days!'
29 |
30 | echo 'Renewing...'
31 |
32 | fi
33 |
34 | fi
35 |
36 | # Grab docker secrets
37 |
38 | export CF_Key='$$(cat /run/secrets/CF_Key)'
39 |
40 | export CF_Email='$$(cat /run/secrets/CF_Email)'
41 |
42 | # Issue Certificates
43 | #### Remember to remove '--staging' in production! ####
44 |
45 | # acme.sh
46 | # --issue
47 | # --dns dns_cf
48 | # --dnssleep 60
49 | # --domain '*.seby.io'
50 | # --keylength 4096
51 | # --fullchain-file /opt/ssl/fullchain.pem
52 | # --key-file /opt/ssl/key.pem
53 | # --ca-file /opt/ssl/ca.pem
54 | # --cert-file /opt/ssl/cert.pem
55 | # --reloadcmd 'cat /opt/ssl/key.pem > cat /opt/ssl/fullchain.pem > /opt/ssl/fullchain-key.pem.rsa'
56 |
57 | acme.sh
58 | --issue
59 | --dns dns_cf
60 | --dnssleep 60
61 | --domain '*.seby.io'
62 | --keylength ec-384
63 | --fullchain-file /opt/ssl/fullchain-ecc.pem
64 | --key-file /opt/ssl/key-ecc.pem
65 | --ca-file /opt/ssl/ca-ecc.pem
66 | --cert-file /opt/ssl/cert-ecc.pem
67 | --reloadcmd 'cat /opt/ssl/key-ecc.pem > cat /opt/ssl/fullchain-ecc.pem > /opt/ssl/fullchain-key.pem.ecdsa'
68 | \" > start.sh
69 | && chmod +x start.sh
70 | && ./start.sh"
71 | deploy:
72 | restart_policy:
73 | condition: on-failure
74 | max_attempts: 2
75 | logging:
76 | driver: "json-file"
77 | options:
78 | max-size: "200k"
79 | max-file: "10"
80 | secrets:
81 | - CF_Email
82 | - CF_Key
83 | volumes:
84 | - ssl:/opt/ssl
85 | - acme-sh:/root/.acme.sh
86 | - acme-acc:/acme.sh
87 | acme-daemon:
88 | container_name: acme
89 | image: neilpang/acme.sh
90 | command: daemon
91 | deploy:
92 | replicas: 1
93 | restart_policy:
94 | condition: on-failure
95 | max_attempts: 20
96 | logging:
97 | driver: "json-file"
98 | options:
99 | max-size: "200k"
100 | max-file: "10"
101 | secrets:
102 | - CF_Email
103 | - CF_Key
104 | volumes:
105 | - ssl:/opt/ssl
106 | - acme-sh:/root/.acme.sh
107 | - acme-acc:/acme.sh
108 | - /var/run/docker.sock:/var/run/docker.sock
109 | environment:
110 | - DEPLOY_DOCKER_CONTAINER_LABEL=sh.acme.autoload.domain=*.seby.io
111 | - DEPLOY_DOCKER_CONTAINER_KEY_FILE=/opt/ssl/key-ecc.pem
112 | - DEPLOY_DOCKER_CONTAINER_CERT_FILE="/opt/ssl/cert-ecc.pem"
113 | - DEPLOY_DOCKER_CONTAINER_CA_FILE="/opt/ssl/ca-ecc.pem"
114 | - DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE="/opt/ssl/fullchain-ecc.pem"
115 | - DEPLOY_DOCKER_CONTAINER_RELOAD_CMD="cat /opt/ssl/key-ecc.pem > cat /opt/ssl/fullchain-ecc.pem > /opt/ssl/fullchain-key.pem.ecdsa; sv restart haproxy"
116 |
117 | nsd:
118 | container_name: nsd
119 | build: nsd
120 | image: publicarray/nsd
121 | deploy:
122 | replicas: 1
123 | restart_policy:
124 | condition: any
125 | delay: 5s
126 | max_attempts: 20
127 | logging:
128 | driver: "json-file"
129 | options:
130 | max-size: "200k"
131 | max-file: "10"
132 | volumes:
133 | - nsd:/etc/nsd/run
134 | networks:
135 | - nsd-net
136 |
137 | unbound:
138 | container_name: unbound
139 | depends_on:
140 | - nsd
141 | build: unbound
142 | image: publicarray/unbound
143 | command: -m -d nsd
144 | deploy:
145 | replicas: 1
146 | resources:
147 | limits:
148 | memory: 260M
149 | restart_policy:
150 | condition: any
151 | delay: 5s
152 | max_attempts: 4
153 | logging:
154 | driver: "json-file"
155 | options:
156 | max-size: "200k"
157 | max-file: "10"
158 | ports:
159 | - target: 4949
160 | published: 4949
161 | protocol: tcp
162 | mode: ingress
163 | networks:
164 | - nsd-net
165 | - unbound-net
166 |
167 | m13253-doh:
168 | container_name: doh
169 | depends_on:
170 | - unbound
171 | build: m13253-doh
172 | image: publicarray/m13253-doh
173 | command: -d unbound
174 | deploy:
175 | replicas: 1
176 | restart_policy:
177 | condition: any
178 | delay: 5s
179 | logging:
180 | driver: "json-file"
181 | options:
182 | max-size: "200k"
183 | max-file: "10"
184 | networks:
185 | - unbound-net
186 |
187 | # doh-proxy:
188 | # depends_on:
189 | # - unbound
190 | # build: doh-proxy
191 | # image: publicarray/doh-proxy
192 | # command: -d
193 | # deploy:
194 | # replicas: 1
195 | # restart_policy:
196 | # condition: any
197 | # delay: 5s
198 | # networks:
199 | # - unbound-net
200 |
201 | haproxy:
202 | container_name: haproxy
203 | depends_on:
204 | - acme
205 | - m13253-doh
206 | - unbound
207 | labels:
208 | - sh.acme.autoload.domain=*.seby.io
209 | build: haproxy
210 | image: publicarray/haproxy
211 | command: -d -r
212 | deploy:
213 | replicas: 1
214 | restart_policy:
215 | condition: any
216 | delay: 5s
217 | max_attempts: 20
218 | logging:
219 | driver: "json-file"
220 | options:
221 | max-size: "200k"
222 | max-file: "10"
223 | ports:
224 | - target: 443
225 | published: 443
226 | protocol: tcp
227 | mode: ingress
228 | - target: 853
229 | published: 853
230 | protocol: tcp
231 | mode: ingress
232 | volumes:
233 | - ssl:/opt/ssl
234 | networks:
235 | - haproxy-net
236 | - unbound-net
237 |
238 | dnscrypt-server:
239 | depends_on:
240 | - unbound
241 | image: publicarray/dnscrypt-server
242 | command:
243 | - init
244 | - -d unbound
245 | - -N
246 | - dns.seby.io
247 | - -E
248 | - 139.99.222.72:8443
249 | - -A
250 | deploy:
251 | replicas: 1
252 | restart_policy:
253 | condition: any
254 | delay: 5s
255 | max_attempts: 20
256 | logging:
257 | driver: "json-file"
258 | options:
259 | max-size: "200k"
260 | max-file: "10"
261 | ports:
262 | - target: 443
263 | published: 8443
264 | protocol: tcp
265 | mode: ingress
266 | - target: 443
267 | published: 8443
268 | protocol: udp
269 | mode: ingress
270 | volumes:
271 | - dnscrypt:/opt/dnscrypt-wrapper
272 | - dnscrypt-server:/opt/encrypted-dns
273 | networks:
274 | - dnscrypt-net
275 | - unbound-net
276 |
277 | secrets:
278 | CF_Email:
279 | external: true
280 | CF_Key:
281 | external: true
282 |
283 | networks:
284 | dnscrypt-net:
285 | driver: overlay
286 | haproxy-net:
287 | driver: overlay
288 | nsd-net:
289 | driver: overlay
290 | unbound-net:
291 | driver: overlay
292 |
--------------------------------------------------------------------------------
/docker.md:
--------------------------------------------------------------------------------
1 | # [Docker Machine](https://docs.docker.com/machine/overview/)
2 |
3 | https://docs.docker.com/machine/drivers/
4 |
5 | https://github.com/docker/docker.github.io/blob/master/machine/AVAILABLE_DRIVER_PLUGINS.md
6 |
7 | ## Vultr / Digital Ocean
8 |
9 | ```sh
10 | brew install docker docker-machine docker-machine-driver-vultr # https://github.com/janeczku/docker-machine-vultr
11 |
12 | # Vultr
13 | docker-machine create -d vultr --vultr-region-id 19 --vultr-plan-id 201 --vultr-api-key "$VTOKEN" --vultr-ssh-key-id xxxxxxxxxxxxxx --vultr-ipv6 --vultr-ros-version v1.3.0 rancher-node
14 | # Digital Ocean
15 | docker-machine create -d digitalocean --digitalocean-region sfo1 --digitalocean-size 1gb --digitalocean-ssh-user rancher --digitalocean-image rancheros --digitalocean-access-token $DOTOKEN rancher-node
16 |
17 | docker-machine ssh rancher-node
18 | eval "$(docker-machine env rancher-node)" # for fish: eval (docker-machine env rancher-node)
19 | docker ps
20 | ```
21 |
22 | ## Google Cloud Platform
23 |
24 | ```sh
25 | brew install docker docker-machine
26 | brew cask intall google-cloud-sdk
27 |
28 | gcloud auth login
29 | gcloud auth application-default login # (should only be used temporarily)
30 | gcloud compute images list --uri # for machine-image
31 |
32 | docker-machine create -d google --google-project dns-infra-xxxxxxx --google-zone australia-southeast1-a --google-machine-type f1-micro --google-tags doh,dnscrypt,g-node --google-machine-image https://www.googleapis.com/compute/v1/projects/centos-cloud/global/images/centos-7-v20180507 g-node
33 | # use "--google-preemptible" for testing
34 |
35 | # https://rancher.com/docs/os/v1.1/en/running-rancheros/cloud/gce/
36 | # https://cloud.google.com/sdk/gcloud/reference/compute/instances/create
37 | #gcloud compute instances create g-node --zone australia-southeast1-a --machine-type f1-micro --image xxxxxxxxxxxxxx
38 |
39 | gcloud compute ssh g-node
40 | docker-machine ssh g-node
41 |
42 | eval "$(docker-machine env g-node)" # for fish: eval (docker-machine env g-node)
43 | ```
44 | For logging I suggest you follow: https://cloud.google.com/community/tutorials/docker-gcplogs-driver
45 |
46 | # [Docker Swarm](https://docs.docker.com/engine/swarm/) Setup
47 |
48 | ```sh
49 | eval "$(docker-machine env rancher-node)" # for fish: eval (docker-machine env rancher-node)
50 | docker-machine ls
51 |
52 | docker swarm init --advertise-addr node_ip_address_from_docker-machine_ls
53 | # docker swarm join --token your_swarm_token manager_node_ip_address:2377
54 | docker node ls
55 |
56 | # Add Cloudflare API key for acme.sh to do domain validation via DNS
57 | echo "email@example.com" | docker secret create CF_Email -
58 | echo "xxxxxxxxxxxxxx" | docker secret create CF_Key -
59 |
60 | # You need to modify docker-compose.yml to your needs:
61 | # - Change the domain name for certificate generation (TLS)
62 | # - Change the acme.sh script if you are not using Cloudflare
63 | # - Change dnscrypt-wrapper external IP address and provider name
64 | # - Change memory allocations / limits
65 | # - Change any port allocations if you desire
66 | docker stack deploy --compose-file=docker-compose.yml dns-server
67 | docker ps -a
68 |
69 | # Some useful commands
70 | docker-machine ssh rancher-node
71 | docker-machine ip rancher-node
72 | docker logs xxxxxxxxxxxxxx
73 | docker exec -it xxxxxxxxxxxxxx sh
74 | docker exec -it xxxxxxxxxxxxxx /entrypoint.sh provider-info # for dnscrypt-wrapper
75 | docker stack rm dns-server # when things go wrong and you need to start form a blank slate
76 | docker run --rm -it sh # debug a docker build
77 | ```
78 |
79 | ## Local development with virtualbox
80 |
81 | ```sh
82 | docker-machine create -d virtualbox local
83 | # docker-machine create -d virtualbox --virtualbox-boot2docker-url https://releases.rancher.com/os/latest/rancheros.iso
84 | eval "$(docker-machine env local)" # for fish: eval (docker-machine env local)
85 | ```
86 |
--------------------------------------------------------------------------------
/doh-proxy/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM rust:latest as doh-proxy-build
2 | LABEL org.opencontainers.image.source https://github.com/publicarray/dns-resolver-infra
3 | ENV REVISION 1
4 | ARG VERSION=0.9.9
5 |
6 | ENV RUSTFLAGS "-C link-arg=-s"
7 | RUN cargo install doh-proxy --version $VERSION --target=x86_64-unknown-linux-gnu && \
8 | strip --strip-all /usr/local/cargo/bin/doh-proxy
9 |
10 | #------------------------------------------------------------------------------#
11 | FROM ubuntu:22.04
12 | LABEL org.opencontainers.image.source https://github.com/publicarray/dns-resolver-infra
13 | LABEL maintainer="publicarray"
14 | LABEL description="A DNS-over-HTTP server proxy in Rust. https://github.com/DNSCrypt/doh-server"
15 |
16 | RUN apt-get update && \
17 | apt-get install -qy --no-install-recommends bash libc6 curl ca-certificates dnsutils libssl3 && \
18 | rm -fr /tmp/* /var/tmp/* /var/cache/apt/* /var/lib/apt/lists/* /var/log/apt/* /var/log/*.log
19 | RUN update-ca-certificates 2> /dev/null || true
20 | COPY --from=doh-proxy-build /usr/local/cargo/bin/doh-proxy /usr/local/bin/doh-proxy
21 |
22 | RUN set -x && \
23 | groupadd _doh_proxy && \
24 | useradd -g _doh_proxy -s /dev/null -d /dev/null _doh_proxy
25 |
26 | USER _doh_proxy
27 |
28 | COPY entrypoint.sh /
29 |
30 | EXPOSE 3000/udp 3000/tcp
31 |
32 | RUN doh-proxy --version
33 |
34 | HEALTHCHECK --start-period=5s --interval=2m \
35 | CMD curl -f -H 'accept: application/dns-message' 'http://127.0.0.1:3000/dns-query?dns=q80BAAABAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB' >/dev/null || exit 1
36 |
37 | ENTRYPOINT ["/entrypoint.sh"]
38 |
--------------------------------------------------------------------------------
/doh-proxy/doh-proxy-deployment.yml:
--------------------------------------------------------------------------------
1 | apiVersion: apps/v1
2 | kind: Deployment
3 | metadata:
4 | name: doh-proxy
5 | spec:
6 | selector:
7 | matchLabels:
8 | app: dns-server
9 | component: doh-proxy
10 | strategy:
11 | type: Recreate
12 | replicas: 1
13 | template:
14 | metadata:
15 | labels:
16 | app: dns-server
17 | component: doh-proxy
18 | spec:
19 | containers:
20 | - name: doh-proxy
21 | image: publicarray/doh-proxy
22 | # command: ["/entrypoint.sh"]
23 | ports:
24 | - name: dns
25 | containerPort: 3000
26 | # resources:
27 | # requests:
28 | # cpu: 100m
29 | # memory: 50Mi
30 | restartPolicy: Always
31 |
--------------------------------------------------------------------------------
/doh-proxy/doh-proxy-srv.yml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: doh-proxy
5 | labels:
6 | app: dns-server
7 | component: doh-proxy
8 | spec:
9 | selector:
10 | app: dns-server
11 | component: doh-proxy
12 | ports:
13 | - name: doh-tcp
14 | protocol: TCP
15 | port: 3000
16 | targetPort: 3000
17 | # type: ClusterIP
18 |
--------------------------------------------------------------------------------
/doh-proxy/entrypoint.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | set -e
3 |
4 | getServiceIP () {
5 | dig "$1" +short
6 | }
7 |
8 | waitOrFail () {
9 | maxTries=24
10 | i=0
11 | while [ $i -lt $maxTries ]; do
12 | outStr="$($@)"
13 | if [ $? -eq 0 ];then
14 | echo "$outStr"
15 | return
16 | fi
17 | i=$((i+1))
18 | echo "==> waiting for a dependent service $i/$maxTries" >&2
19 | sleep 5
20 | done
21 | echo "Too many failed attempts" >&2
22 | exit 1
23 | }
24 |
25 | UNBOUND_SERVICE_HOST=${UNBOUND_SERVICE_HOST-"1.1.1.1"}
26 | UNBOUND_SERVICE_PORT=${UNBOUND_SERVICE_PORT-"53"}
27 | while getopts "h?d" opt; do
28 | case "$opt" in
29 | h|\?) echo "-d domain lookup for service discovery"; exit 0;;
30 | d) UNBOUND_SERVICE_HOST="$(waitOrFail getServiceIP unbound)"
31 | ;;
32 | esac
33 | done
34 | shift $((OPTIND-1))
35 | export RESOLVER="$UNBOUND_SERVICE_HOST:$UNBOUND_SERVICE_PORT"
36 |
37 | if [ $# -eq 0 ]; then
38 | echo "doh-proxy - resolver: $RESOLVER"
39 | exec /usr/local/bin/doh-proxy --server-address "${RESOLVER}" --listen-address 0.0.0.0:3000
40 | fi
41 |
42 | [ "$1" = '--' ] && shift
43 |
44 | exec /usr/local/bin/doh-proxy "$@"
45 |
--------------------------------------------------------------------------------
/haproxy/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM alpine:3.19 as build
2 | LABEL org.opencontainers.image.source https://github.com/publicarray/dns-resolver-infra
3 | LABEL maintainer="publicarray"
4 | LABEL description="The Reliable, High Performance TCP/HTTP Load Balancer"
5 | # https://github.com/docker-library/haproxy/tree/master
6 |
7 | ENV HAPROXY_BUILD_DEPS gcc ca-certificates libc-dev linux-headers make openssl-dev pcre2-dev readline-dev tar zlib-dev
8 | RUN apk add --no-cache $HAPROXY_BUILD_DEPS
9 |
10 | ENV HAPROXY_VERSION_SHORT 2.9
11 | ENV HAPROXY_VERSION 2.9.7
12 | ENV HAPROXY_SHA256 d1a0a56f008a8d2f007bc0c37df6b2952520d1f4dde33b8d3802710e5158c131
13 | ENV HAPROXY_DOWNLOAD_URL "https://www.haproxy.org/download/${HAPROXY_VERSION_SHORT}/src/haproxy-${HAPROXY_VERSION}.tar.gz"
14 |
15 | RUN set -x && \
16 | mkdir -p /tmp/src/haproxy && \
17 | cd /tmp/src/haproxy && \
18 | wget -O haproxy.tar.gz $HAPROXY_DOWNLOAD_URL && \
19 | echo "${HAPROXY_SHA256} *haproxy.tar.gz" | sha256sum -c - && \
20 | tar xzf haproxy.tar.gz -C /tmp/src/haproxy --strip-components=1 && \
21 | nproc="$(getconf _NPROCESSORS_ONLN)" && \
22 | makeOpts=' \
23 | TARGET=linux-musl \
24 | USE_GETADDRINFO=1 \
25 | USE_OPENSSL=1 \
26 | USE_QUIC=1 \
27 | USE_QUIC_OPENSSL_COMPAT=1 \
28 | USE_PCRE2=1 \
29 | USE_PCRE2_JIT=1 \
30 | USE_ZLIB=1 \
31 | ' && \
32 | eval "make $makeOpts -j '$nproc' all" && \
33 | eval "make $makeOpts install-bin"
34 |
35 | #------------------------------------------------------------------------------#
36 | FROM alpine:3.19
37 | LABEL org.opencontainers.image.source https://github.com/publicarray/dns-resolver-infra
38 |
39 | ENV HAPROXY_RUN_DEPS curl shadow zlib pcre2 openssl socat runit coreutils bind-tools
40 |
41 | RUN apk add --no-cache $HAPROXY_RUN_DEPS
42 |
43 | COPY --from=build /usr/local/sbin/haproxy /usr/local/sbin/haproxy
44 | COPY --from=build /tmp/src/haproxy/examples/errorfiles /usr/local/etc/haproxy/errors
45 |
46 | RUN set -x && \
47 | groupadd _haproxy && \
48 | useradd -g _haproxy -s /dev/null -d /dev/null _haproxy && \
49 | mkdir -p \
50 | /etc/service/haproxy/ \
51 | /run/haproxy/ \
52 | update-ca-certificates 2> /dev/null || true
53 |
54 | COPY entrypoint.sh /
55 | COPY haproxy.conf /etc/haproxy.conf
56 | COPY haproxy.sh /etc/service/haproxy/run
57 | # wget https://ssl-config.mozilla.org/ffdhe2048.txt -O /opt/ssl/dhparam.pem
58 | COPY ffdhe2048.txt /opt/ssl/dhparam.pem
59 |
60 | VOLUME ["/opt/ssl"]
61 |
62 | EXPOSE 853/udp 853/tcp 443/udp 443/tcp
63 |
64 | RUN haproxy -vv
65 | RUN haproxy -f /etc/haproxy.conf -c || true
66 |
67 | # Gracefully exit
68 | # All services are then put into soft-stop state,
69 | # which means that they will refuse to accept new connections
70 | STOPSIGNAL SIGUSR1
71 |
72 | # HEALTHCHECK --start-period=5s --interval=3m \
73 | # CMD curl -f -H 'accept: application/dns-message' -k 'https://127.0.0.1/dns-query?ct&dns=AAABAAABAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB'>/dev/null || exit 1
74 |
75 | ENTRYPOINT ["/entrypoint.sh"]
76 |
--------------------------------------------------------------------------------
/haproxy/entrypoint.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | set -e
3 | set -x
4 |
5 | getServiceIP () {
6 | for arg
7 | do dig "$arg" +short
8 | done
9 | }
10 |
11 | waitOrFail () {
12 | maxTries=24
13 | i=0
14 | while [ $i -lt $maxTries ]; do
15 | outStr="$($@)"
16 | if [ $? -eq 0 ];then
17 | echo "$outStr"
18 | return
19 | fi
20 | i=$((i+1))
21 | echo "==> waiting for a dependent service $i/$maxTries" >&2
22 | sleep 5
23 | done
24 | echo "Too many failed attempts" >&2
25 | exit 1
26 | }
27 |
28 | UNBOUND_SERVICE_HOST=${UNBOUND_SERVICE_HOST-"1.1.1.1"}
29 | UNBOUND_SERVICE_PORT=${UNBOUND_SERVICE_PORT-"53"}
30 | DOH_PROXY_SERVICE_HOST=${DOH_PROXY_SERVICE_HOST-"127.0.0.1"}
31 | DOH_PROXY_SERVICE_PORT=${DOH_PROXY_SERVICE_PORT-"3000"}
32 |
33 | if [ ! -f /opt/ssl/dhparam.pem ]; then
34 | openssl dhparam -out /opt/ssl/dhparam.pem 4096
35 | fi
36 |
37 | while getopts "h?dr" opt; do
38 | case "$opt" in
39 | h|\?)
40 | echo "-d domain lookup for service discovery";
41 | echo "-r uncomment lines in haproxy.conf with the word 'redirect' in them";
42 | exit 0
43 | ;;
44 | d)
45 | UNBOUND_SERVICE_HOST="$(waitOrFail getServiceIP unbound)"
46 | DOH_PROXY_SERVICE_HOST="$(waitOrFail getServiceIP doh-proxy m13253-doh)"
47 | ;;
48 | r)
49 | sed -i '/^#.* redirect /s/^#//' /etc/haproxy.conf
50 | ;;
51 | esac
52 | done
53 | shift $((OPTIND-1))
54 | export RESOLVER="$UNBOUND_SERVICE_HOST:$UNBOUND_SERVICE_PORT"
55 | export DOH_SERVER="$DOH_PROXY_SERVICE_HOST:$DOH_PROXY_SERVICE_PORT"
56 |
57 | sed -i -e "s/server doh-proxy .*/server doh-proxy ${DOH_SERVER}/" \
58 | -e "s/server dns .*/server dns ${RESOLVER}/" \
59 | /etc/haproxy.conf
60 |
61 | if [ $# -eq 0 ]; then
62 | exec /sbin/runsvdir -P /etc/service
63 | fi
64 |
65 | [ "$1" = '--' ] && shift
66 | /sbin/runsvdir -P /etc/service
67 | exec "$@"
68 |
--------------------------------------------------------------------------------
/haproxy/ffdhe2048.txt:
--------------------------------------------------------------------------------
1 | -----BEGIN DH PARAMETERS-----
2 | MIIBCAKCAQEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz
3 | +8yTnc4kmz75fS/jY2MMddj2gbICrsRhetPfHtXV/WVhJDP1H18GbtCFY2VVPe0a
4 | 87VXE15/V8k1mE8McODmi3fipona8+/och3xWKE2rec1MKzKT0g6eXq8CrGCsyT7
5 | YdEIqUuyyOP7uWrat2DX9GgdT0Kj3jlN9K5W7edjcrsZCwenyO4KbXCeAvzhzffi
6 | 7MA0BM0oNC9hkXL+nOmFg/+OTxIy7vKBg8P+OxtMb61zO7X8vC7CIAXFjvGDfRaD
7 | ssbzSibBsu/6iGtCOGEoXJf//////////wIBAg==
8 | -----END DH PARAMETERS-----
--------------------------------------------------------------------------------
/haproxy/haproxy-deployment.yml:
--------------------------------------------------------------------------------
1 | apiVersion: extensions/v1beta1
2 | kind: Deployment
3 | metadata:
4 | namespace: default
5 | labels:
6 | service: haproxy
7 | name: haproxy
8 | spec:
9 | strategy:
10 | type: Recreate
11 | replicas: 1
12 | template:
13 | metadata:
14 | labels:
15 | app: dns-server
16 | component: haproxy
17 | spec:
18 | containers:
19 | - env:
20 | image: publicarray/haproxy
21 | name: haproxy
22 | ports:
23 | - name: dns-over-tls
24 | containerPort: 853
25 | - name: doh
26 | containerPort: 443
27 | volumeMounts:
28 | - name: ssl
29 | mountPath: /opt/ssl
30 | # command: ["/usr/local/sbin/haproxy", "-f", "/etc/haproxy.conf"]
31 | # resources:
32 | # requests:
33 | # memory: "1Gi"
34 | restartPolicy: Always
35 | volumes:
36 | - name: ssl
37 | hostPath:
38 | path: /data/ssl
39 | type: DirectoryOrCreate
40 |
--------------------------------------------------------------------------------
/haproxy/haproxy-srv.yml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: haproxy
5 | labels:
6 | app: dns-server
7 | component: haproxy
8 | spec:
9 | selector:
10 | app: dns-server
11 | component: haproxy
12 | ports:
13 | - name: dns-over-tls-tcp
14 | protocol: TCP
15 | port: 853
16 | targetPort: 853
17 | - name: dns-over-tls-udp
18 | protocol: UDP
19 | port: 853
20 | targetPort: 853
21 | - name: doh-tcp
22 | protocol: TCP
23 | port: 443
24 | targetPort: 443
25 | - name: doh-udp
26 | protocol: UDP
27 | port: 443
28 | targetPort: 443
29 | type: NodePort
30 |
--------------------------------------------------------------------------------
/haproxy/haproxy.conf:
--------------------------------------------------------------------------------
1 | global
2 | log stdout format raw local0
3 | stats socket /run/haproxy/admin.sock mode 660 level admin
4 | stats socket ipv4@127.0.0.1:9000 level admin
5 | stats timeout 2m
6 | hard-stop-after 30s
7 | #maxconn 4000
8 | # chroot /var/haproxy
9 | user _haproxy
10 | group _haproxy
11 | # daemon
12 | pidfile /var/run/haproxy.pid
13 | ## SSL/TLS config
14 | # generated 2019-09-08, https://ssl-config.mozilla.org/#server=haproxy&server-version=2.0.4&config=intermediate
15 | ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
16 | ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
17 | ssl-default-bind-options no-sslv3 no-tlsv10 no-tlsv11 no-tls-tickets
18 | # curl https://ssl-config.mozilla.org/ffdhe2048.txt > /path/to/dhparam.pem
19 | ssl-dh-param-file /opt/ssl/dhparam.pem
20 | defaults
21 | log global
22 | mode http
23 | option dontlognull
24 | option redispatch
25 | option splice-auto
26 | retries 1
27 | # https://delta.blue/blog/haproxy-timeouts
28 | timeout connect 5s
29 | timeout check 5s
30 | timeout queue 10s
31 | timeout client 30s
32 | timeout client-fin 3s
33 | timeout server-fin 3s
34 | timeout server 30s
35 | timeout tunnel 20m
36 | timeout http-request 10s
37 |
38 | frontend dns-over-tls-in
39 | mode tcp
40 | option tcplog
41 | bind 0.0.0.0:853 ssl crt /opt/ssl/fullchain-key.pem.ecdsa
42 | bind :::853 v6only ssl crt /opt/ssl/fullchain-key.pem.ecdsa
43 | default_backend dns-servers
44 |
45 | frontend doh-in
46 | http-response set-header Strict-Transport-Security "max-age=63072000"
47 | bind 0.0.0.0:443 ssl crt /opt/ssl/fullchain-key.pem.ecdsa alpn h2
48 | bind :::443 v6only ssl crt /opt/ssl/fullchain-key.pem.ecdsa alpn h2
49 |
50 | acl dns_url path /dns-query
51 | redirect location https://dns.seby.io code 301 if !dns_url { hdr(host) -i dns.seby.io }
52 | redirect location https://dns.seby.io code 301 if !dns_url { hdr(host) -i www.dns.seby.io }
53 | redirect location https://dns.seby.io code 301 if !dns_url { hdr(host) -i dot.seby.io }
54 | redirect location https://dns.seby.io code 301 if !dns_url { hdr(host) -i www.dot.seby.io }
55 | redirect location https://dns.seby.io code 301 if !dns_url { hdr(host) -i doh.seby.io }
56 | redirect location https://dns.seby.io code 301 if !dns_url { hdr(host) -i www.doh.seby.io }
57 | redirect location https://www.ntppool.org/en/ code 301 if !dns_url { hdr(host) -i ntppool.org }
58 |
59 | use_backend doh-servers if dns_url
60 | default_backend no-match
61 |
62 | backend no-match
63 | http-request deny deny_status 400
64 |
65 | backend dns-servers
66 | mode tcp
67 | server dns 127.0.0.1:53 maxconn 20
68 |
69 | backend doh-servers
70 | #option forwardfor
71 | http-response del-header server
72 | http-response del-header x-powered-by
73 | server doh-proxy 127.0.0.1:3000 maxconn 20
74 |
--------------------------------------------------------------------------------
/haproxy/haproxy.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | set -e
3 |
4 | exec /usr/local/sbin/haproxy -V -f /etc/haproxy.conf
5 |
--------------------------------------------------------------------------------
/haproxy/ocsp-updater.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | set -x
4 | set -e
5 |
6 | # https://www.haproxy.com/blog/haproxy-1-9-has-arrived/
7 | # https://icicimov.github.io/blog/server/HAProxy-OCSP-stapling/
8 |
9 | # Certificates path and names
10 | DIR="/opt/ssl"
11 | CERT="fullchain-key.pem"
12 | CERT_RSA="fullchain-key.pem.rsa"
13 | CERT_ECC="fullchain-key.pem.ecdsa"
14 | RUNTIME_API=/run/haproxy/admin.sock
15 |
16 | create_ocsp () {
17 | CERT=$1
18 |
19 | # Get the issuer URI, download it's certificate and convert into PEM format
20 | ISSUER_URI=$(openssl x509 -in ${DIR}/${CERT} -text -noout | grep 'CA Issuers' | cut -d: -f2,3)
21 | ISSUER_NAME=letsencrypt
22 | if [ -z "$ISSUER_URI" ]; then
23 | return
24 | fi
25 |
26 | wget -q -O- "$ISSUER_URI" | openssl x509 -inform DER -outform PEM -out ${DIR}/${ISSUER_NAME}.pem
27 |
28 | # Get the OCSP URL from the certificate
29 | ocsp_url=$(openssl x509 -noout -ocsp_uri -in ${DIR}/${CERT})
30 |
31 | # Extract the hostname from the OCSP URL
32 | ocsp_host=$(echo "$ocsp_url" | cut -d/ -f3)
33 |
34 | # Create/update the ocsp response file and update HAProxy
35 | openssl ocsp -noverify -no_nonce -issuer ${DIR}/${ISSUER_NAME}.pem -cert ${DIR}/${CERT} -url "$ocsp_url" -header Host="$ocsp_host" -respout ${DIR}/${CERT}.ocsp
36 | [ $? -eq 0 ] && [ "$(pidof haproxy)" ] && [ -s ${DIR}/${CERT}.ocsp ] && echo "set ssl ocsp-response $(base64 -w 0 ${DIR}/${CERT}.ocsp)" | socat $RUNTIME_API stdio
37 | }
38 |
39 | create_ocsp $CERT
40 | create_ocsp $CERT_RSA
41 | create_ocsp $CERT_ECC
42 |
43 | sleep 259200 # 3 days
44 | exit 0
45 |
--------------------------------------------------------------------------------
/kube.md:
--------------------------------------------------------------------------------
1 | ## Getting Started with [Kubernetes](https://kubernetes.io)
2 |
3 | ```sh
4 | minikube delete
5 | minikube start
6 | kubectl create -f cloudflare-secret.yml
7 | # kubectl get secrets
8 | # kubectl get secret cloudflare -o yaml
9 |
10 | kubectl create -f acme-init-job.yml
11 | kubectl create -f dnscrypt-wrapper/dnscrypt-init-job.yml
12 |
13 | kubectl create -f nsd/nsd-srv.yml
14 | kubectl create -f unbound/unbound-srv.yml
15 | kubectl create -f doh-proxy/doh-proxy-srv.yml
16 | kubectl create -f haproxy/haproxy-srv.yml
17 | kubectl create -f dnscrypt-wrapper/dnscrypt-srv.yml
18 |
19 | kubectl create -f nsd/nsd-deployment.yml
20 | kubectl create -f unbound/unbound-deployment.yml
21 | kubectl create -f doh-proxy/doh-proxy-deployment.yml
22 | kubectl create -f haproxy/haproxy-deployment.yml
23 | kubectl create -f dnscrypt-wrapper/dnscrypt-deployment.yml
24 | ```
25 |
26 | Workflow
27 |
28 | ```sh
29 | kubectl delete job/acme-init
30 | kubectl create -f acme-init-job.yml
31 | kubectl logs job/acme-init
32 | kubectl get jobs
33 | kubectl describe job/acme-init
34 | ```
35 |
36 | Dashboard
37 |
38 | ```sh
39 | kubectl create -f https://raw.githubusercontent.com/kubernetes/dashboard/master/src/deploy/recommended/kubernetes-dashboard.yaml
40 | # or
41 | minikube dashboard
42 | ```
43 |
44 | Debugging
45 |
46 | ```sh
47 | kubectl get nodes
48 | kubectl get jobs
49 | kubectl get deployments
50 | kubectl get services
51 | kubectl get pods -o wide
52 | kubectl get all -l app=dns-server
53 |
54 | ## SSH into the container/pod
55 | #export POD_NAME=$(kubectl get pods -o go-template --template '{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}')
56 | kubectl get pods
57 | kubectl logs job/dnscrypt-init
58 | kubectl exec -ti $POD_NAME sh
59 | kubectl exec -ti $(kubectl get pods | grep 'unbound' | awk '{print $1}') sh
60 |
61 | ## SSH into a new neighbouring container/pod
62 | kubectl run busybox -it --image=busybox --restart=Never --rm
63 | kubectl run alpine -it --image=alpine --restart=Never --rm
64 |
65 | minikube ssh
66 |
67 | kubectl logs deployment/nsd
68 | kubectl describe deployment/nsd
69 | ```
70 |
71 | Build docker images
72 |
73 | ```sh
74 | docker build -t publicarray/nsd nsd/
75 | docker build -t publicarray/unbound unbound/
76 | docker build -t publicarray/doh-proxy doh-proxy/
77 | docker build -t publicarray/haproxy haproxy/
78 | docker build -t publicarray/dnscrypt-wrapper dnscrypt-wrapper/
79 | docker images
80 | docker push publicarray/unbound
81 |
82 | docker run --rm --name myunbound -it publicarray/unbound sh
83 | docker run -p 5300:53/udp -v (pwd)/unbound/unbound.conf:/etc/unbound/unbound.conf:ro --name myunbound publicarray/unbound
84 | docker run -p 4430:443/udp -p 4430:443/tcp --name=dnscrypt-server dnscrypt init -N example.com -E 127.0.0.1:4430
85 | docker start dnscrypt-server
86 |
87 | docker rm dnscrypt-server --force
88 | ```
89 |
--------------------------------------------------------------------------------
/lint.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # yarn
4 | find . -not -path "./node_modules/*" -type f -name Dockerfile | xargs -L1 node_modules/.bin/dockerlint
5 | # find . -not -path "./node_modules/*" -type f -name Dockerfile | xargs -L1 node_modules/.bin/dockerfile_lint -f
6 | find . -not -path "./node_modules/*" -type f -name Dockerfile | xargs -L1 node_modules/.bin/dockerfilelint -c .
7 |
8 | if command -v hadolint >/dev/null; then
9 | find . -not -path "./node_modules/*" -type f -name Dockerfile | xargs -L1 hadolint
10 | else
11 | echo "For more linting install hadolint 'brew install hadolint'"
12 | fi
13 |
--------------------------------------------------------------------------------
/logo/horizonal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/publicarray/dns-resolver-infra/c0f32be0b0956088d355361a204df5b1fce990ee/logo/horizonal.png
--------------------------------------------------------------------------------
/logo/icon-transparent.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/publicarray/dns-resolver-infra/c0f32be0b0956088d355361a204df5b1fce990ee/logo/icon-transparent.png
--------------------------------------------------------------------------------
/logo/icon-transparent.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/logo/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/publicarray/dns-resolver-infra/c0f32be0b0956088d355361a204df5b1fce990ee/logo/icon.png
--------------------------------------------------------------------------------
/logo/icon.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
69 |
--------------------------------------------------------------------------------
/logo/monochrome_horizontal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/publicarray/dns-resolver-infra/c0f32be0b0956088d355361a204df5b1fce990ee/logo/monochrome_horizontal.png
--------------------------------------------------------------------------------
/logo/monochrome_horizontal.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
190 |
--------------------------------------------------------------------------------
/logo/monochrome_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/publicarray/dns-resolver-infra/c0f32be0b0956088d355361a204df5b1fce990ee/logo/monochrome_icon.png
--------------------------------------------------------------------------------
/logo/monochrome_icon.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
72 |
--------------------------------------------------------------------------------
/logo/monochrome_vertical.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/publicarray/dns-resolver-infra/c0f32be0b0956088d355361a204df5b1fce990ee/logo/monochrome_vertical.png
--------------------------------------------------------------------------------
/logo/monochrome_vertical.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
185 |
--------------------------------------------------------------------------------
/logo/vertical.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/publicarray/dns-resolver-infra/c0f32be0b0956088d355361a204df5b1fce990ee/logo/vertical.png
--------------------------------------------------------------------------------
/m13253-doh/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM golang:alpine3.19 as doh-build
2 | LABEL org.opencontainers.image.source https://github.com/publicarray/dns-resolver-infra
3 | LABEL maintainer="publicarray"
4 | LABEL description="High performance DNS over HTTPS server in golang. https://github.com/m13253/dns-over-https"
5 | ENV REVISION 2
6 |
7 | ENV DOH_BUILD_DEPS git make
8 | ENV COMMIT a2b984f816f858aa5d53ef59395b9ccabf20ae2f
9 | RUN apk add --no-cache $DOH_BUILD_DEPS
10 |
11 | RUN set -x && \
12 | mkdir ~/gopath && \
13 | export GOPATH=~/gopath && \
14 | git clone https://github.com/m13253/dns-over-https.git && \
15 | cd dns-over-https && \
16 | git checkout ${COMMIT} && \
17 | make && \
18 | make install
19 | #------------------------------------------------------------------------------#
20 | FROM alpine:3.19
21 | LABEL org.opencontainers.image.source https://github.com/publicarray/dns-resolver-infra
22 |
23 | ENV DOH_RUN_DEPS curl bind-tools
24 |
25 | RUN apk add --no-cache $DOH_RUN_DEPS
26 |
27 | COPY --from=0 /usr/local/bin/doh-server /usr/local/bin/doh-server
28 |
29 | COPY entrypoint.sh /
30 | COPY doh-server.conf /etc/dns-over-https/doh-server.conf
31 |
32 | EXPOSE 3000/udp 3000/tcp
33 |
34 | RUN /usr/local/bin/doh-server -version
35 |
36 | HEALTHCHECK --start-period=5s --interval=60s \
37 | CMD curl -H 'accept: application/dns-message' 'http://127.0.0.1:3000/dns-query?dns=q80BAAABAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB' >/dev/null || exit 1
38 |
39 | ENTRYPOINT ["/entrypoint.sh"]
40 |
--------------------------------------------------------------------------------
/m13253-doh/doh-proxy-deployment.yml:
--------------------------------------------------------------------------------
1 | apiVersion: apps/v1
2 | kind: Deployment
3 | metadata:
4 | name: m13253-doh
5 | spec:
6 | selector:
7 | matchLabels:
8 | app: dns-server
9 | component: m13253-doh
10 | strategy:
11 | type: Recreate
12 | replicas: 1
13 | template:
14 | metadata:
15 | labels:
16 | app: dns-server
17 | component: m13253-doh
18 | spec:
19 | containers:
20 | - name: m13253-doh
21 | image: publicarray/m13253-doh
22 | # command: ["/entrypoint.sh"]
23 | ports:
24 | - name: dns
25 | containerPort: 3000
26 | # resources:
27 | # requests:
28 | # cpu: 100m
29 | # memory: 50Mi
30 | restartPolicy: Always
31 |
--------------------------------------------------------------------------------
/m13253-doh/doh-proxy-srv.yml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: m13253-doh
5 | labels:
6 | app: dns-server
7 | component: m13253-doh
8 | spec:
9 | selector:
10 | app: dns-server
11 | component: m13253-doh
12 | ports:
13 | - name: doh-tcp
14 | protocol: TCP
15 | port: 3000
16 | targetPort: 3000
17 | # type: ClusterIP
18 |
--------------------------------------------------------------------------------
/m13253-doh/doh-server.conf:
--------------------------------------------------------------------------------
1 | # HTTP listen port
2 | listen = [
3 | "0.0.0.0:3000",
4 | ]
5 |
6 | # TLS certification file
7 | # If left empty, plain-text HTTP will be used.
8 | # You are recommended to leave empty and to use a server load balancer (e.g.
9 | # Caddy, Nginx) and set up TLS there, because this program does not do OCSP
10 | # Stapling, which is necessary for client bootstrapping in a network
11 | # environment with completely no traditional DNS service.
12 | cert = ""
13 |
14 | # TLS private key file
15 | key = ""
16 |
17 | # HTTP path for resolve application
18 | path = "/dns-query"
19 |
20 | # Upstream DNS resolver
21 | # If multiple servers are specified, a random one will be chosen each time.
22 | upstream = [
23 | "udp:127.0.0.1:53",
24 | ]
25 |
26 | # Upstream timeout
27 | timeout = 12
28 |
29 | # Number of tries if upstream DNS fails
30 | tries = 2
31 |
32 | # Enable logging
33 | verbose = false
34 |
35 | # Enable log IP from HTTPS-reverse proxy header: X-Forwarded-For or X-Real-IP
36 | # Note: http uri/useragent log cannot be controlled by this config
37 | log_guessed_client_ip = false
38 |
--------------------------------------------------------------------------------
/m13253-doh/entrypoint.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | set -e
3 |
4 | getServiceIP () {
5 | dig "$1" +short
6 | }
7 |
8 | waitOrFail () {
9 | maxTries=24
10 | i=0
11 | while [ $i -lt $maxTries ]; do
12 | outStr="$($@)"
13 | if [ $? -eq 0 ];then
14 | echo "$outStr"
15 | return
16 | fi
17 | i=$((i+1))
18 | echo "==> waiting for a dependent service $i/$maxTries" >&2
19 | sleep 5
20 | done
21 | echo "Too many failed attempts" >&2
22 | exit 1
23 | }
24 |
25 | UNBOUND_SERVICE_HOST=${UNBOUND_SERVICE_HOST-"1.1.1.1"}
26 | UNBOUND_SERVICE_PORT=${UNBOUND_SERVICE_PORT-"53"}
27 | while getopts "h?d:" opt; do
28 | case "$opt" in
29 | h|\?) echo "-d domain lookup for service discovery"; exit 0;;
30 | d) UNBOUND_SERVICE_HOST="$(waitOrFail getServiceIP "$OPTARG")"
31 | ;;
32 | esac
33 | done
34 | shift $((OPTIND-1))
35 | export RESOLVER="$UNBOUND_SERVICE_HOST:$UNBOUND_SERVICE_PORT"
36 | echo "==> Configuring doh"
37 | sed \
38 | -e "s/\"udp:127.0.0.1:53\"/\"udp:${RESOLVER}\"/g" \
39 | -i "/etc/dns-over-https/doh-server.conf"
40 |
41 | if [ $# -eq 0 ]; then
42 | echo "doh - resolver: $RESOLVER"
43 | exec /usr/local/bin/doh-server -conf /etc/dns-over-https/doh-server.conf
44 | fi
45 |
46 | [ "$1" = '--' ] && shift
47 |
48 | exec /usr/local/bin/doh-server "$@"
49 |
--------------------------------------------------------------------------------
/namespace.yml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Namespce
3 | metadata:
4 | name: dns
5 |
--------------------------------------------------------------------------------
/nsd/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM alpine:3.19 as build
2 | LABEL org.opencontainers.image.source https://github.com/publicarray/dns-resolver-infra
3 | LABEL maintainer="publicarray"
4 | LABEL description="NSD is an authoritative only, high performance, simple and open source name server. https://www.nlnetlabs.nl/projects/nsd/"
5 | ENV REVISION 2
6 |
7 | ENV NSD_BUILD_DEPS make tar gcc musl-dev libevent-dev openssl-dev
8 |
9 | RUN apk add --no-cache $NSD_BUILD_DEPS
10 |
11 | ARG NSD_VERSION=4.8.0
12 | ARG NSD_SHA256=820da4e384721915f4bcaf7f2bed98519da563c6e4c130c742c724760ec02a0a
13 | ARG NSD_DOWNLOAD_URL=https://www.nlnetlabs.nl/downloads/nsd/nsd-${NSD_VERSION}.tar.gz
14 |
15 | RUN set -x && \
16 | mkdir -p /tmp/src && \
17 | cd /tmp/src && \
18 | wget -O nsd.tar.gz $NSD_DOWNLOAD_URL && \
19 | echo "${NSD_SHA256} *nsd.tar.gz" | sha256sum -c - && \
20 | tar xzf nsd.tar.gz && \
21 | rm -f nsd.tar.gz && \
22 | cd nsd-${NSD_VERSION} && \
23 | ./configure --enable-root-server --with-configdir=/etc/nsd \
24 | --with-user=_nsd --with-libevent \
25 | CFLAGS="-O2 -flto -fPIE -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -fstack-protector-strong -Wformat -Werror=format-security" \
26 | LDFLAGS="-Wl,-z,now -Wl,-z,relro" && \
27 | make install
28 |
29 | #------------------------------------------------------------------------------#
30 | FROM alpine:3.19
31 | LABEL org.opencontainers.image.source https://github.com/publicarray/dns-resolver-infra
32 |
33 | ENV NSD_RUN_DEPS openssl libevent shadow drill
34 | RUN apk add --no-cache $NSD_RUN_DEPS
35 |
36 | COPY --from=build /usr/local/sbin/nsd /usr/local/sbin/nsd
37 | COPY --from=build /usr/local/sbin/nsd-control-setup /usr/local/sbin/nsd-control-setup
38 | COPY --from=build /usr/local/sbin/nsd-checkconf /usr/local/sbin/nsd-checkconf
39 | COPY --from=build /usr/local/sbin/nsd-checkzone /usr/local/sbin/nsd-checkzone
40 | COPY --from=build /usr/local/sbin/nsd-control /usr/local/sbin/nsd-control
41 |
42 | RUN set -x && \
43 | groupadd _nsd && \
44 | useradd -g _nsd -s /dev/null -d /dev/null _nsd && \
45 | mkdir -p /etc/nsd/run/zonefiles /etc/service/nsd && \
46 | chown _nsd:_nsd /etc/nsd/run/zonefiles && \
47 | chown _nsd:_nsd /etc/nsd/run
48 |
49 | COPY nsd.conf /etc/nsd/nsd.conf
50 | COPY opennic.conf /etc/nsd/opennic.conf
51 | COPY entrypoint.sh /
52 |
53 | VOLUME ["/etc/nsd/run"]
54 |
55 | EXPOSE 53/udp 53/tcp
56 |
57 | RUN nsd -v
58 | RUN nsd-checkconf /etc/nsd/nsd.conf
59 |
60 | HEALTHCHECK --start-period=5s --interval=2m \
61 | CMD ["drill", "-Q", "dns.opennic.glue", "@127.0.0.1", "SOA"]
62 |
63 | CMD ["-d"]
64 |
65 | ENTRYPOINT ["/entrypoint.sh"]
66 |
--------------------------------------------------------------------------------
/nsd/entrypoint.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | set -e
3 |
4 | if [ ! -f /etc/nsd/nsd_server.pem ]; then
5 | nsd-control-setup
6 | fi
7 |
8 | [ "$1" = '--' ] && shift
9 |
10 | exec /usr/local/sbin/nsd "$@"
11 |
--------------------------------------------------------------------------------
/nsd/nsd-deployment.yml:
--------------------------------------------------------------------------------
1 | apiVersion: apps/v1
2 | kind: Deployment
3 | metadata:
4 | name: nsd
5 | spec:
6 | selector:
7 | matchLabels:
8 | app: dns-server
9 | component: nsd
10 | strategy:
11 | type: Recreate
12 | replicas: 1
13 | template:
14 | metadata:
15 | labels:
16 | app: dns-server
17 | component: nsd
18 | spec:
19 | containers:
20 | - name: nsd
21 | image: publicarray/nsd
22 | # command: ["/entrypoint.sh"]
23 | ports:
24 | - name: nsd
25 | containerPort: 53
26 | resources:
27 | requests:
28 | cpu: 100m
29 | memory: 500Mi
30 | restartPolicy: Always
31 |
--------------------------------------------------------------------------------
/nsd/nsd-srv.yml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: nsd
5 | labels:
6 | app: dns-server
7 | component: nsd
8 | spec:
9 | selector:
10 | app: dns-server
11 | component: nsd
12 | ports:
13 | - name: nsd-tcp
14 | protocol: TCP
15 | port: 53
16 | targetPort: 53
17 | - name: nsd-udp
18 | protocol: UDP
19 | port: 53
20 | targetPort: 53
21 | # type: ClusterIP
22 |
--------------------------------------------------------------------------------
/nsd/nsd.conf:
--------------------------------------------------------------------------------
1 | # https://www.nlnetlabs.nl/projects/nsd/nsd.conf.5.html
2 | # nsd.conf -- the NSD(8) configuration file, nsd.conf(5).
3 | #
4 | # Copyright (c) 2001-2011, NLnet Labs. All rights reserved.
5 | #
6 | # See LICENSE for the license.
7 | #
8 |
9 | server:
10 | # Number of NSD servers to fork. Put the number of CPUs to use here.
11 | server-count: 1
12 |
13 | # uncomment to specify specific interfaces to bind (default are the
14 | # wildcard interfaces 0.0.0.0 and ::0).
15 | # For servers with multiple IP addresses, list them one by one,
16 | # or the source address of replies could be wrong.
17 | # Use ip-transparent to be able to list addresses that turn on later.
18 | # ip-address: 1.2.3.4
19 | # ip-address: 1.2.3.4@5678
20 | # ip-address: 12fe::8ef0
21 | # ip-address: 127.0.0.1
22 | ip-address: 0.0.0.0
23 |
24 | # listen on IPv4 connections
25 | do-ip4: yes
26 |
27 | # listen on IPv6 connections
28 | do-ip6: yes
29 |
30 | # port to answer queries on. default is 53.
31 | port: 53
32 |
33 | # Verbosity level.
34 | verbosity: 0
35 |
36 | # After binding socket, drop user privileges.
37 | # can be a username, id or id.gid.
38 | username: _nsd
39 |
40 |
41 | # Run NSD in a chroot-jail.
42 | # make sure to have pidfile and database reachable from there.
43 | # by default, no chroot-jail is used.
44 | chroot: "/etc/nsd/run"
45 |
46 | # The directory where zone transfers are stored, in a subdir of it.
47 | xfrdir: "/etc/nsd/run/zonefiles"
48 |
49 | # File to store pid for nsd in.
50 | pidfile: "/etc/nsd/run/nsd.pid"
51 |
52 | # The file where secondary zone refresh and expire timeouts are kept.
53 | # If you delete this file, all secondary zones are forced to be
54 | # 'refreshing' (as if nsd got a notify). Set to "" to disable.
55 | xfrdfile: "/etc/nsd/run/ixfr.state"
56 |
57 | # the database to use
58 | # if set to "" then no disk-database is used, less memory usage.
59 | database: "/etc/nsd/run/nsd.db"
60 |
61 | # The directory for zonefile: files. The daemon chdirs here.
62 | zonesdir: "/etc/nsd/run/zonefiles"
63 |
64 | # the list of dynamically added zones.
65 | zonelistfile: "/etc/nsd/run/zone.list"
66 |
67 | # log messages to file. Default to stderr and syslog (with
68 | # facility LOG_DAEMON). stderr disappears when daemon goes to bg.
69 | # logfile: "/var/log/nsd.log"
70 |
71 | # don't answer VERSION.BIND and VERSION.SERVER CHAOS class queries
72 | hide-version: yes
73 |
74 | # statistics are produced every number of seconds. Prints to log.
75 | # Default is 0, meaning no statistics are produced.
76 | statistics: 0
77 |
78 | # use the reuseport socket option for performance. Default no.
79 | reuseport: yes
80 |
81 | # round robin rotation of records in the answer.
82 | round-robin: yes
83 |
84 | minimal-responses: no
85 |
86 | xfrd-reload-timeout: 1
87 |
88 | # write changed zonefiles to disk, every N seconds.
89 | # default is 0(disabled) or 3600(if database is "").
90 | zonefiles-write: 3600
91 |
92 | # Optional local server config
93 | # include: "/etc/nsd/server.d/*.conf"
94 |
95 | # Include optional local configs.
96 | include: "/etc/nsd/opennic.conf"
97 |
98 | # Remote control config section.
99 | remote-control:
100 | # Enable remote control with nsd-control(8) here.
101 | # set up the keys and certificates with nsd-control-setup.
102 | control-enable: yes
103 |
104 | # what interfaces are listened to for control, default is on localhost.
105 | control-interface: 127.0.0.1
106 |
107 | # port number for remote control operations (uses TLS over TCP).
108 | control-port: 8952
109 |
110 | # nsd server key file for remote control.
111 | server-key-file: "/etc/nsd/nsd_server.key"
112 |
113 | # nsd server certificate file for remote control.
114 | server-cert-file: "/etc/nsd/nsd_server.pem"
115 |
116 | # nsd-control key file.
117 | control-key-file: "/etc/nsd/nsd_control.key"
118 |
119 | # nsd-control certificate file.
120 | control-cert-file: "/etc/nsd/nsd_control.pem"
121 |
--------------------------------------------------------------------------------
/nsd/opennic.conf:
--------------------------------------------------------------------------------
1 | # https://servers.opennicproject.org/
2 | # http://opennic.glue/
3 | # https://wiki.opennic.org/opennic/t2slaved
4 | pattern:
5 | name: "opennic"
6 | # allow-notify: 45.56.115.189 NOKEY # ns0.opennic.glue
7 | # allow-notify: 45.56.116.224 NOKEY # ns0.opennic.glue
8 | allow-notify: 161.97.219.84 NOKEY # ns2.opennic.glue
9 | allow-notify: 2001:470:4212:10:0:100:53:10 NOKEY # ns2.opennic.glue
10 | # allow-notify: 104.168.144.17 NOKEY # ns3.opennic.glue
11 | # allow-notify: 2001:470:8269::53 NOKEY # ns3.opennic.glue
12 | allow-notify: 163.172.168.171 NOKEY # ns4.opennic.glue
13 | allow-notify: 2001:bc8:4400:2100::17:213 NOKEY # ns4.opennic.glue
14 | allow-notify: 94.103.153.176 NOKEY # ns5.opennic.glue
15 | allow-notify: 2a02:990:219:1:ba:1337:cafe:3 NOKEY # ns5.opennic.glue
16 | # allow-notify: 207.192.71.13 NOKEY # ns6.opennic.glue
17 | # allow-notify: 2002:cfc0:470d::1 NOKEY # ns6.opennic.glue
18 | allow-notify: 178.63.116.152 NOKEY # ns8.opennic.glue
19 | allow-notify: 2a01:4f8:141:4281::999 NOKEY # ns8.opennic.glue
20 | # allow-notify: 138.68.128.160 NOKEY # ns9.opennic.glue
21 | # allow-notify: 2a03:b0c0:1:a1::46b:a001 NOKEY # ns9.opennic.glue
22 | allow-notify: 188.226.146.136 NOKEY # ns10.opennic.glue
23 | allow-notify: 2001:470:1f04:ebf::2 NOKEY # ns10.opennic.glue
24 | # allow-notify: 45.55.97.204 NOKEY # ns11.opennic.glue
25 | # allow-notify: 2604:a880:800:a1::14c1:1 NOKEY # ns11.opennic.glue
26 | # allow-notify: 79.124.7.81 NOKEY # ns12.opennic.glue
27 | # allow-notify: 2a01:8740:1:ff13::ae67 NOKEY # ns12.opennic.glue
28 | allow-notify: 144.76.103.143 NOKEY # ns13.opennic.glue
29 | allow-notify: 2a01:4f8:192:43a5::2 NOKEY # ns13.opennic.glue
30 |
31 | # request-xfr: 45.56.115.189 NOKEY # ns0.opennic.glue
32 | # request-xfr: 45.56.116.224 NOKEY # ns0.opennic.glue
33 | request-xfr: 161.97.219.84 NOKEY # ns2.opennic.glue
34 | request-xfr: 2001:470:4212:10:0:100:53:10 NOKEY # ns2.opennic.glue
35 | # request-xfr: 104.168.144.17 NOKEY # ns3.opennic.glue
36 | # request-xfr: 2001:470:8269::53 NOKEY # ns3.opennic.glue
37 | request-xfr: 163.172.168.171 NOKEY # ns4.opennic.glue
38 | request-xfr: 2001:bc8:4400:2100::17:213 NOKEY # ns4.opennic.glue
39 | request-xfr: 94.103.153.176 NOKEY # ns5.opennic.glue
40 | request-xfr: 2a02:990:219:1:ba:1337:cafe:3 NOKEY # ns5.opennic.glue
41 | # request-xfr: 207.192.71.13 NOKEY # ns6.opennic.glue
42 | # request-xfr: 2002:cfc0:470d::1 NOKEY # ns6.opennic.glue
43 | request-xfr: 178.63.116.152 NOKEY # ns8.opennic.glue
44 | request-xfr: 2a01:4f8:141:4281::999 NOKEY # ns8.opennic.glue
45 | # request-xfr: 138.68.128.160 NOKEY # ns9.opennic.glue
46 | # request-xfr: 2a03:b0c0:1:a1::46b:a001 NOKEY # ns9.opennic.glue
47 | request-xfr: 188.226.146.136 NOKEY # ns10.opennic.glue
48 | request-xfr: 2001:470:1f04:ebf::2 NOKEY # ns10.opennic.glue
49 | # request-xfr: 45.55.97.204 NOKEY # ns11.opennic.glue
50 | # request-xfr: 2604:a880:800:a1::14c1:1 NOKEY # ns11.opennic.glue
51 | # request-xfr: 79.124.7.81 NOKEY # ns12.opennic.glue
52 | # request-xfr: 2a01:8740:1:ff13::ae67 NOKEY # ns12.opennic.glue
53 | request-xfr: 144.76.103.143 NOKEY # ns13.opennic.glue
54 | request-xfr: 2a01:4f8:192:43a5::2 NOKEY # ns13.opennic.glue
55 |
56 | pattern:
57 | name: "new-nations" # ns2.opennic.glue knows about ku -> dig @161.97.219.84 ns1.new-nations.ku | dig ku NS @161.97.219.84
58 | allow-notify: 5.45.96.220 NOKEY # ns1.new-nations.ku
59 | request-xfr: 5.45.96.220 NOKEY # ns1.new-nations.ku
60 | allow-notify: 185.82.22.133 NOKEY # ns2.new-nations.ku
61 | request-xfr: 185.82.22.133 NOKEY # ns2.new-nations.ku
62 |
63 | pattern: # nic.fur
64 | name: "fur" # dig nic.fur NS @188.40.132.212
65 | allow-notify: 188.40.132.212 NOKEY # ns8.nic.fur
66 | request-xfr: 188.40.132.212 NOKEY # ns8.nic.fur
67 | allow-notify: 178.63.26.172 NOKEY # ns10.nic.fur
68 | request-xfr: 178.63.26.172 NOKEY # ns10.nic.fur
69 | allow-notify: 2a01:4f8:141:4281::150 NOKEY # ns10.nic.fur
70 | request-xfr: 2a01:4f8:141:4281::150 NOKEY # ns10.nic.fur
71 | allow-notify: 178.63.145.230 NOKEY # ns12.nic.fur
72 | request-xfr: 178.63.145.230 NOKEY # ns12.nic.fur
73 | allow-notify: 2a01:4f8:101:3062::5:2 NOKEY # ns12.nic.fur
74 | request-xfr: 2a01:4f8:101:3062::5:2 NOKEY # ns12.nic.fur
75 | allow-notify: 151.236.24.112 NOKEY # ns13.nic.fur
76 | request-xfr: 151.236.24.112 NOKEY # ns13.nic.fur
77 | allow-notify: 178.63.145.236 NOKEY # ns15.nic.fur
78 | request-xfr: 178.63.145.236 NOKEY # ns15.nic.fur
79 | allow-notify: 2a01:4f8:221:1e01::1f:12 NOKEY # ns15.nic.fur
80 | request-xfr: 2a01:4f8:221:1e01::1f:12 NOKEY # ns15.nic.fur
81 |
82 | # dig txt tlds.opennic.glue @161.97.219.84 +short
83 | # https://wiki.opennic.org/opennic/dot
84 | zone:
85 | name: "dns.opennic.glue"
86 | zonefile: "%s.zone"
87 | include-pattern: opennic
88 | zone:
89 | name: "."
90 | zonefile: "%s.zone"
91 | include-pattern: opennic
92 | zone:
93 | name: "bbs"
94 | zonefile: "%s.zone"
95 | include-pattern: opennic
96 | zone:
97 | name: "bit"
98 | zonefile: "%s.zone"
99 | include-pattern: opennic
100 | zone:
101 | name: "chan"
102 | zonefile: "%s.zone"
103 | include-pattern: opennic
104 | zone:
105 | name: "cyb"
106 | zonefile: "%s.zone"
107 | include-pattern: opennic
108 | zone:
109 | name: "dyn"
110 | zonefile: "%s.zone"
111 | include-pattern: opennic
112 | zone:
113 | name: "epic"
114 | zonefile: "%s.zone"
115 | include-pattern: opennic
116 | # zone:
117 | # name: "free"
118 | # zonefile: "%s.zone"
119 | # include-pattern: opennic
120 | zone:
121 | name: "fur"
122 | zonefile: "%s.zone"
123 | include-pattern: fur
124 | zone:
125 | name: "geek"
126 | zonefile: "%s.zone"
127 | include-pattern: opennic
128 | zone:
129 | name: "gopher"
130 | zonefile: "%s.zone"
131 | include-pattern: opennic
132 | zone:
133 | name: "indy"
134 | zonefile: "%s.zone"
135 | include-pattern: opennic
136 | zone:
137 | name: "libre"
138 | zonefile: "%s.zone"
139 | include-pattern: opennic
140 | zone:
141 | name: "neo"
142 | zonefile: "%s.zone"
143 | include-pattern: opennic
144 | zone:
145 | name: "null"
146 | zonefile: "%s.zone"
147 | include-pattern: opennic
148 | zone:
149 | name: "o"
150 | zonefile: "%s.zone"
151 | include-pattern: opennic
152 | zone:
153 | name: "opennic.glue"
154 | zonefile: "%s.zone"
155 | include-pattern: opennic
156 | zone:
157 | name: "oss"
158 | zonefile: "%s.zone"
159 | include-pattern: opennic
160 | zone:
161 | name: "oz"
162 | zonefile: "%s.zone"
163 | include-pattern: opennic
164 | zone:
165 | name: "parody"
166 | zonefile: "%s.zone"
167 | include-pattern: opennic
168 | zone:
169 | name: "pirate"
170 | zonefile: "%s.zone"
171 | include-pattern: opennic
172 | zone:
173 | name: "ku"
174 | zonefile: "%s.zone"
175 | include-pattern: new-nations
176 | zone:
177 | name: "te"
178 | zonefile: "%s.zone"
179 | include-pattern: new-nations
180 | zone:
181 | name: "ti"
182 | zonefile: "%s.zone"
183 | include-pattern: new-nations
184 | zone:
185 | name: "uu"
186 | zonefile: "%s.zone"
187 | include-pattern: new-nations
188 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "devDependencies": {
3 | "bats": "^1.9.0",
4 | "bats-assert": "^2.0.0",
5 | "bats-support": "^0.3.0",
6 | "dockerfilelint": "^1.8.0",
7 | "dockerlint": "^0.3.9"
8 | },
9 | "scripts": {
10 | "bats": "bats"
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/test-dog.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | set +x
4 | set -e
5 |
6 | if ! command -v dog; then
7 | echo "Please install dog first:"
8 | echo "https://github.com/ogham/dog/"
9 | exit
10 | fi
11 |
12 | step() {
13 | echo "=====> $@ <====="
14 | }
15 |
16 | step 'test DNS -over-TLS:'
17 | dog -S @dot.seby.io example.com
18 | # dog -S @139.99.222.72 example.com
19 | # dog -S @45.76.113.31 example.com
20 |
21 | step 'test opennic:'
22 |
23 | # domains="opennic.glue grep.geek nic.fur be.libre register.null opennic.oz www.opennic.chan"
24 | for domain in $domains; do
25 | dog -S @dot.seby.io $domain
26 | # dog -S @139.99.222.72 $domain
27 | # dog -S @45.76.113.31 $domain
28 | done
29 |
30 | step 'test DNS-over-HTTPS'
31 | dog -H @https://doh.seby.io/dns-query example.com
32 | # dog -H @https://doh-2.seby.io/dns-query example.com
33 | dog -H @https://doh-1.seby.io/dns-query example.com
34 |
35 | step 'test for TLS 1.3'
36 | # echo "Q" | openssl s_client -connect 139.99.222.72:853 | grep TLSv1.3
37 | echo "Q" | openssl s_client -connect 45.76.113.31:853 | grep TLSv1.3
38 | # echo "Q" | openssl s_client -connect 139.99.222.72:443 | grep TLSv1.3
39 | echo "Q" | openssl s_client -connect 45.76.113.31:443 | grep TLSv1.3
40 |
41 | # step 'test dnscrypt-proxy:'
42 |
43 | # # fetch the public-resolvers.md
44 | # dnscrypt-proxy -config tests/publicarray-au.toml -show-certs
45 |
46 | # dnscrypt-proxy -config tests/publicarray-au-doh.toml &
47 | # sleep 1
48 | # dnscrypt-proxy -config tests/publicarray-au-doh.toml -resolve example.com
49 | # kill $(jobs -lp | tail)
50 | # dnscrypt-proxy -config tests/publicarray-au.toml &
51 | # sleep 1
52 | # dnscrypt-proxy -config tests/publicarray-au.toml -resolve example.com
53 | # kill $(jobs -lp | tail)
54 | # dnscrypt-proxy -config tests/publicarray-au2-doh.toml &
55 | # sleep 1
56 | # dnscrypt-proxy -config tests/publicarray-au2-doh.toml -resolve example.com
57 | # kill $(jobs -lp | tail)
58 | # dnscrypt-proxy -config tests/publicarray-au2.toml &
59 | # sleep 1
60 | # dnscrypt-proxy -config tests/publicarray-au2.toml -resolve example.com
61 | # kill $(jobs -lp | tail)
62 | # sleep 1
63 | # jobs -l
64 | # killall dnscrypt-proxy
65 | step 'All Tests Passed!'
66 |
--------------------------------------------------------------------------------
/test-doggo.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | set +x
4 | set -e
5 |
6 | if ! command -v doggo; then
7 | echo "Please install doggo first:"
8 | echo "https://github.com/mr-karan/doggo"
9 | echo "Arch: yay -S doggo-bin"
10 | echo "macOS: brew install doggo"
11 | echo "Windows: scoop install doggo"
12 | echo "source: go install github.com/mr-karan/doggo/cmd/doggo@latest"
13 | exit
14 | fi
15 |
16 | step() {
17 | echo "=====> $@ <====="
18 | }
19 |
20 | step 'test DNS -over-TLS:'
21 |
22 | doggo @tls://dot.seby.io example.com
23 | # doggo @tls://139.99.222.72 example.com
24 | # doggo @tls://45.76.113.31 example.com
25 |
26 | step 'test opennic:'
27 |
28 | # domains="opennic.glue grep.geek nic.fur be.libre register.null opennic.oz www.opennic.chan"
29 | for domain in $domains; do
30 | doggo @tls://dot.seby.io $domain
31 | # doggo @tls://139.99.222.72 $domain
32 | # doggo @tls://45.76.113.31 $domain
33 | done
34 |
35 | step 'test DNS-over-HTTPS'
36 | doggo @https://doh.seby.io/dns-query example.com
37 | doggo @https://doh-1.seby.io/dns-query example.com
38 | # doggo @https://doh-2.seby.io/dns-query example.com
39 |
40 | step 'test for TLS 1.3'
41 | # echo "Q" | openssl s_client -connect 139.99.222.72:853 | grep TLSv1.3
42 | echo "Q" | openssl s_client -connect 45.76.113.31:853 | grep TLSv1.3
43 | # echo "Q" | openssl s_client -connect 139.99.222.72:443 | grep TLSv1.3
44 | echo "Q" | openssl s_client -connect 45.76.113.31:443 | grep TLSv1.3
45 |
46 | # step 'test dnscrypt-proxy:'
47 |
48 | # fetch the public-resolvers.md
49 | # doggo example.com @sdns://AQcAAAAAAAAADDQ1Ljc2LjExMy4zMSAIVGh4i6eKXqlF6o9Fg92cgD2WcDvKQJ7v_Wq4XrQsVhsyLmRuc2NyeXB0LWNlcnQuZG5zLnNlYnkuaW8
50 | # doggo example.com @sdns://AgcAAAAAAAAADDQ1Ljc2LjExMy4zMaA-GhoPbFPz6XpJLVcIS1uYBwWe4FerFQWHb9g_2j24OCAyhv9lpl-vMghe6hOIw3OLp-N4c8kGzOPEootMwqWJiBBkb2guc2VieS5pbzo4NDQzCi9kbnMtcXVlcnk
51 | # doggo example.com @sdns://AQcAAAAAAAAAEjEzOS45OS4yMjIuNzI6ODQ0MyDR7bj6zoAmbRaE1B8qTkCL_O84QCDMYPUgXZy5FRqUYRsyLmRuc2NyeXB0LWNlcnQuZG5zLnNlYnkuaW8
52 | # doggo example.com @sdns://AgcAAAAAAAAADTEzOS45OS4yMjIuNzKgPhoaD2xT8-l6SS1XCEtbmAcFnuBXqxUFh2_YP9o9uDggMob_ZaZfrzIIXuoTiMNzi6fjeHPJBszjxKKLTMKliYgRZG9oLTIuc2VieS5pbzo0NDMKL2Rucy1xdWVyeQ
53 |
54 | step 'All Tests Passed!'
55 |
--------------------------------------------------------------------------------
/test-infra.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | set -x
4 |
5 | minikube delete
6 | minikube start
7 | # Enable DNS service: https://kubernetes.io/docs/concepts/services-networking/connect-applications-service/
8 | # kubectl --namespace=kube-system scale deployment kube-dns --replicas=1
9 |
10 | sleep 10 # Wait for API port to open
11 |
12 | kubectl create -f cloudflare-secret.yml
13 |
14 | kubectl create -f acme-init-job.yml
15 | kubectl create -f dnscrypt-wrapper/dnscrypt-init-job.yml
16 |
17 | kubectl create -f acme-cron-job.yml
18 |
19 | sleep 65 # Wait for certificate from Let's Encrypt
20 |
21 | kubectl create -f nsd/nsd-srv.yml
22 | kubectl create -f unbound/unbound-srv.yml
23 | kubectl create -f doh-proxy/doh-proxy-srv.yml
24 | kubectl create -f haproxy/haproxy-srv.yml
25 | kubectl create -f dnscrypt-wrapper/dnscrypt-srv.yml
26 |
27 | kubectl create -f nsd/nsd-deployment.yml
28 | kubectl create -f unbound/unbound-deployment.yml
29 | kubectl create -f doh-proxy/doh-proxy-deployment.yml
30 | kubectl create -f haproxy/haproxy-deployment.yml
31 | kubectl create -f dnscrypt-wrapper/dnscrypt-deployment.yml
32 |
33 | sleep 180 #300# Wait for deployment
34 |
35 | kubectl get nodes
36 | kubectl get jobs
37 | kubectl get deployments
38 | kubectl get services
39 | kubectl get pods -o wide
40 | kubectl get all -l app=dns-server
41 |
42 | minikube ip
43 | kubectl get services
44 | kubectl logs job/dnscrypt-init
45 | minikube service dnscrypt --url
46 | minikube service haproxy --url
47 |
--------------------------------------------------------------------------------
/test.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # set +x
4 | # set -e
5 |
6 | # docker run -it --rm bats/bats:latest --tap
7 | # docker run -it -v "$PWD":/opt/bats" --workdir /opt/bats bats/bats:latest test
8 |
9 | npm i --legacy-peer-deps
10 |
11 | if ! command -v kdig; then
12 | echo "Please install knot first:"
13 | echo "https://www.knot-dns.cz/"
14 | echo "Arch: pacman -S knot"
15 | echo "macOS: brew install knot"
16 | exit
17 | fi
18 |
19 | npm run bats tests
20 |
21 | exit
22 |
23 | step() {
24 | echo "=====> $@ <====="
25 | }
26 | # kdig -d @139.99.222.72 +tls-ca +tls-host=dot.seby.io example.com
27 | # kdig -d @45.76.113.31 +tls-ca +tls-host=dot.seby.io example.com
28 |
29 | step 'test DNS -over-TLS:'
30 | # kdig @139.99.222.72 +tls-ca +tls-host=dot.seby.io example.com
31 | kdig @45.76.113.31 +tls-ca +tls-host=dot.seby.io example.com
32 |
33 | step 'test opennic:'
34 |
35 | domains="opennic.glue grep.geek nic.fur be.libre register.null opennic.oz www.opennic.chan"
36 | # step '139.99.222.72'
37 | # for domain in $domains; do
38 | # kdig @139.99.222.72 +short +tls-ca +tls-host=dot.seby.io $domain
39 | # done
40 | step '45.76.113.31'
41 | for domain in $domains; do
42 | kdig @45.76.113.31 +short +tls-ca +tls-host=dot.seby.io $domain
43 | done
44 | # curl -v 'https://doh-2.seby.io/dns-query?dns=q80BAAABAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB' | hexdump -C
45 | # curl -v 'https://doh.seby.io:8443/dns-query?dns=q80BAAABAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB' | hexdump -C
46 |
47 | step 'test DNS-over-HTTPS'
48 | # curl -so /dev/null --doh-url https://doh.seby.io:8443/dns-query https://example.com
49 | curl 'https://doh.seby.io/dns-query?dns=q80BAAABAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB' | hexdump -C
50 | curl 'https://doh-1.seby.io:443/dns-query?dns=q80BAAABAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB' | hexdump -C
51 | # curl 'https://doh-2.seby.io:443/dns-query?dns=q80BAAABAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB' | hexdump -C
52 | curl -H 'content-type: application/dns-message' 'https://doh.seby.io/dns-query?dns=q80BAAABAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB' | hexdump -C
53 | curl -H 'content-type: application/dns-message' 'https://doh-1.seby.io/dns-query?dns=q80BAAABAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB' | hexdump -C
54 | # curl -H 'content-type: application/dns-message' 'https://doh-2.seby.io/dns-query?dns=q80BAAABAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB' | hexdump -C
55 | curl --doh-url https://doh.seby.io/dns-query https://ip.seby.io
56 | curl --doh-url https://doh-1.seby.io/dns-query https://ip.seby.io
57 | # curl --doh-url https://doh-2.seby.io/dns-query https://ip.seby.io
58 |
59 | step 'test for TLS 1.3'
60 | # echo "Q" | openssl s_client -connect 139.99.222.72:853 | grep TLSv1.3
61 | echo "Q" | openssl s_client -connect 45.76.113.31:853 | grep TLSv1.3
62 | # echo "Q" | openssl s_client -connect 139.99.222.72:443 | grep TLSv1.3
63 | echo "Q" | openssl s_client -connect 45.76.113.31:8443 | grep TLSv1.3
64 |
65 | # step 'test dnscrypt-proxy:'
66 |
67 | # echo doggo install
68 |
69 | # doggo example.com @sdns://AQcAAAAAAAAADDQ1Ljc2LjExMy4zMSAIVGh4i6eKXqlF6o9Fg92cgD2WcDvKQJ7v_Wq4XrQsVhsyLmRuc2NyeXB0LWNlcnQuZG5zLnNlYnkuaW8
70 | # doggo example.com @sdns://AgcAAAAAAAAADDQ1Ljc2LjExMy4zMaA-GhoPbFPz6XpJLVcIS1uYBwWe4FerFQWHb9g_2j24OCAyhv9lpl-vMghe6hOIw3OLp-N4c8kGzOPEootMwqWJiBBkb2guc2VieS5pbzo4NDQzCi9kbnMtcXVlcnk
71 | # doggo example.com @sdns://AQcAAAAAAAAAEjEzOS45OS4yMjIuNzI6ODQ0MyDR7bj6zoAmbRaE1B8qTkCL_O84QCDMYPUgXZy5FRqUYRsyLmRuc2NyeXB0LWNlcnQuZG5zLnNlYnkuaW8
72 | # doggo example.com @sdns://AgcAAAAAAAAADTEzOS45OS4yMjIuNzKgPhoaD2xT8-l6SS1XCEtbmAcFnuBXqxUFh2_YP9o9uDggMob_ZaZfrzIIXuoTiMNzi6fjeHPJBszjxKKLTMKliYgRZG9oLTIuc2VieS5pbzo0NDMKL2Rucy1xdWVyeQ
73 |
74 | # fetch the public-resolvers.md
75 | # dnscrypt-proxy -config tests/publicarray-au.toml -show-certs
76 |
77 | # dnscrypt-proxy -config tests/publicarray-au-doh.toml &
78 | # sleep 1
79 | # dnscrypt-proxy -config tests/publicarray-au-doh.toml -resolve example.com
80 | # kill $(jobs -lp | tail)
81 | # dnscrypt-proxy -config tests/publicarray-au.toml &
82 | # sleep 1
83 | # dnscrypt-proxy -config tests/publicarray-au.toml -resolve example.com
84 | # kill $(jobs -lp | tail)
85 | # dnscrypt-proxy -config tests/publicarray-au2-doh.toml &
86 | # sleep 1
87 | # dnscrypt-proxy -config tests/publicarray-au2-doh.toml -resolve example.com
88 | # kill $(jobs -lp | tail)
89 | # dnscrypt-proxy -config tests/publicarray-au2.toml &
90 | # sleep 1
91 | # dnscrypt-proxy -config tests/publicarray-au2.toml -resolve example.com
92 | # kill $(jobs -lp | tail)
93 | # sleep 1
94 | # jobs -l
95 | # killall dnscrypt-proxy
96 | step 'All Tests Passed!'
97 |
--------------------------------------------------------------------------------
/tests/dnscrypt.bats.old:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bats
2 | load ../node_modules/bats-support/load.bash
3 | load ../node_modules/bats-assert/load.bash
4 |
5 | # https://dnscrypt.info/stamps/
6 |
7 | #@test "139.99.222.72 dnscrypt" {
8 | # run doggo example.com @sdns://AQcAAAAAAAAAEjEzOS45OS4yMjIuNzI6ODQ0MyDR7bj6zoAmbRaE1B8qTkCL_O84QCDMYPUgXZy5FRqUYRsyLmRuc2NyeXB0LWNlcnQuZG5zLnNlYnkuaW8
9 | # assert_output -p "example.com."
10 | #}
11 | #@test "139.99.222.72 DNS-over-HTTPS" {
12 | # run doggo example.com @sdns://AgcAAAAAAAAADTEzOS45OS4yMjIuNzKgPhoaD2xT8-l6SS1XCEtbmAcFnuBXqxUFh2_YP9o9uDggMob_ZaZfrzIIXuoTiMNzi6fjeHPJBszjxKKLTMKliYgRZG9oLTIuc2VieS5pbzo0NDMKL2Rucy1xdWVyeQ
13 | # assert_output -p "example.com."
14 | #}
15 |
16 | @test "45.76.113.31 dnscrypt" {
17 | run doggo example.com @sdns://AQcAAAAAAAAADDQ1Ljc2LjExMy4zMSAIVGh4i6eKXqlF6o9Fg92cgD2WcDvKQJ7v_Wq4XrQsVhsyLmRuc2NyeXB0LWNlcnQuZG5zLnNlYnkuaW8
18 | assert_output -p "example.com."
19 | }
20 | @test "45.76.113.31 DNS-over-HTTPS" {
21 | run doggo example.com @sdns://AgcAAAAAAAAADDQ1Ljc2LjExMy4zMaA-GhoPbFPz6XpJLVcIS1uYBwWe4FerFQWHb9g_2j24OCAyhv9lpl-vMghe6hOIw3OLp-N4c8kGzOPEootMwqWJiBBkb2guc2VieS5pbzo4NDQzCi9kbnMtcXVlcnk
22 | assert_output -p "example.com."
23 | }
24 |
--------------------------------------------------------------------------------
/tests/doh.bats:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bats
2 | load ../node_modules/bats-support/load.bash
3 | load ../node_modules/bats-assert/load.bash
4 |
5 | exampledotcom="q80BAAABAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB"
6 |
7 | #@test "139.99.222.72 GET DNS-over-HTTPS" {
8 | # run curl "https://doh-2.seby.io/dns-query?dns=$exampledotcom"
9 | # assert_success
10 | #}
11 |
12 |
13 | #@test "139.99.222.72 GET with content-type DNS-over-HTTPS" {
14 | # run curl -H 'content-type: application/dns-message' "https://doh-2.seby.io/dns-query?dns=$exampledotcom"
15 | # assert_success
16 | #}
17 |
18 | #@test "139.99.222.72 curl-url DNS-over-HTTPS" {
19 | # run curl --doh-url https://doh-2.seby.io/dns-query https://ip.seby.io
20 | # assert_success
21 | #}
22 |
23 | @test "45.76.113.31 GET DNS-over-HTTPS" {
24 | run curl "https://doh-1.seby.io/dns-query?dns=$exampledotcom"
25 | assert_success
26 | }
27 |
28 | @test "45.76.113.31 GET with content-type DNS-over-HTTPS" {
29 | run curl -H 'content-type: application/dns-message' "https://doh-1.seby.io/dns-query?dns=$exampledotcom"
30 | assert_success
31 | }
32 |
33 | @test "45.76.113.31 curl-url DNS-over-HTTPS" {
34 | run curl --doh-url https://doh-1.seby.io/dns-query https://ip.seby.io
35 | assert_success
36 | }
37 |
--------------------------------------------------------------------------------
/tests/dot.bats:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bats
2 | load ../node_modules/bats-support/load.bash
3 | load ../node_modules/bats-assert/load.bash
4 |
5 | #@test "139.99.222.72 DNS-over-TLS online" {
6 | # run kdig @139.99.222.72 +tls-ca +tls-host=dot.seby.io example.com
7 | # assert_success
8 | # assert_output -p "NOERROR;"
9 | #}
10 |
11 | @test "45.76.113.31 DNS-over-TLS online" {
12 | run kdig @45.76.113.31 +tls-ca +tls-host=dot.seby.io example.com
13 | assert_success
14 | assert_output -p "NOERROR;"
15 | }
16 |
17 |
--------------------------------------------------------------------------------
/tests/opennic.bats:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bats
2 | load ../node_modules/bats-support/load.bash
3 | load ../node_modules/bats-assert/load.bash
4 |
5 | domains="opennic.glue grep.geek nic.fur be.libre register.null opennic.oz www.opennic.chan"
6 |
7 | #@test "139.99.222.72 opennic.glue DNS-over-TLS" {
8 | # run kdig @139.99.222.72 +tls-ca +tls-host=dot.seby.io opennic.glue
9 | # assert_success
10 | # assert_output -p "NOERROR;"
11 | #}
12 | @test "45.76.113.31 opennic.glue DNS-over-TLS" {
13 | run kdig @45.76.113.31 +tls-ca +tls-host=dot.seby.io opennic.glue
14 | assert_success
15 | assert_output -p "NOERROR;"
16 | }
17 |
18 | #@test "139.99.222.72 grep.geek DNS-over-TLS" {
19 | # run kdig @139.99.222.72 +tls-ca +tls-host=dot.seby.io grep.geek
20 | # assert_success
21 | # assert_output -p "NOERROR;"
22 | #}
23 | @test "45.76.113.31 grep.geek DNS-over-TLS" {
24 | run kdig @45.76.113.31 +tls-ca +tls-host=dot.seby.io grep.geek
25 | assert_success
26 | assert_output -p "NOERROR;"
27 | }
28 |
29 |
30 | #@test "139.99.222.72 nic.fur DNS-over-TLS" {
31 | # run kdig @139.99.222.72 +tls-ca +tls-host=dot.seby.io nic.fur
32 | # assert_success
33 | # assert_output -p "NOERROR;"
34 | #}
35 | @test "45.76.113.31 nic.fur DNS-over-TLS" {
36 | run kdig @45.76.113.31 +tls-ca +tls-host=dot.seby.io nic.fur
37 | assert_success
38 | assert_output -p "NOERROR;"
39 | }
40 |
41 | #@test "139.99.222.72 be.libre DNS-over-TLS" {
42 | # run kdig @139.99.222.72 +tls-ca +tls-host=dot.seby.io be.libre
43 | # assert_success
44 | # assert_output -p "NOERROR;"
45 | #}
46 | @test "45.76.113.31 be.libre DNS-over-TLS" {
47 | run kdig @45.76.113.31 +tls-ca +tls-host=dot.seby.io be.libre
48 | assert_success
49 | assert_output -p "NOERROR;"
50 | }
51 |
52 |
53 | #@test "139.99.222.72 register.null DNS-over-TLS" {
54 | # run kdig @139.99.222.72 +tls-ca +tls-host=dot.seby.io register.null
55 | # assert_success
56 | # assert_output -p "NOERROR;"
57 | #}
58 | @test "45.76.113.31 register.null DNS-over-TLS" {
59 | run kdig @45.76.113.31 +tls-ca +tls-host=dot.seby.io register.null
60 | assert_success
61 | assert_output -p "NOERROR;"
62 | }
63 |
64 | #@test "139.99.222.72 opennic.oz DNS-over-TLS" {
65 | # run kdig @139.99.222.72 +tls-ca +tls-host=dot.seby.io opennic.oz
66 | # assert_success
67 | # assert_output -p "NOERROR;"
68 | #}
69 | @test "45.76.113.31 opennic.oz DNS-over-TLS" {
70 | run kdig @45.76.113.31 +tls-ca +tls-host=dot.seby.io opennic.oz
71 | assert_success
72 | assert_output -p "NOERROR;"
73 | }
74 |
75 | #@test "139.99.222.72 www.opennic.chan DNS-over-TLS" {
76 | # run kdig @139.99.222.72 +tls-ca +tls-host=dot.seby.io www.opennic.chan
77 | # assert_success
78 | # assert_output -p "NOERROR;"
79 | #}
80 | @test "45.76.113.31 www.opennic.chan DNS-over-TLS" {
81 | run kdig @45.76.113.31 +tls-ca +tls-host=dot.seby.io www.opennic.chan
82 | assert_success
83 | assert_output -p "NOERROR;"
84 | }
85 |
--------------------------------------------------------------------------------
/tests/publicarray-au-doh.toml:
--------------------------------------------------------------------------------
1 | server_names = ['publicarray-au2-doh']
2 | listen_addresses = ['127.0.0.1:4320']
3 |
4 | [sources]
5 |
6 | ## An example of a remote source from https://github.com/DNSCrypt/dnscrypt-resolvers
7 |
8 | [sources.'public-resolvers']
9 | urls = ['https://raw.githubusercontent.com/DNSCrypt/dnscrypt-resolvers/master/v2/public-resolvers.md', 'https://download.dnscrypt.info/resolvers-list/v2/public-resolvers.md']
10 | cache_file = '/tmp/public-resolvers.md'
11 | minisign_key = 'RWQf6LRCGA9i53mlYecO4IzT51TGPpvWucNSCh1CBM0QTaLn73Y7GFO3'
12 | prefix = ''
13 |
14 |
--------------------------------------------------------------------------------
/tests/publicarray-au.toml:
--------------------------------------------------------------------------------
1 | server_names = ['publicarray-au']
2 | listen_addresses = ['127.0.0.1:4321']
3 |
4 | [sources]
5 |
6 | ## An example of a remote source from https://github.com/DNSCrypt/dnscrypt-resolvers
7 |
8 | [sources.'public-resolvers']
9 | urls = ['https://raw.githubusercontent.com/DNSCrypt/dnscrypt-resolvers/master/v2/public-resolvers.md', 'https://download.dnscrypt.info/resolvers-list/v2/public-resolvers.md']
10 | cache_file = '/tmp/public-resolvers.md'
11 | minisign_key = 'RWQf6LRCGA9i53mlYecO4IzT51TGPpvWucNSCh1CBM0QTaLn73Y7GFO3'
12 | prefix = ''
13 |
14 |
--------------------------------------------------------------------------------
/tests/publicarray-au2-doh.toml:
--------------------------------------------------------------------------------
1 | server_names = ['publicarray-au2-doh']
2 | listen_addresses = ['127.0.0.1:4322']
3 |
4 | [sources]
5 |
6 | ## An example of a remote source from https://github.com/DNSCrypt/dnscrypt-resolvers
7 |
8 | [sources.'public-resolvers']
9 | urls = ['https://raw.githubusercontent.com/DNSCrypt/dnscrypt-resolvers/master/v2/public-resolvers.md', 'https://download.dnscrypt.info/resolvers-list/v2/public-resolvers.md']
10 | cache_file = '/tmp/public-resolvers.md'
11 | minisign_key = 'RWQf6LRCGA9i53mlYecO4IzT51TGPpvWucNSCh1CBM0QTaLn73Y7GFO3'
12 | prefix = ''
13 |
14 |
--------------------------------------------------------------------------------
/tests/publicarray-au2.toml:
--------------------------------------------------------------------------------
1 | server_names = ['publicarray-au2']
2 | listen_addresses = ['127.0.0.1:4323']
3 |
4 | [sources]
5 |
6 | ## An example of a remote source from https://github.com/DNSCrypt/dnscrypt-resolvers
7 |
8 | [sources.'public-resolvers']
9 | urls = ['https://raw.githubusercontent.com/DNSCrypt/dnscrypt-resolvers/master/v2/public-resolvers.md', 'https://download.dnscrypt.info/resolvers-list/v2/public-resolvers.md']
10 | cache_file = '/tmp/public-resolvers.md'
11 | minisign_key = 'RWQf6LRCGA9i53mlYecO4IzT51TGPpvWucNSCh1CBM0QTaLn73Y7GFO3'
12 | prefix = ''
13 |
14 |
--------------------------------------------------------------------------------
/tests/tls.bats:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bats
2 | load ../node_modules/bats-support/load.bash
3 | load ../node_modules/bats-assert/load.bash
4 |
5 | openssl_client() {
6 | echo "Q" | openssl s_client -connect $@
7 | }
8 |
9 | #@test "139.99.222.72 TLS 1.3 support DNS-over-TLS" {
10 | # run openssl_client 139.99.222.72:853
11 | # assert_output -p "TLSv1.3"
12 | #}
13 |
14 | #@test "139.99.222.72 TLS 1.3 support DNS-over-HTTPS" {
15 | # run openssl_client 139.99.222.72:443
16 | # assert_output -p "TLSv1.3"
17 | #}
18 |
19 | @test "45.76.113.31 TLS 1.3 support DNS-over-TLS" {
20 | run openssl_client 45.76.113.31:853
21 | assert_output -p "TLSv1.3"
22 | }
23 |
24 | @test "45.76.113.31 TLS 1.3 support DNS-over-HTTPS" {
25 | run openssl_client 45.76.113.31:443
26 | assert_output -p "TLSv1.3"
27 | }
28 |
--------------------------------------------------------------------------------
/unbound/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM alpine:3.19 as build
2 | LABEL org.opencontainers.image.source https://github.com/publicarray/dns-resolver-infra
3 | ENV REVISION 9
4 |
5 | ENV UNBOUND_BUILD_DEPS expat-dev file gcc libevent-dev openssl-dev make musl-dev nghttp2-dev
6 |
7 | RUN apk --no-cache add $UNBOUND_BUILD_DEPS
8 |
9 | ARG UNBOUND_VERSION=1.20.0
10 | ARG UNBOUND_SHA256=56b4ceed33639522000fd96775576ddf8782bb3617610715d7f1e777c5ec1dbf
11 | ARG UNBOUND_DOWNLOAD_URL=https://nlnetlabs.nl/downloads/unbound/unbound-${UNBOUND_VERSION}.tar.gz
12 |
13 | RUN set -x && \
14 | mkdir -p /tmp/src && \
15 | cd /tmp/src && \
16 | wget -O unbound.tar.gz $UNBOUND_DOWNLOAD_URL && \
17 | echo "${UNBOUND_SHA256} *unbound.tar.gz" | sha256sum -c - && \
18 | tar xzf unbound.tar.gz && \
19 | rm -f unbound.tar.gz && \
20 | cd unbound-${UNBOUND_VERSION} && \
21 | ./configure --with-conf-file=/etc/unbound/unbound.conf --with-run-dir=/etc/unbound \
22 | --with-pthreads --with-username=_unbound --with-libevent --with-libnghttp2 \
23 | CFLAGS="-O2 -flto -fPIE -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -fstack-protector-strong -Wformat -Werror=format-security" \
24 | LDFLAGS="-Wl,-z,now -Wl,-z,relro" && \
25 | make install && \
26 | ls /usr/local/lib/
27 |
28 | #------------------------------------------------------------------------------#
29 | FROM alpine:3.19
30 | LABEL org.opencontainers.image.source https://github.com/publicarray/dns-resolver-infra
31 |
32 | ENV UNBOUND_RUN_DEPS expat libevent openssl runit shadow drill wget bc ca-certificates nghttp2-libs
33 |
34 | # https://github.com/NLnetLabs/unbound/blob/master/configure#L2852
35 | # https://archlinux.pkgs.org/rolling/archlinux-extra-x86_64/unbound-1.20.0-1-x86_64.pkg.tar.zst.html
36 | ARG LIBUNBOUND_CURRENT=8
37 | ARG LIBUNBOUND_AGE=1
38 | ARG LIBUNBOUND_REVISION=27
39 |
40 | # {LIBUNBOUND_CURRENT}.{LIBUNBOUND_AGE}.{LIBUNBOUND_REVISION}
41 | ARG LIBUNBOUND_VERSION=${LIBUNBOUND_CURRENT}.${LIBUNBOUND_AGE}.${LIBUNBOUND_REVISION}
42 |
43 | RUN apk add --no-cache $UNBOUND_RUN_DEPS
44 |
45 | COPY --from=build /usr/local/sbin/unbound /usr/local/sbin/unbound
46 | COPY --from=build /usr/local/sbin/unbound-checkconf /usr/local/sbin/unbound-checkconf
47 | COPY --from=build /usr/local/sbin/unbound-control /usr/local/sbin/unbound-control
48 | COPY --from=build /usr/local/sbin/unbound-host /usr/local/sbin/unbound-host
49 | COPY --from=build /usr/local/sbin/unbound-anchor /usr/local/sbin/unbound-anchor
50 | COPY --from=build /usr/local/sbin/unbound-control-setup /usr/local/sbin/unbound-control-setup
51 | COPY --from=build /usr/local/lib/libunbound.so.${LIBUNBOUND_VERSION} /usr/local/lib/libunbound.so.${LIBUNBOUND_VERSION}
52 |
53 | RUN set -x && \
54 | cd /usr/local/lib/ && \
55 | ln -sf libunbound.so.${LIBUNBOUND_VERSION} libunbound.so.${LIBUNBOUND_CURRENT} && \
56 | ln -sf libunbound.so.${LIBUNBOUND_VERSION} libunbound.so && \
57 | cd && \
58 | groupadd _unbound && \
59 | useradd -g _unbound -s /dev/null -d /dev/null _unbound && \
60 | mkdir -p /etc/service/unbound /etc/unbound/run && \
61 | unbound-anchor -a /etc/unbound/run/root.key || true && \
62 | chown _unbound:_unbound /etc/unbound/run && \
63 | chown _unbound:_unbound /etc/unbound/run/root.key && \
64 | wget -O /etc/unbound/root.hints https://www.internic.net/domain/named.root \
65 | update-ca-certificates 2> /dev/null || true
66 |
67 | COPY unbound.conf /etc/unbound/unbound.conf
68 | COPY unbound.sh /etc/service/unbound/run
69 | COPY entrypoint.sh /
70 |
71 | EXPOSE 53/udp 53/tcp
72 | EXPOSE 4949/tcp
73 | EXPOSE 853/tcp
74 |
75 | RUN unbound -h || true
76 | RUN unbound-checkconf /etc/unbound/unbound.conf || true
77 |
78 | HEALTHCHECK --start-period=1m --interval=2m \
79 | CMD ["drill", "-D", "-Q", ".", "@127.0.0.1", "SOA"]
80 |
81 | ENTRYPOINT ["/entrypoint.sh"]
82 |
83 | # Metadata
84 | LABEL org.opencontainers.image.title="unbound" \
85 | org.opencontainers.image.description="Unbound is a validating, recursive, caching DNS resolver." \
86 | org.opencontainers.image.url="https://nlnetlabs.nl/projects/unbound/about/" \
87 | org.opencontainers.image.documentation="https://nlnetlabs.nl/documentation/unbound/" \
88 | org.opencontainers.image.source="https://nlnetlabs.nl/svn/unbound/" \
89 | org.opencontainers.image.authors="publicarray" \
90 | org.opencontainers.image.version=${UNBOUND_VERSION}
91 |
--------------------------------------------------------------------------------
/unbound/entrypoint.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | set -e
3 |
4 | getServiceIP () {
5 | drill -4 "$1" | awk '/ANSWER SECTION/ {print;getline;print}' | grep -oE '(([0-9]{1,3})\.){3}(1?[0-9]{1,3})'
6 | }
7 |
8 | waitOrFail () {
9 | maxTries=24
10 | i=0
11 | while [ $i -lt $maxTries ]; do
12 | outStr="$($@)"
13 | if [ $? -eq 0 ];then
14 | echo "$outStr"
15 | return
16 | fi
17 | i=$((i+1))
18 | echo "==> waiting for a dependent service $i/$maxTries" >&2
19 | sleep 5
20 | done
21 | echo "Too many failed attempts" >&2
22 | exit 1
23 | }
24 |
25 | #------------------------ Optional add munin statistics -----------------------#
26 | munin() {
27 | echo "==> Installing munin-node"
28 | apk update
29 | apk add munin-node
30 | mkdir -p /etc/munin/plugin-state
31 | echo "==> Installing contrib/unbound_munin_"
32 | wget https://raw.githubusercontent.com/NLnetLabs/unbound/master/contrib/unbound_munin_ -O /etc/munin/unbound_munin_
33 | chmod +x /etc/munin/unbound_munin_
34 | ln -s /etc/munin/unbound_munin_ /etc/munin/plugins/unbound_munin_by_class
35 | ln -s /etc/munin/unbound_munin_ /etc/munin/plugins/unbound_munin_by_flags
36 | ln -s /etc/munin/unbound_munin_ /etc/munin/plugins/unbound_munin_by_opcode
37 | ln -s /etc/munin/unbound_munin_ /etc/munin/plugins/unbound_munin_by_rcode
38 | ln -s /etc/munin/unbound_munin_ /etc/munin/plugins/unbound_munin_by_type
39 | ln -s /etc/munin/unbound_munin_ /etc/munin/plugins/unbound_munin_histogram
40 | ln -s /etc/munin/unbound_munin_ /etc/munin/plugins/unbound_munin_hits
41 | ln -s /etc/munin/unbound_munin_ /etc/munin/plugins/unbound_munin_memory
42 | ln -s /etc/munin/unbound_munin_ /etc/munin/plugins/unbound_munin_queue
43 | echo "==> Configuring munin-node"
44 | groupadd _munin-node
45 | useradd -g _munin-node -s /dev/null -d /dev/null _munin-node
46 | chown -R _munin-node:_munin-node /etc/munin/
47 | sed \
48 | -re "s/user\\s{0,}\\root\\w/user _munin-node/" \
49 | -re "s/group\\s{0,}\\root\\w/group _munin-node/" \
50 | -i "/etc/munin/munin-node.conf"
51 | # Allow all connections (we are in a nat environment)
52 | echo "allow .*" >> /etc/munin/munin-node.conf
53 | # enable tls
54 | openssl req -x509 -nodes -sha256 -subj '/CN=localhost' -newkey rsa:4096 \
55 | -keyout /etc/ssl/munin.key \
56 | -out /etc/ssl/munin.pem \
57 | -days 999999
58 | echo "tls enabled" >> /etc/munin/munin-node.conf
59 | echo "tls_verify_certificate no" >> /etc/munin/munin-node.conf
60 | echo "tls_private_key /etc/ssl/munin.key" >> /etc/munin/munin-node.conf
61 | echo "tls_certificate /etc/ssl/munin.pem" >> /etc/munin/munin-node.conf
62 |
63 | cat << EOF > /etc/munin/plugin-conf.d/local.conf
64 | [unbound*]
65 | user root
66 | env.statefile /etc/munin/plugin-state/unbound-state
67 | env.unbound_conf /etc/unbound/unbound.conf
68 | env.unbound_control /usr/local/sbin/unbound-control
69 | env.spoof_warn 1000
70 | env.spoof_crit 100000
71 | EOF
72 |
73 | echo "==> Configuring unbound"
74 | sed \
75 | -re "s/# statistics-interval:.*/statistics-interval: 0/" \
76 | -re "s/# extended-statistics:.*/extended-statistics: yes/" \
77 | -re "s/# statistics-cumulative:.*/statistics-cumulative: no/" \
78 | -i "/etc/unbound/unbound.conf"
79 |
80 | echo "==> Done munin-node"
81 | /usr/sbin/munin-node &
82 | }
83 |
84 | usage() {
85 | echo "-d [domain name] domain lookup for service discovery"
86 | echo "-m setup munin node"
87 | exit 0
88 | }
89 |
90 | optimise_unbound_memory() {
91 | reserved=25
92 | memoryMB=$(( $( (grep -F MemAvailable /proc/meminfo || grep -F MemTotal /proc/meminfo) | sed 's/[^0-9]//g' ) / 1024 ))
93 | # https://fabiokung.com/2014/03/13/memory-inside-linux-containers/
94 | dokerMemoryLimitMB=0
95 | if [ -f "/sys/fs/cgroup/memory/memory.limit_in_bytes" ]; then
96 | dokerMemoryLimitMB=$(($(( $(cat /sys/fs/cgroup/memory/memory.limit_in_bytes) / 1024)) / 1024))
97 | elif [ -f "/sys/fs/cgroup/memory.max" ]; then
98 | dokerMemoryLimitMB=$(($(( $(cat /sys/fs/cgroup/memory.max) / 1024)) / 1024))
99 | fi
100 |
101 | if [ $dokerMemoryLimitMB -gt 0 ] && [ $dokerMemoryLimitMB -le $memoryMB ]; then
102 | memoryMB=$dokerMemoryLimitMB
103 | fi
104 |
105 | if [ $memoryMB -le $reserved ]; then
106 | echo "Not enough memory" >&2
107 | exit 1
108 | fi
109 | memory=$(($((memoryMB / 4)) - reserved))
110 |
111 | nproc=$(nproc)
112 | if [ "$nproc" -gt 1 ]; then
113 | threads=$((nproc - 1))
114 | else
115 | threads=1
116 | fi
117 |
118 | sed \
119 | -re "s/num-threads:\\s{0,}\\d{1,}\\w/num-threads: ${threads}/" \
120 | -re "s/msg-cache-slabs:\\s{0,}\\d{1,}\\w/msg-cache-size: ${threads}/" \
121 | -re "s/rrset-cache-slabs:\\s{0,}\\d{1,}\\w/rrset-cache-slabs: ${threads}/" \
122 | -re "s/key-cache-slabs:\\s{0,}\\d{1,}\\w/key-cache-slabs: ${threads}/" \
123 | -re "s/infra-cache-slabs:\\s{0,}\\d{1,}\\w/infra-cache-slabs: ${threads}/" \
124 | -re "s/msg-cache-size:\\s{0,}\\d{1,}\\w/msg-cache-size: ${memory}m/" \
125 | -re "s/rrset-cache-size:\\s{0,}\\d{1,}\\w/rrset-cache-size: $((memory * 2))m/" \
126 | -re "s/key-cache-size:\\s{0,}\\d{1,}\\w/key-cache-size: $((memory / 2))m/" \
127 | -re "s/neg-cache-size:\\s{0,}\\d{1,}\\w/neg-cache-size: $((memory / 2))m/" \
128 | -i "/etc/unbound/unbound.conf"
129 |
130 | if [ -n "$NSD_SERVICE_HOST" ]; then
131 | export NSD_SERVICE="${NSD_SERVICE_HOST}@${NSD_SERVICE_PORT}"
132 | echo "==> Info: NSD_SERVICE=$NSD_SERVICE"
133 | sed -e "s/stub-addr: \"127.0.0.1@552\"/stub-addr: \"${NSD_SERVICE}\"/g" \
134 | -i "/etc/unbound/unbound.conf"
135 | else
136 | echo "==> Info: NSD_SERVICE_HOST is not defined"
137 | fi
138 | }
139 |
140 | while getopts "h?d:m" opt; do
141 | case "$opt" in
142 | h|\?) usage;;
143 | d) NSD_SERVICE_HOST="$(waitOrFail getServiceIP "$OPTARG")"
144 | ;;
145 | m) munin;;
146 | esac
147 | done
148 |
149 | NSD_SERVICE_HOST=${NSD_SERVICE_HOST-""}
150 | NSD_SERVICE_PORT=${NSD_SERVICE_PORT-"53"}
151 |
152 | shift $((OPTIND-1))
153 | if [ ! -f /etc/unbound/unbound_server.pem ]; then
154 | unbound-control-setup
155 | fi
156 | optimise_unbound_memory
157 | echo "==> Done configuring unbound"
158 |
159 | if [ "$1" = '--' ] && shift; then
160 | /sbin/runsvdir -P /etc/service &
161 | exec "$@"
162 | fi
163 |
164 | exec /sbin/runsvdir -P /etc/service
165 |
--------------------------------------------------------------------------------
/unbound/unbound-deployment.yml:
--------------------------------------------------------------------------------
1 | apiVersion: apps/v1
2 | kind: Deployment
3 | metadata:
4 | name: unbound
5 | spec:
6 | selector:
7 | matchLabels:
8 | app: dns-server
9 | component: unbound
10 | strategy:
11 | type: Recreate
12 | replicas: 1
13 | template:
14 | metadata:
15 | labels:
16 | app: dns-server
17 | component: unbound
18 | spec:
19 | containers:
20 | - name: unbound
21 | image: publicarray/unbound
22 | # command: ["/entrypoint.sh"]
23 | ports:
24 | - name: dns
25 | containerPort: 53
26 | resources:
27 | requests:
28 | cpu: 100m
29 | memory: 300Mi
30 | restartPolicy: Always
31 |
--------------------------------------------------------------------------------
/unbound/unbound-srv.yml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: unbound
5 | labels:
6 | app: dns-server
7 | component: unbound
8 | spec:
9 | selector:
10 | app: dns-server
11 | component: unbound
12 | ports:
13 | - name: dns-tcp
14 | protocol: TCP
15 | port: 53
16 | targetPort: 53
17 | - name: dns-udp
18 | protocol: UDP
19 | port: 53
20 | targetPort: 53
21 | type: NodePort
22 | # type: LoadBalancer
23 |
--------------------------------------------------------------------------------
/unbound/unbound.conf:
--------------------------------------------------------------------------------
1 | # See unbound.conf(5) man page.
2 | # https://nlnetlabs.nl/documentation/unbound/unbound.conf/
3 | # https://raw.githubusercontent.com/NLnetLabs/unbound/master/doc/example.conf.in
4 | #
5 | # Use this to include other text into the file.
6 | # include: "otherfile.conf"
7 |
8 | server:
9 |
10 | #### Options already enabled by default:
11 | ## https://tools.ietf.org/html/rfc7816
12 | # qname-minimisation: yes
13 | ### Enabled in v1.8.0
14 | # so-reuseport: yes
15 | # minimal-responses: yes
16 | ## https://tools.ietf.org/html/rfc8020
17 | # harden-below-nxdomain: yes
18 | ####
19 |
20 | ## new option in v1.7.3
21 | # https://tools.ietf.org/html/rfc7828
22 | edns-tcp-keepalive: yes
23 | # edns-tcp-keepalive-timeout: 120000 # 2min
24 | # tcp-idle-timeout: 30000 # 30 sec
25 | edns-buffer-size: 1232
26 | ## New Options in v1.8.0
27 | serve-expired-ttl: 86400 # max 1 day
28 | #serve-expired-ttl-reset: no
29 | #log-servfail: no
30 |
31 | ## new option in v1.8.2
32 | # This responds with an empty message to queries of type ANY.
33 | deny-any: yes
34 | # unknown-server-time-limit: 376
35 | # min-client-subnet-ipv6: 0
36 | # min-client-subnet-ipv4: 0
37 | # max-ecs-tree-size-ipv4: 100
38 | # max-ecs-tree-size-ipv6 : 100
39 | # unknown-server-time-limit: 376
40 | # fast-server-permil: 0
41 | # fast-server-num: 3
42 |
43 | # http://unbound.nlnetlabs.nl/documentation/howto_optimise.html
44 | # https://unbound.net/pipermail/unbound-users/2010-March/001083.html
45 | # https://github.com/jedisct1/dnscrypt-server-docker/blob/master/unbound.sh
46 | num-threads: 1
47 | msg-cache-slabs: 1
48 | rrset-cache-slabs: 1
49 | key-cache-slabs: 1
50 | infra-cache-slabs: 1
51 | # dnscrypt-shared-secret-cache-slabs: 1
52 | # dnscrypt-nonce-cache-slabs:1
53 |
54 | msg-cache-size: 54m # default 4m
55 | rrset-cache-size: 108m # rrset=msg*2 # default 4m
56 | key-cache-size: 54m # default 4m
57 | neg-cache-size: 27m # default 1m
58 | infra-cache-numhosts: 50000
59 | # dnscrypt-shared-secret-cache-size: 13m # default 4m
60 | # dnscrypt-nonce-cache-size: 13m # default 4m
61 |
62 | ## if--with-libevent
63 | # outgoing-range: 8192.0
64 | # num-queries-per-thread: 4096.0
65 | ## else
66 | # outgoing-range: 974.0
67 | # num-queries-per-thread: 487.0
68 |
69 | ## Larger socket buffer. OS may need config.
70 | # so-rcvbuf: 4m
71 | # so-sndbuf: 4m
72 |
73 | domain-insecure: "dns.opennic.glue"
74 | domain-insecure: "bbs"
75 | domain-insecure: "bit"
76 | domain-insecure: "chan"
77 | domain-insecure: "cyb"
78 | domain-insecure: "dyn"
79 | domain-insecure: "epic"
80 | # domain-insecure: "free"
81 | domain-insecure: "fur"
82 | domain-insecure: "geek"
83 | domain-insecure: "gopher"
84 | domain-insecure: "indy"
85 | domain-insecure: "libre"
86 | domain-insecure: "neo"
87 | domain-insecure: "null"
88 | domain-insecure: "o"
89 | domain-insecure: "opennic.glue"
90 | domain-insecure: "oss"
91 | domain-insecure: "oz"
92 | domain-insecure: "parody"
93 | domain-insecure: "pirate"
94 | domain-insecure: "glue"
95 | domain-insecure: "bazar"
96 | domain-insecure: "coin"
97 | domain-insecure: "emc"
98 | domain-insecure: "lib"
99 | domain-insecure: "ku"
100 | domain-insecure: "te"
101 | domain-insecure: "ti"
102 | domain-insecure: "uu"
103 |
104 | verbosity: 0
105 | do-ip6: no
106 | logfile: run/unbound.log
107 | auto-trust-anchor-file: run/root.key
108 | tls-cert-bundle: /etc/ssl/certs/ca-certificates.crt
109 | root-hints: root.hints
110 | pidfile: run/unbound.pid
111 | username: _unbound
112 | directory: /etc/unbound
113 | chroot: /etc/unbound
114 | # use-syslog: yes
115 | log-time-ascii: yes
116 | # val-log-level: 0
117 | # statistics-interval: 0
118 | # extended-statistics: yes
119 | # statistics-cumulative: no
120 | interface: 0.0.0.0
121 | # interface: 127.0.0.1
122 | # interface: ::1 # Docker ipv6 -> can't bind socket: Address not available for ::1
123 | # interface: 10.19.96.4
124 | # interface: 0.0.0.0@853
125 | # interface: ::0@853
126 | port: 53
127 | # ssl-service-key: /etc/unbound/private.key
128 | # ssl-service-pem: /etc/unbound/certificate.pem
129 | # ssl-port: 853
130 | access-control: 0.0.0.0/0 allow
131 | access-control: ::/0 allow
132 | # qname-minimisation-strict : yes
133 | # https://tools.ietf.org/html/draft-vixie-dnsext-dns0x20-00
134 | # use-caps-for-id: yes
135 | # caps-whitelist: example.com
136 | # https://tools.ietf.org/html/draft-ietf-dnsop-nsec-aggressiveuse
137 | aggressive-nsec: yes
138 | local-zone: example. static
139 | local-zone: local. static
140 | local-zone: i2p. static
141 | local-zone: home. static
142 | local-zone: zghjccbob3n0. static
143 | local-zone: dhcp. static
144 | local-zone: lan. static
145 | local-zone: localdomain. static
146 | local-zone: ip. static
147 | local-zone: internal. static
148 | local-zone: openstacklocal. static
149 | local-zone: dlink. static
150 | local-zone: gateway. static
151 | local-zone: corp. static
152 | local-zone: workgroup. static
153 | local-zone: belkin. static
154 | local-zone: davolink. static
155 | local-zone: domain. static
156 | local-zone: virtualmin. static
157 | local-zone: invalid. static
158 | local-zone: wlan_ap. static
159 | local-zone: dlinkrouter. static
160 | local-zone: lan1. static
161 | serve-expired: yes
162 | prefetch: yes
163 | prefetch-key: yes
164 | rrset-roundrobin: yes
165 | num-queries-per-thread: 2048
166 | # outgoing-range: 32767
167 | outgoing-range: 4096
168 | incoming-num-tcp: 100
169 | outgoing-num-tcp: 100
170 | jostle-timeout: 325 # average roundtrip time from AU (myserver) to US + a tiny bit extra
171 | neg-cache-size: 25m
172 | cache-min-ttl: 120
173 | cache-max-ttl: 86400
174 | infra-host-ttl: 3600
175 | # cache-max-negative-ttl: 3600
176 | val-bogus-ttl: 120
177 | hide-identity: yes
178 | hide-version: yes
179 | hide-trustanchor: yes
180 | unwanted-reply-threshold: 10000000
181 | ## Simple DNS rebinding protection
182 | ## refer to RFC1918, RFC5735, RFC5156 and https://en.wikipedia.org/wiki/Reserved_IP_addresses
183 | ## IPv4
184 | private-address: 0.0.0.0/32 # Should not be on the Internet (only valid as source address) See https://lwn.net/Articles/791086/ still conflits with https://tools.ietf.org/html/rfc8190
185 | private-address: 10.0.0.0/8 # Private networks
186 | private-address: 127.0.0.0/8 # Loopback, spam-blocklists (RBL) (https://www.dnsbl.info/) e.g. "dig +short 0.0.0.0.zen.spamhaus.org" will stop working (https://www.spamhaus.org/zen/, https://www.spamhaus.org/faq/section/DNSBL%20Usage#202)
187 | private-address: 169.254.0.0/16 # link-local (networks without DHCP)
188 | private-address: 172.16.0.0/12 # Private networks
189 | private-address: 192.168.0.0/16 # Private networks
190 | private-address: 255.255.255.255/32 # Broadcast destination
191 | ## IPv6
192 | private-address: ::/128 # Unspecified addresses (only valid as source address)
193 | private-address: ::1/128 # Loopback
194 | private-address: 2001:db8::/32 # Documentation addresses used for documentation purposes such as user manuals, RFCs, etc. (RFC3849)
195 | # private-address: ::ffff:0:0/96 # IPv4-mapped IPv6 addresses (depreciated and should not be on the public internet) (blocks potentially valid addresses / gives wrong result from DNS Benchmark)
196 | private-address: fe80::/10 # IP address autoconfiguration (link-local unicast, Private network)
197 | private-address: fc00::/7 # Unique Local Addresses (Private network)
198 | # private-address: fec0::/10 # Depreciated site networks
199 | # private-address: 2002::/16 # 6to4 (deprecated)
200 | # private-address: 64:ff9b::/96 # 6to4 "Well-Known" Prefix
201 | # private-address: 2001::/32 # Teredo
202 | private-address: 2001:10::/28 # ORCHID
203 | # private-address: ff00::/8 # Multicast
204 | ## Selected IPv4 mapped addresses from IPv4 above (fixes potentially wrong result from DNS Benchmark if blocking all of ::ffff:0:0/96)
205 | private-address: ::ffff:0.0.0.0/128 # Private IPv4-mapped addresses
206 | private-address: ::ffff:10.0.0.0/120 # Private IPv4-mapped addresses
207 | private-address: ::ffff:127.0.0.1/120 # Loopback IPv4-mapped addresses, spam-blocklists (RBL)
208 | private-address: ::ffff:169.254.0.0/112 # Link-local IPv4-mapped addresses
209 | private-address: ::ffff:172.16.0.0/116 # Private IPv4-mapped addresses
210 | private-address: ::ffff:192.168.0.0/112 # Private IPv4-mapped addresses
211 | private-address: ::ffff:255.255.255.255/128 # Broadcast IPv4-mapped addresses
212 | ##
213 | do-not-query-localhost: yes # ::1 and 127.0.0.1/8
214 | do-not-query-address: 127.0.0.0/8
215 | # do-not-query-address: 10.0.0.0/8 # kube/docker ips, needed for nsd
216 | # do-not-query-address: 172.16.0.0/12 # docker-compose, needed for nsd
217 | do-not-query-address: 192.168.0.0/16
218 | # ratelimit: 500
219 | # ip-ratelimit: 50
220 | ### harden-large-queries: yes
221 | ### harden-short-bufsize: yes
222 | ## harden-algo-downgrade: yes
223 | ### harden-referral-path: yes
224 | ## prefer-ip6: yes
225 | # delay-close: 1500
226 |
227 | # https://support.mozilla.org/en-US/kb/configuring-networks-disable-dns-over-https
228 | local-zone: "use-application-dns.net." always_nxdomain
229 | auth-zone:
230 | name: "."
231 | url: "https://www.internic.net/domain/root.zone"
232 | fallback-enabled: yes
233 | for-downstream: no
234 | for-upstream: yes
235 | zonefile: /run/root.zone
236 | remote-control:
237 | control-enable: yes
238 | control-interface: 127.0.0.1
239 | stub-zone:
240 | name: "dns.opennic.glue"
241 | stub-addr: "127.0.0.1@552" # Authorative Slave DNS server
242 | stub-zone:
243 | name: "bbs"
244 | stub-addr: "127.0.0.1@552"
245 | stub-zone:
246 | name: "bit"
247 | stub-addr: "127.0.0.1@552"
248 | stub-zone:
249 | name: "chan"
250 | stub-addr: "127.0.0.1@552"
251 | stub-zone:
252 | name: "cyb"
253 | stub-addr: "127.0.0.1@552"
254 | stub-zone:
255 | name: "dyn"
256 | stub-addr: "127.0.0.1@552"
257 | stub-zone:
258 | name: "epic"
259 | stub-addr: "127.0.0.1@552"
260 | # stub-zone:
261 | # name: "free"
262 | # stub-addr: "127.0.0.1@552"
263 | stub-zone:
264 | name: "fur"
265 | stub-addr: "127.0.0.1@552"
266 | stub-zone:
267 | name: "geek"
268 | stub-addr: "127.0.0.1@552"
269 | stub-zone:
270 | name: "gopher"
271 | stub-addr: "127.0.0.1@552"
272 | stub-zone:
273 | name: "indy"
274 | stub-addr: "127.0.0.1@552"
275 | stub-zone:
276 | name: "libre"
277 | stub-addr: "127.0.0.1@552"
278 | stub-zone:
279 | name: "neo"
280 | stub-addr: "127.0.0.1@552"
281 | stub-zone:
282 | name: "null"
283 | stub-addr: "127.0.0.1@552"
284 | stub-zone:
285 | name: "o"
286 | stub-addr: "127.0.0.1@552"
287 | stub-zone:
288 | name: "opennic.glue"
289 | stub-addr: "127.0.0.1@552"
290 | stub-zone:
291 | name: "oss"
292 | stub-addr: "127.0.0.1@552"
293 | stub-zone:
294 | name: "oz"
295 | stub-addr: "127.0.0.1@552"
296 | stub-zone:
297 | name: "parody"
298 | stub-addr: "127.0.0.1@552"
299 | stub-zone:
300 | name: "pirate"
301 | stub-addr: "127.0.0.1@552"
302 | # OpenNIC Peers:
303 | stub-zone:
304 | name: "bazar"
305 | stub-host: "seed1.emercoin.com"
306 | stub-host: "seed2.emercoin.com"
307 | stub-zone:
308 | name: "coin"
309 | stub-host: "seed1.emercoin.com"
310 | stub-host: "seed2.emercoin.com"
311 | stub-zone:
312 | name: "emc"
313 | stub-host: "seed1.emercoin.com"
314 | stub-host: "seed2.emercoin.com"
315 | stub-zone:
316 | name: "lib"
317 | stub-host: "seed1.emercoin.com"
318 | stub-host: "seed2.emercoin.com"
319 | stub-zone:
320 | name: "ku"
321 | stub-addr: "127.0.0.1@552"
322 | stub-addr: "5.45.96.220" # ns1.new-nations.ku
323 | stub-addr: "185.82.22.133" # ns2.new-nations.ku
324 | stub-zone:
325 | name: "te"
326 | stub-addr: "127.0.0.1@552"
327 | stub-addr: "5.45.96.220" # ns1.new-nations.te
328 | stub-addr: "185.82.22.133" # ns2.new-nations.te
329 | stub-zone:
330 | name: "ti"
331 | stub-addr: "127.0.0.1@552"
332 | stub-addr: "5.45.96.220" # ns1.new-nations.ti
333 | stub-addr: "185.82.22.133" # ns2.new-nations.ti
334 | stub-zone:
335 | name: "uu"
336 | stub-addr: "127.0.0.1@552"
337 | stub-addr: "5.45.96.220" # ns1.new-nations.uu
338 | stub-addr: "185.82.22.133" # ns2.new-nations.uu
339 | # stub-zone:
340 | # name: "ko"
341 | # stub-addr: "127.0.0.1@552"
342 | # stub-addr: "5.45.96.220" # ns1.new-nations.ko
343 | # stub-addr: "185.82.22.133" # ns2.new-nations.ko
344 | # stub-zone:
345 | # name: "rm"
346 | # stub-addr: "127.0.0.1@552"
347 | # stub-addr: "5.45.96.220" # ns1.new-nations.rm
348 | # stub-addr: "185.82.22.133" # ns2.new-nations.rm
349 |
--------------------------------------------------------------------------------
/unbound/unbound.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | set -e
3 | exec 2>&1
4 | # . /etc/envvars
5 | exec /usr/local/sbin/unbound -d
6 |
--------------------------------------------------------------------------------
/yarn.lock:
--------------------------------------------------------------------------------
1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2 | # yarn lockfile v1
3 |
4 |
5 | ansi-regex@^2.0.0:
6 | version "2.1.1"
7 | resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz"
8 | integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==
9 |
10 | ansi-regex@^3.0.0:
11 | version "3.0.1"
12 | resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz"
13 | integrity sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==
14 |
15 | ansi-regex@^4.1.0:
16 | version "4.1.1"
17 | resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz"
18 | integrity sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==
19 |
20 | ansi-styles@^3.2.0, ansi-styles@^3.2.1:
21 | version "3.2.1"
22 | resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz"
23 | integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==
24 | dependencies:
25 | color-convert "^1.9.0"
26 |
27 | argparse@^1.0.7:
28 | version "1.0.10"
29 | resolved "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz"
30 | integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==
31 | dependencies:
32 | sprintf-js "~1.0.2"
33 |
34 | bats-assert@^2.0.0:
35 | version "2.0.0"
36 | resolved "https://registry.npmjs.org/bats-assert/-/bats-assert-2.0.0.tgz"
37 | integrity sha512-qO3kNilWxW8iCONu9NDUfvsCiC6JzL6DPOc/DGq9z3bZ9/A7wURJ+FnFMxGbofOmWbCoy7pVhofn0o47A95qkQ==
38 |
39 | bats-support@^0.3.0:
40 | version "0.3.0"
41 | resolved "https://registry.npmjs.org/bats-support/-/bats-support-0.3.0.tgz"
42 | integrity sha512-z+2WzXbI4OZgLnynydqH8GpI3+DcOtepO66PlK47SfEzTkiuV9hxn9eIQX+uLVFbt2Oqoc7Ky3TJ/N83lqD+cg==
43 |
44 | bats@^1.9.0:
45 | version "1.9.0"
46 | resolved "https://registry.npmjs.org/bats/-/bats-1.9.0.tgz"
47 | integrity sha512-Z5BJaAmmHv/ujj7obhjEzJ//OL+ZtjVq0iRnHu+2fE9OeUaPMbJpBgYiOdNbDrG3E2hqe84/AXNnS/UiXl/UcA==
48 |
49 | camelcase@^5.0.0:
50 | version "5.3.1"
51 | resolved "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz"
52 | integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==
53 |
54 | chalk@^2.4.2:
55 | version "2.4.2"
56 | resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz"
57 | integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
58 | dependencies:
59 | ansi-styles "^3.2.1"
60 | escape-string-regexp "^1.0.5"
61 | supports-color "^5.3.0"
62 |
63 | cliui@^4.1.0:
64 | version "4.1.0"
65 | resolved "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz"
66 | integrity sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==
67 | dependencies:
68 | string-width "^2.1.1"
69 | strip-ansi "^4.0.0"
70 | wrap-ansi "^2.0.0"
71 |
72 | cliui@^5.0.0:
73 | version "5.0.0"
74 | resolved "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz"
75 | integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==
76 | dependencies:
77 | string-width "^3.1.0"
78 | strip-ansi "^5.2.0"
79 | wrap-ansi "^5.1.0"
80 |
81 | code-point-at@^1.0.0:
82 | version "1.1.0"
83 | resolved "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz"
84 | integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==
85 |
86 | color-convert@^1.9.0:
87 | version "1.9.3"
88 | resolved "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz"
89 | integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==
90 | dependencies:
91 | color-name "1.1.3"
92 |
93 | color-name@1.1.3:
94 | version "1.1.3"
95 | resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz"
96 | integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==
97 |
98 | decamelize@^1.2.0:
99 | version "1.2.0"
100 | resolved "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz"
101 | integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==
102 |
103 | dockerfilelint@^1.8.0:
104 | version "1.8.0"
105 | resolved "https://registry.npmjs.org/dockerfilelint/-/dockerfilelint-1.8.0.tgz"
106 | integrity sha512-j0tipeP1kpTWfx1XV6QVrrJTtGiP/46+3NT5JuaqXUnYrNlusgvrSP4/ACkqQdglJfmeedIU7c2wztmxEV+JQA==
107 | dependencies:
108 | chalk "^2.4.2"
109 | cliui "^4.1.0"
110 | js-yaml "^3.6.0"
111 | lodash "^4.3.0"
112 | yargs "^13.2.1"
113 |
114 | dockerlint@^0.3.9:
115 | version "0.3.9"
116 | resolved "https://registry.npmjs.org/dockerlint/-/dockerlint-0.3.9.tgz"
117 | integrity sha512-gps1IlRWx0hqhG7qZNYoF/Ae8wpnnPDGV0eYC60FdH2UscS4hZ+NFYX3Pusj/GImjLD/Pxkp/wib7CBb63yzZw==
118 | dependencies:
119 | sty "^0.6.1"
120 | subarg "^1.0.0"
121 |
122 | emoji-regex@^7.0.1:
123 | version "7.0.3"
124 | resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz"
125 | integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==
126 |
127 | escape-string-regexp@^1.0.5:
128 | version "1.0.5"
129 | resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz"
130 | integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==
131 |
132 | esprima@^4.0.0:
133 | version "4.0.1"
134 | resolved "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz"
135 | integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==
136 |
137 | find-up@^3.0.0:
138 | version "3.0.0"
139 | resolved "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz"
140 | integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==
141 | dependencies:
142 | locate-path "^3.0.0"
143 |
144 | get-caller-file@^2.0.1:
145 | version "2.0.5"
146 | resolved "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz"
147 | integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
148 |
149 | has-flag@^3.0.0:
150 | version "3.0.0"
151 | resolved "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz"
152 | integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==
153 |
154 | is-fullwidth-code-point@^1.0.0:
155 | version "1.0.0"
156 | resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz"
157 | integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==
158 | dependencies:
159 | number-is-nan "^1.0.0"
160 |
161 | is-fullwidth-code-point@^2.0.0:
162 | version "2.0.0"
163 | resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz"
164 | integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==
165 |
166 | js-yaml@^3.6.0:
167 | version "3.14.1"
168 | resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz"
169 | integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==
170 | dependencies:
171 | argparse "^1.0.7"
172 | esprima "^4.0.0"
173 |
174 | locate-path@^3.0.0:
175 | version "3.0.0"
176 | resolved "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz"
177 | integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==
178 | dependencies:
179 | p-locate "^3.0.0"
180 | path-exists "^3.0.0"
181 |
182 | lodash@^4.3.0:
183 | version "4.17.21"
184 | resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz"
185 | integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
186 |
187 | minimist@^1.1.0:
188 | version "1.2.6"
189 | resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz"
190 | integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==
191 |
192 | number-is-nan@^1.0.0:
193 | version "1.0.1"
194 | resolved "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz"
195 | integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==
196 |
197 | p-limit@^2.0.0:
198 | version "2.3.0"
199 | resolved "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz"
200 | integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==
201 | dependencies:
202 | p-try "^2.0.0"
203 |
204 | p-locate@^3.0.0:
205 | version "3.0.0"
206 | resolved "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz"
207 | integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==
208 | dependencies:
209 | p-limit "^2.0.0"
210 |
211 | p-try@^2.0.0:
212 | version "2.2.0"
213 | resolved "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz"
214 | integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==
215 |
216 | path-exists@^3.0.0:
217 | version "3.0.0"
218 | resolved "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz"
219 | integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==
220 |
221 | require-directory@^2.1.1:
222 | version "2.1.1"
223 | resolved "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz"
224 | integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==
225 |
226 | require-main-filename@^2.0.0:
227 | version "2.0.0"
228 | resolved "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz"
229 | integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==
230 |
231 | set-blocking@^2.0.0:
232 | version "2.0.0"
233 | resolved "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz"
234 | integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==
235 |
236 | sprintf-js@~1.0.2:
237 | version "1.0.3"
238 | resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz"
239 | integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==
240 |
241 | string-width@^1.0.1:
242 | version "1.0.2"
243 | resolved "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz"
244 | integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==
245 | dependencies:
246 | code-point-at "^1.0.0"
247 | is-fullwidth-code-point "^1.0.0"
248 | strip-ansi "^3.0.0"
249 |
250 | string-width@^2.1.1:
251 | version "2.1.1"
252 | resolved "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz"
253 | integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==
254 | dependencies:
255 | is-fullwidth-code-point "^2.0.0"
256 | strip-ansi "^4.0.0"
257 |
258 | string-width@^3.0.0, string-width@^3.1.0:
259 | version "3.1.0"
260 | resolved "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz"
261 | integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==
262 | dependencies:
263 | emoji-regex "^7.0.1"
264 | is-fullwidth-code-point "^2.0.0"
265 | strip-ansi "^5.1.0"
266 |
267 | strip-ansi@^3.0.0, strip-ansi@^3.0.1:
268 | version "3.0.1"
269 | resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz"
270 | integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==
271 | dependencies:
272 | ansi-regex "^2.0.0"
273 |
274 | strip-ansi@^4.0.0:
275 | version "4.0.0"
276 | resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz"
277 | integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==
278 | dependencies:
279 | ansi-regex "^3.0.0"
280 |
281 | strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0:
282 | version "5.2.0"
283 | resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz"
284 | integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==
285 | dependencies:
286 | ansi-regex "^4.1.0"
287 |
288 | sty@^0.6.1:
289 | version "0.6.1"
290 | resolved "https://registry.npmjs.org/sty/-/sty-0.6.1.tgz"
291 | integrity sha1-3j+5rlcLxgp0RyRfDewxIT6i1ag= sha512-Pu/JG9iZxf9n0nS9958Eml71lg5mlKFh7qnq3P10qXff1SP8Kc4dwfnyRaiaI5KEyq2ff4DBucrLW/a8xv+MkA==
292 |
293 | subarg@^1.0.0:
294 | version "1.0.0"
295 | resolved "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz"
296 | integrity sha1-9izxdYHplrSPyWVpn1TAauJouNI= sha512-RIrIdRY0X1xojthNcVtgT9sjpOGagEUKpZdgBUi054OEPFo282yg+zE+t1Rj3+RqKq2xStL7uUHhY+AjbC4BXg==
297 | dependencies:
298 | minimist "^1.1.0"
299 |
300 | supports-color@^5.3.0:
301 | version "5.5.0"
302 | resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz"
303 | integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==
304 | dependencies:
305 | has-flag "^3.0.0"
306 |
307 | which-module@^2.0.0:
308 | version "2.0.0"
309 | resolved "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz"
310 | integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==
311 |
312 | wrap-ansi@^2.0.0:
313 | version "2.1.0"
314 | resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz"
315 | integrity sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU= sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw==
316 | dependencies:
317 | string-width "^1.0.1"
318 | strip-ansi "^3.0.1"
319 |
320 | wrap-ansi@^5.1.0:
321 | version "5.1.0"
322 | resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz"
323 | integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==
324 | dependencies:
325 | ansi-styles "^3.2.0"
326 | string-width "^3.0.0"
327 | strip-ansi "^5.0.0"
328 |
329 | y18n@^4.0.0:
330 | version "4.0.3"
331 | resolved "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz"
332 | integrity sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==
333 |
334 | yargs-parser@^13.1.2:
335 | version "13.1.2"
336 | resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz"
337 | integrity sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==
338 | dependencies:
339 | camelcase "^5.0.0"
340 | decamelize "^1.2.0"
341 |
342 | yargs@^13.2.1:
343 | version "13.3.2"
344 | resolved "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz"
345 | integrity sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==
346 | dependencies:
347 | cliui "^5.0.0"
348 | find-up "^3.0.0"
349 | get-caller-file "^2.0.1"
350 | require-directory "^2.1.1"
351 | require-main-filename "^2.0.0"
352 | set-blocking "^2.0.0"
353 | string-width "^3.0.0"
354 | which-module "^2.0.0"
355 | y18n "^4.0.0"
356 | yargs-parser "^13.1.2"
357 |
--------------------------------------------------------------------------------