Skip to content

Commit f10fde9

Browse files
committedMay 8, 2022
initial commit, v0.9.0
0 parents  commit f10fde9

16 files changed

+1683
-0
lines changed
 

‎.ddns-aws.yaml

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# This is initial DDNS-AWS config file
2+
# but it will be overwritten by DDNS-AWS and comments will be lost!
3+
# ENV variables will take precendence over config AND will also overwrite config!
4+
#
5+
#
6+
# `make install` copies this config to `etc/.ddns-aws.yaml` but it can also be moved
7+
# to HOME directory of user running it
8+
9+
10+
#Port to run server on. DDNS_AWS_SERVER_PORT takes precendence if defined:
11+
server_port: 8125
12+
13+
#Username to authenticate ddns clients. DDNS_AWS_SERVER_USERNAME takes precendence if defined
14+
server_username: ddns
15+
16+
#Password (or key) to authenticate ddns clients. DDNS_AWS_SERVER_PASSWORD takes precendence if defined
17+
server_password: ddns
18+
19+
#path to server certificate (for HTTPS). DDNS_AWS_SERVER_CERT takes precendence if defined
20+
server_cert: ""
21+
22+
#path to server private key (for HTTPS). DDNS_AWS_SERVER_PRIVATE_KEY takes precendence if defined
23+
server_privatekey: ""
24+
25+
#NOTE: if certificate or private key is not specified, DDNS-AWS will run in HTTP mode (not recommended for production!)
26+
27+
28+
# AWS Route 53 access config. ENV variables (all caps) take precendence if defined
29+
AWS_region: ""
30+
AWS_Access_key_id: ""
31+
AWS_Secret_access_key: ""
32+
33+
34+
35+
36+
# No need to edit this line now. DDNS-AWS will update it using CLI. It contains list of active domains
37+
# (domains allowed to be managed by DDNS-AWS)
38+
active: []

‎.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
*.pem
2+
bin/

‎Dockerfile

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
FROM golang:alpine AS builder
2+
3+
RUN apk update && apk add --no-cache git ca-certificates && update-ca-certificates && rm -rf /var/cache/apk/*
4+
5+
WORKDIR /app
6+
7+
COPY go.mod ./
8+
COPY go.sum ./
9+
RUN go mod download
10+
COPY *.go ./
11+
COPY VERSION ./
12+
COPY .ddns-aws.yaml ./.ddns-aws.yaml
13+
RUN mkdir -p /certificates
14+
15+
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-w -s" -o /ddns-aws
16+
17+
18+
19+
20+
FROM scratch
21+
WORKDIR /
22+
VOLUME /etc
23+
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
24+
COPY --from=builder /etc/passwd /etc/passwd
25+
COPY --from=builder /etc/group /etc/group
26+
COPY --from=builder /ddns-aws /ddns-aws
27+
COPY --from=builder /app/.ddns-aws.yaml /etc/.ddns-aws.yaml
28+
COPY --from=builder /certificates /certificates
29+
30+
EXPOSE 8125
31+
32+
ENTRYPOINT ["/ddns-aws","server","run"]

‎LICENSE

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2020 Philipp Böhm
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

‎Makefile

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
version = $(file < VERSION)
2+
3+
build:
4+
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -ldflags="-w -s" -o bin/ddns-aws
5+
6+
install:
7+
install -m 755 ./bin/ddns-aws /usr/local/bin
8+
install -m 644 ./.ddns-aws.yaml /etc/
9+
10+
service:
11+
install -m 644 ./ddns-aws.service /etc/systemd/system/
12+
13+
docker:
14+
docker build -t psihoza/ddns-aws:latest .
15+
docker tag psihoza/ddns-aws:latest psihoza/ddns-aws:${version}
16+
17+
uninstall:
18+
rm /usr/local/bin/ddns-aws
19+
rm /etc/.ddns-aws.yaml
20+
rm /etc/systemd/system/ddns-aws.service
21+
22+
clean:
23+
go clean
24+
rm bin/*

‎README.md

+238
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,238 @@
1+
2+
[![MIT License](https://img.shields.io/apm/l/atomic-design-ui.svg?)](https://github.com/tterb/atomic-design-ui/blob/master/LICENSEs)
3+
![Docker Image Size (tag)](https://img.shields.io/docker/image-size/psihoza/ddns-aws/latest)
4+
5+
6+
```
7+
______ ______ __ _ _______ _______ _ _ _ _______
8+
| \ | \ | \ | |______ ___ |_____| | | | |______
9+
|_____/ |_____/ | \_| ______| | | |__|__| ______|
10+
11+
```
12+
13+
# DDNS-AWS
14+
15+
DDNS-AWSD is a self-hosted Dynamic DNS server that uses Amazon AWS Route53.
16+
## Features
17+
18+
- can be used as CLI tool, System service or Docker Image
19+
- minimal (less than 10MB), no-dependency binary written in Go. Docker image also less than 10MB
20+
- basic compatibility with Dynamic DNS Update API (https://help.dyn.com/remote-access-api/)
21+
- CLI to list/add/remove managed A records from AWS Route 53
22+
- CLI to manually update IP of selected A record
23+
24+
25+
## Requirements
26+
DDNS-AWS uses AWS Route53 DNS provider so you need at least 1 hosted zone on route 53 (which is free with AWS Free tier).
27+
28+
Next, you need AWS IAM user and policy configured, with minimal access rights for security reasons.
29+
You don't want your whole AWS account compromised if your config file gets exposed somehow.
30+
31+
Configuring AWS is out of the scope of this document, but short howto is:
32+
33+
1) Login to AWS Console and open the service 'IAM Managemenent Console'
34+
2) Click 'Policies' -> 'Create Policy' -> tab 'JSON'
35+
3) copy paste this (tighten `Resource` more if you don't want to give access to all DNS resources):
36+
```json
37+
{
38+
"Version": "2012-10-17",
39+
"Statement": [
40+
{
41+
"Sid": "VisualEditor0",
42+
"Effect": "Allow",
43+
"Action": [
44+
"elasticloadbalancing:DescribeLoadBalancers",
45+
"route53:ListHostedZones",
46+
"route53:ChangeResourceRecordSets",
47+
"route53:ListResourceRecordSets"
48+
],
49+
"Resource": "*"
50+
}
51+
]
52+
}
53+
```
54+
4) In next steps, name and describe your policy and click to create it.
55+
5) Under `Users` click `Add Users` and fill in details (for credentials type choose 'programmatic access')
56+
6) Next step is 'Permissions'. Click top box named 'attach existing policy directly'
57+
7) In the list below, search for the policy you just created and mark the checkbox next to it.
58+
8) Finish creating user. Last steps are selfe-xplanatory.
59+
9) You will be presented with access and secret keys. Copy them to safe place or download .csv
60+
61+
Now you have credentials needed for DDNS-AWS to connect to Route53 safely.
62+
63+
TLS Certificates are optional but highly recommended for production. This enables HTTPS and encryption.
64+
You can create self signed certificate (https://www.linode.com/docs/guides/create-a-self-signed-tls-certificate/),
65+
but idealy you should use free services like LetsEncrypt or similar (https://geekflare.com/free-ssl-tls-certificate/).
66+
Process of renewing certificates can also be automated.
67+
## Installation
68+
69+
There are 3 methods of installation and usage: CLI program, System Service or Docker image.
70+
71+
### Install as a CLI program
72+
73+
```bash
74+
git clone https://github.com/psiho/ddns-aws
75+
cd ddns-aws
76+
make build
77+
```
78+
79+
Now, edit `.ddns-aws.yaml` configuration file and then install with:
80+
```bash
81+
sudo make install
82+
```
83+
84+
Edit config file `/etc/.ddns-aws.yaml` and enter your server details. Also enter your AWS credentials to be able to connect to Route53 (described in 'Requirements' section).
85+
86+
Alternatively, you can use environment variables to specify most of the settings. Those values will take precendence over ones in config file.
87+
Also, note that DDNS-AWS will overwrite config file with values from ENV variables.
88+
89+
Environment variable names are:
90+
```
91+
DDNS_AWS_SERVER_PORT
92+
SERVER_USERNAME
93+
SERVER_PASSWORD
94+
SERVER_CERT
95+
SERVER_PRIVATEKEY
96+
AWS_REGION
97+
AWS_ACCESS_KEY_ID
98+
AWS_SECRET_ACCESS_KEY
99+
```
100+
### Install as a service
101+
This is a recommended method of installation if you plan to run it 24/7, which is expected way of using any DDNS service.
102+
103+
It should work on any Systemd linux variant.
104+
105+
After following above steps for installation as CLI, just add one more command:
106+
```bash
107+
sudo make service
108+
```
109+
start service with:
110+
```bash
111+
sudo systemnctl start ddns-aws
112+
```
113+
... then check status with:
114+
```bash
115+
sudo systemnctl status ddns-aws
116+
```
117+
If you want to enable automatic start at system startup:
118+
```bash
119+
sudo systemnctl enable ddns-aws
120+
```
121+
### Docker install
122+
Pre-built Docker image and instructions are at https://hub.docker.com/r/psihoza/ddns-aws
123+
124+
If you want to build your own image, `Dockerfile` is available in the root directory. You can create docker image with:
125+
```bash
126+
make docker
127+
```
128+
129+
You can run Docker image like:
130+
```bash
131+
docker run -it \
132+
-e AWS_REGION=<enter-aws-region> \
133+
-e AWS_ACCESS_KEY_ID=<your-key-from-aws-iam> \
134+
-e AWS_SECRET_ACCESS_KEY=<your-secret-key-from-aws-iam> \
135+
-e DDNS_AWS_SERVER_PORT=8125 \
136+
-e SERVER_USERNAME=<username-for-ddns-client> \
137+
-e SERVER_PASSWORD=<password-for-ddns-client> \
138+
-e SERVER_CERT=/certificates/<your-server-certificate> \
139+
-e SERVER_PRIVATEKEY=/certificates/<your-server-private-key> \
140+
--name=ddns-aws \
141+
-p 8125:8125 \
142+
-v <host-path-to-server-certificates>:/certificates \
143+
-d psihoza/ddns-aws
144+
```
145+
146+
How to get AWS keys and TLS Certificates? It is described above in 'Requirements' section.
147+
If you don't pass `SERVER_CERT` or `SERVER_PRIVATEKEY` server will run in HTTP mode (unencrypted!) which is not recommended for production!
148+
149+
If you want to run CLI commands in docker, from the host machine type:
150+
```bash
151+
docker exec -it ddns-aws /ddns-aws <command>
152+
```
153+
154+
155+
## Usage
156+
CLI can be used to configure service, enable or disable managed domains, update IPs, etc.
157+
158+
When updating IPs and managing records, service does not need to be restarted, config is reloaded automatically. Hoeverer, if you want to change Server settings or AWS credentials, it is recommended to restart the server.
159+
160+
### all command line options
161+
```bash
162+
Usage: ddns-aws <command>
163+
164+
Flags:
165+
-h, --help Show context-sensitive help.
166+
167+
Manage records:
168+
records list <zone-id>
169+
List all A records in the hosted zone
170+
171+
records activate <zone-id> <resource-name>
172+
Activate record for DDNS updates
173+
174+
records deactivate <resource-name>
175+
Deactivate record for DDNS updates
176+
177+
records update <resource-name> [<ip>]
178+
Manually update IP address of the record
179+
180+
Manage hosted zones:
181+
zones list
182+
183+
Server: Run DDNS server
184+
server run
185+
186+
Run "ddns-aws <command> --help" for more information on a command.
187+
```
188+
189+
If you want to run CLI commands in docker, from the host machine type:
190+
```bash
191+
docker exec -it ddns-aws /ddns-aws <command>
192+
```
193+
194+
## examples
195+
Note, if you only want to run ddns-aws as a regular user, you can move config file from `/etc` to the `$HOME` directory of that user. Sudo will not be needed then.
196+
197+
Usually, first command will be:
198+
```bash
199+
ddns-aws zones list
200+
```
201+
This will give you list of all your hosted zones and their IDs. Copy one of the zone IDs and list all A records:
202+
```bash
203+
ddns-aws records list <zoneID>
204+
```
205+
Note that all domains in the list are disabled by default(empty [ ]) and DDNS-AWS will refuse to update their IP records until activated. Do this by:
206+
```bash
207+
sudo ddns-aws records activate <zoneID> <my_domain_with_trailing_dot>
208+
```
209+
Check the list of domains again:
210+
```bash
211+
ddns-aws records list <zoneID>
212+
```
213+
... and your first domain should be active now. Let's update IP for it manually:
214+
```bash
215+
sudo ddns-aws records update <my_domain_with_trailing_dot> 8.8.8.8
216+
```
217+
You can try skipping 8.8.8.8 above. DDNS-AWS will try to figure out your IP, but if it fails, specify it manually like above. Then check status again:
218+
```bash
219+
ddns-aws records list <zoneID>
220+
```
221+
... and new IP should be displayed.
222+
223+
To manually start the server:
224+
```bash
225+
ddns-aws server run
226+
```
227+
But before running it, check your config file and server configuration.
228+
For production, it is strongly recommended to run DDNS-AWS as a service or as a Docker imagem, AND with server certificates configured in your config (which enables HTTPS).
229+
## Contributing
230+
231+
This is a project used to learn Go (I'm also using it for my own domains), so any help is appreciated. But my goal is to keep it simple and small so for bigger changes I guess forking is a better option.
232+
233+
234+
## License
235+
236+
[MIT](https://choosealicense.com/licenses/mit/)
237+
238+

‎VERSION

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
0.9.0

0 commit comments

Comments
 (0)