LAMP em Debian 8
3 Maio 2016A necessidade aguça o engenho, e de repente, precisei de montar um servidor LAMP, e como sempre, decidi usar Debian 8, pois já estou mais que acostumado a trabalhar com este SO. Outra das necessidades é ter sempre pronta uma snapshot (servidores virtuais é uma maravilha, já tinha dito?) deste deployment para quando for preciso um servidor de teste para a empresa (bastando repor o snapshot para o ter pronto desde a raiz).
Raspberry Pi
Para quem quer trabalhar com RPi, usem raspbian-ua-netinst que facilita bastante o trabalho de instalação. Basta descarregar e passar para o cartão SD com o Win32Disk Imager. Aconselho descarregar o ficheiro raspbian-ua-netinst-v1.x.x.img.bz2 e depois descompactar com o 7zip.
Para os mais avançados, existem duas distribuições para as duas versões (ver aqui), a armel (Rasp v1) e a armhf (Rasp v2). Fiz uso obviamente das versões mais mini, a netinstall igualmente disponível na página de descarregamentos. Escolham as que estão disponíveis debaixo de “CDs pequenos”.
Para escrever para o SD, usar o Win32Disk Imager. Não esquecer de usar uma partição/formatar o SD em FAT32.
Configuração de rede
Visto que este irá ser um servidor empresarial convém o mais possível que o IP seja fixo (até porque vão precisar dele fixo mais tarde). Usei a ajuda da Debian para o fazer, disponível aqui.
Para definir o IP fixo, editar:
nano /etc/network/interfaces
E depois definir à eth0 os seguintes valores (substituir pelos vossos):
PS: No Ubuntu14.x e Debian 8 é provável que encontrem algum texto novo, colocar a configuração estática debaixo de: “source-directory /etc/network/interfaces.d”.
allow-hotplug eth0 auto eth0 iface eth0 inet static address 10.0.0.35 netmask 255.255.255.0 gateway 10.0.0.1 network 10.0.0.0 broadcast 10.0.0.255
A seguir convém sempre reiniciar a placa de rede para ela poder assumir o IP atribuído:
ifdown eth0 ifup eth0
Em alguns casos será também boa ideia definir os servidores de resolução de nomes:
nano /etc/resolv.conf
E adicionar os seguintes, OpenDNS e Google DNS, respectivamente alterando:
nameserver 208.67.222.222 nameserver 8.8.8.8 nameserver 208.67.220.220 nameserver 8.8.4.4
SSH
Se já estão a usar a versão Jenny do Debian, cuidado que o acesso SSH remoto para root está fechado por defeito. Se o quiserem abrir, o que não é recomendável senão apenas enquanto estão a fazer a instalação, deverão aceder à configuração do SSH:
nano /etc/ssh/sshd_config
e alterando a seguinte linha de:
PermitRootLogin without-password
para
PermitRootLogin yes
Por fim, reiniciar o servidor SSH
/etc/init.d/ssh restart
NOTA: Assumindo que querem sempre aceder por root, e que o vosso router não tenha a porta 22 aberta. Aconselha-se sempre a utilização de uma VPN para posterior acesso SSH, não deixem “tudo aberto”, facilitando os ataques. Mais tarde, após terminadas as configurações, fechar o acesso novamente.
Instalar o Apache
Se não instalaram o apache durante a instalação ( [X] webserver), há que o instalar agora. De notar que na versão Debian Whezzy será instalada a versão 2.2.x e no Debian Jenny será instalada a versão 2.4.x.
apt-get install apache2
PHP
Instalar o PHP é tão simples como:
apt-get install php5 php-pear php5-apcu php5-memcached memcached
Convém sempre fazer já algumas alterações que podem dar muito jeito, especialmente quando se trabalha com bases de dados de alguma dimensão, e plataformas como Zabbix, ownCloud, etc. Aceder ao ficheiro de configuração do PHP:
nano /etc/php5/apache2/php.ini
e inserir os seguintes valores:
max_execution_time = 300 memory_limit = 512M post_max_size = 512M upload_max_filesize = 512M max_input_time = 300 date.timezone = Europe/Lisbondatabase = Mysqlalways_populate_raw_post_data = -1
Se quiserem que o PHP fique optimizado no que à memoria diz respeito, podem fazer as seguintes alterações no:
nano /etc/php5/cli/php.ini
e depois acrescentar as linhas (depois de ;opcache.enable_cli=0):
;opcache.enable_cli=0 apc.enabled=1 apc.enable_cli=1
Base de dados MySQL
apt-get install php5-mysql mysql-server mysql-client
Para limpar bases de dados de testes e coisas afins:
mysql_secure_installation
Algumas configurações podem e devem de ser alteradas no ficheiro de configuração do mySQL para que sejam o mais similares possível às anteriores configurações do PHP. Portanto, aceder ao ficheiro:
nano /etc/mysql/my.cnf
e depois alterar para (o primeiro bind-address é o localhost, e o segundo bind-address deve ser o IP de rede do servidor). Também estou a utilizar alguns tweeks de performance como vi aqui:
# Instead of skip-networking the default is now to listen only on # localhost which is more compatible and is not less secure. bind-address = 127.0.0.1 bind-address = 10.0.0.15 # # * Fine Tuning # key_buffer = 512M max_allowed_packet = 512M thread_stack = 192K thread_cache_size = 8 max_connections = 500 table_cache = 1024 # thread's pelo número de cores thread_concurrency = 8 # # * Query Cache Configuration # query_cache_limit = 64M # * InnoDB # # InnoDB is enabled by default with a 10MB datafile in /var/lib/mysql/. # Read the manual for more InnoDB related options. There are many! # innodb_thread_concurrency = 0 innodb_read_io_threads = 64 innodb_write_io_threads = 64
Um dica, para no caso de terem as vossas próprias aplicações web a correr num servidor caseiro, é definir o max_statement_time (na versão 5.7.4)/ max_execution_time (na versão 5.7.8), o qual irá definir, em milissegundos, o tempo máximo de execução de cada SELECT. É especialmente útil para casos em que são efectuadas pesquisas dentro de uma tabela grande.
#mySQL v5.7.4 SET GLOBAL MAX_STATEMENT_TIME=2000; #mySQL v5.7.8 SET GLOBAL MAX_EXECUTION_TIME=2000;
Assim, será definido 2 segundos como o tempo máximo para cada SELECT. No entanto ainda é possível definir o tempo máximo para cada sessão especifica (no caso de vários utilizadores):
#mySQL v5.7.4 SET SESSION MAX_STATEMENT_TIME=2000; #mySQL v5.7.8 SET SESSION MAX_EXECUTION_TIME=2000;
Ainda é possível, em último caso, se não quiserem mexer nas definições do mySQL, usar esta definição dentro da propria query, como no seguinte exemplo:
#mySQL v5.7.4 SELECT MAX_STATEMENT_TIME=1000 * FROM table; #mySQL v5.7.8 SELECT MAX_EXECUTION_TIME=1000 * FROM table;
Configurar Acesso HTTPS/SSL
Seguindo este tutorial e este, consegui implementar facilmente o acesso através de HTTPS, torando o meu servidor bem mais seguro. Primeiro há que instalar o openSSL
apt-get install openssl
e de seguida activar o módulo SSL do apache.
a2enmod ssl
a2ensite default-ssl
a2enmod rewrite
Antes de criar o certificado, convém primeiro criar a pasta onde este irá ser instalado.
mkdir -p /etc/apache2/ssl
Agora podemos, sim, criar o certificado. De notar que pode ser dado outro nome à chave/certificado (apache.key e apache.crt respectivamente):
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/apache2/ssl/apache.key -out /etc/apache2/ssl/apache.crt
A pasta onde estão os certificados deverá ser sempre protegida:
sudo chmod 600 /etc/apache2/ssl/*
Para que o servidor passe a usar SSL na pasta default, há que configurar o default-ssl.conf:
nano /etc/apache2/sites-enabled/default-ssl.conf
E alterar os seguintes parâmetros (substituir pela vossa “pasta”):
<VirtualHost _default_:443>
ServerAdmin webmaster@localhost
ServerName example.com:443
DocumentRoot /var/www/html/<pasta>
....
SSLEngine on
SSLCertificateFile /etc/apache2/ssl/apache.crt
SSLCertificateKeyFile /etc/apache2/ssl/apache.key
<Directory /var/www/html/"pasta">
# AllowOverride All
AllowOverride AuthConfig
DirectoryIndex index.php
# Order allow,deny
# Require all granted
# Require all denied
Options All -Indexes
</Directory>
NOTA: em DocumentRoot podemos redireccionar logo para a pasta/sitio pretendido. De seguida bastará reiniciar o apache:
service apache2 restart
phpMyAdmin
Aproveitar para instalar também o phpMyAdmin, que para o qual usei este tutorial:
apt-get install mcrypt phpmyadmin
Uma das grandes preocupações que deve existir, é, configurar não só o acesso SSL:
nano /etc/phpmyadmin/config.inc.php
E adicionar a seguinte linha em “Server(s) configuration”
/** * Server(s) configuration */ $cfg['ForceSSL'] = 'true'; $i = 0;
mas também, sempre que possível, bloquear o acesso externo ao phpMyAdmin , desta forma aceder ao:
nano /etc/apache2/conf-available/phpmyadmin.conf
e adicionar as seguintes linhas:
<Directory /usr/share/phpmyadmin> Options FollowSymLinks DirectoryIndex index.php Deny from all Allow from 10.0.0.0/24
Permitindo assim apenas o acesso a partir da rede interna.
Assim que phpMyAdmin for instalado,e devidamente configurado, acho que é a altura certa para criar o snapshot, para mais tarde, se for necessário, repor a máquina virtual.
Redireccionamentos
Na pasta de raiz (/var/www/html) criar o ficheiro .htaccess:
touch .htaccess
Introduzir:
<IfModule mod_rewrite.c> RewriteEngine On RewriteCond %{HTTP_HOST} !^http://domain.tld$ [NC] RewriteRule ^(.*)$ https://futurcabo.no-ip.info:440/€ 0,91 (€0.87) [L,R=301]
E não esquecer de alterar as permissões do ficheiro:
chown -R www-data:www-data .htaccess
Copias de Segurança das BD’s
Recorri a vários tutoriais e a várias ideias para construir um sistema de copias de segurança simples. Um dos conselhos que posso dar é: nunca guardar as cópias apenas num sítio, e muito menos na própria máquina.
Para inicio do processo, quero aproveitar uma partilha de rede já existente onde já são efectuadas copias de segurança, no entanto essa partilha é em Windows Server, e requer algumas opções. O objectivo é fazer um mount point com essa partilha. Para isso vamos já criar uma pasta dentro de /mnt:
cd /mnt mkdir windowsserver
Agora podemos proceder ao mount da partilha, o qual aconselho que tenha obviamente <username>:<password> e respectivas permissões de leitura e escrita:
UPDATED [nova versão do cifs 2.0x / 3.16.0-4-amd64]
mount -vt cifs -o domain=meudominio.local,username=<username>,password='password',rw,nounix,iocharset=utf8,file_mode=0777,dir_mode=0777,sec=ntlm //10.0.0.50/BackupBD /mnt/windowsserver
onde “//10.0.0.50/Data/BackupBD” é o caminho de rede para a partilha no Windows Server.
O passo seguinte é criar um script bash que efectue alguns procedimentos:
cd /usr/local/sbin/ nano backupprocedure.sh
E introduzir o seguinte código que faz o seguinte:
- procura na pasta /var/tmp todos os ficheiros mais velhos que 7 dias e apaga-os
- faz o dump da base de dados, comprime em bzip2 com a data de hoje no nome e guarda em /var/tmp
- pega em todos os ficheiros .sql.bz2 com data de ontem para a frente e move para o mount da partilha
#!/bin/sh find /var/tmp/ -type f -mtime +7 -exec rm {} + mysqldump -u<user> -p<password> nome_da_bd | bzip2 > /var/tmp/nome_da_bd$(date +%F).sql.bz2 find /var/tmp/ -name "*.sql.bz2" -mtime -1 -print -exec mv {} /mnt/windowsserver\;
UPDATE: Entretanto tive a necessidade de aumentar o script e prever uma futura redundância na falha do servidor que actualmente disponibiliza o sistema. O objectivo é ter uma cópia com pelo menos 8h (ver hora do CronJob mais à frente) num servidor remoto, e numa emergência, poder redireccionar o trafego para este.
- O script vai ter de limpar todas as tabelas da base de dados remota, ignorando as chaves (aquando o DROP)
- O script vai trasportar integralmente a base de dados para o servidor remoto, mantendo as chaves
#!/bin/sh mysqldump -h$RDS_HOSTNAME -u$RDS_USERNAME -p$RDS_PASSWORD --add-drop-table --no-data $RDS_DB_NAME | grep -e '^DROP \| FOREIGN_KEY_CHECKS' | mysql -h$RDS_HOSTNAME -u$RDS_USERNAME -p$RDS_PASSWORD $RDS_DB_NAME mysqldump -u$localuser -p$localserverpassword $localdatabase | mysql -hremoteserver -uremoteuser -premoteserverpassword
Não esquecer de alterar as permissões ao ficheiro:
chmod +x /usr/local/sbin/backupprocedure.sh
Não esquecer de testar sempre o script, para ver se ele está realmente a fazer aquilo que é suposto:
cd /usr/local/sbin/.
/
backupprocedure.sh
Agora só falta criar um cronjob que corra este scrip, todos os dias por volta das 23h (meia hora antes da copia de segurança do Windows Server, que neste caso o intervalo de tempo chega):
crontab -e
e inserir a linha:
00 23 * * * bash /usr/local/sbin/backupprocedure.sh > /dev/null 2>&1
Mail / PHP Mail / SSMTP
Muitos de vós devem ter servidores LAMP como eu, caseiros, ou internos na empresa, mas que normalmente são secundários. O correio electrónico está sempre à responsabilidade de um servidor externo (alugado). O problema é quando é necessário enviar e-mails das aplicações/servidor internas para fora. Encontrei a solução aqui, visto que apenas preciso de um forward, e não propriamente um servidor SMTP interno.
ssmtp is a send-only sendmail emulator for machines which normally pick their mail up from a centralized mailhub (via pop, imap, nfs mounts or other means). It provides the functionality required for humans and programs to send mail via the standard or /usr/bin/mail user agents.
Ora, então, há que instalar primeiro o SSMTP.
apt-get install ssmtp
E começar a devida configuração:
nano /etc/ssmtp/ssmtp.conf
E alterar as seguintes linhas:
root=webmaster@domain ... mailhub=mail.domain.pt ... #este deve de ser o nome da máquina, que em principio está preenchido por defeito hostname=lamp.domain FromLineOverride=YES
Descomentar a última opção é importante, caso queiram/usem formulários em que o e-mail do remetente é automáticamente preenchido (cuidado com user error). Se o servidor requerer autenticação (inluindo Gmail), então as seguintes configurações deverão ser também introduzidas:
AuthUser=youremail@mail.tld
AuthPass=yourpassword
UseSTARTTLS=yes
UseTLS=yes
##Metodo de autenticação para Gmail
#AuthMethod=LOGIN
Caso definam a opção “FromLineOverride=NO”, terão que configurar o seguinte ficheiro:
nano /etc/ssmtp/revaliases
e alterar a seguinte linha para o e-mail a ser utilizado:
www-data:webmaster@example.com
Em principio, agora basta utilizar um qualquer formulário de contacto e o e-mail deverá ser enviado. Testem e vejam se não dá erro e se recebem (ver por vezes a caixa de spam).
Recursos
- websites/lamp/lamp-on-debian-8-jessie
- install-apache-with-php-and-mysql-lamp-on-debian-jessie
- how-do-i-enable-remote-access-to-mysql-database-server
- how-to-create-a-ssl-certificate-on-apache-for-debian-8
- possible-to-make-mysql-use-more-than-one-core/5670#5670
- tunning-mysql-innodb-performance
- backup-compactadoem-mysql-mysqldump-gzip-bzip2
- properly-mount-a-windows-share-to-move-files-on-the-mountpoint
- test-driving-shell-scripts–net
- proftpd-installation-on-debian-and-ubuntu
- How to Set Up PHP mail in Debian