Сегодня попробуем создать свой маленький уютный git, прямо у себя дома. В качестве которого будем использовать gitea. Данный сервис должен быть доступен из глобальной сети, и для это мы используем ранее поднятый vpn (wireguard
) сервер. По сути мы просто пробросим порты (80 и 433) из сервера с белым ip до компьютера находящегося в комнате. А также прикрутим поддомены к ip vpn-сервера. Это позволит открывать наши сервисы по доменному имени.
Железо
Для начала нам нужен компьютер для использования его в роли сервера, подойдет любой старый ПК или ноут. Дальше устанавливаем на него последнюю Debian, снимая все галочки с предложениями доп пакетов.
После установки скорее всего вы заметите что интернет, подключенный проводом (который работал при установки системы) не работает, это связанно с тем что нужно вручную получить IP через DHCP. Делается это очень просто:
sudo dhclient
ip a
Последняя команда покажет этот ip. В случае если вы хотите продолжить работать с кабелем, можно включить автоматическое получение ip при подключении витой пары. Для этого нужно в конец конфига /etc/network/interfaces
дописать следующие строки:
auto eth0
iface eth0 inet dhcp
Где eth0
это название вашего интерфейса.
Если же вы планируете подключать сервер через WiFi, то можно воспользоваться network-manager
c nmtui
, Однако сначала его нужно установить и да нужно обязательно сначала подключится по проводу, т.к. для настроики WiFi нужен специальный пакет, а для его установки нужен интернет. Когда интернет работает через провод устанавливаем network-manager
:
sudo apt install network-manager
nmtui
# тут выбираем в консольной GUI свою сеть, и вводим пароль
После того как заработал интернет нужно установить оставшиеся пакеты для работы:
sudo apt install tmux htop git ssh
Также, если вы используете ноутбук, нужно решить проблему ухода системы в сон при закрытии крышки, это явно не то поведение которое мы ожидаем от сервера. Для этого нужно будет исправить один конфиг:
sudo nano /etc/systemd/logind.conf
Поменять и раскомментировать в нем пару параметров:
HandleLidSwitch=ignore
HandleLidSwitchDocked=ignore
Так-же могут пригодится команды для проверки состояния батареи:
cat /sys/class/power_supply/BAT0/capacity #уровень заряда в процентах
cat /sys/class/power_supply/BAT0/status #статус батареи
Если вам (как и мне), не нравится то что терминал не отображает цвета при подключении по ssh то можно раскомментировать один параметр в файле ~/.bashrc
:
force_color_prompt=yes
Сеть
Первым делом попробуем настроить сеть, и получить доступ к тестовым страницам через nginx.
Поддомены
Для работы со своими доменными именами я использую этот сервис. В нем (хотя в любом другом это будет работать точно так-же) нужно добавить 2 А записи (с www
и без него):
У меня это git.your_domain.com
и www.git.your_domain.com
.
Проброс портов
Далее нам нужно пробросить порты (80 и 443) от сетевого интерфейса с белым ip до виртуального интерфейса wireguard. Для этого сначала нужно сгенерировать конфиг клиента wireguard для домашнего сервера (это делается на VPN сервере), напомню что для easy-wg-quick
который использовался тут делается это с помощью команд:
./easy-wg-quick server_git
sudo wg-quick down ./wghub.conf
sudo wg-quick up ./wghub.conf
В данном конфиге будет жёстко прописан ip (в дальнейшем он будет обозначатся как iptable
:
[Interface]
Address = <client_ip_vpn>/24
...
Далее, для проброса портов необходимо разрешить forwarding:
sudo nano /etc/sysctl.conf
Там необходимо раскомментировать 2 строки:
net.ipv4.ip_forward=1
net.ipv6.conf.all.forwarding=1
Дальше нужно настроить непосредственно проброс портов, через iptables
:
sudo iptables -A FORWARD -i eth0 -o wghub -j ACCEPT
sudo iptables -t nat -A PREROUTING -p tcp -d <server_ip_global> --dport 80 -j DNAT --to-destination <client_ip_vpn>:80
sudo iptables -t nat -A PREROUTING -p tcp -d <server_ip_global> --dport 443 -j DNAT --to-destination <client_ip_vpn>:443
sudo iptables -L -t nat
Тут используется ip адрес который мы посмотрели ранее в конфиге, а так-же физический ip (POSTROUTING
не нужен т.к. из-за использования сервера, как vpn, разрешены все маршруты.
Для удаления правила нужно сделать следующее:
sudo iptables -L -t nat --line-numbers
# тут смотрим номер нужного правила (например 3)
sudo iptables -t nat -D POSTROUTING 3
Эти настройки не сохранятся после перезагрузки, для того чтобы они применялись при старте системы, для начала, их нужно просто сохранить:
sudo /sbin/iptables-save | sudo tee /etc/iptables/rules.v4
sudo /sbin/ip6tables-save | sudo tee /etc/iptables/rules.v6
Для того чтобы эти параметры автоматически загружались при старте системы в debian есть специальный пакет:
sudo apt install iptables-persistent
NGINX
Теперь попробуем поднять тестовую страницу, что-бы убедится в том что все вышеперечисленное работает.
Первое что необходимо сделать это подключится по SSH к домашнему серверу и подключить сервер к vpn. Подробно этот процесс описан тут, так что тут описывать его не буду. После чего устанавливаем nginx и php:
sudo apt install -y nginx curl mariadb-server wget
Далее рассмотрим создание тестовой страницы, которая будет доступна в глобальной сети через доменное имя. У меня это доменное имя это git.zenembed.com
, но для удобства читателей в дальнейшем я буду обозначать его как git.your_domain.com
:
sudo mkdir -p /var/www/git.your_domain.com/html
sudo chown -R $USER:$USER /var/www/git.your_domain.com/html
sudo chmod -R 755 /var/www/git.your_domain.com
Создаем страницу и конфиг:
nano /var/www/git.your_domain.com/html/index.html
<html>
<head>
<title>Welcome to git.your_domain.com!</title>
</head>
<body>
<h1>Success! The git.your_domain.com server block is working!</h1>
</body>
</html>
sudo nano /etc/nginx/sites-available/git.your_domain.com
server {
listen 80;
listen [::]:80;
root /var/www/git.your_domain.com/html;
index index.html index.htm index.nginx-debian.html;
server_name git.your_domain.com www.git.your_domain.com;
location / {
try_files $uri $uri/ =404;
}
}
После включаем данный конфиг:
sudo ln -s /etc/nginx/sites-available/git.your_domain.com /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx
После этого по git.your_domain.com откроется тестовая страница.
SSL
Теперь необходимо получить сертификаты Let's Encrypt для нашей странице. Для этого будем использовать acme.sh. Скачиваем скрипт, переключаем на letsencrypt
и генерируем ключи:
sudo su
curl https://get.acme.sh | sh
mkdir -p /etc/nginx/certs/git.your_domain.com
exec $SHELL
acme.sh --set-default-ca --server letsencrypt
acme.sh --nginx --issue -d git.your_domain.com -d www.git.your_domain.com --key-file /etc/nginx/certs/git.your_domain.com/key.pem --fullchain-file /etc/nginx/certs/git.your_domain.com/cert.pem --reloadcmd "service nginx force-reload"
exit
Генерация происходит пользователем root
, это связанно с тем что скрипт вызывает nginx
, а это доступно только рут пользователю. Так-же данный скрипт сам создаст задачу в cron
которая раз в день будет проверять актуальность установленных сертификатов.
После этого нужно подправить конфиг nginx для тестовой страницы:
sudo nano /etc/nginx/sites-available/git.your_domain.com
server {
listen 443 ssl;
ssl_certificate /etc/nginx/certs/git.your_domain.com/cert.pem;
ssl_certificate_key /etc/nginx/certs/git.your_domain.com/key.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
root /var/www/git.your_domain.com/html;
index index.html index.htm index.nginx-debian.html;
server_name git.your_domain.com www.git.your_domain.com;
location / {
try_files $uri $uri/ =404;
}
}
sudo systemctl restart nginx
Теперь наша тестовая страница открывается по запросу с git.your_domain.com https
. Если вы попытаетесь открыть сайт без ssl (с http
) то будет открыта страница описанная в конфиге default
nginx. Для решения этой проблемы изменим дефолтный конфиг так, чтобы он всегда перенаправлял на версию сайта с SSL:
sudo nano /etc/nginx/sites-available/default
server {
listen 80 default_server;
server_name _;
return 301 https://$host$request_uri;
}
sudo systemctl restart nginx
UDP:
Может произойти так, что обновление сертификатов не будет работать с ошибкой 404. Это можно решить открытие 80-го порта и дальнейшее ручное обновление сертификатов. Для этого нужно добавить в конфиг nginx следующий блок:
server {
listen 80;
listen [::]:80;
server_name git.your_domain.com www.git.your_domain.com;
server_tokens off;
location /.well-known/acme-challenge/ {
allow all;
root /var/www/git.your_domain.com;
}
}
После чего обновляем сертификаты:
sudo systemctl restart nginx
acme.sh --nginx --issue -d cloud.your_domain.com -d www.cloud.your_domain.com --key-file /etc/nginx/certs/cloud.your_domain.com/key.pem --fullchain-file /etc/nginx/certs/cloud.your_domain.com/cert.pem --reloadcmd "service nginx force-reload" --force -w /var/www/cloud.your_domain.com/
Gitea
Теперь разберемся как поднять гит.
User
Для большей безопасности создадим отдельного пользователя для работы с этим приложением:
sudo adduser --system --shell /bin/bash --gecos 'Git Version Control' --group --disabled-password --home /home/git git
sudo passwd -d git
Mariabd
После установки mariadb-server
(это сделано в блоке nginx) её необходимо настроить, для этого нужно сначала запустить конфигурационный скрипт:
sudo mysql_secure_installation
Далее нужно настроить БД и установить пароль:
Enter current password for root (enter for none): Enter
Switch to unix_socket authentication [Y/n] : Y
Change the root password? [Y/n]: n
Remove anonymous users? [Y/n]: Y
Disallow root login remotely? [Y/n]: Y
Remove test database and access to it? [Y/n]: Y
Reload privilege tables now? [Y/n]: Y
После этого необходимо создать базу данных для нашего приложения:
sudo mysql -u root -p
> CREATE DATABASE gitea;
> GRANT ALL PRIVILEGES ON gitea.* TO 'gitea'@'localhost' IDENTIFIED BY "<your_bd_pass>";
> FLUSH PRIVILEGES;
> QUIT;
В <your_bd_pass>
нужно подставить свой пароль.
Установка gitea
Далее необходимо скачать и установить исполняемый файл gitea:
curl -s https://api.github.com/repos/go-gitea/gitea/releases/latest |grep browser_download_url | cut -d '"' -f 4 | grep '\linux-amd64$' | wget -i -
chmod +x gitea-*-linux-amd64
sudo mv gitea-*-linux-amd64 /usr/local/bin/gitea
gitea --version
Systemd
Для авто запуска необходимо создать сервис Systemd:
sudo mkdir -p /etc/gitea /var/lib/gitea/{custom,data,indexers,public,log}
sudo chown git:git /var/lib/gitea/{data,indexers,log}
sudo chmod 750 /var/lib/gitea/{data,indexers,log}
sudo chown root:git /etc/gitea
sudo chmod 770 /etc/gitea
sudo nano /etc/systemd/system/gitea.service
[Unit]
Description=Gitea (Git with a cup of tea)
After=syslog.target
After=network.target
After=mysql.service
[Service]
LimitMEMLOCK=infinity
LimitNOFILE=65535
RestartSec=2s
Type=simple
User=git
Group=git
WorkingDirectory=/var/lib/gitea/
ExecStart=/usr/local/bin/gitea web -c /etc/gitea/app.ini
Restart=always
Environment=USER=git HOME=/home/git GITEA_WORK_DIR=/var/lib/gitea
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now gitea
systemctl status gitea
Nginx
sudo nano /etc/nginx/sites-available/git.your_domain.com
server {
listen 443 ssl;
ssl_certificate /etc/nginx/certs/git.your_domain.com/cert.pem;
ssl_certificate_key /etc/nginx/certs/git.your_domain.com/key.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
server_name git.your_domain.com www.git.your_domain.com;
location / {
proxy_pass http://localhost:3000;
}
}
sudo systemctl restart nginx.service
После этого необходимо пройти по данному адресу и настроить пароль от БД а так-же прописать адрес сервера. Так-же было бы не плохо поменять некоторые парамеры в конфиге /etc/gitea/app.ini
:
# домашнаяя страница будет показывать открытые проекты
[server]
LANDING_PAGE = explore
# отключение возможности регистрации
[service]
DISABLE_REGISTRATION = true
# Так-же отключим показ версии пакета.
[other]
SHOW_FOOTER_VERSION = false
SHOW_FOOTER_TEMPLATE_LOAD_TIME = false
Для применения настроек нужно:
sudo systemctl restart gitea
Beckup
Последнее что необходимо сделать это настроить бекап для git, для чего используем скрипт:
dump_name=dump-$(date +"%d.%m.%Y-%H:%M")
dump_folder=/tmp/$dump_name
mkdir $dump_folder
chmod 777 $dump_folder
su - git -c "gitea dump -c /etc/gitea/app.ini --file $dump_folder/gitea.zip; chmod 666 $dump_folder/gitea.zip"
mysqldump -u gitea --password=<your_bd_pass> gitea > $dump_folder/gitea.sql
cd $dump_folder
tar -czvf $dump_folder.tar.gz *
chmod 666 $dump_folder.tar.gz
cd ~
mv $dump_folder.tar.gz .
rm -rf $dump_folder.tar.gz $dump_folder
Данный скрипт кидает архив с бекапом в home пользователя, не плохо было бы поменять это на внешний диск или флешку.
Для того чтобы этот скрипт запускался раз в день, нужно добавить задачу в cron:
crontab -e
# добавить строку
30 4 * * * ~/dump.sh