Asosiy matnga o'tish
Blog

Server

Ma'lumotlar bazasi xavfsizligi: portdan maydon shifrlashgacha

Baza internetga ochiq bo'lmasligi, minimal huquqli foydalanuvchilar, TLS, zaxira, maxfiy maydonlarni shifrlash va audit. PostgreSQL va MySQL uchun amaliy qo'llanma.

· 11 daq. o'qish

Foto: The National Archives (UK), CC BY 3.0 · Wikimedia Commons

Ma'lumotlar bazasi — tizimning eng qimmatli qismi. Foydalanuvchilar, to'lovlar, hujjatlar, shaxsiy ma'lumotlar — hammasi shu yerda. Shunga qaramay, baza ko'pincha "ilova ishlayapti, demak hammasi joyida" tamoyili bilan o'rnatiladi: standart sozlamalar, bitta root yoki postgres foydalanuvchisi, barcha tarmoq interfeyslarida tinglash.

Bu maqolada bazani himoyalashning asosiy qatlamlarini ko'rib chiqamiz: tarmoq, foydalanuvchilar va huquqlar, shifrlangan ulanish, maxfiy maydonlarni shifrlash, zaxira va audit. Misollar PostgreSQL va MySQL/MariaDB uchun, ilova tomoni esa Laravel va Node misolida.

Muammo nimada

Bazalarda eng ko'p uchraydigan xatolar:

  • Port internetga ochiq. MySQL (3306), PostgreSQL (5432), Redis (6379), MongoDB (27017) tashqaridan ko'rinadi. Bu parol tanlash hujumlari va baza dasturidagi zaifliklar uchun to'g'ridan-to'g'ri yo'l.
  • Ilova superuser bilan ulanadi. root yoki postgres foydalanuvchisi ilovada ishlatilsa, ilovadagi bitta SQL injection butun serverni boshqarish imkonini berishi mumkin: boshqa bazalar, fayl o'qish, buyruq bajarish.
  • Kuchsiz yoki takrorlangan parollar. Bir xil parol bir nechta muhitda, .env fayli git tarixida qolgan.
  • Shifrlanmagan ulanish. Ilova va baza turli serverlarda bo'lsa, so'rovlar va natijalar tarmoqda ochiq matnda yuradi.
  • Maxfiy maydonlar ochiq saqlanadi. Pasport ma'lumotlari, JSHSHIR, tokenlar oddiy matn ko'rinishida. Bazaning har qanday nusxasi — to'liq oqish.
  • Ma'lumotlar bazasining veb-interfeysi ochiq. phpMyAdmin, Adminer kabi vositalar ommaviy manzilda turadi.

Nega bu ekspertiza uchun muhim

Ekspertizada server tashqaridan portlar bo'yicha skanerlanadi — ochiq baza porti darhol topiladi. O'z mahsulotimiz ekspertizasida ham ochiq portlar alohida topilma bo'lgan (u yerda FTP va panel portlari edi), batafsil: ochiq portlar va server hardening. Bundan tashqari:

  • /phpmyadmin, /adminer.php, /pma kabi manzillar odatiy nomlar bo'yicha tekshiriladi;
  • SQL injection topilsa, uning ta'siri bazadagi foydalanuvchi huquqlariga bog'liq — minimal huquq zararni cheklaydi;
  • OWASP Top 10 (2021) dagi A02 "Cryptographic Failures" maxfiy ma'lumotlarni saqlash va uzatishda shifrlash yo'qligini qamrab oladi, A05 "Security Misconfiguration" esa standart sozlamalarni.

Printsip: baza faqat ilovaga ko'rinsin, ilova faqat kerakli narsani qila olsin, maxfiy ma'lumot esa bazadan sizib chiqsa ham o'qib bo'lmaydigan bo'lsin.

O'zingiz tekshiring

Baza qayerda tinglayapti

Server ichida:

sudo ss -tlnp | grep -E "3306|5432|6379|27017"

127.0.0.1 yoki Unix soket — yaxshi. 0.0.0.0 yoki * — firewall yo'q bo'lsa, baza tashqaridan ochiq.

Tashqaridan (boshqa kompyuterdan, faqat o'z serveringizga):

nmap -Pn -p 3306,5432,6379,27017 your-server-ip

Foydalanuvchilar va huquqlar

PostgreSQL:

SELECT rolname, rolsuper, rolcreaterole, rolcreatedb FROM pg_roles WHERE rolcanlogin;

MySQL:

SELECT user, host FROM mysql.user;
SHOW GRANTS FOR 'app'@'localhost';

Ilova foydalanuvchisida SUPER, FILE, GRANT OPTION yoki ALL PRIVILEGES ON *.* bo'lmasligi kerak. host ustunida % bo'lsa — foydalanuvchi istalgan manzildan ulana oladi.

Veb-interfeyslar

for p in phpmyadmin pma adminer.php adminer phpMyAdmin; do
  printf "%s " "$p"; curl -s -o /dev/null -w "%{http_code}\n" "https://example.uz/$p/"
done

Tuzatish

1. Bazani faqat lokal manzilga bog'lang

PostgreSQL postgresql.conf:

listen_addresses = 'localhost'

MySQL/MariaDB mysqld.cnf:

[mysqld]
bind-address = 127.0.0.1

Redis redis.conf: bind 127.0.0.1 ::1 va protected-mode yes, shuningdek parol yoki ACL.

Agar baza alohida serverda bo'lsa, u faqat ichki tarmoqda tinglasin va firewall faqat ilova serverining IP manziliga ruxsat bersin:

sudo ufw allow from 10.0.0.5 to any port 5432 proto tcp

PostgreSQL'da pg_hba.conf ham shu printsip bo'yicha:

# TYPE  DATABASE  USER  ADDRESS        METHOD
local   appdb     app                  scram-sha-256
hostssl appdb     app   10.0.0.5/32    scram-sha-256

trust usulidan foydalanmang, parol xeshlash uchun scram-sha-256 ni tanlang (password_encryption = scram-sha-256).

2. Minimal huquqli foydalanuvchilar

Kamida uchta rol ajrating: migratsiya (sxema o'zgartiradi), ilova (faqat ma'lumot bilan ishlaydi) va zaxira yoki hisobot (faqat o'qiydi).

PostgreSQL:

CREATE ROLE app LOGIN PASSWORD '...';
REVOKE ALL ON SCHEMA public FROM PUBLIC;
GRANT USAGE ON SCHEMA public TO app;
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO app;
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO app;
ALTER DEFAULT PRIVILEGES FOR ROLE migrator IN SCHEMA public
  GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO app;

MySQL:

CREATE USER 'app'@'localhost' IDENTIFIED BY '...';
GRANT SELECT, INSERT, UPDATE, DELETE ON appdb.* TO 'app'@'localhost';
CREATE USER 'report'@'localhost' IDENTIFIED BY '...';
GRANT SELECT ON appdb.* TO 'report'@'localhost';

Parollarni openssl rand -base64 24 bilan yarating va faqat .env yoki sirlar menejerida saqlang. Har bir muhit (test, production) uchun alohida parol. Batafsil: sirlar va kalitlarni boshqarish.

3. Shifrlangan ulanish (TLS)

Baza va ilova bitta serverda bo'lib, ulanish Unix soket yoki 127.0.0.1 orqali bo'lsa, TLS shart emas. Turli serverlarda bo'lsa — majburiy.

PostgreSQL serverida ssl = on va sertifikat sozlanadi, pg_hba.conf da hostssl ishlatiladi. Laravel config/database.php:

'pgsql' => [
    // ...
    'sslmode' => env('DB_SSLMODE', 'verify-full'),
],

MySQL uchun foydalanuvchini faqat TLS bilan ulanishga majburlash mumkin:

ALTER USER 'app'@'10.0.0.5' REQUIRE SSL;

Node.js (pg) misolida:

const pool = new Pool({
  connectionString: process.env.DATABASE_URL,
  ssl: { ca: fs.readFileSync('/etc/ssl/db-ca.pem'), rejectUnauthorized: true },
});

rejectUnauthorized: false — sertifikat tekshirilmaydi, bu esa TLS ma'nosini yo'qqa chiqaradi.

4. Maxfiy maydonlarni shifrlash

Disk shifrlash server o'g'irlansa himoya qiladi, lekin baza dumpi yoki SQL injection orqali olingan ma'lumotni himoya qilmaydi. Eng maxfiy maydonlar uchun ilova darajasida shifrlash qo'shing.

Laravel'da encrypted cast:

protected function casts(): array
{
    return [
        'passport_number' => 'encrypted',
        'api_secret' => 'encrypted',
    ];
}

Shifrlangan maydon bo'yicha qidirish kerak bo'lsa, alohida ustunda kalitli xesh (HMAC) saqlang va qidiruvni shu ustun bo'yicha bajaring. Parollar esa shifrlanmaydi, balki bcrypt yoki argon2id bilan xeshlanadi.

Muhim: shifrlash kaliti (APP_KEY) bazadan alohida saqlanadi. Kalit va baza bir joyda sizib chiqsa, shifrlash himoya qilmaydi. Kalitni almashtirish rejasi ham oldindan o'ylab qo'yilishi kerak.

5. Veb-interfeyslarni yoping

phpMyAdmin yoki Adminer kerak bo'lsa, ularni ommaviy manzilda qoldirmang: faqat SSH tunnel yoki allowlist orqali. Eng yaxshisi — ishlab chiqarish serverida ularni umuman o'rnatmaslik va kerak bo'lganda SSH tunnel orqali lokal mijoz bilan ulanish:

ssh -L 5432:127.0.0.1:5432 user@your-server

6. Zaxira va audit

Baza zaxirasi shifrlangan va boshqa joyda saqlanishi, tiklash muntazam sinab ko'rilishi kerak — bu haqda zaxira nusxa va tiklash maqolasida batafsil.

Audit uchun:

  • PostgreSQL'da log_connections = on, log_disconnections = on, sxema o'zgarishlari uchun log_statement = 'ddl'; batafsil audit uchun pgaudit kengaytmasi;
  • MySQL'da muvaffaqiyatsiz ulanishlarni loglash, Percona yoki MariaDB'da audit plagini;
  • ilova darajasida — kim qaysi maxfiy yozuvni ko'rgani yoki o'zgartirgani (audit jadvali).

Barcha so'rovlarni loglash (log_statement = 'all') ko'p joy egallaydi va loglarga maxfiy ma'lumot tushishiga olib keladi — buni faqat vaqtinchalik diagnostika uchun yoqing.

7. Yangilanishlar

Baza dasturi ham yangilanishi kerak. Qo'llab-quvvatlash muddati tugagan versiyalar xavfsizlik tuzatishlarini olmaydi. Versiyani tekshiring (SELECT version();) va ishlab chiquvchining qo'llab-quvvatlash jadvali bilan solishtiring.

Ilova tomonida

Baza sozlamalari ilovadagi xatoni to'liq yopa olmaydi. Asosiy qoidalar:

  • faqat parametrlangan so'rovlar, whereRaw va xom SQL'da qiymatlarni satrga qo'shmaslik;
  • orderBy va ustun nomlari uchun allowlist;
  • xato xabarlarida SQL so'rovi va baza tafsilotlarini ko'rsatmaslik (APP_DEBUG=false);
  • ulanish satrini front-end yoki mobil ilovaga hech qachon qo'ymaslik.

Qisqa checklist

  • Baza portlari internetdan yopiq, baza 127.0.0.1 yoki ichki tarmoqda tinglaydi
  • pg_hba.conf / MySQL host faqat kerakli manzillarga ruxsat beradi, trust yo'q
  • Ilova superuser bilan emas, minimal huquqli foydalanuvchi bilan ulanadi
  • Migratsiya, ilova va hisobot uchun alohida rollar
  • Kuchli, har bir muhit uchun alohida parollar; .env git'da yo'q
  • Turli serverlar orasida TLS va sertifikat tekshiruvi
  • Eng maxfiy maydonlar ilova darajasida shifrlangan, kalit alohida
  • phpMyAdmin/Adminer ommaviy manzilda yo'q
  • Shifrlangan zaxira va tiklash testi
  • Ulanishlar va sxema o'zgarishlari loglanadi, baza versiyasi qo'llab-quvvatlanadi

Xulosa

Bazani himoyalash bir nechta oddiy qatlamdan iborat: tarmoqdan yashirish, huquqlarni cheklash, ulanishni va maxfiy maydonlarni shifrlash, nusxa olish va kuzatish. Har bir qatlam boshqasi ishlamay qolganda zararni cheklaydi. Bizning jarayonda Claude AI agenti baza konfiguratsiyasi, pg_hba.conf, foydalanuvchi huquqlari va ilova kodidagi so'rovlarni ko'rib chiqadi, mutaxassis esa o'zgarishlarni ishlab turgan tizimni to'xtatmasdan, xavfsiz tartibda qo'llaydi.

Bazangiz ekspertizaga tayyorligini bilmoqchi bo'lsangiz, skanerlash uchun ariza qoldiring. Rasmiy tekshiruvdan oldin teshiklarni yopishga yordam beramiz.