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