Initial commit
commit
2a217b5a82
|
@ -0,0 +1,4 @@
|
|||
*.py[co]
|
||||
config.cfg
|
||||
ovh.conf
|
||||
hook-config
|
|
@ -0,0 +1,20 @@
|
|||
local-letsencrypt
|
||||
=================
|
||||
|
||||
PoC for letsencrypt SSL certificates, as public, as local hswaw DNS zone is.
|
||||
|
||||
Usage
|
||||
-----
|
||||
cp server/config.cfg.dist server/config.cfg
|
||||
vim server/config.cfg
|
||||
|
||||
cp client/hook-config.dist client/hook-config
|
||||
vim client/hook-config
|
||||
|
||||
(cd server && python master.py) &
|
||||
|
||||
certbot-auto certonly --manual --preferred-challenges=dns \
|
||||
--manual-auth-hook `pwd`/client/install-hook.sh \
|
||||
--manual-cleanup-hook `pwd`/client/cleanup-hook.sh \
|
||||
--manual-public-ip-logging-ok \
|
||||
-d testing2.waw.inf.re
|
|
@ -0,0 +1,5 @@
|
|||
#!/bin/bash
|
||||
|
||||
. $(dirname $(realpath $0))/hook-config
|
||||
|
||||
curl "$API_URL/api/1/remove?token=$API_TOKEN&record=$CERTBOT_DOMAIN"
|
|
@ -0,0 +1,2 @@
|
|||
API_URL="http://localhost:5000" # you may want to keep it on ssl...
|
||||
API_TOKEN="testtoken"
|
|
@ -0,0 +1,11 @@
|
|||
#!/bin/bash
|
||||
|
||||
. $(dirname $(realpath $0))/hook-config
|
||||
|
||||
curl "$API_URL/api/1/add?token=$API_TOKEN&record=$CERTBOT_DOMAIN&value=$CERTBOT_VALIDATION"
|
||||
|
||||
# FIXME: ovh is shit
|
||||
while [ "$(dig _acme-challenge.$CERTBOT_DOMAIN TXT +short | wc -l)" -lt 1 ]; do
|
||||
echo 'still waiting...' >&2
|
||||
sleep 5;
|
||||
done
|
|
@ -0,0 +1,45 @@
|
|||
class Backend(object):
|
||||
def __init__(self, config):
|
||||
self.config = config
|
||||
|
||||
def add(self, name, value):
|
||||
raise NotImplemented
|
||||
|
||||
def remove(self, name):
|
||||
raise NotImplemented
|
||||
|
||||
|
||||
class OVHBackend(Backend):
|
||||
def __init__(self, config):
|
||||
import ovh
|
||||
import ovh.exceptions
|
||||
|
||||
self.config = config
|
||||
self.client = ovh.Client()
|
||||
try:
|
||||
self.client.get('/auth/currentCredential')
|
||||
except (ovh.exceptions.InvalidKey, ovh.exceptions.InvalidCredential):
|
||||
req = ovh.Client().request_consumerkey([
|
||||
{'method': 'GET', 'path': '/domain/zone/*/record'},
|
||||
{'method': 'POST', 'path': '/domain/zone/*/record'},
|
||||
{'method': 'POST', 'path': '/domain/zone/*/refresh'},
|
||||
{'method': 'DELETE', 'path': '/domain/zone/*/record/*'},
|
||||
])
|
||||
print(req)
|
||||
|
||||
def add(self, name, value):
|
||||
if not name.endswith(self.config['OVH_ZONE']):
|
||||
raise Exception()
|
||||
|
||||
v = self.client.post('/domain/zone/%s/record' % (self.config['OVH_ZONE'],),
|
||||
fieldType='TXT', subDomain=name+'.', target=value)
|
||||
print(v)
|
||||
self.client.post('/domain/zone/%s/refresh' % (self.config['OVH_ZONE'],))
|
||||
|
||||
def remove(self, name):
|
||||
ids = self.client.get(
|
||||
'/domain/zone/%s/record' % (self.config['OVH_ZONE'],), fieldType='TXT', subDomain=name+'.')
|
||||
for i in ids:
|
||||
print('Removing', i)
|
||||
self.client.delete('/domain/zone/%s/record/%d' % (self.config['OVH_ZONE'], i))
|
||||
self.client.post('/domain/zone/%s/refresh' % (self.config['OVH_ZONE'],))
|
|
@ -0,0 +1,7 @@
|
|||
# Global configuration
|
||||
TOKENS = {
|
||||
'testing3.waw.inf.re': 'testtoken',
|
||||
}
|
||||
|
||||
# OVH-specific backend configuration
|
||||
OVH_ZONE = 'inf.re'
|
|
@ -0,0 +1,26 @@
|
|||
import flask
|
||||
from flask import request
|
||||
|
||||
from backends import OVHBackend
|
||||
from utils import verify_token
|
||||
|
||||
app = flask.Flask(__name__)
|
||||
app.config.from_pyfile('config.cfg')
|
||||
|
||||
app.backend = OVHBackend(app.config)
|
||||
|
||||
@app.route('/api/1/add')
|
||||
@verify_token
|
||||
def add():
|
||||
app.backend.add('_acme-challenge.'+request.args['record'], request.args['value'])
|
||||
return 'ok'
|
||||
|
||||
@app.route('/api/1/remove')
|
||||
@verify_token
|
||||
def remove():
|
||||
app.backend.remove('_acme-challenge.'+request.args['record'])
|
||||
return 'ok'
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app.run(debug=True)
|
|
@ -0,0 +1,18 @@
|
|||
from functools import wraps
|
||||
from flask import current_app, request, abort
|
||||
|
||||
|
||||
def verify_token(f):
|
||||
"""Verifies request token"""
|
||||
|
||||
@wraps(f)
|
||||
def wrapped(*args, **kwargs):
|
||||
rec = request.args.get('record', None)
|
||||
token = request.args.get('token', None)
|
||||
|
||||
if rec in current_app.config['TOKENS'] and current_app.config['TOKENS'][rec] == token:
|
||||
return f(*args, **kwargs)
|
||||
|
||||
abort(403)
|
||||
|
||||
return wrapped
|
Loading…
Reference in New Issue