Conexão PHP com o PostgreSQL (e o MySQL) no CentOS 7

Após a instalação do PHP, PostgreSQL e MySQL no CentOS 7, ao tentar fazer um simples teste de conexão do PHP com o PostgreSQL, estava recebendo a seguinte mensagem de erro:

Warning: pg_connect(): Unable to connect to PostgreSQL server: could not connect to server: Permission denied Is the server running on host “localhost” (127.0.0.1) and accepting TCP/IP connections on port 5432?

O código de teste foi o seguinte:

<?php

 $casa = "localhost";
 $banco = "nome_do_banco";
 $porta = 5432;
 $usuario = "nome_do_usuario";
 $senha = "senha_do_usuario";

 $conexao = pg_connect("host=$casa dbname=$banco port=$porta user=$usuario password=$senha");

 if (! $conexao ) {
 print "<h3>Não foi possível conectar ao PostgreSQL.</h3><br />";
 pg_errormessage();
 } else {
 pg_close($conexao);
 print "<h3>Conexão OK.</h3>";
 }

?>

Eu já tinha ajustado as configurações do pg_hba.conf e postgresql.conf e, mesmo assim, o PHP não conseguia estabelecer uma conexão com o PostgreSQL. Por segurança, chequei as regras do firewall e estavam todas corretas também.

Aí me lembrei: o SELinux! Será que o SELinux estaria bloqueando por padrão as conexões ao banco de dados? Bem, o comando abaixo (como root) retorna as configurações do SELinux para os servidores web:

# getsebool -a | grep httpd
httpd_anon_write --> off
httpd_builtin_scripting --> on
httpd_can_check_spam --> off
httpd_can_connect_ftp --> off
httpd_can_connect_ldap --> off
httpd_can_connect_mythtv --> off
httpd_can_connect_zabbix --> off
httpd_can_network_connect --> off
httpd_can_network_connect_cobbler --> off
httpd_can_network_connect_db --> off
httpd_can_network_memcache --> off
httpd_can_network_relay --> off
httpd_can_sendmail --> off
httpd_dbus_avahi --> off
httpd_dbus_sssd --> off
httpd_dontaudit_search_dirs --> off
httpd_enable_cgi --> on
httpd_enable_ftp_server --> off
httpd_enable_homedirs --> off
httpd_execmem --> off
httpd_graceful_shutdown --> on
httpd_manage_ipa --> off
httpd_mod_auth_ntlm_winbind --> off
httpd_mod_auth_pam --> off
httpd_read_user_content --> off
httpd_run_preupgrade --> off
httpd_run_stickshift --> off
httpd_serve_cobbler_files --> off
httpd_setrlimit --> off
httpd_ssi_exec --> off
httpd_sys_script_anon_write --> off
httpd_tmp_exec --> off
httpd_tty_comm --> off
httpd_unified --> off
httpd_use_cifs --> off
httpd_use_fusefs --> off
httpd_use_gpg --> off
httpd_use_nfs --> off
httpd_use_openstack --> off
httpd_use_sasl --> off
httpd_verify_dns --> off

Pronto, identificamos o problema! A propriedade httpd_can_network_connect_db está em “off” (e a httpd_can_network_connect também) e o SELinux está impedindo a conexão do PHP com o PostgreSQL. Para permitir que o SELinux deixe o PHP se conectar ao PostgreSQL (e ao MySQL), faça o seguinte (como root):

setsebool -P httpd_can_network_connect_db on
setsebool -P httpd_can_network_connect on

Agora o Apache/PHP já consegue se conectar aos bancos de dados!

Script de backup para o MySQL ou MariaDB

Segue um script simples de backup para o MySQL ou o MariaDB. O script tem como pré-requisito a criação de um usuário específico para backup, com privilégios restritos (altere o que está em vermelho e itálico):

#!/bin/bash

# backup_mysql.sh
# Script para backup simples de um ou mais bancos de dados MySQL/MariaDB

# Dados de conexão:
#------------------
host="localhost"
bancos="nome_do_banco" # Se mais de um, separar por espaços
usuario="nome_do_usuario"
senha="senha_do_usuario"
data=`date +"%Y-%m-%d_%H-%M-%S"`
arquivo="/path/do/diretorio/de/backup/${data}"

# Configura opções:
#------------------
opcoes="--add-drop-database --add-drop-table --add-locks --comments --complete-insert --create-options --disable-keys --default-character-set=utf8 --extended-insert --dump-date --lock-tables --order-by-primary --quick --routines --set-charset --triggers"

# Faz backup:
#------------
for i in `echo $bancos`
do
  mysqldump -h $host -u $usuario --password=$senha --databases $i -r ${arquivo}_${i}.sql
done

O script acima fará um backup de todos os bancos listados, gerando arquivos com o nome de: YYYY-MM-DD_HH-MI-SS_nome_do_banco.sql.

Obviamente o usuário que faz o backup deve ter permissão em todos os bancos de dados.

Agora configure o cron para rodar automaticamente o script e apagar os backups mais velhos que 5 dias. Coloque isso em seu crontab (altere o que está em vermelho itálico):

# Faz o backup do MySQL, todo dia as 19:00h:
00 19 * * * /path/ate/o/script/backup_mysql.sh


# Apaga os backups antigos do MySQL (backups com mais de 5 dias),
# todo dia as 19:30h:
30 19 * * * find /path/do/diretorio/de/backup -name "*.sql" -mtime +5 -exec rm -f {} \;

Agora você já tem um script simples para o backup de seus bancos de dados. Obviamente você deverá copiar esse backup para algum outro host ou mídia de backup.

Usuário específico para backup no MySQL (MariaDB)

Muitas vezes precisamos escrever scripts de backup para o MySQL (ou o MariaDB) que armazenam a senha de acesso ao banco de dados. Obviamente se seu servidor for comprometido e o hacker tiver acesso ao script de backup, ele pegará a senha do banco de dados de presente.

Um jeito mais seguro de usar scripts com senhas de usuários para backup é criar um usuário específico para backup, com dois privilégios: SELECT e de LOCK TABLES. Um hacker que conseguisse essa senha específica do usuário de backup ainda conseguiria fazer algum estrago (dar um lock me alguma tabela), mas não conseguiria apagar um banco de dados ou alterar os dados.

Para aumentar um pouco a segurança de seus scripts de backup, crie o usuário específico, dê os grants e use esse usuário/senha em seus scripts. Entre no MySQL (ou MariaDB) como usuário root e faça o seguinte (substitua os nomes em itálico sublinhado de acordo com seu sistema):

CREATE USER usuario@localhost
IDENTIFIED BY 'senha';

GRANT SELECT, LOCK TABLES
ON nome_do_banco_de_dados.*
TO usuario;

FLUSH PRIVILEGES;

Agora você tem um usuário que só pode dar SELECT e LOCK TABLES, e apenas para o banco de dados que você especificou.

Use esse usuário/senha menos privilegiado em seus scripts de backup.

Instalação do Apache, PHP e MySQL (MariaDB) no CentOS 7

Antes de fazer qualquer coisa, verifique se o sistema está atualizado:

# yum check-update
# yum update

Agora, para instalar o Apache, o PHP e o MySQL (MariaDB) no CentOS 7, siga os passos abaixo.

1) Instalação do MySQL (MariaDB):

Depois que o sistema estiver atualizado, como root, instale o MySQL (MariaDB):

# yum -y install mariadb-server mariadb

O CentOS instalará o MySQL (MariaDB) e quaisquer dependências. Depois disso, inicie o banco de dados e habilite a inicialização automática durante o boot do host:

# systemctl enable mariadb.service
# systemctl start mariadb.service

O próximo passo é rodar a rotina de configuração de segurança do MySQL, que “tranca” a instalação para evitar acessos não autorizados (em vermelho negrito estão os comandos a serem digitados durante a execução do comando):

# mysql_secure_installation
NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MariaDB
      SERVERS IN PRODUCTION USE! PLEASE READ EACH STEP CAREFULLY!

In order to log into MariaDB to secure it, we'll need the current
password for the root user. If you've just installed MariaDB, and
you haven't set the root password yet, the password will be blank,
so you should just press enter here.

Enter current password for root (enter for none):
OK, successfully used password, moving on...

Setting the root password ensures that nobody can log into the MariaDB
root user without the proper authorisation.

Set root password? [Y/n] Y
New password: (digite a senha aqui)
Re-enter new password: (repita a senha aqui)
Password updated successfully!
Reloading privilege tables..
 ... Success!


By default, a MariaDB installation has an anonymous user, allowing anyone to log into MariaDB without having to have a user account created for them. This is intended only for testing, and to make the installation go a bit smoother. You should remove them before moving into a production environment.

Remove anonymous users? [Y/n] Y
 ... Success!

Normally, root should only be allowed to connect from 'localhost'. This ensures that someone cannot guess at the root password from the network.

Disallow root login remotely? [Y/n] Y
 ... Success!

By default, MariaDB comes with a database named 'test' that anyone can
access. This is also intended only for testing, and should be removed
before moving into a production environment.

Remove test database and access to it? [Y/n] Y
 - Dropping test database...
 ... Success!
 - Removing privileges on test database...
 ... Success!

Reloading the privilege tables will ensure that all changes made so far will take effect immediately.

Reload privilege tables now? [Y/n] Y
 ... Success!

Cleaning up...

All done! If you've completed all of the above steps, your MariaDB
installation should now be secure.

Thanks for using MariaDB!

2) Instalação do Apache:

Como root, instale o Apache:

# yum -y install httpd httpd-manual httpd-tools

O CentOS instalará o Apache e as dependências. Depois disso habilite o Apache para inicialização automática e inicie o daemon:

# systemctl enable httpd.service
# systemctl start httpd.service

Se nenhuma mensagem de erro for exibida, o Apache foi instalado corretamente. Agora é necessário configurar o firewall do CentOS para permitir acesso às portas 80 e 443:

# firewall-cmd --permanent --zone=public --add-service=http
# firewall-cmd --permanent --zone=public --add-service=https
# firewall-cmd --reload

Nesse momento você pode abrir o endereço http://<ip do servidor> para verificar se a página de teste do Apache é exibida corretamente (lembre-se que o firewall corporativo, além do firewall do próprio host onde o Apache está instalado, também tem que ser configurado para permitir o acesso):

Página de teste do Apache

 3) Instalação do PHP:

A instalação básica do PHP é muito simples:

# yum -y install php

O comando acima instalará o PHP 5.4 no CentOS e as dependências. Precisamos instalar mais alguns módulos importantes para o PHP (dependendo de sua aplicação web, outros módulos não listados aqui também podem ser necessários):

# yum -y install php-gd php-mysql php-odbc php-pear php-recode php-xml

Para fazer com que o Apache utilize PHP, basta reiniciá-lo:

# systemctl restart httpd.service

O teste mais básico para verificar se o PHP está instalado e corretamente configurado com o Apache é criar o arquivo /var/www/html/info.php com o seguinte conteúdo:

<?php
phpinfo();
?>

Abra o endereço http://<ip do servidor>/info.php e verifique se as informações do PHP são exibidas corretamente:

Informações do PHP

Por motivos de segurança o arquivo /var/www/html/info.php deve ser excluído após o teste.