Acesso remoto ao MySQL – Access denied for user ‘root’@’localhost’

Estava testando o laravel homestead, e surgiu a necessidade de acessar o MySql a partir da minha máquina local. Quando tentei acessar utilizando o usuário e senha do banco apareceu o erro: ERRO 1045: ACCESS DENIED FOR USER: 'ROOT@LOCALHOST', mas, como vocês poderão ver, solucioná-lo é tão fácil quanto parece.

Como habilitar o acesso remoto MySQL

Acesso remoto ao MySQL do laravel homestead é desabilitado por padrão por razões de segurança. No entanto, pode haver momentos em que é necessário para habilitá-lo para fornecer acesso a partir de um local remoto ou simplesmente da sua máquina de desenvolvimento. Este artigo irá descrever o processo em detalhe, e é destinado a usuários familiarizados com SSH e MySQL.

Conecte-se ao servidor MySQL

O laravel homestead MySQL é acessado através de SSH. Uma vez que a conexão com o servidor foi realizado, um segundo comando fornece acesso ao servidor MySQL. O procedimento para estabelecer a ligação é como se segue:

Conecte-se ao servidor via SSH. Em seguida, conecte com o MySQL. Isso envolve a inserção do nome de usuário e senha dada especificamente para uso MySQL. O comando para iniciar a conexão é:

mysql -u root -p  

Digite a senha do MySQL quando solicitado. No caso do laravel homestead a senha é secret.

Habilitar acesso remoto ao MySQL de um IP externo

O comando a seguir irá permitir o acesso ao banco de dados MySQL a partir de um endereço IP remoto:

mysql> GRANT ALL PRIVILEGES ON *.* TO usuario@HOST IDENTIFIED BY 'senha';  

Substitua o usuario, o HOST e a senha nesse comando com os dados relevantes.
O HOST é um endereço de ip válido, por exemplo: 192.168.1.10
O usuário no laravel homestead é root e senha é secret

Habilitar acesso remoto ao MySQL de qualquer IP

Se um usuário está em um endereço IP dinâmico não será possível utilizar o método acima. Para fazer isso, use '%' no lugar do ip. Isso não é recomendado em ambientes de produção, porque é menos seguro, uma vez que permite que a conexão seja estabelecida de qualquer lugar.

mysql> GRANT ALL PRIVILEGES ON *.* TO usuario@'%' IDENTIFIED BY 'senha';  

Novamente, substitua o usuario e senha nesse comando com os dados relevantes.
O usuário no laravel homestead é root e senha é secret

Recarregar os Privilégios

Para que as novas permissões funcionem, após utilizar o grant para atribuir as permissões de acesso, é necessário recarregar os privilégios.

mysql> flush privileges;  

Agora você já pode conectar-se à seu mysql sem se deparar com o ERRO 1045: ACCESS DENIED FOR USER.

Até.

O que fazer quando o Vagrant não retoma o download

Se você chegou até aqui, você com certeza já se deparou com esse erro irritante quando você tenta retomar um download que falhou?

PS D:\vagrant> vagrant init rasmus/php7dev  
A `Vagrantfile` has been placed in this directory. You are now  
ready to `vagrant up` your first virtual environment! Please read  
the comments in the Vagrantfile as well as documentation on  
`vagrantup.com` for more information on using Vagrant.
PS D:\vagrant> vagrant up --provider=virtualbox  
Bringing machine 'default' up with 'virtualbox' provider...  
==> default: Box 'rasmus/php7dev' could not be found. Attempting to find and install...
    default: Box Provider: virtualbox
    default: Box Version: >= 0
==> default: Loading metadata for box 'rasmus/php7dev'
    default: URL: https://atlas.hashicorp.com/rasmus/php7dev
==> default: Adding box 'rasmus/php7dev' (v0.0.8) for provider: virtualbox
    default: Downloading: https://atlas.hashicorp.com/rasmus/boxes/php7dev/versions/0.0.8/providers/virtualbox.box
==> default: Box download is resuming from prior download progress
    default: Progress: 0% (Rate: 0/s, Estimated time remaining: --:--:--):--)
An error occurred while downloading the remote file. The error  
message, if any, is reproduced below. Please fix this error and try  
again.  

Para solucionar esse problema, é necessário apenas remover o arquivo que foi parcialmente baixado, para fazê-lo basta executar o seguinte comando em seu powerShell.

PS D:\vagrant>rm ~/.vagrant.d/tmp/*  

Como utilizar o gzip com mysql para importar/exportar backups

Se você está armazenando qualquer coisa em bancos de dados MySQL que você não quer perder, é muito importante fazer backups regulares de seus dados afim de evitar perda de dados. Este tutorial tem como objetivo mostrar como você pode fazer o backup e compactá-lo – bem como restaurá-lo – assim fica mais fácil movê-lo para um outro servidor.

Como fazer o backup do MySql

Como fazer backup de um único banco de dados:

Este exemplo tem um backup do banco de dados teste e gera a saída para o arquivo teste.sql

# mysqldump -u root -pSENHA teste > teste.sql

# mysqldump -u root -p[senha_de_root] [nome_do_banco] > nome_do_arquivo.sql

Como fazer backup de vários bancos de dados:

Por exemplo, se você quiser ter backup dos banco de dados producao e teste, executar o mysqldump como mostrado abaixo:

# mysqldump -u root -pSENHA --databases producao teste > producao_teste.sql

Você pode verificar se o arquivo gerado contém os dois bancos de dados utilizando o comando a seguir

# grep -i "Current database:" /tmp/producao_teste.sql
-- Current Database: `producao`
-- Current Database: `teste`

Como fazer backup de todos bancos de dados:

O exemplo a seguir faz uma cópia de segurança de todos os banco de dados da instância do MySQL.

# mysqldump -u root -pSENHA --all-databases > /tmp/todos_bancos.sql

Como fazer backup de uma tabela específica do banco de dados:

Neste exemplo, será feito o backup apenas da tabela clientes da base de dados teste.

# mysqldump -u root -pSENHA teste clientes > /tmp/teste_clientes.sql

Como exportar um banco de dados e compactar com Gzip

No exemplo a seguir, vamos fazer o backup do banco teste e em seguida redirecionar a saída para o gzip que vai compactá-lo para o arquivo teste.sql.gz

# mysqldump -u root -pSENHA teste | gzip > teste.sql.gz

Como restaurar o backup do MySql

Restaurar o banco de dados

Neste exemplo, para restaurar o banco teste, é necessário executar mysql com < como mostrado abaixo. Quando você estiver restaurando o backup em uma outra instância do banco de dados, certifique-se de criar o banco de dados teste – em nosso exemplo – antes de poder executar a restauração.

Para criar o banco você deve executar os seguintes comandos:

# mysql -u root -pSENHA

mysql> create database teste;  
Query OK, 1 row affected (0.06 sec)  

E, para efetuar a restauração

# mysql -u root -pSENHA teste < /tmp/teste.sql

# mysql -u root -p[root_password] [database_name] < arquivodebackup.sql

Como importar um banco de dados e compactado com Gzip

No exemplo a seguir, vamos descompactar o arquivo teste.sql.gz. e, redirecionar a saída para o mysql, definindo que a restauração do arquivo deve ser feita no banco teste.

gunzip < teste.sql.gz | mysql -u user -pSenha teste  

SQLSTATE[HY000]: General error: 29 File ‘file.csv’ not found (Errcode: 13)

O que é o AppArmor

O AppArmor permite que o administrador do sistema para associar a cada programa um perfil de segurança que restringe os recursos do programa.

Verificando se o AppArmor realmente é o problema

Atualemnte o Ubuntu vem com o AppArmor ativado e o perfil do MySQL pode estar sendo executado em modo forçado por padrão. Você pode verificar isso executando o comando sudo aa-status da seguinte forma:

  
$ sudo aa-status
apparmor module is loaded.  
5 profiles are loaded.  
5 profiles are in enforce mode.  
   /sbin/dhclient
   /usr/lib/NetworkManager/nm-dhcp-client.action
   /usr/lib/connman/scripts/dhclient-script
   /usr/sbin/mysqld
   /usr/sbin/tcpdump
0 profiles are in complain mode.  
2 processes have profiles defined.  
2 processes are in enforce mode.  
   /sbin/dhclient (1088) 
   /usr/sbin/mysqld (26214) 
0 processes are in complain mode.  
0 processes are unconfined but have a profile defined.  

Se o mysqld está incluído no modo forçado, então provavelemente você acabou de encontrar o culpado por negar a acesso e/ou gravação. As entradas também seriam escritas em seu log quando o AppArmor bloqueia as gravações e/ou acessos.

Como alterar o perfil do MySql para aceitar o acesso/gravação

O que você pode fazer é editar /etc/apparmor.d/usr.sbin.mysqld e adicionar o path de onde o arquivo se encontra ou onde deverá ser exportado, por exemplo: /data/ e /data/* perto da parte inferior da seguinte forma:

  
sudo vi /etc/apparmor.d/usr.sbin.mysqld  
/usr/sbin/mysqld {
...
/var/log/mysql/ r,
/var/log/mysql/* rw,
/var/run/mysqld/mysqld.pid w,
/var/run/mysqld/mysqld.sock w,
/data/ r,
/data/* rw,
}

Agora só resta reiniciar o AppArmor

  
$ sudo /etc/init.d/apparmor reload

Como ler aquivos do excel com php

Ler arquivos do Excel com PHP pode ser complicado, mas felizmente há uma grande biblioteca que torna essa tarefa muito mais fácil: PHPExcel. Nesse post vamos ver como utilizar o PHPExcel para converter as planilhas do excel em arrays e usar os dados em PHP.

Instalando o PHPExcel

O primeiro passo para trabalhar com documentos do Excel no PHP será instalar a biblioteca PHPExcel. Eu vou fazer isso utilizando o composer. Se você ainda não está familiarizado com composer, você definitivamente deve ter um olhar para ele e usá-lo para gerenciar as dependências do seu projeto. O arquivo composer.json é extremamente simples:

{
 "require":
   {
      "phpoffice/phpexcel": "dev-develop"
   }
}

Então você precisa para instalar as dependências com o composer, o que pode demorar alguns segundos para completar:

composer install  

Você vai notar que a biblioteca foi baixada e instalada no diretório project_root/vendor/phpoffice/phpexcel juntamente com o diretório project_root/vendor/composer e um arquivo project_root/vendor/autoload.php que foi gerado automaticamente para gerenciar o autoloading das classes para a biblioteca.

Carregando o arquivo no PHPExcel

Há duas maneiras básicas para carregar o arquivo no PHPExcel. Você pode especificar um dos tipos de arquivos suportados manualmente ou você pode deixar a biblioteca determinar o tipo de arquivo automaticamente com base no arquivo que você fornece. Aqui está o código necessário para ambos e uma lista dos tipos de arquivos suportados que você pode escolher se você decidir definir explicitamente o tipo de arquivo:

<?php  
require_once "vendor/autoload.php";

$fileName = "exemplo.xlsx";

/** detecta automaticamente o tipo de arruivo que será carregado */
$excelReader = PHPExcel_IOFactory::createReaderForFile($fileName);

/** Definindo manualmente.
// $inputFileType = 'Excel5';
// $inputFileType = 'Excel2007';
// $inputFileType = 'Excel2003XML';
// $inputFileType = 'OOCalc';
// $inputFileType = 'SYLK';
// $inputFileType = 'Gnumeric';
// $inputFileType = 'CSV';
$excelReader = PHPExcel_IOFactory::createReader($inputFileType);
*/

Definir as opções de leitura

Não vou entrar em muitos detalhes sobre as diferentes opções que você pode usar, porque eles são muito poucos, mas é importante exemplificar as mais comuns e úteis.

//Se não precisarmos de formatação
$excelReader->setReadDataOnly();

//carregar apenas algumas abas
$loadSheets = array('aba1', 'aba2');
$excelReader->setLoadSheetsOnly($loadSheets);

//o comportamente padrão é carregar todas as abas
$excelReader->setLoadAllSheets();

Estes são bastante simples. Certifique-se que você só carregar as abas de que você precisa para usar uma vez que a biblioteca pode usar uma grande quantidade de memória especialmente para arquivos grandes. Além disso, o método setReadDataOnly ajuda a acelerar as coisas um pouco por carregar apenas os dados das células, sem qualquer formatação especial do excel. Você tem que estar ciente de que embora qualquer formatação de data será perdida se você usar essa opção e as datas serão carregados como números, sem formatação.

Carregar e exibir os dados

O passo final é para carregar os dados do Excel para o PHP.

$excelObj = $excelReader->load($fileName);

Isto produzirá um objeto PHPExcel, mas, a fim de modificar e transformar os dados para atender às nossas necessidades o seu melhor para convertê-lo em um array facilmente.

$excelObj->getActiveSheet()->toArray(null, true,true,true);

Tenha em mente que PHPExcel só vai exibir as informações sobre a folha ativa no momento, que é o último a ser carregado. No entanto, você pode alternar manualmente entre as folhas e obter o seu conteúdo ou você pode automatizar o processo e obter todas as folhas como um array:

//Pega os nomes das abas
$worksheetNames = $excelObj->getSheetNames($fileName);
$return = array();
foreach($worksheetNames as $key => $sheetName){  
//define a aba ativa
$excelObj->setActiveSheetIndexByName($sheetName);
//cria um array com o nome da aba como índice
$return[$sheetName] = $excelObj->getActiveSheet()->toArray(null, true,true,true);
}
//exibe o array
var_dump($return);  

Como verificar se os links de um rss estão ativos

Primeiro criamos a classe que vai conter os posts e todos os atributos, em seguida criaremos a classe que manipulará o feed de notícias, para tal utilizaremos o simplexml que interpreta um arquivo XML e o transforma em um objeto.

Esse post foi uma sugestão do Gerson, e, nós vamos utilizar a função daquele mesmo post nesse aqui.

A Classe BlogPost

Nessa classe vamos colocar os atributos de um post no feed rss, que são data, link, título, texto e um atributo disponibilidade para exibir se o post está disponível ou não.

<?php  
class BlogPost  
{
    var $data;
    var $ts;
    var $link;
    var $titulo;
    var $texto;
    var $disponibilidade;
}

A Classe BlogFeed

Agora criaremos uma classe para preencher os objetos da classe BlogPost, que terá um construtor que recebe por parâmetro a url do feed de notícias. Para isso vamos utilizar o simplexmlloadfile.

class BlogFeed  
{
    var $posts = array();

    function __construct($file_or_url)
    {
        $file_or_url = $this->resolverArquivo($file_or_url);
        if (!($x = simplexml_load_file($file_or_url)))
            return;

        foreach ($x->channel->item as $item)
        {
            $post = new BlogPost();
            $post->data             = (string) $item->postsubDate;
            $post->ts               = strtotime($item->pubDate);
            $post->link             = (string) $item->link;
            $post->titulo           = (string) $item->title;
            $post->texto            = (string) $item->description;
            $post->disponibilidade = $this->verificarDisponibilidade($item->link);

            // Create summary as a shortened body and remove images,
            // extraneous line breaks, etc.
            $post->summary = $this->resumirTexto($post->texto);

            $this->posts[] = $post;
        }
    }

    private function resolverArquivo($file_or_url) {
        if (!preg_match('|^https?:|', $file_or_url))
            $feed_uri = $_SERVER['DOCUMENT_ROOT'] .'/shared/xml/'. $file_or_url;
        else
            $feed_uri = $file_or_url;

        return $feed_uri;
    }

    private function resumirTexto($summary) {
        $summary = strip_tags($summary);

        $max_len = 100;
        if (strlen($summary) > $max_len)
            $summary = substr($summary, 0, $max_len) . '...';

        return $summary;
    }

    private function verificarDisponibilidade($url) {
        $ch = @curl_init($url);
        @curl_setopt($ch, CURLOPT_HEADER, TRUE);
        @curl_setopt($ch, CURLOPT_NOBODY, TRUE);
        @curl_setopt($ch, CURLOPT_FOLLOWLOCATION, FALSE);
        @curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
        $status = array();
        preg_match('/HTTP\/.* ([0-9]+) .*/', @curl_exec($ch) , $status);
        return ($status[1] == 200) ? "YES" : "NO" ;
    }
}

Como utilizar

Como vocês já devem ter percebido esse post é pra ser uma dica rápida, então para utilizar é simples.

$feed = new BlogFeed("http://blog.adlerdias.eti.br/rss");

foreach ($feed as $posts) {  
    foreach ($posts as $post) {
        echo $post->avaliable . " - " . $post->link . "\n";
    }
}

Juntando Tudo

<?php  
class BlogPost  
{
    var $data;
    var $ts;
    var $link;
    var $titulo;
    var $texto;
    var $disponibilidade;
}

class BlogFeed  
{
    var $posts = array();

    function __construct($file_or_url)
    {
        $file_or_url = $this->resolverArquivo($file_or_url);
        if (!($x = simplexml_load_file($file_or_url)))
            return;

        foreach ($x->channel->item as $item)
        {
            $post = new BlogPost();
            $post->data             = (string) $item->postsubDate;
            $post->ts               = strtotime($item->pubDate);
            $post->link             = (string) $item->link;
            $post->titulo           = (string) $item->title;
            $post->texto            = (string) $item->description;
            $post->disponibilidade = $this->verificarDisponibilidade($item->link);

            // Create summary as a shortened body and remove images,
            // extraneous line breaks, etc.
            $post->summary = $this->resumirTexto($post->texto);

            $this->posts[] = $post;
        }
    }

    private function resolverArquivo($file_or_url) {
        if (!preg_match('|^https?:|', $file_or_url))
            $feed_uri = $_SERVER['DOCUMENT_ROOT'] .'/shared/xml/'. $file_or_url;
        else
            $feed_uri = $file_or_url;

        return $feed_uri;
    }

    private function resumirTexto($summary) {
        $summary = strip_tags($summary);

        $max_len = 100;
        if (strlen($summary) > $max_len)
            $summary = substr($summary, 0, $max_len) . '...';

        return $summary;
    }

    private function verificarDisponibilidade($url) {
        $ch = @curl_init($url);
        @curl_setopt($ch, CURLOPT_HEADER, TRUE);
        @curl_setopt($ch, CURLOPT_NOBODY, TRUE);
        @curl_setopt($ch, CURLOPT_FOLLOWLOCATION, FALSE);
        @curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
        $status = array();
        preg_match('/HTTP\/.* ([0-9]+) .*/', @curl_exec($ch) , $status);
        return ($status[1] == 200) ? "YES" : "NO" ;
    }
}

$feed = new BlogFeed("http://blog.adlerdias.eti.br/rss");

foreach ($feed as $posts) {  
    foreach ($posts as $post) {
        echo $post->disponibilidade . " - " . $post->link . "\n";
    }
}

Caso tenha alguma dúvida é só deixar nos comentários.

Como adicionar colorização de sintaxe no Ghost

PRISM.JS

A biblioteca que nós utilizaremos para fazer a colorização de sintaxe, vamos utilizar o Prism.JS, que além de ser muito bom, como diz o site, é “super rápido”. E tem um bom conjunto de temas pré-definidos e alguns plugins úteis, para que ele possa atender às suas necessidades.

var str = 'rb.ite.saidrelda.golb//:ptth';  
[].map.call(str, function(x) {
  return x;
}).reverse().join(''); 
// Saída: 'http://blog.adlerdias.eti.br'

Como instalar o Prism.JS

Instalar o Prism.JS é muito fácil:

  • Primeiro você precisa fazer o download clicando aqui
  • Após selecionar as opções que você acha que vai atender às suas necessidades, faça o download dos arquivos de script(js) e estilo(css) gerados.
  • Coloque os arquivos nas pastas assets/css e assets/js adequadas, no tema que você estiver utilizando – o conteúdo content/themes/tema/assets/js/prism.js e content/themes/tema/assets/css/prism.css
  • Agora é só adicionarmos esses arquivos em seu layout.

Para fazer isso, abra o arquivo content/themes/theme-name/default.hbs e adicione a tag <link> no head para o css.

...
<link rel="stylesheet" type="text/css" href="{{asset "css/prism.css"}}" />  
...

e a tag <script>antes da tag </body>

...
    <script type="text/javascript" src="{{asset "js/prism.js"}}"></script>
</body>  

Pronto

Isso foi fácil. Agora você está pronto para começar a usar a colorização de sintaxe utilizando os recursos fornecidos pelo Prism.JS. O modo como funciona é procurando por um elemento <code class="language-*"></code>, ou no ghost, “`language-javascript em seu código. Então você só precisa adicionar a classe adequada para o seu bloco de código, assim:

```language-javascript
var str = 'rb.ite.saidrelda.golb//:ptth';  
[].map.call(str, function(x) {
  return x;
}).reverse().join(''); 
// Saída: 'http://blog.adlerdias.eti.br'
// é necessário colocar ``` para finalizar a marcação do bloco de código

E aqui está como o código é renderizado.

var str = 'rb.ite.saidrelda.golb//:ptth';  
[].map.call(str, function(x) {
  return x;
}).reverse().join(''); 
// Saída: 'http://blog.adlerdias.eti.br'

Como configurar um servidor WEB com Ubuntu 14.04

Depois de criar uma VM com Ubuntu 14.04 no Azure, é hora de iniciar a instalação e configuração do mesmo, como esse será um servidor web vamos começar configurando o ssh, fail2ban e fazendo a instalação padrão do LAMP.

Antes de tudo

Antes de fazer qualquer outra coisa, é bom adquirir o hábito de atualizar os programas e também o sistema operacional:

$ sudo apt-get update
$ sudo apt-get upgrade -y

Configurando a Localidade (locale)

Se você não tem UTF-8 como sua localidade padrão, algumas coisas podem dar errado enquanto você configura seu sistema. Portanto, verifique a localidade em primeiro lugar:

# exibe o locale
locale -a  
# criaremos a localidade UTF-8 Inglês
sudo locale-gen en_US.UTF-8  
export LANG=en_US.UTF-8  
# caso existam outras localidades UTF-8 disponíveis, você pode simplesmente optar por utilizá-la.
# Por exemplo, 
export LANG=C.UTF-8  

Fazendo isso, você estará corrigindo e evitando problemas como:

UnicodeDecodeError: ‘ascii’ codec can’t decode byte 0x* in position *: ordinal not in range(128)

Para finalizar, você deve criar o arquivo /etc/default/locale e inserir os valores:

$ sudo -s
touch /etc/default/locale  
echo LANG="en_US.UTF-8" > /etc/default/locale  
echo LANGUAGE="en_US:en" >> /etc/default/locale  

Configurando SSH

A primeira alteração que devemos fazer, é trocar porta padrão do ssh.

cp /etc/ssh/sshd_config /etc/ssh/sshd_config.old  
sed 's/Port 22/Port 6543/' < /etc/ssh/sshd_config    >/etc/ssh/sshd_config.new  
mv /etc/ssh/sshd_config.new /etc/ssh/sshd_config  
service ssh restart  

Também é necessário verificar as configurações de PermitRootLogin e PermitEmptyPasswords.

grep "PermitRootLogin" /etc/ssh/sshd_config  

Deve retornar

PermitRootLogin no

grep "PermitEmptyPasswords" /etc/ssh/sshd_config  

Deve retornar

PermitEmptyPasswords no

Caso PermitRootLogin ou PermitEmptyPasswords retornem yes, basta entrar no seu editor de texto preferido e trocar para no. Após fazer essas alterações é necessário reiniciar o ssh.

sudo service ssh restart  

Liberando Endpoint no Azure

Após fazer essa alteração, não se esqueça de adicionar a porta 6543 no endpoint do azure, caso contrário, não será mais possível se conectar à sua VM.

Instalando e Configurando o Fail2Ban

Primeiro vamos instalar o Fail2Ban utilizando o comando abaixo

sudo apt-get -y install fail2ban  

Como você pode ver, a instalação é trivial. Agora podemos iniciar a configuração para nosso próprio uso.

Vamos editar o arquivo /etc/fail2ban/jail.local

e vamos deixá-lo da seguinte forma:

[DEFAULT]
ignoreip = 127.0.0.0/8  
bantime  = 1800  
findtime  = 1800  
maxretry = 5  
backend = gamin

[ssh]
enabled  = true  
port     = 6543  
filter   = sshd  
logpath  = /var/log/auth.log  
maxretry = 5

[vsftpd-notification]
enabled  = false  
filter   = vsftpd  
action   = sendmail-whois[name=VSFTPD, dest=adlersd@gmail.com]  
logpath  = /var/log/vsftpd.log  
maxretry = 5  
bantime  = 1800

[vsftpd-iptables]
enabled  = true  
filter   = vsftpd  
action   = iptables[name=VSFTPD, port=ftp, protocol=tcp]  
           sendmail-whois[name=VSFTPD, dest=adlersd@gmail.com]
logpath  = /var/log/vsftpd.log  
maxretry = 5  
bantime  = 1800  
failregex = vsftpd(?:\(pam_unix\))?(?:\[\d+\])?:.* authentication failure; .* rhost=<HOST>(?:\s+user=\S*)?\s*$  
\[.+\] FAIL LOGIN: Client "<HOST>"\s*$

Dessa maneira estaremos protegendo tanto nosso ssh na porta customizada(6543) como o servidor ftp, VSFTPD.

Finalmente, devemos reiniciar o fail2ban.

sudo service fail2ban restart  

Instalando e Configurando o LAMP

Vamos instalar o LAMP utilizando o tasksel, para instalá-lo basta utilizarmos o comando:

Feito isso, podemos prosseguir e instalar o LAMP, isso pode ser feito de duas maneiras utilizando o tasksel – podemos executar o comando sudo tasksel – e da maneira como vamos fazer nesse guia utilizando a sintaxe alternativa do tasksel.

Você pode instalar o LAMP em um único comando, usando o apt-get modo tasksel (não se esqueça do acento ^ no final):

sudo apt-get install lamp-server^  

Pronto, agora temos tudo o que vamos precisar para essa primeira parte.

Configurando o MySql

Primeiro, vamos reiniciar o serviço:

sudo service mysql restart  

Vamos iniciar as configurações:

sudo /usr/bin/mysql_secure_installation  

O prompt irá pedir a sua senha de root atual, porém, como acabamos de fazer a instalação, basta deixá-lo em branco pressionando enter.

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

Em seguida, a mensagem irá perguntar se você deseja definir uma senha de root. Vá em frente e escolha Y e siga as instruções.

By default, a MySQL installation has an anonymous user, allowing anyone  
to log into MySQL 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, MySQL 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 MySQL  
installation should now be secure.

Thanks for using MySQL!  

Agora, vamos criar um usuário:

Será necessário que você digite a senha que você definiu como senha de root para a sua instalação do MySql.

mysql -u root -p  
CREATE DATABASE novoBancoDeDados;  
CREATE USER novoUsuario@% IDENTIFIED BY 'novaSenha';  
GRANT ALL PRIVILEGES ON novoBancoDeDados.* TO novoUsuario@%;  
FLUSH PRIVILEGES;  
exit  

Configurando o Php

Nós precisamos fazer uma pequena mudança na configuração do php. Abra /etc/php.ini:

Encontre a linha, cgi.fix_pathinfo = 1, e mudar de 1 para 0.

cgi.fix_pathinfo=0  

Também pode ser necessário alterar os valores de algumas variáveis de ambiente.

date.timezone = America/Sao_Paulo  
short_open_tag = Off  
expose_php = off  
max_execution_time = 60  
memory_limit = 256M  
post_max_size = 128M  
upload_max_filesize = 128M  

Agora basta reiniciar o apache, para que as alterações entrem em vigor.

sudo service apache2 restart  

Como desabilitar as notificações por email da Cron

Recentemente eu me deparei com uma enxurrada de emails de notificação de cada tarefa que a cron executava no servidor. Um deles, por exemplo, executava ums script PHP a cada dez minutos. Mesmo que o script foi executado com êxito, eu estava ficando um e-mail a cada dez minutos, contendo a saída do script. Então, como vamos “desabilitar” esses e-mails? Você pode fazer isso de algumas maneiras.

Utilizando a variável MAILTO

A variável MAILTO permite que você defina o endereço de e-mail que os e-mails de notificação de Cron são enviados. Você pode suprimir todos os e-mails de suas tarefas Cron definindo esta variável como vazia:

$ crontab -e

No topo do arquivo, adicione a linha:

MAILTO=""  

Agora, basta salvar e sair do documento.

Enviando a saída para /dev/null

O dispositivo nulo, /dev/null, dos sistemas operacionais unix-like é um “buraco negro” para os dados, ou seja, qualquer saída enviada aqui será descartada, o que o torna um grande candidato para suprimir a saída das tarefas da Cron.

Para suprimir todas as saídas (STDOUT e STDERR) da sua tarefa Cron, você precisará adicionar ao final do seu comando > /dev/null 2>&1.

$ crontab -e

adicione ao final do comando:

*/10 * * * * comando > /dev/null 2>&1

O número 2 representa o fluxo de STDERR (erro padrão), enquanto 1 é o fluxo STDOUT (saída padrão).

Se você quiser receber e-mails sobre erros, mas não os sucessos, você precisará adicionar ao final do seu comando > /dev/null, assim, você irá suprimir a saída de apenas STDOUT:

$ crontab -e

adicione ao final do comando:

*/10 * * * * comando > /dev/null

ERROR 2006 (HY000) at line 27652: MySQL server has gone away

Enquanto estava usando um script para substituir o meu banco de dados local com o banco de dados de produção, eu me deparei com o seguinte erro:

ERROR 2006 (HY000) at line 27652: MySQL server has gone away

O primeiro passo é verificar o tamanho da variável max_allowed_packet

  
+--------------------+----------+
| Variable_name      | Value    |
+--------------------+----------+
| max_allowed_packet | 16777216 |
+--------------------+----------+

O valor da variável max_allowed_packet está definido como 16777216, isso quer dizer que em nosso /etc/mysql/my.cnf ela está definica com 16M (16777216÷1024÷1024).

Como resolver ERROR 2006 (HY000) at line 27652: MySQL server has gone away

Para resolvermos esse problema, vamos alterar o valor da variável max_allowed_packet, no arquivo /etc/mysql/my.cnf

  
$ sudo vim /etc/mysql/my.cnf

Vamos alterar para 128M

  
...
[mysqld]
...
max\_allowed\_packet    = 128M  
...
[mysqldump]
max\_allowed\_packet    = 128M  
...

Caso você também queira aumentar o tempo de timeout, adicione abaixo do [mysqld]

  
...
[mysqld]
...
wait_timeout = 6000  
...

Agora é só reiniciar o serviço do mysql

$ sudo service mysql restart

					
							        
	

© 2016 Adler Dias

Theme by Anders NorenUp ↑