Към съдържанието

Настройки за бисквитки

Изберете кои видове бисквитки разрешавате. Можете да промените избора си по всяко време чрез „Настройки за бисквитки“ в долната част на всяка страница. Декларация за поверителност

Необходими

Винаги включени

Нужни са за вход, за запазване на количката и на Вашите избори. Те са винаги включени.

Кои бисквитки?
  • weboke_sessie, weboke_klant, weboke_remember: Вашата сесия и оставането в акаунта
  • weboke_basket: Вашата количка
  • wkBtwIncl: показване на цените с или без ДДС
  • wok_cookies: Вашият избор за бисквитките, 12 месеца

Измерват коя реклама води до посещение или поръчка, за да не плащаме за реклами без резултат.

Кои бисквитки?
  • Google Ads чрез Google Tag Manager (_gcl_au, _gcl_aw), до 90 дни
  • OpenAI Ads, реклами в ChatGPT
  • wok_aff: кой партньор Ви е препратил към нас (партньорска програма), 60 дни

4,6

Държава и език

Всяка държава има собствен сайт, с цените и ДДС на тази държава.

Преглед

Собствени услуги и таймери

Модул 6: Услуги и логове · Време за четене: 11 минути

Цел на урока: След този урок ще можете да стартирате собствена програма като systemd услуга под отделен потребител, с няколко защитни опции, и да планирате задачи със systemd timer или cron.

Основни понятия: unit файл, [Unit], [Service], [Install], ExecStart, User=, WorkingDirectory, EnvironmentFile, Restart=, WantedBy, NoNewPrivileges, ProtectSystem, ProtectHome, PrivateTmp, systemd-analyze security, timer, OnCalendar, Persistent, crontab

Защо не просто "nohup" или "screen"?

Който качи собствена програма на сървър (малко уеб приложение, бот, скрипт, който всяка нощ върши нещо), често я стартира първия път ръчно: node server.js & или в сесия на screen. Това работи, докато не излезете от системата, сървърът не се рестартира или програмата не се срине. Тогава тя изчезва и никой не забелязва.

Програма, която трябва да работи постоянно, трябва да бъде systemd услуга. Тогава:

  • тя стартира автоматично при зареждане на системата;
  • systemd я стартира отново, ако се срине;
  • изходът ѝ отива в journal (урок 6.2);
  • тя работи под потребител, когото Вие изберете, с правата, които Вие разрешите.

Собствен unit файл

Да предположим, че имате малко Node.js приложение в /opt/factuurapp, което слуша на 127.0.0.1:3000. По-късно nginx или Caddy ще го направят достъпно навън (модул 7).

Стъпка 1: отделен потребител без shell (урок 3.2). Приложението не е нужно да бъде root и не е нужно да влиза в системата:

anna@web1:~$ sudo adduser --system --group --home /opt/factuurapp --no-create-home factuurapp
anna@web1:~$ sudo chown -R factuurapp:factuurapp /opt/factuurapp/data

Самият код може да остане собственост на root (приложението не е нужно да променя себе си); само папката, в която то пише, принадлежи на потребителя на услугата.

Стъпка 2: unit файлът. Собствените units се поставят в /etc/systemd/system/:

# /etc/systemd/system/factuurapp.service
[Unit]
Description=Factuurapp (Node.js)
After=network-online.target
Wants=network-online.target

[Service]
User=factuurapp
Group=factuurapp
WorkingDirectory=/opt/factuurapp
EnvironmentFile=/etc/factuurapp/env
ExecStart=/usr/bin/node /opt/factuurapp/server.js
Restart=on-failure
RestartSec=5s

NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
PrivateTmp=true
ReadWritePaths=/opt/factuurapp/data

[Install]
WantedBy=multi-user.target

Трите блока:

  • [Unit]: описание и ред на стартиране. After=network-online.target заедно с Wants= гарантира, че услугата стартира едва когато мрежата е налична.
  • [Service]: как работи програмата. ExecStart с пълния път (systemd не използва път за търсене като Вашия shell). User= и Group= определят под кой потребител. EnvironmentFile чете настройки, например парола за база данни, от отделен файл, така че те да не стоят в unit файла.
  • [Install]: какво прави enable. WantedBy=multi-user.target означава: стартирай при нормално зареждане на системата.

Стъпка 3: тайните отделно, със строги права.

anna@web1:~$ sudo mkdir /etc/factuurapp
anna@web1:~$ sudo install -m 600 -o root -g root /dev/null /etc/factuurapp/env
anna@web1:~$ sudoedit /etc/factuurapp/env

Съдържанието може да бъде например DATABASE_URL=postgres://factuur:...@127.0.0.1/factuur. systemd чете файла като root, преди да превключи към потребителя на услугата, затова 600 със собственик root е достатъчно.

Стъпка 4: зареждане, стартиране, проверка.

anna@web1:~$ sudo systemctl daemon-reload
anna@web1:~$ sudo systemctl enable --now factuurapp
anna@web1:~$ systemctl status factuurapp
anna@web1:~$ journalctl -u factuurapp -f

Защитни опции: малко усилие, голяма разлика

Четирите реда под RestartSec в примера ограничават какво може да прави услугата, дори ако някой открие уязвимост във Вашето приложение:

ОпцияЕфект
NoNewPrivileges=trueпроцесът и неговите дъщерни процеси никога не могат да получат повече права (нито чрез sudo, нито чрез setuid програми)
ProtectSystem=strictцялата файлова система е само за четене за услугата, освен това, което разрешите с ReadWritePaths=
ProtectHome=true/home, /root и /run/user са невидими
PrivateTmp=trueсобствена, празна /tmp, която другите програми не виждат

systemd може да оцени Вашия unit:

anna@web1:~$ systemd-analyze security factuurapp
...
→ Overall exposure level for factuurapp.service: 4.9 OK 🙂

Колкото по-ниско е числото, толкова по-добре. Услуга без опции получава около 9 ("UNSAFE"). Не е нужно да стигате до нула: всяка добавена опция може да счупи нещо, от което приложението се нуждае. Добавяйте ги една по една и тествайте след всяка стъпка. Ако нещо спре да работи, причината обикновено е в journal ("Read-only file system", "Permission denied").

Планиране на задачи: таймери

За нещо, което трябва да се случва в определено време (резервно копие, скрипт за почистване, отчет), Ви е нужен timer. Един systemd timer се състои от два units с едно и също име: .service, който казва какво трябва да се направи, и .timer, който казва кога.

# /etc/systemd/system/opruimen.service
[Unit]
Description=Oude exportbestanden opruimen

[Service]
Type=oneshot
User=factuurapp
ExecStart=/usr/bin/find /opt/factuurapp/data/export -type f -mtime +30 -delete
# /etc/systemd/system/opruimen.timer
[Unit]
Description=Dagelijks oude exportbestanden opruimen

[Timer]
OnCalendar=*-*-* 03:15:00
RandomizedDelaySec=10m
Persistent=true

[Install]
WantedBy=timers.target

Type=oneshot означава: програмата се изпълнява и след това приключва. OnCalendar е графикът: всеки ден в 03:15. Можете да напишете и daily, weekly или Mon *-*-* 02:00; systemd-analyze calendar "Mon *-*-* 02:00" показва кога ще бъде следващото изпълнение. Persistent=true е важно: ако сървърът е бил изключен в 03:15, задачата се изпълнява веднага след стартирането. RandomizedDelaySec разпределя малко момента на стартиране.

Включвате timer, а не service:

anna@web1:~$ sudo systemctl daemon-reload
anna@web1:~$ sudo systemctl enable --now opruimen.timer
anna@web1:~$ systemctl list-timers opruimen
NEXT                        LEFT     LAST PASSED UNIT           ACTIVATES
Tue 2026-11-10 03:19:42 CET 15h left -    -      opruimen.timer opruimen.service
anna@web1:~$ sudo systemctl start opruimen.service    # сега еднократен ръчен тест
anna@web1:~$ journalctl -u opruimen.service

А cron?

cron е по-старият и по-прост инструмент и все още работи добре. Ред в crontab на даден потребител (crontab -e):

15 3 * * * /usr/local/bin/opruimen.sh

Петте полета са минута, час, ден от месеца, месец и ден от седмицата. Предимства и недостатъци един до друг:

cronsystemd timer
Настройванеедин реддва файла
Пропуснато изпълнение (сървърът е изключен)пропуска сес Persistent=true се изпълнява по-късно
Изход и грешкипо имейл, ако сървърът може да изпраща поща; иначе се губятв journal
Защитни опции, потребителчрез самия скриптвсичко от systemd (вижте по-горе)
Кога е било изпълненотрудно се виждаsystemctl list-timers и journal

За сървър, който администрирате сериозно, таймерите са по-добрият избор, особено за резервни копия (урок 8.2): искате да сте сигурни, че са се изпълнили и какво са съобщили. Ред в cron, който тихо се проваля, забелязвате едва когато Ви потрябва резервното копие.

При AlmaLinux и Rocky Linux

Units и таймерите работят по абсолютно същия начин. Една разлика: SELinux може да спре собствена услуга, която чете или пише файлове на място, което SELinux не очаква, или която слуша на необичаен порт. Съобщението се намира в /var/log/audit/audit.log. Не изключвайте SELinux, за да решите проблема; потърсете правилния етикет или правило (например с semanage).

Обобщение

  • Програма, която трябва да работи постоянно, трябва да бъде systemd услуга: автоматично стартиране, рестартиране при срив, логове в journal.
  • Собствените units са в /etc/systemd/system/, с User= отделен потребител без shell, тайните в EnvironmentFile с права 600.
  • NoNewPrivileges, ProtectSystem=strict с ReadWritePaths, ProtectHome и PrivateTmp ограничават щетите при уязвимост; systemd-analyze security оценява unit файла.
  • Таймерът е .service плюс .timer с OnCalendar; Persistent=true наваксва пропуснатите изпълнения. Включете таймера, а не service.
  • cron все още работи, но таймерите дават по-добри логове и не пропускат изпълнения.

Тест (quiz)

1. Вашето приложение работи като услуга с User=root. Защо отделен потребител е по-добър вариант?



2. Създали сте .service и .timer. Какво включвате с enable --now?



3. Какво прави Persistent=true в един timer?



4. Добавяте ProtectSystem=strict и след това приложението Ви дава "Read-only file system" при запазване на качени файлове. Кое е правилното решение?



5. Къде поставяте паролата за базата данни на Вашата собствена услуга?



Задача

Задача O6.3: Собствена услуга с таймер. Създайте на сървъра си малка собствена услуга с таймер, например скрипт, който всяка нощ записва свободното дисково пространство и systemctl --failed във файл или в journal. Използвайте отделен потребител, Type=oneshot, поне две защитни опции и Persistent=true. Тествайте с systemctl start, прегледайте изхода в journal и запишете оценката от systemd-analyze security. Поставете своите .service и .timer и отговорете на въпросите в контролния списък.

Задача O6.3: Собствена услуга с таймер

Тази задача изпълнявате сами; никой не я проверява. Отбележете какво сте направили и маркирайте задачата като изпълнена.




Вашите отметки и бележки остават само в този браузър; не ги изпращаме никъде. Ако сте влезли, в Моите курсове запазваме само че сте изпълнили задачата.

Още за четене

Моля, изчакайте…

Настройте домейните си

За всеки домейн настройте сървърите за имена, връзката с хостинга и кой ще бъде собственикът.

Домейните Ви се зареждат…