Salt la conținut

Setări cookie-uri

Alegeți pentru fiecare tip ce cookie-uri permiteți. Puteți modifica oricând alegerea prin Setări cookie-uri, în partea de jos a fiecărei pagini. Declarație de confidențialitate

Necesare

Mereu active

Necesare pentru autentificare, pentru păstrarea coșului și pentru a vă reține alegerile. Acestea sunt mereu active.

Ce cookie-uri?
  • weboke_sessie, weboke_klant, weboke_remember: sesiunea și menținerea autentificării
  • weboke_basket: coșul de cumpărături
  • wkBtwIncl: afișarea prețurilor cu sau fără TVA
  • wok_cookies: alegerea privind cookie-urile, 12 luni

Măsoară ce reclamă duce la o vizită sau o comandă, ca să nu plătim pentru reclame care nu aduc nimic.

Ce cookie-uri?
  • Google Ads prin Google Tag Manager (_gcl_au, _gcl_aw), până la 90 de zile
  • OpenAI Ads, reclame în ChatGPT
  • wok_aff: prin ce partener ați ajuns la noi (program de afiliere), 60 de zile

4,6

Țară și limbă

Fiecare țară are propriul site, cu prețurile și TVA-ul pentru țara respectivă.

Vedeți

Servicii proprii și timere

Modulul 6: Servicii și jurnale · Timp de citire: 11 minute

Obiectivul lecției: După această lecție veți putea rula propriul program ca serviciu systemd sub un utilizator dedicat, cu câteva opțiuni de securitate, și veți putea planifica sarcini cu un timer systemd sau cu cron.

Noțiuni cheie: fișier unit, [Unit], [Service], [Install], ExecStart, User=, WorkingDirectory, EnvironmentFile, Restart=, WantedBy, NoNewPrivileges, ProtectSystem, ProtectHome, PrivateTmp, systemd-analyze security, timer, OnCalendar, Persistent, crontab

De ce nu pur și simplu "nohup" sau "screen"?

Cine pune un program propriu pe un server (o mică aplicație web, un bot, un script care face ceva în fiecare noapte) îl pornește adesea prima dată manual: node server.js & sau într-o sesiune screen. Acest lucru funcționează până când vă deconectați, serverul repornește sau programul se blochează. Atunci a dispărut, iar nimeni nu observă.

Un program care trebuie să ruleze permanent trebuie să fie un serviciu systemd. Astfel:

  • pornește automat la inițializarea sistemului;
  • systemd îl repornește dacă se blochează;
  • ieșirea ajunge în journal (lecția 6.2);
  • rulează sub un utilizator ales de dumneavoastră, cu permisiunile pe care le permiteți dumneavoastră.

Un fișier unit propriu

Să presupunem că aveți o mică aplicație Node.js în /opt/factuurapp, care ascultă pe 127.0.0.1:3000. Ulterior, nginx sau Caddy o va expune în exterior (modulul 7).

Pasul 1: un utilizator dedicat, fără shell (lecția 3.2). Aplicația nu are nevoie să fie root și nu trebuie să se autentifice:

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

Codul în sine poate rămâne în proprietatea lui root (aplicația nu trebuie să se modifice singură); doar directorul în care scrie aparține utilizatorului serviciului.

Pasul 2: fișierul unit. Unit-urile proprii le puneți în /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

Cele trei secțiuni:

  • [Unit]: descrierea și ordinea. After=network-online.target împreună cu Wants= asigură că serviciul pornește abia după ce rețeaua este disponibilă.
  • [Service]: modul în care rulează programul. ExecStart cu calea completă (systemd nu folosește o cale de căutare precum shell-ul dumneavoastră). User= și Group= stabilesc sub ce utilizator. EnvironmentFile citește setări, precum o parolă de bază de date, dintr-un fișier separat, astfel încât acestea să nu stea în unit.
  • [Install]: ce face enable. WantedBy=multi-user.target înseamnă: pornește odată cu o inițializare normală a sistemului.

Pasul 3: secretele separat, cu permisiuni stricte.

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

Conținutul poate fi, de exemplu, DATABASE_URL=postgres://factuur:...@127.0.0.1/factuur. systemd citește fișierul ca root înainte de a trece la utilizatorul serviciului, așa că 600 în proprietatea lui root este suficient.

Pasul 4: încărcați, porniți, verificați.

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

Opțiuni de securitate: efort mic, diferență mare

Cele patru linii de sub RestartSec din exemplu limitează ce poate face serviciul, chiar și atunci când cineva găsește o vulnerabilitate în aplicația dumneavoastră:

OpțiuneEfect
NoNewPrivileges=trueprocesul și copiii săi nu pot obține niciodată mai multe permisiuni (nici prin sudo sau prin programe setuid)
ProtectSystem=strictîntregul sistem de fișiere este doar în citire pentru serviciu, cu excepția a ceea ce permiteți cu ReadWritePaths=
ProtectHome=true/home, /root și /run/user sunt invizibile
PrivateTmp=trueun /tmp propriu, gol, pe care alte programe nu îl văd

systemd vă poate evalua unit-ul:

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

Cu cât numărul este mai mic, cu atât mai bine. Un serviciu fără opțiuni are un scor în jur de 9 ("UNSAFE"). Nu trebuie să ajungeți la zero: fiecare opțiune adăugată poate strica ceva de care aplicația are nevoie. Adăugați-le pe rând și testați după fiecare pas. Dacă ceva nu mai funcționează, de obicei mesajul apare în journal ("Read-only file system", adică sistemul de fișiere este doar în citire, sau "Permission denied", adică permisiune refuzată).

Planificarea sarcinilor: timere

Pentru ceva ce trebuie să se întâmple la ore fixe (un backup, un script de curățare, un raport) aveți nevoie de un timer. Un timer systemd constă din două unit-uri cu același nume: un .service care spune ce trebuie să se întâmple și un .timer care spune când.

# /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 înseamnă: programul rulează și apoi se încheie. OnCalendar este programul orar: în fiecare zi la 03:15. Puteți scrie și daily, weekly sau Mon *-*-* 02:00; systemd-analyze calendar "Mon *-*-* 02:00" arată când va fi următoarea rulare. Persistent=true este important: dacă serverul era oprit la 03:15, sarcina rulează totuși imediat după pornire. RandomizedDelaySec distribuie puțin momentul de start.

Activarea se face cu timer-ul, nu cu serviciul:

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    # testați acum o dată manual
anna@web1:~$ journalctl -u opruimen.service

Și cron?

cron este instrumentul mai vechi și mai simplu și funcționează în continuare foarte bine. O linie în crontab-ul unui utilizator (crontab -e):

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

Cele cinci câmpuri sunt minutul, ora, ziua din lună, luna și ziua din săptămână. Avantaje și dezavantaje, alăturate:

crontimer systemd
Configurareo singură liniedouă fișiere
Rulare ratată (server oprit)este sărităcu Persistent=true rulează totuși
Ieșire și eroriprin e-mail, dacă serverul poate trimite e-mail; altfel se pierdîn journal
Opțiuni de securitate, utilizatorprin scriptul însușitot ce oferă systemd (lecția de mai sus)
Vedeți când a rulatdificilsystemctl list-timers și journal-ul

Pentru un server pe care îl administrați serios, timerele sunt alegerea mai bună, mai ales pentru backupuri (lecția 8.2): doriți să știți sigur că au rulat și ce au raportat. O linie cron care eșuează în tăcere o observați abia când aveți nevoie de backup.

Pe AlmaLinux și Rocky Linux

Unit-urile și timerele funcționează exact la fel. O diferență: SELinux poate bloca un serviciu propriu care citește sau scrie fișiere într-un loc la care SELinux nu se așteaptă ori care ascultă pe un port neobișnuit. Mesajul apare în /var/log/audit/audit.log. Nu dezactivați SELinux pentru a rezolva problema; căutați eticheta sau regula corectă (de exemplu cu semanage).

Rezumat

  • Un program care trebuie să ruleze permanent trebuie să fie un serviciu systemd: pornire automată, repornire la blocare, jurnale în journal.
  • Unit-urile proprii stau în /etc/systemd/system/, cu User= un utilizator dedicat fără shell, iar secretele într-un EnvironmentFile cu permisiunile 600.
  • NoNewPrivileges, ProtectSystem=strict cu ReadWritePaths, ProtectHome și PrivateTmp limitează pagubele în cazul unei vulnerabilități; systemd-analyze security evaluează unit-ul.
  • Un timer înseamnă un .service plus un .timer cu OnCalendar; Persistent=true recuperează rulările ratate. Activați timer-ul, nu serviciul.
  • cron funcționează în continuare, dar timerele oferă jurnale mai bune și nu ratează rulări.

Test (quiz)

1. Aplicația dumneavoastră rulează ca serviciu cu User=root. De ce este mai bun un utilizator dedicat?



2. Ați creat un .service și un .timer. Ce activați cu enable --now?



3. Ce face Persistent=true într-un timer?



4. Adăugați ProtectSystem=strict, iar apoi aplicația afișează "Read-only file system" la salvarea fișierelor încărcate. Care este soluția corectă?



5. Unde puneți parola bazei de date a serviciului dumneavoastră propriu?



Exercițiu

Exercițiul O6.3: Un serviciu propriu cu timer. Creați pe serverul dumneavoastră un mic serviciu propriu cu un timer, de exemplu un script care în fiecare noapte scrie spațiul liber pe disc și systemctl --failed într-un fișier sau în journal. Folosiți un utilizator dedicat, Type=oneshot, cel puțin două opțiuni de securitate și Persistent=true. Testați cu systemctl start, consultați ieșirea în journal și notați scorul obținut cu systemd-analyze security. Lipiți fișierele .service și .timer și răspundeți la întrebările din lista de verificare.

Exercițiul O6.3: Un serviciu propriu cu timer

Acest exercițiu îl faceți singur; nimeni nu îl verifică. Bifați ce ați făcut și marcați exercițiul ca finalizat.




Bifele și notițele dumneavoastră rămân doar în acest browser; nu le trimitem nicăieri. Dacă sunteți autentificat, păstrăm în Cursurile mele doar faptul că ați finalizat exercițiul.

Lecturi suplimentare

Un moment…

Configurați domeniile

Stabiliți pentru fiecare domeniu nameserverele, legătura cu hostingul și cine devine titularul.

Se încarcă domeniile…