Compare commits

..

No commits in common. "master" and "docker_and_rework" have entirely different histories.

15 changed files with 55 additions and 173 deletions

View File

@ -1,57 +0,0 @@
version: 2.1
orbs:
docker: circleci/docker@1.5.0
jobs:
test:
docker:
- image: circleci/golang:1.16
working_directory: /go/src/github.com/pboehm/ddns
steps:
- checkout
- run: go get -v -t -d ./...
- run: go test -v ./...
docker-build:
executor: docker/docker
steps:
- setup_remote_docker
- checkout
- docker/build:
image: pboehm/ddns
dockerfile: docker/ddns/Dockerfile
docker-build-and-push:
executor: docker/docker
steps:
- setup_remote_docker
- checkout
- docker/check
- docker/build:
image: pboehm/ddns
dockerfile: docker/ddns/Dockerfile
tag: $CIRCLE_SHA1,latest
- docker/push:
image: pboehm/ddns
tag: $CIRCLE_SHA1,latest
workflows:
commit:
jobs:
- test:
filters: # required since `docker-XXXX` have tag filters AND require `test`
tags:
only: /.*/
- docker-build:
requires:
- test
filters:
branches:
ignore: master
- docker-build-and-push:
requires:
- test
filters:
branches:
only: master

2
.gitignore vendored
View File

@ -2,5 +2,3 @@
/docker/docker-compose.*.yml /docker/docker-compose.*.yml
/ddns /ddns
dump.rdb dump.rdb
/docker/.caddy_mount/
/docker/.redis_mount/

View File

@ -1,6 +1,6 @@
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2020 Philipp Böhm Copyright (c) 2018 Philipp Böhm
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.

View File

@ -1,28 +1,18 @@
# `ddns` - Dynamic DNS # `ddns` - Dynamic DNS
[![CircleCI](https://img.shields.io/circleci/build/github/pboehm/ddns?style=flat)](https://circleci.com/github/pboehm/ddns) A self-hosted Dynamic DNS solution similar to DynDNS or NO-IP.
[![Docker Image Size (tag)](https://img.shields.io/docker/image-size/pboehm/ddns/latest?logo=Docker)](https://hub.docker.com/r/pboehm/ddns)
[![Docker Pulls](https://img.shields.io/docker/pulls/pboehm/ddns?logo=Docker)](https://hub.docker.com/r/pboehm/ddns)
[![GitHub](https://img.shields.io/github/license/pboehm/ddns?style=flat)](https://github.com/pboehm/ddns)
You can use a hosted version at [ddns.pboehm.de](https://ddns.pboehm.de/) where you can register a
host under the `d.pboehm.de` domain (e.g `test.d.pboehm.de`).
A self-hosted Dynamic DNS solution similar to DynDNS or NO-IP based on the **Recent Changes**
[PowerDNS Remote Backend](https://doc.powerdns.com/md/authoritative/backend-remote/).
<img src="screenshot.png" alt="screenshot" width="500"/> `ddns` has been massively restructured and refactored and now uses the PowerDNS
[Remote Backend](https://doc.powerdns.com/md/authoritative/backend-remote/) instead
of the [Pipe Backend](https://doc.powerdns.com/md/authoritative/backend-pipe/), which
is far easier to deploy. It now serves both the frontend and the backend other HTTP using different ports.
The old `ddns` source code can be found at the [legacy](https://github.com/pboehm/ddns/tree/legacy) tag.
## ⚠️⚠️⚠️ Note regarding hosted version at `ddns.pboehm.de`
The hosted `ddns` service with custom hosts under the `d.pboehm.de` domain (e.g `test.d.pboehm.de`) is not available
anymore! I did not use this service for quite some time and recently there were some issues which resulted in downtime
and expiration of all registered hosts.
### Alternatives
There is at least one other hosted version of `pboehm/ddns` that
[can be found via Google](https://www.google.com/search?q=pboehm%2Fddns+%22DDNS+is+a+project+that+lets+you+host+a+Dynamic+DNS+Service%2C+similar+to+DynDNS%2FNO-IP%2C+on+your+own+servers.%22)
or you can host it yourself as described below.
## How can I update my IP if it changes? ## How can I update my IP if it changes?
@ -57,9 +47,17 @@ you have to create the following two DNS records:
### `ddns`-Setup ### `ddns`-Setup
Setting up `ddns` was kind of a hassle in the legacy version, because there are multiple components that have to
work together:
* `ddns` that runs the frontend and provides and provides an API compatible with the
[Remote Backend](https://doc.powerdns.com/md/authoritative/backend-remote/)
* Redis as storage backend for `ddns`
* PowerDNS as DNS server, which uses the `ddns` backend API on Port `8053`
* A web server that makes the `ddns` frontend accessible to the Internet through HTTPS
The setup is now automated using [docker-compose](https://docs.docker.com/compose/) and only some customization has The setup is now automated using [docker-compose](https://docs.docker.com/compose/) and only some customization has
to be made in a `docker-compose.override.yml` file to be made in a `docker-compose.override.yml` file.
(a [sample](./docker/docker-compose.override.yml.sample) is available here).
#### Configuring the Setup #### Configuring the Setup
@ -77,11 +75,12 @@ Please adjust the settings in `docker-compose.override.yml` marked with the `#<<
* adjust the domain part in lines marked with `# <<< ADJUST DOMAIN` according to your DNS-Setup * adjust the domain part in lines marked with `# <<< ADJUST DOMAIN` according to your DNS-Setup
* insert your email address in lines marked with `# <<< INSERT EMAIL` which is required for getting certificates * insert your email address in lines marked with `# <<< INSERT EMAIL` which is required for getting certificates
from Lets Encrypt from Lets Encrypt
* adjust the path component before the `:` in lines marked with `# <<< ADJUST LOCAL PATH` if the shown path
does not meet your requirements
Finally execute the following `docker-compose` command, which creates 4 containers in detached mode which are also Finally execute the following `docker-compose` command, which creates 4 containers in detached mode which are also
started automatically after reboot. For updating an existing installation use the same command because it automatically started automatically after reboot.
rebuilds the containers.
``` ```
docker-compose --project-name ddns up -d --build docker-compose --project-name ddns up -d
``` ```

View File

@ -1,8 +1,8 @@
package backend package backend
import ( import (
"github.com/gin-gonic/gin"
"github.com/pboehm/ddns/shared" "github.com/pboehm/ddns/shared"
"gopkg.in/gin-gonic/gin.v1"
"log" "log"
"strings" "strings"
) )
@ -51,13 +51,7 @@ func (b *Backend) Run() error {
r.GET("/dnsapi/getDomainMetadata/:name/:kind", func(c *gin.Context) { r.GET("/dnsapi/getDomainMetadata/:name/:kind", func(c *gin.Context) {
c.JSON(200, gin.H{ c.JSON(200, gin.H{
"result": []string{"0"}, "result": false,
})
})
r.GET("/dnsapi/getAllDomainMetadata/:name", func(c *gin.Context) {
c.JSON(200, gin.H{
"result": gin.H{"PRESIGNED": []string{"0"}},
}) })
}) })

View File

@ -1,18 +1,13 @@
FROM golang:alpine FROM golang:1.9-alpine3.7
RUN apk add --no-cache git RUN apk add --no-cache git
WORKDIR /go/src/github.com/pboehm/ddns WORKDIR /go/src/github.com/pboehm/ddns
COPY . . COPY . .
RUN GO111MODULE=on go get -d -v ./... RUN go-wrapper download # "go get -d -v ./..."
RUN GO111MODULE=on go install -v ./... RUN go-wrapper install # "go install -v ."
ENV GIN_MODE release ENV GIN_MODE release
ENV DDNS_EXPIRATION_DAYS 10
CMD /go/bin/ddns \ CMD /go/bin/ddns --domain=${DDNS_DOMAIN} --soa_fqdn=${DDNS_SOA_DOMAIN} --redis=${DDNS_REDIS_HOST}
--domain=${DDNS_DOMAIN} \
--soa_fqdn=${DDNS_SOA_DOMAIN} \
--redis=${DDNS_REDIS_HOST} \
--expiration-days=${DDNS_EXPIRATION_DAYS}

View File

@ -5,15 +5,14 @@ services:
environment: environment:
DDNS_DOMAIN: d.example.net # <<< ADJUST DOMAIN DDNS_DOMAIN: d.example.net # <<< ADJUST DOMAIN
DDNS_SOA_DOMAIN: ddns.example.net # <<< ADJUST DOMAIN DDNS_SOA_DOMAIN: ddns.example.net # <<< ADJUST DOMAIN
DDNS_EXPIRATION_DAYS: 10
powerdns: powerdns:
ports: ports:
- "53:53/udp" - "53/udp:53/udp"
redis: redis:
volumes: volumes:
- "${PWD}/.redis_mount:/data" - "/root/ddns-redis:/data" # <<< ADJUST LOCAL PATH
caddy: caddy:
restart: unless-stopped restart: unless-stopped
@ -21,13 +20,12 @@ services:
depends_on: depends_on:
- ddns - ddns
environment: environment:
ACME_AGREE: "true"
DDNS_FRONTEND_HOST: ddns:8080 DDNS_FRONTEND_HOST: ddns:8080
DDNS_CADDY_DOMAIN: ddns.example.net # <<< ADJUST DOMAIN DDNS_CADDY_DOMAIN: ddns.example.net # <<< ADJUST DOMAIN
DDNS_CADDY_TLS_EMAIL: changeme@example.net # <<< INSERT EMAIL DDNS_CADDY_TLS_EMAIL: changeme@example.net # <<< INSERT EMAIL
volumes: volumes:
- "${PWD}/caddy/Caddyfile:/etc/Caddyfile" - "${PWD}/caddy/Caddyfile:/etc/Caddyfile"
- "${PWD}/.caddy_mount:/root/.caddy" - "/root/ddns-caddy:/root/.caddy" # <<< ADJUST LOCAL PATH
ports: ports:
- "80:80" - "80:80"
- "443:443" - "443:443"

View File

@ -10,7 +10,7 @@ services:
- redis - redis
environment: environment:
DDNS_DOMAIN: d.example.net DDNS_DOMAIN: d.example.net
DDNS_SOA_DOMAIN: ddns.example.net DDNS_SOA_DOMAIN: ns.example.net
DDNS_REDIS_HOST: redis:6379 DDNS_REDIS_HOST: redis:6379
powerdns: powerdns:

View File

@ -1,12 +1,12 @@
FROM buildpack-deps:bookworm-scm FROM buildpack-deps:jessie-scm
# the setup procedure according to https://repo.powerdns.com/ (Debian 12 Bookworm) # the setup procedure according to https://repo.powerdns.com/ (Debian 8 Jessie)
RUN echo "deb [arch=amd64] http://repo.powerdns.com/debian bookworm-auth-49 main" > /etc/apt/sources.list.d/pdns.list \ RUN echo "deb http://repo.powerdns.com/debian jessie-auth-41 main" > /etc/apt/sources.list.d/pdns.list \
&& echo "Package: pdns-*\nPin: origin repo.powerdns.com\nPin-Priority: 600\n" >> /etc/apt/preferences.d/pdns \ && echo "Package: pdns-*\nPin: origin repo.powerdns.com\nPin-Priority: 600\n" >> /etc/apt/preferences.d/pdns \
&& curl https://repo.powerdns.com/FD380FBB-pub.asc | apt-key add - \ && curl https://repo.powerdns.com/FD380FBB-pub.asc | apt-key add - \
&& apt-get -y update \ && apt-get -y update \
&& apt-get install -y pdns-server pdns-backend-remote \ && apt-get install -y pdns-server pdns-backend-remote \
&& rm -rf /var/lib/apt/lists/* && rm -rf /var/lib/apt/lists/*
COPY pdns.conf /etc/powerdns/pdns.conf COPY pdns.conf /etc/powerdns/pdns.conf
@ -16,4 +16,4 @@ ENTRYPOINT ["/entrypoint.sh"]
EXPOSE 53 EXPOSE 53
CMD ["pdns_server", "--daemon=no"] CMD ["pdns_server", "--daemon=no"]

View File

@ -1,3 +1,4 @@
disable-tcp=yes
cache-ttl=0 cache-ttl=0
loglevel=7 loglevel=7
log-dns-details=yes log-dns-details=yes

View File

@ -2,8 +2,8 @@ package frontend
import ( import (
"fmt" "fmt"
"github.com/gin-gonic/gin"
"github.com/pboehm/ddns/shared" "github.com/pboehm/ddns/shared"
"gopkg.in/gin-gonic/gin.v1"
"html/template" "html/template"
"log" "log"
"net" "net"
@ -60,8 +60,10 @@ func (f *Frontend) Run() error {
var err error var err error
if _, err := f.hosts.GetHost(hostname); err == nil { if h, err := f.hosts.GetHost(hostname); err == nil {
c.JSON(403, gin.H{"error": "This hostname has already been registered."}) c.JSON(403, gin.H{
"error": fmt.Sprintf("This hostname has already been registered. %v", h),
})
return return
} }
@ -153,7 +155,7 @@ func buildTemplate() *template.Template {
} }
func isValidHostname(host string) (string, bool) { func isValidHostname(host string) (string, bool) {
valid, _ := regexp.Match("^([a-zA-Z0-9]([a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9])?)$", []byte(host)) valid, _ := regexp.Match("^[a-z0-9]{1,32}$", []byte(host))
return host, valid return host, valid
} }

View File

@ -139,6 +139,10 @@ const indexTemplate string = `
<div id="command_output"></div> <div id="command_output"></div>
<div class="footer">
<p>&copy; Philipp Böhm</p>
</div>
</div> <!-- /container --> </div> <!-- /container -->
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) --> <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->

10
go.mod
View File

@ -1,10 +0,0 @@
module github.com/pboehm/ddns
go 1.12
require (
github.com/garyburd/redigo v1.6.0
github.com/gin-gonic/gin v1.4.0
github.com/stretchr/testify v1.3.0
golang.org/x/sync v0.0.0-20190423024810-112230192c58
)

42
go.sum
View File

@ -1,42 +0,0 @@
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/garyburd/redigo v1.6.0 h1:0VruCpn7yAIIu7pWVClQC8wxCJEcG3nyzpMSHKi1PQc=
github.com/garyburd/redigo v1.6.0/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY=
github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3 h1:t8FVkw33L+wilf2QiWkw0UV77qRpcH/JHPKGpKa2E8g=
github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s=
github.com/gin-gonic/gin v1.4.0 h1:3tMoCCfM7ppqsR0ptz/wi1impNpT7/9wQtMZ8lr1mCQ=
github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM=
github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/json-iterator/go v1.1.6 h1:MrUvLMLTMxbqFJ9kzlvat/rYZqZnW3u4wkLzWTaFwKs=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/mattn/go-isatty v0.0.7 h1:UvyT9uN+3r7yLEYSlJsbQGdsaB/a0DlgWP3pql6iwOc=
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/ugorji/go v1.1.4 h1:j4s+tAvLfL3bZyefP2SEWmhBzmuIlH/eqNuPdFPgngw=
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c h1:uOCk1iQW6Vc18bnC13MfzScl+wdKBmM9Y9kU7Z83/lw=
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/go-playground/assert.v1 v1.2.1 h1:xoYuJVE7KT85PYWrN730RguIQO0ePzVRfFMXadIrXTM=
gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
gopkg.in/go-playground/validator.v8 v8.18.2 h1:lFB4DoMU6B626w8ny76MV7VX6W2VHct2GVOI3xgiMrQ=
gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

Binary file not shown.

Before

Width:  |  Height:  |  Size: 125 KiB