Sunucu Chroot Ayarları
İşletim Sistemi

Bir onceki makalede olduğu gibi, işletim sistemimiz FreeBSD 4.7. Ancak belirtilen metotlar gelişmiş Unix ve Unix_benzeri sistemlerde de uygulanabilir.

Chroot Alanı Hazırlama
Chroot alanı hazırlamak icin, aşağıdaki dizin yapısını oluşturmamız gerekiyor:
mkdir -p /chroot/mysql/dev
mkdir -p /chroot/mysql/etc
mkdir -p /chroot/mysql/tmp
mkdir -p /chroot/mysql/var/tmp
mkdir -p /chroot/mysql/usr/local/mysql/libexec
mkdir -p /chroot/mysql/usr/local/mysql/share/mysql/english

Erişim Haklarının Ayarlanması Yukarıda belirtilen dizinlere erişim hakları, aşağıdaki şekilde ayarlanmalıdır:
chown -R root:sys /chroot/mysql
chmod -R 755 /chroot/mysql
chmod 1777 /chroot/mysql/tmp

Dizin Yapısı Oluşturmak
Sonrasında ise, aşağıdaki dosyalar yeni dizin yapısıne kopyalanmalıdır:
cp /usr/local/mysql/libexec/mysqld /chroot/mysql/usr/local/mysql/libexec/
cp /usr/local/mysql/share/mysql/english/errmsg.sys /chroot/mysql/usr/local/mysql/share/mysql/english/
cp /etc/hosts /chroot/mysql/etc/
cp /etc/host.conf /chroot/mysql/etc/
cp /etc/resolv.conf /chroot/mysql/etc/
cp /etc/group /chroot/mysql/etc/
cp /etc/master.passwd /chroot/mysql/etc/passwords
cp /etc/my.cnf /chroot/mysql/etc/

Şifreleri ve Grupları Guclendirmek
Mysql hesabı ve grubu haric, /chroot/mysql/etc/passwords ve /chroot/mysql/etc/group dosyalarından tum satırları kaldırmalıyız. Sonra, aşağıda belirtildiği şekilde şifre veritabanı oluşturmalıyız (Bu sadece FreeBSD sistemlerde uygulanır):
cd /chroot/mysql/etc
pwd_mkdb -d /chroot/mysql/etc passwords
rm -rf /chroot/mysql/etc/master.passwd

Ozel Hususlar
Apache web sunucu kullanımı halinde, ozel bir aygıt dosyası yaratmalıyız /dev/lisanssız:
ls -al /dev/lisanssız
crw-rw-rw- 1 root sys 2, 2 Jun 21 18:31 /dev/lisanssız
mknod /chroot/mysql/dev/lisanssız c 2 2
chown root:sys /chroot/mysql/dev/lisanssız
chmod 666 /chroot/mysql/dev/lisanssız

Ayrıca, MySQL kurulumunda oluşturulmuş grant tablolar iceren mysql veritabanını da kopyalamalıyız:
cp -R /usr/local/mysql/var/ /chroot/mysql/usr/local/mysql/var
chown -R mysql:mysql /chroot/mysql/usr/local/mysql/var

Sabitleme
Eğer ingilizce haricinde başka bir dil kullanılacaksa, ayrıca /usr/local/mysql/share/mysql/charsets dizininden ilgili charset'leri de kopyalamalıyız.

Konfigurasyonun Testi
Bu noktada MySQL Chroot edilmiş alanda calışmaya hazırdır. Eğer doğru calışıyorsa aşağıdaki komutlarla test yapabiliriz:
chrootuid /chroot/mysql mysql /usr/local/mysql/libexec/mysqld &
Eğer herhangi bir hata oluşursa truss komutunu ya da ktrace/kdump, strace gibi alternatiflerini kullanmalıyız. Bu sorunların sebeplerini tespit ve elimine atmak icin bize yardımcı olacaktır.

Not olarak, mysqld işlemini calıştırmak icin, Apache ya da PHP kullanımlarında chrootuid programı chroot yerine kullanılabilir. Ana farklılık ise, chrootuid'in, uygulanan işlemin sahibini değiştirmesidir.

Sunucu Konfigurasyonu
Sonraki adım ise veritabanı sunucusunu, bizim guvenlik gerekliliklerimizi tamamlayacak şekilde konfigure etmektir.
MySQL'in default kurulumu halinde, ana konfigurasyon dosyası" /etc/my.cnf" dır. Bizim durumumuzda, her ne kadar chroot edilmiş ortamda calışan sunucu olsa da, biz 2 konfigurasyon dosyası kullanacağız: /chroot/mysql/etc/my.cnf ve /etc/my.cnf.

İlk dosya sadece MySQL sunucu tarafından kullanılacaktır, sonraki ise MySQL aracları tarafından "mysqladmin, mysql, mysqldump vb"Her iki durumda da bazı konfigurasyon değişiklikleri gerekebilir.

Uzaktan Erişimin Kapatılması
İlk değişiklik, MySQL'in default olarak dinlemede olduğu 3306/TCP portunda uygulanır. Cunku, ilk ayarlamalara gore veritabanı sadece lokal olarak kurulmuş PHP uygulaması tarafından kullanılacaktır, rahatlıkla bu port uzerinden dinlemeyi kapatabiliriz.

Bu, diğer hostlardan direkt olarak TCP/IP protokolu uzerinden MySQL'e yapılacak saldırı ihtimallerini kısıtlayacaktır. Lokal bağlantı ise mysql.sock soket uzerinden calışmaya devam edecektir. Bahse konu port uzerinde dinlemeyi kapatmak icin, aşağıdaki parametrelerin /chroot/mysql/etc/my.cnf dizininin mysqld bolumune eklenmesi gerekmektedir:

skip-networking
Eğer bir sebeple veritabanına uzaktan erişim hala gerekiyorsa (orneğin veri yedeklemesi icin), SSH protokolu aşağıda belirtildiği şekilde kullanılabilir:
backuphost$ ssh mysqlserver /usr/local/mysql/bin/mysqldump -A > backup

Lokal Guvenliğin Geliştirilmesi
Sonraki değişiklik ise LOAD DATA LOCAL INFILE komutunun kullanıma kapatılmasıdır, ki bu da lokal dosyalar uzerindeki yetkisiz "'okuma"' hakkı elde edilmesini onlemek icindir.

Bu amacla, aşağıdaki parametrelerin /chroot/mysql/etc/my.cnf dizinininmysqld bolumune eklenmesi gerekir:
set-variable=local-infile=0

İlaveten, veritabanı yonetim araclarının kullanımı mumkun ise, /etc/my.cnf dizininin client bolumunde bulunan aşağıdaki parametreler değiştirilmelidir:
socket = /chroot/mysql/tmp/mysql.sock

Artık her zaman bu aracları calıştıracağımız zaman --socket=/chroot/mysql/tmp/mysql.sock komutu ile mysql, mysqladmin,mysqldump araclarını desteklememiz gerekmiyor.

Yonetici Şifresinin Değiştirilmesi
Bunu uygulayabilmek icin MySQL'i calıştırmamız gerekmektedir ( eğer o anda calışmıyorsa):
chrootuid /chroot/mysql mysql /usr/local/mysql/libexec/mysqld &
and change the administrator's password as follows:
/usr/local/mysql/bin/mysql -u root
mysql> SET PASSWORD FOR rootatlocalhost=PASSWORD('new_password');

Bu, komut satırından şifre değiştirilmemesi icin, orneğin bir "mysqladmin password" kullanmadan, iyi bir uygulamadır. Uygunsuz erişim izinleri ayarlanmış olsa bile bu şekilde şifre, orneğin "ps aux" komutu kullanarak ya da history dosyalarına bakarak (~/.history, ~/.bash_history etc) kolaylıkla ortaya cıkmayacaktır.

Default Kullanıcı/Veritabanlarının Kaldırılması
Sonraki adımda ise, ornek veritabanını (test) ve lokal root hesabı haric diğer tum hesapları kaldırmalıyız:
mysql> drop database test;
mysql> use mysql;
mysql> delete from db;
mysql> delete from user where not (host="localhost" and user="root");
mysql> flush privileges;
Bu, veritabanına anonim bağlantılar sağlanmasını ve /chroot/mysql/etc/my.cnf dizinindeki skip-networking parametresine bakmaksızın uzak bağlantıları onleyecektir.

Yonetici Hesap İsminin Değiştirilmesi
Ayrıca default yonetici hesabı isminin de ( root), farklı ve tahmin edilmesi zor bir isim ile değiştirilmesi tavsiye edilmektedir.Bu tip bir değişiklik yonetici şifresine brute-force ve dictionary tabir edilen saldırıların yapılmasını oldukca zorlaştıracaktır. Bu durumda saldırgan sadece şifreyi değil, birincil ve mecburi olarak yonetici hesabı ismini de tahmin etmek zorundadır.
mysql> update user set user="mydbadmin" where user="root";
mysql> flush privileges;

History Dosyasının Kaldırılması
En son olarak, uygulanmış tum SQL komutlarının bulunduğu ( ozellikle basit text olarak tutulan şifreler) MySQL History (~/.mysql_history) dosyasının iceriğini de kaldırmamız gerekmektedir:
cat /dev/lisanssız > ~/.mysql_history

PHP ile MySQL Arasındaki Haberleşme
Bir diğer makalemizde ("Adım adım PHP Guvenliği"), programlardan biri chroot edilmiş alanda calıştırıldığında PHP ile MySQL arasındaki haberleşme sorunlarına dikkat cekmiştik.. Cunku lokal olarak PHP, /tmp/mysql.sock soketi aracılığı ile MySQL ile haberleşmektedir, PHP'nin chroot edilmiş alanda olması demek, birbirleri ile haberleşememeleri anlamına gelmektedir.
Bu sorunu cozmek icin, MySQL'i calıştırdığımız her zaman, PHP'nin chroot edilmiş alanına hard link oluşturmamız gerekmektedir:
ln /chroot/mysql/tmp/mysql.sock /chroot/httpd/tmp/
Not edilmelidir ki, /chroot/mysql/tmp/mysql.sock soketi ve /chroot/httpd/tmp dizini fiziksel olarak aynı dosya sisteminde bulunmalıdır. Aksi halde programların birbirleri ile haberleşmeleri mumkun olmayacaktır -- hard linkler dosya sistemleri arasında calışmaz.

Son Adımlar
Bu noktada spesifik PHP uygulaması tarafından kullanılacak olan tum veritabanlarını ve hesapları yaratmalıyız. Onemle vurgulamak gerekir ki bu hesaplar, sadece PHP uygulaması tarafından kullanılan veritabanına girmeye yetkili olmalıdır.
Farklı olarak bu hesaplar mysql veritabanına erişim iznine ya da herhangi bir sistem icin yonetici yetkisine sahip olmamalıdır, (FILE, GRANT, ALTER, SHOW DATABASE, RELOAD, SHUTDOWN, PROCESS, SUPER vb.).
Son olarak, işletim sistemi calıştığında MySQL'inde calışması icin ayrıca bir shell script'i yaratmalıyız. Ornek script aşağıda gosterilmektedir:
#!/bin/sh
CHROOT_MYSQL=/chroot/mysql
CHROOT_PHP=/chroot/httpd
SOCKET=/tmp/mysql.sock
MYSQLD=/usr/local/mysql/libexec/mysqld
PIDFILE=/usr/local/mysql/var/`hostname`.pid
CHROOTUID=/usr/local/sbin/chrootuid

echo -n "mysql"
case "$1" in
start)
rm -rf $/$
nohup $ $ mysql $ >/dev/lisanssız 2>&1
&
sleep 5 && ln $/$ $/$
;;
stop)
kill `cat $/$`
rm -rf $/$
;;
*)
echo ""
echo "Usage: `basename $0` " >&2
exit 64
;;
esac
exit 0
FreeBSD sistem kullanımı halinde, yukarıdaki script, mysql.sh ismi ile /usr/local/etc/rc.d dizini altında bulunmalıdır.
Sonuc
Veritabanını chroot edilmiş alanda calıştırmak, 3306/TCP port dinlemesini kapatmak ve kullanıcı hesaplarına guclu şifreler koymak, default kurulumda oluşması muhtemel bir cok saldırıya karşın veritabanını dokunulmaz hale getirmemize olanak sağlamaktadır.Bununla birlikte, hicbir metot %100 guvenlik elde etmemizi sağlamaz, vurgulanan metotlar, web sunucumuzu kotu niyetlerle ziyaret edenlerden gelebilecek saldırıları en aza indirgeyecektir.
alıntı:http://www.olympos.org/article/articleview/1852/1/12/mysql_guvenligi