J'essaie d'apprendre comment je pourrais empêcher les données d'être modifiées après leur passage sur un réseau ouvert entre un serveur et un travailleur
dans ma tête, je pensais que cela devrait suivre quelque chose comme:
|server|---send_job----->|worker|
| |<--send_results--| |
| | | |
| |-send_kill_req-->| |
évidemment, je ne veux pas que quelqu'un modifie mon send_job
pour faire quelque chose de néfaste, et je ne veux pas que quelqu'un jette un œil à mes résultats.
j'ai donc une configuration client/serveur aiohttp
super simple dans laquelle j'essaie d'implémenter ssl
mais je suis complètement perdu.
ci-dessous est l'essentiel que j'ai essayé, mais j'ai également essayé d'implémenter mes propres certificats SSL via:
openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout domain_srv.key -out domain_srv.crt
ainsi que de suivre la documentation mais je ne suis toujours jamais en mesure de get
aucune réponse du tout.
Comment pourrais-je implémenter correctement le ssl_context
pour que ça marche?!
server.py
from aiohttp import web
import msgpack
import ssl
async def handle(request):
name = request.match_info.get('name', "Anonymous")
text = "Hello, " + name
return web.Response(text=text)
app = web.Application()
app.add_routes([web.get('/', handle),
web.get('/{name}', handle)])
ssl_context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH)
web.run_app(app, ssl_context=ssl_context)
client.py
import aiohttp import asyncio import ssl
async def main():
sslcontext = ssl.create_default_context(purpose=ssl.Purpose.CLIENT_AUTH)
async with aiohttp.ClientSession() as session:
async with session.get("https://0.0.0.0:8443", ssl=sslcontext) as response:
html = await response.read()
print(html)
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
python3 server.py
dans une fenêtrepython3 client.py
dans une autre fenêtreJe me retrouve ensuite généralement avec quelque chose comme:
Traceback (most recent call last):
File "/home/mEE/miniconda3/envs/py3/lib/python3.6/site-packages/aiohttp/connector.py", line 822, in _wrap_create_connection
return await self._loop.create_connection(*args, **kwargs)
File "/home/mEE/miniconda3/envs/py3/lib/python3.6/asyncio/base_events.py", line 804, in create_connection
sock, protocol_factory, ssl, server_hostname)
File "/home/mEE/miniconda3/envs/py3/lib/python3.6/asyncio/base_events.py", line 830, in _create_connection_transport
yield from waiter
ConnectionResetError
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "client.py", line 14, in <module>
loop.run_until_complete(main())
File "/home/mEE/miniconda3/envs/py3/lib/python3.6/asyncio/base_events.py", line 468, in run_until_complete
return future.result()
File "client.py", line 9, in main
async with session.get("https://0.0.0.0:8443", ssl=sslcontext) as response:
File "/home/mEE/miniconda3/envs/py3/lib/python3.6/site-packages/aiohttp/client.py", line 843, in __aenter__
self._resp = await self._coro
File "/home/mEE/miniconda3/envs/py3/lib/python3.6/site-packages/aiohttp/client.py", line 366, in _request
timeout=timeout
File "/home/mEE/miniconda3/envs/py3/lib/python3.6/site-packages/aiohttp/connector.py", line 445, in connect
proto = await self._create_connection(req, traces, timeout)
File "/home/mEE/miniconda3/envs/py3/lib/python3.6/site-packages/aiohttp/connector.py", line 757, in _create_connection
req, traces, timeout)
File "/home/mEE/miniconda3/envs/py3/lib/python3.6/site-packages/aiohttp/connector.py", line 879, in _create_direct_connection
raise last_exc
File "/home/mEE/miniconda3/envs/py3/lib/python3.6/site-packages/aiohttp/connector.py", line 862, in _create_direct_connection
req=req, client_error=client_error)
File "/home/mEE/miniconda3/envs/py3/lib/python3.6/site-packages/aiohttp/connector.py", line 829, in _wrap_create_connection
raise client_error(req.connection_key, exc) from exc
aiohttp.client_exceptions.ClientConnectorError: Cannot connect to Host 0.0.0.0:8443 ssl:<ssl.SSLContext object at 0x7fe4800d2278> [None]
Ce fut un problème en deux parties,
Je n'avais aucune idée de ce que je faisais avec openssl, la bibliothèque de requêtes m'a aidé à comprendre cela!
import requests
requests.get("https://0.0.0.0:8443", verify="domain_srv.crt")
SSLError: HTTPSConnectionPool(Host='0.0.0.0', port=8443): Max retries exceeded with url: / (Caused by SSLError(CertificateError("hostname '0.0.0.0' doesn't match None",),))
En fait, ces lignes que je viens de définir par défaut lors de la création de mes certificats openssl importaient réellement. Une configuration un peu plus correcte (mais probablement toujours erronée) similaire à
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:.
Locality Name (eg, city) []:.
Organization Name (eg, company) [Internet Widgits Pty Ltd]:.
Organizational Unit Name (eg, section) []:.
Common Name (e.g. server FQDN or YOUR name) []:0.0.0.0
Email Address []:.
m'a conduit au résultat:
import requests
requests.get("https://0.0.0.0:8443", verify="domain_srv.crt")
SubjectAltNameWarning: Certificate for 0.0.0.0 has no `subjectAltName`, falling back to check for a `commonName` for now. This feature is being removed by major browsers and deprecated by RFC 2818. (See https://github.com/shazow/urllib3/issues/497 for details.)
Il semblerait que 'subjectAltName' soit quelque chose d'un peu plus difficile à ajouter, nécessitant beaucoup plus de travail qu'une simple commande, vous voudrez suivre un guide comme this , je vais l'essayer et voir si cette erreur disparaît.
Je pense que j'utilisais ssl.Purpose.CLIENT/SERVER_AUTH
à tort, comme @Andrej l'a mentionné, j'ai changé cela (comme je vais le montrer ci-dessous) et j'ai apporté quelques autres changements et maintenant j'obtiens les bonnes réponses. Je vais juste dire que je ne comprends toujours pas ssl.Purpose
mais au moins j'ai quelque chose avec lequel je peux travailler pour le moment, et j'espère que je trouverai le reste à temps.client.py
import aiohttp
import asyncio
import ssl
async def main():
sslcontext = ssl.create_default_context(purpose=ssl.Purpose.SERVER_AUTH, cafile='domain_srv.crt')
async with aiohttp.ClientSession() as session:
async with session.get("https://0.0.0.0:8443/JOHNYY", ssl=sslcontext) as response:
html = await response.read()
print(html)
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
server.py
from aiohttp import web
import ssl
async def handle(request):
name = request.match_info.get('name', "Anonymous")
text = "Hello, " + name
return web.Response(text=text)
app = web.Application()
app.add_routes([web.get('/', handle),
web.get('/{name}', handle)])
ssl_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
ssl_context.load_cert_chain('domain_srv.crt', 'domain_srv.key')
web.run_app(app, ssl_context=ssl_context)
commandline
>python3 server.py
# Switch to a new window/pane
>python3 client.py
b'Hello, JOHNYY'
Vous créez les certificats mais ne les chargez pas dans la chaîne SSL. Et changez votre création ssl_context de ssl.Purpose.SERVER_AUTH
à ssl.Purpose.CLIENT_AUTH
:
from aiohttp import web
import ssl
async def handle(request):
name = request.match_info.get('name', "Anonymous")
text = "Hello, " + name
return web.Response(text=text)
app = web.Application()
app.add_routes([web.get('/', handle),
web.get('/{name}', handle)])
ssl_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
ssl_context.load_cert_chain('domain_srv.crt', 'domain_srv.key')
web.run_app(app, ssl_context=ssl_context)
Lorsque vous exécutez votre serveur, le client imprime lors de la connexion:
b'Hello, Anonymous'