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
/ddns
dump.rdb
/docker/.caddy_mount/
/docker/.redis_mount/

View file

@ -1,6 +1,6 @@
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
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
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
SOFTWARE.
SOFTWARE.

View file

@ -1,28 +1,18 @@
# `ddns` - Dynamic DNS
[![CircleCI](https://img.shields.io/circleci/build/github/pboehm/ddns?style=flat)](https://circleci.com/github/pboehm/ddns)
[![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)
A self-hosted Dynamic DNS solution similar to DynDNS or NO-IP.
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
[PowerDNS Remote Backend](https://doc.powerdns.com/md/authoritative/backend-remote/).
**Recent Changes**
<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.
## ⚠️⚠️⚠️ 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.
The old `ddns` source code can be found at the [legacy](https://github.com/pboehm/ddns/tree/legacy) tag.
## How can I update my IP if it changes?
@ -57,9 +47,17 @@ you have to create the following two DNS records:
### `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
to be made in a `docker-compose.override.yml` file
(a [sample](./docker/docker-compose.override.yml.sample) is available here).
to be made in a `docker-compose.override.yml` file.
#### 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
* insert your email address in lines marked with `# <<< INSERT EMAIL` which is required for getting certificates
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
started automatically after reboot. For updating an existing installation use the same command because it automatically
rebuilds the containers.
started automatically after reboot.
```
docker-compose --project-name ddns up -d --build
docker-compose --project-name ddns up -d
```

View file

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

View file

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

View file

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

View file

@ -10,7 +10,7 @@ services:
- redis
environment:
DDNS_DOMAIN: d.example.net
DDNS_SOA_DOMAIN: ddns.example.net
DDNS_SOA_DOMAIN: ns.example.net
DDNS_REDIS_HOST: redis:6379
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)
RUN echo "deb [arch=amd64] http://repo.powerdns.com/debian bookworm-auth-49 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 \
&& curl https://repo.powerdns.com/FD380FBB-pub.asc | apt-key add - \
&& apt-get -y update \
&& apt-get install -y pdns-server pdns-backend-remote \
&& rm -rf /var/lib/apt/lists/*
# the setup procedure according to https://repo.powerdns.com/ (Debian 8 Jessie)
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 \
&& curl https://repo.powerdns.com/FD380FBB-pub.asc | apt-key add - \
&& apt-get -y update \
&& apt-get install -y pdns-server pdns-backend-remote \
&& rm -rf /var/lib/apt/lists/*
COPY pdns.conf /etc/powerdns/pdns.conf
@ -16,4 +16,4 @@ ENTRYPOINT ["/entrypoint.sh"]
EXPOSE 53
CMD ["pdns_server", "--daemon=no"]
CMD ["pdns_server", "--daemon=no"]

View file

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

View file

@ -2,8 +2,8 @@ package frontend
import (
"fmt"
"github.com/gin-gonic/gin"
"github.com/pboehm/ddns/shared"
"gopkg.in/gin-gonic/gin.v1"
"html/template"
"log"
"net"
@ -60,8 +60,10 @@ func (f *Frontend) Run() error {
var err error
if _, err := f.hosts.GetHost(hostname); err == nil {
c.JSON(403, gin.H{"error": "This hostname has already been registered."})
if h, err := f.hosts.GetHost(hostname); err == nil {
c.JSON(403, gin.H{
"error": fmt.Sprintf("This hostname has already been registered. %v", h),
})
return
}
@ -153,7 +155,7 @@ func buildTemplate() *template.Template {
}
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
}

View file

@ -139,6 +139,10 @@ const indexTemplate string = `
<div id="command_output"></div>
<div class="footer">
<p>&copy; Philipp Böhm</p>
</div>
</div> <!-- /container -->
<!-- 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