Os donos dos encanamentos

Antigamente os ricos tinham terras e o que definia o status e o poder era a quantidade de terras que se tinha. Quanto mais terra, mais vassalos. Quanto mais vassalos, mais mão de obra trabalhando e maior a sua riqueza e poder. As leis, até muito pouco tempo atrás, trabalhavam para que pouquíssimos pudessem, efetivamente, ser donos das terras.

Até muito recentemente tinha-se apenas a posse (e muita área rural ainda é assim) e na troca da posse, os donos da terra ganhavam um pouquinho – isso praticamente virou o ITBI – mas agora você é o dono e quem recolhe este imposto é o governo.

Passaram-se algumas centenas de anos e vivemos a revolução industrial – agora além das terras os ricos tinham outros meios de produzir riqueza e explorar o trabalho alheio: máquinas, fábricas, projetos industriais. Criou-se uma nova classe dos detentores do poder econômico e social: os burgueses, que se estabeleceram com as indústrias de petróleo, transportes e os mercados de capitais para iniciar o processo de empresas centenárias, perpetuando o histórico de concentração de renda.

Chegamos na era da mídia, rádio e TV agora traziam informação, entretenimento e uma nova oportunidade de exibir anúncios e vender produtos para milhares de desavisados.

Enquanto a TV se popularizava a concessão de transmissão era barata e as empresas compraram concessões e tinham lá o seu canal de TV. Eram poucos canais pois era o que era possível transmitir com a tecnologia da época – e conseguir conteúdo não era uma tarefa tão simples. Era uma transmissão direta do canal para o usuário: os canais de TV eram os donos do meio de transmissão, os encanamentos do negócio eram Canal -> usuário.

Eis que vem uma revolução no meio da mídia: a TV a cabo com uma nova maneira de levar canais para centenas de milhares de telespectadores – criou-se um novo sistema de “encanamento” para distribuição de um produto e agora os canais tinham que pagar para uma operadora para conseguirem chegar aos seus usuários – a TV a cabo passou a valer mais do que os canais de TV.

Mais alguns anos chegamos nos meios digitais, o nascimento da internet comercial e logo em seguida a efusão de esperança na democratização do conteúdo com a promessa da “web 2.0”.  O discurso agora era de que muito valor poderia ser criado mesmo se você não tivesse muito capital: uma promessa de que com uma boa ideia de produto ou serviço você poderia criar um excelente negócio.

Agora a burguesia e os donos dos “meios de produção” não tinham como impedir um programador de desenvolver e lançar um produto, ou um escritor ou jornalista de criar o seu blog e gerar e distribuir seu próprio conteúdo para um número infinito de usuários. Surgiu o RSS que fazia essa ligação direta entre público e público. O público tinha controle do que consumir e o produtor tinha finalmente um número virtualmente infinito de audiência, sem intermediários.

Os encanamentos chegaram finalmente na mão da ralé, do peão, dos trabalhadores.

E isso parecia estar funcionando: nasceram Apple, Microsoft, IBM e dezenas de empresas de jogos e software que revolucionaram o mercado computacional e de entretenimento.

Parecia, mas o que não se considerava – mas agora é óbvio em retrospecto – é a astúcia do capitalismo em cooptar inovações, gerar lucro e criar empecilhos para novos entrantes. O capitalista é um especialista em criar estes novos encanamentos, vender como se fosse algo bom para todos – ele vai chamar isso de eficiência e dizer que aumentará a disponibilização de um bem, barateará custos, ou qualquer outro discurso que fique bom em uma notícia paga. E quando o mundo aderir ao seu novo sistema de distribuição logo em breve será pego nem tão de surpresa com a instalação de um relógio medidor, que virá com uma cobrança para que qualquer um que queira utilizar aquele sistema.

Passamos pela nobreza do feudalismo, os burgueses da era industrial e me parece que carecemos de um novo termo para definir os donos dos encanamentos do mundo digital. Minha sugestão é titãs digitais, e estes trabalham incansavelmente para que tudo transite dentro do seu sistema de encanamentos: Google, Facebook, Amazon, Apple.

O Google matou o Google Reader, um leitor de Feed RSS que fazia essa ligação entre criador de conteúdo e público. Recentemente também matou o Google Podcast, que fazia esta mesma conexão com podcasts – agora você tem que usar o Youtube para isso e tanto o criador quanto o público ficam a mercê do obscuro algoritmo que define o que você vai consumir, ou para quem seu conteúdo será entregue.

Se você não utiliza os encanamentos de distribuição deles, você não está fazendo buscas e gerando impressão de anúncio, e acaba não clicando no primeiro resultado patrocinado – da loja que você já conhece mas agora reparte uma considerável do lucro com o Google via adwords.

E os donos dos encanamentos farão de tudo para que nenhum novo sistema de encanamento apareça – e vão gastar recursos com lobby, tecnologia e manipulação de opinião para fechar qualquer gotinha que esteja vazando para fora.

Como testar localmente uma Google Cloud Function com trigger de tópico PubSub

Estou trabalhando em um projeto de monitoramento de dados com Google Cloud Functions e, para agilizar e evitar custos desnecessários, queria testar a ativação de uma GCF com um gatilho de evento (tópico no PubSub)

O primeiro passo é iniciar o emulador de PubSub, nesse caso ele vai rodar na porta 8043, para o projeto odesenvolvedor

Criando um emulador do PubSub

gcloud beta emulators pubsub start \
    --project=odesenvolvedor \
    --host-port='localhost:8043'Code language: JavaScript (javascript)

É esperado que você veja no terminal o log do emulador, com alguns detalhes da exeução e indicando que ele está rodando e em qual porta:

[pubsub] INFO: Server started, listening on 8043Code language: CSS (css)

Você vai precisar criar um tópico, em outro terminal execute:

curl -s -X PUT 'http://localhost:8043/v1/projects/odesenvolvedor/topics/mytopic'Code language: JavaScript (javascript)

Agora vamos especificar o endpoint de assinatura do push

curl -s -X PUT 'http://localhost:8043/v1/projects/odesenvolvedor/subscriptions/mysub' \
    -H 'Content-Type: application/json' \
    --data '{"topic":"projects/odesenvolvedor/topics/mytopic","pushConfig":{"pushEndpoint":"http://localhost:8080/projects/odesenvolvedor/topics/mytopic"}}'Code language: JavaScript (javascript)

Enviando uma mensagem para o PubSub

Com o emulador rodando você pode disparar novas mensagens fazendo um post para o emulador (no nosso exmeplo, localhost:8043) indicando o projeto, tópico e ação.

Para publicar uma mensagem no terminal, você pode usar o comando abaixo, lembrando que o data da mensagem deve estar codificado em base64.

curl -s -X POST 'http://localhost:8043/v1/projects/odesenvolvedor/topics/mytopic:publish' \
    -H 'Content-Type: application/json' \
    --data '{"messages":[{"data":"eyJmb28iOiJiYXIifQ=="}]}'Code language: JavaScript (javascript)

Você também pode usar uma ferramenta como Postman para fazer os envios, configurando método como POST, a url como http://localhost:8043/v1/projects/odesenvolvedor/topics/mytopic:publish e o tipo de conteúdo como application/json, enviando a mensagem no corpo do post.

Rodando uma Cloud Function local que escute o evento

Antes de criar a função, você precisa definir as variáveis de ambiente para que sua função utilize o PubSub do emulador e não tente se conectar ao PubSub da Google Cloud, para isso execute o comando abaixo, trocando o id do projeto:

gcloud beta emulators pubsub env-init
export PUBSUB_EMULATOR_HOST=[::1]:8432
export PUBSUB_PROJECT_ID=odesenvolvedorCode language: JavaScript (javascript)

Com o emulador rodando e sabendo como enviar uma mensagem para um tópico, falta apenas criarmos uma função que ouça o tópico.

Crie a função na sua linguagem favorita, no exemplo abaixo uma função em Python:

import json
import base64

def minha_gcf(event, _context = None):
    payload = base64.b64decode(event['data']).decode('utf-8')
    payload = json.loads(payload)
    print(payload)
    return "OK"Code language: JavaScript (javascript)

Agora é só rodar esta função localmente, avisando que ela deve ouvir os eventos do PubSub:

functions_framework --debug --port 8080 --target=minha_gcf --signature-type=event

O importante aí é o –signature-type=event, mesmo sendo uma função local rodando na porta 8080 ela irá escutar os eventos do PubSub

Ao enviar novas mensagens para seu emulador do PubSub, sua função será executada.

ISPConfig 3.2 e jailkit – problemas para login com ssh

Depois de atualizar o ISPConfig para a versão 3.2 tive problemas com alguns acessos ssh para usuários com jailkit ativo.

Aqui, alguns usuários logo após tentar fazer o login com chave, eram desconectados do ssh.

Como a maioria dos processos de deploy que utilizo neste servidor utilizam rsync, isso travou o deploy das aplicações com este problema.

Baseado neste link e em algumas outras leituras, acompanhei o /var/log/auth.log enquanto autenticava com os usuários e parecia ser um erro de permissão, o resultado era muito parecido com o da thread linkada:

Oct 15 18:46:43 server1 jk_chrootsh[16809]: ERROR: failed to execute shell /bin/bash for user username (5007), check the permissions and libraries of /var/www/clients/client1/web78//bin/bashCode language: JavaScript (javascript)

Logo após isso, o logout do usuário. A barra dupla não é um problema (foi a primeira coisa que achei que poderia ser).

No fim, depois de muitas horas e testes, eu não consegui identificar a causa do problema. As configurações do jailkit estava idênticas as ispconfig.

Tentei fazer o resync dos usuários shell, não retornava erro mas não alterava em nada.

Solução encontrada

O que resolveu aqui, foi bem parecido com o sugerido no final da thread no fórum:

  • Removi todos os usuários shell da conta em questão
  • Na configuração de site, marque na aba options a opção Delete unused jailkit chroot
  • Aguarde a sincronização do ISPConfig ou execute manualmente o update via .sh no server
  • Recrie o usuário shell – isso irá recriar a estrutura de arquivos para o chroot e recriar o usuário

Estes passos resolveram e o acesso voltou a funcionar com o jailkit, mas não consegui identificar a causa (não ocorreu com todos os usuários com jailkit).

Mantendo o WordPress seguro – permissões corretas de arquivos e diretórios

Seguindo as recomendações de segurança do WordPress, as permissões de arquivos devem ser: 755 para diretórios e 644 para arquivos.

Isso pode ser configurado com o comando abaixo (unix):

find . -type d -exec chmod 755 {} \;
find . -type f -exec chmod 644 {} \;Code language: CSS (css)

Para os uploads funcionarem (via wp-admin) é necessário que o usuário do seu servidor (no meu caso, o Apache usa o www-data) tenha acesso a pasta de uploads.

chown www-data:www-data wp-content/uploads

O acesso ao www-data também é necessário no restante dos arquivos se você quiser habilitar o update via painel, instalação de temas e plugins.

Como configurar um domínio com LAMP – (Linux + Apache + MySQL + PHP)

Para quem está começando, algumas configurações de ambiente podem se mostrar realmente difíceis, uma das que tive bastante trabalho foi exatemente para poder rodar um projeto localmente utilizando PHP e por isso achei interessante compartilhar a forma que finalmente deu certo pra mim.

Existem algumas formas de se rodar um projeto localmente, um deles é o formato “LAMP”, que utiliza os softwares (PHP, Apache e MySQL). Após algumas tentativas esse foi o modelo que melhor funcionou para mim.

Instalando o Apache

Primeiro temos que instalar o Apache. Para isso abra seu terminal, para isso você pode procurar em aplicações e selecionar o terminal ou utilizar o atalho (CTRL + ALT + T) e digite os seguintes comandos:

$ sudo apt update
$ sudo apt install apache2

Ao terminar a instalação, confira se já é possível acessar o apache em seu navegador utilizando a url

http://127.0.0.1 ou http://localhostCode language: JavaScript (javascript)

Se a instalação ocorreu conforme esperado, você deverá ver essa imagem:

Instalando MySQL

O próximo passo é instalar um banco de dados, no nosso caso foi escolhido o mySQL. Para isso utilize seu terminal novamente e digite o seguinte comando:

$ sudo apt intall mysql-server

Quando a instalação for completada, ainda temos que configurar o MySQL para deixar mais seguro, para isso podemos rodar o comando:

$ sudo mysql_secure_installation

Isso trará uma série de perguntas no terminal, nos quais você poderá fazer algumas alterações nas opções de segurança da sua instalação do MySQL. O primeiro prompt perguntará se você deseja configurar o plug-in Validar senha, que pode ser usado para testar a força da sua senha do MySQL. Independentemente de sua escolha, o próximo prompt será definir uma senha para o usuário root do MySQL. Digite e confirme uma senha segura de sua escolha.

A partir daí, você pode pressionar Y e ENTER para aceitar os padrões para todas as perguntas subseqüentes. Isso removerá alguns usuários anônimos e o banco de dados de teste, desabilitar os logins raiz remotos e carregará essas novas regras para que o MySQL respeite imediatamente as alterações que você fez.

(opcional) Ajustes de autenticação e privilégios do usuário

O usuário root do MySQL é configurado para autenticar usando o plugin auth_socket por padrão, e não com uma senha. Isso permite maior segurança e usabilidade em muitos casos, mas também pode complicar as coisas quando você precisa permitir que um programa externo (por exemplo, phpMyAdmin) acesse o usuário.

Para usar uma senha para conectar-se ao MySQL como root, você precisará mudar seu método de autenticação de auth_socket para mysql_native_password. Para fazer isso, abra o prompt do MySQL no seu terminal:

$ sudo mysql

Em seguida, verifique qual método de autenticação cada uma das suas contas de usuário MySQL usa com o seguinte comando:

mysql> SELECT user,authentication_string,plugin,host FROM mysql.user;Code language: CSS (css)
Output
+——————+——————————————-+———————–+———–+
| user | authentication_string | plugin | host |
+——————+——————————————-+———————–+———–+
| root | | auth_socket | localhost |
| mysql.session | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE | mysql_native_password | localhost |
| mysql.sys | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE | mysql_native_password | localhost |
| debian-sys-maint | *CC744277A401A7D25BE1CA89AFF17BF607F876FF | mysql_native_password | localhost |
+——————+——————————————-+———————–+———–+
4 rows in set (0.00 sec)
Neste exemplo, você pode ver que o usuário root realmente se autentica usando o plugin auth_socket.

Para configurar a conta raiz para autenticar com uma senha, execute o seguinte comando ALTER USER. Certifique-se de alterar a senha para uma senha forte de sua escolha e observe que este comando altera a senha raiz que você definiu anteriormente:

mysql> ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password';Code language: JavaScript (javascript)

Em seguida, execute FLUSH PRIVILEGES, que instrui o servidor a recarregar as tabelas de concessão e colocar suas novas alterações em vigor:

mysql> FLUSH PRIVILEGES;

Para verificar se o método de autenticação foi alterado:

mysql> SELECT user,authentication_string,plugin,host FROM mysql.user;Code language: CSS (css)
Output
+——————+——————————————-+———————–+———–+
| user             | authentication_string                     | plugin                | host      |
+——————+——————————————-+———————–+———–+
| root             | *3636DACC8616D997782ADD0839F92C1571D6D78F | mysql_native_password | localhost |
| mysql.session    | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE | mysql_native_password | localhost |
| mysql.sys        | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE | mysql_native_password | localhost |
| debian-sys-maint | *CC744277A401A7D25BE1CA89AFF17BF607F876FF | mysql_native_password | localhost |
+——————+——————————————-+———————–+———–+
4 rows in set (0.00 sec)
Você pode ver neste exemplo de saída que o usuário root do MySQL agora é autenticado usando uma senha.

Depois de confirmar isso em seu próprio servidor, você pode sair do shell do MySQL:

mysql> exitCode language: PHP (php)
Nota 1: Se você tiver a autenticação de senha ativada para raiz, conforme descrito nos parágrafos anteriores, será necessário usar um comando diferente para acessar o shell do MySQL. A seguir, você executará seu cliente MySQL com privilégios regulares de usuário e você só obterá privilégios de administrador no banco de dados autenticando:
$ mysql -u root -p

Nota 2: Para eventualmente ver o status, parar ou reiniciar o mysql rode um dos comandos respectivamente:

$ systemctl status mysql.service
$ systemctl stop mysql.service
$ systemctl start mysql.service

Finalmente instalamos o MySQL Workbench, você pode rodar os comandos abaixo ou seguir a documentação oficial na página do mysql :

Primeiro é necessário fazer o download do pacote no repositório:

$ wget https://dev.mysql.com/get/mysql-apt-config_0.8.15-1_all.debCode language: JavaScript (javascript)

Agora entre na pasta onde baixou o arquivo, geralmente em Downloads, e descompacte:

$ cd Downloads
$ sudo dpkg -i mysql-apt-config*.deb
$ sudo apt update

No momento em que você executar o comando acima, um shell interativo será aberto, use o botão TAB e selecione a opção OK, depois pressione o botão ENTER. Finalmente podemos instalar o MySQL Workbench

$ sudo apt install mysql-workbench-community

Instalando PHP e suas dependências

Aqui estão várias dependências do PHP que geralmente são necessárias para se utilizar o LAMP.

$ sudo apt install php autoconf bison build-essential curl gettext libcurl4-openssl-dev libedit-dev libicu-dev libjpeg-dev libmysqlclient-dev libonig-dev libpng-dev libpq-dev libreadline-dev libsqlite3-dev libssl-dev libxml2-dev libzip-dev openssl pkg-config re2c zlib1g-dev libapache2-mod-php php-mysql php-zip

Caso prefira uma instalação menor, instale ao menos as dependências a seguir

$ sudo apt-get install php libapache2-mod-php php-mysqlCode language: JavaScript (javascript)

Após a instalação do PHP e as dependências, é necessário algumas configurações para que o apache procure primeiro por arquivos com extensão .php ao invés de .html.

Para fazer isso será necessário editar o arquivo dir.conf com privilégios de root

$ sudo nano /etc/apache2/mods-enabled/dir.conf

O arquivo dir.conf original se parecerá com isso:

<IfModule mod_dir.c>
    DirectoryIndex index.html index.cgi index.pl index.php index.xhtml index.htm
</IfModule>
/etc/apache2/mods-enabled/dir.conf

Tudo que precisa fazer é mover “index.php” (em destaque) para a primeira posição apoś “DirectoryIndex” como no exemplo a seguir.

<IfModule mod_dir.c>
    DirectoryIndex index.php index.html index.cgi index.pl index.xhtml index.htm
</IfModule>
/etc/apache2/mods-enabled/dir.conf

Quando terminar, salve e feche o arquivo pressionando CTRL + X. Confirme o salvamento digitando Y e pressione ENTER para verificar o local de salvamento do arquivo.

Depois disso, reinicie o servidor da web Apache para que suas alterações sejam reconhecidas. Faça isso digitando o seguinte:

$ sudo systemctl restart apache2

É possível também checar o status do apache usando systemctl

$ sudo systemctl status apache2

Configurando Virtual Hosts

Ao usar o servidor Apache, configure os hosts virtuais para poder acessar os projetos mais facilmente.

Para que o Apache sirva esse conteúdo, é necessário criar um arquivo host virtual com as diretivas corretas. Em vez de modificar o arquivo de configuração padrão localizado em /etc/apache2/sites-available/000-default.conf diretamente, criar um novo em /etc/apache2/sites-available/projeto.localhost.conf usando o comando cp:

$ sudo cp /etc/apache2/sites-available/000-default.conf /etc/apache2/sites-available/projeto.localhost.confCode language: JavaScript (javascript)

Em seguida abra o arquivo com seu editor

$ sudo nano /etc/apache2/sites-available/projeto.localhost.conf

E cole o seguinte bloco de configuração, que é semelhante ao padrão, mas atualizado para o novo diretório e nome de domínio:


<VirtualHost *:80>
ServerAdmin webmaster@localhost
DocumentRoot “/diretório_do_projeto/public

ServerName  projeto.localhost
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory /diretório_do_projeto/public>
Options Indexes FollowSymLinks
Require all granted
AllowOverride All
</Directory>
</VirtualHost>
/etc/apache2/sites-available/projeto.localhost.conf

Observe que DocumentRoot e Directory (em destaque) para o caminho onde estão os arquivos do projeto e ServerName (em destaque) com o mesmo nome do arquivo .conf que está criando “projeto.localhost”.

É necessário habilitar o arquivo que acabou de criar utilizando o comando:

$ sudo a2ensite projeto.localhost.conf

Para testar se está tudo correto, pode utilizar o seguinte comando:

$ sudo apache2ctl configtest
Output
Syntax OK
Esse deve ser o resultado

Altere também o arquivo hosts:

$ sudo nano /etc/hosts

E cole o seguinte bloco de configuração, que é semelhante ao padrão, mas atualizado para o novo diretório e nome de domínio:

127.0.0.1 localhost
127.0.0.1 *.localhost
/etc/hosts

Também é necessário dar as permissões para acessar os diretórios do Path onde está o projeto

$ sudo chown -R $USER:$USER /diretório_do_projeto
$ sudo chmod -R 755 /diretório_do_projetoCode language: PHP (php)

Finalmente reinicie o Apache para implementar as mudanças:

$ sudo systemctl restart apache2

Testando PHP

Para testar se seu sistema está configurado corretamente para PHP, crie um script PHP muito básico chamado info.php. Para que o Apache encontre esse arquivo e o sirva corretamente, ele deve ser salvo no diretório raiz do projeto.

Crie o arquivo na raiz do projeto que você criou na etapa anterior e adicione o seguinte comando:

<?php
phpinfo();
?>
info.php

Quando terminar, salve e feche o arquivo.

Agora você pode testar se seu servidor da web é capaz de exibir corretamente o conteúdo gerado por esse script PHP. Para fazer isso, visite esta página no seu navegador.

O endereço que você deseja visitar é:

http://projeto.localhost/info.phpCode language: JavaScript (javascript)

A página que você acessa deve ter a seguinte aparência:

Após testar, delete esse arquivo info.php.

Pronto, se tudo ocorreu como esperado, agora você poderá acessar seus projetos localmente.

Talvez seja possivel fazer essa mesma configuração de maneira mais enxuta, mas no meu caso, foi seguindo esses passos que deu certo 🙂