Shared posts

20 Jun 04:00

Let’s Encrypt: Delivering SSL/TLS Everywhere

Vital personal and business information flows over the Internet more frequently than ever, and we don’t always know when it’s happening. It’s clear at this point that encrypting is something all of us should be doing. Then why don’t we use TLS (the successor to SSL) everywhere? Every browser in every device supports it. Every server in every data center supports it. Why don’t we just flip the switch?

The challenge is server certificates. The anchor for any TLS-protected communication is a public-key certificate which demonstrates that the server you’re actually talking to is the server you intended to talk to. For many server operators, getting even a basic server certificate is just too much of a hassle. The application process can be confusing. It usually costs money. It’s tricky to install correctly. It’s a pain to update.

Let’s Encrypt is a new free certificate authority, built on a foundation of cooperation and openness, that lets everyone be up and running with basic server certificates for their domains through a simple one-click process.

Mozilla Corporation, Cisco Systems, Inc., Akamai Technologies, Electronic Frontier Foundation, IdenTrust, Inc., and researchers at the University of Michigan are working through the Internet Security Research Group (“ISRG”), a California public benefit corporation, to deliver this much-needed infrastructure in Q2 2015. The ISRG welcomes other organizations dedicated to the same ideal of ubiquitous, open Internet security.

The key principles behind Let’s Encrypt are:

  • Free: Anyone who owns a domain can get a certificate validated for that domain at zero cost.
  • Automatic: The entire enrollment process for certificates occurs painlessly during the server’s native installation or configuration process, while renewal occurs automatically in the background.
  • Secure: Let’s Encrypt will serve as a platform for implementing modern security techniques and best practices.
  • Transparent: All records of certificate issuance and revocation will be available to anyone who wishes to inspect them.
  • Open: The automated issuance and renewal protocol will be an open standard and as much of the software as possible will be open source.
  • Cooperative: Much like the underlying Internet protocols themselves, Let’s Encrypt is a joint effort to benefit the entire community, beyond the control of any one organization.

If you want to help these organizations in making TLS Everywhere a reality, here’s how you can get involved:

To learn more about the ISRG and our partners, check out our About page.

20 Nov 13:51

Robins Tharakan: Explain-Plan-Nodes Grid

While reading up about the various PostgreSQL EXPLAIN Plan nodes from multiple sources, I realized a clear lack of a consolidated grid / cheat-sheet, from which I could (in-one-view) cross-check how the plan nodes perform on a comparative basis. While at it, I also tried to attribute what their (good / bad) characteristics are. Hope this (Work-In-Progress) lookup table helps others on the same
20 Nov 02:49

Baji Shaik: Finally, its.... Slony !! (switchover and failover)

Great tool for replication and using by most of the organizations for replicating b/w different versions of postgres and can do upgrade with minimum downtime(almost 0 sometimes??) and popular tool which I am weak at ... yeah, its SLONY. It was always in my TODO list. So finally, I learned it.. got some hands on.

And I found answer for my own question.. "when was the last time you did something NEW for the first time".

I see a lot posts on installing and configuring Slony, however when I had to do a switchover and failover of Slony for a customer, faced hard time with google. Ok, so better I have it somewhere, why not here !!!.

Customer wanted to upgrade their database from PostgreSQL 8.4 to 9.2. They have around 397 tables and wanted one set for each table hence 397 sets. Just for convenience, I'm taking 10 tables/sets to explain.

Create tables using below script in source(8.4) and target(9.3) databases:
source=# select 'create table slony_tab_'||generate_series(1,10)||'(t int primary key);';
Inserted values using below script in source database:
source=# select 'insert into slony_tab_'||a||' values (generate_series(1,100));' from generate_series(1,10) a;

Configure Slony using below scripts:

1. Init cluser script
#################################################################################################

cluster name = shadow;
node 1 admin conninfo='host=127.0.0.1 dbname=source user=postgres port=5434';
node 2 admin conninfo='host=127.0.0.1 dbname=target user=postgres port=5432';
init cluster (id = 1 , comment = 'Primary Node For the Slave postgres');
#Setting Store Nodes ...
store node (id = 2, event node = 1 , comment = 'Slave Node For The Primary postgres');
#Setting Store Paths ...
echo  'Stored all nodes in the slony catalogs';
store path(server = 1 , client = 2, conninfo = 'host=127.0.0.1 dbname=source user=postgres port=5434');
store path(server = 2, client = 1 , conninfo = 'host=127.0.0.1 dbname=target user=postgres port=5432');
echo  'Stored all Store Paths for Failover and Switchover into slony catalogs ..';

#################################################################################################
2. Create Set Script
#################################################################################################

cluster name = shadow;
node 1 admin conninfo='host=127.0.0.1 dbname=source user=postgres port=5434';
node 2 admin conninfo='host=127.0.0.1 dbname=target user=postgres port=5432';
try { create set (id = 1 ,origin = 1 , comment = 'Set for public'); } on error { echo  'Could not create Subscription set1 for upgrade!'; exit 1;}
try { create set (id = 2 ,origin = 1 , comment = 'Set for public'); } on error { echo  'Could not create Subscription set2 for upgrade!'; exit 1;}
try { create set (id = 3 ,origin = 1 , comment = 'Set for public'); } on error { echo  'Could not create Subscription set3 for upgrade!'; exit 1;}
try { create set (id = 4 ,origin = 1 , comment = 'Set for public'); } on error { echo  'Could not create Subscription set4 for upgrade!'; exit 1;}
try { create set (id = 5 ,origin = 1 , comment = 'Set for public'); } on error { echo  'Could not create Subscription set5 for upgrade!'; exit 1;}
try { create set (id = 6 ,origin = 1 , comment = 'Set for public'); } on error { echo  'Could not create Subscription set6 for upgrade!'; exit 1;}
try { create set (id = 7 ,origin = 1 , comment = 'Set for public'); } on error { echo  'Could not create Subscription set7 for upgrade!'; exit 1;}
try { create set (id = 8 ,origin = 1 , comment = 'Set for public'); } on error { echo  'Could not create Subscription set8 for upgrade!'; exit 1;}
try { create set (id = 9 ,origin = 1 , comment = 'Set for public'); } on error { echo  'Could not create Subscription set9 for upgrade!'; exit 1;}
try { create set (id = 10 ,origin = 1 , comment = 'Set for public'); } on error { echo  'Could not create Subscription set10 for upgrade!'; exit 1;}
set add table (set id = 1 ,origin = 1 , id = 1, full qualified name = 'public.slony_tab_1', comment = 'Table slony_tab_1 with primary key');
set add table (set id = 2 ,origin = 1 , id = 2, full qualified name = 'public.slony_tab_2', comment = 'Table slony_tab_2 with primary key');
set add table (set id = 3 ,origin = 1 , id = 3, full qualified name = 'public.slony_tab_3', comment = 'Table slony_tab_3 with primary key');
set add table (set id = 4 ,origin = 1 , id = 4, full qualified name = 'public.slony_tab_4', comment = 'Table slony_tab_4 with primary key');
set add table (set id = 5 ,origin = 1 , id = 5, full qualified name = 'public.slony_tab_5', comment = 'Table slony_tab_5 with primary key');
set add table (set id = 6 ,origin = 1 , id = 6, full qualified name = 'public.slony_tab_6', comment = 'Table slony_tab_6 with primary key');
set add table (set id = 7 ,origin = 1 , id = 7, full qualified name = 'public.slony_tab_7', comment = 'Table slony_tab_7 with primary key');
set add table (set id = 8 ,origin = 1 , id = 8, full qualified name = 'public.slony_tab_8', comment = 'Table slony_tab_8 with primary key');
set add table (set id = 9 ,origin = 1 , id = 9, full qualified name = 'public.slony_tab_9', comment = 'Table slony_tab_9 with primary key');
set add table (set id = 10 ,origin = 1 , id = 10, full qualified name = 'public.slony_tab_10', comment = 'Table slony_tab_10 with primary key');

#################################################################################################

3. Starting Slon Processes
#################################################################################################
/opt/PostgreSQL/9.2/bin/slon -s 1000 -d2 shadow 'host=127.0.0.1 dbname=source user=postgres port=5434' > /tmp/node1.log 2>&1 &
/opt/PostgreSQL/8.4/bin/slon -s 1000 -d2 shadow 'host=127.0.0.1 dbname=target user=postgres port=5432' > /tmp/node2.log 2>&1 &

#################################################################################################

4. Subscribing the sets.
#################################################################################################
cluster name = shadow;
node 1 admin conninfo='host=127.0.0.1 dbname=source user=postgres port=5434';
node 2 admin conninfo='host=127.0.0.1 dbname=target user=postgres port=5432';
try { subscribe set (id = 1, provider = 1 , receiver = 2, forward = yes, omit copy = false); } on error { exit 1; } echo  'Subscribed nodes to set 1';
try { subscribe set (id = 2, provider = 1 , receiver = 2, forward = yes, omit copy = false); } on error { exit 1; } echo  'Subscribed nodes to set 2';
try { subscribe set (id = 3, provider = 1 , receiver = 2, forward = yes, omit copy = false); } on error { exit 1; } echo  'Subscribed nodes to set 3';
try { subscribe set (id = 4, provider = 1 , receiver = 2, forward = yes, omit copy = false); } on error { exit 1; } echo  'Subscribed nodes to set 4';
try { subscribe set (id = 5, provider = 1 , receiver = 2, forward = yes, omit copy = false); } on error { exit 1; } echo  'Subscribed nodes to set 5';
try { subscribe set (id = 6, provider = 1 , receiver = 2, forward = yes, omit copy = false); } on error { exit 1; } echo  'Subscribed nodes to set 6';
try { subscribe set (id = 7, provider = 1 , receiver = 2, forward = yes, omit copy = false); } on error { exit 1; } echo  'Subscribed nodes to set 7';
try { subscribe set (id = 8, provider = 1 , receiver = 2, forward = yes, omit copy = false); } on error { exit 1; } echo  'Subscribed nodes to set 8';
try { subscribe set (id = 9, provider = 1 , receiver = 2, forward = yes, omit copy = false); } on error { exit 1; } echo  'Subscribed nodes to set 9';
try { subscribe set (id = 10, provider = 1 , receiver = 2, forward = yes, omit copy = false); } on error { exit 1; } echo  'Subscribed nodes to set 10';
#################################################################################################

Till here it is normal, I mean, all can do very easily.... and of-course many sources you can find. However switchover.. failover !!

If you try to insert values in tables of "target" database, it throws below error:
target=# insert into slony_tab_1 values (11);
ERROR:  Slony-I: Table slony_tab_1 is replicated and cannot be modified on a subscriber node - role=0

Ah, its time to SwitchOver and FailOver...

Let us start with Switch-Over script --
cluster name = shadow;
node 1 admin conninfo='host=127.0.0.1 dbname=source user=postgres port=5434';
node 2 admin conninfo='host=127.0.0.1 dbname=target user=postgres port=5432';
lock set (id = 1, origin = 1); sync (id = 1); wait for event (origin = 1, confirmed = 2, wait on = 2); move set (id = 1, old origin = 1, new origin = 2); echo 'Set 1 Has Been Moved From Origin Node 1 To 2 ';
lock set (id = 2, origin = 1); sync (id = 1); wait for event (origin = 1, confirmed = 2, wait on = 2); move set (id = 2, old origin = 1, new origin = 2); echo 'Set 2 Has Been Moved From Origin Node 1 To 2 ';
lock set (id = 3, origin = 1); sync (id = 1); wait for event (origin = 1, confirmed = 2, wait on = 2); move set (id = 3, old origin = 1, new origin = 2); echo 'Set 3 Has Been Moved From Origin Node 1 To 2 ';
lock set (id = 4, origin = 1); sync (id = 1); wait for event (origin = 1, confirmed = 2, wait on = 2); move set (id = 4, old origin = 1, new origin = 2); echo 'Set 4 Has Been Moved From Origin Node 1 To 2 ';
lock set (id = 5, origin = 1); sync (id = 1); wait for event (origin = 1, confirmed = 2, wait on = 2); move set (id = 5, old origin = 1, new origin = 2); echo 'Set 5 Has Been Moved From Origin Node 1 To 2 ';
lock set (id = 6, origin = 1); sync (id = 1); wait for event (origin = 1, confirmed = 2, wait on = 2); move set (id = 6, old origin = 1, new origin = 2); echo 'Set 6 Has Been Moved From Origin Node 1 To 2 ';
lock set (id = 7, origin = 1); sync (id = 1); wait for event (origin = 1, confirmed = 2, wait on = 2); move set (id = 7, old origin = 1, new origin = 2); echo 'Set 7 Has Been Moved From Origin Node 1 To 2 ';
lock set (id = 8, origin = 1); sync (id = 1); wait for event (origin = 1, confirmed = 2, wait on = 2); move set (id = 8, old origin = 1, new origin = 2); echo 'Set 8 Has Been Moved From Origin Node 1 To 2 ';
lock set (id = 9, origin = 1); sync (id = 1); wait for event (origin = 1, confirmed = 2, wait on = 2); move set (id = 9, old origin = 1, new origin = 2); echo 'Set 9 Has Been Moved From Origin Node 1 To 2 ';
lock set (id = 10, origin = 1); sync (id = 1); wait for event (origin = 1, confirmed = 2, wait on = 2); move set (id = 10, old origin = 1, new origin = 2); echo 'Set 10 Has Been Moved From Origin Node 1 To 2 ';

Executing this script gives you this:
-bash-4.1$ /opt/PostgreSQL/9.2/bin/slonik /tmp/Switchover_script.slonik
/tmp/Switchover_script.slonik:4: Set 1 Has Been Moved From Origin Node 1 To 2
/tmp/Switchover_script.slonik:5: Set 2 Has Been Moved From Origin Node 1 To 2
/tmp/Switchover_script.slonik:6: Set 3 Has Been Moved From Origin Node 1 To 2
/tmp/Switchover_script.slonik:7: Set 4 Has Been Moved From Origin Node 1 To 2
/tmp/Switchover_script.slonik:8: waiting for event (1,5000000211) to be confirmed on node 2
/tmp/Switchover_script.slonik:8: Set 5 Has Been Moved From Origin Node 1 To 2
/tmp/Switchover_script.slonik:9: Set 6 Has Been Moved From Origin Node 1 To 2
/tmp/Switchover_script.slonik:10: Set 7 Has Been Moved From Origin Node 1 To 2
/tmp/Switchover_script.slonik:11: Set 8 Has Been Moved From Origin Node 1 To 2
/tmp/Switchover_script.slonik:12: waiting for event (1,5000000224) to be confirmed on node 2
/tmp/Switchover_script.slonik:12: Set 9 Has Been Moved From Origin Node 1 To 2
/tmp/Switchover_script.slonik:13: Set 10 Has Been Moved From Origin Node 1 To 2

-- Now try to insert values in tables of "target" database.. that should allow you.. :-)
target=# insert into slony_tab_1 values(21);
INSERT 0 1

Wow, its done.. isn't it easy.. !!
And now go ahead with failover.. its yours :P
Below is the script for FailOver...
cluster name = shadow;
node 1 admin conninfo='host=127.0.0.1 dbname=source user=postgres port=5434';
node 2 admin conninfo='host=127.0.0.1 dbname=target user=postgres port=5432';
try {failover (id = 1, backup node = 2 );} on error { echo 'Failure Of The Failover For The Set 1  to 2 ';exit 1; }echo 'Failover Has been performed from 1 to 2';

Check if replication is happening..it should not !
so we are done with Switchover and Failover..
Hope this helps to someone. Any comments or suggestion would be appreciated !


16 Nov 00:24

Como se não bastasse ser o país das bikes, Holanda cria agora ciclovias que geram energia limpa

by Redacao_Hypeness
A Holanda, país famoso por suas bikes, agora tem mais um motivo para se orgulhar das ciclovias: um novo bloco inteligente que faz as vezes do asfalto é capaz de criar energia limpa a partir da captação de raios solares. Chamado de SolaRoad, o primeiro protótipo foi instalado na cidade de Krommenie, localizada a 25 […]
15 Nov 19:55

Funcionário Público

Eu nunca quis ser funcionário público.

Como praticamente toda a minha família é de funcionários públicos (mãe, pai, padrasto, irmã, tios, tias, avô…), desde criança sempre ouvi histórias indignantes que eles contavam sobre o lado ruim do funcionalismo: morosidade, politicagem, pilantragem, desperdício, dinossauros…

Minha mãe era uma chefe “durona”, que botava todos pra trabalhar sério e lutava por mudanças, mas sofria para conseguir melhorar, modernizar, informatizar as coisas. Tudo era muito difícil de fazer acontecer. Mas apesar de tudo, até hoje ela valoriza a carreira pública e sempre sonhou que um dia eu também a seguisse.

Porém, eu sou a ovelha negra da família, sou o desajustado.

Além de ter aversão ao funcionalismo, eu também me ejetei da iniciativa privada e decidi seguir um estilo de vida hippongo-alternativo: fui desempregado por opção durante 8 anos.

Até que…

Num belo dia, estava eu em casa, feliz, curtindo minha vida de desempregado, trabalhando em algum de meus projetos pessoais. De repente, minha querida esposa Mog me diz:

— Ah, você tem um concurso pra fazer este domingo, tá?
— Como assim???!?!?111¡¿

Isso foi em 2009. Sem eu saber, a Mog me inscreveu no concurso da prefeitura de Joinville. Ela só me contou na última hora e me convenceu a ir fazer a prova.

“Vai, sem compromisso, só pra ver como é a prova…”

Fiz a prova de cabeça fria, sem a pressão do “tenho que passar” e até que fui bem. Me classifiquei em 21º na vaga de Analista de TI. Como eram somente 9 vagas e eu estava longe na fila, esquecemos desse concurso.

— ∞ —

Pula quatro anos, para agosto de 2013.

Continuo feliz na minha vida de desempregado. Toca o telefone, era do RH da prefeitura. Eu nem lembrava mais desse concurso. Meu interesse nele continua zero. Mais uma vez, a Mog, manipuladora master, me convenceu a ir:

“Pelo menos vá lá conversar para saber como é a vaga. Você não é obrigado a aceitar.”

Fui. Minhas expectativas eram as piores possíveis:

  • Deve ser uma vaga de suporte técnico.
  • Deve ser tudo Windows.
  • Deve ser um bando de véios dinossauros.
  • Devem programar em COBOL ou algo assim.
  • Deve ser uma mamata com muito tempo ocioso.
  • O chefe deve ser um político sem noção.
  • As decisões devem ser políticas e não técnicas.

Para minha total e completa surpresa, nada disso se confirmou.

A vaga era para o setor de Desenvolvimento de Software (na mosca), com expediente de 6h/dia (sobra tempo pros meus projetos) para programar (perfeito) em Ruby on Rails (massa), PHP (ok) e ASP.NET (blé), com servidores Linux (show), bancos de dados modernos (show) e usando Git para controle de versão (show). O coordenador e o gerente também eram analistas de TI, os caras da equipe eram de minha idade, e tinha muito, muito trabalho a ser feito.

(Som de armadilha sendo acionada)

E assim amiguinhos, um desempregado convicto foi reassimilado pelo sistema.

Minha mãe ficou mega feliz, minha sogra ficou feliz, e todos os membros da família que se preocupavam com meu futuro, apaziguaram-se. Um arco-íris encantado decorou o céu de Joinville. Enquanto isso, eu e a Mog estávamos curiosos para saber quanto tempo eu duraria lá dentro…

— ∞ —

Em setembro de 2014 completei um ano de prefeitura.

A imagem (preconceito) que eu tinha, do funcionário público preguiçoso, se desfez. Há muito trabalho a fazer e muita gente disposta a trabalhar pesado. As maçãs podres existem, claro, mas são a minoria.

Trabalhei bastante, aprendi tecnologias novas (Rails), velhas (Oracle) e pude aplicar e aprimorar meu conhecimento em várias áreas nerds. Também reaprendi a trabalhar em grupo, após tantos anos seguindo solo.

A maior parte desse primeiro ano eu fui o programador responsável pelo sistema de controle imobiliário da cidade, que gerencia imóveis, proprietários, logradouros, mapas, fotos, certidões, relatórios…

Me orgulho de ter conseguido migrar o seu enorme banco de dados de Oracle (caríssimo) para o PostgreSQL (gratuito), poupando os cofres públicos desse gasto.

É o maior sistema que já mexi, com centenas de arquivos-fonte e centenas de tabelas no banco de dados. É um sistema legado, criado na jurássica versão 1 do Ruby on Rails por uma empresa terceira. O maior desafio foi entender o seu funcionamento, pois não há documentação (claro), o código não é bonito nem comentado, e em boa parte não adere ao MVC nem às convenções do Rails.

Atualizar a versão do Rails (1→4) seria um sonho, mas… complicado.

— ∞ —

Em agosto de 2014 fui convidado para ser o coordenador do meu setor.

Ser chefe não é o meu perfil (eu gosto de executar, não delegar), mas aceitei pelo desafio e pelo aprendizado. O cargo mudou, o salário aumentou e passei a trabalhar 8h (ou mais) por dia.

Até hoje estou lá, aprendendo a gerenciar chamados, pessoas e projetos. Não estou feliz nessa nova rotina, mas vale pela experiência.

— ∞ —

Então é isso. Passei de desempregado profissional a funcionário público. Por enquanto :)

Ah, antes que eu me esqueça: meu desktop no trabalho é um Windows 7 :P

13 Nov 20:45

Oli Warner: Putting the Secure in SSH; hardening your shell server against most attacks

SSH is the de facto remote access technique for Ubuntu and Linux servers and yet some of the defaults you'll get from sudo apt-get install ssh can be downright dangerous in the wrong circumstances. This article will steer you around the biggest pitfalls to keep your server's front door well protected.

Stop logging in as root directly Use key-based authentication and disable password authentication Block brute-force attackers with fail2ban Move the SSH server to another port Network isolation Ideas for going further

Good security is all about layers.

It's not enough to pick a strong password or hide your SSH server. You need to take multiple approaches to wrap your server. Ubuntu gives you fairly sane application defaults but in terms of actual security, it's only going to stop you setting a <6 character password. Installing SSH on a brand new Ubuntu install with a weak password can result in a near-instant hack.

I'm suggesting the following in order of importance. They can be applied independently but I would strongly suggest using all of them. There are some extension ideas at the end for the really paranoid.

And none of these is a substitute for other good-security practices. Keep your packages and websites updated, don't run things you don't need and use a firewall so only the right services are exposed to the internet.

Stop logging in as root directly

Generally speaking you shouldn't need to run as root to get things done. Modern systems have utilities like sudo that make group-based permissions easy to allocate. I'm not going to enumerate all the reasons for not using root directly here but for the purposes of attacking a server, if root login is allowed, the attacker knows the username it should be attacking. If you disable it, they would also need to guess your username. Layers, baby.

So if you're still running everything as root, let's change that. Log into the server (as root) and we'll start by creating a user in the sudo group. If you're using an Ubuntu machine from before 12.04 —or one updated from then— you may need the admin group.

adduser <username> sudo

Try logging in as that user and make sure commands like sudo whoami work (it uses the account's password, not root's). Then we need to disable root login. This is a two-pronged attack. We'll start by removing the root password:

sudo passwd -l root

Then we'll explicitly disable root access via SSH by running:

sudo sed -ir 's/^(PermitRootLogin) .+/\1 no/' /etc/ssh/sshd_config
sudo /etc/init.d/ssh restart

Use key-based authentication and disable password authentication

A strong passphrase might keep you secure enough today but the botnets of tomorrow are going to chow through 20+ char phrases. What is impossible today will be childsplay in ten years time.

Key-based authentication uses algorithmic signing to verify a challenge/response and encrypt traffic between server and host. You keep a private half of the key in your $HOME/.ssh/ directory and upload a public hash to the server (under the remote users' $HOME/.ssh/authorized_keys file).

While theoretically still crackable, it makes your "password" thousands of characters long and full of punctuation; essentially impossible to crack within the lifetime of any would-be attacker, even factoring in the advance of computing.

There are multiple types of key cryptography on offer. DSA and RSA are probably strong enough and are supported everywhere. Newer versions of Ubuntu support elliptical-curve algorithms. These are shorter and generally considered stronger encryption than a similar RSA or DSA keypair counterpart (please feel free to correct me in the comments).

Anyway, let's create a key on the client. I'm using the fancy newer ed25519 crypto (suitable for 14.04 but not 12.04 clients and servers). If you need 12.04 support, use -t rsa.

ssh-keygen -t ed25519

This will give you an opportunity to add a password to your key. This is optional but it does make it two-factor authentication (something you have, something you know). Certainly worth considering if you feel there's any risk of your private key falling into the wrong hands before you can revoke it.

When you're done there, let's upload the public half:

ssh-copy-id user@my.host

ssh-copy-id supports a -p <port> argument if your sshd already lives on a port other than 22.

OSX users can use a bit of simple scripting to emulate ssh-copy-id:

cat ~/.ssh/id_ed25519.pub | \
  ssh user@my.host "mkdir -p ~/.ssh; cat >> ~/.ssh/authorized_keys"

It's a bit harder in Windows. You're probably limited to RSA/DSA. The procedure is essentially:

  • Download and generate a key with PuTTYgen
  • Install the key in PuTTY
  • Upload the .ppk file to the server
  • Convert and insert your public key into ~/.ssh/authorized_keys
    ssh-keygen -i -f id.ppk >> ~/.ssh/authorized_keys
    

You should be able to log in without a password now with just ssh user@my.host. Once all your SSH users have keys, and you have tested them, we can disable password login. Run sudoedit /etc/ssh/sshd_config and change

sudo sed -ir 's/^#?(PasswordAuthentication) .+/\1 no/' /etc/ssh/sshd_config
sudo /etc/init.d/ssh restart

Before you close you current connection to the server, test the following in new local terminals:

  • ssh user@my.host should work still, and
  • ssh -o PubkeyAuthentication=no user@my.host should deny entry.

Block brute-force attackers with fail2ban

Even with an "uncrackable" authentication method, we shouldn't be over-confident. Why would we want to let people keep attacking our a once we know they're trying to maliciously attack it? fail2ban is a great system that watches various log files for bad login attempts (amongst other things). If a number of failed attempts come from one IP within a certain timeframe, that IP is blocked for five minutes.

This level of time-ban isn't going to ruin your life if you accidentally need to try five or six attempts at legitimately remembering your password but it's going to completely arrest a true brute force attempt by limiting it to 72 attempts an hour. Given they would likely need to attempt billion of billions to crack your key-based auth, attackers will very quickly give up when faced with that throughput.

Installation is dead simple too:

sudo apt-get install fail2ban

It ships with a number of filters. /ets/fail2ban/filters.d/ contains the configurations for discovering perpetrators and /ets/fail2ban/jail.{conf,local} handle how they're dealt with. There are SSH rules included by default.

Move the SSH server to another port

Every bot scanning for exploitable and crackable SSH servers is looking on port 22. Let's move your SSH server off to a port other than 22.

Some people claim this is mere "security through obscurity" but they're clearly not paying attention. Security through obscurity refers to situations when secrecy is your only line of defence. Having a hidden but otherwise open door, for example. We still have all our other security. We're just adding a layer of camouflage.

This won't stop a directed attack. Somebody checking all your ports will find it but that does take extra time and that means it stops the everyday people scanning for exploits.

The first thing to do is pick a port. You have a huge choice but I would suggest something in the 10,000-64,000 range that isn't already taken and most importantly, something that isn't in use by your server currently. Once you have that, log into the server and run:

sudo sed -ir 's/^(Port) .+/\1 12345/' /etc/ssh/sshd_config
sudo /etc/init.d/ssh restart

Obviously change the port number to the one you want. Finish by restarting SSH: It is critical that you test this on the new port before you disconnect your current session. Open a new session in a new client terminal:

ssh -p 12345 user@my.host

If that doesn't work, something's sqwonk.
Check /etc/ssh/sshd_config for obvious issues, fix them and try again.

You can make things easier by editing your local ~/.ssh/config to tell it about your new server configuration:

Host my.host
    User user
    Port 12345

Then you'll be able to run ssh my.host and you'll be straight in.

Network isolation

So a bunch of computers in China and Russia are still trying to crack your SSH server? Well, why do they have access to it in the first place? Most people only access their server from a limited number of networks. You have a couple of choices here.

You can whitelist a few addresses if you have static outgoing addresses. This is obviously unsuitable for people who are on dynamically assigned IPs (unless you know every IP your ISP can allocate you) but works well if you're on a static IP or can route your connection through one. To enable this we run sudoedit /etc/ssh/sshd_config and add a line like:

AllowUsers *@1.2.3.* *@7.8.9.*

This is the equivilent of whitelisting any user from the 1.2.3.0/24 and 7.8.9.0/24 subnets. You can add wildcards further up the IP to widen the net. It wouldn't take too long to work out your ISP's entire range and enter that in. Similarly you could just add a single IP if you want to limit it to a single IP. Once you've done that, sudo /etc/init.d/ssh restart and test that it works before you disconnect.

If that's impractical (because you hop between too many networks, you could adopt a GeoIP blocking in IPTables.

And if you have more than one server, you could designate one as the main SSH server and limit SSH connections to the others from that server's IP. It complicates some connections (like deep SFTP access) but it ultimately protects the herd.

Ideas for going further

By this point we're blocking all but the most concentrated attacks. Somebody is going to need a colossal botnet and more than one lifetime to crack your system through conventional means. There is still the risk that somebody could discover your SSH port and deploy an exploit against an unpatched vulnerability.

I can offer you here are a few more ideas for further obfuscating access to the SSH server:

  • Port-scan detection and blocking using psad. This rate-limits your discovery but is circumventable with enough bots; there are single botnets big enough to handle one port each.

  • Port knocking keeps the port locked down until a client taps the right sequence of ports. It's like adding a mined garden path up to your door. However, this would happen in the open and could be sniffed on the local network. Plus it's a pain in the arse if you don't have a knock client.

Whichever combination of solutions you end up going with, remember that SSH isn't the only way into a system. Make sure you use a firewall to block access to services that don't need to be externally (ufw is a good one for Ubuntu users, just make sure you allow your new SSH port before you activate it) and keep things (including popular web-scripts like Wordpress and Drupal) up to date.

And if none of this meant anything to you, perhaps you shouldn't be running a web-accessible server. I don't mean that in an unkind way but just because anybody can afford to rent a VPS these days, doesn't mean they're ready for the job of looking after it. Keeping on top of security can be miserable at times. If you think you fall into that bracket, by all means learn on Ubuntu at home but go with managed web services. Or hire me or some other chump to look after your server for you.

13 Nov 14:52

Andrew Dunstan: Assignment beats SELECT INTO

While working on some customer code, I noticed that they have a lot of code that reads like this:
SELECT a,b,c
INTO foo.x, foo,y, foo.z;
I wondered why they were doing it that way, and if it might be easier to read if it was just:
foo := (a,b,c);
Now, these aren't quite the same, especially if foo has more than three fields. But even that could be got around.

But before I tried this out I decided to see how they performed. Here's what happened:
andrew=# do $x$ 
declare
r abc;
begin
for i in 1 .. 10000000
loop
select 'a','b',i into r.x,r.y,r.z;
end loop;
end;
$x$;
DO
Time: 63731.434 ms
andrew=# do $x$ 
declare
r abc;
begin
for i in 1 .. 10000000
loop
r := ('a','b',i);
end loop;
end;
$x$;
DO
Time: 18744.151 ms
That's a very big difference! Direct assignment takes less than 30% of the time that SELECT INTO takes.

I'm going to dig into why this happens, but meanwhile, I have quite a lot of low hanging performance fruit to pick as a result of this.
13 Nov 12:30

Mosh, um substituto para o SSH

by Raphael Amorim

Se você usa SSH constantemente, provavelmente alguma vez você já deve ter se irritado quando sua conexão estava lenta. Seja na demora das respostas dos comandos enviados ou até mesmo digitando algo.

mosh

Para resolver problemas com conexões e outros, surgiu o Mosh (mobile shell). O mosh é uma ferramenta utilizada para se conectar a partir de um computador cliente para um servidor através da Internet, para executar um terminal remoto.

Mosh é semelhante ao SSH (entenda como aplicação para linha de comando e não como protocolo) com recursos adicionais destinados a melhorar a usabilidade. Mais robusto e ágil, especialmente através de Wi-Fi e celulares.Você consegue usar no xterm, gnome-terminal, urxvt, Terminal.app, iTerm, emacs, screen, tmux e outros.

Você pode começar uma conexão SSH de casa no seu laptop, ir trabalhar e voltar como se nada tivesse acontecido. Ou seja não há conexão de sessão, você pode colocar seu laptop em modo sleep e quando retornar a conexão fica intacta.

Se você ficar sem acesso a internet, o Mosh vai te alertar. Porém quando a internet voltar, a conexão irá funcionar tranquilamente e ainda de onde você estava.

Excelente em conexões lentas, também como rápidas. Talvez a maior vantagem do Mosh sejaevitar e fugir de problemas com lag. Sabemos queo SSH aguarda a resposta do servidor antes de te mostrar sua própria digitação.

O Mosh é diferente: ele dá uma resposta instantânea a digitação, exclusão e edição. Ele faz isso de forma adaptativa, funcionando tranquilamente em programas que usam tela cheia como recurso (ex: vim e emacs). Em uma conexão ruim, digitações pendentes são sublinhadas, assim você não será enganado.

Outra vantagem é o famoso Control-C funcionar perfeitamente.

Diferente do SSH, o Mosh é um protocolo baseado em UDP, logo ele lida muito bem com a perda de pacotes e define a taxa de quadros com base nas condições de rede.

Sim, o Mosh é incrível e vocêprovávelmentedeveestar se perguntando: “Como eu começo a usar o mosh?” Basta acessar o site oficial do Mosh. Lá tem toda documentação de instalação até usabilidade.

O melhor de tudo é o Mosh ser software livre, disponível para GNU/Linux, FreeBSD, Solaris, Mac OS X, and Android.

 

Mensagem do anunciante:

Torne-se um Parceiro de Software Intel®. Filie-se ao Intel® Developer Zone. Intel®Developer Zone

12 Nov 20:57

Valendo: Empresas têm que entregar 80% da velocidade contratada na banda larga

by Augusto Campos

Via g1.globo.com:

A partir do último sábado (1º), ficaram mais rigorosos os limites mínimos da velocidade de banda larga fixa e móvel que deve ser entregue pelas operadoras aos seus clientes. Pela regra definida pela Agência Nacional de Telecomunicações (Anatel), esse o mínimo passa a ser de 80% da velocidade contratada.

Isso significa que, num plano de 10 MBps (megabits por segundo), a média mensal da velocidade fornecida pela operadora deve ser de 8 MBps, no mínimo.

A regra faz parte do regulamento de Gestão da Qualidade nos serviços de Comunicação Multimídia

O artigo "Valendo: Empresas têm que entregar 80% da velocidade contratada na banda larga" foi originalmente publicado no site BR-Linux.org, de Augusto Campos.

12 Nov 17:51

Josh Berkus: Finding Foreign Keys with No Indexes

Unlike some other SQL databases, PostgreSQL does not automatically create indexes on the "child" (in formal language "referencing") side of a foreign key.  There are some good reasons for this (see below), but it does give users another opportunity to forget something, which is indexing the foreign keys (FKs) that need it.  But which ones need it?  Well, fortunately, you can interrogate the system catalogs and find out.

I have added a query for finding foreign keys without indexes to pgx_scripts.  Indexes on the "parent", or "referenced" side of the FK are automatically indexed (they have to be, because they need to be unique), so we won't talk about them further.

Now, in order to understand how to interpret this, you have to understand why you would or would not have an index on an FK, and what sort of indexes are valid.  There's two times that indexes on the child side of FKs are used:
  • when doing JOIN and lookup queries using the FK column
  • when updating or deleting a row from the "parent" table
The second occasion is news to some DBAs.  The way it works is this: before letting you delete or change a row in the "parent" table, Postgres has to verify that there are no rows in the "child" table referencing the FK value that might be going away.  If there are, it needs to perform the action you have defined (such as CASCADE, SET NULL or RESTRICT).  If the "child" table is large, this can be substantially speeded up by having an index on the FK column.

This means that it's important to have an index on the child side of the FK if any of the following are true:
  • The child table is large and the parent table gets updates/deletes
  • The parent table is large and the FK is used for JOINs
  • The child table is large and the FK is used to filter (WHERE clause) records on the child table
This means most FKs, but not all of them.  If both tables are small, or if the parent table is small and the FK is used only to prevent bad data entry, then there's no reason to index it.  Also, if the FK is very low cardinality (like, say, only four possible values) then it's probably also a waste of resources to index it.

Now you're ready to run the query on your own database and look at the results. The query tries to filter for the best indexing candidates, but it is just a query and you need to use your judgement on what you know about the tables.  The query also filters for either the parent or child table being larger than 10MB.

Now, you might say "but I have an index on column Y" and wonder why it's appearing on the report.   That's probably because the FK does match the first columns of the index.  For example, an index on ( name, team_id ) cannot be used for an FK on team_id.

You may notice a 2nd section of the report called "questionable indexes".  These are FKs which have an index available, but that index may not be usable for JOINs and constraint enforcement, or may be very inefficient.  This includes:
  • Non-BTree indexes.  Currently other types of indexes can't be used for FK enforcement, although that is likely to change in future Postgres versions.  But they can sometimes be used for joins.
  • Indexes with more than one column in addition to the FK columns.  These indexes can be used for FKs, but they may be very inefficient at it due to the bigger size and extra index levels.
  • Partial indexes (i.e. INDEX ... WHERE).  In general, these cannot be used for FK enforcement, but they can sometimes be used for joins.
It's not quite as clear when you want to add to, or replace those indexes.  My advice is to start with the missing indexes and then move on to the more nuanced cases.




    12 Nov 00:08

    Mischa Spiegelmock: MySQL vs PostgreSQL - Why You Care

    Like many others before and since, my introduction to the world of databases was via MySQL. It was a good enough database that did what I wanted, so I was content to use it without realizing what I was missing out on.

    Comparing MySQL to PostgreSQL is a bit like comparing notepad.exe to emacs. While they both let you type in some text and save it to a file, that doesn’t quite tell the whole story. They are both RDBMSes that allow for the execution of queries via a client connection, but the philosophies, capabilities and sophistication of each are hardly even on the same plane of existence.

    The way I think about it is that MySQL is a simple database program. Technically it does have pluggable engines; you can choose between a terrifically useless engine and one that at least knows what a transaction is. I consider Pg more of a “database framework”: an incredibly sophisticated and flexible program that provides a standard frontend interface, much as emacs ties everything together through “modes” and elisp, Pg has a C client library and speaks SQL.
    To give you a more concrete example of what I mean, in Pg you can create “foreign data wrappers”, where the actual implementation of a query can be defined by a plugin. One example of a foreign wrapper is “MySQL" - you connect to Pg like normal through your client library and run a SQL query, but it’s actually executed on a remote MySQL server and presented as a table view in Pg. Or perhaps your query is auto-parallelized and distributed among many mongoDB nodes instead. No big deal.
    Pg also has an astonishingly powerful set of extensions. My absolute favorite is PostGIS, a geospatial extension that adds geographic and geometric types, operators, indexed storage and much much more. Seeing a demo of it at the SFPUG meetups blew my mind, and I’ve been an avid user of it ever since.
    Did I mention it also has a full-text search capability every bit as useful as Solr or ElasticSearch, with stemming and your choice of GIN or GiST indexes? My life is so much better now that I can simply use a trigger to keep my tsearch columns updated instead of application-level logic to keep Solr indexes in sync.
    Pg is chock-full of awesomesauce that I’ve used to replace many moving parts of my application. I chucked out Solr and replaced it with PostGIS and tsearch. Also I ditched ZeroMQ (nothing against ZMQ - it’s a great project) and just use Pg’s built-in async message queue instead. Oh, you didn’t know it had a message queueing system? As a matter of fact it does, and I gave a talk on it for SFPUG at UC Berkeley, coincidentally a few feet from where the precursor to Postgres was first written. In my talk I showed how to construct a location-based storage engine using PostGIS and a single trigger, which would fire off an async notif of JSON-encoded lat/lng updates whenever a row was inserted or updated. Add in a WebSocket<->Pg client/server (such as the esteemed WSNotify) and you have a real-time event push system that notifies a JavaScript browser client whenever a location field on a row is changed, all without a single line of application code (other than the SQL trigger). Let’s see MySQL do that. (Slides and example code are here: https://github.com/revmischa/pgnotify-demos)

    We all love fancy features and reducing the number of moving parts in our infrastructure, but I actually think the most compelling argument for Pg is that it is an community-driven project and is not owned by Oracle. MySQL is not an open project, and it is owned by Oracle. One does not need to look far for bone-chilling examples of Oracle’s management of open-source database projects. Let’s talk about BDB.
    BDB, the Berkeley DataBase, was a nice little embedded database engine used by many pieces of software dating all the way back to 1994. Any of the maintainers of software using BDB might be in for a bit of a nasty shock should they decide to upgrade to the latest version, now that Oracle’s acquired the software and changed the terms of the license. Now they have two options which are helpfully explained on Oracle’s website.
    You can choose from option A - the “open source” version, or you can choose option B - the “pay Oracle money” version. That webpage does seem to leave out one minor little detail though, the “open source” version is actually the Affero GPL. The AGPL sounds a lot like the GPL but with an important difference – not only does it require any programs you distribute to provide the source code, but also covers server software as well (N.B. I am totally not a lawyer and probably don’t know what I’m talking about).
    Many projects sort of skirt around the requirements of sharing their code even though they use GPL software because they don’t actually distribute binaries, instead they just run a server and let it communicate to clients. The AGPL was designed to close that rather sizable loophole. What this means in practice is that the thousands of existing commercial products that use BDB, or use code that uses BDB, are all going to be prevented from upgrading to the latest BDB unless they make their product open source… or choose option B (cough up the dough).
    You gotta give Larry props for that one. I respect him and am very pleased with the fact that at least someone in this world is willing to go full James Bond villain, complete with tropical island fortress. However I’ll stick with the community-run project for my database system.
    Last point to make here: there is clearly a hard limit on how good MySQL is going to be able to get. If it was truly awesome and powerful, why would anyone need to buy Oracle DB?

    Well at this point you might be saying “gee, that PostgreSQL option does sound pretty nifty, but how on Earth am I going to switch my existing application to Postgres?” Worry not, friend. There is a very handy DB dump conversion tool (mysql2pgsql) which does the job for you. I used it myself and had a bit of trouble with converting BLOBs and some ordering of foreign keys, but I was able to patch those problems up quite easily and get my changes upstream, so no big deal. I switched in 2012 or so and haven’t looked back since.

    Finally, the PostgreSQL community is wonderful. I have always had a great time at the SF postgres user group and seen some amazing stuff people do with it that you would never imagine could be done with your database server if you’re stuck in the tiny MySQL world. Go check it out.

    I watch this video every day:

    11 Nov 18:46

    David Tomaschik: Towards a Better Password Manager

    The consensus in the security community is that passwords suck, but they're here to stay, at least for a while longer. Given breaches like Adobe, ..., it's becoming more and more evident that the biggest threat is not weak passwords, but password reuse. Of course, the solution to password to reuse is to use one password for every site that requires you to log in. The problem is that your average user has dozens of online accounts, and they probably can't remember those dozens of passwords. So, we build tools to help people remember passwords, mostly password managers, but do we build them well?

    I don't think so. But before I look at the password managers that are out there, it's important to define the criteria that a good password manager would meet.

    1. Use well-understood encryption to protect the data. A good password manager should use cryptographic constructions that are well understood and reviewed. Ideally, it would build upon existing cryptographic libraries or full cryptosystems. This includes the KDF (Key-derivation function) as well as encryption of the data itself. Oh, and all of the data should be encrypted, not just the passwords.

    2. The source should be auditable. No binaries, no compressed/minified Javascript. If built in a compiled language, it should have source available with verifiable builds. If built in an interpreted language, the source should be unobfuscated and readable. Not everyone will audit their password manager, but it should be possible.

    3. The file format should be open. The data should be stored in an open, documented, format, allowing for interoperability. Your passwords should not be tired into a particular manager, whether that's because the developer of that manager abandoned it, or because it's not supported on a particular platform, or because you like a blue background instead of grey.

    4. It should integrate with the browser. Yes, there are some concerns about exposing the password manager within the browser, but it's more important that this be highly usable. That includes making it easy to generate passwords, easy to fill passwords, and most importantly: harder to phish. In-browser password managers can compare the origin of the page you're on to the data stored, so users are less likely to enter their password in the wrong page. With a separate password manager, users generally copy/paste their passwords into a login page, which relies on the user to ensure they're putting their password into the right site.

    5. Sync, if offered, should be independent to encryption. Your encryption passphrase should not be used for sync. In fact, your encryption passphrase should never be sent to the provider: not at signup, not at login, not ever. Sync, unfortunately, sounds simple: drop a file in Dropbox or Google Drive, right? What happens if the file gets updated while the password manager is open? How do changes get synced if two clients are open?

    These are just the five most important features as I see them, and not a comprehensive design document for password managers. I've yet to find a manager that meets all of these criteria, but I'm hoping we're moving in this direction.

    07 Nov 12:29

    Tropeçando 62

    by rafael
    05 Nov 13:43

    Receita passa a taxar serviços de hospedagem no exterior

    by Ronaldo Gogoni

    datacenter

    E mais uma vez a Receita Federal faz das suas. Nós sabemos que o mercado de tecnologia brasileiro, especificamente serviços de hospedagem de dados não são muito baratos por aqui e vira e mexe costumam dar problema. Pode não representar muita diferença para uma pessoa física, mas para uma grande empresa contar com datacentes de companhias como IBM, SAP, Oracle, Amazon, Microsoft e outras pode significar uma economia muito grande no fim do mês.

    Pois bem, isso acabou. De olho nesse crescente mercado e motivada por pressão das empresas locais, a Receita Federal irá através do Ato Declaratório nº 7, publicado no Diário Oficial da União na última sexta-feira cobrar impostos e taxas das empresas que possuem contratos de serviços de armazenamento e processamento de dados com provedores no exterior. E a conta não sairá barata.

    Hoje, contratar serviços de hospedagem fora do país se mostra um negócio muito vantajoso, visto a grande concorrência das empresas que levam a preços bem competitivo. Em média, contratar um datacenter lá fora sai em torno de 15% mais em conta do que utilizar um daqui, isso sem contar as vantagens no que diz respeito à infraestrutura, suporte e segurança. Isso meio que ajuda a preterir as companhias brasileiras em prol das estrangeiras, causando algo que o governo abomina: fuga de divisas.

    A resolução da Receita Federal é um ato declaratório interpretativo, em que ela entende que um datacenter é um serviço e não uma locação de bem móvel. Com essa manobra, o governo os enquadrou nas regras de importação dos mesmos e irá cobrar impostos e taxas das empresas que contratam tais serviços lá fora, criando a velha situação em que para privilegiar o mercado nacional, oneram-se ambos mas de forma a tornar os de empresas brasileiras mais atraentes, financeiramente falando.

    leao-receita-federal

    Para variar o Leão vai morder e com força. As empresas passarão a recolher IRRF (Imposto de Renda Retido na Fonte), Cide-Royalties (Imposto de Intervenção no Domínio Econômico destinada a financiar o Programa de Estímulo à Interação Universidade-Empresa para o Apoio à Inovação), PIS/Pasep e Cofins, além de IOF para operações de crédito e incidência municipal do ISSQN (Imposto Sobre Serviços de Qualquer Natureza). Algumas empresas grandes já pagam esses tributos, mas quem não se enquadra hoje passará a ver o dinheiro escoar ainda mais. O grande problema é que a decisão é um alinhamento à Normativa 1.277 de 2012, que pressupões que empresas contratantes de datacenters já recolhiam impostos há dois anos. Para quem o fez nada muda, mas para quem entendia a questão como locação de bem móvel poderá se ver às voltas com cobranças retroativas de impostos.

    Basicamente, a incidência de impostos acarretará um aumento de até 50% nos custos de datacenters no exterior (originalmente em torno de R$ 1,5 mil por mês, agora podem chegar a R$ 2,3 mil), tornando as soluções brasileiras, ainda que caras (média de R$ 1,7 mil/mês) cerca de 20% mais baratas. Desnecessário dizer que grupos como UOL, Locaweb e Ascenty comemoraram a decisão.

    E o que muda? Num primeiro momento o consumidor não seria afetado, mas estamos falando de muitas empresas que provavelmente hospedam serviços de dados lá fora, e é óbvio que esse aumento de custo será repassado para o usuário final em algum momento, independente de qual ramo os mesmos operam. Como a norma foi publicada DOA no dia 18/10 ela já está em vigor, mas não se sabe se será dado um prazo para adaptação ou se a Receita sairá cobrando todo mundo de cara.

    Novamente, parabéns a todos os envolvidos.

    Fonte: CW.

    The post Receita passa a taxar serviços de hospedagem no exterior appeared first on Meio Bit.








    04 Nov 20:57

    Por que você deve usar o document.readyState

    by Steve Souders

    Perguntei para vários desenvolvedores web o que aconteceria se um handler onload acrescentasse outro handler onload. Será que o segundo handler onload executa?

    O evento onload já foi acionado, por isso pode ser tarde demais para o segundo onload se desencadear. Por outro lado, a fase onload não acabou (estamos entre loadEventStart e loadEventEnd em termos de Navigation Timing), então pode ter uma chance de o segundo handler onload poder ser adicionado a uma fila e executado no final.

    Nenhuma das pessoas que perguntei sabia a resposta, mas todos nós tínhamos um palpite. Vou explicar por que isso é importante, mas, até então, resolva a sua resposta – você acha que o segundo onload executa?

    Para responder a essa pergunta eu criei a página de testes OnLoad in OnLoad. Ela define um handler onload inicial. Nesse primeiro handler onload, é adicionado um segundo handler onload. Aqui está o código:

    function addOnload(callback) {
        if ( "undefined" != typeof(window.attachEvent) ) {
            return window.attachEvent("onload", callback);
        }
        else if ( window.addEventListener ){
            return window.addEventListener("load", callback, false);
        }
    }
    
    function onload1() {
        document.getElementById('results').innerHTML += "First onload executed.";
        addOnload(onload2);
    }
    
    function onload2() {
        document.getElementById('results').innerHTML += "Second onload executed.";
    }
    
    addOnload(onload1);

    Eu criei um teste de usuário Browserscope para registrar os resultados e tuitei pedindo às pessoas para executá-lo. Graças ao crowdsourcing, temos resultados de dezenas de browsers. Até agora, nenhum navegador executa o segundo handler onload.

    Por que isso é importante?

    Existe uma crescente sensibilização para o impacto negativo que os scripts têm sobre os tempos de carregamento da página. Muitos sites estão seguindo as melhores práticas de desempenho de carregamento de scripts de forma assíncrona. Enquanto essa é uma mudança fantástica que faz as páginas renderizar mais rapidamente, ainda é possível para um script assíncrono tornar as páginas mais lentas porque o onload não dispara até que todos os scripts assíncronos tenham sido baixados e executados.

    Para atenuar o impacto negativo no desempenho dos scripts, alguns sites foram transferidos para os scripts de carga em um handler onload. O problema é que muitas vezes os scripts que estão sendo transferidos para o handler onload são scripts de terceiros. Combine isso com o fato de que muitos scripts de terceiros, especialmente métricas, dão o pontapé inicial de sua execução por meio de um handler onload. O resultado final é que nós estamos carregando os scripts que incluem um handler onload em um handler onload. Sabemos, a partir dos resultados do teste acima, que isso resulta no segundo handler onload não sendo executado, o que significa que o script de terceiros não vai completar toda a sua funcionalidade.

    Os scripts (especialmente scripts de terceiros) que usam manipuladores onload devem, portanto, verificar se o evento onload já foi acionado. Se sim, então em vez de usar um handler onload, a execução de script deve começar imediatamente. Um bom exemplo disso é a minha biblioteca Episodes RUM. Anteriormente, eu iniciava a coleta das métricas RUM por meio de um handler onload, mas agora episodes.js também verifica document.readyState para garantir que as métricas estejam reunidas mesmo se o onload já tiver sido acionado. Eis o código:

        if ( "complete" == document.readyState ) {
            // The page is ALREADY loaded - start EPISODES right now.
            if ( EPISODES.autorun ) {
                EPISODES.done();
            }
        }
        else {
            // Start EPISODES on onload.
            EPISODES.addEventListener("load", EPISODES.onload, false);
        }

    Resumindo

    • Se você tem um site e quer fazer tudo certinho para um script não afetar os tempos de carregamento da página, considere colocá-lo em um handler onload. Ao fazer isso, certifique-se de testar se o script atrasado não depende de um handler onload para completar sua funcionalidade (outra opção é carregar o script em um iframe, mas scripts de terceiros podem não funcionar corretamente dentro de um iframe).
    • Se você possui um script de terceiros que acrescenta um handler onload, talvez você queira aumentar, verificando document.readyState para se certificar de que o onload não tenha sido disparado ainda.

    ***

    Artigo traduzido pela Redação iMasters com autorização do autor. Publicado originalmente em http://www.stevesouders.com/blog/2014/09/12/onload-in-onload/

    Mensagem do anunciante:

    Torne-se um Parceiro de Software Intel®. Filie-se ao Intel® Developer Zone. Intel®Developer Zone

    03 Nov 17:17

    Finalmente! Cientistas criam a hoverboard de De volta para o futuro!

    by administrador@bytequeeugosto.com.br (Marcel Dias)

    O artigo Finalmente! Cientistas criam a hoverboard de De volta para o futuro! faz parte do conteúdo do Byte Que Eu Gosto! - Nerd, Geek, Dicas, Cinema, Games e mais!.

    hover

    Desde que De volta para o futuro 2 apresentou ao mundo a hoverboard, aquele skate voador que na verdade era um patinete, o mundo não pensou em outra coisa a não ser “quando teremos skates voadores a nossa disposição?”.

    Ok, talvez o mundo não tenha pensado isso, mas eu sim. Depois de várias tentativas, diversos projetos que ou não saíram do papel ou seriam inviáveis, parece que finalmente os cientistas mostraram sua real utilidade e criaram uma hoverboard para nosso regozijo e deleite.

    Tudo bem que tem alguns poréns. A hoverbord só flutua sobre metal, a bateria dura míseros 7 minutos e o custo é de 10 mil dólares se você quiser adquirir uma. Ninguém disse que seria fácil ou barato, não é mesmo? A criação é de uma startup da Califórnia.

    O criador colocou um post no Kickstarter buscando arrecadar 250 mil dólares para dar os ajustes finais ao produto. Caso você ache que essa prancha vale 10 mil obamas, você pode ser um dos 10 felizardos a conquistar uma ajudando com esse montante.

    hendo3

    Curiosidade: hoje falta exatamente 1 ano pra Doc Brown e Marty McFly chegarem a 2015. No filme, eles chegam no futuro exatamente nessa data. E ainda não temos carros voadores. Mas pelo menos a hoverboard parece bem encaminhada.

    O artigo Finalmente! Cientistas criam a hoverboard de De volta para o futuro! faz parte do conteúdo do Byte Que Eu Gosto! - Nerd, Geek, Dicas, Cinema, Games e mais!.

    02 Nov 08:44

    PowerPoint tem vulnerabilidade de segurança, alerta a Microsoft

    by Pedro Simões
    Os produtos da Microsoft são por norma os principais alvos de ataques e de tentativa de exploração de vulnerabilidades. É normal surgirem novas formas de acesso não autorizado ou de execução de código malicioso em ferramentas que a Microsoft tem no mercado. Consciente deste problema a Microsoft tem um cuidado especial nos seus produtos e […]
    02 Nov 01:31

    Microsoft lança carregador sem fio sem fio que carrega sem fio

    by Carlos Cardoso

    NUSA-PP-Hero-Icon-DC-50-Hero-2000x1000-jpg

    Toda vez que alguém fala que vivemos num mundo sem fios eu começo a rir, afinal cada cabo de dados que se perde é um cabo de força que se ganha. O carregamento por indução é algo que pretende amenizar isso, lembrando que o carregador também precisa de um fio.

    Esse DC-50 da Nokia Microsoft é exceção.

    Nokia-Portable-Wireless-Charging-Plate-DC-50

    Ele funciona como um carregador sem fio normal, pode ficar na sua mesa conectado a uma porta USB e acomodar seu celular, mas se você precisar sair, desconecte-o do cabo, enfie no bolso ou na mochila e quando precisar dar uma carga no possante, é só deixar os dois no bolso. A bateria de 2.400 mAh garante uma sobrevida bem razoável para seu celular.

    Eu uso baterias auxiliares normais, e admito, é incômodo ficar com um cabo saindo da mochila. Com um desses no bolso tudo seria mais fácil.

    Ah sim, o DC-50 não só carrega outros aparelhos por indução como também é carregado. Se o seu ficar sem força e você tiver outro por perto, é só encostar os dois e o seu será carregado.

    A previsão de chegada no mercado é “em breve”, e virá nas cores amarela branca azul e vermelha. Pelo visto a Microsoft demitiu mesmo o diretor daltônico da Nokia que só aceitava produtos preto e branco. O preço? R$ 229,00. Não é barato, mas garante que você não caia na roleta dos carregadores da DX.

    Fonte: MSFT.

    Leia também:

    The post Microsoft lança carregador sem fio sem fio que carrega sem fio appeared first on Meio Bit.








    02 Nov 01:27

    Why I prefer Python to Java, in two code samples.

    by Xof

    Assignment: Load a remote URL via https, verifying the site certificate against a local root CA certificate.

    Java, Android SDK:

    // Load CAs from an InputStream
    // (could be from a resource or ByteArrayInputStream or ...)
    CertificateFactory cf = CertificateFactory.getInstance("X.509");
    // From https://www.washington.edu/itconnect/security/ca/load-der.crt
    InputStream caInput = new BufferedInputStream(new FileInputStream("load-der.crt"));
    Certificate ca;
    try {
        ca = cf.generateCertificate(caInput);
        System.out.println("ca=" + ((X509Certificate) ca).getSubjectDN());
    } finally {
        caInput.close();
    }
    
    // Create a KeyStore containing our trusted CAs
    String keyStoreType = KeyStore.getDefaultType();
    KeyStore keyStore = KeyStore.getInstance(keyStoreType);
    keyStore.load(null, null);
    keyStore.setCertificateEntry("ca", ca);
    
    // Create a TrustManager that trusts the CAs in our KeyStore
    String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
    TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
    tmf.init(keyStore);
    
    // Create an SSLContext that uses our TrustManager
    SSLContext context = SSLContext.getInstance("TLS");
    context.init(null, tmf.getTrustManagers(), null);
    
    // Tell the URLConnection to use a SocketFactory from our SSLContext
    URL url = new URL("https://certs.cac.washington.edu/CAtest/");
    HttpsURLConnection urlConnection =
        (HttpsURLConnection)url.openConnection();
    urlConnection.setSSLSocketFactory(context.getSocketFactory());
    InputStream in = urlConnection.getInputStream();
    copyInputStreamToOutputStream(in, System.out);
    

    Python:

    import requests
    x = requests.get('https://certs.cac.washington.edu/CAtest/', verify='load-der.crt')
    
    02 Nov 00:09

    O guarda-chuva inovador que protege você das gotas com uma capa invisível

    by Redação Hypeness
    As descobertas tecnológicas mudaram muito nossas vidas, mas o guarda-chuva continua o mesmo: inconveniente de carregar, pouco eficaz e traiçoeiro – ou você acha mesmo que ele não vai virar do avesso bem no meio daquele temporal? Para mudar esse cenário, foi criado o Air Umbrella, um guarda-chuva inovador que utiliza ar pressurizado para criar […]
    01 Nov 23:12

    Converta o Windows XP numa máquina virtual com o VirtualXP

    by Mário Sousa
    Como é sabido, a Microsoft deixou de oferecer suporte técnico ou actualizações de segurança para aquele que muitos ainda consideram como o sistema operativo com mais sucesso, o Windows XP. Os utilizadores que insistem em permanecer com este sistema operativo podem estar sob o jugo de ameaças de vírus nocivos, spyware e outros softwares mal-intencionados. […]
    31 Oct 21:04

    Desenvolvedor PHP que trabalha para o Google lança compilador PHP

    by Manuel Lemos

    Recentemente foi lançado um novo compilador PHP chamado Recki-CT, que gera código nativo que supera o mesmo código PHP rodando no Zend Engine ou no Facebook HHVM. Leia este artigo para saber mais sobre esse novo compilador PHP, como ele funciona e os planos para o futuro.

    O que é o Recki-CT?

    Recki-CT (Recki Compiler Toolkit) é um projeto de Anthony Ferrara, desenvolvedor PHP das antigas que há algum tempo se tornou Developer Advocate no Google.

    Apesar de ele trabalhar no Google, o Recki-CT não é realmente uma parte do seu trabalho como developer advocate. É algo que ele faz em 20% do seu tempo no Google – a empresa permite que seus funcionários trabalhem em projetos de sua escolha. Então, o compilador não é um projeto do Google, apesar das menções à empresa no copyright e de ser necessário que os contribuidores assinem uma CLA (Contributor License Agreement – Acordo de Licença de Contribuição).

    Recki-CT é um projeto totalmente escrito em PHP. Ele faz o parse do código PHP e gera um código de máquina como resultado da compilação do código PHP.

    Como o Recki-CT funciona?

    Conversei com o Anthony e ele foi muito gentil em esclarecer como o Recki-CT funciona e como ele pode compilar código PHP com resultados de performance tão bons.

    Basicamente, Recki é uma biblioteca PHP que pega um pouco de código, faz o parse para fazer uma Árvore Sintática Abstrata usando o parser PHP de Nikita Popov. Então, ele analisa a árvore sintática para realizar algumas otimizações. O resultado é um código compilado em uma representação intermediária em formato texto. Esse código é passado para a extensão JIT-FU de Jow Watkins, que emite código nativo usando a biblioteca libjit.

    O código de máquina resultante pode ser executado ao chamá-lo da mesma forma que você chama uma função closure em PHP.

    Quão rápido é o Recki-CT?

    Em termos de velocidade, nós precisamos observar dois pontos de vista. O primeiro é o passo da compilação. Esta não é uma etapa rápida, não apenas porque é implementada com código PHP, mas também porque as tarefas de parseamento, análise e otimização costumam ser lentas devido à sua complexidade. Por essa razão, o Recki-CT faz cache do código compilado para evitar que leve muito tempo para recompilar o mesmo código várias vezes.

    Para o código compilado, de acordo com parâmetros publicados em um artigo no blog do Anthony, em alguns casos o código resultante tem performance melhor que na versão do Zend Engine, incluído no PHP 5.5, assim como no HHVM 3.2.

    Aqui estão alguns dos resultados retirados desse artigo. Veja que em alguns casos os testes falham porque rodam código que ainda não é suportado pelo Recki-CT.

    php 5.5 Recki-CT hhvm 3.2 hippy-c qb
    simple() 139.63357 1.00000 8.30447 7.65693 8.35018
    simplecall() 38.99476 FAIL 1.32552 1.00000 FAIL
    simpleucall() 54.02041 1.00000 3.52439 1.51072 47.91090
    simpleudcall() 52.14534 1.00000 3.75936 1.41614 47.55259
    mandel() 21.26249 1.00000 2.03372 2.11208 FAIL
    mandel_typed() 23.16553 1.00000 2.11128 2.09212 3.00061
    mandel2() 24.43275 1.00000 2.57704 1.87802 FAIL
    mandel2_typed() 23.79989 1.00000 2.90105 1.57193 7.11054
    ackermann(7) 35.04870 1.00000 2.27557 103.45436 621.72526
    ary(50000) 1.39338 FAIL 1.00000 4.47888 FAIL
    ary2(50000) 1.26952 FAIL 1.00000 2.28231 FAIL
    ary3(2000) 5.96015 FAIL 1.70997 1.00000 FAIL
    fibo(30) 39.48440 1.00000 1.60647 16.40883 FAIL
    hash1(50000) 1.70014 FAIL 1.00000 3.27314 FAIL
    hash2(500) 2.23648 FAIL 1.00000 1.30044 FAIL
    heapsort(20000) 3.67800 FAIL 1.00000 4.96699 FAIL
    matrix(20) 4.38364 FAIL 1.00000 37.72782 FAIL
    nestedloop(12) 29.24924 1.00000 2.91459 3.07568 FAIL
    sieve(30) 10.95413 FAIL 1.00000 4.95152 FAIL
    strcat(200000) 1.48186 FAIL 2.06003 1.00000 FAIL
    jumpapaluza(50, 50) 11.67746 1.09240 1.48192 1.00000 FAIL
    bitapaluza1(21) 63.33357 1.00000 21.39655 1.46851 FAIL
    bitapaluza2(18) 21.83346 1.00000 6.19715 2.59416 FAIL

    Futuros desenvolvimentos

    Atualmente o Recki-CT não oferece suporte para todos os métodos construtores de PHP. Isso vai ser melhorado com o tempo.

    Neste momento, o último passo para compilar para o código da máquina é feito no runtime. Então, Anthony planeja levar esse passo para o passo de compilação em si, e ter o código de máquina resultante também em cache.

    Outra possibilidade interessante é aproveitar o suporte embutido para a Árvore Sintática Abstrata que está sendo incluído no PHP 7, graças à contribuição de Nikita Popov ao desenvolvimento dessa versão da linguagem. Isso faria o passo de compilação em si mais rápido, já que o suporte para a Árvore Sintática Abstrata no Recki-CT está sendo implementada no código PHP.

    Conclusão

    2014 tem sido um ano fantástico para o PHP em termos de desenvolvimentos importantes que trazem uma performance melhor para a linguagem.

    Primeiramente, o Facebook HHVM e a linguagem Hack trouxeram características incríveis e melhorias na velocidade. Depois, tivemos a reação da Zend para trazer mais melhorias de velocidade no PHP 7.

    Mais recentemente, o Recki-CT, assim como o Hippy-VM, que é outra implementação super rápida da linguagem PHP usando a tecnologia PyPy.

    Recki-CT vem trazer aspectos adicionais interessantes quando comparado a outras soluções. Um deles é que você pode usá-lo para compilar apenas partes do seu código PHP. Isso significa que você não precisa compilar toda a sua aplicação PHP para se aproveitar das suas capacidades de melhorar a velocidade de partes da sua aplicação PHP que estiverem lentas.

    Outro aspecto é que, como a maioria disso é feito em PHP, ele pode rodar com a Zend Engine baseada em PHP, ou mesmo com HHVM ou Hippy-VM, contanto que a extensão JIT-FU esteja disponível. Então, não é realmente uma alternativa para outras engines PHP, mas algo que pode melhorar ainda mais a performance do seu código PHP.

    Um aspecto que não está relacionado à performance do PHP é o fato de que compilando o código para o código de máquina a solução pode ser utilizada eventualmente para enviar código compilado sem abrir mão do código-fonte.

    Apesar de essa não ter sido a intenção original do projeto, esse aspecto pode interessar a desenvolvedores que querem vender o seu trabalho em PHP sem abrir mão do código-fonte.

    Todos esses aspectos fazem o futuro do PHP ainda mais promissor e animador do que já é. Parabéns ao Anthony Ferrara e a todos os outros que têm feito melhorias tão grandiosas no PHP.

    O que você acha? Você acredita que algo mais é importante para tornar o PHP ainda mais bacana? Deixe um comentário com suas ideias!

    ***

    Artigo traduzido pela Redação iMasters com autorização do autor. Publicado originalmente em http://www.phpclasses.org/blog/post/247-PHP-Developer-working-for-Google-Launches-New-PHP-Compiler.html

    Mensagem do anunciante:

    Em apoio à evangelização do WordPress, os cursos da Apiki são gratuitos para que você possa se especializar na plataforma que mais cresce no mundo. Vagas limitadas, Inscreva-se agora.

    31 Oct 20:04

    Backups na nuvem: existe uma nuvem para cada um de nós?

    by Marcello Lins

    A velocidade com que novas tecnologias e metodologias chegam no cenário de computação só não é maior do que a velocidade com que elas mesmas desaparecem. De tempos em tempos, porém, alguma aparece, fica, e muda o jogo completamente. A última grande mudança relevante no cenário tecnológico atual foi a adoção em massa da nuvem. A computação em nuvem como conhecemos atualmente pode ser usada para fins diversos, mas falarei apenas do seu uso no cenário de “backup”.

    A nuvem é realmente segura?

    Antes de começar a defender as utilidades da nuvem para as nossas tarefas do dia-a-dia, vale a pena dizer que não existe (atualmente) nenhuma solução que seja “a prova de bala”, totalmente segura e confiável. Grande parte dos serviços de Cloud que usamos (e confiamos) hoje em dia – confiando nossos documentos, fotos, vídeos e senhas – não são totalmente seguros. Alguns dos maiores “players” de Cloud atualmente, como “Dropbox” e “Evernote”, já sofreram ataques que foram longe o suficiente para expor dados sensíveis sobre seus usuários.

    Outro fator que se deve ter em mente é a resistência destes serviços contra desastres naturais. Não existe proteção capaz de resistir a um forte terremoto, tsunami ou incêndio. Atualmente, alguns destes serviços realizam a duplicação de dados em espaços físicos distantes para tentar minimizar o impacto caso o pior aconteça. Sempre cheque a política de segurança e disponibilidade de um serviço antes de “pular de cabeça” nele.

    Porque eu deveria migrar para a nuvem?

    Como acabou de ver, a nuvem não é totalmente segura, mas e quanto a sua casa? As chances de alguém morar em um Bunker atualmente são bem baixas, então… Todos os seus dados, cuidadosamente gravados em um disco externo, DVD ou flashdrive, guardados com zelo em sua gaveta estão suscetíveis às mesmas falhas citadas anteriormente. A grande diferença é que estes serviços dispõem de profissionais tomando conta dos seus dados e de muita tecnologia por trás.

    Atualmente existem serviços de armazenamento em nuvem para todo e qualquer tipo de arquivo, não importa o formato. Fotos? Flickr. Anotações e rascunhos? Evernote. Documentos Office? Google Drive. Senhas? Lastpass. Jogos? Steam. Código? Github. Todo o resto? Dropbox / OneDrive. O céu é o limite quando falamos de provedores deste tipo de serviço. Ou devemos dizer que a nuvem é o limite?

    Outra grande vantagem da adoção da nuvem como meio de armazenamento é a disponibilidade dos seus arquivos. Uma vez armazenados, seus arquivos passam a ser acessíveis de praticamente qualquer dispositivo com internet. Desde os arquivos da última reunião, até as fotos da sua última viagem, tudo a poucos cliques de distância quando você precisar.

    Qual é o custo de abraçar a nuvem?

    Para um usuário comum, eu diria que é possível começar sem gastar nada. Atualmente a grande maioria dos serviços de armazenamento online disponibilizam um espaço considerável de graça. O espaço disponibilizado varia muito: serviços como o Dropbox, OneDrive, Copy e Mega oferecem desde 2GB até 50GB totalmente gratuito, enquanto o Flickr permite 1 Terabyte de fotos por usuário.

    Existem também soluções voltadas para atender empresas, como a Amazon Web Services e o Box. Estas soluções são bem mais robustas do que as mencionadas anteriormente e podem ser mais custosas.

    Fique de olho aberto, pesquise bastante e procure provedores confiáveis antes de adotar a nuvem completamente.

    Nos vemos no próximo artigo!

    29 Oct 01:48

    The Fridge: Happy 10th Birthday Ubuntu!

    10 years ago today, Mark Shuttleworth made the 4th post ever to the ubuntu-announce mailing list when he wrote: Announcing Ubuntu 4.10 “The Warty Warthog Release”

    In this announcement, Mark wrote:

    Ubuntu is a new Linux distribution that brings together the extraordinary breadth of Debian with a fast and easy install, regular releases (every six months), a tight selection of excellent packages installed by default and a commitment to security updates with 18 months of security and technical support for every release.

    So it’s with much excitement, the Ubuntu News team wishes Ubuntu a happy 10th Birthday!

    Ubuntu cake

    Over the years, we’ve had several cakes celebrating releases, here are a sampling we found on Flickr, first from the 8.04 release party in London:

    ubuntu cake

    And an amazing trio from Kitchener-Waterloo, Ontario, Canada for 9.10, 10.10 and 11.04:

    Ubuntu 9.10: Karmic Koala Release Party
    CIMG4679.JPG
    CIMG4817

    And dozens of strictly Ubuntu logo cakes over the years (this one from 2006):

    Ubuntu cake!!

    With the release of 14.10 just days away, enjoy your release parties and perhaps take some time to reflect upon how far we’ve come in these 10 years!

    Posted by Elizabeth K. Joseph, on behalf of the Ubuntu News Team

    28 Oct 00:06

    Mark Shuttleworth: V is for Vivid

    Release week! Already! I wouldn’t call Trusty ‘vintage’ just yet, but Utopic is poised to leap into the torrent stream. We’ve all managed to land our final touches to *buntu and are excited to bring the next wave of newness to users around the world. Glad to see the unicorn theme went down well, judging from the various desktops I see on G+.

    And so it’s time to open the vatic floodgates and invite your thoughts and contributions to our soon-to-be-opened iteration next. Our ventrous quest to put GNU as you love it on phones is bearing fruit, with final touches to the first image in a new era of convergence in computing. From tiny devices to personal computers of all shapes and sizes to the ventose vistas of cloud computing, our goal is to make a platform that is useful, versal and widely used.

    Who would have thought – a phone! Each year in Ubuntu brings something new. It is a privilege to celebrate our tenth anniversary milestone with such vernal efforts. New ecosystems are born all the time, and it’s vital that we refresh and renew our thinking and our product in vibrant ways. That we have the chance to do so is testament to the role Linux at large is playing in modern computing, and the breadth of vision in our virtual team.

    To our fledgling phone developer community, for all your votive contributions and vocal participation, thank you! Let’s not be vaunty: we have a lot to do yet, but my oh my what we’ve made together feels fantastic. You are the vigorous vanguard, the verecund visionaries and our venerable mates in this adventure. Thank you again.

    This verbose tract is a venial vanity, a chance to vector verbal vibes, a map of verdant hills to be climbed in months ahead. Amongst those peaks I expect we’ll find new ways to bring secure, free and fabulous opportunities for both developers and users. This is a time when every electronic thing can be an Internet thing, and that’s a chance for us to bring our platform, with its security and its long term support, to a vast and important field. In a world where almost any device can be smart, and also subverted, our shared efforts to make trusted and trustworthy systems might find fertile ground. So our goal this next cycle is to show the way past a simple Internet of things, to a world of Internet things-you-can-trust.

    In my favourite places, the smartest thing around is a particular kind of monkey. Vexatious at times, volant and vogie at others, a vervet gets in anywhere and delights in teasing cats and dogs alike. As the upstart monkey in this business I can think of no better mascot. And so let’s launch our vicenary cycle, our verist varlet, the Vivid Vervet!

    25 Oct 01:59

    Pavel Stehule: styles for unicode borders are merged (PostgreSQL 9.5)

    Following feature is less important for performance, but for somebody can be important for aesthetic reasons - now you can use a styles for unicode table borders. Possible styles are only two, but you can set a border, header and column style. It is a 6 combinations. Next you have a 3 styles for borders generally - so it together 18 possible combinations of psql table output:
    postgres=# \pset unicode_header_linestyle double 
    Unicode border linestyle is "double".
    postgres=# \pset linestyle unicode
    Line style is unicode.
    postgres=# \l
    List of databases
    Name │ Owner │ Encoding │ Collate │ Ctype │ Access privileges
    ═══════════╪══════════╪══════════╪═════════════╪═════════════╪═══════════════════════
    postgres │ postgres │ UTF8 │ en_US.UTF-8 │ en_US.UTF-8 │
    template0 │ postgres │ UTF8 │ en_US.UTF-8 │ en_US.UTF-8 │ =c/postgres ↵
    │ │ │ │ │ postgres=CTc/postgres
    template1 │ postgres │ UTF8 │ en_US.UTF-8 │ en_US.UTF-8 │ =c/postgres ↵
    │ │ │ │ │ postgres=CTc/postgres
    (3 rows)

    postgres=# \l
    List of databases
    Name Owner Encoding Collate Ctype Access privileges
    ═════════ ════════ ════════ ═══════════ ═══════════ ═════════════════════
    postgres postgres UTF8 en_US.UTF-8 en_US.UTF-8
    template0 postgres UTF8 en_US.UTF-8 en_US.UTF-8 =c/postgres ↵
    postgres=CTc/postgres
    template1 postgres UTF8 en_US.UTF-8 en_US.UTF-8 =c/postgres ↵
    postgres=CTc/postgres
    (3 rows)


    postgres=# \pset border 2
    Border style is 2.
    postgres=# \l
    List of databases
    ┌───────────┬──────────┬──────────┬─────────────┬─────────────┬───────────────────────┐
    │ Name │ Owner │ Encoding │ Collate │ Ctype │ Access privileges │
    ╞═══════════╪══════════╪══════════╪═════════════╪═════════════╪═══════════════════════╡
    │ postgres │ postgres │ UTF8 │ en_US.UTF-8 │ en_US.UTF-8 │ │
    │ template0 │ postgres │ UTF8 │ en_US.UTF-8 │ en_US.UTF-8 │ =c/postgres ↵│
    │ │ │ │ │ │ postgres=CTc/postgres │
    │ template1 │ postgres │ UTF8 │ en_US.UTF-8 │ en_US.UTF-8 │ =c/postgres ↵│
    │ │ │ │ │ │ postgres=CTc/postgres │
    └───────────┴──────────┴──────────┴─────────────┴─────────────┴───────────────────────┘
    (3 rows)

    postgres=# \pset unicode_border_linestyle double
    Unicode border linestyle is "double".
    postgres=# \l
    List of databases
    ╔═══════════╤══════════╤══════════╤═════════════╤═════════════╤═══════════════════════╗
    ║ Name │ Owner │ Encoding │ Collate │ Ctype │ Access privileges ║
    ╠═══════════╪══════════╪══════════╪═════════════╪═════════════╪═══════════════════════╣
    ║ postgres │ postgres │ UTF8 │ en_US.UTF-8 │ en_US.UTF-8 │ ║
    ║ template0 │ postgres │ UTF8 │ en_US.UTF-8 │ en_US.UTF-8 │ =c/postgres ↵║
    ║ │ │ │ │ │ postgres=CTc/postgres ║
    ║ template1 │ postgres │ UTF8 │ en_US.UTF-8 │ en_US.UTF-8 │ =c/postgres ↵║
    ║ │ │ │ │ │ postgres=CTc/postgres ║
    ╚═══════════╧══════════╧══════════╧═════════════╧═════════════╧═══════════════════════╝
    (3 rows)

    postgres=# \pset border 1
    Border style is 1.
    postgres=# \pset unicode_column_linestyle double
    Unicode column linestyle is "double".
    postgres=# \l
    List of databases
    Name ║ Owner ║ Encoding ║ Collate ║ Ctype ║ Access privileges
    ═══════════╬══════════╬══════════╬═════════════╬═════════════╬═══════════════════════
    postgres ║ postgres ║ UTF8 ║ en_US.UTF-8 ║ en_US.UTF-8 ║
    template0 ║ postgres ║ UTF8 ║ en_US.UTF-8 ║ en_US.UTF-8 ║ =c/postgres ↵
    ║ ║ ║ ║ ║ postgres=CTc/postgres
    template1 ║ postgres ║ UTF8 ║ en_US.UTF-8 ║ en_US.UTF-8 ║ =c/postgres ↵
    ║ ║ ║ ║ ║ postgres=CTc/postgres
    (3 rows)

    21 Oct 15:07

    Ubuntu: Vários sites num único servidor Web

    by Pedro Pinto
    Qualquer distribuição Linux tem as características perfeitas para implementar os mais diversos serviços web. As configurações dos serviços são normalmente realizadas em ficheiros de texto, mas existem algumas plataformas que simplificam ainda mais a configuração, uma vez que oferecem uma interface web. Depois de termos ensinar a ter vários sites num servidor Web no CentOS, […]
    20 Oct 15:40

    IE8 Countdown – Enforcando o demônio

    by diego@tableless.com.br (Tableless.com.br)

    A própria Microsoft iniciou um processo para minimizar a utilização do IE6 pelo mundo. Claro, o IE6 era muito, mas muito pior que o IE8. Contudo, o IE8 é um browser antigo e não goza (ops!) das vantagens que os outros browsers mais modernos tem de sobra. Por isso foi iniciado um projeto para enforcar o Internet Explorer 8 chamado The Internet Explorer 8 Countdown. Esse é um projeto de 2013 e que parece estar voltando com tudo para acabar de vez com essa maldição.

    O que me assusta bastante é que no mês de setembro a taxa de uso do IE8 aumentou um pouco! O.o

    A ideia é que você possa, além de colocar o bannerzinho aí embaixo nos lugares que puder (ops!), educar as pessoas a sua volta que ainda usam esse browser a migrarem para outro mais moderno. Pode ser qualquer um, até mesmo outro Internet Explorer (o 11 de preferência, se não o 10). Esse processo de educação é ainda mais importante do que toda parafernália que você pode fazer para tentar convencer os usuários.

    Mãos à obra e let’s hunt IE today.

    <!--[if IE]><div style='clear: both; height: 112px; padding:0; position: relative;'><a href="http://www.theie8countdown.com/ie-users-info"><img src="http://www.theie8countdown.com/assets/badge_iecountdown.png" border="0" height="112" width="348" alt="" /></a></div><![endif]-->
    

    ---
    Este artigo foi escrito por Diego Eis.

    Visite o nosso site para mais posts sobre desenvolvimento web! Tableless.

    20 Oct 13:48

    IEEE disponibiliza seu próprio ranking de popularidade de linguagens de programação

    by Augusto Campos

    Via www.infoq.com:

    O IEEE publicou recentemente no Spectrum uma aplicação com o ranking interativo de popularidade de linguagens de programação no ano de 2014. Esta aplicação disponibiliza diversas opções de filtros dinâmicos, como por exemplo: linguagens mais relevantes para um setor específico como web, mobile, corporativo (enterprise) e sistemas embarcados. Neste ano, novas linguagens disputam posições com as já consagradas Java, C e C++.

    O ranking é criado através da combinação e ponderação de 12 métricas, provenientes de 10 fontes de dados distintas. (...) O ranking utiliza um conjunto de fontes de dados de websites relevantes para programadores, como por exemplo: GitHub, StackOverflow, HackerNews e Reddit.

    O artigo "IEEE disponibiliza seu próprio ranking de popularidade de linguagens de programação" foi originalmente publicado no site BR-Linux.org, de Augusto Campos.

    19 Oct 23:27

    Celulas fotovoltáicas transparentes poderiam transformar sua janela em um painel solar

    by Redacao_Hypeness
    Pense em todas as janelas dos prédios da sua cidade e no sol que passa por elas e não é aproveitado. Sim, os vidros poderiam ser usados como forma de captar a luz solar para transformá-la em energia limpa e barata. Essa é a ousada proposta da Ubiquitous Energy, que conseguiu desenvolver um tipo de célula […]