Виртуальный сервер: настройка всякого
В этой теме мы научимся заказывать и настраивать виртуальный сервер. Выкатим на него телеграм-бота, небольшую веб-страницу и настроим свой собственный vpn.
В этой теме мы научимся заказывать и настраивать виртуальный сервер. Выкатим на него телеграм-бота, небольшую веб-страницу и настроим свой собственный vpn.
Для работы под Windows установите следующие программы:
Искать дешёвый VPS удобно на сайте https://poiskvps.ru/. Для наших целей достаточно 1ГБ оперативки и 1 ядра процессора. Вы можете выбрать что-то своё, я буду показывать на примере skyhost и тарифа VDS-1: 149 рублей в месяц за 1ГБ оперативки и 1 ядро.
Итак, регаемся на skyhost (или где-то ещё) и заказываем новый VPS. При регистрации укажите не свои, но с виду валидные адрес и номер паспорта. Скажем, «ул. Трофимова, 15-24» и «4508956118». Имя сервера укажите какое вам нравится. Но лучше разумное, оно будет отображаться в консоли. В качестве операционной системы выбирайте Ubuntu 20.04 (amd64). Панель управления вам не нужна. Через некоторое время на почту придёт письмо вида
VDS-1 SSH-доступ: IP: 193.187.123.123 Login: root Password: somePassword
Этого достаточно, чтобы подключиться! Открываете Windows Terminal или PowerShell (или иной терминал) и вводите команду:
ssh root@193.187.123.123 -p 22
В этой команде root — это имя пользователя, дальше после @ идёт ip-адрес вашего сервера, а -p 22
— это указание порта для подключения.
По умолчанию порт и так 22, поэтому его можно и не указывать.
После подключения спросят пароль, введите его.
Если вы используете Windows Terminal, то для копипаста можно использовать Ctrl+C и Ctrl+V.
Иначе Ctrl+Insert для копирования и Shift+Insert для вставки.
Если всё получилось правильно, то вы получите ответ вида:
Welcome to Ubuntu 20.04.1 LTS (GNU/Linux 5.4.0-58-generic x86_64) * Documentation: https://help.ubuntu.com * Management: https://landscape.canonical.com * Support: https://ubuntu.com/advantage root@test179:~#
Если всё так, то поздравляю! Вы успешно подключились к своему новому виртуальному серверу!
В этой задаче нужно сдать в тестирующую систему две строчки: ip-адрес VPS'а и порт для подключения по SSH (стандартно 22). (Это после того, как вы получили доступ к своему VPS).
Взаимодействие с виртуальным сервером будут происходить через команды в терминале. Прочитать можно них можно вот здесь:
Полезно уметь делать стандартные штуки в терминале: скачивать файлы, перемещаться между папками, копировать, перемещать и удалять файлы и папки. А также искать файлы по имени и по содержимому.
Итак в этой задаче нужно сделать последовательность команд, после чего сохранить историю в файл output.txt и сдать его на проверку.
Лучше сначала убедиться, что вы всё понимаете, а потом провести чистовой проход.
В выдаче разрешаются лишние команды, но лучше оставить их поменьше.
Чтобы начать всё с начала:
# Удаляем архив и папку с файлами rm -f ~/bash.7z rm -rf ~/bash # Чистим историю history -c
~
.wget
'ом файл https://server.179.ru/tasks/python/2022b/attachments/bash.7z
.p7zip
, в котором архиватор 7-zip.bash.7z
в текущую папку (p7zip --help
в помощь).cntrl
(гуглить mkdir
).bash
, который был в архиве (гуглить cd
).ls
).ee
.one
из этого каталога в каталог cntrl
, созданный выше, вместе со всеми файлами и вложенными подкаталогами (гуглить cp
и использование ..
).one
каталога cntrl
, созданного выше (одной командой).two
из текущего каталога в родительский каталог вместе со всеми файлами и вложенными подкаталогами (гуглить mv
).two
родительского каталога (он должен быть создан в результате выполнения предыдущего пункта) (одной командой).cntrl/one
, который был создан выше (п.11). Используйте относительный путь
для задания адреса.cntrl/one
, который был создан выше (п.11). Используйте относительный путь для задания адреса.one
и two
(гуглить rm
).one
(не переходя в него!).one
все вложенные файлы и подкаталоги, не удаляя сам каталог one
и не переходя в него.one
(гуглить rmdir
).two
вместе со всеми содержащимися в нем файлами и подкаталогами.cntrl
вместе со всеми файлами и подкаталогами.bash/files/nose
(гуглить cat
).bash/files
, которые начинаются на fo
(гуглить find
).bash/rows/rows.txt
(гуглить head
).bash/rows/rows.txt
(гуглить tail
).bash/rows/rows.txt
, содержащие слово Artur
(гуглить grep
).bash/files
, содержащие слово fools
в любом регистре (выводить файл и пример строки) (снова гуглить grep
).history > output.txt
, отправьте его в тестирующую систему.Начинаться всё должно примерно так:
В этой задаче нужно создать нового пользователя при помощи команды adduser
.
Дайте ему какое угодно имя и какой угодно пароль (чур без пробелов внутри!).
Сдайте их в тестирующую систему в таком формате:
# Создаём restricted bash sudo ln -s /bin/bash /bin/rbash # Создаём папку для разрешённых бинарников (yourestricteduser — имя вашего пользователя) sudo mkdir /home/yourestricteduser/bin # Создаём ссылку на команду ls, чтобы её разрешить sudo ln -s /bin/ls /home/yourestricteduser/bin/ls # Ставим restricted bash при запуске sudo chsh -s /bin/rbash yourestricteduser # Настройка при логине echo 'export PATH=$HOME/bin' | sudo tee /home/yourestricteduser/.bash_profile
В идеале нужно научиться находить решения в интернете.
Поэтому все решения будут спрятаны за спойлерами.
Почти все запросы для поиска должны на старте выглядеть так: «ubuntu установить mc».
Если вам неохота искать и разбираться, то... открывайте спойлеры и вводите команды.
Даже это не всегда на 100% просто!
Если что-то не работает — спрашивайте/пишите.
После подключения по ssh под root'ом выполните команду:
apt install mc
Должно получиться в конце что-то такое:
root@test179:~# apt install mc Reading package lists... Done ... ... Setting up mc (3:4.8.24-2ubuntu1) ... update-alternatives: using /usr/bin/mcview to provide /usr/bin/view (view) in auto mode Processing triggers for man-db (2.9.1-1) ... Processing triggers for mime-support (3.64ubuntu1) ... Processing triggers for libc-bin (2.31-0ubuntu9.1) ... root@test179:~#
После установки выполните команду mc
.
И хотя «суровые админы» практически никогда не пользуются этой штукой, она может очень скрасить вам знакомство с администрированием linux.
Смотрите: там прямо сразу есть подсказка: переключение между Midnight commander'ом и консолью по клавишам Ctrl+O.
Запомните его, пригодится.
Для работы в консольном текстовом редакторе вам потребуются горячие клавиши Ctrl+S, чтобы сохранить изменения, и Ctrl+Q для выхода.
Чтобы система понимала, что вы «любите» русский язык в utf-8, нужно настроить локаль. Для этого нужно выполнить команды:
# Ставим пакет с русской локалью sudo apt-get install language-pack-ru # Ставим локалью по умолчанию utf-8 sudo update-locale LANG=ru_RU.UTF-8
Чтобы начало работать, нужно перезайти в терминал.
SSH (англ. Secure Shell — «безопасная оболочка») — сетевой протокол прикладного уровня, позволяющий производить удалённое управление операционной системой. Всё управление виртуальным сервером будет производиться как раз через SSH. Так как 99.9% серверов управляются через SSH, то много «желающих» ваш виртуальный сервер сломать и использовать его для каких-нибудь своих целей: рассылать спам, устраивать DDOS-адаки, майнить крипту и т.п. Поэтому для стандартного начала работы с новым сервером нужно сделать следующие шаги:
root
с паролем (пользователь root может сделать с системой вообще всё, что угодно).Ещё одна причина, почему с этого нужно начинать такая: в результате неаккуратной настройки можно потерять доступ к серверу. Потребуется переустановка операционной системы. Очень обидно, если это происходит, когда в системе уже сделано что-то полезное.
Итак, ключевые слова, чтобы искать: «ubuntu сменить порт для ssh», «ubuntu новый пользователь с правами root», «ubuntu windows ssh ключ». Ну, вы уже поняли, да?
Открываем конфиг демона, который рулит SSH'ем на сервере.
Он называется /etc/ssh/sshd_config
.
sudo nano /etc/ssh/sshd_config
Находите там строчку вида #Port 22
.
Удаляете решётку — это комментарий — и ставите порт 22179.
Сохраняете изменения.
Далее следует перезапустить демон SSH. Выполните команду:
sudo systemctl restart sshd
Проверяем порты SSH-сервера:
sudo ss -tupln | grep ssh # Должно получиться # serge@test179:~$ sudo ss -tupln | grep sshd # tcp LISTEN 0 128 0.0.0.0:22179 0.0.0.0:* users:(("sshd",pid=71737,fd=3)) # tcp LISTEN 0 128 [::]:22179 [::]:* users:(("sshd",pid=71737,fd=4))
Теперь не закрывая старый терминал (на случай, если что-то сделали не так), открываем новый и вводим в нём:
ssh root@193.187.123.123 -p 22179
Если всё пошло по плану, то вы должны успешно подключиться.
По идее вы уже должны были создать нового пользователя. Но если ещё нет, то
adduser serge
вводите пароль и соглашаетесь. Теперь нужно добавить пользователя в группу sudo:
usermod -aG sudo serge
Теперь логинитесь под этим пользователем:
ssh serge@193.187.123.123 -p 22179
И проверяете работу sudo:
sudo ls -la /root
Учтите, что последует запрос пароля. Это не запрос пароля root! Это ваш пароль!
Если на sudo вам отвечают что-то в духе «sudo: unable to resolve host somehosthere: Name or service not known»,
то нужно в файл /etc/hosts
добавить строчку вида
127.0.0.1 somehosthere
Редактировать /etc/hosts
нужно с sudo.
Чтобы вводить каждый раз пароль не требовался, можно добавить настройку в файл /etc/sudoers
.
На старте это очень удобно, но для «большого продакшена» не очень безопасно.
Только не нужно редактировать его явно, вместо этого нужно редактировать через visudo.
Так вы не сможете записать туда что-то невалидное и сломать систему.
Запустите редактирование командой
EDITOR=nano sudo -E visudo
и добавьте в конец (но не раньше строчки %sudo ALL=(ALL:ALL) ALL
) строчку вида (вместо serge ваш пользователь).
serge ALL=(ALL) NOPASSWD:ALL
Теперь нужно сгенерировать SSH-ключ (приватный и публичный).
Публичный записать в файл .ssh/authorized_keys
на сервере.
А приватный использовать для подключения.
Команда для подключения будет иметь вид:
ssh serge@193.187.175.97 -p 22179 -i "path\to\private_openSSH.ppk"
Если у вас linux или mac, то выполняете, то погуглите сами :). Если у вас Windows, то для создания ключа потребуется программа puttygen. Открыли? В заголовке «PuTTY Key Generator»? Если да, то поехали:
ssh-rsa
и т.д.private.ppk
.private_openSSH.ppk
.Ключ готов, а нам нужно подготовить для «место» на сервере. Вот команды с комментариями:
# Создаём папочку для ключей. Нужно один раз. mkdir ~/.ssh # Ставим нужные права на папочку. Чужим не подглядывать! chmod 0700 ~/.ssh # Создаём файлик, в котором лежат публичные ключи, по которым можно входить без пароля touch ~/.ssh/authorized_keys # Ставим нужные права на файлик. Чужим не подглядывать! chmod 0600 ~/.ssh/authorized_keys # Теперь нужно скопировать в буфер публичный ключ из окна puttygen # Открываем файлик на редактирование nano ~/.ssh/authorized_keys # Вставляем туда ключик. Выход по Ctrl+X # Как вариант, можно сразу вставить ключ командой вида echo 'ssh-rsa AAAAB3NzaC1...yQJQ== infkeyv2' >> ~/.ssh/authorized_keys
Отлично! Внесли ключ. Подключаемся командой в духе
ssh serge@193.187.175.97 -p 22179 -i "path\private_openSSH.ppk"
Но Windows вам ответит:
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: UNPROTECTED PRIVATE KEY FILE! @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Permissions for '...\\private_openSSH.ppk' are too open. It is required that your private key files are NOT accessible by others. This private key will be ignored. Load key ...\\private_openSSH.ppk": bad permissions
Тихо матерясь, нужно в винде поменять права к этому файлу (типа private_openSSH.ppk).
Повторяем:
ssh serge@193.187.175.97 -p 22179 -i "path\private_openSSH.ppk"
Вот теперь всё должно сработать! Вы должны успешно подключиться без пароля! Если пароль от пользователя всё ещё требуют, то что-то пошло не по плану. Обычно проблемы с правами. Сделайте
cd ~/.ssh ls -alh
У файла authorized_keys во владельцах должен стоять ваш пользователь! Если это не так, то нужно поменять владельца:
sudo chown serge:serge authorized_keys
Это наконец-таки совсем просто.
Но перед этим убедитесь, что можете подключиться под root'ом с SSH-ключом.
Под ним ваш публичный ключ тоже нужно будет добавить.
Если подключение без пароля работает, то в файле /etc/ssh/sshd_config
заменяете # PermitRootLogin yes
на PermitRootLogin no
.
Затем перезапустите демона: systemctl restart sshd
К концу этого блока вы должны иметь возможность подключаться к серверу командой вида
ssh serge@193.187.175.97 -p 22179 -i "path\to\private_openSSH.ppk"
Во-первых, под своим пользователем, во-вторых, по нестандартному порту, в-третьих, с использованием ключа. Обратите внимание, пароль при подключении не должен требоваться!
Когда подключение заработает, в windows терминале откройте параметры, слева внизу выберите «Добавить новый профиль», используйте пустой.
И «Имя» и в «Заголовок вкладки» введите то, что вам удобно.
А в «Командная строка» введите ту самую команду: ssh ну_и_так_далее
.
Создайте нового пользователя (если вы ещё не) (например, judge
).
Добавьте ему для подключения через ssh вот такой публичный ключ:
В тестирующую систему сдайте ip-адрес, порт и пользователя для подключения.
Здесь всё достаточно просто.
sudo apt install python3 python3-dev git wget unzip acl build-essential libssl-dev libffi-dev
Сюда входит свежий питон, компиляторы, архиваторы, компилятор си и т.п. Установка должна занять пару минут.
Чтобы перекидывать кучу файликов между Windows и сервером, удобно использовать программу WinSCP. Запускайте её. Она предложит выбрать подключение, которых ещё нет. Будем создавать.
Для каждого проекта мы будем создавать отдельного пользователя в отельной папке. Так проекты будут максимально независимы.
# Создаём папку проектов (если ещё не), и выставляем к ней права сразу sudo mkdir -m 755 /web
Теперь для каждого нового проекта мы будем создавать нового юзера и папочку. Лучше не включать в имя проекта подчёркивания или дефисы. Для своего нового проекта замените test179 на имя этого нового проекта. А serge замените на пользователя, под которым вы работаете.
cd /web # Содержимое каждого проекта будет находиться в собственном каталоге, # создаём нового пользователя, который будет «жить» в этой папке sudo useradd test179 -b /web/ -m -U -s /bin/false # Добавляем себя (в примере serge) в группу к этому пользователю, чтобы видеть «его» файлики sudo usermod -a -G test179 serge # Делаем юзера и его группу владельцем всех своих папок sudo chown -R test179:test179 /web/test179 # Изменяем права доступа на каталог (юзеру и группе можно, остальным — ни-ни) sudo chmod -R g+rwXs /web/test179 # Делаем так, чтобы все новые файлы и папки сразу принадлежали группе test179 sudo setfacl -R -d -m group:test179:rwx /web/test179 sudo setfacl -R -m group:test179:rwx /web/test179
Важно! Теперь нужно «перезайти» в терминал, чтобы права «прижились»!
# Перезагрузить shell (на самом деле это — хак, чтобы информация о группах обновилась) newgrp -
Благодаря -s /bin/false
в useradd залогиниться под этим юзером невозможно.
Но можно выполнять команды из-под него:
sudo -H -u test179 команда
Первая часть подготовки готова.
Теперь установим виртуальное окружение и поставим туда нужные библиотеки.
# Заходим в проект cd /web/test179 # Создаём виртуальное окружение python3 -m venv --without-pip test179_env # Заходим в это окружение source /web/test179/test179_env/bin/activate # Устанавливаем pip curl https://bootstrap.pypa.io/get-pip.py | python3 # Перезаходим в окружение deactivate source /web/test179/test179_env/bin/activate # Ставим нужные библиотеки pip install --upgrade pytelegrambotapi requests # Перезаходим в окружение deactivate # Передаём это всё во владение нашему проектному пользователю sudo chown -R test179:test179 /web/test179
Теперь при помощи WinSCP копируем файлик с кодом бота в папку /web/test179.
Пусть файл называется, скажем, bot.py
.
Перед первым запуском не забудьте добавить в начало файла настройки логирования:
import sys logging.basicConfig(stream=sys.stdout, level=logging.DEBUG) logging.getLogger('TeleBot').setLevel(logging.DEBUG)
Теперь можно запускать!
# Заходим в проект cd /web/test179 # Запускаем (сначала под собой) test179_env/bin/python bot.py # А ещё лучше запускаем под нашим проектным пользователем sudo -H -u test179 test179_env/bin/python bot.py
Хорошо, если бот работает в терминальчике! Но это всё ещё очень неудобно! Нужно, чтобы он работал... ну, как бы сам по себе, чтобы за ним можно было не присматривать. Для этого его нужно запустить в режиме демона (англ. «daemons») или сервиса. Де́мон — компьютерная программа в UNIX-подобных системах, работающая в фоновом режиме без прямого взаимодействия с пользователем. Это — то что нам нужно для работы бота.
Для этого существует штука, которая называется systemd — подсистема инициализации и управления службами в Linux. Короче, systemd запускает сервисы, описанные в его конфигурации. И перезапускает их при необходимости.
Внутри конфигурации можно написать много разных полезных штук: с какой рабочей директорией запускать сервис, под каким пользователем, нужно ли перезапускать, если сервис упадёт.
(Как обычно, test179 — это имя вашего проекта)
Вот пример конфигурации, которую нужно сохранить в файл test179.service
:
# Заходим в проект cd /web/test179 # Создаём конфиг для systemd nano test179.service
[Unit] # Описание Description=Мой супер телеграм-бот # Запускать только после того, как сеть оживёт After=network.target [Service] # В этом файле будет записан id процесса, в котором работает бот. Может быть удобно для разных целей PIDFile=/web/test179/test179.pid # simple — служба будет запущена незамедлительно. Может быть forking, но это вам не надо Type=simple # Пользователь и группа, из-под которой это всё работает. Указываем нашего проектного User=test179 Group=test179 # Рабочая папка WorkingDirectory=/web/test179 # Команда для старта бота. Здесь нужно указывать полный путь к python'у из окружения ExecStart=/web/test179/test179_env/bin/python bot.py # Нужно ли перезапускать, если бот упадёт? Restart=always RestartSec=5 [Install] # Многопользовательский режим без графики WantedBy=multi-user.target
Когда конфиг готов, создаём ссылку (алиас) на него, которую увидит SystemD (здесь нужно sudo, лезем в «чужую» вотчину):
sudo ln -s /web/test179/test179.service /etc/systemd/system/test179.service
Теперь проверяем наш конфиг на валидность:
sudo systemctl status test179 # Должна получиться выдача вида # ● test179.service - Мой супер телеграм-бот # Loaded: loaded (/etc/systemd/system/test179.service; disabled; vendor preset: enabled) # Active: inactive (dead)
Здесь мы видим, что сервис отключён (disabled) и не запущен (inactive). Следующий шаг — включить его (разрешить его запуск).
# Обновить список конфигов (нужно делать после редактирования service-файло/ sudo systemctl daemon-reload # Разрешаем запуск сервис sudo systemctl enable test179 # Проверяем текущий статус sudo systemctl status test179
# Пример выдачи ответа serge@test179:/web/test179$ sudo systemctl enable test179 Created symlink /etc/systemd/system/multi-user.target.wants/test179.service → /etc/systemd/system/test179.service. serge@test179:/web/test179$ sudo systemctl status test179 ● test179.service - Мой супер телеграм-бот Loaded: loaded (/etc/systemd/system/test179.service; enabled; vendor preset: enabled) Active: inactive (dead)
Теперь собственно запускаем сервис:
sudo systemctl start test179
и сразу проверяем его статус:
sudo systemctl status test179
# Пример выдачи ответа serge@test179:/web/test179$ sudo systemctl status test179 ● test179.service - Мой супер телеграм-бот Loaded: loaded (/etc/systemd/system/test179.service; enabled; vendor preset: enabled) Active: active (running) since Mon 2021-11-29 03:06:51 MSK; 28s ago Main PID: 88864 (python) Tasks: 4 (limit: 1111) Memory: 13.9M CGroup: /system.slice/test179.service └─88864 /web/test179/test179_env/bin/python bot.py ноя 29 03:06:51 test179 systemd[1]: Started Мой супер телеграм-бот. ноя 29 03:06:51 test179 python[88864]: DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): api.telegram.org:443 ноя 29 03:07:11 test179 python[88864]: DEBUG:urllib3.connectionpool:https://api.telegram.org:443 "GET /bot1231231231:ABABCBAB_asjkbakjasdhkbajsakhfj_asdfde>
Обратите внимание: DEBUG-сообщения будут только в том случае, если вы их включили :)
Но часто что-то не запускается.
Тогда статус будет не такой радужный.
Чтобы посмотреть лог, выполните:
sudo journalctl -u test179 --since "5 minutes ago" # Вместо "5 minutes ago" можно указать что-то более подходящее
Наконец, чтобы остановить сервис, нужно выполнить
sudo systemctl stop test179
Кстати, как только вы запустили sudo systemctl start test179
, systemd будет пытаться перезапустить ваш сервис в соответствии с настройками.
В нашем примере это каждые 5 секунд.
Не забудьте сделать stop, если бот заведомо неработоспособен.
Алиас — сокращенное имя консольной команды или даже серии команд. Алиас можно представить как ярлык (ссылку), который вызывает команду. Для создания временного алиаса нужно ввести команды в духе
alias ..="cd .." alias web='cd /web && ls -alh' alias ll="ls -alh" alias sstart="sudo systemctl start" alias sstop="sudo systemctl stop" alias sjrn='sudo journalctl --since "5 minutes ago" -u'
Чтобы сделать алиасы постоянными, их нужно добавить в файл ~/.bash_aliases
, после чего перезапустить bash:
# Добавляем алиасы nano ~/.bash_aliases
# Обновляем . ~/.bashrc
Осторожнее с редактированием файла .bashrc
!
Ошибка в нём может лишить вас возможности залогиниться под этим пользователем.
Выкатите на свой виртуальный сервер вот такого бота:
import telebot import subprocess, sys TOKEN = 'ЗДЕСЬ_ТОКЕН_ВАШЕГО_БОТА' bot = telebot.TeleBot(TOKEN) @bot.message_handler(content_types=['text']) def get_text_messages(message: telebot.types.Message): cmd = message.text if cmd == 'executable': msg = sys.executable elif cmd in ('whoami', 'pwd', 'ls', 'ps -f'): msg = subprocess.check_output(cmd, shell=True).decode('utf-8') else: msg = 'Низзя!' bot.send_message(message.from_user.id, msg) bot.infinity_polling()
В тестирующую систему сдайте имя бота.
nginx (по-русски произносится как э́нжин-и́кс) — веб-сервер, один из самых быстрых и надёжных. nginx может обрабатывать любые сетевые запросы к вашему серверу и либо отдавать соответствующий статический файл как есть, либо передать их вашему веб-приложению для обработки (тогда это называется «обратный прокси-сервер»). nginx берёт на себя кучу разной работы: маршрутизация, кеширование, фильтры, SSL и т.д.
Итак ставим nginx:
# Обновляем индекс пакетов sudo apt update # Ставим nginx sudo apt install nginx # Добавляем nginx в автозагрузку sudo systemctl enable nginx # Стартуем nginx sudo systemctl start nginx
Теперь вводите в браузере ip-адрес вашего сервера (например http://193.187.175.97/
),
и должна открыться стандартная заглушка «Welcome to nginx!».
Если открылась — ура, всё работает!
Настройки Nginx состоят из основного файла конфигурации и файлов для виртуальных хостов.
Самое главное правило — после редактирования конфига обязательно проверять его валидность командой
sudo nginx -t
Если конфиг валидный, то дальше можно перечитать конфиги:
sudo systemctl reload nginx
Если вы испортили конфиг, то может потребоваться перезапуск:
sudo systemctl status nginx sudo systemctl stop nginx sudo systemctl start nginx sudo systemctl status nginx
Ещё может пригодиться просмотр логов nginx'а:
# Последние 10 строчек лога ошибок sudo tail -n 10 /var/log/nginx/error.log # Последние 10 строчек лога запросов sudo tail -n 10 /var/log/nginx/access.log
Как и раньше, будем делать для каждого сайта отдельного пользователя и отдельную папку.
cd /web # Содержимое каждого проекта будет находиться в собственном каталоге, # создаём нового пользователя, который будет «жить» в этой папке sudo useradd web179 -b /web/ -m -U -s /bin/false # Добавляем себя (в примере serge) и www-data в группу к этому пользователю, чтобы видеть «его» файлики # www-data — это пользователь, под которым по умолчанию работает nginx sudo usermod -a -G web179 serge sudo usermod -a -G web179 www-data # Создаём папку для собственно статичных файлов. Важно, чтобы это была именно подпапка! sudo mkdir /web/web179/www # Делаем юзера и его группу владельцем всех своих папок sudo chown -R web179:web179 /web/web179 # Изменяем права доступа на каталог (юзеру и группе можно, остальным — ни-ни) sudo chmod -R g+rwXs /web/web179 # Делаем так, чтобы все новые файлы и папки сразу принадлежали группе web179 sudo setfacl -R -d -m group:web179:rwx /web/web179 sudo setfacl -R -m group:web179:rwx /web/web179
Важно! Теперь нужно «перезайти» в терминал, чтобы права «прижились»!
# Перезагрузить shell (на самом деле это — хак, чтобы информация о группах обновилась) newgrp -
Создаём файл index.html с тестовым содержимым.
# Заходим в папку с файлами cd /web/web179/www # Заливаем html. Эта команда сразу зальёт всё в файл, но можно и вручную через nano echo '<!DOCTYPE html> <html lang="ru"> <head> <meta charset="UTF-8"> <title>Это сайт!</title> </head> <body> Он работает! </body> </html> ' > /web/web179/www/index.html
Теперь создаём конфиг nginx для нашего корневого сайта
# Заходим в папку проекта cd /web/web179 # Заливаем конфиг. Эта команда сразу зальёт всё в файл, но можно и вручную через nano echo ' server { # слушаем 80-й порт (http без https) listen 80 default_server; # обрабатываем все запросы # (имя “_” не является особенным, это одно из некорректных имён, которые никогда не пересекутся с реальными) server_name _; # Корневая папка. Например, файл для запроса http://193.187.175.97/my/file.txt будет взят из /web/web179/www/my/file.txt (если он там будет) root /web/web179/www; # Запросы, которые заканчиваются слэшом (‘/’), будут направлены на этот файл index index.html; # Настройка для всех запросов, для которых нет более «точных» настроек location / { # First attempt to serve request as file, then as directory, then fall back to displaying a 404. try_files $uri $uri/ =404; } } ' > web179.conf
Когда конфиг готов, создаём ссылку (алиас) на него, которую увидит nginx (здесь нужно sudo, лезем в «чужую» вотчину):
sudo ln -s /web/web179/web179.conf /etc/nginx/conf.d/web179.conf
Теперь нужно отключить дефолтную настройку для корневого сайта:
sudo rm /etc/nginx/sites-enabled/default
Проверяем, валидный ли конфиг получился
sudo nginx -t # должно получиться # nginx: the configuration file /etc/nginx/nginx.conf syntax is ok # nginx: configuration file /etc/nginx/nginx.conf test is successful
И подтягиваем конфиг:
sudo systemctl reload nginx
Открываем теперь в браузере наш http://193.187.175.97, должны получить «Он работает!»
Если же что-то не работает, то нужно добавить в настройки логирование:
error_log /web/web179/log debug;
В результате будет получаться простыни логов, но можно будет хоть что-то понять.
Сделайте так, чтобы по адресу /judge_test/proof.txt лежал файл с содержимым Sure!
.
В тестирующую систему сдайте адрес этой страницы.
Чтобы можно было получить доступ к сайту по имени (в духе shashkovs.ru), а также для того, чтобы можно было использовать SSL (https и прочее шифрование), потребуется доменное имя и сертификаты. В некоторых вопросах без него можно обойтись, но это мы сейчас пропустим.
Купить доменное имя можно у регистраторов. При этом существует несколько сотен зон: типичные типа .ru, .com, .org, частые типа .me, и т.д. до совсем уж странных.
Доменное имя может иметь большую ценность (если вдруг вы законно завладеете именем google.ru, то сможете продать его за много миллионов долларов!). Поэтому с владением, продлением и передачей есть разнообразные формальные тонкости. Пока мы «развлекаемся», на них можно забить. Но как только вы начнёте делать что-то стоящее, убедитесь, что с вашим доменном всё ок.
Владение доменным именем требует трат двух типов: покупка и продление. Если вы ищете очень дешёвый домен, то может оказаться, что покупка стоит 50р, а продление — 10000р. Если ваш проект на таком домене взлетит, то будет очень обидно :)
Домен в зоне .ru стоит около 200р, продление — обычно около 200-300р в год. Некоторые провайдеры могут предлагать домен или продление «в подарок».
Вы можете использовать любого регистратора, но я буду рассказывать на примере beget.com. У других действуйте по аналогии.
Cначала вам нужно зарегистрироваться на https://beget.com.
Затем жмёте на «Баланс» и закидываете на счёт нужную сумму.
После этого вы идёте в Меню в раздел «Домены и поддомены», а потом жмёте «Регистрация доменов».
Вводите желаемое имя и выбираете в выпадающем списке подходящий (обратите внимание на стоимость покупки и продления!).
Полный список зон здесь.
Можете использовать домен в духе shashkov.fun
, он стоит всего 99 рублей.
Но продлять его будет дорого!
Потом потребуется ввести персональные данные.
В принципе можно ввести треш, но тогда в случае любых происшествий не удастся подтвердить, что домен ваш.
Выбор надёжность/приватность.
Теперь нужно настроить DNS. DNS — связь имени с IP адресом (если упростить). Для этого идём в меню, затем в DNS. В выпадающем списке под «Управление записями DNS» выбираете ваш нужный домен. Вам нужно добавить A-запись, в которой указан ip адрес вашего VPS. Но перед этим нужно удалить всё лишнее. Удаляете внизу все поддомены, которые beget добавил автоматически (www, autoconfig, autodiscover), а из основной записи удаляете A-строчку (карандашик, удалить, сохранить). Теперь в «Быстрое добавление» вы выбираете тип записи A, вводите ваш ip (например, 193.187.175.97) и жмёте «Добавить». Если у вас есть ip6 адрес (skyhost его пришлёт), то добавляете AAAA запись. ip6 адрес выглядит так: 2a0b:b200:b200:27c3:ef5f:6d39:b8d3:0001. Всё готово! Однако в браузере ваш новый адрес будет открывать не сразу. Потребуется некоторое время, пока dns-сервисы узнают об этом новом доменном имени. На это уйдёт от 5 минут до нескольких часов — как повезёт.
Аналогично любому домену можно добавлять поддомены (скажем, foo.shashkovs.ru, baz.shashkovs.ru, foo.baz.shashkovs.ru и т.п.). Для этого в настройках DNS выбираем «Добавить подзону» и настраиваем её аналогично.
Теперь, когда у вас есть своё доменное имя, мы можете сделать себе сертификат, который нужен для работы https и прочего. Сертификат подтверждает, что это именно ваш сервер отдаёт данные, а не какой-нибудь чужой и непонятный.
Чтобы получить сертификат, которому будут доверять браузеры, нужен центр сертификации, который проверит, что у вас и вправду есть доступ и к домену, и к серверу, и выпустит его. Мы будем использовать бесплатные сертификаты от Let’s Encrypt.
Для начала потребуется certbot — штука, которая позволяет получать и продлевать сертификаты в близком к автоматическому режиме.
sudo apt install certbot python3-certbot-nginx
Certbot предоставляет несколько способов получения сертификатов SSL. Для нас важны только два: в режиме «certonly» и в режиме «добавить в nginx». В самом «злом» режиме для создания сертификата нужно выполнить команду в духе
# Не запускать пока! sudo certbot certonly --standalone -d 50.proj179.ru
Но мы не будем использовать этот режим, а сразу будем использовать плагин Nginx. Он изменит конфигурацию Nginx и перезагрузит ее, когда это потребуется.
sudo certbot --nginx -d 50.proj179.ru
Потребуется ввести e-mail, на который будут высылать напоминания о необходимости продлить домен. Ещё будет вопрос про «redirect HTTP traffic to HTTPS». Ставьте «2: Redirect», чтобы не делать эту настройку вручную.
В результате получится выдача в духе
Congratulations! You have successfully enabled https://50.proj179.ru You should test your configuration at: https://www.ssllabs.com/ssltest/analyze.html?d=50.proj179.ru - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at: /etc/letsencrypt/live/50.proj179.ru/fullchain.pem Your key file has been saved at: /etc/letsencrypt/live/50.proj179.ru/privkey.pem Your cert will expire on 2022-03-05. To obtain a new or tweaked version of this certificate in the future, simply run certbot again with the "certonly" option. To non-interactively renew *all* of your certificates, run "certbot renew"
Важного тут вот что: ключи для домена лежат в /etc/letsencrypt/live/50.proj179.ru/
.
Для обновления сертификата нужно выполнить команду certbot renew
.
Но лучше, если обновление будет автоматическим:
sudo systemctl enable certbot.timer sudo systemctl start certbot.timer sudo systemctl status certbot.timer
Теперь вы можете открывать свой сайт по адресу в духе https://50.proj179.ru/.
Если у вас уже есть доменное имя, то для каждого проекта удобно использовать свой отдельный поддомен третьего уровня (это будет бесплатно). Это и упростит настройку, и сделает её гибче, и значительно упростит возможные переезды.
Ах, да! Эта процедура «испортила» вам конфиг nginx'а (в примере выше /etc/nginx/conf.d/web179.conf). Откройте и поглядите! Там добавились блоки, подписанные «managed by Certbot».
Сделайте так, чтобы по адресу /judge_test/proof.txt лежал файл с содержимым Sure!
.
В тестирующую систему сдайте адрес сервера.
Адрес должен начинаться с https.
To be done
TBD
To be done
OpenVPN — свободная реализация технологии виртуальной частной сети (VPN) для создания зашифрованных каналoв. Она позволяет соединять в единую «сеть» физически расположенные в разных местах сети и делать их коммуникацию недоступной для окружающих. А ещё она позволяет, например, присоединиться к сети виртуального сервера в Нидерландах и выходить в «мир» как бы оттуда. Иногда удобно :)
Устанавливаем OpenVPN и Easy-RSA для работы с секретными ключами.
sudo apt install openvpn easy-rsa
Первое что нужно сделать, это создать правильную инфраструктуру для генерации ключей. Все секретные ключи должны находится в надежном месте. В OpenVPN открытый ключ называется сертификатом и имеет расширение .crt, а закрытый ключ так и называется ключом, его расширение — .key. Обслуживать всё это мы будем с помощью набора скриптов Easy-RSA.
Создаём новую директорию от имени пользователя non-root с названием ~/easy-rsa, и создаём символьные ссылки на скрипты easyrsa у себя. Потом ставим «злые» права на эту папку: никому ни-ни:
# Создаём папку mkdir ~/easy-rsa # «Копируем» скрипты (создаём ссылки) ln -s /usr/share/easy-rsa/* ~/easy-rsa/ # Меняем владельца на себя (вместо serge пишите своего юзера) sudo chown -R serge ~/easy-rsa chmod 700 ~/easy-rsa
Далее нам нужно создать центр сертификации в этой папке:
создать папку pki и необходимые файлы для генерации сертификатов.
Но перед этим создадим файл с настройками.
ec — криптографии на эллиптических кривых (Elliptic Curve Cryptography, ECC) при генерации ключей,
sha512 — криптографически стойкая хеш-функция.
# Переходим в папку cd ~/easy-rsa/ # Заливаем настройки echo ' set_var EASYRSA_REQ_COUNTRY "RU" set_var EASYRSA_REQ_PROVINCE "Moscow" set_var EASYRSA_REQ_CITY "Moscow" set_var EASYRSA_REQ_ORG "" set_var EASYRSA_REQ_EMAIL "my@179.ru" set_var EASYRSA_REQ_OU "" set_var EASYRSA_ALGO "ec" set_var EASYRSA_DIGEST "sha512" ' > vars # Запускаем инициацию ./easyrsa init-pki # Должен получиться вывод в духе: # Note: using Easy-RSA configuration from: ./vars # init-pki complete; you may now create a CA or requests. # Your newly created PKI dir is: /home/serge/easy-rsa/pki
Теперь мы пачку сертификатов для сервера.
# Идём в папку сертификатов cd ~/easy-rsa # Создаём ключ центра сертификации # Там спросят Common Name, введите что-нибудь понятное (типа test179). # Без пароля (nopass) не очень безопасно, но тут уж решайте сами ./easyrsa build-ca nopass # Можно создать ключи Диффи-Хафмана, но мы пока мы планиуем использовать эллиптические кривые :) # Поэтому эта команда не нужна. Но если запустить, будет работать несколько минут. # sudo ./easyrsa gen-dh # Создаём ключ Hash-based Message Authentication Code (HMAC) sudo openvpn --genkey --secret ~/easy-rsa/pki/ta.key # Создаём ключ для отзыва подписанных сертификатов ./easyrsa gen-crl # Создаём сертификаты сервера ./easyrsa build-server-full server nopass
Теперь копируем все файлы в ключами в /etc/openvpn
sudo cp pki/ca.crt /etc/openvpn/ca.crt sudo cp pki/crl.pem /etc/openvpn/crl.pem sudo cp pki/ta.key /etc/openvpn/ta.key sudo cp pki/issued/server.crt /etc/openvpn/server.crt sudo cp pki/private/server.key /etc/openvpn/server.key
Все эти сертификаты надо будет использовать позже, при создании конфигурационного файла сервера.
По умолчанию, конфигурационных файлов OpenVPN нет. Создаём его из «рыбы»:
# Берём пример из архива в документации и кладём его в /etc/openvpn/server.conf zcat /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz | sudo tee /etc/openvpn/server.conf # Редактируем его sudo nano /etc/openvpn/server.conf
Конфиг, зараза, довольно большой. Поэтому при помощи Ctrl+W можно искать в нём нужные куски.
# Ищем tls-auth, заменяем на ;tls-auth ta.key 0 # This file is secret tls-crypt ta.key # Ищем cipher, заменяем на ;cipher AES-256-CBC cipher AES-256-GCM auth SHA256 # Ищем dh, заменяем на ;dh dh2048.pem dh none # Ищем ;user, убираем «;», должно получиться: user nobody group nogroup # Ищем redirect-gateway, убираем «;» push "redirect-gateway def1 bypass-dhcp" # Ищем dhcp-option, заменяем на push "dhcp-option DNS 8.8.8.8" push "dhcp-option DNS 1.1.1.1"
Сохраняете конфиг. Выводите все активные настройки:
cat /etc/openvpn/server.conf | grep -e "^[^#;]"
Должно получиться что-то такое:
port 1194 proto udp dev tun ca ca.crt cert server.crt key server.key # This file should be kept secret dh none server 10.8.0.0 255.255.255.0 ifconfig-pool-persist /var/log/openvpn/ipp.txt push "redirect-gateway def1 bypass-dhcp" push "dhcp-option DNS 8.8.8.8" push "dhcp-option DNS 1.1.1.1" keepalive 10 120 tls-crypt ta.key cipher AES-256-GCM auth SHA256 user nobody group nogroup persist-key persist-tun status /var/log/openvpn/openvpn-status.log verb 3 explicit-exit-notify 1
Настройка сервера OpenVPN завершена. Дальше необходимо запустить OpenVPN сервер.
# Проверяем конфиг: cd /etc/openvpn && sudo openvpn /etc/openvpn/server.conf # Должен быть вывод Initialization Sequence Completed. # Жмём Ctrl+C дважды, чтобы остановить # Если всё ок, добавляем в автозапуск sudo systemctl -f enable openvpn@server sudo systemctl start openvpn@server sudo systemctl status openvpn@server
Чтобы OpenVPN мог правильно перенаправлять трафик через сеть VPN, необходимо изменить некоторые параметры конфигурации сети сервера.
# Открываем конфиг sudo nano /etc/sysctl.conf
# В конец нужно добавить строчку net.ipv4.ip_forward = 1
# Обновляем текущую сессию sudo sysctl -p
Теперь надо разрешить прохождение пакетов в брандмауэре. Будем использовать iptables. Сначала надо посмотреть сетевой интерфейс для доступа к внешней сети.
ip -br a # Нужна строка вида # eth0 UP 193.187.175.97/24 fe80::f816:3eff:fe40:a1c0/64 # Вот eth0 — это то, что нам нужно
Теперь добавляем правила для iptables:
sudo iptables -I FORWARD -i tun0 -o eth0 -j ACCEPT sudo iptables -I FORWARD -i eth0 -o tun0 -j ACCEPT sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE # Смотрим, что получилось (и сохраняем) sudo iptables-save
TBD
TBD
To be done
TBD