Modul 6 · 6.3
Vlastite usluge i timeri
Modul 6: Servisi i zapisi · Vrijeme čitanja: 11 minuta
Cilj učenja: Nakon ove lekcije moći ćete pokrenuti vlastiti program kao systemd uslugu pod vlastitim korisnikom, uz nekoliko sigurnosnih opcija, te planirati zadatke systemd timerom ili cronom.
Ključni pojmovi: unit datoteka, [Unit], [Service], [Install], ExecStart, User=, WorkingDirectory, EnvironmentFile, Restart=, WantedBy, NoNewPrivileges, ProtectSystem, ProtectHome, PrivateTmp, systemd-analyze security, timer, OnCalendar, Persistent, crontab
Zašto ne jednostavno "nohup" ili "screen"?
Tko postavi vlastiti program na poslužitelj (malu web-aplikaciju, bota, skriptu koja svake noći nešto radi), prvi ga put često pokrene ručno: node server.js & ili u screen sesiji. To radi dok se ne odjavite, dok se poslužitelj ne ponovno pokrene ili dok se program ne sruši. Tada ga više nema, a nitko to ne primijeti.
Program koji mora stalno raditi treba biti systemd usluga. Tada:
- se sam pokreće pri podizanju sustava;
- ga systemd ponovno pokreće ako se sruši;
- njegov ispis završava u journalu (lekcija 6.2);
- radi pod korisnikom kojeg Vi odaberete, s pravima koja Vi dopustite.
Vlastita unit datoteka
Pretpostavimo: imate malu Node.js aplikaciju u /opt/factuurapp koja sluša na 127.0.0.1:3000. nginx ili Caddy kasnije će je objaviti prema van (modul 7).
Korak 1: vlastiti korisnik bez ljuske (lekcija 3.2). Aplikacija ne mora biti root i ne mora se prijavljivati:
anna@web1:~$ sudo adduser --system --group --home /opt/factuurapp --no-create-home factuurapp
anna@web1:~$ sudo chown -R factuurapp:factuurapp /opt/factuurapp/dataSam kod može ostati u vlasništvu korisnika root (aplikacija ne mora mijenjati samu sebe); samo je mapa u koju piše u vlasništvu korisnika usluge.
Korak 2: unit datoteka. Vlastite unite stavljate u /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 bloka:
- [Unit]: opis i redoslijed.
After=network-online.targetsWants=osigurava da se usluga pokrene tek kada je mreža dostupna. - [Service]: kako program radi.
ExecStarts punom putanjom (systemd ne koristi putanju pretraživanja kao Vaša ljuska).User=iGroup=određuju pod kojim korisnikom.EnvironmentFilečita postavke, poput lozinke baze podataka, iz zasebne datoteke, tako da nisu zapisane u unitu. - [Install]: što radi
enable.WantedBy=multi-user.targetznači: pokreni se zajedno s uobičajenim podizanjem sustava.
Korak 3: tajne zasebno, sa strogim pravima.
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/envSadržaj je na primjer DATABASE_URL=postgres://factuur:...@127.0.0.1/factuur. systemd čita datoteku kao root prije nego što se prebaci na korisnika usluge, pa je 600 u vlasništvu korisnika root dovoljno.
Korak 4: učitavanje, pokretanje, provjera.
anna@web1:~$ sudo systemctl daemon-reload
anna@web1:~$ sudo systemctl enable --now factuurapp
anna@web1:~$ systemctl status factuurapp
anna@web1:~$ journalctl -u factuurapp -fSigurnosne opcije: malo truda, velika razlika
Četiri retka ispod RestartSec u primjeru ograničavaju što usluga može, čak i ako netko pronađe propust u Vašoj aplikaciji:
| Opcija | Učinak |
|---|---|
NoNewPrivileges=true | proces i njegovi podprocesi nikada ne mogu dobiti veća prava (ni putem sudo ni putem setuid programa) |
ProtectSystem=strict | cijeli datotečni sustav za uslugu je samo za čitanje, osim onoga što dopustite s ReadWritePaths= |
ProtectHome=true | /home, /root i /run/user su nevidljivi |
PrivateTmp=true | vlastiti, prazni /tmp koji drugi programi ne vide |
systemd može ocijeniti Vaš unit:
anna@web1:~$ systemd-analyze security factuurapp
...
→ Overall exposure level for factuurapp.service: 4.9 OK 🙂Što je broj niži, to bolje. Usluga bez opcija postiže oko 9 ("UNSAFE"). Ne morate doći do nule: svaka opcija koju dodate može pokvariti nešto što aplikaciji treba. Dodajte ih jednu po jednu i testirajte nakon svakog koraka. Ako nešto prestane raditi, to obično piše u journalu ("Read-only file system", "Permission denied").
Planiranje zadataka: timeri
Za nešto što se mora događati u određeno vrijeme (sigurnosna kopija, skripta za čišćenje, izvještaj) potreban Vam je timer. systemd timer sastoji se od dva unita istog naziva: .service koji kaže što se treba dogoditi i .timer koji kaže kada.
# /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 znači: program se izvrši i nakon toga završi. OnCalendar je raspored: svaki dan u 03:15. Možete napisati i daily, weekly ili Mon *-*-* 02:00; systemd-analyze calendar "Mon *-*-* 02:00" pokazuje kada je sljedeće pokretanje. Persistent=true je važan: ako je poslužitelj u 03:15 bio isključen, zadatak se ipak izvrši odmah nakon podizanja sustava. RandomizedDelaySec malo raspršuje trenutak pokretanja.
Uključujete timer, a ne 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 # sada jednom ručno testirajte
anna@web1:~$ journalctl -u opruimen.serviceA cron?
cron je stariji, jednostavniji alat i još uvijek odlično radi. Redak u crontabu korisnika (crontab -e):
15 3 * * * /usr/local/bin/opruimen.shPet polja su minuta, sat, dan u mjesecu, mjesec i dan u tjednu. Prednosti i nedostaci usporedno:
| cron | systemd timer | |
|---|---|---|
| Postavljanje | jedan redak | dvije datoteke |
| Propušteno pokretanje (poslužitelj isključen) | preskače se | s Persistent=true ipak se izvrši |
| Ispis i pogreške | e-poštom, ako poslužitelj može slati e-poštu; inače nestaju | u journalu |
| Sigurnosne opcije, korisnik | putem same skripte | sve što nudi systemd (gornji dio lekcije) |
| Uvid u to kada je zadatak radio | teško | systemctl list-timers i journal |
Za poslužitelj kojim ozbiljno upravljate, timeri su bolji izbor, osobito za sigurnosne kopije (lekcija 8.2): želite sa sigurnošću znati da su se izvršile i što su ispisale. Cron redak koji tiho zakaže primijetit ćete tek kada Vam sigurnosna kopija zatreba.
Na AlmaLinuxu i Rocky Linuxu
Uniti i timeri rade potpuno jednako. Jedna razlika: SELinux može blokirati vlastitu uslugu koja čita ili piše datoteke na mjestu koje SELinux ne očekuje ili koja sluša na neuobičajenom priključku. Poruka se nalazi u /var/log/audit/audit.log. Nemojte isključiti SELinux da biste to riješili; potražite ispravnu oznaku ili pravilo (na primjer s semanage).
Sažetak
- Program koji mora stalno raditi treba biti systemd usluga: samostalno pokretanje, ponovno pokretanje nakon rušenja, zapisi u journalu.
- Vlastiti uniti u
/etc/systemd/system/, sUser=vlastitim korisnikom bez ljuske, tajne uEnvironmentFiles pravima 600. NoNewPrivileges,ProtectSystem=strictsReadWritePaths,ProtectHomeiPrivateTmpograničavaju štetu kod propusta;systemd-analyze securityocjenjuje unit.- Timer je
.serviceplus.timersOnCalendar;Persistent=truenadoknađuje propuštena pokretanja. Uključite timer, a ne service. - cron još uvijek radi, ali timeri daju bolje zapise i ne propuštaju pokretanja.
Kviz
Zadatak
Zadatak O6.3: Vlastita usluga s timerom. Na svom poslužitelju izradite malu vlastitu uslugu s timerom, na primjer skriptu koja svake noći zapisuje slobodni prostor na disku i systemctl --failed u datoteku ili u journal. Koristite vlastitog korisnika, Type=oneshot, najmanje dvije sigurnosne opcije i Persistent=true. Testirajte s systemctl start, pregledajte ispis u journalu i zabilježite ocjenu koju daje systemd-analyze security. Zalijepite svoj .service i .timer te odgovorite na pitanja s popisa za provjeru.
Zadatak O6.3: Vlastita usluga s timerom
Ovaj zadatak rješavate sami; nitko ga ne provjerava. Označite što ste napravili i označite zadatak kao završen.
S Persistent=true zadatak se ipak pokreće nakon pokretanja sustava. Ocjena ispod 6 dobra je za prvu uslugu; prava pisanja samo putem ReadWritePaths.
Vaše kvačice i bilješke ostaju samo u ovom pregledniku; ne šaljemo ih nikamo. Ako ste prijavljeni, u Moji tečajevi čuvamo samo podatak da ste zadatak završili.
Dodatno štivo
- DirectAdmin priručnik 15.1: Cron Jobs: automatsko pokretanje zadataka
- Priručnik
systemd.exec(5)(User=, ProtectSystem=, NoNewPrivileges=): https://manpages.debian.org/trixie/systemd/systemd.exec.5.en.html - Priručnik
systemd.timer(5)(OnCalendar=, Persistent=): https://manpages.debian.org/trixie/systemd/systemd.timer.5.en.html - Priručnik
systemd.time(7)(rasporedi): https://manpages.debian.org/trixie/systemd/systemd.time.7.en.html
