deploy: add notification proxy

jaseg-patch-1
jaseg 2020-01-17 11:11:52 +01:00
rodzic 40ae8e829c
commit 314d03748e
8 zmienionych plików z 196 dodań i 0 usunięć

Wyświetl plik

@ -1,2 +1,3 @@
*_secret.txt
*_apikey.txt
playbook.retry

Wyświetl plik

@ -129,6 +129,44 @@ http {
}
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name automation.jaseg.de;
root /usr/share/nginx/html;
ssl_certificate "/etc/letsencrypt/live/automation.jaseg.de/fullchain.pem";
ssl_certificate_key "/etc/letsencrypt/live/automation.jaseg.de/privkey.pem";
ssl_dhparam "/etc/letsencrypt/ssl-dhparams.pem";
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_stapling on;
ssl_stapling_verify on;
resolver 67.207.67.2 67.207.67.3 valid=300s;
resolver_timeout 10s;
add_header Strict-Transport-Security "max-age=86400";
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
location / {
include uwsgi_params;
uwsgi_pass unix:/run/uwsgi/notification-proxy.socket;
}
error_page 404 /404.html;
location = /40x.html {
root /usr/share/nginx/html;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;

Wyświetl plik

@ -0,0 +1,89 @@
import smtplib
import ssl
import email.utils
import hmac
from email.mime.text import MIMEText
from datetime import datetime
import functools
import json
import binascii
from flask import Flask, request, abort
app = Flask(__name__)
app.config.from_pyfile('config.py')
smtp_server = "smtp.sendgrid.net"
port = 465
mail_routes = {}
def mail_route(name, receiver, subject):
def wrap(func):
global routes
mail_routes[name] = (receiver, subject, func)
return func
return wrap
def authenticate(secret):
def wrap(func):
func.last_seqnum = 0
@functools.wraps(func)
def wrapper(*args, **kwargs):
if not request.is_json:
abort(400)
if not 'auth' in request.json and 'payload' in request.json:
abort(400)
if not isinstance(request.json['auth'], str):
abort(400)
their_digest = binascii.unhexlify(request.json['auth'])
our_digest = hmac.digest(secret.encode('utf-8'), request.json['payload'].encode('utf-8'), 'sha256')
if not hmac.compare_digest(their_digest, our_digest):
abort(403)
try:
payload = json.loads(request.json['payload'])
except:
abort(400)
if not isinstance(payload['seq'], int) or payload['seq'] <= func.last_seqnum:
abort(400)
func.last_seqnum = payload['seq']
del payload['seq']
return func(payload)
return wrapper
return wrap
@mail_route('klingel', 'computerstuff@jaseg.de', 'It rang!')
@authenticate(app.config['SECRET_KLINGEL'])
def klingel(_):
return f'Date: {datetime.utcnow().isoformat()}'
@app.route('/notify/<route_name>', methods=['POST'])
def notify(route_name):
try:
context = ssl.create_default_context()
smtp = smtplib.SMTP_SSL(smtp_server, port)
smtp.login('apikey', app.config['SENDGRID_APIKEY'])
sender = f'{route_name}@{app.config["DOMAIN"]}'
receiver, subject, func = mail_routes[route_name]
msg = MIMEText(func() or subject)
msg['Subject'] = subject
msg['From'] = sender
msg['To'] = receiver
msg['Date'] = email.utils.formatdate()
smtp.sendmail(sender, receiver, msg.as_string())
finally:
smtp.quit()
return 'success'
if __name__ == '__main__':
app.run()

Wyświetl plik

@ -0,0 +1,5 @@
SENDGRID_APIKEY = '{{lookup('file', 'notification_proxy_sendgrid_apikey.txt')}}'
DOMAIN = 'automation.jaseg.de'
SECRET_KLINGEL = '{{lookup('password', 'notification_proxy_klingel_secret.txt length=32')}}'

Wyświetl plik

@ -71,3 +71,6 @@
- name: Setup pogojig
include_tasks: setup_pogojig.yml
- name: Setup notification proxy
include_tasks: setup_notification_proxy.yml

Wyświetl plik

@ -0,0 +1,48 @@
---
- name: Create notification proxy worker user and group
user:
name: uwsgi-notification-proxy
create_home: no
group: uwsgi
password: '!'
shell: /sbin/nologin
system: yes
- name: Create webapp dir
file:
path: /var/lib/notification-proxy
state: directory
owner: uwsgi-notification-proxy
group: uwsgi
mode: 0550
- name: Copy webapp sources
copy:
src: notification_proxy.py
dest: /var/lib/notification-proxy/
owner: uwsgi-notification-proxy
group: uwsgi
mode: 0440
- name: Template webapp config
template:
src: notification_proxy_config.py.j2
dest: /var/lib/notification-proxy/config.py
owner: uwsgi-notification-proxy
group: root
mode: 0660
- name: Copy uwsgi config
copy:
src: uwsgi-notification-proxy.ini
dest: /etc/uwsgi.d/notification-proxy.ini
owner: uwsgi-notification-proxy
group: uwsgi
mode: 0440
- name: Enable uwsgi systemd socket
systemd:
daemon-reload: yes
name: uwsgi-app@notification-proxy.socket
enabled: yes

Wyświetl plik

@ -21,6 +21,7 @@
- kochbuch.jaseg.net
- tracespace.jaseg.net
- openjscad.jaseg.net
- automation.jaseg.de
- name: Copy uwsgi systemd socket config
copy:
@ -54,6 +55,7 @@
- tracespace.jaseg.net
- openjscad.jaseg.net
- pogojig.jaseg.net
- automation.jaseg.de
- name: Copy final nginx config
copy:

Wyświetl plik

@ -0,0 +1,10 @@
[uwsgi]
master = True
cheap = True
die-on-idle = False
manage-script-name = True
log-format = [pid: %(pid)|app: -|req: -/-] %(addr) (%(user)) {%(vars) vars in %(pktsize) bytes} [%(ctime)] %(method) [URI hidden] => generated %(rsize) bytes in %(msecs) msecs (%(proto) %(status)) %(headers) headers in %(hsize) bytes (%(switches) switches on core %(core))
plugins = python3
chdir = /var/lib/notification-proxy
mount = /=notification_proxy:app