klintorg_site/#README.org#
2024-02-19 13:18:14 +03:00

595 lines
17 KiB
Plaintext
Raw Permalink 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 vi /etc/ssh/sshd_config
#+end_src
Добавляем или изменяем строки:
#+begin_src conf
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
sudo dnf install epel-release
#+end_src
Ставим необходимые пакеты:
#+begin_src shell
sudo dnf install zsh vim htop nginx git wget vim python3-pip python3-devel gcc emacs-nox -y
sudo pip3 install virtualenv
#+end_src
Устанавливаем [[https://github.com/robbyrussell/oh-my-zsh][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
sudo firewall-cmd --add-port=8000/tcp
#+end_src
Чтобы посмотреть лист открытых портов:
#+begin_src shell
sudo firewall-cmd --list-all
#+end_src
** Тестим проект
Можем протестировать проект:
#+begin_src shell
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
Теперь для ~klintorg-www~ назначаем права:
#+begin_src shell
sudo chown -R klintorg-www:nginx /home/klintorg-www
sudo chmod -R 755 /home/klintorg-www
#+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
** Настраиваем 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 = MOJMpDrnsE5upIw9iqFQgkQnbsCAdQI17tL5mGuGRW8=
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-cmd --add-port=51820/udp
PostDown = firewall-cmd --zone=public --remove-masquerade; firewall-cmd --direct --remove-rule ipv4 filter FORWARD 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 = 6I+0r4jXDsPQJqHEsrNHNu44ZMS/tDivDFL7/rVRxV8=
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 = l3tzC968A9at/1AvLaxRX9BmUj9kfGFql3Y0HEk35So= # <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
** OpenVPN
*** Server
Просто приложу команды:
#+begin_src shell
sudo -i
dnf install openvpn
dnf install easy-rsa
mkdir /etc/easy-rsa
cp -air /usr/share/easy-rsa/3.0.8/* /etc/easy-rsa/ # last ver. 3.0.8
cd /etc/easy-rsa/
./easyrsa init-pki
./easyrsa build-ca
./easyrsa gen-dh
./easyrsa build-server-full server nopass
openvpn --genkey secret /etc/easy-rsa/pki/ta.key
./easyrsa gen-crl
cp -rp /etc/easy-rsa/pki/{ca.crt,dh.pem,ta.key,crl.pem,issued,private} /etc/openvpn/server/
#+end_src
*** Clients
#+begin_src shell
./easyrsa build-client-full gentoo nopass # 1 client
./easyrsa build-client-full johndoe nopass # 2 client
mkdir /etc/openvpn/client/{gentoo,johndoe}
cp -rp /etc/easy-rsa/pki/{ca.crt,issued/gentoo.crt,private/gentoo.key} /etc/openvpn/client/gentoo
cp -rp /etc/easy-rsa/pki/{ca.crt,issued/johndoe.crt,private/johndoe.key} /etc/openvpn/client/johndoe/
cp /usr/share/doc/openvpn/sample/sample-config-files/server.conf /etc/openvpn/server/
emacs /etc/openvpn/server/server.conf
#+end_src
Конфиг сервера:
#+begin_src conf
port 1194
proto udp4
dev tun
ca ca.crt
cert issued/server.crt
key private/server.key # This file should be kept secret
dh dh.pem
topology subnet
server 10.8.0.0 255.255.255.0
ifconfig-pool-persist ipp.txt
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 208.67.222.222"
push "dhcp-option DNS 192.168.10.3"
client-to-client
keepalive 10 120
tls-auth ta.key 0 # This file is secret
cipher AES-256-CBC
comp-lzo
user nobody
group nobody
persist-key
persist-tun
status /var/log/openvpn/openvpn-status.log
log-append /var/log/openvpn/openvpn.log
verb 3
explicit-exit-notify 1
auth SHA512
#+end_src
#+begin_src shell
mkdir /var/log/openvpn/
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
sysctl --system
firewall-cmd --add-port=1194/udp --permanent
firewall-cmd --add-masquerade --permanent
ip route get 8.8.8.8 # Чтобы посмотреть имя сетевого интерфейса ~ens3~
firewall-cmd --permanent --direct --passthrough ipv4 -t nat -A POSTROUTING -s 10.8.0.0/24 -o ens3 -j MASQUERADE
firewall-cmd --reload
systemctl enable --now openvpn-server@server
tail /var/log/openvpn/openvpn.log
#+end_src
Конфиг клиентов ~(client_file.ovpn)~:
#+begin_src conf
client
tls-client
pull
dev tun
proto udp4
remote 192.168.60.19 1194
resolv-retry infinite
nobind
#user nobody
#group nogroup
persist-key
persist-tun
key-direction 1
remote-cert-tls server
auth-nocache
comp-lzo
verb 3
auth SHA512
tls-auth ta.key 1
ca ca.crt
cert gentoo.crt
key gentoo.key
#+end_src
Работать будет только в том случае, если все сертификаты лежат рядом с файлом .ovpn. Иначе надо сертификаты писать в файл, вот так:
#+begin_src conf
client
tls-client
pull
dev tun
proto udp4
remote 192.168.60.19 1194
resolv-retry infinite
nobind
#user nobody
#group nogroup
persist-key
persist-tun
key-direction 1
remote-cert-tls server
auth-nocache
comp-lzo
verb 3
auth SHA512
<tls-auth>
-----BEGIN OpenVPN Static key V1-----
feb1af5407baa247d4e772c76aed6c75
...
-----END OpenVPN Static key V1-----
</tls-auth>
<ca>
-----BEGIN CERTIFICATE-----
MIIDTjCCAjagAwIBAgIUX0VQrHTgLDabUUIOAf7tD9cGp4YwDQYJKoZIhvcNAQEL
...
WA9BBk2shVWfR849Lmkep+GPyqHpU47dZAz37ARB2Gfu3w==
-----END CERTIFICATE-----
</ca>
<cert>
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
...
/7FvJaeLqmUHnvSs5eBlRZSgtOL19SCFkG0HXdnw3LtBaoHQXxgzOkDPW1+5
-----END CERTIFICATE-----
</cert>
<key>
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC+DI7kg6MsRoCs
...
6WdLcNtWKAcU294xJEZoOA8/
-----END PRIVATE KEY-----
</key>
#+end_src
Если работаем с OpenWRT - добавляем опцию (перед <tls-auth>) route-noexec.
После этого добавляем файл в OVPNClient и радуемся)