klintorg_site/README.org
2022-11-12 22:34:59 +03:00

451 lines
14 KiB
Org Mode
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#+TITLE: Install server from scratch (Rocky Linux)
#+SUBTITLE: Quick reference card
#+AUTHOR: Norets Alexey
#+EMAIL: (concat "asnorets" at-sign "gmail.com")
#+DESCRIPTION: Rocky Linux from scratch
#+KEYWORDS: Rocky linux, gunicorn + nginx + flask
#+LANGUAGE: ru
#+OPTIONS: H:4 num:nil toc:2 p:t
* Установка сервера с нуля (gunicorn + nginx + flask) и настройка WireGuard
Данная инструкция предназначена для перенастройки сервера с сайтом и VPN.
** Создание и первоначальная настройка сервера
Создаем сервер. Заходим через SSH -> выходим -> копируем ключи на сервер:
#+begin_src shell
ssh <login>@<ip-address server>
exit
ssh-copy-id <login>@<ip-address server>
#+end_src
Теперь можем заходить по ключу (~/.ssh).
На сервере настраиваем SSH (запрет авторизации по паролю, запрет root по ssh):
#+begin_src shell
sudo vim /etc/ssh/sshd_config
#+end_src
Добавляем или изменяем строки:
#+begin_src conf
AllowUsers <login>
PermitRootLogin no
PasswordAuthentication no
#+end_src
Перезапускаем ssh:
#+begin_src shell
sudo systemctl restart sshd
#+end_src
** Установка необходимых пакетов
Обновляем систему:
#+begin_src shell
sudo dnf update
sudo dnf upgrade --refresh
#+end_src
Включаем CRB репозиторий:
#+begin_src shell
sudo dnf config-manager --set-enabled crb
#+end_src
Далее устанавливаем EPEL. Как я понимаю - это репозиторий Fedora:
#+begin_src shell
sudo dnf install \
https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm \
https://dl.fedoraproject.org/pub/epel/epel-next-release-latest-9.noarch.rpm
#+end_src
Ставим необходимые пакеты:
#+begin_src shell
sudo dnf install zsh htop nginx git wget vim python3-pip python3-devel gcc -y
sudo pip3 install virtualenv
#+end_src
Устанавливаем [oh-my-zsh](https://github.com/robbyrussell/oh-my-zsh):
#+begin_src shell
sh -c "$(curl -fsSL https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh)"
#+end_src
Добавляем в ~~/.zshrc~:
#+begin_src conf
# History
# хранить историю в указанном файле
export HISTFILE=~/.zsh_history
# максимальное число команд, хранимых в сеансе
export HISTSIZE=1000
export SAVEHIST=$HISTSIZE
# включить историю команд
setopt APPEND_HISTORY
# убрать повторяющиеся команды, пустые строки и пр.
setopt HIST_IGNORE_ALL_DUPS
setopt HIST_IGNORE_SPACE
setopt HIST_REDUCE_BLANKS
# alias ls='exa'
#+end_src
** Начинаем работу с проектом.
Создаем пользователя ~klintorg-www~:
#+begin_src shell
sudo mkdir /home/klintorg-www
sudo groupadd klintorg-www
sudo adduser -G nginx -g klintorg-www -d /home/klintorg-www klintorg-www --system --shell=/bin/false
#+end_src
~Временно~ выдаем права на папку ~klintorg-www~ и переходим в нее:
#+begin_src shell
sudo chmod -R 777 /home/klintorg-www
cd /home/klintorg-www
#+end_src
Клонируем проект:
#+begin_src shell
git clone https://github.com/Noretsa/klintorg.git
#+end_src
git запросит логин и пароль. Пароль необходимо создать, github -> settings -> Developer settings -> Personal access token -> Fine grained tokens. Дальше надо дать права токену, ну разберешься...
Переходим в папку проекта:
#+begin_src shell
cd klintorg
#+end_src
Создаем файл ~wsgi.py~:
#+begin_src shell
vim wsgi.py
#+end_src
В нем делаем так:
#+begin_src python
from __init__ import app
if __name__ == "__main__":
app.run()
#+end_src
Создаем папку окружения и ставим зависимости проекта:
#+begin_src shell
virtualenv .klintorg
source .klintorg/bin/activate
pip install -r requirements.txt
pip install gunicorn
deactivate
#+end_src
Разрешаем в firewall порт 5000 и 8000 для тестов:
#+begin_src shell
sudo firewall-cmd --add-port=5000/tcp --permanent
sudo firewall-cmd --add-port=8000/tcp --permanent
sudo firewall-cmd --reload
#+end_src
Чтобы посмотреть лист открытых портов:
#+begin_src shell
sudo firewall-cmd --list-all
#+end_src
Отключаем ~SELinux~:
#+begin_src shell
sudo vim /etc/selinux/config
#+end_src
#+begin_src conf
SELINUX=disabled #enforcing
#+end_src
Перезагружаемся:
#+begin_src shell
sudo reboot now
#+end_src
Теперь для ~klintorg-www~ назначаем права:
#+begin_src shell
sudo chown -R klintorg-www:nginx /home/klintorg-www
sudo chmod -R 755 /home/klintorg-www
#+end_src
** Тестим проект
Можем протестировать проект:
#+begin_src shell
cd /home/klintorg-www/klintorg
source .klintorg/bin/activate
python __init__.py
#+end_src
С локального компьютера открываем браузер на странице http://<ip-address server>:5000.
Если все работает - начинаем тестировать gunicorn:
#+begin_src shell
gunicorn --bind 0.0.0.0:8000 wsgi:app
#+end_src
С локального компьютера открываем браузер на странице http://<ip-address server>:8000.
Если все работет гасим gunicorn (ctrl+c) и деактивируем окружение python:
#+begin_src shell
deactivate
#+end_src
** Настраиваем Flask Application
Мы протестировали что наш ~gunicorn~ работает с нашим приложением Flask. Теперь необходимо сделать так, чтобы он загружался при старте системы. Чтобы этого добиться, мы создадим ~systemd service~ и ~socket file~.
~Gunicorn socket~ будет создаваться при загрузке системы и прослушивать соединения. Когда придет коннект, ~systemd~ автоматически запустит ~Gunicorn~ процесс для поддержания соединения.
Начнем с создания ~systemd socket~ файла:
#+begin_src shell
sudo vim /etc/systemd/system/klintorg.socket
#+end_src
Внутри создаем следующие секции:
#+begin_src conf
[Unit]
Description=klintorg socket
[Socket]
ListenStream=/run/klintorg.sock
[Install]
WantedBy=sockets.target
#+end_src
Далее создаем ~systemd service~ файл. Имя этого файла должно совпадать с именем ~socket~ файла:
#+begin_src shell
sudo vim /etc/systemd/system/klintorg.service
#+end_src
В этом файле будет так:
#+begin_src conf
[Unit]
Description=klintorg daemon
Requires=klintorg.socket
After=network.target
[Service]
User=nginx
Group=nginx
WorkingDirectory=/home/klintorg-www/klintorg
ExecStart=/home/klintorg-www/klintorg/.klintorg/bin/gunicorn \
--access-logfile - \
--workers 3 \
--bind unix:/run/klintorg.sock -m 007\
wsgi:app
[Install]
WantedBy=multi-user.target
#+end_src
Перезапускаем демоны:
#+begin_src shell
sudo systemctl daemon-reload
#+end_src
Теперь запускаем ~Gunicorn socket~, когда он запустится, он стартанет наш ~gunicorn service~:
#+begin_src shell
sudo systemctl start klintorg.socket
sudo systemctl enable klintorg.socket
#+end_src
** Настраиваем NGINX
Создаем файл конфигурации:
#+begin_src shell
sudo vim /etc/nginx/conf.d/klintorg.conf
#+end_src
В файл добавляем следующие строки:
#+begin_src conf
server {
listen 80;
server_name server_domain_or_IP;
location / {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://unix:/run/klintorg.sock;
}
}
#+end_src
Теперь разрешаем Nginx доступ к соккету gunicorn:
#+begin_src shell
sudo semanage permissive -a httpd_t
#+end_src
Так же разрешаем Nginx доступ к папке проекта (???????):
#+begin_src shell
sudo chgrp -R nginx /usr/share/nginx/html/klintorg-www/klintorg/
#+end_src
Проверяем синтаксис:
#+begin_src shell
sudo nginx -t
#+end_src
Запускаем и добавляем в автостарт nginx:
#+begin_src shell
sudo systemctl start nginx
sudo systemctl enable nginx
#+end_src
Открываем 80 и 443 порты на firewall:
#+begin_src shell
sudo firewall-cmd --add-port=80/tcp --permanent
sudo firewall-cmd --add-port=443/tcp --permanent
sudo firewall-cmd --reload
#+end_src
** Настраиваем сертификат Let's Encrypt
Ставим ~certbot~:
#+begin_src shell
sudo dnf install certbot python3-certbot-nginx
#+end_src
Ставим ~snapd~ для автопродления сертификата:
#+begin_src shell
sudo dnf install snapd
sudo systemctl enable --now snapd.socket
sudo ln -s /var/lib/snapd/snap /snap
exit
#+end_src
Необходимо перезайти в систему!
Запускаем:
#+begin_src shell
sudo certbot --nginx
#+end_src
Проверяем обновляется ли:
#+begin_src shell
sudo certbot renew --dry-run
#+end_src
Проверяем что встало автообновление:
#+begin_src shell
sudo systemctl list-timers -all
#+end_src
** Wireguard
# https://www.digitalocean.com/community/tutorials/how-to-set-up-wireguard-on-rocky-linux-8
# Это более полезна оказалась: https://unix.stackexchange.com/questions/713798/rocky-linux-9-wireguard-masquerade-traffic-to-internet-not-working
Начальная установка:
#+begin_src shell
sudo dnf install elrepo-release epel-release
sudo dnf install wireguard-tools
#+end_src
Генерируем ключи:
#+begin_src shell
wg genkey | sudo tee /etc/wireguard/private.key
sudo chmod go= /etc/wireguard/private.key
sudo cat /etc/wireguard/private.key | wg pubkey | sudo tee /etc/wireguard/public.key
#+end_src
Создаем файл конфигурации:
#+begin_src shell
sudo vim /etc/wireguard/wg0.conf
#+end_src
#+begin_src conf
[Interface]
Address = 10.8.0.1/24
# SaveConfig = true
ListenPort = 51820
PrivateKey = KM12oqlqAxKPyHXuOhL1XXcCeaGzYwAZ2pyYmHM8u2s=
PostUp = firewall-cmd --zone=public --add-masquerade; firewall-cmd --direct --add-rule ipv4 filter FORWARD 0 -i \
wg0 -o ens3 -j ACCEPT; firewall-cmd --direct --add-rule ipv4 nat POSTROUTING 0 -o ens3 -j MASQUERADE; firewall-c\
md --add-port=51820/udp
PostDown = firewall-cmd --zone=public --remove-masquerade; firewall-cmd --direct --remove-rule ipv4 filter FORWA\
RD 0 -i wg0 -o ens3 -j ACCEPT; firewall-cmd --direct --remove-rule ipv4 nat POSTROUTING 0 -o ens3 -j MASQUERADE;\
firewall-cmd --remove-port=51820/udp
[Peer]
PublicKey = ffLtSBKib0Wi7KnaEZXp7ZSWV+dswaPjPQHDYO1iiSQ=
AllowedIPs = 10.8.0.2/32
#+end_src
#+begin_src shell
sudo vim /etc/sysctl.conf
#+end_src
#+begin_src conf
net.ipv4.ip_forward=1
#+end_src
#+begin_src shell
sudo sysctl -p
#+end_src
# https://www.digitalocean.com/community/tutorials/how-to-set-up-a-firewall-using-firewalld-on-rocky-linux-9
Настраиваем Firewall (сначала делаем без этого, выше ссылка на инструкцию):
#+begin_src shell
firewall-cmd --permanent --direct --passthrough ipv4 -t nat -A POSTROUTING -s 10.8.0.0/24 -o enp0s3 -j MASQUERADE # это в первую очередь и проверяем, потом уже остальные
sudo firewall-cmd --zone=public --add-port=51830/udp --permanent
sudo firewall-cmd --zone=internal --add-interface=wg0 --permanent
sudo firewall-cmd --zone=public --add-rich-rule='rule family=ipv4 source address=10.8.0.0/24 masquerade' --permanent
# sudo firewall-cmd --zone=public --add-rich-rule='rule family=ipv6 source address=fd0d:86fa:c3bc::/64 masquerade' --permanent
sudo firewall-cmd --reload
#+end_src
Включаем ~Wireguard~:
#+begin_src shell
sudo systemctl enable wg-quick@wg0.service
sudo systemctl start wg-quick@wg0.service
#+end_src
*** Настройка клиента
Создаем папку в домашней директории:
#+begin_src shell
mkdir wg_norets
#+end_src
Создаем клиентскую пару ключей:
#+begin_src shell
wg genkey | tee /home/norets/wg_norets/norets_privatekey | wg pubkey | tee /home/norets/wg_norets/norets_publickey
#+end_src
Добавляем в конфиг WG:
#+begin_src shell
sudo vim /etc/wireguard/wg0.conf
#+end_src
#+begin_src conf
[Peer]
PublicKey = ll3VDt3gl81S54Lg9fX4wo2TylqfQLYZEB/63dxPgRg= # <norets_publickey>
AllowedIPs = 10.8.0.2/32
#+end_src
Перезапускаем сервис wireguard:
#+begin_src shell
sudo systemctl restart wg-quick@wg0
sudo systemctl status wg-quick@wg0
#+end_src
На клиенте создаем файл:
#+begin_src conf
[Interface]
PrivateKey = 2JgSg050VqNNgd+9rEt/NkhmuGTdzJNnzhNsDvIvSH8= # <CLIENT-PRIVATE-KEY>
Address = 10.8.0.2/32
DNS = 8.8.8.8
[Peer]
PublicKey = cW4mpBGG3CBcW01I2HTSXpyxzId72Lh/EAF5Q7iS3RQ= # <SERVER-PUBKEY>
Endpoint = 88.210.3.57:51830
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 20
#+end_src