Modul 6 · 6.3
Vlastné služby a časovače
Modul 6: Služby a logy · Čas čítania: 11 minút
Cieľ lekcie: Po tejto lekcii dokážete spustiť vlastný program ako službu systemd pod vlastným používateľom, s niekoľkými bezpečnostnými voľbami, a plánovať úlohy pomocou časovača systemd alebo cronu.
Kľúčové pojmy: súbor unit, [Unit], [Service], [Install], ExecStart, User=, WorkingDirectory, EnvironmentFile, Restart=, WantedBy, NoNewPrivileges, ProtectSystem, ProtectHome, PrivateTmp, systemd-analyze security, časovač (timer), OnCalendar, Persistent, crontab
Prečo nie jednoducho "nohup" alebo "screen"?
Kto si na server nasadí vlastný program (malú webovú aplikáciu, bota, skript, ktorý každú noc niečo urobí), často ho prvýkrát spustí ručne: node server.js & alebo v relácii screen. Funguje to, kým sa neodhlásite, server sa nereštartuje alebo program nespadne. Potom je preč a nikto si to nevšimne.
Program, ktorý musí bežať stále, by mal byť službou systemd. Potom:
- sa sám spustí pri štarte systému;
- ho systemd po páde znova spustí;
- jeho výstup ide do journalu (lekcia 6.2);
- beží pod používateľom, ktorého si zvolíte, s právami, ktoré mu povolíte.
Vlastný súbor unit
Príklad: máte malú aplikáciu Node.js v /opt/factuurapp, ktorá počúva na 127.0.0.1:3000. Navonok ju neskôr sprístupní nginx alebo Caddy (modul 7).
Krok 1: vlastný používateľ bez shellu (lekcia 3.2). Aplikácia nemusí bežať ako root a nepotrebuje sa prihlasovať:
anna@web1:~$ sudo adduser --system --group --home /opt/factuurapp --no-create-home factuurapp
anna@web1:~$ sudo chown -R factuurapp:factuurapp /opt/factuurapp/dataSamotný kód môže patriť používateľovi root (aplikácia nemusí meniť sama seba); používateľovi služby patrí iba priečinok, do ktorého zapisuje.
Krok 2: súbor unit. Vlastné units ukladajte do /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.targetTri bloky:
- [Unit]: popis a poradie.
After=network-online.targetspolu sWants=zabezpečí, že sa služba spustí až vtedy, keď je dostupná sieť. - [Service]: ako program beží.
ExecStarts úplnou cestou (systemd nepoužíva vyhľadávaciu cestu ako váš shell).User=aGroup=určujú, pod kým beží.EnvironmentFilenačíta nastavenia, napríklad heslo k databáze, zo samostatného súboru, aby neboli v unite. - [Install]: čo urobí
enable.WantedBy=multi-user.targetznamená: spustiť pri bežnom štarte systému.
Krok 3: tajné údaje zvlášť, s prísnymi právami.
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/envObsah môže byť napríklad DATABASE_URL=postgres://factuur:...@127.0.0.1/factuur. systemd súbor načíta ako root ešte predtým, ako sa prepne na používateľa služby, takže 600 s vlastníkom root stačí.
Krok 4: načítať, spustiť, skontrolovať.
anna@web1:~$ sudo systemctl daemon-reload
anna@web1:~$ sudo systemctl enable --now factuurapp
anna@web1:~$ systemctl status factuurapp
anna@web1:~$ journalctl -u factuurapp -fBezpečnostné voľby: malá námaha, veľký rozdiel
Štyri riadky pod RestartSec v príklade obmedzujú, čo služba dokáže, aj keď niekto nájde vo vašej aplikácii zraniteľnosť:
| Voľba | Účinok |
|---|---|
NoNewPrivileges=true | proces a jeho potomkovia už nikdy nemôžu získať vyššie práva (ani cez sudo či programy so setuid) |
ProtectSystem=strict | celý súborový systém je pre službu iba na čítanie, okrem toho, čo povolíte pomocou ReadWritePaths= |
ProtectHome=true | /home, /root a /run/user sú neviditeľné |
PrivateTmp=true | vlastný prázdny /tmp, ktorý iné programy nevidia |
systemd vie váš unit ohodnotiť:
anna@web1:~$ systemd-analyze security factuurapp
...
→ Overall exposure level for factuurapp.service: 4.9 OK 🙂Čím nižšie číslo, tým lepšie. Služba bez volieb dosiahne približne 9 ("UNSAFE"). Nulu dosahovať nemusíte: každá pridaná voľba môže pokaziť niečo, čo aplikácia potrebuje. Pridávajte ich po jednej a po každom kroku testujte. Ak niečo prestane fungovať, väčšinou to nájdete v journale ("Read-only file system", "Permission denied").
Plánovanie úloh: časovače
Na niečo, čo sa má diať v pevných časoch (záloha, upratovací skript, report), potrebujete časovač (timer). Časovač systemd tvoria dva units s rovnakým názvom: .service, ktorý hovorí, čo sa má vykonať, a .timer, ktorý hovorí, kedy.
# /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.targetType=oneshot znamená: program sa spustí a potom skončí. OnCalendar je časový plán: každý deň o 03:15. Môžete napísať aj daily, weekly alebo Mon *-*-* 02:00; systemd-analyze calendar "Mon *-*-* 02:00" ukáže, kedy to bude nabudúce. Persistent=true je dôležité: ak bol server o 03:15 vypnutý, úloha sa dodatočne spustí hneď po štarte. RandomizedDelaySec trochu rozloží okamih spustenia.
Zapína sa časovač, nie služba:
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 # teraz raz otestovať ručne
anna@web1:~$ journalctl -u opruimen.serviceA čo cron?
cron je starší, jednoduchší nástroj a stále funguje dobre. Riadok v crontabe používateľa (crontab -e):
15 3 * * * /usr/local/bin/opruimen.shPäť polí znamená minútu, hodinu, deň v mesiaci, mesiac a deň v týždni. Výhody a nevýhody vedľa seba:
| cron | časovač systemd | |
|---|---|---|
| Nastavenie | jeden riadok | dva súbory |
| Zmeškané spustenie (server vypnutý) | preskočí sa | s Persistent=true sa vykoná dodatočne |
| Výstup a chyby | e-mailom, ak server vie posielať poštu; inak sa stratia | v journale |
| Bezpečnostné voľby, používateľ | cez samotný skript | všetko zo systemd (pozri vyššie v lekcii) |
| Zistiť, kedy bežal | náročné | systemctl list-timers a journal |
Pri serveri, ktorý spravujete zodpovedne, sú časovače lepšou voľbou, najmä pri zálohách (lekcia 8.2): chcete mať istotu, že prebehli a čo hlásili. Riadok v crone, ktorý potichu zlyháva, odhalíte až vtedy, keď zálohu potrebujete.
Na AlmaLinux a Rocky Linux
Units a časovače fungujú úplne rovnako. Jeden rozdiel: SELinux môže zablokovať vlastnú službu, ktorá číta alebo zapisuje súbory na mieste, kde to SELinux neočakáva, alebo ktorá počúva na nezvyčajnom porte. Hlásenie nájdete v /var/log/audit/audit.log. SELinux kvôli tomu nevypínajte; nájdite správny label alebo pravidlo (napríklad pomocou semanage).
Zhrnutie
- Program, ktorý musí bežať stále, by mal byť službou systemd: sám sa spustí, po páde sa reštartuje, logy idú do journalu.
- Vlastné units patria do
/etc/systemd/system/, sUser=pre vlastného používateľa bez shellu a tajnými údajmi vEnvironmentFiles právami 600. NoNewPrivileges,ProtectSystem=strictsReadWritePaths,ProtectHomeaPrivateTmpobmedzujú škody pri zraniteľnosti;systemd-analyze securityunit ohodnotí.- Časovač je
.serviceplus.timersOnCalendar;Persistent=truedobehne zmeškané spustenia. Zapnite časovač, nie službu. - cron stále funguje, ale časovače poskytujú lepšie logy a nezmeškajú žiadne spustenie.
Kvíz
Úloha
Úloha O6.3: Vlastná služba s časovačom. Vytvorte na svojom serveri malú vlastnú službu s časovačom, napríklad skript, ktorý každú noc zapíše voľné miesto na disku a systemctl --failed do súboru alebo do journalu. Použite vlastného používateľa, Type=oneshot, aspoň dve bezpečnostné voľby a Persistent=true. Otestujte to pomocou systemctl start, pozrite si výstup v journale a zapíšte si skóre z systemd-analyze security. Vložte svoj .service a .timer a odpovedzte na otázky v kontrolnom zozname.
Úloha O6.3: Vlastná služba s časovačom
Túto úlohu vykonávate sami, nikto ju nekontroluje. Odškrtnite, čo ste urobili, a označte úlohu ako splnenú.
S Persistent=true sa úloha spustí dodatočne po štarte systému. Skóre pod 6 je pre prvú službu dobré; práva na zápis iba cez ReadWritePaths.
Vaše zaškrtnutia a poznámky zostávajú iba v tomto prehliadači, nikam ich neposielame. Po prihlásení si v sekcii Moje kurzy uchovávame iba to, že ste úlohu splnili.
Ďalšie čítanie
- Návod na DirectAdmin 15.1: CRON úlohy: automatické spúšťanie úloh
- Manuál
systemd.exec(5)(User=, ProtectSystem=, NoNewPrivileges=): https://manpages.debian.org/trixie/systemd/systemd.exec.5.en.html - Manuál
systemd.timer(5)(OnCalendar=, Persistent=): https://manpages.debian.org/trixie/systemd/systemd.timer.5.en.html - Manuál
systemd.time(7)(časové plány): https://manpages.debian.org/trixie/systemd/systemd.time.7.en.html
