NGINX Güvenliği (Virtual Domain güvenliği)

Merhaba,

Bilindiği gibi nginx, virtual domainler üzerinde nginx:nginx kullanıcı ve grubu ile işlem yapmaktadır. Tüm virtual domain’leriniz default olarak nginx:nginx kullanıcısına aittir. Onlarca web siteniz olduğunu düşünün, içlerinden herhangi birisi bir şekilde hacklendiğinde diğer web sitelerinizi de güvenlik olarak ciddi tehlikelere düşürecektir. Bu yazıda farklı php-fpm socketleri kullanarak farklı kullanıcıların virtual domain üzerinden çalışmasını ve güvenlik sağlamasından bahsedeceğim.

Özellikle wordpress, joomla gibi hazır sitelerinde açıklarından faydalanıp backdoor, shell atarak tüm sitelerinize ulaşılabilir hale gelmek çok zor olmayacaktır. Her web sitesinin kendi kullanıcı adı ve grubu ile hareket etmesi, hacklenen sitenizin başka sitelere de zarar vermesini engelleyecek, sunucunuzdaki açığı da bulmanızı kolaylaşacaktır. Güvenliği sağlamadan önce nginx’in son sürümü kullandığınızdan emin olun ve nginx’i nasıl update edeceğinizi şu yazımda okuyun.

Nginx’i update ettikten sonra aşağıdaki talimatları (mantığını anlayarak) yerine getirin.

Öncelikle her virtual domain için bir kullanıcı adı ve grup oluşturacağız. Ancak bu kullanıcıların ssh giriş yetkileri bulunmayacak. Böylelikle ssh üzerinden gelebilecek olası saldırları da önlemiş olacağız.

Virtual domain adına bir grup oluşturun. Buradaki grup adları illaki domain adı olmak zorunda değil, ancak ileride karıştırmamak adına domainadi.com olarak oluşturuyoruz.

1
 $ groupadd domainadi.com

Virtual domain adına bir user oluşturun.

1
adduser -s /sbin/nologin -d [dosyalarin bulundugu dizin] -g [grup adı] [açacağınız kullanıcı adı]
1
adduser -s /sbin/nologin -d /var/www/domainadi.com -g domainadi.com domainadi.com

-s /sbin/nologin açacağımız kullanıcının ssh üzerinden oturum açmasını engelleyecek.

Şimdi /etc/php-fpm.d/ klasörüne giriş yapınız.

1
# cd /etc/php-fpm.d/

php-fpm.d klasörü her linux sürümlerinde farklı yerlerde veya isimlerde olabilir. Genellikle /etc klasörü altında yer almaktadır. Eğer cpanel, vpanel gibi özel paneller kullanıyorsanız bu klasörlerin yerleri farklı olacaktır. Cpanel gibi paneller zaten sizin yerinize bu güvenliği sağlıyor olabilir.

php-fpm.d klasörü içerisinde www.conf adında bir dosya var. Bu dosyada “;” hariç olan satırları sıralayınca aşağıdaki gibi bir çıktı elde edersiniz.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 # grep -v ^\; www.conf
[www]
user = nginx
group = nginx
listen = /run/php-fpm/php7.1-fpm.sock
listen.owner = nginx
listen.group = nginx
listen.mode = 0660
listen.allowed_clients = 127.0.0.1
pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 35
slowlog = /var/log/php-fpm/www-slow.log
php_admin_value[error_log] = /var/log/php-fpm/www-error.log
php_admin_flag[log_errors] = on
php_value[session.save_handler] = files
php_value[session.save_path]    = /var/lib/php/session
php_value[soap.wsdl_cache_dir]  = /var/lib/php/wsdlcache

Yukarıdaki standart www.conf dosyası php7.1-fpm.sock adında bir socket dosyası oluşturup nginx:nginx kullanıcısı üzerinden web sayfasını dinlemektedir. Web sayfasının php dosyaları da bu socket üzerinden derlenerek kullanıcıların karşısına tarayıcı tarafından çıkarılmaktadır. Biz her virtual domain için bir conf dosyası oluşturacağız. Aşağıdaki örneğe bakın

1
2
# cd /etc/php-fpm.d/
# touch domainadi.com.conf

Yukarıda conf dosyamızı oluşturduk. İçerisine aşağıdaki kodları ekleyelim.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[domainadi.com]
user = domainadi.com
group = domainadi.com
listen = /run/php-fpm/domainadi.com.sock
listen.owner = nginx
listen.group = nginx
listen.mode = 0660
listen.allowed_clients = 127.0.0.1
pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 35
php_admin_value[disable_functions] = exec,passthru,shell_exec,system
php_admin_flag[allow_url_fopen] = off
slowlog = /var/log/php-fpm/domainadi.com-slow.log
php_admin_value[error_log] = /var/log/php-fpm/domainadi.com-error.log
php_admin_flag[log_errors] = on
php_value[session.save_handler] = files
php_value[session.save_path]    = /var/lib/php/session
php_value[soap.wsdl_cache_dir]  = /var/lib/php/wsdlcache

Yukarıdaki kodu bir metin programı ile domainadi.com.conf dosyası içerisine yapıştırın. Burada dikkat etmeniz gereken şey; az önce açtığınız kullanıcı ve grup adını kullanmanız ve socket’i domainadi.com.sock olarak kullanmanız. php tarafında da bazı kısıtlamalara gittik, mesela exec’i disable ettik. Bunun sebebi insanlar php üzerinden linux komutlarını çalıştıramasın. Fazla detaya girmeden bu kısmı atlıyorum.

Yukarıdaki işlem bittikten sonra aynı klasörde iki adet conf dosyası görmeniz gerekiyor. Şimdi php-fpm’i restart edelim.

1
# systemctl restart php-fpm

Restart sonrasında socket’in çalışıp çalışmadığına bakalım.

1
2
3
# ps -aux | grep php
domain.+ 23383  0.0  0.0 364104  7580 ?        S    Mar01   0:00 php-fpm: pool domainadi.com
nginx    23384  0.0  0.1 370244 15692 ?        S    Mar01   0:05 php-fpm: pool www

çalışan servislerde domainadi.com’u görüyor olmanız lazım. Eğer görüyorsanız işlemlerin büyük kısmı tamamlanmış demektir. Şimdi nginx’in ilgili virtual domain conf dosyasında değişiklik yapalım.

1
2
# cd /etc/nginx/sites-available/
# nano domainadi.com.conf

Yukarıdaki conf dosyası sizin domainadi.com sitenize ait NGINX conf dosyasıdır. Az önceki php-fpm conf dosyası ile karıştırmayınız. /etc/nginx/sites-available/ içerisindeki conf dosyası sizin nginx sürümünüze göre farklılık gösterebilir. Bu nedenle farklı klasör veya isimlerde olabilir. Her sunucuya özgün klasör adları da olabilir. Bu nedenle bu dosyayı sizin bulmanız gerekiyor.

İlgili conf dosyası içerisinde

1
2
3
4
5
fastcgi_pass unix:/run/php-fpm/php7.1-fpm-www.sock;

yukarıdaki alanı aşağıdaki gibi değiştirin, kaydedip çıkın.

fastcgi_pass unix:/run/php-fpm/domainadi.com.sock;

Evet son olarak nginx’in çalışıp çalışmadığını nginx -t yaparak kontrol edin. Eğer çalışıyorsa systemctl restart nginx diyerek nginx’i restart edin. Hatasız değişiklikler meydana gelmişse, çalışacaktır.

Bir sonraki yazıda görüşmek üzere…

You may also like...

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Güvenlik Sorusu *