-
Notifications
You must be signed in to change notification settings - Fork 111
/
Copy pathserver.py
111 lines (84 loc) · 4.94 KB
/
server.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# -*- coding: utf-8 -*-
from __future__ import print_function # для единого кода Python2, Python3
import sys
import argparse
from datetime import datetime
from werkzeug import serving
from flask import Flask, request
if sys.version_info >= (3, 0):
import ssl
else:
#pip install backports.ssl
#2.7.12-2.7.16 на Mac Flask с TLS дает исключение при подключении.
import backports.ssl as ssl
app = Flask(__name__)
"""
Настроим защищенную передачу данных от Вотериуса.
Создадим Центр сертификации и сгенерируем ключ/сертификат для сервера.
В Ватериус запишем сертификат Центра сертификации. Он подтвердит, что сервер тот, за кого себя выдает.
openssl genrsa -out ca_key.pem 2048
openssl req -x509 -new -nodes -key ca_key.pem -days 8000 -out ca_cer.pem -subj '/CN=192.168.1.10/C=RU/ST=Moscow/L=Moscow/O=Waterius LLC/OU=Waterius community'
openssl genrsa -out server_key.pem 2048
# Замените 192.168.1.10 на свой домен или IP адрес сервера (!). Именно его и подтверждает сертификат.
openssl req -out server_req.csr -key server_key.pem -new -subj '/CN=192.168.1.10/C=RU/ST=Moscow/L=Moscow/O=Waterius LLC/OU=Waterius community'
# в windows другие / надо указывать: openssl req -out server_req.csr -key server_key.pem -new -subj '//CN=192.168.1.10\C=RU\ST=Moscow\L=Moscow\O=Waterius LLC\OU=Waterius community'
openssl x509 -req -in server_req.csr -out server_cer.pem -sha256 -CAcreateserial -days 8000 -CA ca_cer.pem -CAkey ca_key.pem
ca_key.pem - ключ вашего Центра сертификации. Храним в сейфе.
ca_cer.pem - публичный X.509 сертификат Центра сертификации для генерации ключей сервера, служит и для проверки публичного ключа сервера.
server_key.pem - приватный ключ сервера. Только на сервере.
server_cer.pem - публичный ключ сервера. Может быть передан клиентам.
В память Вотериуса записываем ca_cer.pem . Теперь Вотериус может по передавать данные зашифровано, убеждаясь, что сервер настоящий.
Сертификат имеет срок годности и требует обновления.
Просмотреть содержимое сертификата:
openssl x509 -in ca_cer.pem -text
"""
@app.route('/data', methods=['POST'])
def root():
"""
Получение данных от Ватериуса
curl -X POST -d '{"ch0": 1, "ch1": 2, "key": "123", "delta0": 1, "delta1": 1,
"version": 1, "voltage": 3.0, "version_esp": "0", "resets": 0, "good": 0, "boot": 0}'
-H "Content-Type: application/json" http://192.168.1.10:10000/data -v
"""
try:
print(datetime.utcnow())
print(request.data)
j = request.get_json()
ret = 'OK' if j['ch0'] > 0 and j['ch1'] > 0 else 'ERROR null value'
print('{} ({}, {})'.format(ret, j['ch0'], j['ch1']))
except Exception as err:
return "{}".format(err), 400
return 'OK'
@app.route('/ping', methods=['GET'])
def ping():
"""
Проверка сервера GET запросом утилиты Curl:
curl https://192.168.1.10:10000/ping --cacert ./certs/ca_cer.pem
"""
return 'pong'
if __name__ == "__main__":
"""
Пример вызова скрипта:
HTTP сервер
python server.py --host 192.168.1.10 --port 10000
HTTPS сервер
сгенерируйте свои ключи и положите в папку certs. запишите в waterius ca_cer.pem.
python server.py --host 192.168.1.10 --port 10000 --tls
"""
parser = argparse.ArgumentParser(description='Waterius TLS server example')
parser.add_argument('--host', help='Ip address')
parser.add_argument('--port', type=int, default=443, help='Port') # in Mac, Linux use sudo for port < 1000
parser.add_argument('--cacert', default='certs/ca_cer.pem', help='CA certificate file')
parser.add_argument('--key', default='certs/server_key.pem', help='Private key')
parser.add_argument('--cert', default='certs/server_cer.pem', help='Certificate file')
parser.add_argument('--tls', action='store_true', help='Use HTTPS TLS 1.2')
args = parser.parse_args()
print(args)
if args.tls:
context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
#context.verify_mode = ssl.CERT_REQUIRED
context.load_verify_locations(args.cacert)
context.load_cert_chain(args.cert, args.key)
else:
context = None
serving.run_simple(args.host, args.port, app, ssl_context=context)