cd uso-lab git pull cd ~/uso-lab/labs/09-task-admin/lab-container/ ./lab_prepare.sh cleanup
cd ~/uso-lab/labs/09-task-admin/lab-container ./lab_prepare.sh install remote ./lab_prepare.sh install ssh-server ./lab_prepare.sh install local
docker image prune --all
.
Noi ca dezvoltatori software sau administratori de sisteme, avem nevoie de multă putere de procesare pentru a ne realiza obiectivele și accesibilitatea necesară pentru a folosi sistemele oricând, oricum.
Un avantaj la folosirea unei stații la distanță este faptul că este mereu disponibilă. Aceasta nu trebuie să fie oprită, nu are nevoie de restart, dacă ne deplasăm undeva, aceasta nu se schimbă cu nimic. De oriunde de oriunde l-ai accesa, vei avea la dispoziție sistemul la modul “Pickup and Play”.
Unele lucruri pe care vrem să le rezolvăm care necesită putere de procesare sunt compilarea programelor, antrenarea modelelor de machine learning, testarea la limită (stress testing) a aplicațiilor, sau simularea infrastructurilor complexe folosind mașini virtuale, rularea de servere complexe pentru anumite aplicații.
În mod obișnuit, sistemele care oferă multă putere de procesare nu vin în pachete compacte, ci acestea sunt sub formă de calculatoare de tip stații de lucru (workstation), servere, sau laptopuri grele. O altă abordare pentru a folosi un workstation este să obținem o mașină virtuală într-un cloud, cum ar fi AWS sau Microsoft Azure.
În același timp, nu este un lucru la îndemână pentru toți să lucreze pe astfel de sisteme din considerente de generare de căldură, consum de curent, spațiu la locul de muncă lipsă de mobilitate a sistemelor. Astfel, dacă vrem să lucrăm la o problemă care necesită multă putere de procesare, avem nevoie să fim în apropierea unui sistem care ne oferă multă putere de procesare. Acest lucru nu este mereu posibil din motive precum faptul că nu ai acces la locul de muncă sau că lucrezi într-un mediu la distanță.
În acest capitol prezentăm situația lucrului pe o stație la distanță. Cum putem să ne adaptăm modul de lucru pentru a folosi sisteme la care nu avem acces fizic și cum putem să monitorizăm și să folosim cât mai bine aceste sisteme.
Pentru a parcurge această secțiune este recomandat să descărcați ultima versiune a respository-ului laboratorului. Pentru a descărca ultima versiune a repository-ului, rulați comanda git pull
în directorul ~/uso-lab/labs/09-task-admin/lab-container/
.
Infrastructura laboratorului este bazată pe containere Docker ale căror imagini vor fi generate pe propriul calculator. Dacă nu aveți deja instalat Docker Engine pe sistem, scriptul ~/uso-lab/labs/09-task-admin/lab-container/lab_prepare.sh
va instala aplicația.
După ce ați terminat de lucrat, vă recomandăm să opriți containerele rulând comanda ./lab_prepare.sh delete
în directorul ~/uso-lab/labs/09-task-admin/lab-container/
.
Prima problemă cu care ne vom confrunta este conectarea la stație, deoarece, în majoritatea cazurilor, nu vom lucra în aceeași rețea cu sistemul la distanță și stația nu va avea o adresă IP publică. Așadar, nu ne vom putea conecta direct la sistem folosind un protocol de comunicare la distanță, cum ar fi SSH fără să facem pași suplimentari.
Câteva soluții de conectare la sistem pe care le vom aborda sunt:
Nu vom aborda soluția bazată pe DDNS, deoarece aceasta presupune că avem o adresă IP publică configurată pe ruterul primit de la furnizorul de Internet, dar acest lucru nu mai este valabil pentru majoritatea stațiilor.
Pentru rularea acestui demo, rulați în directorul ~/uso-lab/labs/09-task-admin/lab-container/
comanda ./lab_prepare.sh install remote
și comanda ./lab_prepare.sh install local
Pentru a ne conecta la infrastructura pentru această secțiune, vom folosi comanda ./lab_prepare.sh connect
având ca parametru numele mașinii la care vrem să ne conectăm, local
sau remote
.
Adresele IPv4 au fost contruite pentru a fi identificatori unici în Internet pentru stații. Acestea pot să identifice maxim $2^{32}$ stații în Internet. Însă acum există mai multe dispozitive conectate la Internet decât există adrese IPv4 care se pot asigna pe dispozitive.
Pentru a se rezolva această problemă, au fost alese anumite intervale de adrese IP care pot fi atribuite pe mai multe dispozitive în același timp. Astfel, s-a rezolvat problema suprapunerii adreselor IP. Dezavantajul este că aceste adrese, nemaifiind unice, nu mai pot să fie accesibile de oriunde din Internet.
Intervalele adreselor IPv4 private sunt următoarele:
10.0.0.0
- 10.255.255.255
;172.16.0.0
- 172.31.255.255
;192.168.0.0
- 192.168.255.255
Nicio adresă IP din intervalele de mai sus nu poate fi accesată direct din Internet.
În această subsecțiune vom lucra cu 3 stații care sunt distribuite în felul următor:
local
, reprezintă stația “locală”, adică laptopul de pe care ne-am conecta, dacă ar fi vorba de un scenariu real; are o singură interfață de rețea cu adresa IP 10.11.11.3
remote
, reprezintă workstationul la care vrem să ne conectăm; are o singură interfață cu adresa IP 10.10.10.3
.
Vom verifica conectivitatea cu stația remote
de pe stația local
folosind comanda ping
:
root@local:~# ping -c 2 10.10.10.3 PING 10.10.10.3 (10.10.10.3) 56(84) bytes of data. --- 10.10.10.3 ping statistics --- 2 packets transmitted, 0 received, 100% packet loss, time 1010ms root@local:~# ping -c 2 141.85.241.99 PING 141.85.241.99 (141.85.241.99) 56(84) bytes of data. 64 bytes from 141.85.241.99: icmp_seq=1 ttl=61 time=9.02 ms 64 bytes from 141.85.241.99: icmp_seq=2 ttl=61 time=8.58 ms --- 141.85.241.99 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 1001ms rtt min/avg/max/mdev = 8.588/8.806/9.024/0.218 ms
Rezultatul comenzii primei rulări a comenzii ping
demonstrează faptul că nu avem conectivitate între stația local
și stația remote
. Totuși, am testat și conectivitatea cu o altă adresă IP din Internet, în cazul acesta folosind adresa IP a stației fep.grid.pub.ro
(cu adresa IP 141.85.241.99), cu care putem să comunicăm, deci nu este o problemă de conectare la Internet. Pentru a recapitula funcționalitatea utilitarului ping
, revizitați capitolul Configurarea sistemului.
remote
. Pentru a ne conecta la stația remote
vom rula comanda ./lab_prepare.sh connect remote
în directorul ~/uso-lab/labs/09-task-admin/lab-container/
.
Prima soluție pentru conectarea la o stație care folosește o adresă IP privată o reprezintă serviciile de tip VPN (Virtual Private Network). Acestea conectează două stații care în mod fizic nu sunt conectate la aceeași rețea.
Pentru această soluție avem două moduri de organizare: folosind un server public pe care îl configurăm noi drept server de VPN, sau folosirea unui serviciu public de VPN cum ar fi:
Am folosit ca exemplu serviciile Hamachi sau ZeroTier, deoarece acestea pot fi folosite gratuit și sunt ușor de configurat.
Soluții VPN
Nume soluție | Avantaje | Dezavantaje |
---|---|---|
Hamachi | * Ușor de setat * Aplicație client disponibilă pe Linux și pe Windows * Nu necesită înregistrarea | * Latență mai mare decât alte soluții * Soluția gratis nu este optimă pentru un număr mare de calculatoare |
ZeroTier | * Ușor de instalat și setat * Permite 50 de stații într-o rețea | * Necesită înregistrare pentru folosire |
FreeLAN | * Soluție gratis * Nu limitează numărul de stații dintr-o rețea | * Configurare dificilă * Nu funcționează pe toate stațiile, este nevoie de anumite condiții speciale |
Pentru început, recomandăm folosirea aplicației Hamachi, deoarece acesta nu presupune înregistrarea unui cont pentru folosirea aplicație. Hamachi vine cu dezavantajul că putem să conectăm maxim cinci stații între ele și viteza conexiunii este mai mică decât dacă am folosi unele servicii plătite, cum ar fi OpenVPN.
Nu vom instala pachetul folosind aplicația apt
, cum am învățat până acum, deoarece repository-ul de pachete folosit de Ubuntu nu conține pachetul pentru Hamachi. Pentru instalarea aplicației Hamachi vom descărca pachetul.
Vom folosi comanda wget
pentru a descărca pachetul:
root@remote:~# wget https://vpn.net/installers/logmein-hamachi_2.1.0.203-1_amd64.deb --2023-01-12 12:44:34-- https://vpn.net/installers/logmein-hamachi_2.1.0.203-1_amd64.deb Resolving vpn.net (vpn.net)... 173.199.52.250 Connecting to vpn.net (vpn.net)|173.199.52.250|:443... connected. HTTP request sent, awaiting response... 200 OK Length: 1613102 (1,5M) [application/vnd.debian.binary-package] Saving to: ‘logmein-hamachi_2.1.0.203-1_amd64.deb’ logmein-hamachi_2.1.0.203-1_a 100%[==============================================>] 1,54M 479KB/s in 3,3s 2023-01-12 12:44:38 (479 KB/s) - ‘logmein-hamachi_2.1.0.203-1_amd64.deb’ saved [1613102/1613102] root@remote:~# dpkg -i logmein-hamachi_2.1.0.203-1_amd64.deb Selecting previously unselected package logmein-hamachi. (Reading database ... 12216 files and directories currently installed.) Preparing to unpack logmein-hamachi_2.1.0.203-1_amd64.deb ... Unpacking logmein-hamachi (2.1.0.203-1) ... Setting up logmein-hamachi (2.1.0.203-1) ... mknod: /dev/net/tun: File exists Starting LogMeIn Hamachi VPN tunneling engine logmein-hamachi starting - success Processing triggers for systemd (245.4-4ubuntu3.3) ...
Am folosit comanda dpkg
care gestionează aplicații sub forma pachetelor .deb
, specifice distribuțiilor Debian, Ubuntu și Mint. Opțiunea -i
specifică comenzii dpkg
că vrem să instalăm o aplicație.
Verificăm că am instalat aplicația Hamachi folosind comanda hamachi
în felul următor:
root@remote:~# hamachi version : 2.1.0.203 pid : 42 status : offline client id : address : nickname : lmi account:
Pentru a ne autentifica la serverele Hamachi, folosim comanda hamachi login
:
root@remote:~# hamachi login Logging in .......... ok root@remote:~# hamachi version : 2.1.0.203 pid : 42 status : logged in client id : 253-932-022 address : 25.114.254.180 2620:9b::1972:feb4 nickname : remote lmi account: -
Această comandă generează un identificator unic per stație și stabilește un nickname. Rulând comanda hamachi
vor fi afișate identificatorul, nickname-ul sistemului, adresa IP din VPN și nickname-ul sistemului.
Instalați Hamachi pe stația local
.
Odată ce am instalat Hamachi pe ambele stații pe care vrem să le conectăm, trebuie să creăm o rețea virtuală prin care acestea două să comunice. Această rețea va conecta cele două calculatoare, cu toate că ele nu sunt fizic în aceeași rețea.
Vom crea rețeaua virtuală de pe stația remote
. Pentru a crea o rețea virtuală folosim comanda hamachi create
împreună cu numele rețelei și parola acesteia. Stația remote
va avea drepturi de administrare a rețelei. Doar având drepturi administrative se poate scoate sisteme din rețea, sau se poate șterge rețeaua. Pentru demo-ul pe care îl urmăriți, folosiți în loc de șirul de caractere nume-prenume
numele și prenumele vostru.
root@remote:~# hamachi create nume-prenume 12345667890 Creating nume-prenume .. ok root@remote:~# hamachi list * [nume-prenume] capacity: 1/5, subscription type: Free, owner: This computer
Am folosit comanda hamachi list
pentru a verifica faptul că a fost creată rețeaua. Comanda hamachi list
afișează toate rețelele din care face parte stația.
Pentru a conecta stația local
la rețeaua privată vom folosi comanda hamachi join
urmată de numele rețelei la care vom conecta stația și parola rețelei.
root@local:~# hamachi join nume-prenume 12345667890 Joining nume-prenume .. ok root@local:~# hamachi list * [nume-prenume] capacity: 2/5, subscription type: Free, owner: remote (253-932-022) * 253-932-022 remote 25.114.254.180 alias: not set 2620:9b::1972:feb4 via server TCP
Rulând comanda hamachi list
, am afișat rețelele la care este conectată stația local
și stațiile cu care împarte rețelele. Adresa IP a stației stației remote
din rețeaua privată este 25.114.254.180
, conform rezultatului comenzii.
Pentru a testa conexiunea dintre stațiile local
și remote
vom rula comanda ping
.
root@local:~# ping -c 2 25.114.254.180 PING 25.114.254.180 (25.114.254.180) 56(84) bytes of data. 64 bytes from 25.114.254.180: icmp_seq=1 ttl=64 time=76.5 ms 64 bytes from 25.114.254.180: icmp_seq=2 ttl=64 time=92.3 ms --- 25.114.254.180 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 1003ms rtt min/avg/max/mdev = 76.592/84.493/92.394/7.901 ms
Creați o nouă rețea privată numită prenume-nume
, cu parola de acces anaaremere
. Conectați stațiile local
și remote
la noua rețea.
Pentru rularea acestui demo, rulați în directorul ~/uso-lab/labs/09-task-admin/lab-container/
comanda ./lab_prepare.sh install ssh-server
. Pentru a ne conecta la infrastructura pentru această secțiune, vom folosi comanda ./lab_prepare.sh connect
având ca parametrul numele mașinii la care vrem să ne conectăm, local
, remote
sau ssh-server
.
Abordările pe care le-am discutat mai sus presupun accesul la un server central și drepturi de administrator din partea utilizatorului pentru instalarea aplicațiilor (cum ar fi Hamachi sau OpenVPN). Dacă nu avem acces la un cont de administrator, nu putem să ne conectăm la stația de la distanță.
O alternativă care nu presupune drepturi administrative sunt tunelele SSH. Un tunel SSH reprezintă o conexiune între două stații facilitată de protocolul SSH. Astfel, în loc să trimitem comenzi prin SSH către o stație, putem trimite orice tip de mesaj, pentru orice aplicație.
Dezavantajul acestei abordări este că necesită accesul la un server terț care să fie accesibil de ambele stații.
În această subsecțiune vom lucra cu 3 stații care sunt distribuite în felul următor:
local
, reprezintă stația “locală”, adică laptopul de pe care ne-am conecta, dacă ar fi vorba de un scenariu real; are o singură interfață de rețea cu adresa IP 10.11.11.3
;remote
, reprezintă workstationul la care vrem să ne conectăm; are o singură interfață cu adresa IP 10.10.10.3
;ssh-server
, reprezintă serverul terț prin care ne vom conecta ca să ajungem la workstation; această stație are două interfețe conectate la ea, cu adresele IP 10.11.11.2
și 10.10.10.2
, dar în realitate aceasta ar avea o singură placă de rețea.
Stațiile local
și remote
nu au conectivitate între ele, dar au conectivitate la stația ssh-server
, deoarece sunt în aceeași rețea.
Primul pas necesar pentru conectarea la o stație prin tunel SSH este inițializarea tunelului. Când inițializăm tunelul acesta va deschide portul 4242
pe stația ssh-server
de la adresa 10.10.10.2
, astfel încât mesajele trimise către portul 4242
vor fi trimise către portul 22
de pe stația remote
, stația de pe care inițializăm tunelul SSH. Vom folosi utilizatorul root
cu parola root
pentru a ne conecta.
Pentru a deschide tunelul vom folosi comanda următoare:
root@remote:~# ssh -N -R 4242:localhost:22 root@10.10.10.2 The authenticity of host '10.10.10.2 (10.10.10.2)' can't be established. ECDSA key fingerprint is SHA256:xV1orHYj4fhkc5HE91sfh8QhaVqke/AEMa8mYI423HY. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added '10.10.10.2' (ECDSA) to the list of known hosts. root@10.10.10.2's password:
Opțiunile comenzii ssh
folosite sunt următoarele:
-N
este folosită atunci când deschidem tunele pentru a nu deschide shelluri în care să dăm comenzi;4242
este portul pe care vrem să îl deschidă pe stația ssh-server
;localhost
este stația către care vor fi trimise mesajele primite pe portul 4242
. În cazul acesta mesajele vor fi trimise către localhost
, adică stația remote
, cea de pe care rulăm comanda de tunelare;22
este portul de pe stația localhost
către care vrem să fie trimise mesajele primite pe portul 4242
de pe stația ssh-server
;root@10.10.10.2
, utilizatorul și adresa IP a stației către care vrem să deschidem tunelul; în cazul acesta este adresa IP a stației ssh-server
.
ssh
nu va mai afișa nimic la terminal.
Tunelul va rămâne activ cât timp comanda ssh
de mai sus rulează.
Putem să verificăm că a fost deschis portul 4242
pe stația ssh-server
rulând comanda netstat -tlpn
:
root@ssh-server:~# netstat -tlpn Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 24/sshd tcp 0 0 127.0.0.1:4242 0.0.0.0:* LISTEN 99/sshd: root tcp 0 0 127.0.0.11:42991 0.0.0.0:* LISTEN - tcp6 0 0 :::22 :::* LISTEN 24/sshd
Cât timp această fereastră rămâne deschisă, tunelul va fi activ. Vom învăța în secțiunea task_admin_services_config_custom
cum să rulăm această comandă în afara terminalului și cum să ne asigurăm că tunelul este mereu deschis.
Odată creat tunelul, vrem să îl folosim de pe stația local
, pentru a putea rula comenzi pe stația remote
.
Pentru a face acest lucru, trebuie să ne conectăm la stația server
. Serverul server
poate fi accesat la adresa 10.11.11.2
.
root@local:~# ssh root@10.11.11.2 root@10.11.11.2's password: Welcome to Ubuntu 18.04.5 LTS (GNU/Linux 5.4.0-52-generic x86_64) * Documentation: https://help.ubuntu.com * Management: https://landscape.canonical.com * Support: https://ubuntu.com/advantage This system has been minimized by removing packages and content that are not required on a system that users do not log into. To restore this content, you can run the 'unminimize' command. Last login: Tue Jan 5 23:08:53 2021 from 10.11.11.3 root@ssh-server:~#
După cum am observat mai sus, în rezultatul comenzii netstat
, tunelul SSH este deschis pe portul 4242
al stației ssh-server
și redirectează mesajele către stația remote
.
Pentru a ne conecta la acest port folosind clientul SSH, rulăm următoarea comandă:
root@ssh-server:~# ssh root@localhost -p 4242 [...] root@remote:~#
Am folosit opțiunea -p
pentru a ne conecta folosind SSH pe un alt port decât portul predefinit (22
). În comanda de mai sus ne-am conectat la stația localhost
, adică stația ssh-server
dar, deoarece portul 4242
este de fapt un tunel, conexiunea a fost redirectată la stația remote
.
Observăm că promptul s-a schimbat în root@remote:~#
, deci ne-am conectat la stația remote
.
Creați un tunel SSH care să ducă de la stația local
la ssh-server
folosind portul 6970 și conectați-vă la stația local
din stația remote
folosindu-vă de stația ssh-server
ca mai sus.
Odată ce am reușit să realizăm o conexiune persistentă între stația locală și workstationul remote pe care vrem să lucrăm și ne-am configurat mediul de lucru la distanță, vrem să folosim stația.
Pentru folosirea stației vom presupune următorul flux de lucru:
uso
.
Atunci când ne conectăm la un calculator printr-un client SSH și rulăm comenzi, acestea vor rula în foreground.
Dacă avem o aplicație care rulează mult timp, cum ar fi o căutare intensă în sistemul de fișiere folosind updatedb
, și conexiunea SSH se întrerupe, se va întrerupe și execuția comenzii updatedb
.
Pentru a rezolva această problemă și a ne folosi de disponibilitatea oferită de un sistem distanță, vom folosi utilitarul tmux
. Acest utilitar pornește o sesiune de shell care este independentă de terminalul în care rulează, astfel, putem să ne conectăm și să ne deconectăm de la ea.
Fiecare pornire a aplicației tmux
deschide o nouă sesiune. Putem considera fiecare sesiune ca o fereastră a unui browser. De regulă nu este nevoie să avem mai multe ferestre de browser, sau de tmux
pornite, deoarece avem alte moduri de organizare a spațiului de lucru cu care putem să lucrăm mai ușor folosind scurtături. În plus, pentru fiecare sesiune de tmux
ar fi nevoie să pornim un nou client SSH, lucru care, în funție de modul de conectare la stație, adaugă pași în plus.
Aplicația tmux
permite detașarea de la o sesiune folosind combinația de taste Ctrl+v d
tmux
folosesc ca prefix combinația Ctrl+v
. Această combinație este predefinită pe mașina virtuală USO.ova
, dar pe sistemele obișnuite combinația va fi Ctrl+b
. Putem modifica prefixul în fișierul de configurare tmux.conf
.
Pentru a ne reatașa la o sesiune trebuie să ne dăm seama la care sesiune să ne atașăm. Fiecare sesiune tmux
are asociat un identificator.
Vom afișa toate sesiunile deschise folosind comanda tmux ls
:
student@uso:~$ tmux ls 0: 1 windows (created Wed Jan 6 02:44:06 2021)
În momentul de față există o singură sesiune cu identificatorul 0
.
Pentru a ne reatașa la sesiune folosim comanda tmux attach-session -t 0
.
Pentru a ne organiza terminalele deschise pe stația de la distanță, recomandăm folosirea taburilor (numite ferestre - window în tmux
), deoarece acestea sunt deschise pe durata sesiunii și permit crearea și gestiunea facilă.
De exemplu, pentru a lucra la o aplicație, avem nevoie să deschidem într-un tab documentul sursă pe care îl gestionăm, într-un tab avem un shell în care compilăm aplicația și într-un tab rulăm comenzi de verificare a aplicației. Având fiecare tab cu sarcina sa desemnată, păstrăm un istoric mai curat și mai ușor de interpretat. Astfel vom reduce numărul de comenzi pe care le rulăm pentru a reporni editorul de text, pentru a schimba directul de lucru etc.
Pentru a porni un nou tab folosim combinația de taste Ctrl+v c
.
În bara de taburi din terminal a apărut un nou tab cu denumirea 1:bash*
.
Fiecare tab are propriul identificator și propriul nume. De exemplu, Ctrl+v 1
ne va plasa pe primul tab, iar Ctrl+v 2
ne va plasa pe al doilea tab.
Odată ce se schimbă tabul activ se schimbă și sublinierea tabului activ din bara de taburi.
tmux
.htop
și în al doilea tab deschideți fișierul /etc/passwd
folosind editorul de text nano
.sudo apt-get update
, rulați în al doilea terminal comanda iostat -x 2 5
și în al treilea tab rulați comanda tail -f /var/log/syslog
. Reveniți la primul tab din sesiune.După ce am realizat o conexiune către stația pe care vom lucra, trebuie să ne pregătim mediul de lucru. Configurația mediului de lucru depinde de propriile gusturi și aplicațiile pe care le folosește fiecare.
Configurarea mediului de lucru este recomandată pentru a adapta sistemul la propriile nevoi. De exemplu, o persoană care va lucra foarte mult cu repository-uri de tip Git, probabil va avea nevoie de un prompt care să îi afișeze pe ce branch lucrează, astfel încât să gestioneze mai ușor branchurile. Aceste modificări au rolul de a reduce acțiunile repetitive pe care le facem sau de a pregăti aplicații pe care le vom folosi mai departe.
Această secțiune cuprinde recomandări de configurare a sistemului de la distanță. Au formă de sugestii, nu sunt obligații, pe baza cărora fiecare poate decide pentru configurarea propriului mediu de lucru.
uso
.
Primul aspect pe care îl vom modifica la mediul de lucru este shellul în care rulăm comenzi, deoarece acesta este cea mai folosită unealtă. Fie că că edităm cod, sau administrăm sisteme, acesta este locul unde rulăm comenzi.
Modificările la nivelul shellului se fac schimbând variabile de mediu sau rulând comenzi înainte de rularea efectivă a shellului.
Modificarea mediului shellului o realizăm într-un fișier de configurare. Vom folosi fișierul ~/.profile
, deoarece acesta este citit și rulat de toate implementările de shell majorore, cum ar fi dash
, csh
, bash
sau zsh
, astfel oferă intercompatibilitate între shelluri.
Ne dorim să modificăm shellul predefinit pe care îl folosește sistemul, deoarece fiecare implementare de shell oferă propriile funcționalități. De exemplu, fiecare dintre shellurile csh
, bash
și zsh
implementează un mecanism de auto-completion diferit, astfel completarea se face în mod diferit atunci când apăsăm tasta Tab
.
Pentru a modifica shellul predefinit al unui utilizator folosim comanda usermod
cu opțiunea -s
în felul următor:
student@uso:~$ sudo apt-get install zsh [...] student@uso:~$ sudo usermod -s /bin/zsh student student@uso:~$ su - student This is the Z Shell configuration function for new users, [...] --- Type one of the keys in parentheses --- 2 /home/student/.zshrc:15: scalar parameter HISTFILE created globally in function zsh-newuser-install (eval):1: scalar parameter LS_COLORS created globally in function zsh-newuser-install student@uso ~ % echo $SHELL /bin/zsh
Rulând comanda de mai sus, am modificat shellul predefinit al utilizatorului student
în /bin/zsh
. Pentru verificare, ne-am autentificat ca utilizatorul student
. La prima autentificare zsh
ne-a întrebat ce fel de configurare vrem, iar noi am folosit opțiunea 2
, pentru generarea automată a unei configurări. Am afișat valoarea variabilei SHELL
pentru a afișa calea către shellul folosit.
Modificați shellul predefinit al utilizatorului student
cu shellul /bin/bash
. Încercați să folosiți funcționalitatea de auto-complete. Ce observați?
Există comenzi pe care le rulăm frecvent. Totuși, unele comenzi sunt lungi și durează mult timp să le tastăm de fiecare dată atunci când vrem să le rulăm. Pentru a rezolva această problemă, putem folosi aliasuri. Un alias este o prescurtare pentru o comandă.
Vom folosi comanda alias
pentru defini un alias.
student@uso:~$ alias gs="git status" student@uso:~$ cd uso-lab/ student@uso:~/uso-lab$ gs On branch master Your branch is up to date with 'origin/master'. nothing to commit, working tree clean student@uso:~/uso-lab$ alias [...] alias gs='git status' alias gti='git' alias l='ls -CF' alias la='ls -A' alias ll='ls -alF' alias ls='ls --color=auto'
Am definit aliasul gs
pentru comanda git status
și am verificat-o în repository-ul uso-lab
.
Pentru a verifica ce aliasuri sunt definite, vom folosi comanda alias
fără parametri.
Definirea de mai sus a unui alias nu este persistentă, ci acesta va fi definit cât timp shellul curent este deschis. Pentru a defini un alias în mod persistent, trebuie să îl definim, folosind comanda alias
într-un fișier de configurare, cum ar fi .profile
.
gcs
pentru comanda git commit --signnoff
.glog
pentru comanda git log --oneline
.Fișierul de istoric al unui shell este locul unde sunt salvate comenzile rulate într-un shell până la închiderea sesiunii de shell. Acest fișier este folositor pentru repetarea acțiunilor.
De exemplu, funcționalitatea de căutare inversă din shell bazată pe Ctrl+r
caută în istoricul shellului, așa că este de preferat să avem un istoric complet în care să căutăm pentru a avea mai multe intrări în care să căutăm.
Pentru a mări dimensiunea istoricului shellului, este suficient să setăm variabila de mediu HISTSIZE
într-un fișier de configurare. Vom folosi fișierul de configurare .profile
din motivele enumerate mai sus, aflat în directorul home al utilizatorului student
. Această modificare va fi valabilă doar pentru utilizatorul student
.
student@uso:~$ echo HISTSIZE=20000 >> /home/student/.profile
Modificarea de mai sus nu este suficientă, deoarece aceasta schimbă doar dimensiunea istoricului din shell, care este salvat în fișierul de istoric la închiderea sesiunii de shell. La pornirea shellului, dimensiunea fișierului de istoric este concatenată folosind variabila HISTFILESIZE
. Valoarea predefinită a acestei variabile este 500
.
Faceți modificările necesare astfel încât fișierul de istoric să fie concatenat la 20000
de comenzi la pornirea shellului.
Promptul este o sursă importantă de informații. Acesta ne poate oferi mai multă informație și ne eliberează din a rula anumite comenzi. Practic, noi putem obține mai mult informații rulând mai puține comenzi.
De exemplu, dacă lucrăm foarte des cu repository-uri de Git, vrem să avem un mod cât mai facil de a vedea pe ce branch lucrăm. Această informație poate fi adăugată în prompt.
Promptul shellului bash
este setat folosind variabila PS1
. Orice șir de caractere va fi scris în variabila PS1
și va fi afișat înainte de zona în care introducem comenzi. Dacă modificăm variabila PS1
vom vedea că promptul se modifică:
student@uso:~$ echo $PS1 \[\e]0;\u@\h: \w\a\]${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ student@uso:~$ PS1="president@white-house:~$ " president@white-house:~$ hostname uso president@white-house:~$ id uid=1000(student) gid=1000(student) groups=1000(student),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),120(lpadmin),131(lxd),132(sambashare),997(docker) president@white-house:~$
După cum observăm în rezultatul primei comenzi rulate mai sus, valoarea variabilei PS1
este un șir de caractere complex, dar noi putem să îl suprascriem. Odată suprascrisă variabila PS1
, promptul se schimbă în valoarea din variabilă. Totuși, am rulat comenzi de verificare pentru a vedea că utilizatorul cu care suntem autentificați este în continuare student
și stația la care suntem conectați este uso
Putem să generăm propriul prompt complex folosind utilitare online. Recomandăm EZPrompt . Acest site are funcționalitatea de a genera un prompt modificat. Vrem să generăm un prompt de forma username@hostname:path_to_current_dir-git_branch
. EZPrompt a generat următoarele comenzi pentru a modifica promptul, pe care le vom adăuga la finalul fișierului .profile
:
# get current branch in git repo function parse_git_branch() { BRANCH=`git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/'` if [ ! "${BRANCH}" == "" ] then STAT=`parse_git_dirty` echo "[${BRANCH}${STAT}]" else echo "" fi } # get current status of git repo function parse_git_dirty { status=`git status 2>&1 | tee` dirty=`echo -n "${status}" 2> /dev/null | grep "modified:" &> /dev/null; echo "$?"` untracked=`echo -n "${status}" 2> /dev/null | grep "Untracked files" &> /dev/null; echo "$?"` ahead=`echo -n "${status}" 2> /dev/null | grep "Your branch is ahead of" &> /dev/null; echo "$?"` newfile=`echo -n "${status}" 2> /dev/null | grep "new file:" &> /dev/null; echo "$?"` renamed=`echo -n "${status}" 2> /dev/null | grep "renamed:" &> /dev/null; echo "$?"` deleted=`echo -n "${status}" 2> /dev/null | grep "deleted:" &> /dev/null; echo "$?"` bits='' if [ "${renamed}" == "0" ]; then bits=">${bits}" fi if [ "${ahead}" == "0" ]; then bits="*${bits}" fi if [ "${newfile}" == "0" ]; then bits="+${bits}" fi if [ "${untracked}" == "0" ]; then bits="?${bits}" fi if [ "${deleted}" == "0" ]; then bits="x${bits}" fi if [ "${dirty}" == "0" ]; then bits="!${bits}" fi if [ ! "${bits}" == "" ]; then echo " ${bits}" else echo "" fi } export PS1="\u@\h:\w-\`parse_git_branch\` "
Pornind un nou shell, vedem că promptul s-a schimbat, acum nu mai este colorat. Când schimbăm directorul curent într-un repository Git, în prompt va apărea și branch-ul pe care este setată replica repository-ului
student@uso:~- cd uso-lab/ student@uso:~/uso-lab-[master !?] check-language-support ^C
Se întâmplă ca atunci când lucrăm cu ierarhii de fișiere cu multe directoare, să nu încapă comenzile pe un singur rând. Acest lucru este deranjant, deoarece comenzile devin greu de urmărit.
Pentru a rezolva această problemă, vrem să avem promptul pe un rând și spațiul unde introducem textul pe următorul rând.
Modificați promptul astfel încât comenzile rulate să apară pe următorul rând față de prompt.
Pentru a parcurge această secțiune este recomandat să descărcați ultima versiune a respository-ului laboratorului. Pentru a descărca ultima versiune a repository-ului, rulați comanda git pull
în directorul ~/uso-lab/labs/09-task-admin/lab-container/
.
Infrastructura laboratorului este bazată pe containere Docker ale căror imagini vor fi generate pe propriul calculator. Dacă nu aveți deja instalat Docker Engine pe sistem, scriptul ~/uso-lab/labs/09-task-admin/lab-container/lab_prepare.sh
vă va instala aplicația.
După ce ați terminat de lucrat, vă recomandăm să opriți containerele rulând comanda ./lab_prepare.sh delete
în directorul ~/uso-lab/labs/09-task-admin/lab-container/
.
O componentă importantă a mediului de lucru este spațiul de stocare. Cu toate că vom rula aplicații pe serverul de la distanță, avem nevoie de acces la spațiul de stocare al acestuia, deoarece vrem ca, într-un final, să urmărim rezultatul procesării și, eventual, să îl analizăm folosind utilitare grafice dedicate. O altă nevoie pe care o avem este editarea codului la distanță, deoarece majoritatea programatorilor folosesc IDE-uri în mediu grafic, care nu pot rula mereu eficient de la distanță. Soluția la această nevoie este să partajăm spațiul de stocare între serverul remote
și stația local
de pe care lucrăm.
Pentru rularea acestui demo, rulați în directorul ~/uso-lab/labs/09-task-admin/lab-container/
comanda ./lab_prepare.sh install remote
și comanda ./lab_prepare.sh install ssh-server
. Pentru a ne conecta la infrastructura pentru această secțiune, vom folosi comanda ./lab_prepare.sh connect local
.
SSHFS este o soluție de stocare partajată care permite montarea unui sistem de fișiere care nu este legat fizic la stația local
, ci se folosește de protocolul SSH pentru a transmite operațiile asupra fișierelor prin rețea către un sistem de fișiere conectat prin rețea.
Avantajul folosirii SSHFS este că nu necesită descărcarea sistemului de fișiere de la distanță, deci nu duce la duplicarea fișierelor. Dezavantajul acestei abordări este că dacă pierdem conexiunea la sistemul de fișiere de la distanță, nu mai avem acces la fișiere.
Pentru a monta sistemul de fișiere de pe un alt sistem, vom folosi comanda sshfs
root@local:~# ls /mnt/ root@local:~# sshfs root@10.11.11.2:/ /mnt/ The authenticity of host '10.11.11.2 (10.11.11.2)' can't be established. ECDSA key fingerprint is SHA256:xV1orHYj4fhkc5HE91sfh8QhaVqke/AEMa8mYI423HY. Are you sure you want to continue connecting (yes/no)? yes root@10.11.11.2's password: root@local:~# df -h Filesystem Size Used Avail Use% Mounted on overlay 16G 14G 539M 97% / tmpfs 64M 0 64M 0% /dev tmpfs 2.0G 0 2.0G 0% /sys/fs/cgroup /dev/sda5 16G 14G 539M 97% /etc/hosts shm 64M 0 64M 0% /dev/shm root@10.11.11.2:/ 16G 14G 539M 97% /mnt root@local:~# ls /mnt/ bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
Comanda de mai sus a montat ierarhia de fișiere cu rădăcina în directorul /
de pe sistemul de la adresa IP 10.11.11.2
în directorul /mnt
de pe stația locală, cu numele local
, autentificându-se ca utilizatorul root
.
Am folosit comanda df
pentru a afișa informații despre toate sistemele de fișiere montate pe stația locală. Observăm că pe ultima linie apare conexiunea către stația de la adresa 10.11.11.2
.
Sintaxa comenzii sshfs
se aseamănă cu sintaxa comenzii scp
.
Acest mod de montare a sistemului de fișiere este temporară. Atunci când vom opri stația, sistemul de fișiere va fi demontat.
/
de pe stația 10.11.11.2
în directorul /mnt/vol1
./home/student
de pe stația 10.11.11.2
în directorul /mnt/vol2
.
Deoarece nu ne dorim să rulăm comanda sshfs
atunci când vrem să folosim un sistem de fișiere la distanță, vrem să montăm persistent sistemul de fișiere de la distanță, astfel încât această montare să persiste după oprirea stației locale.
Ca să montăm persistent sistemul de fișiere avem nevoie să copiem cheia SSH pe stația de la distanță, deoarece montarea se va face în mod neinteractiv, deci nu vom avea posibilitatea de a introduce parola, așa cum am descoperit în laboratorul Configurarea avansată a sistemului.
Pentru a monta persistent sistemul de fișiere, vom scrie o intrare în fișierul /etc/fstab
, care va conține detalii despre sistemul de fișiere pe care vrem să îl montăm. Pentru a monta sistemul de fișiere /
de pe sistemul de la adresa IP 10.11.11.2 în directorul /mnt de pe stația locală, autentificându-ne ca utilizatorul root`, vom folosi următoarele comenzi:
root@local:~# ssh-keygen [...] root@local:~# ssh-copy-id root@10.11.11.2 [...] root@local:~# echo "root@10.11.11.2:/ /mnt fuse.sshfs defaults 0 0" >> /etc/fstab root@local:~# mount -a root@local:~# df -h Filesystem Size Used Avail Use% Mounted on overlay 16G 14G 539M 97% / tmpfs 64M 0 64M 0% /dev tmpfs 2.0G 0 2.0G 0% /sys/fs/cgroup /dev/sda5 16G 14G 539M 97% /etc/hosts shm 64M 0 64M 0% /dev/shm root@10.11.11.2:/ 16G 14G 539M 97% /mnt
Am scris în fișierul /etc/fstab
folosind comanda echo
, iar pentru a monta sistemul de fișiere am folosit comanda mount
cu opțiunea -a
pentru montarea sistemelor de fișiere descrise în fișierul /etc/fstab
.
Atenție!:
În mod normal am scrie în fișierul /etc/fstab
folosind un editor de text. Vă recomandăm să nu scrieți în fișiere critice sistemului folosind redirectări, deoarece orice greșeală poate șterge conținutul fișierului.
/
de pe stația 10.11.11.2
în directorul /mnt/vol1
./home/student
de pe stația 10.11.11.2
în directorul /mnt/vol2
.SSHFS nu este o soluție bună pentru a face backup fișierelor deoarece, existând o singură replică, ștergerea locală a unui fișier duce la ștergerea sa și de pe stația remote și, astfel, la pierderea sa. Pe lângă aceasta, dacă stația locală are conexiune slabă la Internet, accesul la fișiere este greoi și neresponsiv. Suplimentar, trebuie configurată o conexiune SSH, care poate necesita la rândul ei existența unui tunel etc.
O alternativă la folosirea SSHFS sunt soluții cum ar fi GoogleDrive, Dropbox, ownCloud sau One Drive. Aceste soluții stochează o replică a fișierului pe toate calculatoarele autentificate de pe un anumit cont. Un alt avantaj al acestora este că oferă suport pentru controlul versiunilor pentru a șterge modificarea anterioară. Cu dezavantajul că trebuie configurate și cu riscul apariției conflictelor la modificări simultane pe noduri diferite. Și cu dezavantajul că acum informația este duplicată: dublu spațiu ocupat și pot apărea conflicte la modificări.
Pentru rularea acestui demo vom folosi direct mașina virtuală uso
.
Dropbox este o soluție care se folosește de un server în Internet care stochează fișierele, ca apoi acestea să fie replicate pe fiecare calculator client.
Este necesară crearea și activarea un cont pentru a folosi serviciul Dropbox.
Dropbox oferă o aplicație care rulează în linie de comandă pe care o vom descărca pentru a sincroniza sistemul de fișiere de pe serverele Dropbox într-un director local.
Vom descărca aplicația Dropbox folosind comanda wget
și o vom instala folosind comanda dpkg
împreună cu parametrul -i
.
student@uso:~$ wget https://www.dropbox.com/download?dl=packages/ubuntu/dropbox_2020.03.04_amd64.deb -O dropbox.deb [...] student@uso:~$ sudo dpkg -i dropbox.deb Starting Dropbox... Dropbox is the easiest way to share and store your files online. Want to learn more? Head to https://www.dropbox.com/ In order to use Dropbox, you must download the proprietary daemon. [y/n] y [...] student@uso:~$ dropbox start To link this computer to a Dropbox account, visit the following url: https://www.dropbox.com/cli_link_nonce?nonce=ffd7d648a2ca2302d1177c0c389e87bd
Observație
Am folosit opțiunea -O
a comenzii wget
pentru a salva fișierul descărcat cu numele dropbox.deb
.
Pentru a instala ultimele componente ale clientului Dropbox este necesar să rulăm comanda dropbox start -i
. După ce am ponit aplicația, este necesar să înregistrăm stația online la contul nostru. Vom face acest lucru accesând linkul afișat de aplicație.
Pentru rezolvarea acestui exercițiu, rulați în directorul ~/uso-lab/labs/09-task-admin/lab-container/
comanda ./lab_prepare.sh install dropbox
. Pentru a ne conecta la infrastructura pentru această secțiune, vom folosi comanda ./lab_prepare.sh connect dropbox
.
dropbox
și porniți aplicația Dropbox pe aceasta.hello.txt
în directorul ~/Dropbox
, partajat de cele două mașini. Scrieți în fișier mesajul Hello from remote
pe stația dropbox
. Verificați că există fișierul hello.txt
în directorul ~/Dropbox
pe stația uso
.
Scopul serviciilor este să ruleze în continuu și să primească cereri de la aplicații client, cum ar fi un client SSH, și să răspundă la aceste cereri. Serviciile sunt aplicații care rulează în continuu pe stație, spre deosebire de comenzi, cum ar fi find
sau ls
, care rulează cât timp se execută comanda. Deoarece ne dorim să avem majoritatea timpului conectivitate la mașină, sau ne dorim să avem acces la paginile web folosite, serverele rulează fără oprire și servesc cereri venite de la clienți. Un sever / serviciu este oprit explicit de utilizator prin comenzi specifice sau este oprit la oprirea sistemului. Fără o intervenție explicită și fără oprirea sistemului, un server / serviciu va rula nedefinit.
Vrem să pornim și să configurăm servicii instalate în sistem, precum:
Avem nevoie de o interfață unică, cu o sintaxă minimală, care ne permite să gestionăm serviciile pe sistem, și care ne permite sa generăm noi propriile servicii.
Comanda folosită pentru gestionarea serviciilor este systemctl
. Aceasta se regăsește pe majoritatea distribuțiilor moderne de Linux.
Atunci când instalăm o aplicație care rulează sub forma unui serviciu, vom putea să îi verificăm starea folosind comanda systemctl status
.
student@uso:~$ systemctl status ssh ● ssh.service - OpenBSD Secure Shell server Loaded: loaded (/lib/systemd/system/ssh.service; enabled; vendor preset: enabled) Active: active (running) since Sat 2021-01-09 04:22:11 EET; 1min 17s ago Docs: man:sshd(8) man:sshd_config(5) Process: 639 ExecStartPre=/usr/sbin/sshd -t (code=exited, status=0/SUCCESS) Main PID: 657 (sshd) Tasks: 1 (limit: 4656) Memory: 4.8M CGroup: /system.slice/ssh.service └─657 sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups ian 09 04:22:11 uso systemd[1]: Starting OpenBSD Secure Shell server... ian 09 04:22:11 uso sshd[657]: Server listening on 0.0.0.0 port 22. ian 09 04:22:11 uso sshd[657]: Server listening on :: port 22. ian 09 04:22:11 uso systemd[1]: Started OpenBSD Secure Shell server. ian 09 04:23:25 uso sshd[1821]: Accepted password for student from 192.168.56.1 port 33714 ssh2 ian 09 04:23:25 uso sshd[1821]: pam_unix(sshd:session): session opened for user student by (uid=0)
Mai sus am afișat starea serviciului SSH. Observăm că acesta este activ și putem urmări ce procese a generat și ce mesaje de diagnosticare afișează.
Programul systemd
se ocupă de pornirea, oprirea și gestionarea serviciilor folosite în sistem pe baza unor fișiere numite fișiere unitate. Fișierul care gestionează serviciul SSH este /lib/systemd/system/ssh.service
. Îl putem identifica din rezultatul comenzii systemctl status
.
Atunci când un serviciu este instalat, acesta vine la pachet cu fișierul cu extensia .service
cu care acesta va fi gestionat de systemd
, după cum putem vedea în rezultatul comenzii de mai jos:
student@uso:~$ sudo apt install ntp [...] Setting up ntp (1:4.2.8p12+dfsg-3ubuntu4) ... Created symlink /etc/systemd/system/network-pre.target.wants/ntp-systemd-netif.path → /lib/systemd/system/ntp-systemd-netif.path. Created symlink /etc/systemd/system/multi-user.target.wants/ntp.service → /lib/systemd/system/ntp.service. ntp-systemd-netif.service is a disabled or a static unit, not starting it. [...]
Serviciul ntp
este folosit pentru sincronizarea ceasului cu surse precise de timp din Internet. Acesta este un serviciu important pentru buna funcționare a aplicațiilor în Internet, deoarece o configurare a timpului pentru o stație poate duce la o funcționare incorectă a acesteia în comunicare.
Afișați starea serviciului thermald
, care gestionează senzorii de temperatură ai sistemului.
Pentru a opri un serviciu vom folosi comanda systemctl stop
în felul următor:
student@uso:~$ sudo netstat -tlpn [sudo] password for student: Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN 501/systemd-resolve tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 4425/sshd: /usr/sbi tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN 541/cupsd tcp6 0 0 :::22 :::* LISTEN 4425/sshd: /usr/sbi tcp6 0 0 ::1:631 :::* LISTEN 541/cupsd student@uso:~$ sudo systemctl stop ssh [sudo] password for student: student@uso:~$ sudo systemctl status ssh ● ssh.service - OpenBSD Secure Shell server Loaded: loaded (/lib/systemd/system/ssh.service; enabled; vendor preset: e> Active: inactive (dead) since Sat 2021-01-09 04:58:28 EET; 9s ago Docs: man:sshd(8) man:sshd_config(5) Process: 640 ExecStartPre=/usr/sbin/sshd -t (code=exited, status=0/SUCCESS) Process: 660 ExecStart=/usr/sbin/sshd -D $SSHD_OPTS (code=exited, status=0/> Main PID: 660 (code=exited, status=0/SUCCESS) ian 09 04:57:29 uso systemd[1]: Starting OpenBSD Secure Shell server... ian 09 04:57:29 uso sshd[660]: Server listening on 0.0.0.0 port 22. ian 09 04:57:29 uso sshd[660]: Server listening on :: port 22. ian 09 04:57:29 uso systemd[1]: Started OpenBSD Secure Shell server. ian 09 04:58:28 uso sshd[660]: Received signal 15; terminating. ian 09 04:58:28 uso systemd[1]: Stopping OpenBSD Secure Shell server... ian 09 04:58:28 uso systemd[1]: ssh.service: Succeeded. ian 09 04:58:28 uso systemd[1]: Stopped OpenBSD Secure Shell server.
Pentru a verifica dacă mai funcționează serviciul SSH vom folosi comanda netstat
pentru a verifica dacă mai ascultă serverul SSH pe portul 22
.
student@uso:~$ sudo netstat -tlpn Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN 501/systemd-resolve tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN 541/cupsd tcp6 0 0 ::1:631 :::* LISTEN 541/cupsd
Observăm că nu ascultă niciun program pe portul 22
.
Afișați starea serviciului ssh
.
Pornirea unui serviciu se face folosind comanda systemctl start
în felul următor:
student@uso:~$ systemctl start ssh student@uso:~$ systemctl status ssh ● ssh.service - OpenBSD Secure Shell server Loaded: loaded (/lib/systemd/system/ssh.service; enabled; vendor preset: enabled) Active: active (running) since Sat 2021-01-09 05:05:30 EET; 2min 30s ago Docs: man:sshd(8) man:sshd_config(5) Process: 4408 ExecStartPre=/usr/sbin/sshd -t (code=exited, status=0/SUCCESS) Main PID: 4425 (sshd) Tasks: 1 (limit: 4656) Memory: 3.4M CGroup: /system.slice/ssh.service └─4425 sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups ian 09 05:05:30 uso systemd[1]: Starting OpenBSD Secure Shell server... ian 09 05:05:30 uso sshd[4425]: Server listening on 0.0.0.0 port 22. ian 09 05:05:30 uso sshd[4425]: Server listening on :: port 22. ian 09 05:05:30 uso systemd[1]: Started OpenBSD Secure Shell server. ian 09 05:05:54 uso sshd[4477]: Accepted password for student from 192.168.56.1 port 34852 ssh2 ian 09 05:05:54 uso sshd[4477]: pam_unix(sshd:session): session opened for user student by (uid=0)
Dacă serviciul nu pornește cu succes, aceasta va afișa un mesaj de avertizare.
Pe parcursul rulării serviciilor pe un sistem, vom dori să schimbăm configurația unui serviciu sau să adăugăm parametri de rulare în plus. Majoritatea aplicațiilor citesc fișierele de configurare o singură dată, atunci când sunt pornite, deci orice modificare ulterioară a fișierelor de configurare nu va fi sesizată de serviciu. Din acest motiv, avem nevoie să repornim servicii.
De exemplu, vrem să permitem utilizatorilor să se autentifice ca utilizatorul root
pe sistemul nostru. Acest lucru este dezactivat în mod predefinit de serviciu din motive de securitate.
student@uso:~$ ssh root@localhost root@localhost's password: Permission denied, please try again. [...]
Observăm că inițial nu puteam să ne conectăm la mașina locală ca utilizatorul root
, cu toate că introduceam parola corectă.
student@uso:~$ sudo su -c 'echo "PermitRootLogin yes" >> /etc/ssh/sshd_config' student@uso:~$ systemctl restart ssh student@uso:~$ ssh root@localhost root@localhost's password: [...] root@uso:~#
Pentru a face acest lucru, avem nevoie să reconfigurăm serviciul SSH. Odată ce am adăugat opțiunea PermitRootLogin yes
în fișierul de configurare al serviciului și am repornit serviciului, am reușit să ne autentificăm ca utilizatorul root
.
Atunci când configurăm un sistem și vrem să definim servicii care rulează pe el, ne dorim ca serviciile să fie setup and forget
, să nu fie necesar să le supraveghem și să le monitorizăm prea mult. Un mod de a ne ușura lucrul cu serverul este pornirea serviciilor la startup, ca să nu fie nevoie sa intervenim noi după secvența de pornire a sistemului, ca să le pornim de mână, folosind comanda systemctl start
Putem să vedem dacă un sistem pornește automat la startup din rezultatul comenzii systemctl status
pe linia care începe cu Loaded:
. Dacă rezultatul conține șirul de caractere enabled
, atunci serviciul pornește la startup, iar dacă aceasta conține șirul disabled
, atunci serviciul nu va porni la startup.
Pentru a dezactiva un serviciu la startup vom folosi comanda systemctl disable
în felul următor:
student@uso:~$ sudo systemctl disable ntp Synchronizing state of ntp.service with SysV service script with /lib/systemd/systemd-sysv-install. Executing: /lib/systemd/systemd-sysv-install disable ntp Removed /etc/systemd/system/multi-user.target.wants/ntp.service. student@uso:~$ sudo systemctl status ntp ● ntp.service - Network Time Service Loaded: loaded (/lib/systemd/system/ntp.service; disabled; vendor preset: enabled) Active: active (running) since Sat 2021-01-09 05:18:49 EET; 27min ago Docs: man:ntpd(8) Main PID: 9756 (ntpd) Tasks: 2 (limit: 4656) Memory: 1.3M CGroup: /system.slice/ntp.service └─9756 /usr/sbin/ntpd -p /var/run/ntpd.pid -g -u 127:134 ian 09 05:18:55 uso ntpd[9756]: Soliciting pool server 185.173.16.132 ian 09 05:24:31 uso ntpd[9756]: kernel reports TIME_ERROR: 0x2041: Clock Unsynchronized ian 09 05:28:41 uso ntpd[9756]: 91.189.91.157 local addr 10.0.2.15 -> <null> ian 09 05:29:00 uso ntpd[9756]: 85.204.240.2 local addr 10.0.2.15 -> <null> ian 09 05:29:04 uso ntpd[9756]: 188.213.49.35 local addr 10.0.2.15 -> <null> ian 09 05:29:05 uso ntpd[9756]: 86.124.75.41 local addr 10.0.2.15 -> <null> ian 09 05:29:08 uso ntpd[9756]: 85.204.240.1 local addr 10.0.2.15 -> <null> ian 09 05:29:09 uso ntpd[9756]: 195.135.194.3 local addr 10.0.2.15 -> <null> ian 09 05:29:52 uso ntpd[9756]: 91.189.89.198 local addr 10.0.2.15 -> <null> ian 09 05:38:03 uso ntpd[9756]: 93.190.144.28 local addr 10.0.2.15 -> <null>
Observăm că pe linia care conține șirul de caractere Loaded
, mesajul este disabled
, dar serviciul funcționează în continuare.
Pentru a activa un serviciu la startup vom folosi comanda systemctl enable
:
student@uso:~$ sudo systemctl enable ntp Synchronizing state of ntp.service with SysV service script with /lib/systemd/systemd-sysv-install. Executing: /lib/systemd/systemd-sysv-install enable ntp Created symlink /etc/systemd/system/multi-user.target.wants/ntp.service → /lib/systemd/system/ntp.service. student@uso:~$ sudo systemctl status ntp ● ntp.service - Network Time Service Loaded: loaded (/lib/systemd/system/ntp.service; enabled; vendor preset: enabled) Active: active (running) since Sat 2021-01-09 05:18:49 EET; 30min ago Docs: man:ntpd(8) Main PID: 9756 (ntpd) Tasks: 2 (limit: 4656) Memory: 1.3M CGroup: /system.slice/ntp.service └─9756 /usr/sbin/ntpd -p /var/run/ntpd.pid -g -u 127:134 ian 09 05:18:55 uso ntpd[9756]: Soliciting pool server 185.173.16.132 ian 09 05:24:31 uso ntpd[9756]: kernel reports TIME_ERROR: 0x2041: Clock Unsynchronized ian 09 05:28:41 uso ntpd[9756]: 91.189.91.157 local addr 10.0.2.15 -> <null> ian 09 05:29:00 uso ntpd[9756]: 85.204.240.2 local addr 10.0.2.15 -> <null> ian 09 05:29:04 uso ntpd[9756]: 188.213.49.35 local addr 10.0.2.15 -> <null> ian 09 05:29:05 uso ntpd[9756]: 86.124.75.41 local addr 10.0.2.15 -> <null> ian 09 05:29:08 uso ntpd[9756]: 85.204.240.1 local addr 10.0.2.15 -> <null> ian 09 05:29:09 uso ntpd[9756]: 195.135.194.3 local addr 10.0.2.15 -> <null> ian 09 05:29:52 uso ntpd[9756]: 91.189.89.198 local addr 10.0.2.15 -> <null> ian 09 05:38:03 uso ntpd[9756]: 93.190.144.28 local addr 10.0.2.15 -> <null>
Observăm că pe linia care conține șirul de caractere Loaded
, mesajul s-a schimbat în enabled
.
În majoritatea cazurilor, serviciile sunt configurate prin fișiere de configurare. Acestea se pot găsi în mai multe locuri:
/etc/default/
, unde sunt fișiere care permit modificarea opțiunilor de rulare a unei comenzi, ca și cum am adăuga noi opțiuni la rularea unei comenzi. Aceste fișiere sunt citite de systemd
, înainte să pornească serviciul;/etc/nume_serviciu/
, unde se află fișierele de configurare sau direct fișierul /etc/nume_serviciu
. Aceste fișiere sunt citite și interpretate de servici. De exemplu, pentru configurarea serviciului NTP, există fișierul /etc/ntp.conf
, iar pentru configurarea serviciului SSH folosim fișierele din directorul /etc/ssh/
.root
folosind numai autentificare bazată pe chei.vsftpd
. Acesta este un serviciu de transfer de fișiere.Realizați modificările necesare astfel încât acest serviciu să NU pornească la startup; Dezactivați funcționalitatea bazată pe IPv6 a serviciului. Hint: listen_ipv6
, listen
. Asigurați-vă că serviciul rulează. Acest serviciu ascultă pe portul 21
.
Atunci când vrem să ne conectăm la Internet printr-un proxy, avem nevoie ca proxy-ul să fie deschis în permanență și să redeschidă conexiunea în cazul în care aceasta este întreruptă. Putem să facem acest lucru folosind servicii systemd
pe care să le gestionăm noi folosind suita de comenzi systemctl
.
Ne propunem să găzduim propriul proxy care va trimite mesaje criptate prin SSH către o altă stație, de unde vor fi trimise mesaje în Internet. Astfel vom putea trece peste anumite filtre care țin cont de poziția geografică.
Un serviciu în systemd
se definește printr-un fișier de configurare în directorul /lib/systemd/system/libvirtd.service
. Pentru serviciul nostru vom genera fișierul la calea /lib/systemd/system/libvirtd.service/auto-proxy.service
. Acest fișier va avea următorul conținut:
[Unit] Description=Keeps a proxy to 'fep.grid.pub.ro' open After=network-online.target ssh.service [Service] User=student ExecStart=/usr/bin/ssh -D 1337 -q -C -N <username-acs>@fep.grid.pub.ro ExecStop=/usr/bin/pkill -f '/usr/bin/ssh -D 1337 -q -C -N' KillMode=process Type=simple Restart=always RestartSec=10 [Install] WantedBy=multi-user.target
Acesta este un șablon pe care putem să îl folosim pentru multe tipuri de servicii. Opțiunile relevante pentru înțelegerea formatului sunt:
ExecStart
, comanda care se va executa pentru a porni serviciul;ExecStop
, comanda care se va executa pentru a opri serviciulAtenție
Pentru ca acest serviciu să funcționeze, este necesar să copiați cheia stației uso
pe mașina fep.grid.pub.ro
.
Putem să verificăm dacă a pornit proxy-ul verificând dacă ascultă vreun serviciu pe mașina locală pe portul 1337
:
student@uso:~$ sudo netstat -tlpn Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 127.0.0.1:1337 0.0.0.0:* LISTEN 32177/ssh tcp 0 0 0.0.0.0:21 0.0.0.0:* LISTEN 15794/vsftpd tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN 7088/systemd-resolv tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 10459/sshd: /usr/sb tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN 541/cupsd tcp6 0 0 ::1:1337 :::* LISTEN 32177/ssh tcp6 0 0 :::22 :::* LISTEN 10459/sshd: /usr/sb tcp6 0 0 ::1:631 :::* LISTEN 541/cupsd
Realizați configurația necesară astfel încât să creați un tunel deschis permanent de pe stația uso
, care primește mesaje din portul 4242
al stației de la adresa 10.11.11.3
și le trimite către portul 22
al mașinii uso
.