19-bo‘lim
Zaxira nusxa, taymerlar va himoya
Ishlaydigan zaxira skripti, systemd taymerlari, tiklashni sinash va fail2ban bilan takroriy hujumlarni bloklash.
Ushbu bo‘lim mundarijasi
Zaxira nusxa - tiklash demak. Nusxa olingani hech nimani anglatmaydi, agar undan tiklab bo'lmasa. Bu bo'lim shu farqqa qurilgan.
Uch-ikki-bir qoidasi #
Nimani zaxiraga olish kerak #
| Nima | Nima uchun |
|---|---|
| Ma'lumotlar bazasi | Tiklab bo'lmaydigan yagona narsa |
/etc | Butun server sozlamasi (2-bo'lim) |
| Foydalanuvchi yuklagan fayllar | /var/www/.../yuklamalar |
/home | Foydalanuvchi ma'lumotlari |
| Ilova kodi | Agar Git da bo'lmasa |
| Zaxira skriptining o'zi | Aks holda tiklash usulini yo'qotasiz |
| Nima kerak emas | Sabab |
|---|---|
/proc, /sys | Soxta fayl tizimlari |
/tmp | Vaqtinchalik |
node_modules, vendor | Qayta o'rnatiladi |
| Jurnal fayllari | Odatda kerak emas |
Arxiv va tiklash #
mkdir -p manba/ichki nusxa
echo "birinchi" > manba/a.txt
echo "ikkinchi" > manba/ichki/b.txt
tar -czf nusxa/zaxira.tar.gz -C manba .
tar -tzf nusxa/zaxira.tar.gz | sort
./
./a.txt
./ichki/
./ichki/b.txt
| Bayroq | Vazifa |
|---|---|
-c | Yaratish |
-x | Ochish |
-t | Ro'yxatni ko'rish |
-z | gzip bilan siqish |
-f fayl | Fayl nomi |
-C katalog | Shu katalogga o'tib ishlash |
--exclude=naqsh | Chiqarib tashlash |
tar -czf nusxa/zaxira.tar.gz -C manba .
mkdir -p tiklangan
tar -xzf nusxa/zaxira.tar.gz -C tiklangan
find tiklangan -type f | sort
tiklangan/a.txt
tiklangan/ichki/b.txt
-C bilan ishlang, mutlaq yo'l bilan emastar -czf zaxira.tar.gz /var/www/sayt
Bu arxivda yo'llar var/www/sayt/... bo'lib saqlanadi va
tar ogohlantirish beradi. Ochganda esa joriy katalogda
var/www/sayt/ tuzilmasi paydo bo'ladi - siz kutgan joyda
emas.
To'g'ri shakl:
tar -czf zaxira.tar.gz -C /var/www sayt
Endi arxivda sayt/... yotadi va uni istagan joyga ochish
mumkin:
tar -xzf zaxira.tar.gz -C /var/www
Ochishdan oldin doim tar -tzf bilan ichida nima
borligini ko'ring - ayniqsa arxiv boshqa joydan kelgan
bo'lsa.
O'sishli zaxira - rsync --link-dest #
Har kuni to'liq nusxa olish diskni tez to'ldiradi. rsync
o'zgarmagan fayllar uchun qattiq havola yaratadi.
mkdir -p kun1 kun2
rsync -a manba/ kun1/
echo "uchinchi" > manba/c.txt
rsync -a --link-dest=../kun1 manba/ kun2/
[ "$(stat -c %i kun1/a.txt)" = "$(stat -c %i kun2/a.txt)" ] \
&& echo "a.txt - bitta inode, disk joyi ikki marta band emas"
[ -f kun2/c.txt ] && echo "c.txt - yangi fayl, alohida nusxa"
a.txt - bitta inode, disk joyi ikki marta band emas
c.txt - yangi fayl, alohida nusxa
kun2 katalogi to'liq nusxaga o'xshaydi - unda hamma
fayllar bor. Lekin o'zgarmagan fayllar diskda ikkinchi
marta yozilmagan: ular 14-bo'limda ko'rgan qattiq
havolalar.
Har kun uchun alohida katalog, lekin disk faqat o'zgargan fayllar hajmicha o'sadi:
rsync -a --delete \
--link-dest="../$(date -d yesterday +%F)" \
/var/www/ "/zaxira/$(date +%F)/"
Afzalliklari:
| Xususiyat | Izoh |
|---|---|
| Har kun to'liq nusxaga o'xshaydi | Tiklash oson - shunchaki ko'chiring |
| Disk kam ishlatiladi | Faqat o'zgarishlar |
| Eskisini o'chirish oson | rm -rf /zaxira/2026-08-01 |
| Zanjir yo'q | Bitta kunni o'chirish qolganlarga ta'sir qilmaydi |
Oxirgisi muhim: an'anaviy "to'liq + o'sishli" sxemada
oradagi bitta arxiv buzilsa, butun zanjir yaroqsiz
bo'ladi. --link-dest da bunday bog'liqlik yo'q.
Ma'lumotlar bazasi #
mysqldump --single-transaction --quick --routines \
--databases softromeda_edu | gzip > /zaxira/baza.sql.gz
| Bayroq | Nima uchun |
|---|---|
--single-transaction | Jadvalni qulflamaydi - sayt ishlashda davom etadi |
--quick | Katta jadvallarni xotiraga to'liq yuklamaydi |
--routines | Saqlangan protseduralar |
--databases | CREATE DATABASE ni ham qo'shadi |
tar bilan nusxalamang/var/lib/mysql katalogini tar bilan arxivlash - buzilgan
zaxira olishning ishonchli usuli. Nusxa olish paytida baza
fayllarga yozishda davom etadi va arxivda yarim yozilgan
holat qoladi.
To'g'ri usullar:
| Usul | Qachon |
|---|---|
mysqldump --single-transaction | InnoDB uchun - eng oddiy |
mariabackup / xtrabackup | Katta bazalar, tez tiklash |
Bazani to'xtatib tar | Faqat texnik tanaffusda |
--single-transaction InnoDB da ishlaydi, chunki u
16-17-bo'limlardagi ma'lumotlar bazasi darsligida ko'rgan
REPEATABLE READ snapshotidan foydalanadi: dump butun
davomida bitta izchil holatni ko'radi.
MyISAM jadvallar uchun bu ishlamaydi - u yerda --lock-tables
kerak, ya'ni sayt to'xtaydi.
Zaxira skripti #
Bu skript darslik davomida to'plangan qoidalarni birlashtiradi.
cat > zaxira.sh <<'EOF'
#!/bin/bash
set -euo pipefail
umask 077
MANBA="/var/www/sayt"
NUSXA="/zaxira"
QULF="/run/zaxira.pid"
exec > >(systemd-cat -t zaxira -p info) 2>&1
if [ -f "$QULF" ] && kill -0 "$(cat "$QULF")" 2>/dev/null; then
echo "oldingi nusxa hali ishlayapti - chiqilmoqda"
exit 0
fi
echo $$ > "$QULF"
trap 'rm -f "$QULF"' EXIT
SANA=$(date +%F)
echo "zaxira boshlandi: $SANA"
nice -n 19 ionice -c 3 \
tar -czf "$NUSXA/sayt-$SANA.tar.gz" -C "$(dirname "$MANBA")" "$(basename "$MANBA")"
find "$NUSXA" -name 'sayt-*.tar.gz' -mtime +14 -delete
echo "zaxira tugadi: $(du -h "$NUSXA/sayt-$SANA.tar.gz" | cut -f1)"
EOF
chmod 755 zaxira.sh
bash -n zaxira.sh && echo "sintaksis to'g'ri"
sintaksis to'g'ri
Har qatorning sababi:
| Qator | Qaysi bo'limdan |
|---|---|
set -euo pipefail | Xatoda darhol to'xtash |
umask 077 | 4-bo'lim - arxivni faqat egasi o'qisin |
exec > >(systemd-cat ...) | 13-bo'lim - jurnalga yozish |
kill -0 bilan qulf | 10-bo'lim - oldingi nusxa ishlayaptimi |
trap ... EXIT | 10-bo'lim - chiqishda tozalash |
nice + ionice | 10-bo'lim - saytga xalaqit bermaslik |
| Mutlaq yo'llar | 2-bo'lim - cron boshqa katalogdan ishga tushiradi |
find -mtime +14 -delete | Eskilarini tozalash |
set -e va quvurlarset -e xato bo'lganda skriptni to'xtatadi - lekin quvurda
faqat oxirgi buyruqning kodiga qaraydi:
mysqldump baza | gzip > nusxa.sql.gz
mysqldump yiqilsa ham, gzip muvaffaqiyatli tugaydi - va
sizda bo'sh, lekin "muvaffaqiyatli" arxiv qoladi.
set -o pipefail aynan shuni tuzatadi: quvurdagi istalgan
buyruq yiqilsa, butun quvur xato hisoblanadi.
Shuning uchun uchtasi doim birga: set -euo pipefail.
-u esa e'lon qilinmagan o'zgaruvchini xato deb hisoblaydi -
bu 7-bo'limdagi rm -rf $ZAXIRA /* halokatining oldini
oladi.
systemd taymerlari #
cron o'rniga systemd taymerlari afzalroq.
| Xususiyat | cron | systemd taymeri |
|---|---|---|
| Jurnal | Pochtaga yoki hech qayerga | journalctl -u |
| O'tkazib yuborilgan ishlar | Yo'qoladi | Persistent=true bilan bajariladi |
| Resurs cheklovi | Yo'q | MemoryMax, CPUQuota |
| Bog'liqliklar | Yo'q | After=, Requires= |
| Tasodifiy kechikish | Qo'lda | RandomizedDelaySec= |
| Holatni ko'rish | Qiyin | systemctl list-timers |
rm -f /etc/systemd/system/sr-zaxira.service /etc/systemd/system/sr-zaxira.timer
cat > /etc/systemd/system/sr-zaxira.service <<'EOF'
[Unit]
Description=Softromeda zaxira nusxasi
[Service]
Type=oneshot
ExecStart=/bin/echo "zaxira bajarildi"
Nice=19
IOSchedulingClass=idle
EOF
cat > /etc/systemd/system/sr-zaxira.timer <<'EOF'
[Unit]
Description=Har kuni 03:30 da zaxira
[Timer]
OnCalendar=*-*-* 03:30:00
RandomizedDelaySec=15m
Persistent=true
[Install]
WantedBy=timers.target
EOF
systemctl daemon-reload
systemd-analyze verify /etc/systemd/system/sr-zaxira.timer && echo "taymer to'g'ri"
taymer to'g'ri
systemctl show sr-zaxira.timer -p Persistent -p RandomizedDelayUSec
RandomizedDelayUSec=15min
Persistent=yes
| Sozlama | Nima beradi |
|---|---|
OnCalendar=*-*-* 03:30:00 | Har kuni soat 03:30 da |
Persistent=true | Server o'chiq bo'lgan bo'lsa - yoqilganda bajaradi |
RandomizedDelaySec=15m | 0-15 daqiqa tasodifiy kechikish |
OnBootSec=5min | Yuklanishdan 5 daqiqa keyin |
OnUnitActiveSec=1h | Oxirgi bajarilishdan bir soat keyin |
RandomizedDelaySec nima uchun kerakAgar sizda o'nta server bo'lsa va hammasi soat 03:30 da zaxira olsa, ular bir vaqtda:
- Bitta zaxira serveriga yozadi - tarmoq to'yinadi;
- Bitta ma'lumotlar bazasidan o'qiydi;
- Provayder tarmog'ida cho'qqi yaratadi.
Tasodifiy kechikish yukni yoyadi. Bu bulutdagi API so'rovlarida ham bir xil naqsh - "thundering herd" muammosining oddiy yechimi.
Persistent=true esa boshqa muammoni hal qiladi: noutbuk
yoki vaqtincha o'chirilgan server soat 03:30 da o'chiq
bo'lsa, cron ishni butunlay o'tkazib yuboradi, taymer
esa yoqilishi bilan bajaradi.
Kalendar ifodasini tekshirish:
systemd-analyze calendar '*-*-* 03:30:00' | grep 'Normalized'
Normalized form: *-*-* 03:30:00
systemd-analyze calendar daily | grep 'Normalized'
Normalized form: *-*-* 00:00:00
sudo systemctl enable --now sr-zaxira.timer
.timer ni yoqasiz, .service ni emas. Xizmat enable
qilinsa, u har yuklanishda ishga tushadi - bu kerak
emas.
Tekshirish:
| Buyruq | Nima ko'rsatadi |
|---|---|
systemctl list-timers | Barcha taymerlar va keyingi ishga tushish vaqti |
systemctl status sr-zaxira.timer | Taymer holati |
journalctl -u sr-zaxira | Bajarilish tarixi |
systemctl start sr-zaxira.service | Qo'lda sinash |
Oxirgisi muhim: taymerni kutmasdan, xizmatni qo'lda ishga tushirib sinang.
systemctl start sr-zaxira.service
sleep 1
journalctl -u sr-zaxira -n 3 --no-pager -o cat | grep -c 'zaxira bajarildi'
1
Tiklashni sinash #
Bu bo'limning eng muhim jumlasi.
Amalda ko'p uchraydigan holatlar:
| Holat | Qachon aniqlanadi |
|---|---|
| Skript oyiga bir marta yiqilgan | Tiklash kerak bo'lganda |
Arxiv bo'sh (pipefail yo'q) | Tiklash kerak bo'lganda |
| Baza dumpi buzilgan | Tiklash kerak bo'lganda |
| Shifrlash kaliti yo'qolgan | Tiklash kerak bo'lganda |
| Zaxira diski to'lgan | Tiklash kerak bo'lganda |
Barchasi bir xil vaqtda aniqlanadi - va bu eng yomon vaqt.
Chora:
| Amaliyot | Qanchalik tez-tez |
|---|---|
| Arxiv hajmini tekshirish | Har nusxadan keyin, avtomatik |
| Bitta faylni tiklab ko'rish | Haftada |
| To'liq tiklashni sinash | Choragiga bir marta |
| Tiklash tartibini yozib qo'yish | Bir marta, keyin yangilab turish |
Oxirgisi ham muhim: tiklash tartibi serverning o'zida saqlanmasin. Server yo'q bo'lganda unga kira olmaysiz.
tar -czf nusxa/sinov.tar.gz -C manba .
tar -tzf nusxa/sinov.tar.gz > /dev/null && echo "arxiv butun"
[ "$(stat -c %s nusxa/sinov.tar.gz)" -gt 100 ] && echo "arxiv bo'sh emas"
arxiv butun
arxiv bo'sh emas
Bu ikki tekshiruvni zaxira skriptining oxiriga qo'shing - ular bo'sh yoki buzilgan arxivni darhol aniqlaydi.
fail2ban #
SSH ga takroriy urinishlarni jurnaldan topib, IP ni vaqtincha bloklaydi.
Avval mexanizmni ko'ramiz - jurnaldan urinishlarni sanash:
cat > auth.log <<'EOF'
Sep 10 08:14:02 srv sshd[1201]: Failed password for root from 203.0.113.55 port 41022 ssh2
Sep 10 08:14:05 srv sshd[1203]: Failed password for root from 203.0.113.55 port 41028 ssh2
Sep 10 08:14:09 srv sshd[1205]: Failed password for admin from 203.0.113.55 port 41034 ssh2
Sep 10 08:15:11 srv sshd[1210]: Failed password for husanboy from 198.51.100.7 port 50122 ssh2
Sep 10 08:16:40 srv sshd[1215]: Accepted publickey for husanboy from 198.51.100.7 port 50130 ssh2
EOF
grep 'Failed password' auth.log | awk '{print $(NF-3)}' | sort | uniq -c | sort -rn
3 203.0.113.55
1 198.51.100.7
fail2ban aynan shuni avtomatlashtiradi: naqshni topadi,
sanaydi va chegaradan oshsa xavfsizlik devoriga qoida
qo'shadi.
sudo apt install fail2ban
sudo tee /etc/fail2ban/jail.local <<'EOF'
[DEFAULT]
bantime = 1h
findtime = 10m
maxretry = 5
backend = systemd
[sshd]
enabled = true
EOF
sudo systemctl enable --now fail2ban
sudo fail2ban-client status sshd
| Sozlama | Ma'no |
|---|---|
maxretry = 5 | Necha urinishdan keyin |
findtime = 10m | Shu oraliqda sanaladi |
bantime = 1h | Qancha vaqtga bloklanadi |
backend = systemd | Jurnalni journald dan o'qish |
ignoreip = 10.0.0.0/8 | O'zingizni chiqarib qo'ying |
fail2ban sizni ham bloklashi mumkinParolni bir necha marta noto'g'ri kiritsangiz, o'zingiz ham bloklanasiz.
Uchta chora:
| Chora | Izoh |
|---|---|
ignoreip ga ofis IP sini qo'shing | Doimiy manzil bo'lsa |
| Kalit bilan kiring | 8-bo'lim - parol umuman ishlatilmaydi |
| Provayder konsolini biling | Bloklanganda yagona yo'l |
Blokni qo'lda yechish:
sudo fail2ban-client set sshd unbanip 203.0.113.55
Muhim nuqta: fail2ban kalit bilan kirishning o'rnini
bosmaydi. PasswordAuthentication no qo'yilgan serverda
parol taxmin qilish hujumi allaqachon foydasiz - fail2ban
esa faqat jurnalni tozaroq qiladi va yukni kamaytiradi.
Tartib shunday: avval kalit, keyin xavfsizlik devori,
undan keyin fail2ban.
Nazorat skripti #
14 va 18-bo'limlarda va'da qilingan tekshiruvlarni birlashtiramiz:
cat > nazorat.sh <<'EOF'
#!/bin/bash
set -uo pipefail
CHEGARA=85
df -h -x tmpfs -x devtmpfs --output=pcent,target | tail -n +2 |
while read -r foiz nuqta; do
son=${foiz%\%}
if [ "$son" -ge "$CHEGARA" ]; then
logger -t nazorat -p user.warning "$nuqta ${son}% to'ldi"
fi
done
if ! systemctl is-system-running --quiet; then
logger -t nazorat -p user.warning \
"yiqilgan xizmatlar: $(systemctl --failed --no-legend | wc -l)"
fi
EOF
chmod 755 nazorat.sh
bash -n nazorat.sh && echo "nazorat skripti to'g'ri"
nazorat skripti to'g'ri
Uni ham taymerga qo'ying - OnCalendar=hourly.
logger xabarni jurnalga yozadi - lekin jurnalni hech kim
o'qimasa, foydasi yo'q.
| Usul | Izoh |
|---|---|
| Pochta | Oddiy, lekin spamga tushishi mumkin |
| Telegram bot | Tez, telefonda ko'rinadi |
| Monitoring tizimi | Zabbix, Prometheus + Alertmanager |
systemd OnFailure= | Xizmat yiqilganda xabar yuborish |
Oxirgisi eng oddiy va ko'pincha yetarli:
[Unit]
OnFailure=xabar@%n.service
Endi har qanday xizmat yiqilganda xabar@ xizmati ishga
tushadi va sizga yozadi.
Muhimi - ogohlantirish kam va ahamiyatli bo'lsin. Kuniga o'nlab xabar kelsa, siz ularni o'qishni to'xtatasiz - va haqiqiy muammoni o'tkazib yuborasiz.
tar -Cbilan arxiv yarating va-tbilan ichini ko'ring.- Arxivni boshqa katalogga tiklang.
rsync --link-destbilan o'sishli nusxa oling.stat -c %ibilan qattiq havolani tasdiqlang.- Zaxira skriptini yozing - qulf,
umask,nicebilan. set -o pipefailnima uchun kerakligini tushuntiring.systemdxizmati va taymerini yarating.systemd-analyze calendarbilan ifodani tekshiring.- Jurnaldan muvaffaqiyatsiz urinishlarni IP bo'yicha sanang.
bash -nbilan ikkala skriptni tekshiring.
Xulosa #
- Zaxira nusxa emas, tiklash muhim - sinalmagan zaxira yo'q hisoblanadi.
- 3-2-1: uch nusxa, ikki muhit, biri boshqa joyda.
- Zaxira serverida o'chirish huquqi bo'lmasin.
tar -Cishlating, mutlaq yo'l bilan arxivlamang.rsync --link-dest- to'liq ko'rinishli, lekin o'sishli nusxa.- Ishlab turgan bazani
tarqilmang -mysqldump --single-transaction. - Skriptda
set -euo pipefail;pipefailbo'sh arxivdan saqlaydi. systemdtaymericrondan afzal: jurnal,Persistent, cheklovlar..timernienableqiling,.serviceni emas.fail2bankalit bilan kirishning o'rnini bosmaydi.
Keyingi va oxirgi bo'limda hamma narsani birlashtiramiz: bo'sh serverdan ishlaydigan saytgacha to'liq yo'l.
O‘qish tarixini saqlamoqchimisiz?
Tizimga kirsangiz, tugatgan bo‘limlaringiz saqlanadi va qoldirgan joyingizdan davom etasiz.
Xatolik topdingizmi?
Imlo xatosi, ishlamaydigan kod yoki noto‘g‘ri ma‘lumotni ko‘rsangiz - bizga xabar bering. Har bir xabar administrator tomonidan ko‘rib chiqiladi.