Pular para o conteúdo
2 de outubro de 2018 / rafaelti

Proteger URL com Nginx

Objetivo

Proteger o acesso a uma URL através do Nginx

Plataforma

Linux, Nginx

Conhecimento

Linux, NGinx, MD5 e PHP

Introdução

Há varias formas de implementar um controle de acesso, um controle é fazer direto no servidor de aplicação

Solução

Para implementar a segurança no servidor de aplicação Nginx uma solução é utilizar o secure link module para utilizar na instalação atráves do gerenciador do pacote ou no ./configure utilizar o --with-http_secure_link_module

No config o location protegido deve seguir o código abaixo

location /secureurl/ {
.
.
.
    secure_token $args;
	secure_link_md5 "$secure_link_expires$uri$remote_addr secret";
	if ($secure_link = "") {
			return 403;
	}
	if ($secure_link = 0) {
			return 410;
	}
.
.
.
}

Para gerar a URL válida segue o código

<?php
/**
 * @param $baseUrl - non protected part of the URL including hostname, e.g. http://example.com
 * @param $path - protected path to the file, e.g. /downloads/myfile.zip
 * @param $secret - the shared secret with the nginx server. Keep this info secure!!!
 * @param $ttl - the number of seconds until this link expires
 * @param $userIp - ip of the user allowed to download
 * @return string
 */
function buildSecureLink($baseUrl, $path, $secret, $ttl, $userIp)
{
    $expires = time() + $ttl;
    $md5 = md5("$expires$path$userIp $secret", true);    
    $md5 = base64_encode($md5);
    $md5 = strtr($md5, '+/', '-_');
    $md5 = str_replace('=', '', $md5);
    return $baseUrl . $path . '?md5=' . $md5 . '&expires=' . $expires;
}
// example usage
$secret = 'secret';
$baseUrl = 'http://127.0.0.1';
$path ='/file/myfile';
$ttl = 1000;//no of seconds this link is active
$userIp = '127.0.0.1';//normally you would read this from something like $_SERVER['REMOTE_ADDR'];
echo buildSecureLink($baseUrl, $path, $secret, $ttl, $userIp);
Anúncios
1 de setembro de 2018 / rafaelti

Certificado Digital para múltiplos subdomínios com Let’s Encrypt no Nginx

Objetivo

Ativar certificado digital para múltiplos subdomínios no servidor Nginx

Plataforma

Let’s Encrypt, Linux e Nginx

Conhecimento

Linux e NGinx

Introdução

Muitas vezes ativamos certificado digital só para o domínio principal e para domínio principal com www. Quando a aplicação cresce precisamos de certificado digital para os subdomínios também.

Solução

A solução é o utilizar o Certbot para gerar as chaves para nosso domínio.

sudo certbot --server https://acme-v02.api.letsencrypt.org/directory -d *.YOUR_SITE_HERE.com.br -d YOUR_SITE_HERE.com.br --manual --preferred-challenges dns-01 certonly

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Connection to _______ closed.                                                                                                      
Plugins selected: Authenticator manual, Installer None
Obtaining a new certificate
Performing the following challenges:
dns-01 challenge for YOUR_SITE_HERE.com.br

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NOTE: The IP of this machine will be publicly logged as having requested this
certificate. If you're running certbot in manual mode on a machine that is not
your server, please ensure you're okay with that.

Are you OK with your IP being logged?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: y

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please deploy a DNS TXT record under the name
_acme-challenge.YOUR_SITE_HERE.com.br with the following value:
CODE_HASH HERE

Neste passo é preciso editar o seu DNS TXT com o domínio _acme-challenge.YOUR_SITE_HERE.com.br e o Hash gerado. Como a imagem abaixo. É preciso lembrar que é preciso propagar a informação do DNS para continuar.

Assim que passar o tempo da propagação pode continuar a execução.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -                                                         
Press Enter to Continue                                                                                                                 
Waiting for verification...                                                                                                             
Cleaning up challenges                                                                                                                  
                                                                                                                                        
IMPORTANT NOTES:                                                                                                                        
 - Congratulations! Your certificate and chain have been saved at:                                                                      
   /etc/letsencrypt/live/YOUR_SITE_HERE.com.br-0001/fullchain.pem                                                                               
   Your key file has been saved at:                                                                                                     
   /etc/letsencrypt/live/YOUR_SITE_HERE.com.br-0001/privkey.pem                                                                                 
   Your cert will expire on 2018-10-22. To obtain a new or tweaked                                                                      
   version of this certificate in the future, simply run certbot                                                                        
   again. To non-interactively renew *all* of your certificates, run                                                                    
   "certbot renew"                                                                                                                      
 - If you like Certbot, please consider supporting our work by:                                                                         
                                                                                                                                        
   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate                                                                   
   Donating to EFF:                    https://eff.org/donate-le                                                                        
                                                                                                                                        
rafael@Principal:~$ 

Então é preciso editar as configuração do servidor e substituir a linha onde tem o caminho do certificado

ssl_certificate /etc/letsencrypt/live/YOUR_SITE_HERE.com.br-0001/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/YOUR_SITE_HERE.com.br-0001/privkey.pem;

Após isso é preciso reiniciar o servidor

rafael@Principal:~$ sudo service nginx restart
1 de agosto de 2018 / rafaelti

Usuários reiniciando serviço sem senha

Objetivo

Fazer usuários reiniciar serviço sem senha

Plataforma

Ubuntu

Conhecimento

Linux

Introdução

Para tarefas automatizadas algumas ações podem ser simplificadas ao ponto de serem executado sem qualquer proteção.

Solução

Para facilitar daremos a um usuário comum a permissão de executar o reinicio do serviço do NGinx.

sudo visudo
#Ir até o final do arquivo e inserir a linha abaixo
YOUR_USER_HERE ALL=NOPASSWD: /bin/systemctl restart nginx.service
7 de junho de 2018 / rafaelti

Redirecionar URL HTTP para HTTPS com Nginx

Objetivo

Redirecionar URL HTTP para HTTPS com Nginx

Plataforma

Linux e Nginx

Conhecimento

Linux

Introdução

Redirecionar seu dominios em HTTP para domínio HTTPS

Solução

A solução é configurar sites-available para redirecionar o tráfego. O sites-enable tem o link simbólico do sites-available.

#redirecionando para https
server {
	listen 80;
    server_name www.yourdomain.com.br yourdomain.com.br;
    return 301 https://yourdomain.com.br$request_uri;
}
#redirecionando para https com www para sem www
server {
	listen 443 ssl http2;
	access_log  off;
	error_log   off;
	server_name www.yourdomain.com.br;
	return 301 https://yourdomain.com.br$request_uri;
}

server {
	listen 443 ssl http2 default_server;
	listen [::]:443 ssl http2 default_server;
	server_name yourdomain.com.br;

	root /usr/share/nginx/html/yourdomain/public;
	index index.html index.htm index.php;

	ssl on;
    #server config
.
.
.
}
10 de abril de 2018 / rafaelti

Usando partition by no Oracle

Objetivo

Utilizar o partition by no Oracle

Plataforma

Oracle SQL Developer

Conhecimento

Oracle SQL Developer e SQL

Introdução

Em um relatório precisei extrair uma sequência de ocorrência. Deparei com o partition by que facilitou minha vida.

Solução

select
EQP_COD, count(*) OVER (partition by PES_COD order by PES_COD) countpes , row_number() OVER (partition by PES_COD order by PES_COD ) seq
from EQUIPE
order by PES_COD

O resultado será para cada equipe da pessoa sua sequência e seu total.

EQP	countpes	seq
TM02	3		1
TM03	3		2
MM02	3		3
MB03	2		1
TB03	2		2
MB05	2		1
TB05	2		2
CO01	1		1
1 de março de 2018 / rafaelti

Erro emulador Android no Ubuntu 16

Objetivo

Corrigir erro ao emular um dispositivo Android no Ubuntu 16

Plataforma

linux, android

Conhecimento

linux

Introdução

Emular android é um recurso válida para testar o app em desenvolvimento quanto por alguma razão não é possível utilizar um dispositivo físico.

Ao executar o comando:

~/Android/Sdk/tools$ ./emulator -avd Nexus_5X_API_25

O retorno será:

libGL error: unable to load driver: i965_dri.so  
libGL error: driver pointer missing  
libGL error: failed to load driver: i965  
libGL error: unable to load driver: i965_dri.so  
libGL error: driver pointer missing  
libGL error: failed to load driver: i965  
libGL error: unable to load driver: swrast_dri.so  
libGL error: failed to load driver: swrast  
X Error of failed request:  GLXBadContext  
  Major opcode of failed request:  155 (GLX)
  Minor opcode of failed request:  6 (X_GLXIsDirect)
  Serial number of failed request:  55
  Current serial number in output stream:  54
...

O que precisará ser feito é substituição de uma biblioteca.

$ cd ~/Android/Sdk/emulator/lib64/libstdc++
$ mv libstdc++.so.6 libstdc++.so.6.bak
$ ln -s /usr/lib/x86_64-linux-gnu/libstdc++.so.6 libstdc++.so.6

Boa codificação

4 de setembro de 2017 / rafaelti

Envio de email com template no ZF2

Objetivo

Envio de email com template através do ZF2

Plataforma

Linux, ZF2

Conhecimento

ZF2, SMTP

Introdução

Em plataformas web é necessário envio email para seus usuários e clientes. A comunicação com seus usuários e clientes com identidade visual é importante.
Portanto o envio de email com template é essencial.

Solução

Eu criei uma classe como serviço no ZF2. Criei o método abaixo.

 public function sendTemplatedGenericEmail() {        
        $view = new \Zend\View\Renderer\PhpRenderer();
        $resolver = new \Zend\View\Resolver\TemplateMapResolver();
        $resolver->setMap([
            'mailTemplate' => __DIR__ . "/../../../../Application/view/layout/{$this->getTemplate()}.phtml"
        ]);
        $view->setResolver($resolver);

        $viewModel = new ViewModel();
        $viewModel->setTemplate('mailTemplate')->setVariables([
            'username' => $this->getUsername(),
            'userid' => $this->getUserid(),
            'subject' => $this->getSubject(),
        ]);

        $bodyPart = new \Zend\Mime\Message();
        $bodyMessage = new \Zend\Mime\Part($view->render($viewModel));
        $bodyMessage->type = 'text/html';
        $bodyPart->setParts(array($bodyMessage));

        $message = new \Zend\Mail\Message();
        $message->setBody($bodyPart);
        $message->setFrom('***psipsi.com.br', 'PsiPsi Info');
        $message->addTo($this->getToemail());
        $message->addBcc('****gmail.com');
        $message->setSubject($this->getSubject());

        $smtpOptions = new \Zend\Mail\Transport\SmtpOptions();
        $smtpOptions->setHost('******.com')
                ->setConnectionClass('login')
                ->setName('*******')
                ->setPort('999')
                ->setConnectionConfig([
                    'username' => '****psipsi.com.br',
                    'password' => '*******',
                    'ssl' => 'tls',
        ]);

        $transport = new \Zend\Mail\Transport\Smtp($smtpOptions);
        $transport->send($message);
    }

Esse trecho seta o template a ser usado. O getter $this->getTemplate() pega o nome do meu template.

$view = new \Zend\View\Renderer\PhpRenderer();
        $resolver = new \Zend\View\Resolver\TemplateMapResolver();
        $resolver->setMap([
            'mailTemplate' => __DIR__ . "/../../../../Application/view/layout/{$this->getTemplate()}.phtml"
        ]);
$view->setResolver($resolver);

Neste trecho é setado as variáveis, tais como o nome e o assunto do email.

 $viewModel = new ViewModel();
 $viewModel->setTemplate('mailTemplate')->setVariables([
		'username' => $this->getUsername(),
		'userid' => $this->getUserid(),
		'subject' => $this->getSubject(),
	]);

Passamos o nosso template para o corpo do email

 $bodyPart = new \Zend\Mime\Message();
 $bodyMessage = new \Zend\Mime\Part($view->render($viewModel));
 $bodyMessage->type = 'text/html';
 $bodyPart->setParts(array($bodyMessage));

É finalizado o email com as informações faltantes para o email. Os getter: $this->getToemail(), $this->getSubject() fazem o trabalho de preencher.

		$message = new \Zend\Mail\Message();
        $message->setBody($bodyPart);
        $message->setFrom('***psipsi.com.br', 'PsiPsi Info');
        $message->addTo($this->getToemail());
        $message->addBcc('****gmail.com');
        $message->setSubject($this->getSubject());

Configuração do SMTP e envio.

		$smtpOptions = new \Zend\Mail\Transport\SmtpOptions();
        $smtpOptions->setHost('******.com')
                ->setConnectionClass('login')
                ->setName('******.com')
                ->setPort('999')
                ->setConnectionConfig([
                    'username' => '****psipsi.com.br',
                    'password' => '*******',
                    'ssl' => 'tls',
        ]);
		$transport = new \Zend\Mail\Transport\Smtp($smtpOptions);
        $transport->send($message);
1 de julho de 2017 / rafaelti

PHP 7 – Classes anônimas

O suporte a classes anônimas foi adicionado utilizando new class. Isso pode ser utilizado no lugar de definições completas de classes para objetos descartáveis.

<?php interface Logger { public function log(string $msg); } class Application { private $logger; public function getLogger(): Logger { return $this->logger;
    }

    public function setLogger(Logger $logger) {
         $this->logger = $logger;
    }
}

$app = new Application;
$app->setLogger(new class implements Logger {
    public function log(string $msg) {
        echo $msg;
    }
});

var_dump($app->getLogger());
?>

O exemplo acima irá imprimir:

object(class@anonymous)#2 (0) {
}

A documentação completa pode ser encontrada na referência de classes anônimas.

20 de junho de 2017 / rafaelti

PHP 7 – Declarações de tipo de retorno

O PHP 7 adiciona o suporte a declarações de tipo de retorno. Similar as declarações de tipo de argumento, as declarações de tipo de retorno especificam o tipo do valor que será retornado por uma função. Os mesmos tipos estão disponíveis para declarações de tipo de retorno, assim como para declarações para tipo de argumentos.

<?php

function arraysSum(array ...$arrays): array
{
    return array_map(function(array $array): int {
        return array_sum($array);
    }, $arrays);
}

print_r(arraysSum([1,2,3], [4,5,6], [7,8,9]));

O exemplo acima irá imprimir:

Array
(
    [0] => 6
    [1] => 15
    [2] => 24
)

A documentação completa, assim como exemplos de declarações de tipo de retorno pode ser encontrada na referencia declarações de tipo de retorno.

1 de junho de 2017 / rafaelti

PHP 7 – Operador “nave espacial” (spaceship)

O operador nave espacial é utilizado para comparação entre duas expressões. Retornará respectivamente -1, 0 ou 1 quando $a for menor que, igual a, ou maior que $b. As comparações são feitas de acordo com a já conhecida regras de comparação de tipos do PHP.

<?php
// Integers
echo 1 <=> 1; // 0
echo 1 <=> 2; // -1
echo 2 <=> 1; // 1

// Floats
echo 1.5 <=> 1.5; // 0
echo 1.5 <=> 2.5; // -1
echo 2.5 <=> 1.5; // 1

// Strings
echo "a" <=> "a"; // 0
echo "a" <=> "b"; // -1
echo "b" <=> "a"; // 1
?>