diff options
author | Mike Crute <mcrute@gmail.com> | 2017-01-22 19:04:41 -0800 |
---|---|---|
committer | Mike Crute <mcrute@gmail.com> | 2017-01-22 19:04:41 -0800 |
commit | fe67f1b502653683d50b0cba442af26e93f3034c (patch) | |
tree | 9c475fe949e9a8c648ec1818e473b8b1207797e1 /ddns | |
parent | 81fcfe8954a81deaa8702cd02831b256d9ade47c (diff) | |
download | dockerfiles-fe67f1b502653683d50b0cba442af26e93f3034c.tar.bz2 dockerfiles-fe67f1b502653683d50b0cba442af26e93f3034c.tar.xz dockerfiles-fe67f1b502653683d50b0cba442af26e93f3034c.zip |
Add dynamic dns handler
Diffstat (limited to 'ddns')
-rw-r--r-- | ddns/Dockerfile | 19 | ||||
-rw-r--r-- | ddns/Makefile | 11 | ||||
-rwxr-xr-x | ddns/bin/ddns.py | 79 | ||||
-rwxr-xr-x | ddns/bin/su-exec | bin | 0 -> 15752 bytes | |||
-rw-r--r-- | ddns/uwsgi.ini | 10 |
5 files changed, 119 insertions, 0 deletions
diff --git a/ddns/Dockerfile b/ddns/Dockerfile new file mode 100644 index 0000000..b112f56 --- /dev/null +++ b/ddns/Dockerfile | |||
@@ -0,0 +1,19 @@ | |||
1 | FROM ubuntu:14.04 | ||
2 | MAINTAINER Michael Crute <mike@crute.us> | ||
3 | |||
4 | RUN export DEBIAN_FRONTEND=noninteractive && \ | ||
5 | apt-get update && \ | ||
6 | apt-get install -y curl python-pip uwsgi uwsgi-plugin-python && \ | ||
7 | pip install flask boto && \ | ||
8 | useradd -r -M -d /srv -s /bin/nologin ddns | ||
9 | |||
10 | ADD uwsgi.ini /srv | ||
11 | ADD bin/* /srv/bin/ | ||
12 | |||
13 | RUN \ | ||
14 | apt-get clean && \ | ||
15 | rm -rf /var/lib/apt/lists/* && \ | ||
16 | rm -rf /tmp/* | ||
17 | |||
18 | STOPSIGNAL SIGINT | ||
19 | CMD ["/usr/bin/uwsgi", "--ini", "/srv/uwsgi.ini"] | ||
diff --git a/ddns/Makefile b/ddns/Makefile new file mode 100644 index 0000000..0d9df95 --- /dev/null +++ b/ddns/Makefile | |||
@@ -0,0 +1,11 @@ | |||
1 | all: | ||
2 | docker build -t ddns . | ||
3 | |||
4 | all-no-cache: | ||
5 | docker build --no-cache -t ddns . | ||
6 | |||
7 | run: | ||
8 | docker run -d \ | ||
9 | -p 9000:9000 \ | ||
10 | -v /srv/ddns/ddns.cfg:/etc/ddns.cfg \ | ||
11 | ddns | ||
diff --git a/ddns/bin/ddns.py b/ddns/bin/ddns.py new file mode 100755 index 0000000..5ec92da --- /dev/null +++ b/ddns/bin/ddns.py | |||
@@ -0,0 +1,79 @@ | |||
1 | #!/usr/bin/env python | ||
2 | |||
3 | import os | ||
4 | import flask | ||
5 | import hashlib | ||
6 | import functools | ||
7 | from boto.route53.record import ResourceRecordSets | ||
8 | from boto.route53.connection import Route53Connection | ||
9 | |||
10 | |||
11 | app = flask.Flask(__name__) | ||
12 | app.config.from_pyfile("/etc/ddns.cfg", silent=True) | ||
13 | app.config.from_pyfile("ddns.cfg", silent=True) | ||
14 | if "AMAZON_KEY_ID" not in app.config: | ||
15 | raise Exception("Not configured") | ||
16 | |||
17 | |||
18 | def returns_plain_text(f): | ||
19 | @functools.wraps(f) | ||
20 | def wrapper(*args, **kwargs): | ||
21 | return flask.Response(f(*args, **kwargs), content_type="text/plain") | ||
22 | |||
23 | return wrapper | ||
24 | |||
25 | |||
26 | def get_ip(): | ||
27 | if "X-Forwarded-For" in flask.request.headers: | ||
28 | return flask.request.headers["X-Forwarded-For"] | ||
29 | else: | ||
30 | return flask.request.remote_addr | ||
31 | |||
32 | |||
33 | def update_record(zone, record, ip): | ||
34 | conn = Route53Connection(app.config["AMAZON_KEY_ID"], | ||
35 | app.config["AMAZON_SECRET_KEY"]) | ||
36 | change_set = ResourceRecordSets(conn, conn.get_zone(zone).id) | ||
37 | change_set.add_change("UPSERT", record, type="A", ttl=60).add_value(ip) | ||
38 | change_set.commit() | ||
39 | |||
40 | |||
41 | @app.errorhandler(404) | ||
42 | @app.errorhandler(405) | ||
43 | @app.errorhandler(500) | ||
44 | def handle_error(ex): | ||
45 | response = flask.Response("Error", content_type="text/plain") | ||
46 | response.status_code = getattr(ex, "code", 500) | ||
47 | return response | ||
48 | |||
49 | |||
50 | @app.route("/new-secret", methods=["GET"]) | ||
51 | @returns_plain_text | ||
52 | def new_secret(): | ||
53 | return hashlib.sha256(os.urandom(100)).hexdigest() | ||
54 | |||
55 | |||
56 | @app.route("/update", methods=["POST"]) | ||
57 | def update_ip(): | ||
58 | key = flask.request.form.get("key") | ||
59 | config = app.config["CLIENTS"].get(key) | ||
60 | |||
61 | if not config: | ||
62 | flask.abort(404) | ||
63 | |||
64 | try: | ||
65 | update_record(config["zone"], config["resource"], get_ip()) | ||
66 | return "OK" | ||
67 | except: | ||
68 | flask.abort(500) | ||
69 | |||
70 | |||
71 | @app.route("/", methods=["GET"]) | ||
72 | @returns_plain_text | ||
73 | def handle_home(): | ||
74 | return get_ip() | ||
75 | |||
76 | |||
77 | if __name__ == "__main__": | ||
78 | app.debug = True | ||
79 | app.run() | ||
diff --git a/ddns/bin/su-exec b/ddns/bin/su-exec new file mode 100755 index 0000000..940f452 --- /dev/null +++ b/ddns/bin/su-exec | |||
Binary files differ | |||
diff --git a/ddns/uwsgi.ini b/ddns/uwsgi.ini new file mode 100644 index 0000000..8478fc0 --- /dev/null +++ b/ddns/uwsgi.ini | |||
@@ -0,0 +1,10 @@ | |||
1 | [uwsgi] | ||
2 | master = true | ||
3 | socket = :9000 | ||
4 | uid = ddns | ||
5 | gid = ddns | ||
6 | plugin = python | ||
7 | chdir = /srv/bin | ||
8 | workers = 2 | ||
9 | module = ddns:app | ||
10 | harakiri = 300 | ||