From 020648070174c7730e91577b3d5a4e17bd04aa96 Mon Sep 17 00:00:00 2001 From: "Gleb O. Ivaniczkij" Date: Tue, 13 Aug 2024 23:57:26 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D1=8B=20=D0=B2=D0=B5=D0=B1-=D0=BF=D1=80=D0=B8=D0=BB?= =?UTF-8?q?=D0=BE=D0=B6=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B8=20=D1=81=D0=B5?= =?UTF-8?q?=D1=80=D0=B2=D0=B5=D1=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/main.py | 14 ++++++++++++++ main.py | 19 +++++++++++++++++-- nginx/main.conf | 29 +++++++++++++++++++++++++++++ nginx/secure-headers.conf | 6 ++++++ requirements.txt | 3 +++ server/__init__.py | 1 + server/main.py | 21 +++++++++++++++++++++ web/__init__.py | 1 + web/main.py | 15 +++++++++++++++ 9 files changed, 107 insertions(+), 2 deletions(-) create mode 100644 nginx/main.conf create mode 100644 nginx/secure-headers.conf create mode 100644 server/__init__.py create mode 100644 server/main.py create mode 100644 web/__init__.py create mode 100644 web/main.py diff --git a/config/main.py b/config/main.py index 636b588..3696355 100644 --- a/config/main.py +++ b/config/main.py @@ -15,6 +15,20 @@ config.read( class Main: + host = config.get( + section='Main', + option='host', + fallback='localhost', + ) + port = config.getint( + section='Main', + option='port', + ) + title = config.get( + section='Main', + option='title', + fallback='CIT IS Bot', + ) cwd = config.get( section='Main', option='cwd', diff --git a/main.py b/main.py index 4f5265b..35eddd5 100644 --- a/main.py +++ b/main.py @@ -1,7 +1,22 @@ import asyncio +import uvicorn + from bot import bot, dp +import config +from web import app +from server import Server -if __name__ == "__main__": - asyncio.run(dp.run_polling(bot)) +if __name__ == '__main__': + config = uvicorn.Config( + app=app, + host=config.Main.host, + port=config.Main.port, + ) + server = Server( + config=config, + ) + + with server.run_in_thread(): + asyncio.run(dp.run_polling(bot)) diff --git a/nginx/main.conf b/nginx/main.conf new file mode 100644 index 0000000..87f17e5 --- /dev/null +++ b/nginx/main.conf @@ -0,0 +1,29 @@ +server { + listen 212.109.196.217:443 ssl; + listen [2a01:230:4:700::6969]:443 ssl; + + server_name cit.csasq.ru; + server_tokens off; + + ssl_certificate /etc/letsencrypt/live/csasq.ru/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/csasq.ru/privkey.pem; + + keepalive_timeout 30; + + location / { + include /opt/cit-is-bot/nginx/secure-headers.conf; + include ./conf.d/http-proxy.conf; + + proxy_pass http://cit.csasq.ru; + } + + location /static/ { + include /opt/cit-is-bot/nginx/secure-headers.conf; + include ./conf.d/gzip.conf; + + root /opt/cit-is-bot; + expires -1; + + add_header Service-Worker-Allowed /; + } +} diff --git a/nginx/secure-headers.conf b/nginx/secure-headers.conf new file mode 100644 index 0000000..0a94df3 --- /dev/null +++ b/nginx/secure-headers.conf @@ -0,0 +1,6 @@ +add_header Content-Security-Policy "default-src 'self'; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; script-src 'self' 'unsafe-inline' https://esm.run https://cdn.jsdelivr.net; font-src 'self' https://fonts.gstatic.com; img-src 'self' data:; media-src 'self' blob:; worker-src 'self' blob:"; +add_header X-Frame-Options "DENY"; +add_header X-Content-Type-Options "nosniff"; +add_header Strict-Transport-Security "max-age=31536000; includeSubDomains"; +add_header Referrer-Policy "origin"; +add_header X-XSS-Protection "1; mode=block; report=mailto:security@csasq.ru"; diff --git a/requirements.txt b/requirements.txt index 85efd53..9c0d153 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,8 @@ aiogram APScheduler +fastapi +jinja2 psycopg[binary] pydantic redis +uvicorn diff --git a/server/__init__.py b/server/__init__.py new file mode 100644 index 0000000..8bd1894 --- /dev/null +++ b/server/__init__.py @@ -0,0 +1 @@ +from .main import Server diff --git a/server/main.py b/server/main.py new file mode 100644 index 0000000..7920f98 --- /dev/null +++ b/server/main.py @@ -0,0 +1,21 @@ +import contextlib +import time +import threading + +import uvicorn + + +class Server(uvicorn.Server): + @contextlib.contextmanager + def run_in_thread(self): + thread = threading.Thread( + target=self.run, + ) + thread.start() + try: + while not self.started: + time.sleep(1e-3) + yield + finally: + self.should_exit = True + thread.join() diff --git a/web/__init__.py b/web/__init__.py new file mode 100644 index 0000000..e4c7aa5 --- /dev/null +++ b/web/__init__.py @@ -0,0 +1 @@ +from .main import app diff --git a/web/main.py b/web/main.py new file mode 100644 index 0000000..f6846a1 --- /dev/null +++ b/web/main.py @@ -0,0 +1,15 @@ +from fastapi import FastAPI + +import config + + +app = FastAPI( + title=config.Main.title, +) + + +@app.get( + path='/', +) +async def _(): + return ';-)'