Kulcsszó - linux

Alább összegyűjtöttem egy pár parancsot, ami egy Samba környezet telepítése után jól jöhet rendszergazdáknak.

Felhasználó létrehozása: samba-tool user create --mail-address=$mailaddress $username $password [ egyéb kapcsolók: --uid-number=$NUMUID --gid-number=$NUMGUID --uid=$username ]
Felhasználó kitiltása: samba-tool user disable $username
Felhasználó kitiltásának feloldása: samba-tool user enable $username
Felhasználó törlése: samba-tool user delete $username
Felhasználók listája: samba-tool user list
Felhasználó jelszava soha ne járjon le: samba-tool user set-expiry $username --noexpiry
Csoport hozzáadása: samba-tool group add $groupname
Csoportok listája: samba-tool group list

Több infó és parancs a samba-tool man page-én.

A mai cikkünkben egy MySQL replika készítésének lépéseit fogom röviden leírni. A cikkben található tutorial egy megbízásom miatt készült, melyben Ubuntu 16.04 LTS szerver alapokon kellett egy master-slave MySQL replikát összerakni.
A master-slave MySQL replika esetén a külső alkalmazások a master szerveren lévő MySQL adatbázisokhoz csatlakoznak, az azokon végzett módosítások pedig automatikusan szinkronizációra kerülnek a slave szerverre. A master-slave felállás előnye, hogy az adatbázisokról real time másolat készül, amit a master szerver kiesése esetén kézzel egy-két perc alatt használhatóvá lehet tenni. A slave szerver ideiglenes kiesése esetén a szinkronizálás annak újra elérhetővé válása után folytatódik. Üzemeltetési szempontból azért is hasznos, mert az adatbázismentéseket lehet futtatni a slave szerveren, ezzel tehermentesítve a mastert. Némely alkalmazásfejlesztő az alkalmazása gyorsítása érdekében úgy írja meg szoftverét, hogy azon read only query-ket, ahol egy-két rekord eltérésnyi hiba elfogadható, a slave szerveren futtatják, ezzel tehermentesítve a master szervert, és gyorsítva a szoftvert.

Először is, mindkét Ubuntura feltelepítjük a MySQL szervert:
apt install mysql-server mysql-client -y

Ezután a master szerveren elvégzünk egy-két konfigurációt:
service mysql stop
vi /etc/mysql/mysql.conf.d/mysqld.cnf # végére alábbi négy sor hozzáadása:
server-id = 250 # beállítunk egy egyedi szerver azonosítót - nálam ez az IP cím utolsó tagja lett
binlog_ignore_db = mysql
log-error = /var/log/mysql/mysql.err
log-bin = /var/log/mysql/mysql-replication.log
Fentieket kívül kommentezzük ki a bind-address sort is a mysqld.cnf-ből.
TODO: érdemes tűzfallal védeni ez esetben a szervert, hogy ne lehessen bárhonnan elérni a MySQL portokat (pl. iptables + fail2ban kombinációval). Erre nekem most nem volt szükségem, mivel egy komplett tűzfal volt a szerverek előtt.
service mysql restart
mysql # alábbi három parancs futtatása
CREATE USER masterslave@'%' IDENTIFIED BY 'IdeJonATavoliKapcsolodastBiztositoFelhasznaloJelszava';
GRANT SELECT, PROCESS, FILE, SUPER, REPLICATION CLIENT, REPLICATION SLAVE, RELOAD ON *.* TO masterslave@'%';
FLUSH PRIVILEGES;

Most következik a slave szerver konfigurációja:
service mysql stop
vi /etc/mysql/mysql.conf.d/mysqld.cnf # végére alábbi sor hozzáadása:
server-id = 251 # beállítunk egy egyedi szerver azonosítót - nálam ez az IP cím utolsó tagja lett

A fenti műveletek elvégzése után feltöltjük ugyanazt a teszt adatbázist mindkét szerverre. (Nem vagyok biztos benne, hogy ez a művelet szükséges - az általam kiindulási alapnak vett dokumentációkban szerepelt. Mindenesetre a replika beállítása után alapértelmezetten az újonnan létrehozott adatbázisok is automatikusan replikálásra kerülnek a slavere.)

Ezután a master szerveren lekérünk egy-két egyedi információt, ami szükséges lesz ahhoz, hogy később párosítsuk a slave szerverrel.
Fontos! A művelet alatt LOCK-oljuk a master szerveren az adatbázist, így az nem lesz írható!
mysql # alábbi két parancs kimenetét jegyezzük fel (file és position érték fog kelleni)
FLUSH TABLES WITH READ LOCK;
SHOW MASTER STATUS;

Ezután a slave szervert párosítjuk a master szerverrel:
mysql
CHANGE MASTER TO MASTER_HOST='192.168.1.250', MASTER_USER='masterslave', MASTER_PASSWORD='IdeJonATavoliKapcsolodastBiztositoFelhasznaloJelszava', MASTER_LOG_FILE='mysql-replication.000001', MASTER_LOG_POS=8794; # ennél a parancsnál a mysql-replication.000001 és a 8794 sztringeket cseréljük ki az előző bekezdésben lekérdezett információkkal, valamint a 192.168.1.250 részt a master IP címével
START SLAVE;
SHOW SLAVE STATUS; # akkor sikerült megfelelően a párosítás, ha a "Waiting for master to send event." üzenet fogad

Végezetül a master szerveren feloldjuk a lockolást:
mysql
UNLOCK TABLES;

A fenti konfiguráció után van egy működő mysql replikánk.

Az LVM (logikai kötetkezelő) fizikai hardvertől függetlenné teszi a háttértárak kezelését.
Használata többek közt azért javasolt, mert partícióink szabadabban kezelhetőek, igény esetén bővíthetőek, pillanatképeket készíthetünk azokról.

Rétegei

  • PV - Physical Volume: maga a fizikai diszk egy speciálisan konvertált verziója
  • VG - Volume Group: kötetcsoport (egy, vagy több PV-ből álló egység)
  • LV - Logical Volume: logikai kötet (egy, vagy több virtuális háttértár egy VG-n)

Beüzemelése

apt install lvm2 # feltelepítjük a használatához szükséges csomagokat
pvcreate /dev/sdb # létrehozunk egy PV-t (a példában a /dev/sdb szerepel, természetesen ez a saját környezetünkben az a block device, amin LVM-et szeretnénk használni)
vgcreate kotetcsoportneve /dev/sdb # létrehozunk az előbb elkészített PV-n egy VG-t (a példában a "kotetcsoportneve" helyett megadhatunk bármilyen tetszőleges nevet)
lvcreate -L10G -n elsoelsolvmneve kotetcsoportneve # létrehozunk egy 10 GB-os LV-t az előbb létrehozott VG-n (a példában a "elsoelsolvmneve" helyett megadhatunk bármilyen tetszőleges nevet)

A fentiekben tehát létrehoztunk egy PV-t, azon egy VG-t, azon pedig egy LV-t. Az LV beformázása után már használhatjuk is azt, például így:
mkfs.ext4 /dev/mapper/kotetcsoportneve-elsolvmneve # létrehozunk egy ext4 partíciót az LV-n
mount /dev/mapper/kotetcsoportneve-elsolvmneve /mnt # felcsatoljuk azt

Használata

Információk lekérése:
pvs # információ a PV-kről
pvdisplay # bővebb információ a PV-kről
vgs # információ a VG-kről
vgdisplay # bővebb információ a VG-kről
lvs # információ a LV-kről
lvdisplay # bővebb információ a LV-kről
Snapshot készítése LV-ről (például valamilyen kritikus művelet elvégzése előtt):
lvcreate -L 5G -n elsolvmneve-snap -s /dev/mapper/kotetcsoportneve-elsolvmneve # ahol a snapshot neve az "elsolvmneve-snap"
Ha nincs szükségünk az LV-ről készült snapshotra:
lvremove /dev/mapper/kotetcsoportneve-elsolvmneve-snap # a snapshot törlése előtt érdemes használaton kívül helyezni az adott LV-t (pl. umount-olni)
Ha vissza kell állni az LV-ről készült snapshotra:
lvconvert --merge /dev/mapper/kotetcsoportneve-elsolvmneve-snap # a snapshot visszaállítása előtt kötezelő használaton kívül helyezni az adott LV-t (pl. umount-olni)
LV törlése:
lvremove /dev/mapper/kotetcsoportneve-elsolvmneve # az LV törlése előtt kötezelő használaton kívül helyezni az adott LV-t (pl. umount-olni)
Bővítés - új diszk berakása a VG-be:
pvcreate /dev/sdc # létrehozunk egy újabb PV-t (a példában a /dev/sdc szerepel, természetesen ez a saját környezetünkben az a block device, amivel bővíteni szeretnénk a VG-t)
vgextend kotetcsoportneve /dev/sdc # az előző parancsban létrehozott PV-vel bővítjük a már létező VG-nket
Először feltelepítjük és bekonfiguráljuk az NFS szervert:
apt-get install nfs-kernel-server # feltelepítjük a szükséges csomagot
mkdir -p /nfs_share/share1 # létrehozzuk a mappát, amit meg fogunk osztani
echo "/nfs_share/share1 192.168.0.24(rw,async,no_root_squash,no_subtree_check)" >> /etc/exports # beállítjuk, hogy mely IP címről (jelen esetben a 192.168.0.24-ről), és milyen opciókkal legyen elérhető a share (ezzel kapcsolatban itt találhatunk bővebb leírást, magyarázatot)
service nfs-kernel-server restart # újraindítjuk a service-t

Ezután beállítjuk a share felcsatolását a kliens gépen:
apt-get install nfs-common # feltelepítjük a szükséges csomagot
showmount -e 192.168.0.22 # megnézzük, hogy látja e a kliens gép a share-t (az NFS szerver IP címe: 192.168.0.22)
Export list for 192.168.0.22:
/nfs_share/share1 192.168.0.24
mkdir -p /remote_nfs # létrehozzuk a mappát, amibe fel fogjuk csatolni a share-t
mount -t nfs 192.168.0.22:/nfs_share/share1 /remote_nfs # felcsatoljuk a share-t

Ha minden rendben van a felcsatolt share-el (lehet olvasni és írni is), akkor beállítjuk fstab-ba, hogy minden indításkor automatikusan csatolódjon fel:
echo "192.168.0.22:/nfs_share/share1 /remote_nfs nfs auto,noatime,nolock,bg,nfsvers=3,intr,tcp,actimeo=1800 0 0" >> /etc/fstab # az opciókkal kapcsolatban itt találhatuk bővebb leírást

Az alábbi tutorialban leírom, miként lehet titkosított merevlemezt készíteni és menedzselni Linux alatt.

Figyelem! A leírás követése visszavonhatatlan adatvesztést okoz a partíción / merevlemezen.
Fontos, hogy a megadott titkosítási jelszót jegyezzük meg, különben búcsút mondhatunk adatainknak!

apt-get install cryptsetup
cryptsetup -y -v luksFormat /dev/sdb1 # a /dev/sdb1 helyett megadjuk a titkosítani kívánt partíció / merevlemez elérési útvonalát
cryptsetup luksOpen /dev/sdb1 secretdisk # a "secretdisk" helyett megadjuk a titkosított partíció / merevlemez fantázianevét, amivel később hivatkozni fogunk rá
apt-get install pv
pv -tpreb /dev/zero | dd of=/dev/mapper/secretdisk bs=128M # azért, hogy ne okozzon problémát az esetleg a diszken lévő régi adat, felülírjuk azt nullákkal
mkdir -p /mnt/secretdisk # elkészítjük a csatolási pontot
cd /etc && echo "/dev/mapper/secretdisk /mnt/secretdisk ext4 defaults,noauto 0 1" >> fstab # beállítjuk fstabba a csatolási pontot
mkfs.ext4 /dev/mapper/secretdisk # elkészítjük a fájlrendszert

A fenti leírás után teszteljük a titkosított kötet működését:
mount /dev/mapper/secretdisk
df -H && cd /mnt/secretdisk && ls -l

Ha le szeretnénk csatolni a crypt-elt kötetet, a következőt kell tennünk:
umount /mnt/secretdisk # lecsatoljuk a kötetet
cryptsetup luksClose secretdisk # bezárjuk a cryptet

Ha újra fel szeretnénk csatolni a követet, csak a következő parancsokat kell kiadnunk:
cryptsetup luksOpen /dev/sdb1 secretdisk # kinyitjuk a cryptet
mount /mnt/secretdisk # felcsatoljuk a kötetet

Hogyan tudjuk megváltoztatni, törölni a jelszavunkat, vagy épp újat hozzáadni?
Minden esetben a fentiek szerint le kell csatolnunk a cryptelt kötetet, majd:

Jelszómódosítás:
cryptsetup luksChangeKey /dev/sdb1

Új jelszó hozzadása (összesen nyolc jelszó tartozhat egy kötethez):
cryptsetup luksAddKey /dev/sdb1

Jelszó törlése (egy jelszónak legalább kell maradnia):
cryptsetup luksRemoveKey /dev/sdb1

Mit tegyünk, ha jelszó megadása nélkül akarjuk felcsatolni a kötetet? Először is gondoljuk át, hogy ez esetben egy kulcsfájlt kell létrehoznunk, ami ha illetéktelenek kezébe kerül, akkor hozzá fognak tudni férni a titkosított köteten tárolt adatainkhoz.
dd if=/dev/urandom of=/root/.secretdisk.keyfile bs=1024 count=4 # elkészítjük a kulcsfájlt
chmod 400 /root/.secretdisk.keyfile # beállítjuk rajta a jogosultságokat
cryptsetup luksAddKey /dev/sdb1 /root/.secretdisk.keyfile # hozzárendeljük azt a kötethez
cd /etc && echo "secretdisk /dev/sdb1 /root/.secretdisk.keyfile luks" >> crypttab

Egy régi VPS mentésünkből egy fájlra volt szükségem. A mentések LVM targetekre készültek, egy LVM target egy VPS összes partícióját tartalmazza. Hogyan lehet ebből adatot kinyerni?
apt-get install kpartx
kpartx -a /dev/backup/regi-vps-backup
mount /dev/mapper/regi-vps-backup1 /mnt

A fenti lépések után kimásoljuk a szükséges állományokat a mentésből, majd lecsatoljuk azt:

umount /mnt
kpartx -d /dev/mapper/regi-vps-backup

Az eddig megismert Linuxos környezetek legtöbbjében a beüzemelő szakemberek külön partíciót hoztak létre a swap-nak. Több esetben belefutottunk így beüzemelt szervereknél, hogy 1. a szerver vagy nem használta ki a cserehely töredékét sem; 2. a swap partíció mérete jócskán kevésnek bizonyult. Bőven vannak érvek a fájlba való swapolás mellett és ellen is (pl. itt, itt, vagy épp itt). Mindenesetre az use case adott, nézzük, hogyan lehet fájlba swapolni:

fallocate -l 32G /swapfile # létrehozunk egy 32Gb méretű fájlt
chmod 600 /swapfile # beállítjuk a jogosultságot
mkswap /swapfile # megformázzuk a cserhelyet
swapon /swapfile # felcsatoljuk a swapot
free -m # ellenőrizzük a swap működését
echo "/swapfile swap swap sw 0 0" >> /etc/fstab # hozzáadjuk az fstab fájlhoz, hogy következő indításkor is meglegyen

Több módon is védhetjük szerverünk SSH portját. Módosíthatjuk, hogy melyik porton lehessen SSH-zni az alapértelmezett 22-es helyett, beállíthatjuk, hogy csak kulcssal lehessen belépni (amire tehetünk extra jelszóvédelmet), fail2ban-t telepíthetünk, mely bizonyos számú hibás bejelentkezés után kitiltja a támadó IP címét, beállíthatunk port knockingot, mely blokkolja az ssh portot, mindaddig, amíg egy másik porton be nem kopogunk a szerverre.
A fenti megoldások sok fejfájástól megkímélhetnek minket, azonban nem nyújtanak teljes védelmet az esetben, ha kikerül a jelszavunk - például feltörik, megfertőzik azt az eszközt, ahonnan csatlakozni szoktunk SSH-n. Erre ad egy extra védelmet a Google Authenticator, mellyel kétfaktoros bejelentkezést tudunk beállítani szerverünkre. Nézzük, hogyan!

Szükségünk lesz egy Android-os, vagy IOS-es telefonra. Mielőtt belevágunk telepítsük a Google Authenticator szoftvert Android-ra, vagy IOS-re

apt-get install libpam-google-authenticator # feltelepítjük a szerverre a google-authenticator alkalmazást
Megnyitjuk /etc/pam.d/sshd állományt, majd a legtetejére hozzáadjuk az alábbi sort:

auth required pam_google_authenticator.so

Megnyitjuk az /etc/ssh/sshd_config fájlt, majd a ChallengeResponseAuthentication sor értékét yes-re állítjuk:

ChallengeResponseAuthentication yes

Ezután újraindítjuk az sshd service-t:service sshd restart
Ezután annak a felhasználónak a nevében, akivel ssh-zni szeretnénk a továbbiakban, futtatjuk a google-authenticator parancsot:
google-authenticator
Do you want authentication tokens to be time-based (y/n) y
QR kód példa
Your new secret key is: ABCD123456EFGHJK
Your verification code is 123321
Your emergency scratch codes are:
12345678
23456789
34567890
45678901
56789012
Do you want me to update your "/home/testuser/.google_authenticator" file (y/n) y
Do you want to disallow multiple uses of the same authenticationtoken? This restricts you to one login about every 30s, but it increasesyour chances to notice or even prevent man-in-the-middle attacks (y/n) y
By default, tokens are good for 30 seconds and in order to compensate forpossible time-skew between the client and the server, we allow an extratoken before and after the current time. If you experience problems with poortime synchronization, you can increase the window from its defaultsize of 1:30min to about 4min. Do you want to do so (y/n) n
If the computer that you are logging into isn hardened against brute-forcelogin attempts, you can enable rate-limiting for the authentication module.By default, this limits attackers to no more than 3 login attempts every 30s.Do you want to enable rate-limiting (y/n) y

Mi a teendőnk? Nyissuk meg a Google Authenticator-t a telefonunkon, szkenneljük be a kapott QR kódot. A parancs futtatásokat megjelenő hat darab "emergency code"-ot írjuk fel, mivel ha nincs nálunk a telefonunk, akkor ezekkel az egyszerhasználatos kódokkal fogunk tudni belépni szerverünkre. Ezenkívül meg kell válaszolnunk a parancs futásakor kapott kérdéseket is.

Felmerülhet a kérdés, hogy van e lehetőségünk fehérlistára tenni IP címeket, vagy címtartományokat, ahonnan Authenticator használata nélkül engedjen be minket a szerver. Igen, van!

Megnyitjuk /etc/pam.d/sshd állományt, majd a legtetejére hozzáadjuk az alábbi sort:

auth [success=1 default=ignore] pam_access.so accessfile=/etc/security/access-local.conf

Megnyitjuk /etc/security/access-local.conf állományt, majd az alábbi sorokat hozzáadjuk (192.168.0.0/24 helyére írjuk a megfelelő címet, címtartományt):

/etc/security/access-local.conf fájlba:# only allow from local IP range+ : ALL : 192.168.0.0/24+ : ALL : LOCAL- : ALL : ALL

A napokban egy LVM targetek mentését végző bash szkript megírásán dolgoztam. A szkript - miután lekéri az LVM targetek listáját - egy while ciklus segítségével sorról sorra feldolgozza az LVM targetek nevét, majd ssh kapcsolatot nyit, snapshotot készít, és lementi a targetek tartalmát.
Tesztjeim során sajnos az első target mentése után a while ciklus mindig megszakadt. Hogy miért? Azért, mert az SSH breakelte a ciklust. Megoldást egy fórumon találtam, a parancs végére egy < /dev/null írása megoldja a problémát:ssh example.com "lvcreate -L 10G -n snapshotneve -s targetneve >/dev/null 2>&1" < /dev/null

Az alábbi parancs kiadásával egy adott szerveren található összes MySQL adatbázis tartalmát kidumpolhatjuk:

for db in $(mysql -u root -pPASSWORD -s -e "SHOW DATABASES;"); do mysqldump -u root -pPASSWORD $db > $db-backup.sql; done

(A "PASSWORD" helyére a mysql root felhasználó jelszavát kell megadni)