diff options
Diffstat (limited to 'ddns.py')
-rwxr-xr-x | ddns.py | 79 |
1 files changed, 79 insertions, 0 deletions
@@ -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() | ||