Compare commits

...

25 Commits

Author SHA1 Message Date
opinux 87c648e7bd docker/powerdns/Dockerfile aktualisiert 2024-09-15 20:26:36 +02:00
opinux 8c086d3194 docker/docker-compose.override.yml aktualisiert 2024-09-15 20:25:42 +02:00
Philipp Böhm 82a5891ba3 add note regarding hosted service at ddns.pboehm.de 2021-11-27 16:47:55 +01:00
陈明 7ed078bb78
support powerdns v4.4 and later (#44) 2021-11-27 16:00:25 +01:00
Philipp Böhm e2b997707b add links for status badges 2021-02-20 19:58:49 +01:00
Philipp Böhm 204fbeba59 add some status badges 2021-02-20 19:50:20 +01:00
Philipp Böhm 8d176ee521 fix docker push with latest tag 2021-02-20 16:46:08 +01:00
Philipp Böhm bc8c5e2810
CircleCi project setup (#32)
Add .circleci/config.yml
2021-02-20 16:42:04 +01:00
Philipp Böhm 016eea259c
Merge pull request #30 from ssiuhk/fix_hostname
Update hostname regex to accept "-"
2021-02-20 13:12:39 +01:00
Sam SIU 3b4513eebd
Update hostname regex to accept "-"
Updated hostname regex to accept "-" according to RFC 1123
2021-02-18 22:54:27 +08:00
Philipp Böhm fdc1312c44
Merge pull request #26 from coldfix/expiration-days
Add DDNS_EXPIRATION_DAYS env variable
2020-10-02 20:14:54 +02:00
Thomas G 3e71d958bc Add DDNS_EXPIRATION_DAYS env variable 2020-10-02 12:10:35 +02:00
Philipp Böhm 3e9c5ef2c5
Merge pull request #22 from pboehm/fix_powerdns_build
Upgrade PowerDNS to 4.3 and use Debian Stretch as base image
2020-04-01 22:28:27 +02:00
Philipp Böhm 087acd1907 upgrade PowerDNS to 4.3 and use Debian Stretch as base image as packages for Debian Jessie are not available anymore 2020-04-01 21:55:06 +02:00
Philipp Böhm d7d7bcbad9 bump year in LICENSE and remove copyright from frontend template 2020-01-13 10:59:22 +01:00
Philipp Böhm 13dae077d9 add ACME_AGREE env variable to override sample and remove requirement for changing local path 2019-08-29 08:46:04 +02:00
Philipp Böhm 9d1d6cccdd
Merge pull request #16 from pboehm/build_failures
Fix Build Failures
2019-08-29 08:20:02 +02:00
Philipp Böhm 004db2f793 fix import path for gin-gonic, introduce go module and change base docker image 2019-08-26 12:00:32 +02:00
Philipp Böhm ba7d494fa3 remove duplicate protocol definition from sample dcker compose file 2018-02-27 18:28:11 +01:00
Philipp Böhm 983249def3 add security notice and change docker compose command to include --build 2018-02-11 22:41:35 +01:00
Philipp Böhm d7f4f8529d adjust the default docker compose setting to the values used in the override file 2018-02-11 22:26:13 +01:00
Philipp Böhm ffe0092e41 Fix horrible bug that exposes information about a registered host
Thank you @asterix11 for pointing this out.
2018-02-11 21:20:47 +01:00
Philipp Böhm 2223aca4b6 fix wrong word 2018-01-28 21:28:29 +01:00
Philipp Böhm e9730f6d31 small fixes in the README 2018-01-28 15:46:16 +01:00
Philipp Böhm c922c49e48
Merge pull request #2 from pboehm/docker_and_rework
Docker-Setup and Rework
2018-01-28 15:32:34 +01:00
15 changed files with 173 additions and 55 deletions

57
.circleci/config.yml Normal file
View File

@ -0,0 +1,57 @@
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,3 +2,5 @@
/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) 2018 Philipp Böhm
Copyright (c) 2020 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,18 +1,28 @@
# `ddns` - Dynamic DNS
A self-hosted Dynamic DNS solution similar to DynDNS or NO-IP.
[![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)
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`).
**Recent Changes**
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/).
`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.
<img src="screenshot.png" alt="screenshot" width="500"/>
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?
@ -47,17 +57,9 @@ 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.
to be made in a `docker-compose.override.yml` file
(a [sample](./docker/docker-compose.override.yml.sample) is available here).
#### Configuring the Setup
@ -75,12 +77,11 @@ 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.
started automatically after reboot. For updating an existing installation use the same command because it automatically
rebuilds the containers.
```
docker-compose --project-name ddns up -d
docker-compose --project-name ddns up -d --build
```

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,7 +51,13 @@ func (b *Backend) Run() error {
r.GET("/dnsapi/getDomainMetadata/:name/:kind", func(c *gin.Context) {
c.JSON(200, gin.H{
"result": false,
"result": []string{"0"},
})
})
r.GET("/dnsapi/getAllDomainMetadata/:name", func(c *gin.Context) {
c.JSON(200, gin.H{
"result": gin.H{"PRESIGNED": []string{"0"}},
})
})

View File

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

View File

@ -5,14 +5,15 @@ services:
environment:
DDNS_DOMAIN: d.example.net # <<< ADJUST DOMAIN
DDNS_SOA_DOMAIN: ddns.example.net # <<< ADJUST DOMAIN
DDNS_EXPIRATION_DAYS: 10
powerdns:
ports:
- "53/udp:53/udp"
- "53:53/udp"
redis:
volumes:
- "/root/ddns-redis:/data" # <<< ADJUST LOCAL PATH
- "${PWD}/.redis_mount:/data"
caddy:
restart: unless-stopped
@ -20,12 +21,13 @@ 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"
- "/root/ddns-caddy:/root/.caddy" # <<< ADJUST LOCAL PATH
- "${PWD}/.caddy_mount:/root/.caddy"
ports:
- "80:80"
- "443:443"

View File

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

View File

@ -1,12 +1,12 @@
FROM buildpack-deps:jessie-scm
FROM buildpack-deps:bookworm-scm
# 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/*
# 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/*
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,4 +1,3 @@
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,10 +60,8 @@ func (f *Frontend) Run() error {
var err error
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),
})
if _, err := f.hosts.GetHost(hostname); err == nil {
c.JSON(403, gin.H{"error": "This hostname has already been registered."})
return
}
@ -155,7 +153,7 @@ func buildTemplate() *template.Template {
}
func isValidHostname(host string) (string, bool) {
valid, _ := regexp.Match("^[a-z0-9]{1,32}$", []byte(host))
valid, _ := regexp.Match("^([a-zA-Z0-9]([a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9])?)$", []byte(host))
return host, valid
}

View File

@ -139,10 +139,6 @@ 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 Normal file
View File

@ -0,0 +1,10 @@
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 Normal file
View File

@ -0,0 +1,42 @@
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=

BIN
screenshot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 KiB