Como gerar códigos de autenticação por dois fatores (2FA) no Linux

EnglishSpanishChinese (Simplified)ItalianPortuguese

Se você tem um computador com Linux, nem que seja em uma máquina virtual, ou possui um VPS com acesso via SSH, sabia que é possível usar esses sistemas para gerar códigos de autenticação por dois fatores (2FA)?

Além de ser muito importante manter suas contas seguras ativando o 2FA e desativando o recebimento de códigos por SMS, é importante também ter múltiplas formas de gerar os tais códigos para situações adversas.

Assim você não fica trancado do lado de fora de suas contas caso o único lugar capaz de gerar esses códigos seja seu celular, por exemplo. Numa situação em que ele é roubado ou furtado, você não fica na mão.

Com este tutorial, caso você tenha acesso SSH ao seu sistema Linux, será possível gerar seus códigos 2FA de qualquer lugar do mundo com acesso à Internet e as devidas credenciais do SSH (como chaves ou senhas).

Pedido de autenticação por dois fatores (2FA) da Microsoft. Imagem: Ed Hardie/Unsplash
Pedido de autenticação por dois fatores (2FA) da Microsoft. Imagem: Ed Hardie/Unsplash

A propósito, a seguir você vai se deparar com uma sigla chamada TOTP, que significa Time-based One Time Password ou “senhas de uso único baseadas em tempo” na tradução livre para o português.

Esse nome se justifica pois são códigos que só podem ser usados uma vez, expiram em 30 segundos e essas “senhas” só vão ser aceitas se seu relógio estiver bem ajustado pois são baseadas na hora atual.

Caso seu relógio esteja desajustado, será gerado um código 2FA diferente daquele esperado pelo serviço no qual você deseja fazer login. Para ter certeza que seu relógio estará sempre certinho, conheça o Alto NTP.

Ingredientes

Para este tutorial você vai precisar do seguinte:

  • Computador ou máquina virtual com Linux instalado;
  • GnuPG e OathTool instalados;
  • Os “seeds” de cada conta para gerar os códigos 2FA;
  • Tesoura sem ponta.

Os seeds mencionados acima são uma sequência alfanumérica que é gerada durante o processo de ativação do 2FA em uma determinada conta. De preferência, salve esses seeds em local seguro para consulta futura.

Seed é uma palavra inglesa que significa “semente” na tradução literal. É a partir desta semente que nosso script vai gerar um “fruto”, que é o código 2FA que você deseja.

Gerando códigos 2FA no Linux

Esse tutorial é compatível com sistemas baseados no Debian/Ubuntu, Fedora/RHEL e SUSE/OpenSUSE. Para instalar os pacotes necessários, use os comandos a seguir de acordo com seu sistema:

# Para sistemas baseados no Fedora:
sudo dnf install oathtool gnupg2 nano

# Para sistemas baseados no CentOS/RHEL:
sudo yum install oathtool gnupg2 nano

# Para sistemas baseados no Debian/Ubuntu:
sudo apt install oathtool gnupg2 nano

# Para sistemas baseados no SUSE/OpenSUSE:
sudo zypper ref
sudo zypper in oath-toolkit gpg2 nano

Agora que está tudo instalado, vamos seguir com as instruções. Abra o Terminal de sua distribuição Linux ou então se conecte a ela usando um cliente SSH como o PuTTY no Windows.

Uma vez no Terminal ou conectado via SSH, primeiro você vai precisar criar e entrar na pasta onde serão mantidos os arquivos necessários para geração dos códigos 2FA. Para isso, use os seguintes comandos:

mkdir -p /opt/totp
mkdir -p /opt/totp/.config
cd /opt/totp

Depois disso você vai criar um novo arquivo com o script que vai fazer o trabalho pesado pra gente. O comando aqui é este: nano totp.sh. Dentro deste arquivo você vai colar o seguinte:

#!/bin/bash

# Copyright (c) 2018, info AT markusholtermann DOT eu
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#     * Redistributions of source code must retain the above copyright
#       notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above copyright
#       notice, this list of conditions and the following disclaimer in the
#       documentation and/or other materials provided with the distribution.
#     * Neither the name of the <organization> nor the
#       names of its contributors may be used to endorse or promote products
#       derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

set -e
set -o pipefail

SOURCE_DIR=/opt/totp/.config
export GPG_TTY=$(tty)

function init() {
    mkdir -p $SOURCE_DIR
    chmod 0700 $SOURCE_DIR

    if ! hash gpg 2>/dev/null ; then
        echo "Please ensure that GnuPG is installed!"
        exit 1
    fi
    if ! hash oathtool 2>/dev/null ; then
        echo "Please ensure that oathtool is installed!"
        exit 2
    fi
}

function add_key() {
    echo "Adding a new key"
    if [ "x$1" != "x" ] ; then
        identifier=$1
    else
        echo "What's the identifier?"
        read -r identifier
    fi
    echo "What's the secret?"
    read -r secret
    echo "$secret" | gpg --quiet --symmetric --out "$SOURCE_DIR/$identifier"
}

function get_totp() {
    if [ "x$1" != "x" ] ; then
        identifier=$1
    else
        echo "What's the identifier?"
        read -r identifier
    fi
    secret="$(gpg --quiet < "$SOURCE_DIR/$identifier")"
    oathtool --base32 --totp "$secret"
}

function list() {
    ls -1 "$SOURCE_DIR"
}

function help() {
    echo "Setup a new TOTP account or generate a new TOTP token from an existing account."
    echo
    echo "Usage: totp.sh [--add|--list|--totp] [IDENTIFIER]"
    echo
    echo -e "--add     Will ask for an identifier (i.e. 'google', 'slack', ...) and\\n" \
            "         then for the secret provided by the service provider."
    echo -e "--list    Will list all available identifiers."
    echo -e "--totp    Will ask for an identifier (i.e. 'google', 'slack', ...) and\\n" \
            "         then return the TOTP token."
}

init

case $1 in
    --add)
        add_key "$2"
        ;;
    --list)
        list
        ;;
    --totp)
        get_totp "$2"
        ;;
    *)
        help
esac

Para salvar as modificações, pressione CTRL + O e para sair do editor de texto nano pressione CTRL + X. Agora precisamos tornar este script em um executável. Para isso, digite o seguinte: chmod +x totp.sh. Pronto!

Plantando e cuidando das sementes

Vamos agora configurar o script para gerar os códigos 2FA pra gente. Aqui você vai precisar do seed gerado durante o processo de ativação da autenticação por dois fatores em uma conta como a do Google ou Facebook por exemplo.

O nosso programinha funciona da seguinte forma:

# Adicionar um novo seed
./totp.sh --add

# Listar os seeds já adicionados
./totp.sh --list

# Gerar um código 2FA
./totp.sh --totp <nome da conta>

Quando você executa o primeiro comando (--add), relativo a adicionar um novo seed, inicialmente o script vai perguntar um nome para ele. Digite algo curto, fácil de lembrar e todo em minúsculo, como google por exemplo.

Depois o script vai perguntar qual o seed desta conta. E por fim vai ser solicitada uma senha para criptografar o arquivo contendo-o e que será usado para gerar os códigos 2FA no futuro. Caso alguém veja a pasta, não verá o seed.

Verá só um monte de símbolos embaralhados e assim não será possível que um curioso ou invasor descubra o seed em si para gerar códigos 2FA por conta própria e invadir suas contas online sem o seu consentimento.

Uma vez que você terminar esse processo, caso digite o comando --list, referente a listar os seeds já adicionados, você verá o nome google aparecer no Terminal ou no cliente SSH de sua preferência.

Esse comando serve para, caso você tenha esquecido o nome que deu ao seed de uma determinada conta durante o processo de configuração, com esse comando será possível saber exatamente qual foi.

Agora vem a parte que todos esperavam: gerar o código 2FA que tanto desejamos. No nosso exemplo, para gerar um código 2FA para nossa conta do Google, o comando seria este:

# Gerar um código 2FA para a conta do Google
./totp.sh --totp google

Após digitar a senha para descriptografar o seed, você verá surgir na tela uma sequência numérica de 6 dígitos que é válida por 30 segundos e permite que você acesse sua conta dentro desta estreita janela de tempo.

E é isso, pessoal. Para cada novo seed que você quiser configurar, basta ir adicionando ele com o comando --add e depois quando surgir a necessidade de gerar um código 2FA é só usar o comando --totp <nome da conta>.

Precisa atualizar o seed? Digamos que, conforme nosso exemplo, você queira atualizar o seed do Google após reconfigurar o 2FA para ele. Simplesmente digite totp --add google outra vez, informe o novo seed.

Ao final, você será perguntado se deseja substituir o arquivo com o seed antigo, daí basta confirmar. Se quiser excluir uma semente já adicionada, basta excluir o arquivo com o nome dela na pasta /opt/totp/.config.

Para não ter que acessar a pasta /opt/totp toda vez que quiser executar o script ./totp e seus comandos, você pode criar algo chamado de alias. Para isso, no Terminal ou cliente SSH, digite nano ~/.profile.

Na última linha deste arquivo, copie e cole o seguinte:

alias totp="/opt/totp/totp.sh"

Pressione CTRL + O para salvar e CTRL + X para sair do nano. Caso esteja no SSH, digite exit para sair e se conecte novamente. Caso esteja no Terminal, saia da sua sessão (logout) e entre novamente.

Agora ao abrir o Terminal ou se conectar usando seu cliente SSH, basta digitar totp seguido do comando desejado, como --totp <nome da conta> para gerar um código 2FA. Bem mais simples e direto, não acham?

Veja como fica agora, em qualquer tela do Terminal ou cliente SSH:

# Adicionar um novo seed
totp --add

# Listar os seeds já adicionados
totp --list

# Gerar um código 2FA
totp --totp <nome da conta>

Os créditos do script vão para Markus Holtermann, com uma pequena modificação minha na linha onde diz export GPG_TTY=$(tty). Essa linha evita o seguinte erro quando o tutorial é executado via SSH:

gpg: problem with the agent: Inappropriate ioctl for device

Por mais que existam apps bem mais simples e diretos do que este tutorial, não deixa de ser importante não colocar todos os ovos numa mesma cesta. Caso essa cesta caia no chão, você não fica sem a sua omelete.