Пишешь свою игру с поддержкой сети? Планируешь свой сайт или веб-сервис? Бот для телеграмма или навык Яндекс Алисы?
Всему этому нужен backend. А backend'у нужна инфраструктура.
Поднимаем свой сервер со своим доменом в интернете на Ubuntu Linux, настраиваем стек Nginx + Gunicorn + Flask, защищаем все соединения при помощи SSL.
Часть первая.
Дисклеймер (Disclaimer)
Это не универсальный метод настройки веб серверов, а всего лишь частное представление того, как это делаю я для своих проектов. Как говорил один кулинар, когда собирался готовить то ли борщ, то ли шурпу:
Знатоков того самого единственного правильного рецепта я попрошу сегодня не беспокоится.
Я не сторонник простых инструкций написанных по принципу - "скопируйте сюда этот файл, а сюда перепишите эту команду и нажмите ввод", однако и превращать эту статью в полный курс по всем аспектам затронутым в данном руководстве нет никакой возможности. Поэтому это будет некий средний вариант, где я буду показывать вам последовательность действий, попутно поясняя смысл введены команд, их ключей и параметров конфигурационных файлов.
Давайте попробуем разбить это руководство на некие условные этапы, но чёткой градации, как мне кажется, достичь просто невозможно, в том числе из-за сильной интеграции сервисов и процессов друг с другом.
Задача
Нам необходимо настроить и запустить веб-сервер, на котором будет работать на проект написанный на языке Python.
Какой проект? Да какой угодно. Веб сайт, чат бот для Telegram или навык для Яндекс Алисы или Google Assitant`а, возможно сервис который ведет статистику пользователей вашей игры, либо даже просто статичная веб страничка, вот, например, с этой инструкцией.
Где.
В первую очередь это вопрос про деньги, поскольку техническая реализация у поставщиков плюс-минус одинаковая. Поэтому ответ - где угодно, главное смотрите, что бы вам было комфортно по платежам.
Регистрация доменного имени. Я для этой цели воспользовался сервисом регистрации от AWS - Route 53. Просто потому, что я давно им пользуюсь, и это не первый домен который я у них регистрирую, вы же, повторюсь, можете воспользоваться услугами абсолютно любого регистратора.
Да, возможно кто то скажет - ну зачем я буду тратить лишние 10-20 долларов на доменное имя, если можно ходить на сервер просто по IP? И да, и нет. Современные правила работы предполагают использование зашифрованного соединения с нашим сервером, а сервисы предоставляющие сертификаты требуют именно зарегистрированное доменное имя, а не IP адрес. Без использования шифрования пользователь, в лучшем случае будет получать постоянные сообщения браузера об угрозе безопасности, а в худшем вообще не сможет подключится.
Итак, я только зарегистрировал имя blueoctopus.cc, и на текущий момент на нем ни одной записи.
Саму виртуальную машину мы сделаем в Yandex Cloud.
Ключи доступа.
Даже если это покажется странным, но начнем мы не с виртуальной, а с вашей домашней машины. Поскольку метод аутентификации на сервере предполагает использование пары ключей SSH (Secure SHell), то мы их сразу ее и создадим, что бы при создании виртуальной машины передать серверу открытую часть.
Итак, откроем консоль кликнув на соответствующую иконку, либо нажав комбинацию клавиш Ctrl + Alt + T (Command (⌘) + T) и перейдем в каталог назначенный по умолчанию для хранения ключей.
cd .ssh
Если такой папки нет, то ее необходимо создать
mkdir .ssh
Ключи удобнее хранить в специально обозначенном каталоге, тогда не прийдется каждый раз при подключении указывать параметр с его размещением.
Если при попытке выполнить указанные выше действия вы столкнулись с ошибками, то вероятно вы используете ОС Wndows на своем ПК. Насколько мне известно, на Windows 10 c 2018 позволяет использовать SSH, только его необходимо отдельно установить. Официальный сайт Microsoft говорит, что:
OpenSSH можно использовать для подключения устройств с Windows 10 (версия 1809 и более поздние) Чтобы установить компоненты OpenSSH, сделайте следующее:
Откройте приложение Параметры, выберите элементы Приложения > Приложения и возможности, щелкните Дополнительные возможности.
Просмотрите этот список и определите, установлено ли средство OpenSSH. Если нет, выберите пункт Добавить компонент в верхней части страницы и сделайте следующее:
Найдите Клиент OpenSSH и щелкните Установить.
Далее проблем с подключением у пользователей Windows быть не должно.
Продолжим. Напомню, у нас открыт терминал и мы находимся в папке .ssh
Напечатаем простую команду:
ssh-keygen
Генератор предложит вам указать уникальное название ключа, защитить его дополнительно паролем, и вроде бы будет еще пара вопросов, которые никто не читает.
Уникальное имя лучше придумать, это поможет когда ключей у вас станет больше чем один, а с паролем решайте сами.
В итоге у вас будет два файла: server_key - это ваш приватный ключ, его необходимо оставить в папке .ssh вашей домашней директории, и никому никогда не передавать. И server_key.pub - это, соответственно, публичная часть, содержимое которого необходимо загрузить при создании конфигурации нашей виртуальной машины.
Выведем содержимое публичного ключа и скопируем его в буфер обмена.
cat server_key.pub
Для удобства, большой точности и безопасности копирования в буфер можно воспользоваться утилитами xclip для Linux и pbcopy для MacOS.
Виртуальная машина в Yandex Cloud
Теперь откроем консоль Yandex Cloud. Если у вас нет аккаунта, то его придется создать, думаю, что с регистрацией на Яндекс проблем возникнуть не должно.
Далее в меню слева выбираем раздел Compute Cloud и нажимаем кнопку Создать ВМ. Я специально решил делать этот пример на сервисах яндекса, поскольку у них есть подробное описание каждого пункта меню на русском языке.
Большинство параметров в этом примере мы оставим по умолчанию, либо выберем минимальные, поскольку при возникновении потребности в дальнейшем увеличить их не составит труда.
Давайте быстро пройдемся по пунктам:
Имя и описание - все понятно, уникальное название и некоторые подробности, что бы вы сами не забыли что это за виртуалка крутится у вас в облаке.
Зона доступности - мне яндекс предложил ru-central-b, так и оставлю.
Операционная система - Ubuntu 20.04
Диск - HDD на 13 Gb
Платформа - Intel Ice Lake
vCPU - 2 (Количество ядер процессора, наверное хватило бы и одного, но яндекс так уже не предлагает)
Гарантированная доля vCPU - 20% (Минимальная гарантированная доля производительности. По моему опыту, при настройке загрузка ЦП не превышает 1-2%, так что этой доли нам более чем достаточно не только для настройки сервера, но и для небольших сервисов развёрнутых на нем.)
RAM - Очевидно оперативная память. Выбирайте минимум 2 GB
Прерываемая - самый спорный пункт. Его выбор делает большую скидку на ВМ, однако это дает право яндексу остановить ее в любой момент. Сервер будет остановлен корректно, так что за сохранность данных переживать не стоит, но включать его обратно прийдется "вручную". Для этого урока я этот пункт включу, но если настраиваемый вами сервер планируется в дальнейшем использовать в рабочем режиме, то выбирать этот пункт точно не стоит.
В сетевых настройках нас интересует только пункт Публичный адрес, все остальное оставляем без изменений.
Думаю здесь необходимо небольшое пояснение - в автоматическом режиме яндекс, конечно, предоставит публичный адрес, но проблема в том что при каждом перезапуске сервера он будет новым, что неприемлемо для настройки доменного имени. И да, это стоит отдельных денег, это нормально. Постоянно зарезервированный адрес стоит немного дороже, чем автоматический, и еще дороже будет стоить зарезервированный, но неиспользуемый адрес. (На момент написания этой статьи это около 150 рублей в месяц.)
В любом случае, когда вы выберите пункт "список", то скорее всего получите сообщение о том, что в вашем облаке нет свободных статических IP-адресов. В конце этого сообщения будет ссылка с названием "список адресов", смело нажимаем на нее и попадаем в раздел Virtual Private Cloud.
Выбираем в меню слева пункт "IP-адреса", и потом жмем на кнопку "Зарезервировать адрес", тут главное проследить что бы зона доступности, где резервируется адрес была той же, где создаётся сервер. Если все правильно - нажимаем "Зарезервировать" и возвращаемся к конфигурированию нашей ВМ.
Теперь при настройке публичного адреса в пункте список будет доступен наш зарезервированный IP. Выберем его и перейдём к настройке доступа.
Сервисный аккаунт - нужен если вы планируете получать доступ с виртуальной машины к другим ресурсам облака. (Например к серверу базы данных). В данном случае в нем нет необходимости.
Логин - имя пользователя в на сервере. Тут все просто, главное не выбирайте root или www-data. Я укажу просто max.
SSH-ключ - содержимое того самого server_key.pub, которое мы скопировали в буфер обмена. Просто вставьте его сюда.
Доступ к серийной консоли не включаем. Считайте это аварийным режимом, при штатной работе сервера он должен быть отключён.
Ну вот, теперь внимательно смотрим на правую колонку, и если цена нас устраивает - жмем на кнопку Создать ВМ внизу страницы.
Подключение к серверу
Наша виртуальна машина готова. Поскольку мы еще не строили доменное имя, то давайте подключимся по IP
ssh max@178.154.219.150
Тут все просто: login@ip-adress
Login - Логин, который мы указали при конфигурации.
ip-adress - Зарезервированный за ВМ статический адрес.
Если вы создали пароль к своему ключу, то после нажатия enter вам предложат его ввести. Если все сделано правильно, то увидим подобное сообщение:
The authenticity of host 'example.com (178.154.219.150)' can't be established.
ECDSA key fingerprint is SHA256:7Q4nIqjuo/lSXWFkt9RaJYVHrT6LUAc6KWrdQ4/DDeA.
Are you sure you want to continue connecting (yes/no/[fingerprint])?
Все в порядке, так и должно быть, это сервер присылает отпечаток ключа для проверки. Просто напечатаем yes и нажмем enter еще раз.
Все, теперь мы видим приглашение командной строки нашей виртуальной машины.
Установка утилит
Давайте для начала обновим данные о репозиториях:
sudo apt update
И, при необходимости, обновим сами пакеты:
sudo apt upgrade
Жмем (Y)es и немного подождем.
Кстати, пока идет обновление, обращу ваше внимание, что мы использовали sudo, для временного повышения полномочий, но пароль запрошен не был. Это странная особенность ВМ, и если вас это беспокоит - напишите, расскажу как это исправить.
Меня данная ситуация вполне устраивает, поэтому продолжаем. Большинство сервисов поставляют ВМ со схожим набором консольных утилит, но я предпочитаю все же выполнить установку одной строкой все требуемых мне, а не проверять их наличие по отдельности. Если что то из этого уже установлено - установщик просто пропустит этот шаг.
sudo apt install mc git curl wget rsync zip unzip
Опять же жмем (Y)es и немного подождем.
И что бы не терять время пройдемся по утилитам:
mc - Midnight Commander, консольный двух-панельный файловый менеджер. Большинство операций, я выполняю через него.
git - тот самый гит, очень пригодится, если захотим что нибудь клонировать с гитхаб или битбакет. Ну или наоборот отправить туда.
curl - Мне кажется не существует сетевого протокола, по которому эта утилита не могла бы послать запрос прямо из командной строки.
wget - качает файлы по ссылке. Можно конечно качать и с помощью curl, но эта мне как то привычнее.
rsync - удобная синхронизация файлов и каталогов, можно запускать по расписанию для создания резервных копий.
zip и unzip - очевидно архиваторы zip. Родные архиваторы bzip2 и gzip как правило есть всегда, а эти бывает, что и не установлены на старте.
Сервер SSH
Следующим шагом пройдёмся по параметрам сервера SSH, который отвечает за обработку нашего подключения.
Для этого откроем файл с настройками параметров.
Это можно сделать напечатав в командной строке:
sudo nano /etc/ssh/sshd_config
Либо запустив midnight commander, найти, выделить файл и нажать F4. При первом запуске МС попросить выбрать предпочитаемый редактор, рекомендую выбрать nano
sudo mc
И да, большую часть команд и правок мы будем вносить используя sudo, (Substitute User and do, дословно «подменить пользователя и выполнить»). Это необходимо для повышения наших полномочий до уровня root
Давайте взглянем на файл конфигурации. Большинство строк с параметрами комментированы символом #, предполагается, что значения указанные в них - будут использованы по умолчанию. Опираясь на один из принципов программирования "явное лучше чем неявное" - пройдемся по параметрам, которые я считаю важным указать явным способом.
Пройдемся по файлу сверху вниз, и первый параметр который нам нужен выглядит так:
PermitRootLogin prohibit-password
Очевидно из названия - разрешить руту подключатся удалённо с использованием непарольных методов аутентификации. Например сканер отпечатка, смарт-карта и т.д.
Раскомментируем строку и ставим значение в no:
PermitRootLogin No
Никаких удалённых авторизаций и входов для root
Следующий параметр отвечает за возможность авторизации по SSH ключу. Мы именно таким способом и зашли на наш сервер.
PubkeyAuthentication yes
Укажем это явно, оставляем yes по умолчанию, просто удалим знак комментария.
Дальше будет длинная строка с параметрами отделёнными табуляцией:
AuthorizedKeysFile .ssh/authorized_keys .ssh/authorized_keys2
Это указание на то где искать файл с публичными частями ключей для авторизации пользователей. Оставляем как есть, просто раскомментируем.
И последний обязательный пункт:
PasswordAuthentication yes
Удаляем символ комментария и устанавливаем параметр в no. Никаких парольных идентификаций, только файлы ключей.
PasswordAuthentication no
Ну а дальше, не скажу, что обязательный параметр, но просто убедитесь, что он выглядит именно так:
X11Forwarding yes
Если на сервер понадобится установить GUI, он поможет перенаправить вывод графической части запущенных приложений на вашу локальную машину.
Все. Теперь нажимаем Ctrl + X и подтверждаем запись файла.
Если вы использовали midnight commander то нажмите Ctrl + O, это скроет панели, отобразив терминал, но не закроет сам MC, так же как и не прервет сессию sudo. Повторное нажатие вернет панели обратно.
Перезапустим наш сервис SSH, что бы применить внесенные изменения.
sudo systemctl restart ssh
Можно отключится напечатав exit, и подключится опять, для проверки работоспособности, но это необязательно.
Есть что дополнить?
https://github.com/trash-max/howto
#server #ubuntu #Nginx #gunicorn #flask