A idéia é montar um servidor Web com Apache em chroot, com o Firewall de Aplicação Web ModSecurity, e com o PHP e o MySQL também em chroot. O sistema utilizado é o Debian 5.0. A topologia do ambiente é essa : 1. APACHE. 1.1 Instalação do Apache 2 1.2 Configuração do Apache 2. 1.3 Desabilitando módulos desnecessários. 2. Mod Security. 2.1 Baixando os fontes. 2.2 Instalando os Pré-requisitos: 2.3 Descompactar / Compilar / instalar. 2.5 Configurando o ModSecurity no Apache. 3. Instalando o PHP. 3.2 Customizando o PHP.INI 3.3 Setando configurações de Segurança no PHP. 3.4 Funções “perigosas “. 4. Chroot do Apache 2 no Debian. 4.1 Criando a Jaula. 4.2 Colocando o Shell e suas libs. 4.4 Colocando o Apache na Jaula. 4.5 Ajuste da hora do Servidor. 4.6 Rotate de Logs. 5. Criando o Script do Apache. 6. Chroot do PHP. 7. MySQL. 7.1 Instalação do MySQL. 7.3 Removendo o script de Inicialização. 7.4 Criando o novo script 7.5 Configurando o MySQL. 7.6. Linkando o MySQL e o PHP. 8. PHPMyAdmin. 8.1 Configurar o PHPMYADMIN.. 9. Ferramentas. 9.1 ApacheTop. 9.2 WWWstat 10. Configuração do Firewall 12. Configuração de Rede. 13. SSH.. 13.1 Publicação de páginas via SSH.. 13.2 Testando a conexão. 13.3 Montando a pasta do Site para o programador. 13.4 Fazendo mais ajustes no SSH.. 14. Considerações Finais.
Reading package lists... Done
Antes de configurá-lo vamos fazer o backup da configuração original. A configuração do Apache no Debian já vem bem ajustada, iremos então apenas limpar os comentários, deixando o arquivo mais fácil para que possamos entender. Em seguida
colocaremos o restante das configurações necessárias.
/etc/apache2/mods-enabled/*.load No arquivo ports.conf estão setadas as portas que o servidor irá escutar. Dentro da pasta "conf.d" ficam outros arquivos de configurações. Nela você pode incluir arquivos de configurações específicos para determinados sites. Por exemplo, um site específico que precisa de configurações php diferente dos outros sites. Você pode criar nessa pasta um arquivo .conf” que irá setar essas configurações específicas para esse site. Os módulos e seus arquivos de configuração são armazenados dentro da pasta "mods-available" e são linkados dentro da pasta "mods-enabled" para poderem serem carregados. # cd
/etc/apache2
Caso deseje fazer alguma outra modificação, acesse esses outros arquivos: # vi
sites-enabled/000-default 1.3 Desabilitando módulos desnecessários
Em "http://httpd.apache.org/docs/2.0/mod/" você pode obter mais informações sobre os módulos e verificar se determinado módulo é necessários ou não em seu ambiente. Os módulos que estão ativos em meu ambiente são esses:
2.
Mod Security
|
|
SecAuditLog /etc/apache2/modsecurity/logs/modsec_audit.log SecDebugLog
/etc/apache2/modsecurity/logs/modsec_debug.log |
Os dois arquivos de configuração principais são o
"modsecurity_crs_10_config.conf" e o
"modsecurity_crs_30_http_policy.conf", vasculhe os dois arquivos para
entender um pouco como funcionam algumas regras do modsecurity. Depois olhe o
conteúdo dos outros. São vários arquivos com diversos tipos de bloqueio. Tem
muita coisa interessante, assim como muita coisa que pode prejudicar o
funcionamento de seu web site.
2.5 Configurando o ModSecurity no Apache
Para que o Apache inclua o ModSecurity em sua configuração é preciso colocar uma linha "include" no apache de modo que ele leia as configurações na pasta modsecurity criada; Além disso precisamos criar um arquivo que carregará as configurações do módulo "modsecurity". Depois com o comando "a2enmod" iremos ativar o módulo. Precisamos ativar o módulo unique_id que é um pré-requisito para o seu funcionamento.
# echo "Include /etc/apache2/modsecurity/*.conf" >> apache2.conf
# vi /etc/apache2/mods-available/mod-security2.load|
LoadFile
/usr/lib/libxml2.so LoadFile /usr/lib/libcurl.so LoadModule security2_module /usr/lib/apache2/modules/mod_security2.so |
# a2enmod mod-security2
# a2enmod unique_id
# /etc/init.d/apache2 restart
Para a segurança em relação ao PHP, iremos configurá-lo enhaulado, aplicar o patch de Segurança “Suhosin” e definirmos alguns parametros de segurança no arquivo php.ini
# aptitude install libapache2-mod-php5
# aptitude install php5 php5-dev
php5-mysql
3.1
Instalando e Configurando o Suhosin
# apt-get install php5-suhosin
Segundo a
documentação oficial do Suhosin, a configuração padrão atende na maioria dos
casos, entretanto no link
http://www.hardened-php.net/suhosin/configuration.html temos mais informações
de outras opções que podem ser configuradas para melhorar ajustá-lo de acordo
com a sua necessidade.
Vamos criar
o arquivo info.php para obter informações PHP do servidor, nele podemos
perceber se o pacth foi aplicado.
# vi /var/www/info.php
|
<?php phpinfo(); ?> |
Antes de acessar o servidor, vamos comentar temporariamente, a linha do arquivo
apache2.conf que "chama" o
modSecurity, pois ele bloqueia essa requisição de informações do PHP, daí
tentaremos acessar o servidor via http://nomedoserver/info.php
para obter essas configurações.
# vi /etc/apache2/apache2.conf
Comente a linha :
|
#Include /etc/apache2/modsecurity/*.conf |
Depois reinicie o Apache :
# /etc/init.d/apache2 restart
Após verificar as informações, descomente novamente a linha e restarte o apache outra vez.
# /etc/init.d/apache2 restart
# cd /etc/php5/apache2
# cp php.ini php.ini.bkp
# vi php.ini
| [PHP] ;;;;;;;;;;;;;;;;;;;; ; Language Options ; ;;;;;;;;;;;;;;;;;;;; engine = On zend.ze1_compatibility_mode = Off short_open_tag = On asp_tags = Off precision = 12 y2k_compliance = On output_buffering = Off zlib.output_compression = Off ;zlib.output_compression_level = -1 implicit_flush = Off unserialize_callback_func= serialize_precision = 100 allow_call_time_pass_reference = On safe_mode = Off safe_mode_gid = Off safe_mode_include_dir = safe_mode_exec_dir = safe_mode_allowed_env_vars = PHP_ safe_mode_protected_env_vars = LD_LIBRARY_PATH ;open_basedir = disable_functions = disable_classes = expose_php = Off ;;;;;;;;;;;;;;;;;;; ; Resource Limits ; ;;;;;;;;;;;;;;;;;;; max_execution_time = 30 ; Maximum execution time of each script, in seconds max_input_time = 60 ; Maximum amount of time each script may spend parsing request data ;max_input_nesting_level = 64 ; Maximum input variable nesting level memory_limit = 128M ; Maximum amount of memory a script may consume (128MB) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Error handling and logging ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; error_reporting = E_ALL & ~E_NOTICE display_errors = Off display_startup_errors = Off log_errors = On log_errors_max_len = 1024 ignore_repeated_errors = Off ignore_repeated_source = Off report_memleaks = On track_errors = Off ;;;;;;;;;;;;;;;;; ; Data Handling ; ;;;;;;;;;;;;;;;;; variables_order = "EGPCS" register_globals = Off register_long_arrays = On register_argc_argv = On auto_globals_jit = On post_max_size = 8M magic_quotes_gpc = On magic_quotes_runtime = Off magic_quotes_sybase = Off auto_prepend_file = auto_append_file = default_mimetype = "text/html" ;;;;;;;;;;;;;;;;;;;;;;;;; ; Paths and Directories ; ;;;;;;;;;;;;;;;;;;;;;;;;; doc_root = user_dir = enable_dl = Off ;;;;;;;;;;;;;;;; ; File Uploads ; ;;;;;;;;;;;;;;;; file_uploads = On ;upload_tmp_dir = upload_max_filesize = 2M ;;;;;;;;;;;;;;;;;; ; Fopen wrappers ; ;;;;;;;;;;;;;;;;;; allow_url_fopen = Off allow_url_include = Off default_socket_timeout = 60 [Syslog] define_syslog_variables = Off [mail function] SMTP = localhost smtp_port = 25 [ODBC] odbc.allow_persistent = On odbc.check_persistent = On odbc.max_persistent = -1 odbc.max_links = -1 odbc.defaultlrl = 4096 odbc.defaultbinmode = 1 [[Date]MySQL] mysql.allow_persistent = On mysql.max_persistent = -1 mysql.max_links = -1 mysql.default_port = mysql.default_socket = /tmp/mysqld.sock mysql.default_host = mysql.default_user = mysql.default_password = mysql.connect_timeout = 60 mysql.trace_mode = Off [Session] #session.save_path = '/tmp' session.save_handler = files session.use_cookies = 1 session.name = PHPSESSID session.auto_start = 0 session.cookie_lifetime = 0 session.cookie_path = / session.cookie_domain = session.cookie_httponly = session.serialize_handler = php session.gc_divisor = 100 session.gc_maxlifetime = 1440 session.bug_compat_42 = 1 session.bug_compat_warn = 1 session.referer_check = session.entropy_length = 0 session.entropy_file = session.cache_limiter = nocache session.cache_expire = 180 session.use_trans_sid = 0 session.hash_function = 0 session.hash_bits_per_character = 4 url_rewriter.tags = "a=href,area=href,frame=src,input=src,form=,fieldset=" |
3.3 Setando configurações de Segurança no PHP
|
Parâmetro |
Descrição |
|
allow_url_fopen = off |
Impede que se use funções como fopen, file_get_contentens e include, evitando, por exemplo, que se abra sites ou arquivos remotos em outros sites. |
|
register_globals = Off |
Impede que valores de INPUT sejam colocados como variáveis globais. |
|
display_errors = Off |
Previne que erros sejam mostrados, evitando a obtenção de informações sobre o PHP |
|
log_errors = on |
Irá gerar registrar erros |
|
expose_php = Off |
Previne que sejam mostradas informações sobre o PHP |
|
safe_mode = On |
Protege contra acessos indevidos ao arquivos de sistemas e adiciona algumas restrições de segurança, como a verificação do owner de um script em execução e dos arquivos afetados. |
|
open_basedir = directory[:...] |
Restringe o acesso a arquivos contidos apenas na pasta especificada. |
|
safe_mode_exec_dir = directory[:...] |
Especifica o diretório para colocar os scripts e executáveis |
|
max_execution_time = 30 |
Define para 30 segundos a execução máx. de cada script |
|
max_input_time = 60 |
Define o tempo máx. em segundos que um script poderá gastar com uma requisição |
|
memory_limit = 16M |
Define a memória máxima que um script pode usar |
|
upload_max_filesize = 2M |
Coloca em 2 Megas o tamanho máximo de Upload |
|
post_max_size = 8M |
Tamanho máx de requisições POST que serão processadas |
3.4 Funções “perigosas “
Algumas funções do PHP são muito interessantes para que uma pessoal mal intencionada possa obter informações sobre o servidor ou mesmo executar códigos nele. Para desabilitá-las basta usar o parâmetro “disable_functions = nome_da_função“ , por exemplo :
disable_functions = php_uname, getmyuid, getmypid, passthru, leak, listen, diskfreespace, tmpfile, link, ignore_user_abord, shell_exec, dl, set_time_limit, exec, system, highlight_file, source, show_source, fpaththru, virtual, posix_ctermid, posix_getcwd, posix_getegid, posix_geteuid, posix_getgid, posix_getgrgid, posix_getgrnam, posix_getgroups, posix_getlogin, posix_getpgid, posix_getpgrp, posix_getpid, posix, _getppid, posix_getpwnam, posix_getpwuid, posix_getrlimit, posix_getsid, posix_getuid, posix_isatty, posix_kill, posix_mkfifo, posix_setegid, posix_seteuid, posix_setgid, posix_setpgid, posix_setsid, posix_setuid, posix_times, posix_ttyname, posix_uname, proc_open, proc_close, proc_get_status, proc_nice, proc_terminate, phpinfo
4. Chroot do Apache 2 no Debian
Agora chegou da parte bastante trabalhosa, que é a criação da “jaula” e “enjaulamento” do Apache.
# mkdir /chroot
# cd /chroot
# mkdir bin lib apache2
4.2 Colocando o Shell e suas libs
# cp /bin/bash /chroot/bin/bash
# ldd /chroot/bin/bash
linux-gate.so.1 => (0xb7f81000)
libncurses.so.5 => /lib/libncurses.so.5 (0xb7f46000)
libdl.so.2 => /lib/i686/cmov/libdl.so.2 (0xb7f42000)
libc.so.6 => /lib/i686/cmov/libc.so.6 (0xb7de7000)
/lib/ld-linux.so.2 (0xb7f82000
# cp /lib/libncurses.so.5 /chroot/lib/
# cp /lib/libdl.so.2 /chroot/lib/
# cp /lib/libc.so.6 /chroot/lib/
# cp /lib/ld-linux.so.2 /chroot/lib/
4.3 Testando a execução do Shell enjaulado
# chroot /chroot /bin/bash
4.4
Colocando o Apache na Jaula
Agora nós vamos localizar onde estão os arquivos do Apache (libs, confs, módulos, etc) e depois copiá-los para a jaula, sem esquecer de incluir as dependências. Para isso usaremos o comando “ldd” para descobrir quais as bibliotecas que cada arquivo necessita.
# mkdir apache2
# whereis
apache2 | tr " " \\012
apache2:
/usr/sbin/apache2
/etc/apache2
/usr/lib/apache2
/usr/include/apache2
/usr/share/apache2
/usr/share/man/man8/apache2.8.gz
# mkdir -p /chroot/apache2/usr/sbin/
# cp /usr/sbin/apache2 /chroot/apache2/usr/sbin/
# ldd /chroot/apache2/usr/sbin/apache2
linux-gate.so.1 => (0xb7fae000)
libpcre.so.3 => /usr/lib/libpcre.so.3 (0xb7f7e000)
libaprutil-1.so.0 => /usr/lib/libaprutil-1.so.0
(0xb7f60000)
libapr-1.so.0 => /usr/lib/libapr-1.so.0 (0xb7f34000)
libpthread.so.0 => /lib/i686/cmov/libpthread.so.0
(0xb7f1b000)
libc.so.6 => /lib/i686/cmov/libc.so.6 (0xb7dc0000)
libldap_r-2.4.so.2 => /usr/lib/libldap_r-2.4.so.2
(0xb7d7d000)
liblber-2.4.so.2 => /usr/lib/liblber-2.4.so.2
(0xb7d70000)
libdb-4.6.so => /usr/lib/libdb-4.6.so (0xb7c3d000)
libpq.so.5 => /usr/lib/libpq.so.5 (0xb7c1d000)
libmysqlclient_r.so.15 => /usr/lib/libmysqlclient_r.so.15
(0xb7a32000)
libsqlite3.so.0 => /usr/lib/libsqlite3.so.0 (0xb79c3000)
libexpat.so.1 => /usr/lib/libexpat.so.1 (0xb799d000)
libuuid.so.1 => /lib/libuuid.so.1 (0xb7999000)
librt.so.1 => /lib/i686/cmov/librt.so.1 (0xb7990000)
libcrypt.so.1 => /lib/i686/cmov/libcrypt.so.1
(0xb795d000)
libdl.so.2 => /lib/i686/cmov/libdl.so.2 (0xb7959000)
/lib/ld-linux.so.2 (0xb7faf000)
libresolv.so.2 => /lib/i686/cmov/libresolv.so.2
(0xb7945000)
libsasl2.so.2 => /usr/lib/libsasl2.so.2 (0xb792e000)
libgnutls.so.26 => /usr/lib/libgnutls.so.26 (0xb7891000)
libssl.so.0.9.8 => /usr/lib/i686/cmov/libssl.so.0.9.8
(0xb784a000)
libcrypto.so.0.9.8 =>
/usr/lib/i686/cmov/libcrypto.so.0.9.8 (0xb76f7000)
libkrb5.so.3 => /usr/lib/libkrb5.so.3 (0xb7663000)
libcom_err.so.2 => /lib/libcom_err.so.2 (0xb7660000)
libgssapi_krb5.so.2 => /usr/lib/libgssapi_krb5.so.2
(0xb7636000)
libnsl.so.1 => /lib/i686/cmov/libnsl.so.1 (0xb761c000)
libm.so.6 => /lib/i686/cmov/libm.so.6 (0xb75f6000)
&amp;nbsp; libz.so.1 => /usr/lib/libz.so.1 (0xb75e1000)
libtasn1.so.3 => /usr/lib/libtasn1.so.3 (0xb75d1000)
libgpg-error.so.0 => /usr/lib/libgpg-error.so.0
(0xb75cd000)
libgcrypt.so.11 => /usr/lib/libgcrypt.so.11 (0xb7564000)
libk5crypto.so.3 => /usr/lib/libk5crypto.so.3
(0xb7540000)
libkrb5support.so.0 => /usr/lib/libkrb5support.so.0
(0xb7538000)
libkeyutils.so.1 => /lib/libkeyutils.so.1 (0xb7535000)
Depois de
descobrir os arquivos necessários para o apache funcionar, precisaremos criar a
estrutura dentro da jaula, para copiar esses arquivos.
# mkdir -p /chroot/apache2/usr/lib/
# mkdir -p /chroot/apache2/usr/lib/i686/cmov/
# mkdir -p /chroot/apache2/lib/i686/cmov/
# cp
/usr/lib/libpcre.so.3 /chroot/apache2/usr/lib/
# cp /usr/lib/libaprutil-1.so.0 /chroot/apache2/usr/lib/
# cp /usr/lib/libapr-1.so.0 /chroot/apache2/usr/lib/
# cp /lib/i686/cmov/libpthread.so.0 /chroot/apache2/lib/i686/cmov/
# cp
/lib/i686/cmov/libc.so.6 /chroot/apache2/lib/i686/cmov/
# cp /usr/lib/libldap_r-2.4.so.2 /chroot/apache2/usr/lib/
# cp /usr/lib/liblber-2.4.so.2 /chroot/apache2/usr/lib/
# cp /usr/lib/libdb-4.6.so /chroot/apache2/usr/lib/
# cp /usr/lib/libpq.so.5 /chroot/apache2/usr/lib/
# cp /usr/lib/libmysqlclient_r.so.15 /chroot/apache2/usr/lib/
# cp /usr/lib/libsqlite3.so.0 /chroot/apache2/usr/lib/
# cp /usr/lib/libexpat.so.1 /chroot/apache2/usr/lib/
# cp /lib/libuuid.so.1 /chroot/apache2/lib/
# cp /lib/i686/cmov/librt.so.1 /chroot/apache2/lib/i686/cmov/
# cp /lib/i686/cmov/libcrypt.so.1 /chroot/apache2/lib/i686/cmov/
# cp /lib/i686/cmov/libdl.so.2 /chroot/apache2/lib/i686/cmov/
# cp /lib/ld-linux.so.2 /chroot/apache2/lib/
# cp /lib/i686/cmov/libresolv.so.2 /chroot/apache2/lib/i686/cmov/
# cp
/usr/lib/libsasl2.so.2 /chroot/apache2/usr/lib/
# cp /usr/lib/libgnutls.so.26 /chroot/apache2/usr/lib/
# cp /usr/lib/i686/cmov/libssl.so.0.9.8 /chroot/apache2/usr/lib/i686/cmov/
# cp /usr/lib/i686/cmov/libssl.so.0.9.8 /chroot/apache2/usr/lib/i686/cmov/
# cp /usr/lib/i686/cmov/libcrypto.so.0.9.8 /chroot/apache2/usr/lib/i686/cmov/
# cp /usr/lib/libkrb5.so.3 /chroot/apache2/usr/lib/
# cp /lib/libcom_err.so.2 /chroot/apache2/lib/
# cp /usr/lib/libgssapi_krb5.so.2 /chroot/apache2/usr/lib/
# cp /lib/i686/cmov/libnsl.so.1 /chroot/apache2/lib/i686/cmov/
# cp /lib/i686/cmov/libm.so.6 /chroot/apache2/lib/i686/cmov/
# cp /usr/lib/libz.so.1 /chroot/apache2/usr/lib/
# cp /usr/lib/libtasn1.so.3 /chroot/apache2/usr/lib/
# cp /usr/lib/libgpg-error.so.0 /chroot/apache2/usr/lib/
# cp /usr/lib/libgcrypt.so.11 /chroot/apache2/usr/lib/
# cp /usr/lib/libk5crypto.so.3 /chroot/apache2/usr/lib/
# cp /usr/lib/libkrb5support.so.0 /chroot/apache2/usr/lib/
# cp /lib/libkeyutils.so.1 /chroot/apache2/lib/
Outras
Libs necessárias :
# cp /usr/lib/libxml2.so /chroot/apache2/usr/lib
# cp /usr/lib/liblua5.1.so.0 /chroot/apache2/usr/lib/
# cp /usr/lib/libcurl.so /chroot/apache2/usr/lib/
# cp /usr/lib/libidn.so.11 /chroot/apache2/usr/lib/
# cp /lib/libbz2.so.1.0 /chroot/apache2/lib/
# cp /lib/libgcc_s.so.1 /chroot/apache2/lib/
Agora,
vamos mover as pastas do sistema para a jaula, depois iremos linká-las para o
local de origem.
# mkdir /chroot/apache2/etc
# mv /etc/apache2 /chroot/apache2/etc
# ln -s /chroot/apache2/etc/apache2
/etc/apache2
# mv /usr/lib/apache2 /chroot/apache2/usr/lib/
# ln -s
/chroot/apache2/usr/lib/apache2 /usr/lib/apache2
# mkdir –p /chroot/apache2/var
# mkdir -p /chroot/apache2/var/run/
# mkdir –p /chroot/apache2/var/log/apache2
# mv /var/www /chroot/apache2/var
# ln –s /chroot/apache2/var/www /var/www
# cp /etc/nsswitch.conf /chroot/apache2/etc/
É preciso modificar o arquivo nsswitch.conf para que ele busque apenas dos arquivos, os passwords e informações de usuários.
# vi
/chroot/apache2/etc/nsswitch.conf
|
passwd:
files |
# cp /lib/libnss_files.so.2
/chroot/apache2/lib
Aqui colocaremos o usuário que irá startar o apache.
# echo
"www-data:x:33:33:www-data:/:/sbin/nologin" >
/chroot/apache2/etc/passwd
# echo "www-data:x:33:" > /chroot/apache2/etc/group
# cp /lib/libnss_dns.so.2 /chroot/apache2/lib
# cp /etc/hosts /chroot/apache2/etc
# cp /etc/resolv.conf /chroot/apache2/etc
# cp /etc/mime.types /chroot/apache2/etc/
# mkdir /chroot/apache2/dev
# mknod –m 666 /chroot/apache2/dev/null c 1 3
# mknod –m 666 /chroot/apache2/dev/zero c 1 5
# mknod –m 666 /chroot/apache2/dev/random c 1 8
# mkdir /chroot/apache2/tmp
# chmod +t /chroot/apache2/tmp
# chmod 777 /chroot/apache2/tmp
4.5 Ajuste da hora do Servidor
No meu
caso, como uso o horário de Belém, simplesmente copiei a minha zona para o
arquivo localtime dentro da jaula.
# cp /usr/share/zoneinfo/America/Belem
/chroot/apache2/etc/localtime
Para que o procedimento de log rotate continue funcionando, vamos ter que alterar o caminho dos logs no arquivo de configuração do Apache, dentro do logrotate.
# vim /etc/logrotate.d/apache2
|
/chroot/apache2/var/log/apache2/*.log
{ |
Rode o
comando para testar o carregamento do apache enjaulado
# chroot /chroot/apache2 /usr/sbin/apache2
apache2: Could not reliably determine the server's fully qualified domain name,
using 127.0.1.1 for ServerName
Caso apresente erros, investigue para ver o que ocorre, procure nos logs, senão rode o comando strace para analisar aonde está o problema.
Caso não apresente erros, para ele para que possamos prosseguir com as configurações.
# chroot /chroot/apache2 /usr/sbin/apache2 -k stop
Após feita a configuração iremos criar o script de inicialização para startar o
apache em modo chroot e desativar o script default do Debian. Depois iremos
startar o Apache e verificar se há algum erro nos logs.
# vi /etc/init.d/apache2-enjaulado
|
#!/bin/sh CHROOT=/chroot/apache2 APACHE=/usr/sbin/apache2 PIDFILE=/var/run/apache2.pid echo -n " apache 2" case "$1" in start) /usr/sbin/chroot $CHROOT $APACHE ;; stop) kill `cat ${CHROOT}/${PIDFILE}` ;; *) echo "" echo "Usage: `basename $0` {start|stop}" >&2 exit 64 ;; esac exit 0 |
# chmod +x /etc/init.d/apache2-enjaulado
# /etc/init.d/apache2-enjaulado start
# /etc/init.d/apache2-enjaulado stop
# update-rc.d -f apache2 remove
Removing any system startup links for /etc/init.d/apache2 ...
/etc/rc0.d/K09apache2
/etc/rc1.d/K09apache2
/etc/rc2.d/S91apache2
/etc/rc3.d/S91apache2
/etc/rc4.d/S91apache2
/etc/rc5.d/S91apache2
/etc/rc6.d/K09apache2
# update-rc.d -f apache2-enjaulado defaults
Adding
system startup for /etc/init.d/apache2-enjaulado ...
/etc/rc0.d/K20apache2-enjaulado -> ../init.d/apache2-enjaulado
/etc/rc1.d/K20apache2-enjaulado -> ../init.d/apache2-enjaulado
/etc/rc6.d/K20apache2-enjaulado -> ../init.d/apache2-enjaulado
/etc/rc2.d/S20apache2-enjaulado -> ../init.d/apache2-enjaulado
/etc/rc3.d/S20apache2-enjaulado -> ../init.d/apache2-enjaulado
/etc/rc4.d/S20apache2-enjaulado -> ../init.d/apache2-enjaulado
/etc/rc5.d/S20apache2-enjaulado -> ../init.d/apache2-enjaulado
# /etc/init.d/apache2-enjaulado
start
apache 2apache2: Could not reliably determine the server's fully
qualified domain name, using 127.0.1.1 for ServerName
# ps aux |
grep apache
root 2120 1.0 3.1 24064
8064 ? Ss
15:35 0:00 /usr/sbin/apache2
www-data 2121 0.0 2.1 24064 5568
? S
15:35 0:00 /usr/sbin/apache2
www-data 2122 0.0 2.1 24064 5568
? S
15:35 0:00 /usr/sbin/apache2
www-data 2123 0.0 2.1 24064 5568
? S
15:35 0:00 /usr/sbin/apache2
www-data 2124 0.0 2.1 24064 5568
? S
15:35 0:00 /usr/sbin/apache2
www-data 2125 0.0 2.1 24064 5568
? S
15:35 0:00 /usr/sbin/apache2
root 2127 0.0 0.2
3116 716 pts/0 S+ 15:35
0:00 grep apache
# tail /chroot/apache2/var/log/apache2/error.log
Apache/2.2.0 (Fedora) configured -- resuming normal operations
[Thu Jul 30 20:30:01 2009] [notice] caught SIGTERM, shutting down
[Thu Jul 30 20:35:31 2009] [notice] ModSecurity for Apache/2.5.9
(http://www.modsecurity.org/) configured.
[Thu Jul 30 20:35:31 2009] [notice] Original server signature: Apache/2.2.9
(Debian)
[Thu Jul 30 20:35:32 2009] [notice] Apache/2.2.9 (Debian) PHP/5.2.6-1+lenny3
with Suhosin-Patch Apache/2.2.0 (Fedora) configured -- resuming normal operations
6. Chroot do PHP
Para "chrootar" o PHP é preciso copiar o módulo, as bibliotecas e o
arquivo de configuração para a jaula do Apache. Como, na configuração do
Apache, já copiamos algumas coisas que o php também utilizará, mas vamos ver o
que ficou faltando.
Como movemos a pasta de módulos do apache para a jaula, o módulo do php já está
dentro da jaula. Vamos verificar quais bibliotecas ainda não foram adicionadas
para a jaula e em seguida copiá-las para lá.
# cat
/chroot/apache2/etc/apache2/mods-available/php5.load
LoadModule php5_module /usr/lib/apache2/modules/libphp5.so
# ldd /usr/lib/apache2/modules/libphp5.so
linux-gate.so.1 => (0xb7f00000)
libcrypt.so.1
=> /lib/i686/cmov/libcrypt.so.1 (0xb798e000)
libz.so.1 => /usr/lib/libz.so.1 (0xb7979000)
libssl.so.0.9.8 => /usr/lib/i686/cmov/libssl.so.0.9.8
(0xb7932000)
libdb-4.6.so => /usr/lib/libdb-4.6.so (0xb77ff000)
libbz2.so.1.0 => /lib/libbz2.so.1.0 (0xb77ef000)
libpcre.so.3 => /usr/lib/libpcre.so.3 (0xb77c6000)
libresolv.so.2 => /lib/i686/cmov/libresolv.so.2
(0xb77b2000)
libm.so.6 =>
/lib/i686/cmov/libm.so.6 (0xb778c000)
libdl.so.2 => /lib/i686/cmov/libdl.so.2 (0xb7787000)
libnsl.so.1 => /lib/i686/cmov/libnsl.so.1 (0xb776e000)
libgssapi_krb5.so.2
=> /usr/lib/libgssapi_krb5.so.2 (0xb7744000)
libkrb5.so.3 => /usr/lib/libkrb5.so.3 (0xb76b0000)
libk5crypto.so.3 => /usr/lib/libk5crypto.so.3
(0xb768c000)
libcom_err.so.2 => /lib/libcom_err.so.2 (0xb7689000)
libxml2.so.2 =>
/usr/lib/libxml2.so.2 (0xb754f000)
libc.so.6 => /lib/i686/cmov/libc.so.6 (0xb73f4000)
libcrypto.so.0.9.8 =>
/usr/lib/i686/cmov/libcrypto.so.0.9.8 (0xb72a1000)
libpthread.so.0 => /lib/i686/cmov/libpthread.so.0
(0xb7288000)
/lib/ld-linux.so.2 (0xb7f01000)
libkrb5support.so.0 => /usr/lib/libkrb5support.so.0
(0xb7280000)
libkeyutils.so.1
=> /lib/libkeyutils.so.1 (0xb727c000)
No meu caso, apenas duas libs não foram copiadas para a jaula, caso você
tenha mais recursos em seu PHP, pode ser que seja preciso copiar mais libs.
# cp /lib/i686/cmov/libm.so.6
/chroot/apache2/lib/i686/
# cp /usr/lib/libxml2.so.2 /chroot/apache2/usr/lib/
Vamos nos certificar de que a
biblioteca do MySQL já foi copiada:
# ls /chroot/apache2/usr/lib/ | grep
mysql
libmysqlclient_r.so.15
Por default, o módulo php5 busca as configurações no arquivo php.ini, que
fica armazenado na pasta "/etc/php5/apache2". Vamos copiar a pasta do
PHP para dentro da pasta /chroot, assim como outras pastas necessárias.
# mv /etc/php5/ /chroot/apache2/etc/
# ln -s /chroot/apache2/etc/php5/ /etc/php5
# mkdir /chroot/apache2/var/lib/
# mv /var/lib/php5/ /chroot/apache2/var/lib/
# ln -s /chroot/apache2/var/lib/php5/ /var/lib/php5
# chmod 1733 /chroot/apache2/var/lib/php5
# mv /usr/lib/php5/ /chroot/apache2/usr/lib/
# ln -s /chroot/apache2/usr/lib/php5/ /usr/lib/php5
Para o MySQL o processo é semelhante do Apache. Só que vamos enjaulá-lo em “/chroot/mysql”. Essa jaula será totalmente independente da jaula do Apache. Para que o php comunique com o Banco de dados MySQL iremos criar um link simbólico entre eles.
Vamos pesquisar os arquivos e as libs necessárias para seu funcionamento. Depois vamos criar uma outra jaula independente da jaula do Apache. Aí então vamos criar sua estrutura e copiar os arquivos para dentro dela.
7.1 Instalação do MySQL
# aptitude install mysql-server
# /etc/init.d/mysql stop
# whereis mysql-common
mysql-common:
/usr/share/mysql-common
# whereis mysql
mysql:
/usr/bin/mysql /etc/mysql /usr/lib/mysql /usr/include/mysql /usr/share/mysql
/usr/share/man/man1/mysql.1.gz
# whereis mysqld
mysqld:
/usr/sbin/mysqld /usr/share/man/man8/mysqld.8.gz
# mknod
/chroot/mysql/dev/null c 2 2
# mkdir -p /chroot/mysql/dev
# mkdir -p /chroot/mysql/etc
# mkdir -p /chroot/mysql/tmp
# mkdir -p /chroot/mysql/usr/bin
# mkdir -p /chroot/mysql/usr/sbin/
# mkdir -p /chroot/mysql/var/lib/
# mkdir -p /chroot/mysql/var/tmp/
# mkdir -p /chroot/mysql/lib/i686/cmov
# mkdir -p /chroot/mysql/var/run/mysqld
# mkdir -p /chroot/mysql/var/log/mysql
# mv /etc/mysql /chroot/mysql/etc/
# ln -s /chroot/mysql/etc/mysql/ /etc/mysql
# mkdir -p /chroot/mysql/usr/lib/
# mv /usr/lib/mysql/
/chroot/mysql/usr/lib/
# ln -s
/chroot/mysql/usr/lib/mysql/ /usr/lib/mysql
# mkdir -p
/chroot/mysql/usr/share/
# mv /usr/share/mysql
/chroot/mysql/usr/share/
# ln -s
/chroot/mysql/usr/share/mysql/ /usr/share/mysql
# mkdir -p /chroot/mysql/var/lib/
# mv /var/lib/mysql/ /chroot/mysql/var/lib/
# ln -s /chroot/mysql/var/lib/mysql/ /var/lib/
# cp /usr/sbin/mysqld /chroot/mysql/usr/sbin/
# cp
/etc/hosts /chroot/mysql/etc/
# cp /etc/host.conf /chroot/mysql/etc/
# cp /etc/resolv.conf /chroot/mysql/etc/
# cp /etc/nsswitch.conf /chroot/mysql/etc/
# cp /lib/libnss_files.so.2 /chroot/mysql/lib/
# echo "mysql:x:105:108:MySQL Server,,,:/var/lib/mysql:/bin/false" > /chroot/mysql/etc/passwd
# echo "mysql:x:108:" > /chroot/mysql/etc/group
# vi /chroot/mysql/etc/nsswitch.conf
|
passwd:
files |
# ldd /usr/sbin/mysqld
linux-gate.so.1 => (0xb7f1c000)
librt.so.1 => /lib/i686/cmov/librt.so.1 (0xb7f0c000)
libz.so.1 => /usr/lib/libz.so.1 (0xb7ef7000)
libwrap.so.0 => /lib/libwrap.so.0 (0xb7eee000)
libdl.so.2 => /lib/i686/cmov/libdl.so.2 (0xb7eea000)
libpthread.so.0 => /lib/i686/cmov/libpthread.so.0 (0xb7ed1000)
libcrypt.so.1 => /lib/i686/cmov/libcrypt.so.1 (0xb7e9f000)
libnsl.so.1 => /lib/i686/cmov/libnsl.so.1 (0xb7e86000)
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0xb7d98000)
libm.so.6 => /lib/i686/cmov/libm.so.6 (0xb7d71000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0xb7d64000)
libc.so.6 => /lib/i686/cmov/libc.so.6 (0xb7c09000)
/lib/ld-linux.so.2 (0xb7f1d000)
# cp
/usr/lib/libstdc++.so.6 /chroot/mysql/usr/lib/
# cp /usr/lib/libz.so.1
/chroot/mysql/usr/lib/
# cp /lib/libwrap.so.0
/chroot/mysql/lib/
# cp /lib/libgcc_s.so.1
/chroot/mysql/lib/
# cp /lib/ld-linux.so.2
/chroot/mysql/lib/
# cp
/lib/i686/cmov/libdl.so.2 /chroot/mysql/lib/i686/cmov/libdl.so.2
# cp
/lib/i686/cmov/libpthread.so.0 /chroot/mysql/lib/i686/cmov/
# cp
/lib/i686/cmov/libcrypt.so.1 /chroot/mysql/lib/i686/cmov/
# cp
/lib/i686/cmov/libnsl.so.1 /chroot/mysql/lib/i686/cmov/
# cp /lib/i686/cmov/librt.so.1 /chroot/mysql/lib/i686/cmov/
# cp
/lib/i686/cmov/libm.so.6 /chroot/mysql/lib/i686/cmov/
# cp
/lib/i686/cmov/libc.so.6 /chroot/mysql/lib/i686/cmov/libc.so.6
# chmod -R 755
/chroot/mysql
# chown -R mysql.mysql /chroot/mysql
# chmod 1777 /chroot/mysql/tmp
# chmod 1777 /chroot/mysql/var/tmp
# chmod 600
/chroot/mysql/var/lib/mysql/mysql_upgrade_info
# chmod 644 /chroot/mysql/var/lib/mysql/debian-5.0.flag
# chmod 660 /chroot/mysql/var/lib/mysql/ib*
# chmod 660 /chroot/mysql/var/lib/mysql/ibdata1
# chmod 660 /chroot/mysql/var/lib/mysql/ib_logfile*
# chmod -R 777 /chroot/mysql/var/run/mysqld/
7.2
Testando o início do MySQL
# chroot
/chroot/mysql/ /usr/sbin/mysqld
Para conectar na console do MySQL, não se esqueça de colocar o parâmetro “socket” e informar a localização, que é dento da jaula.
# mysql -u root -p123
--socket=/chroot/mysql/var/run/mysqld/mysqld.sock
Caso dê algum erro de execução, tente rodar o comando "strace" para
analisar o que está ocorrendo.
# strace chroot /chroot/mysql/
/usr/sbin/mysqld
7.3 Removendo o script de Inicialização
# update-rc.d -f mysql remove
Removing any system startup links for /etc/init.d/mysql ...
/etc/rc0.d/K21mysql
/etc/rc1.d/K21mysql
/etc/rc2.d/S19mysql
/etc/rc3.d/S19mysql
/etc/rc4.d/S19mysql
/etc/rc5.d/S19mysql
/etc/rc6.d/K21mysql
#
update-rc.d -f mysql-ndb remove
(...)
# update-rc.d -f mysql-ndb-mgm remove
(...)
Script baixado de http://www.securityfocus.com/unix/images/mysql.sh e modificado para a configuração desse artigo
# vim /etc/init.d/mysql-enjaulado
|
#!/bin/sh
echo -n " mysql" case "$1" in start) chroot /chroot/mysql/ /usr/sbin/mysqld > /dev/null 2>&1 & sleep 5 rm -f /chroot/apache2/tmp/mysql.sock ln /chroot/mysql/var/run/mysqld/mysqld.sock /chroot/apache2/tmp/ ;; stop) kill `cat /chroot/mysql/var/run/mysqld/mysqld.pid` ;; *) echo "" echo "Usage: `basename $0` {start|stop}" >&2 exit 64 ;; esac exit 0 |
# chmod +x /etc/init.d/mysql-enjaulado
#
update-rc.d mysql-enjaulado defaults
(...)
# vi /chroot/mysql/etc/mysql/my.cnf
|
[client] port = 3306 socket = /var/run/mysqld/mysqld.sock [mysqld_safe] socket = /var/run/mysqld/mysqld.sock nice = 0 [mysqld] user = mysql pid-file = /var/run/mysqld/mysqld.pid socket = /var/run/mysqld/mysqld.sock port = 3306 basedir = /usr datadir = /var/lib/mysql tmpdir = /tmp language = /usr/share/mysql/english skip-external-locking bind-address = 127.0.0.1 skip-networking set-variable=local-infile=0 key_buffer = 16M max_allowed_packet = 16M thread_stack = 128K thread_cache_size = 8 myisam-recover = BACKUP query_cache_limit = 1M query_cache_size = 16M expire_logs_days = 10 max_binlog_size = 100M skip-bdb [mysqldump] quick quote-names max_allowed_packet = 16M [mysql] [isamchk] key_buffer = 16M
!includedir /etc/mysql/conf.d/ |
Para que o PHP consiga conectar no MySQL, no script de execução do MySQL, foi colocado uma linha que faz um hard link do arquivo “/chroot/mysql/var/run/mysqld/mysql.sock”, que está na jaula do MySQL para a jaula do Apache, em “/chroot/apache2/tmp”.
Depois temos que configurar no “php.ini” para ele buscar o socket do MySQL nesse caminho (/chroot/apache2/tmp).
# vim
/etc/php5/apache2/php.ini
|
[MySQL] mysql.default_socket = /tmp/mysqld.sock
|
O PHPMyADmin é a interface que irá ser usada para que o programador possa fazer modificações no banco MySQL. Iremos configurá-lo e limitar o seu acesso.
Vamos instalá-lo e depois restringir o seu acesso, colocando o IP da máquina que irá acessar no arquivo de configuração.
# aptitude install phpmyadmin
# mv /etc/phpmyadmin/ /chroot/apache2/etc/
# ln -s /chroot/apache2/etc/phpmyadmin/ /etc/phpmyadmin
# cp -ra /usr/share/phpmyadmin/ /chroot/apache2/usr/share/
# cat /var/lib/phpmyadmin/blowfish_secret.inc.php > /chroot/apache2/etc/phpmyadmin/blowfish_secret.inc.php
# vi /chroot/apache2/usr/share/phpmyadmin/config.inc.php
|
<?php |
# vi /etc/phpmyadmin/apache.conf
|
Alias /phpmyadmin /usr/share/phpmyadmin <Directory /usr/share/phpmyadmin> Options Indexes FollowSymLinks DirectoryIndex index.php Order deny,allow Deny from all Allow from 192.168.20.1/255.255.255.0 # Authorize for setup <Files setup.php> # For Apache 1.3 and 2.0 <IfModule mod_auth.c> AuthType Basic AuthName "phpMyAdmin Setup" AuthUserFile /etc/phpmyadmin/htpasswd.setup </IfModule> # For Apache 2.2 <IfModule mod_authn_file.c> AuthType Basic AuthName "phpMyAdmin Setup" AuthUserFile /etc/phpmyadmin/htpasswd.setup </IfModule> Require valid-user </Files> <IfModule mod_php4.c> AddType application/x-httpd-php .php php_flag magic_quotes_gpc Off php_flag track_vars On php_flag register_globals Off php_value include_path . </IfModule> <IfModule mod_php5.c> AddType application/x-httpd-php .php php_flag magic_quotes_gpc Off php_flag track_vars On php_flag register_globals Off php_value include_path . </IfModule> </Directory> |
Em relação ao Web Server existem duas ferramentas interessantes, uma para monitoramento e a outra para mostrar estatísticas de acesso e outras informações interessantes.
# aptitude
install apachetop
# apachetop
# aptitude
install wwwstat
Modifique os arquivos de configuração para que ele leia os logs na jaula do
Apache
# vi /etc/wwwstat/wwwerrs.rc
|
$ErrorLog = '/chroot/apache2/var/log/apache/error.log';
# Server's Error Log |
# vi monthly.rc
|
$zcommand = 'gzip -9'; |
# vi /usr/sbin/wwwstat
|
# Specify the default location of your access log |
# wwwstat >
/var/www/wwwstat.html
Depois é
s'acessar o endereço http://www.domain.com/wwwstat.html
Para a configuração do Firewall, vamos abrir a porta 80 onde o servidor receberá as requisições Web e a porta 3322 onde abriremos somente para o desktop do administrador a conexão ssh.
# vim
/etc/firewall.sh
|
#!/bin/bash
|
Aqui iremos configurar a rede e carregar o firewall em sua configuração.
# vim /etc/network/interfaces
|
auto lo |
13.1 Publicação de páginas via SSH
Ao invés de configurarmos um serviço FTP para a equipe de desenvolvimento possa pubicar e fazer alterações nos sites, nós iremos configurar o serviço de SSH para fazer essa função. Para isso criaremos um grupo chamado “sftpusers” que irá conter os usuários que terão permissão de logar via secure FTP.
# addgroup
sftusers
Adding group `sftponly' (GID 1003) ...
Done.
Depois iremos configurar o SSH para essa função:
Adicione as seguintes linhas no fim do arquivos /etc/ssh/sshd_config :
|
Match group sftpusers |
Depois
modifique a linha
“Subsystem sftp /usr/lib/openssh/sftp-server”
Para :
“Subsystem sftp internal-sftp “
Todo usuário que pertencer ao grupo “sftpusers” irá ter permissão de logar via ssh e cair enjaulado no seu próprio “home”. Vamos criar o usuário “programador01”, assim como adicioná-lo ao grupo sftpusers e criar o seu home.
# adduser programador01
Adding user ` programador01' ...
Adding new
group ` programador01' (1002) ...
Adding new user ` programador01' (1002) with group ` programador01' ...
Creating home directory `/home/ programador01' ...
Copying files from `/etc/skel' ...
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
Changing the
user information for programador01
Enter the new value, or press ENTER for the default
Full Name []: Programador 01
Room Number []:
Work Phone []:
Home Phone []:
Other []:
Is the information correct? [Y/n] y
# chown root.root
/home/programador01
# usermod -d /home/
programador01 programador01
# adduser programador01 sftpusers
$ sftp programador01@host
Connecting to host...
user@host's password:
sftp> pwd
Remote working directory: /
sftp> cd ..
13.3 Montando a pasta do Site para o programador
Agora, o usuário “programador01” cai em engaiolado em sua home, no entanto, não enxerga a pasta “/var/www” ou o site dentro dela que ele deverá alterar.
Vamos supor que ele precise alterar paginas dentro de “/chroot/apache2/var/www/joomla”. Vamos supor também que a pasta joomla já tem as permissões acertadas para o usuário programador01.
Para
resolver essa questão iremos “criar um link” com o comando “mount --bind”.
# mkdir /home/programador01/joomla
# mount
--bind
/chroot/apache2/var/www/joomla
/home/programador01/joomla
Assim, quando o usuário logar e cair em seu diretório “home” ele irá ver a pasta joomla e poderá fazer as alterações necessárias.
Depois é só salvar o comando “mount” no /etc/rc.local
# vim /etc/rc.local
mount --bind /chroot/apache2/var/www/joomla /home/programador01/joomla
# vim
/etc/rc.local
|
mount --bind /chroot/apache2/var/www/joomla /home/programador01/joomla |
13.4 Fazendo mais ajustes no SSH
Agora chegou a hora de fazer alguns ajustes na configuração do SSH, principalmente no que diz respeito à segurança.
Como não utilizo o ipv6, eu desabilito ele no ssh colocando a linha
“AddressFamily inet “
Aproveito também para desabilitar do sistema, inserindo duas linhas no arquivo “/etc/modprobe.d/aliases”:
# vim /etc/modprobe.d/aliases
|
alias net-pf-10 off alias ipv6 off |
Outros parâmetros interessantes são o Timeout por uma sessão inativa por 5 minutos e o encaminhamento de portas:
|
ClientAliveInterval 300
AllowTcpForwarding
no |
Vamos modificar também a porta default e configurar quem terá acesso ao SSH do Servidor:
|
Port 3322
PermitRootLogin no AllowUsers tulio programador01 |
Um fator importante que pode ser colocado é um host IDS. Eu uso o Ossec
Bom, chegamos ao final, espero ter ajudado na configuração de seu servidor Web. Por favor, qualquer crítica fique a vontade para deixar aqui (tem que logar com uma conta do google) ou envie um email para matulio at gmail dot com.
Referencias
Mod Security
http://jcksn.com/tools/modsecurity/
http://atomicplayboy.net/blog/2005/01/30/an-introduction-to-mod-security/
http://onlamp.com/lpt/a/4378
http://www.modsecurity.org/documentation/index.html
http://grepanswers.blogspot.com/2009/04/compiling-modsecurity.html
http://isp-control.net/documentation/howto/security/mod_security_on_debian
Apache 2
Security Configuration Benchmarck for Apache Web Server 2.2.0 – The Center for Internet Security
Apache Cookbook, Second Edition – O Reilly - Rich Bowen, Ken Coar
Apache Security – O Reilly – Ivan Ristic
http://httpd.apache.org/docs/2.2/
http://www.debianadmin.com/install-and-configure-apache2-with-php5-and-ssl-support-in-debian-etch.html
http://www.debian-administration.org/article/Setting_up_an_SSL_server_with_Apache2
http://www.ianmiller.net/article.php?id=13
http://www.cs.helsinki.fi/u/janmatti/chrootapache2-howto.html
http://httpd.apache.org/docs/2.2/howto/auth.html
http://httpd.apache.org/docs/2.2/en/howto/htaccess.html
PHP
Programming PHP, second Edition – Kevin Tatroe, Rasmus Lerdorf
http://phpsec.org/projects/guide/
http://phpsec.org/php-security-guide.pdf
http://wiki.debian.org/PHP
http://www.phpbuilder.com/manual/en/install.unix.debian.php
http://www.hardened-php.net/
http://www.madirish.net/?article=229
http://www.securityfocus.com/infocus/1706
http://www.askapache.com/php/custom-phpini-tips-and-tricks.html
http://25yearsofprogramming.com/blog/20070808.htm
http://aymanh.com/checklist-for-securing-php-configuration
http://www.hardened-php.net/suhosin/
http://www.hardened-php.net/suhosin/configuration.html
http://www.howtoforge.com/suhosin_php_debian_etch_ubuntu
http://www.howtoforge.com/suhosin_php_debian_etch_ubuntu_p2
http://www.phpbuilder.com/manual/features.safe-mode.functions.php
MySQL
Learning MySQL – O´Reilly – Hugh Williams, Seyed Tahaghoghi
http://dev.mysql.com/doc/
http://www.securityfocus.com/infocus/1726
http://www.linuxquestions.org/questions/linux-security-4/short-howto-chrooting-mysql-34338/
http://www.uno-code.com/?q=node/11
http://blog.blackdown.de/2005/03/04/chrooting-mysql-on-debian/
http://dev.mysql.com/doc/refman/5.0/en/security.html
http://blog.blackdown.de/2006/12/30/chrooting-recent-mysql-versions-on-debian-and-ubuntu/
http://blog.blackdown.de/static/mysql-chroot
SSH
http://www.openssh.com/manual.html
http://www.linux.com/archive/articles/61061
http://www.cyberciti.biz/tips/linux-unix-bsd-openssh-server-best-practices.html
http://www.debian-administration.org/articles/590
PHPMyAdmin
http://www.phpmyadmin.net/documentation/
http://www.phpmyadmin.net/home_page/index.php
