Ubuntu server 16.04 LTS – LAMP – част 4

Нужда от елементарна защита

В днешно време защитата на LAMP сървър става все по трудна. Дали да влизам в теория на конспирациите незнам, но никой не може да ми обясни какво печелят така наречените “скриптъри” съвсем незаслужено наричащи себе си “хакери”, като “дифейснат” някой сайт с шарена картинка отпред или БотНет който “пръска” излишен и абсолютно бесмислен трафик или пък някой Китайски DVR питащ DNS сървъра ми 100 пъти в секунда за никога несъществуващ домейн и много други подобни случаи в които атакуващия няма никаква изгода. Всеки здравомислещ човек усеща, че има нещо “гнило в Дания”, но казахме вече, че съвсем “мижитурски” ще избягаме от темата с конспирациите. Освен всичко друго забравяйки за безмислените атаки има и такива с ясната цел да те превърнат в зомби, като постоянно те сканират за някакъв отворен порт на услуга опитваики се да отгаднат я парола в SSH или да прихванат някое “куки” от сесиията на логнат потребител в HTTP. Системният администратор на подобна машина като тази трябва ясно да се разбере с девелопера ако има такъв кой, какви отговорности ще носи. Класическия случай е когато администратора си отговаря за SSH а девелопера за HTTP(S) например.

Firewall – защитна стена

Винаги Първата ми стъпка е да сканирам с nmap отдалечено сървъра.

nmap 93.155.130.82

До тук нещата изглеждат добре, имаме отворени 3 порта като 22, тоест SSH през който имаме достъп отдалечено и ще го филтрираме така, че само IP адресите които опишем ще имат достъп до него. За целта ще се логна в Ubuntu server 16.04 LTS и ще създам файла.

sudo nano firewall.sh
#!/bin/bash
 
#
# Basic iptables rules for sample hosting
# Samuil Arsov <support@itservice-bg.net>
#
 
iptables -F
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
 
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -i lo -j ACCEPT
 
iptables -A INPUT -p tcp --dport 22 -s 93.155.130.0/23 -m comment --comment "Local NET" -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -s 93.155.162.0/24 -m comment --comment "Local NET" -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -s 93.155.169.0/24 -m comment --comment "Local NET" -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -s 88.203.250.79 -m comment --comment "My Village" -j ACCEPT
 
iptables -A INPUT -p tcp --dport 80 -j LOG --log-level 7 --log-prefix "ACCEPT HTTP"
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
 
iptables -A INPUT -p tcp --dport 443 -j LOG --log-level 7 --log-prefix "ACCEPT HTTPS"
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
 
iptables -A INPUT -p icmp --icmp-type 8/0 -j LOG --log-level 7 --log-prefix "ACCEPT ICMP"
iptables -A INPUT -p icmp --icmp-type 8/0 -j ACCEPT
iptables -A INPUT -p icmp --icmp-type 11/0 -j LOG --log-level 7 --log-prefix "ACCEPT TIME EXCEEDED"
iptables -A INPUT -p icmp --icmp-type 11/0 -j ACCEPT
 
iptables -A INPUT -j LOG --log-level 7 --log-prefix "DEFAULT DROP"
iptables -A INPUT -j DROP

Ще го направя изпълним

sudo chmod 755 firewall.sh

И ще го стартирам

sudo ./firewall.sh

Ако не сте си отрязяли достъпа защото сте забравили да си напишете ип адреса в веригата на SSH трябва да проверите минават ли някакви пакети през iptables.

sudo iptables -nvL

Видимо явно, да ! Което значи, че нашият iptables работи. Още по любопитното в случая обаче е какво логва iptables в sysloga на Линукс сървъра:

sudo tail -f /var/log/syslog

И веднага се набива на очи още в първите редове на firewall лога как китайски IP адрес SRC=116.31.116.30 проверява дали порт 22 DPT=22 на сървъра DST=93.155.130.82 е отворен SYN. Но тъй като аз съм филтрирал този порт за непознати IP адреси firewall го отхвърля DEFAULT DROPIN=ens3 което ме прави по малко нервен.

Защита на директории

С Firewall защитихме порт 22 SSH, но директория не можем. Достъпа до директориите се управлява от сървъра Apache от така наречените директиви (правила за директории). Когато инсталирахме phpmyadmin ние не защитихме директорията му, въпреки, че той иска потребителско име и парола, един от потребителите е root тоест администратора на MySQL сървъра. Страшничко е някой да ти знае името на потребителя (50% от информацията за акаунта) за да се опита да отгатне паролата му. Затова ние ще защитим директорията по следния начин като редактираме файла:

sudo nano /etc/phpmyadmin/apache.conf

добавяики третата директива AllowOverride All

<Directory /usr/share/phpmyadmin>
    Options FollowSymLinks
    DirectoryIndex index.php
    AllowOverride All

След което трябва да създадем htaccess

sudo nano /usr/share/phpmyadmin/.htaccess

И да му добавим IP адресите които искаме да имат достъп до web директорията на phpmyadmin

deny from all
allow from 93.155.130.0/23
allow from 93.155.162.0/24
allow from 93.155.169.0/24
allow from 88.203.250.79

След което естествено трябва да рестартираме Apache

sudo systemctl restart apache2.service

IP адрес който не е в htaccess листата трябва да види това в браузера си Forbidden

Apache логове

Web сървъра Apache има доста сериозна система за записване на събития. Основно има два вида събития access.log записва посещенията на сайтовете и error.log записва евентуални проблеми. Самият error.log разделя събитията по важност, като error – грешка което си е някакъв проблем, warn – внимание и notice – бележка. Не мисля, че е нужно да изпадам в подробности, има ужасно много документация за Apache дори и на Български въпросът тук, че логовете много често се пренебрегват а те са ключа към решаването на бъдещи все още неизникнали проблеми.

sudo tail -f /var/log/apache2/error.log

По принцип в access.log Apache, записва доста неща които са излишни, затова ще покажа какво филтрирам аз за да извлеча по лесно читаема информация от записаните събития.

awk -F\" '{print $6}' /var/log/apache2/access.log.1 | sort | uniq -c | sort -fr

Списък на броя на посещенията на сайтовете ни от различни платформи. Google bot ни е посетил само за една нощ 6 пъти.

Броя на кодовете в HTTP протокола за една нощ:

awk '{print $9}' /var/log/apache2/access.log.1 | sort | uniq -c | sort

Основните кодове са:

200 - OK
206 - Partial Content
301 - Moved Permanently
302 - Found
304 - Not Modified
401 - Unauthorised (password required)
403 - Forbidden
404 - Not Found

Кой ип адреси, времето на заявка към Apache и пътищата които посещават

cat  /var/log/apache2/access.log.1 | awk '{print $1,$4,$5,$6,$9,$11,$19}'

Няма да се занимаваме повече с логовете на Apache но с риск да стана банален пак ще кажа, че това много често е доста подценяван момент в поддръжката на един LAMP сървър.

Лог на потребителя

Обикновенно една такава машина не се админстрира от един човек или пък девелопера също има достъп до нея през SSH. След като се срине нещо за да се оправи то по най бързия начин е да се разбере историята на потребителя счупил системата. В тези критични моменти обикновенно никой не знае какво се е случило и често звучат репликите:
– Не съм пипал нищо !
– Спря е така без причина !
– Не съм, аз !

Затова първо започваме с последните събития в системата изискващи оторизация

cat /var/log/auth.log

В личната директори в този файл се съхраняват последните 1000 изпълнени команди в терминала:

cat .bash_history

Дори и потребителя да си изтрие историята с командите при съмнения, че той е променил точно определен файл може да се провери със stat (кой и кога е модифицирал файла за последно)

stat firewall.sh

MySQL injection – attacks

MySQL injection е доста често срещана атака към MySQL сървъра, но това още в самото начало трябва да се разберете с разработчика/девелопера на системата, че си е негова работа. Работата на системния администратор е да архивира базите редовно но не и да ги администрира. Казвам това защото има едно често прехвърляне на топката от този на озни отбор.

Sloworis – DdoS TCP attacks

Sloworis е вид DdoS TCP атака в тих режим. Идеята му е да отвори максималните връзки на Apache без нищо да прави с тях като по този начин се явява така нареченото “запушване”. Хитрото в случая е, че системата ви не се товари, трафика е минимален но сайтовете ви се отварят много трудно или въобще не се отварят. Атаката се диагностицира като видите в htop много процеси на Apache и в tcpdump -i $ETH -nn dst host $IP and dst port 80 хиляди SYN пакети от един IP адрес към порт 80. В Apache има такъв модул който помага това да се предотврати.

Инсталираме:

sudo apt-get -y install libapache2-mod-qos

Редактираме:

sudo nano /etc/apache2/mods-available/qos.conf
<IfModule qos_module>
  # minimum request rate (bytes/sec at request reading):
  # QS_SrvRequestRate                                 120
 
  # limits the connections for this virtual host:
  # QS_SrvMaxConn                                     100
 
  # allows keep-alive support till the server reaches 600 connections:
  # QS_SrvMaxConnClose                                600
 
  # allows max 50 connections from a single ip address:
  QS_SrvMaxConnPerIP                                 50
</IfModule>

Рестартираме Apache

sudo systemctl restart apache2.service

high–level – По високо ниво на защита

От администраторска гледна точка ако искате да вдигнете летвата още малко нагоре разгледайте това:

Защита на Ubuntu 16.04 хостинг сървър с Fail2ban и ipset (blacklist – China, Korea, Spamhaus, OpenBL)

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.