MariaDB ve MySQL’de Kullanıcı Yetkilerini Sorgulamak için SHOW GRANTS

Veritabanı yönetiminde en çok gözden kaçan konulardan biri kullanıcı yetkilerinin düzenli olarak sorgulanmasıdır. Bir sistemi kurarken verilen yetkiler zamanla birikir, eski kullanıcılar sistemde kalır, test amaçlı verilen geniş yetkiler production ortamında unutulur. İşte bu yüzden SHOW GRANTS komutu bir DBA’in ya da sysadmin’in en yakın arkadaşlarından biri olmalıdır. Bu yazıda MariaDB ve MySQL üzerinde kullanıcı yetkilerini sorgulamanın tüm yöntemlerini, gerçek dünya senaryolarıyla birlikte ele alacağız.

SHOW GRANTS Nedir ve Neden Önemlidir?

SHOW GRANTS, bir kullanıcıya verilmiş tüm yetkileri GRANT ifadeleri biçiminde listeleyen bir SQL komutudur. Çıktısı doğrudan çalıştırılabilir SQL formatında olduğundan yetki yedekleme ve taşıma işlemlerinde de son derece kullanışlıdır.

Günlük yönetim sürecinde bu komuta ihtiyaç duyduğunuz birkaç tipik durum şunlardır:

  • Bir uygulama veritabanına bağlanamıyor ve hangi yetkinin eksik olduğunu anlamaya çalışıyorsunuz
  • Güvenlik denetimi için hangi kullanıcının hangi veritabanlarına erişebildiğini raporlamanız gerekiyor
  • Yeni bir ortama kullanıcı yetkilerini taşıyacaksınız
  • Bir kullanıcının fazla yetkiye sahip olup olmadığını kontrol etmek istiyorsunuz
  • Ekip arkadaşınızın oluşturduğu kullanıcının tam olarak ne yapabildiğini anlamak istiyorsunuz

Temel Kullanım

En basit haliyle SHOW GRANTS komutu, o an oturum açmış olan kullanıcının yetkilerini gösterir.

mysql -u root -p

-- Oturum açmış kullanıcının yetkilerini göster
SHOW GRANTS;

-- Ya da açıkça belirtmek istiyorsanız
SHOW GRANTS FOR CURRENT_USER;
SHOW GRANTS FOR CURRENT_USER();

Belirli bir kullanıcının yetkilerini sorgulamak için kullanıcı adı ve host bilgisini belirtmeniz gerekir. MySQL ve MariaDB’de bir kullanıcı kimliği kullanici@host formatında tanımlanır. Bu ayrımı atlamak en yaygın hatalardan biridir.

-- Belirli bir kullanıcının yetkilerini göster
SHOW GRANTS FOR 'webapp'@'localhost';

-- Farklı host üzerinden bağlanan aynı kullanıcı
SHOW GRANTS FOR 'webapp'@'192.168.1.100';

-- Wildcard host kullanan kullanıcı
SHOW GRANTS FOR 'readonly_user'@'%';

Burada dikkat edilmesi gereken nokta şudur: 'webapp'@'localhost' ile 'webapp'@'%' MySQL açısından tamamen farklı iki kullanıcıdır. Birinin yetkilerini sorgulamak diğerininkini göstermez.

Mevcut Kullanıcıları Listelemek

SHOW GRANTS kullanmadan önce hangi kullanıcıların sistemde tanımlı olduğunu bilmeniz gerekir. Bunun için mysql.user tablosunu sorgulamanız gerekiyor.

-- Tüm kullanıcı ve host kombinasyonlarını listele
SELECT User, Host FROM mysql.user ORDER BY User, Host;

-- Daha detaylı bilgi için
SELECT User, Host, authentication_string != '' AS has_password,
       account_locked, password_expired
FROM mysql.user
ORDER BY User, Host;

Bu sorgu size sistemdeki tüm kullanıcı@host kombinasyonlarını listeler. Artık hangi kullanıcı için SHOW GRANTS çalıştıracağınızı biliyorsunuzdur.

SHOW GRANTS Çıktısını Anlamak

Bir örnek üzerinden gidelim. webapp adlı bir kullanıcı oluşturup yetkilerini sorgulayalım.

-- Örnek kullanıcı oluşturma ve yetki verme
CREATE USER 'webapp'@'localhost' IDENTIFIED BY 'guclu_sifre_123';
GRANT SELECT, INSERT, UPDATE, DELETE ON production_db.* TO 'webapp'@'localhost';
GRANT SELECT ON reporting_db.* TO 'webapp'@'localhost';

-- Şimdi yetkileri sorgulayalım
SHOW GRANTS FOR 'webapp'@'localhost';

Çıktı şuna benzer görünür:

+------------------------------------------------------------------------------------+
| Grants for webapp@localhost                                                         |
+------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO `webapp`@`localhost`                                         |
| GRANT SELECT, INSERT, UPDATE, DELETE ON `production_db`.* TO `webapp`@`localhost`  |
| GRANT SELECT ON `reporting_db`.* TO `webapp`@`localhost`                           |
+------------------------------------------------------------------------------------+

Bu çıktıyı satır satır inceleyelim:

  • GRANT USAGE ON .: Bu satır kullanıcının var olduğunu gösterir. USAGE aslında “hiçbir şey yok” anlamına gelir. Her kullanıcıda bu satır mutlaka bulunur.
  • GRANT SELECT, INSERT, UPDATE, DELETE ON production_db.*: Kullanıcının production_db veritabanındaki tüm tablolarda bu dört işlemi yapabileceğini gösterir.
  • GRANT SELECT ON reporting_db.*: reporting_db veritabanında sadece okuma yetkisi var.

Tablo ve Kolon Bazlı Yetkileri Görmek

Bazen yetkiler çok daha ince granülariteye sahip olabilir. Belirli tablolara ya da kolonlara özel yetkiler verilmiş olabilir.

-- Tablo bazlı yetki örneği
GRANT SELECT, UPDATE ON production_db.orders TO 'webapp'@'localhost';
GRANT DELETE ON production_db.temp_data TO 'webapp'@'localhost';

-- Kolon bazlı yetki örneği
GRANT SELECT (id, username, email) ON production_db.users TO 'readonly_app'@'localhost';
GRANT UPDATE (last_login) ON production_db.users TO 'readonly_app'@'localhost';

-- Yetkileri sorgula
SHOW GRANTS FOR 'readonly_app'@'localhost';

Çıktıda kolon bazlı yetkileri görebilirsiniz:

| GRANT SELECT (id, username, email), UPDATE (last_login) ON `production_db`.`users` TO `readonly_app`@`localhost` |

Bu seviyedeki yetki kontrolü özellikle kişisel veri içeren tablolarda GDPR ve KVKK uyumu açısından kritik önem taşır.

Stored Procedure ve Function Yetkileri

Veritabanı nesneleri sadece tablolardan ibaret değildir. Stored procedure ve function’lar için de yetkiler ayrı yönetilir.

-- Prosedür yetkisi verme
GRANT EXECUTE ON PROCEDURE production_db.calculate_discount TO 'webapp'@'localhost';
GRANT EXECUTE ON FUNCTION production_db.get_tax_rate TO 'webapp'@'localhost';

-- Bu yetkileri görmek için
SHOW GRANTS FOR 'webapp'@'localhost';

Bir kullanıcının tüm routine’ler üzerindeki yetkisini vermek isterseniz:

GRANT EXECUTE ON production_db.* TO 'storedproc_user'@'localhost';
SHOW GRANTS FOR 'storedproc_user'@'localhost';

Gerçek Dünya Senaryosu 1: Güvenlik Denetimi Yapma

Diyelim ki şirketinizde bir güvenlik denetimi yapacaksınız ve hangi kullanıcının hangi veritabanlarına erişebildiğini raporlamanız gerekiyor. Manuel olarak her kullanıcı için SHOW GRANTS çalıştırmak yerine bunu otomatize edebilirsiniz.

#!/bin/bash
# tum_kullanici_yetkileri.sh
# Sistemdeki tüm kullanıcıların yetkilerini dosyaya yazar

DB_USER="root"
DB_PASS="root_sifreniz"
OUTPUT_FILE="/tmp/yetki_raporu_$(date +%Y%m%d_%H%M%S).sql"

echo "-- Yetki Raporu: $(date)" > "$OUTPUT_FILE"
echo "-- Sunucu: $(hostname)" >> "$OUTPUT_FILE"
echo "" >> "$OUTPUT_FILE"

# Tüm kullanıcı@host kombinasyonlarını al
mysql -u"$DB_USER" -p"$DB_PASS" -N -e 
  "SELECT CONCAT(User, '@', Host) FROM mysql.user WHERE User != ''" 2>/dev/null | 
while read user_host; do
    echo "-- Kullanici: $user_host" >> "$OUTPUT_FILE"
    mysql -u"$DB_USER" -p"$DB_PASS" -N -e 
      "SHOW GRANTS FOR $user_host;" 2>/dev/null >> "$OUTPUT_FILE"
    echo "" >> "$OUTPUT_FILE"
done

echo "Rapor olusturuldu: $OUTPUT_FILE"
cat "$OUTPUT_FILE"

Bu script çalıştırıldığında tüm kullanıcıların yetkilerini tek bir dosyada toplar. Güvenlik ekibine bu dosyayı iletebilir ya da periyodik olarak arşivleyebilirsiniz.

Gerçek Dünya Senaryosu 2: Yetki Sorunlarını Gidermek

Sık karşılaştığım bir durum: Geliştirici “veritabanına bağlanamıyorum” diyor. Hata mesajı Access denied for user 'app_user'@'192.168.1.55' şeklinde. İşte bu durumda yapmanız gerekenler:

-- Önce kullanıcının var olup olmadığını kontrol et
SELECT User, Host FROM mysql.user WHERE User = 'app_user';

-- Sonuç şöyle olabilir:
-- app_user | localhost
-- app_user | 192.168.1.%

-- Kullanıcı 192.168.1.% maskesiyle tanımlı, 192.168.1.55 bu maskeye giriyor
-- Ama bağlantı yine de başarısız oluyorsa yetkileri kontrol et
SHOW GRANTS FOR 'app_user'@'192.168.1.%';

-- Eğer kullanıcı hiç tanımlı değilse
-- 'app_user'@'192.168.1.55' için arama yap
SELECT User, Host FROM mysql.user
WHERE User = 'app_user' AND '192.168.1.55' LIKE Host;

Bu sorgular size sorunun tam olarak nerede olduğunu gösterecektir. Kullanıcı hiç tanımlı değil mi, yanlış host ile mi tanımlı, yoksa tanımlı ama gerekli yetkiler verilmemiş mi, bunları net olarak görebilirsiniz.

information_schema ile Daha Gelişmiş Sorgular

SHOW GRANTS komutu kullanışlıdır ama bazen information_schema üzerinden daha esnek sorgular yazmanız gerekebilir.

-- Belirli bir veritabanına erişimi olan tüm kullanıcıları bul
SELECT GRANTEE, PRIVILEGE_TYPE, IS_GRANTABLE
FROM information_schema.SCHEMA_PRIVILEGES
WHERE TABLE_SCHEMA = 'production_db'
ORDER BY GRANTEE, PRIVILEGE_TYPE;

-- Tüm kullanıcıların global yetkilerini listele
SELECT GRANTEE, PRIVILEGE_TYPE, IS_GRANTABLE
FROM information_schema.USER_PRIVILEGES
ORDER BY GRANTEE;

-- Belirli bir tabloya erişimi olan kullanıcılar
SELECT GRANTEE, TABLE_SCHEMA, TABLE_NAME, PRIVILEGE_TYPE
FROM information_schema.TABLE_PRIVILEGES
WHERE TABLE_SCHEMA = 'production_db'
AND TABLE_NAME = 'users'
ORDER BY GRANTEE;

-- SUPER yetkisine sahip kullanıcıları bul (tehlikeli!)
SELECT GRANTEE
FROM information_schema.USER_PRIVILEGES
WHERE PRIVILEGE_TYPE = 'SUPER';

information_schema üzerinden yapılan sorgular özellikle raporlama ve izleme sistemlerine entegre etmek istediğinizde çok daha esnektir.

MariaDB’ye Özgü Özellikler

MariaDB 10.x sürümlerinde rol tabanlı yetki yönetimi (role-based access control) desteklenmektedir. Bu durumda yetkileri sorgulamak biraz farklılaşır.

-- MariaDB'de rol oluşturma
CREATE ROLE 'app_readonly';
CREATE ROLE 'app_readwrite';

-- Rollere yetki verme
GRANT SELECT ON production_db.* TO 'app_readonly';
GRANT SELECT, INSERT, UPDATE, DELETE ON production_db.* TO 'app_readwrite';

-- Kullanıcılara rol atama
GRANT 'app_readwrite' TO 'webapp'@'localhost';
GRANT 'app_readonly' TO 'report_user'@'localhost';

-- Rollerle birlikte yetkileri görmek
SHOW GRANTS FOR 'webapp'@'localhost';

-- Rolün kendisinin yetkilerini görmek
SHOW GRANTS FOR 'app_readwrite';

MariaDB 10.4 ve sonrasında SHOW GRANTS çıktısında roller de görünür. Kullanıcının doğrudan aldığı yetkiler ile rol üzerinden gelen yetkileri birbirinden ayırt etmek önemlidir.

Gerçek Dünya Senaryosu 3: Yetki Taşıma ve Yedekleme

Bir sunucudan diğerine kullanıcı ve yetkileri taşımak istiyorsunuz. mysqldump kullanıcı yetkilerini her zaman düzgün taşımayabilir. Manuel yöntem daha güvenilirdir.

#!/bin/bash
# yetki_yedekle.sh
# Tüm kullanıcı yetkilerini yedekler, hedef sunucuda çalıştırılabilir

MYSQL_CMD="mysql -u root -p'sifreniz'"
BACKUP_FILE="grants_backup_$(hostname)_$(date +%Y%m%d).sql"

echo "-- Grant Backup: $(date)" > "$BACKUP_FILE"
echo "-- Source Host: $(hostname)" >> "$BACKUP_FILE"
echo "" >> "$BACKUP_FILE"

# Kullanıcıları al ve her biri için SHOW GRANTS çalıştır
mysql -u root -p'sifreniz' -N 2>/dev/null <<'EOF' | 
SELECT CONCAT("'",User,"'@'",Host,"'")
FROM mysql.user
WHERE User NOT IN ('root','mysql.sys','mysql.session','mariadb.sys')
EOF
while read user; do
    echo "-- === $user ===" >> "$BACKUP_FILE"
    mysql -u root -p'sifreniz' -N -e "SHOW CREATE USER $user;" 2>/dev/null 
        | sed 's/$/;/' >> "$BACKUP_FILE"
    mysql -u root -p'sifreniz' -N -e "SHOW GRANTS FOR $user;" 2>/dev/null 
        | sed 's/$/;/' >> "$BACKUP_FILE"
    echo "" >> "$BACKUP_FILE"
done

echo "Yedek alindi: $BACKUP_FILE"

Bu yedek dosyasını hedef sunucuda mysql -u root -p < grants_backup.sql komutuyla çalıştırabilirsiniz.

SHOW GRANTS ile Güvenlik Açıklarını Tespit Etme

Production ortamlarında sıkça gördüğüm tehlikeli yetki konfigürasyonları şunlardır:

-- Tehlikeli durum 1: Global ALL PRIVILEGES
SHOW GRANTS FOR 'app_user'@'localhost';
-- Çıktıda şunu görürseniz dikkat:
-- GRANT ALL PRIVILEGES ON *.* TO 'app_user'@'localhost'

-- Tehlikeli durum 2: WITH GRANT OPTION
-- Kullanıcı başkalarına da yetki verebilir
SHOW GRANTS FOR 'developer'@'%';
-- Çıktıda şunu görürseniz dikkat:
-- GRANT SELECT, INSERT ON production_db.* TO 'developer'@'%' WITH GRANT OPTION

-- Tehlikeli durum 3: FILE yetkisi (sunucu dosyalarını okuyabilir)
SELECT GRANTEE FROM information_schema.USER_PRIVILEGES
WHERE PRIVILEGE_TYPE = 'FILE';

-- Tehlikeli durum 4: PROCESS yetkisi (tüm sorguları görebilir)
SELECT GRANTEE FROM information_schema.USER_PRIVILEGES
WHERE PRIVILEGE_TYPE = 'PROCESS';

-- Tehlikeli durum 5: Wildcard host ile root benzeri kullanıcılar
SELECT User, Host FROM mysql.user
WHERE Host = '%'
AND (Select_priv = 'Y' OR Insert_priv = 'Y')
AND User != '';

Bu sorguların sonuçlarını düzenli olarak gözden geçirmek, güvenlik açıklarını erkenden tespit etmenizi sağlar.

Yetki Değişikliklerini İzlemek

Üretim ortamında yetki değişikliklerinin kim tarafından ne zaman yapıldığını takip etmek istiyorsanız MariaDB/MySQL’in genel log ya da audit log özelliğini aktif etmelisiniz. Ancak anlık durumu kontrol etmek için şu yaklaşım işe yarar:

-- Mevcut yetki durumunu kaydet ve periyodik olarak karşılaştır
-- Önce mevcut durumu kaydet
mysql -u root -p -N -e "
SELECT CONCAT(GRANTEE, '|', PRIVILEGE_TYPE, '|', IS_GRANTABLE)
FROM information_schema.USER_PRIVILEGES
UNION ALL
SELECT CONCAT(GRANTEE, '|', TABLE_SCHEMA, '|', PRIVILEGE_TYPE)
FROM information_schema.SCHEMA_PRIVILEGES
ORDER BY 1;
" > /var/log/mysql_grants_$(date +%Y%m%d).txt

-- Bir sonraki kontrolde farkları karşılaştır
diff /var/log/mysql_grants_onceki.txt /var/log/mysql_grants_simdi.txt

Bu yöntemi bir cron job ile haftada bir ya da günde bir çalıştırarak yetki değişikliklerini takip edebilirsiniz.

Sık Yapılan Hatalar

Yanlış host belirtmek: En yaygın hata, kullanıcıyı 'user'@'%' olarak oluştururken SHOW GRANTS FOR 'user'@'localhost' çalıştırmaktır. Çıktı ya “no such grant” hatası verir ya da sadece USAGE gösterir.

FLUSH PRIVILEGES sonrası kontrol: Yetki verdikten ya da kaldırdıktan sonra SHOW GRANTS her zaman güncel durumu gösterir. Ancak bazı eski alışkanlıklar nedeniyle FLUSH PRIVILEGES çalıştırılmadan değişikliklerin yansımayacağı düşünülür. Modern MariaDB ve MySQL sürümlerinde GRANT/REVOKE komutları direkt olarak etkili olur, FLUSH PRIVILEGES gerekmez.

information_schema görünümlerinin cache’li olması: information_schema.USER_PRIVILEGES ve benzeri görünümler anlık durumu yansıtır. Ama SHOW GRANTS çıktısıyla zaman zaman ufak farklılıklar gözükebilir, özellikle rol tabanlı sistemlerde.

Pratik Kontrol Listesi

Yetki yönetimi için kendinize periyodik bir kontrol rutini oluşturun:

  • Her ay: Sistemdeki tüm kullanıcıları listeleyin, kullanılmayan hesapları tespit edin
  • Her ay: WITH GRANT OPTION kullanan kullanıcıları kontrol edin
  • Her üç ayda bir: SUPER, FILE, PROCESS gibi güçlü yetkilere sahip kullanıcıları gözden geçirin
  • Her altı ayda bir: Tüm kullanıcı yetkilerinin yedeğini alın ve arşivleyin
  • Herhangi bir personel değişikliğinde: Ayrılan kişilerin kullanıcı hesaplarını devre dışı bırakın ya da silin
  • Her yeni uygulama kurulumunda: Minimum yetki prensibini uygulayın, uygulamaya sadece ihtiyacı olan yetkileri verin

Sonuç

SHOW GRANTS komutu basit görünse de veritabanı güvenliğinin temel taşlarından birini oluşturur. Düzenli yetki sorgulamaları yapmak, hem güvenlik açıklarını kapatmanıza hem de sorun gidermede hız kazanmanıza yardımcı olur.

Bu yazıda anlattıklarımı özetlersek: Temel SHOW GRANTS kullanımından başlayarak tablo ve kolon bazlı yetkilere, information_schema sorgularına, güvenlik denetimi script’lerine ve MariaDB’nin rol tabanlı sistemine kadar geniş bir yelpazede konuyu ele aldık.

En pratik tavsiyem şu: Hemen şimdi production veritabanınıza bağlanın ve her kullanıcının yetkilerini bir kez gözden geçirin. Büyük ihtimalle ya unutulmuş bir test kullanıcısı, ya da bir uygulamaya gereksiz yere verilmiş geniş yetkiler bulacaksınız. Bu tür küçük güvenlik iyileştirmeleri zamanla birikerek sisteminizin genel güvenlik duruşunu önemli ölçüde güçlendirir.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir