Nginx Php Fpm Güvenlik Ayarları
Web sunucu olarak kullandığınız nginx, php-fpm bir sunucuda, bir web sitesinde meydana gelen güvenlik açıklarından diğer sitelerinde etkilenmemesini isteyebilirsiniz. Bu durumda Apache’de kullanılan suphp yada suexec benzeri bir yapıyı php-fpm’de de kullanabilirsiniz. Bu yapı Apache/PHP deki gibi php’yi suphp/suexec olarak derlemek yerine, php-fpm’de kullanıcıyı bir pool içine hapsederek, domain kullanıcısını kısıtlamış oluyorsunuz.
Centos 6.4 sistemde anlatacak olursak,
PHP-FPM servisinde default pool conf dosyası www.conf şeklinde geçiyor. Biz sitelerimiz için anımsatıcı bir conf dosyası kullanacağız.
#cd /etc/php-fpm.d/
#cp www.conf domain.conf
#vi domain.conf
domain.conf dosyasını php-fpm.conf içerisine ek olarak tanımlamamıza gerek yok. php-fpm.conf içerinde default olarak php-fpm.d içerisindeki dosyalar include edilmiştir.
domain.conf içeriğini aşağıdaki şekilde düzenliyoruz.
[domain.com]
listen = 127.0.0.1:9001
listen.allowed_clients = 127.0.0.1
user = gokhan
group = gokhan
pm = dynamic
pm.max_children = 9
pm.start_servers = 3
pm.min_spare_servers = 2
pm.max_spare_servers = 4
chdir = /
php_admin_value[open_basedir] = /var/www/html/domain.com:/usr/share/php5:/tmp:/usr/share/phpmyadmin:/etc/phpmyadmin:/var/lib/phpmyadmin
php_admin_value[disable_functions] = dl,exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,show_source
user kısmını gokhan olarak belirledik. Eğer gokhan diye bir kullanıcı tanımlı değilse, php-fpm’i restart ettiğinizde kullanıcı idsini alamıyorum şeklinde bir hata ile karşılaşırsınız. Bu yüzden kullanıcıyı oluşturmamız gerekiyor.
#adduser -M -s /sbin/nologin gokhan
Yaptığımız değişikliklerdeki yerlere değinecek olursak,
listen = 127.0.0.1:9001
Listen satırı her pool için farklı portta çalışacak şekilde ayarlanmalı. Kullanılan bir port tanımlamanız durumunda php-fpm’i restart ettiğinizde aşağıdaki şekilde hata alabilirsiniz.
ERROR: [pool wwww] unable to set listen address as it's already used in another pool 'domain'
Owner olarak tanımlayacağınız kullanıcı ve grup ismi,
user = gokhan
group = gokhan
Process yöneticisinin child processleri nasıl kontrol edildiğinin tanımlandığı bölüm,
# dynamic yada static seçilebilir. Default olarak dynamic tanımlıdır.
pm = dynamic
#Aynı anda kaç tane child processin çalışabileceği değer.
#512 Mb ramli bir sunucuda 220 Mb Php-FPM için kullanmayı düşünürsek,
#her process için 24Mb ayırsak, 220 / 24 = 9.17
pm.max_children = 9
#değer : min_spare_servers + (max_spare_servers - min_spare_servers) / 2
#olarak hesaplanır. Startup anında ne kadar child processin çalışacağını
#belirtinr
pm.start_servers = 3
#min idle processi belirtir.
pm.min_spare_servers = 2
#max idle processi belirtir.
pm.max_spare_servers = 4
#Her child process için maks. request değeri. Default değer limitsiz şeklindedir.
pm.max_requests = 200
chdir = /
php_admin_value[open_basedir] = /var/www/html/domain.com:/usr/share/php5:/tmp:/usr/share/phpmyadmin:/etc/phpmyadmin:/var/lib/phpmyadmin
php_admin_value[disable_functions] = dl,exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,show_source
Open_basedir ve çalışmasını istemediğiniz php fonksiyonlarını conf dosyasına aşağıdaki şekilde yazarak tanımlayabilirsiniz. Open_basedir oldukça önemli, php shell yada benzeri bir zararlı script yüklenmesi durumunda, home dizini dışırısına çıkmasını bu şekilde engellemiş oluyorsunuz.
php_admin_value[open_basedir] = /var/www/html/domain.com:/usr/share/php5:/tmp:/usr/share/phpmyadmin:/etc/phpmyadmin:/var/lib/phpmyadmin
php_admin_value[disable_functions] = dl,exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,show_source
Conf dosyamızı düzenledikten sonra php-fpm’i restart edelim.
#/etc/init.d/php-fpm restart
Sıra geldi nginx domain.conf dosyasını düzenlemeye. Nginx’e domainleri daha düzenli göründüğü için conf.d dosyasından include ederek kullanıyorum. Bu yüzden domain için nginx conf dosyası domain.conf şekilde geçmekte.
PHP-FPM domain.conf dosyasını düzenlerken listen portunu 9001 yapmıştık. Nginx domain.conf dosyasında düzenleyelim.
#vi /usr/local/nginx/conf.d/domain.conf
fastcgi_pass satırını aşağıdaki şekilde düzenliyoruz.
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass 127.0.0.1:9001;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $request_filename;
Conf dosyasını düzenledikten sonra nginx’i restart etmeden önce nginx’in conf ayarlarında bir hata varmı diye kontrol etmemiz gerekiyor. Tüm sitelerin down olmasının önüne geçmiş olursunuz.
#/usr/local/nginx/sbin/nginx -t
Ok sonucunu aldıktan sonra nginx’i restart edebiliriz.
#/usr/local/nginx/sbin/nginx -s reload
TCP Bağlantısı yerine socket bağlantısı kullanıyor isek;
Php-fpm.d altında bulunan domain.conf dosyamızda tcp bağlantısı olarak ayarladığımız listen satırını, soket bağlantı olarak aşağıdaki şekilde ayarlayıp,
listen = /var/run/php5-fpm/domain.com.sock
daha sonra nginx domain.conf dosyamızda da fastcgi_pass satırını aşağıdaki gibi ayarlamalıyız.
listen = /var/run/php5-fpm/domain.com.sock
Artık servisleri restart edebilirsiniz.
#/etc/init.d/php-fpm restart
#/usr/local/nginx/sbin/nginx -t
#/usr/local/nginx/sbin/nginx -s reload
Kaynaklar:
http://bit.ly/16ottn9 http://bit.ly/17SgJZN http://bit.ly/15jb23W