suns
system network data news bugtraq
sexy unix security project
network > Apache+PHP+MySQL droshinaashana (6) 25.01.2005 02:56

Shajaa rakstaa tiek izstaastiits, kaa uzlikt chrootu Apache (ar statiski iebuuveetu PHP un mod_security, jo taa ir vieglaak nochrootot) un MySQL. Taatad buus 2 chrooti. Manaa gadiijumaa, tiek izmantots OpenBSD, bet principaa visam vajadzeetu buut stipri liidziigi arii uz citaam OS (vismaz uz FreeBSD toch ir), vieniigi dazhaam komandaam var atshkjirties sintakse, taapeec iesaku iechekot manuaali pirms taas laist.


Saakums vienmeer gruuts..

Vienvaardsakot saaksim ar pashu sarezhgjiitaako - jaanoslauc Apache, php, MySQL un mod_security. Saslauc to visu vienaa direktorijaa un ver valjaa:

tar xvzf apache_1.3.33.tar.gz
tar xvzf php-4.3.10.tar.gz
tar xvzf mysql-4.1.9.tar.gz
tar xvzf mod_security-1.8.6.tar.gz

MySQL

pirmo liksim MySQL, jo mums buus nepiecieshami MySQL libi, lai tos iekompileetu ieksh Apacha. Saaksim ar to, ka pievienosim mysql lietotaaju:

# groupadd -g 44444 mysql
# useradD -g mysql -d /nonexistent -L daemon -c 'mysql user' -s /sbin/nologin -u 44444 mysql
# cd mysql-4.1.9

Lai MySQL buutu vienkaarshi chrootot, mums tas jaakompilee statisks, taapeec ./configureejot liekam klaat --with-mysqld-ldflags=-all-static:

# ./configure --prefix=/usr/local/mysql --with-mysqld-user=mysql --with-unix-socket-path=/tmp/mysql.sock --with-mysqld-ldflags=-all-static
# gmake && gmake install
# strip /usr/local/mysql/libexec/mysqld
# scripts/mysql_install_db
# chown -R root /usr/local/mysql
# chown -R mysql /usr/local/mysql/var
# chgrp -R mysql /usr/local/mysql

Tagad, atkariibaa no servera slodzes, ir jaaizveelaas pareizais MySQL konfigfails (small, medium, large vai huge), pienjemsim, ka buus videeja slodze taapeec izveeleesimies my-medium.cnf:

# cp support-files/my-medium.cnf /etc/my.cnf
# chown root:sys /etc/my.cnf
# chmod 644 /etc/my.cnf

palaizham MySQL, jo, pirms turpinam, vajag paarliecinaaties, ka viss ir kaartiibaa:

# /usr/local/mysql/bin/mysqld_safe &
# /usr/local/mysql/bin/mysql -u root mysql
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 2 to server version: 4.1.9-log

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql> SHOW DATABASES;
+----------+
| Database |
+----------+
| mysql    |
| test     |
+----------+
2 rows in set (0.03 sec)

mysql> QUIT;

Jaaatziimee tas, ka briidii, kad es rakstiiju sho rakstu, ieksh MySQL bija kljuuda un 'mysql' klients uz OpenBSD nemaz ar negribeeja straadaat. Ja uz briidi, kad tu sho lasi, taa kljuuda veeljoprojaam pastaav, tad te var atrast risinaajumu.


Apache

Uz kaadu briidi liksim mieraa MySQL un uzliksim Apache+php+mod_security. Kaa jau pirmiit piemineeju, kompileesim php un mod_security iekshaa statiski, saaksim ar apache lietotaaju un grupu:

# groupadd -g 44445 apache
# useradd -g apache -d /nonexistent -L daemon -c 'apache user' -s /sbin/nologin -u 44445 apache

Kompileejot Apache noraadiisim visus moduljus, kas ir nepiecieshami, iespeejams, ka tavaa situaacijaa buus nepiecieshami kautkaadi papildus modulji - par to paruupeejies tu pats. Shinii manuaalii tiks izmantoti tikai shie modulji: httpd_core (bez shitaa neiztikt), mod_access (atbild par to, kas driikst un kas nedriikst tikt klaat, un, par cik tiek lietotas 'order', 'allow'' un 'deny' direktiivas, tad bez shitaa modulja arii neiztikt), mod_auth (shis noderees, lai vareetu autentificeet lietotaajus ar paroleem), mod_dir (nepiecieshams, lai vareetu mekleet un pasniegt direktoriju index failus), mod_log_config (nepiecieshams, lai vareetu logot) un mod_mime (nepiecieshams, lai vareetu straadaat ar charsetiem, dokumentu MIME tipiem utt.). paareejos moduljus mees brutaali sleedzam nost, taadejaadi noveershot potenciaalus uzbrukumus gadiijumaa, ja kaadaa no tiem tiks atrasts kaads droshiibas caurums.

Opcionaali varu ieteikt palabot Apache banneri, jo reizeem nav lustes, kad hx0ri var taa vienkaarshi panjemt un noteikt webservera versiju. Neesu paarliecinaats, vai Apache licence ljauj taa dariit, bet man, atklaati sakot, ir vienalga. Ja kas, tad ieksh apache_1.3.33/src/include/httpd.h failinja ap 400 rindu ir kautkas taads:

#define SERVER_BASEVENDOR "Apache Group"
#define SERVER_BASEPRODUCT "Apache"
#define SERVER_BASEREVISION "1.3.33"
#define SERVER_BASEVERSION SERVER_BASEPRODUCT "/" SERVER_BASEREVISION

#define SERVER_PRODUCT SERVER_BASEPRODUCT
#define SERVER_REVISION SERVER_BASEREVISION
#define SERVER_VERSION SERVER_PRODUCT "/" SERVER_REVISION

Daudz nedomaajot mainam sho uz kautko forshu, piemeeram:

#define SERVER_BASEVENDOR "Microsoft"
#define SERVER_BASEPRODUCT "IIS"
#define SERVER_BASEREVISION "5.0"
#define SERVER_BASEVERSION SERVER_BASEVENDOR "-" SERVER_BASEPRODUCT "/" SERVER_BASEREVISION

#define SERVER_PRODUCT SERVER_BASEPRODUCT
#define SERVER_REVISION SERVER_BASEREVISION
#define SERVER_VERSION SERVER_BASEVENDOR "-" SERVER_PRODUCT "/" SERVER_REVISION

Un banneriitis tagad izskatiisies luuk shaadi: Microsoft-IIS/5.0. Nu man arii patiik. Nav ko tur daudz, kjersimies pie darba..

Ieliekam mod_security ieksh Apache source direktorijas (ja to neizdaram, kompileejoties nebuus nekaadu kljuudu pazinjojumu, Apacis saaks suuroties tikai, kad tam neizdosies palaist mod_security), lai Apacis to vareetu iesuukt:

# cd ../mod_security-1.8.6
# cp apache1/mod_security.c ../apache_1.3.33/src/modules/extra

Ceru, ka nav jaapaskaidro, kas notiek taalaak:

# cd ../apache_1.3.33
# ./configure
# cd ../php-4.3.10
# ./configure --with-mysql=/usr/local/mysql --with-apache=../apache_1.3.33 --enable-safe-mode
# make && make install
# cp php.ini-recommended /usr/local/lib/php.ini
# cd ../apache_1.3.33
# ./configure --prefix=/usr/local/apache --disable-module=all --server-uid=apache --server-gid=apache --enable-module=access --enable-module=log_config --enable-module=dir --enable-module=mime --enable-module=auth --activate-module=src/modules/extra/mod_security --enable-module=security --activate-module=src/modules/php4/libphp4.a
# make && make install
# chown -R root:sys /usr/local/apache

Un ieksh /usr/local/apache/conf/httpd.conf ietaisam sho rindu:

AddType application/x-httpd-php .php

Tagad palaizham Apache:

# /usr/local/apache/bin/apachectl start

Uztaisam /usr/local/apache/htdocs/test.php failu ar shaadu saturu:

<html><body>
<?php
$link = mysql_connect("localhost", "root", "")
 or die;
print "Viss straadaa lieliski!";
mysql_close($link);
?>
</body></html>

paarbaudam, vai test.php straadaa, tad priecaajamies un varam turpinaat ar chrootoshanu. pirmo chrootosim Apache, tamdeelj izveidosim jaunu direktoriju struktuuru:

# mkdir -p /chroot/httpd/dev
# mkdir -p /chroot/httpd/etc
# mkdir -p /chroot/httpd/var/run
# mkdir -p /chroot/httpd/usr/lib
# mkdir -p /chroot/httpd/usr/libexec
# mkdir -p /chroot/httpd/usr/local/apache/bin
# mkdir -p /chroot/httpd/usr/local/apache/logs
# mkdir -p /chroot/httpd/usr/local/apache/conf
# mkdir -p /chroot/httpd/www
# mkdir -p /chroot/httpd/usr/local/mysql/lib/mysql
# mkdir -p /chroot/httpd/usr/local/lib
# mkdir -p /chroot/httpd/tmp
# chmod 1777 /chroot/httpd/tmp

Ieksh chroot jaila mums ir nepiecieshams /dev/null devaiss, to var izveidot shaadi:

# mknod /chroot/httpd/dev/null c 2 2
# chown root:sys /chroot/httpd/dev/null
# chmod 666 /chroot/httpd/dev/null

Savukaart log devaisam mums vajag piesaistiit syslogu, taapeec ieksh /etc/rc.conf.local faila liekam shaadu rindu (buus nepiecieshams arii paarstarteet visu sisteemu vai tikai syslog, bet ar attieciigajiem flagiem):

syslogd_flags="-a /chroot/httpd/dev/log"

Tagad vajag uzzinaat, kaadus tad failus likt ieksh chroota. prieksh tam es izmantoju ldd ('ldd /usr/local/apache/bin/httpd', bet uz citaam OS shis var atshkjirties, var meegjinaat izmantot arii shiis komandas: ktrace/ktruss/kdump (*BSD), sotruss (Solaris), strace/ltrace (Linux), strings (*), truss (FreeBSD, Solaris)), uz OpenBSD bija nepiecieshami shie faili:

# cp /usr/local/apache/bin/httpd /chroot/httpd/usr/local/apache/bin/
# cp /usr/local/mysql/lib/mysql/libmysqlclient.so.14.0 /chroot/httpd/usr/local/mysql/lib/mysql/
# cp /usr/lib/libm.so.2.0 /chroot/httpd/usr/lib/
# cp /usr/lib/libc.so.34.1 /chroot/httpd/usr/lib/
# cp /usr/lib/libz.so.4.0 /chroot/httpd/usr/lib/
# cp /usr/libexec/ld.so /chroot/httpd/usr/libexec/
# cp /etc/hosts /chroot/httpd/etc/
# cp /etc/resolv.conf /chroot/httpd/etc/
# cp /etc/localtime /chroot/httpd/etc/
# cp /etc/group /chroot/httpd/etc/
# cp /etc/master.passwd /chroot/httpd/etc/passwords
# cp /usr/local/apache/conf/mime.types /chroot/httpd/usr/local/apache/conf/
# cp /usr/local/lib/php.ini /chroot/httpd/usr/local/lib/

Tagad svariigi ir paediteet /chroot/httpd/etc/passwords un /chroot/httpd/etc/group failus un atstaat tajos tikai nogroup, nobody un apache ierakstus, taalaak taisam pashu parolju db failu:

# cd /chroot/httpd/etc/
# pwd_mkdb -d /chroot/httpd/etc passwords
# rm /chroot/httpd/etc/master.passwd

Tagad atkal paarbaudiisim, vai viss, kas liidz shim tika izdariits, straadaa, ietaisiisim httpd.conf failu un index failu-izbaazeni, neaizmirstam ieksh httpd.conf nomainiit DocumentRoot uz "/www":

# cp /usr/local/apache/conf/httpd.conf /chroot/httpd/usr/local/apache/conf/
# echo "kewl" > /chroot/httpd/www/index.html
# chroot /chroot/httpd /usr/local/apache/bin/httpd

Ja viss kaartiibaa, tad varam turpinaat, ja nee, tad jaameklee un jaalabo probleemas.

Tagad pielabosim php.ini, vissvariigaak ir nomainiit shos mainiigos:

safe_mode = On
expose_php = Off
disable_functions = exec,system,shell_exec,passthru,readfile,phpinfo

Ja shaads variants ir paaraak strikts, tad veel klaat var pielikt:

safe_mode_gid = On

Atgriezhoties pie MySQL

Tagad ir pienaacis laiks mochiit augshaa MySQLa chrootu, tas ir pat vienkaarshaak nekaa bija ar Apaci, saakam ar direktorijaam:

# 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
# chown -R root:sys /chroot/mysql
# chmod -R 755 /chroot/mysql
# chmod 1777 /chroot/mysql/tmp

Failus, kas mums ir nepiecieshami, noskaidrojam gluzhi taadaa pashaa veidaa, kaa ar Apaci, manaa gadiijumaa, bija nepiecieshami shie faili:

# 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/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/

Shoreiz /chroot/mysql/etc/passwords un /chroot/mysql/etc/group failos jaaatstaaj tikai mysql ieraksti:

# cd /chroot/mysql/etc/
# pwd_mkdb -d /chroot/mysql/etc passwords
# rm /chroot/mysql/etc/master.passwd
# mknod /chroot/mysql/dev/null c 2 2
# chown root:sys /chroot/mysql/dev/null
# chmod 666 /chroot/mysql/dev/null
# cp -R /usr/local/mysql/var/ /chroot/mysql/usr/local/mysql/var
# chown -R mysql:mysql /chroot/mysql/usr/local/mysql/var

Un meegjinam palaist MySQL, tikai shoreiz chrootojot noraadam arii lietotaaju:

# chroot -u mysql /chroot/mysql /usr/local/mysql/libexec/mysqld &

Ar hardlinku (un tas noziimee, ka /chroot/mysql un /chroot/httpd ir fiziski jaaatrodas uz vienas failsisteemas, savaadaak hardlinku nevarees uztaisiit, bet softlinks shajaa situaacijaa nestraadaas) paliidziibu uztaisam MySQL socketu ieksh Apache chroota:

# ln /chroot/mysql/tmp/mysql.sock /chroot/httpd/tmp/

Tagad norestarteejam Apaci un paarbaudam ar to pashu test.php, vai viss straadaa. Ja viss kaartiibaa, tad turpinam un editeejam /chroot/mysql/etc/my.cnf, tur jaaieliek shaadas rindas ieksh [mysqld] sadaljas:

skip-networking
set-variable=local-infile=0

skip-networking noraada, lai MySQL neklausiitos TCp (pienjemu, ka pieeja MySQLam ir nepiecieshama tikai lokaala), bet set-variable=local-infile=0 atsleegs LOAD DATA LOCAL INFILE komandu, kas paliidzees izvairiities no neautorizeetas pieejas lokaaliem failiem.

Savukaart ieksh /etc/my.cnf faila [client] sadaljas sho rindu (jo mysql klientam nu buus jaakomunicee ar chroototo MySQLu):

socket = /chroot/mysql/tmp/mysql.sock

Tagad nomainiisim MySQL administratora paroli, izmetiisim liekaas datubaazes un lietotaajus:

# /usr/local/mysql/bin/mysql -u root
mysql> SET PASSWORD FOR root@localhost=PASSWORD('parole');
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;

Neaizmirstam arii iztiiriit .mysql_history failu:

# echo > /root/.mysql_history

Tad tas arii buutu viss. Atliek vairs tikai notesteet un paarliecinaaties, ka viss straadaa :)


Skriptinji

Lai laistu Apache un MySQL ieksh chroota, buutu eertaak izmantot shaadus skriptinjus:


apache.sh

#!/bin/sh

CHROOT=/chroot/httpd
HTTPD=/usr/local/apache/bin/httpd
PIDFILE=/usr/local/apache/logs/httpd.pid

echo -n " apache"

case "$1" in
start)
   /usr/sbin/chroot $CHROOT $HTTPD
   ;;
stop)
   kill `cat ${CHROOT}/${PIDFILE}`
   ;;
*)
   echo ""
   echo "Usage: `basename $0` {start|stop}" >&2
   exit 64
   ;;
esac

exit 0

mysql.sh

#!/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
CHROOT=/usr/sbin/chroot

echo -n " mysql"

case "$1" in
start)
   rm -rf ${CHROOT_PHP}/${SOCKET}
   nohup ${CHROOT} -u mysql ${CHROOT_MYSQL} ${MYSQLD} >/dev/null 2>&1 &
   sleep 5 && ln ${CHROOT_MYSQL}/${SOCKET} ${CHROOT_PHP}/${SOCKET}
   ;;
stop)
   kill `cat ${CHROOT_MYSQL}/${pIDFILE}`
   rm -rf ${CHROOT_MYSQL}/${SOCKET}
   ;;
*)
   echo ""
   echo "Usage: `basename $0` {start|stop}" >&2
   exit 64
   ;;
esac

exit 0

Teiten buus httpd.conf paraugs (neaizmirsti nomainiit ServerTokens direktiivu uz Min, ja pirms kompilaacijas mainiiji Apache banneri uz IIS ieksh httpd.h):

# =================================================
# Basic settings
# =================================================
ServerType standalone
ServerRoot "/usr/local/apache"
pidFile /usr/local/apache/logs/httpd.pid
ScoreBoardFile /usr/local/apache/logs/httpd.scoreboard
ResourceConfig /dev/null
AccessConfig /dev/null

# =================================================
# performance settings
# =================================================
Timeout 300
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 15
MinSpareServers 5
MaxSpareServers 10
StartServers 5
MaxClients 150
MaxRequestsperChild 0

# =================================================
# Apache's modules
# =================================================
ClearModuleList
AddModule mod_log_config.c
AddModule mod_mime.c
AddModule mod_dir.c
AddModule mod_access.c
AddModule mod_auth.c
AddModule mod_php4.c
AddModule mod_security.c

# =================================================
# General settings
# =================================================
port 80
User apache
Group apache
ServerAdmin webmaster@domain.lv
UseCanonicalName Off
ServerSignature Off
HostnameLookups Off
ServerTokens prod
<IfModule mod_dir.c>
    DirectoryIndex index.html index.php
</IfModule>
DocumentRoot "/www/default"

# =================================================
# Access control
# =================================================
<Directory />
    Options None
    AllowOverride None
    Order deny,allow
    Deny from all
</Directory>
<Directory "/www/default">
    Order allow,deny
    Allow from all
</Directory>
<Directory "/www/www.test.lv">
    Order allow,deny
    Allow from all
</Directory>

# =================================================
# MIME encoding
# =================================================
<IfModule mod_mime.c>
    TypesConfig /usr/local/apache/conf/mime.types
</IfModule>
DefaultType text/plain
<IfModule mod_mime.c>
    AddEncoding x-compress Z
    AddEncoding x-gzip gz tgz
    AddType application/x-tar .tgz
    AddType application/x-httpd-php .php
    AddType application/x-httpd-php .inc
    AddType application/x-httpd-php .class
    AddType application/x-httpd-php .phtml
</IfModule>

# =================================================
# mod_security
# =================================================
<IfModule mod_security.c>
    AddHandler application/x-httpd-php .php
    SecAuditEngine RelevantOnly
    SecAuditLog logs/audit_log
    SecFilterScanpOST On
    SecFilterEngine On
    SecFilterDefaultAction "deny,log,status:500"
    SecFilter "<(.|\n)+>"
    SecFilter "delete[[:space:]]+from"
    SecFilter "insert[[:space:]]+into"
    SecFilter "select.+from"
    SecFilterSelective "HTTp_USER_AGENT|HTTp_HOST" "^$"
    SecFilterSelective "HTTp_CONTENT_TYpE" multipart/form-data
</IFModule>

# =================================================
# Logs
# =================================================
LogLevel warn
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%h %l %u %t \"%r\" %>s %b" common
LogFormat "%{Referer}i -> %U" referer
LogFormat "%{User-agent}i" agent
ErrorLog /usr/local/apache/logs/error_log
CustomLog /usr/local/apache/logs/access_log combined

# =================================================
# Virtual hosts
# =================================================
NameVirtualHost *
<VirtualHost *>
    DocumentRoot "/www/www.test.lv"
    ServerName "www.test.lv"
    ServerAlias "test.lv"
    ErrorLog logs/www.test.lv/error_log
    CustomLog logs/www.test.lv/access_log combined
    php_admin_value open_basedir /www/www.test.lv
</VirtualHost>

Nobeigums

Neko jaunu jau neesu izdomaajis un nav nosleepums, ka shis raksts tapis paarsvaraa balstoties uz shiem manuaaljiem: Securing Apache: Step-by-Step, Securing PHP: Step-by-Step un Securing MySQL: Step-by-Step, kurus ir sarakstiijis Artur Maj. Tur viss ir rakstiits smalkaak un tika izmantots FreeBSD. pavisam noteikti iesaku izlasiit visus triis vinja manuaaljus.

/ petruha - http://petruha.bsd.lv/ /
comments
Aivis <aabele(at)gmail.com>:
Tik labs manuaalis, ka nevienam tolkom nedriikst taadu raadiit. Un veel - oranzhie burti ar kaadu jaaraksta komentaars - vienkaarshi izsit. Pieprasu kraasu kontrastu!
r21vo:
labais! latviski shaadus materiaalus atrast ir praktiski neiespeejami.
z1ng3r <z1ng3r(at)console.lv>:
labs, vienīgais nedomāju, ka vajag labot apache sourci, lai izmainītu apache uz IIS, tas ir iespējams ar mod_security vienu parametru.
vells <egils(at)include.lv>:
reku ir shaadi taadi security ruljlji

http://www.gotroot.com/mod_security+rules
http://www.gotroot.com/downloads/ftp/mod_security/recons.conf

ja nu ne lietot, tad vismaz var apskatiit kaa kustomizeet ...

E.
vells <egils(at)include.lv>:
un pie php.ini ljoti labi ir ja iestaada

allow_url_fopen=off

E.
J <jp(at)deephouse.lv>:
tiesham class work :) thx
add comment*
author:
email:
piecpadsmit:
comment:


* ja iztiksi bez spama, offtopika un muljkjiibaam, iespeejams, ka tavs koments netiks izdzeests.
« back

valid xhtmlvalid css