---
title: Capítulo 13. Segurança
part: Parte III. Administração do Sistema
prev: books/handbook/boot
next: books/handbook/jails
showBookMenu: true
weight: 17
params:
  path: "/books/handbook/security/"
---

[[security]]
= Segurança
:doctype: book
:toc: macro
:toclevels: 1
:icons: font
:sectnums:
:sectnumlevels: 6
:sectnumoffset: 13
:partnums:
:source-highlighter: rouge
:experimental:
:images-path: books/handbook/security/

ifdef::env-beastie[]
ifdef::backend-html5[]
:imagesdir: ../../../../images/{images-path}
endif::[]
ifndef::book[]
include::shared/authors.adoc[]
include::shared/mirrors.adoc[]
include::shared/releases.adoc[]
include::shared/attributes/attributes-{{% lang %}}.adoc[]
include::shared/{{% lang %}}/teams.adoc[]
include::shared/{{% lang %}}/mailing-lists.adoc[]
include::shared/{{% lang %}}/urls.adoc[]
toc::[]
endif::[]
ifdef::backend-pdf,backend-epub3[]
include::../../../../../shared/asciidoctor.adoc[]
endif::[]
endif::[]

ifndef::env-beastie[]
toc::[]
include::../../../../../shared/asciidoctor.adoc[]
endif::[]

[[security-synopsis]]
== Sinopse

A segurança, seja física ou virtual, é um tópico tão amplo que todo um setor evoluiu em torno dele. Centenas de práticas padrão foram criadas sobre como proteger sistemas e redes e, como usuário do FreeBSD, é essencial entender como se proteger contra ataques e intrusos.

Neste capítulo, vários fundamentos e técnicas serão discutidos. O sistema FreeBSD vem com múltiplas camadas de segurança, e muitos outros utilitários de terceiros podem ser adicionados para aumentar a segurança.

Depois de ler este capítulo, você saberá:

* Conceitos básicos de segurança do sistema FreeBSD.
* Os vários mecanismos de criptografia disponíveis no FreeBSD.
* Como configurar a autenticação de senha única.
* Como configurar o TCP Wrapper para uso com o man:inetd[8].
* Como configurar o Kerberos no FreeBSD.
* Como configurar o IPsec e criar uma VPN.
* Como configurar e usar o OpenSSH no FreeBSD.
* Como usar ACLs para o sistema de arquivos .
* Como usar o pkg para auditar pacotes de software de terceiros instalados a partir da Coleção de Ports.
* Como utilizar os alertas de segurança do FreeBSD.
* O que é Auditoria de Processos e como ativá-la no FreeBSD.
* Como controlar os recursos do usuário usando classes de login ou o banco de dados de limites de recursos.

Antes de ler este capítulo, você deve:

* Entender os conceitos básicos do FreeBSD e de Internet.

Tópicos de segurança adicionais são abordados em outras partes deste Manual. Por exemplo, o Controle de Acesso Obrigatório é discutido em crossref:mac[mac, Controle de acesso obrigatório] e os firewalls da Internet são discutidos em crossref:firewalls[firewalls, Firewalls].

[[security-intro]]
== Introdução

Segurança é responsabilidade de todos. Um ponto de entrada fraco em qualquer sistema pode permitir que intrusos obtenham acesso a informações críticas e causem estragos em toda a rede. Um dos princípios centrais da segurança da informação é a tríade CIA, que significa Confidencialidade, Integridade e Disponibilidade dos sistemas de informação.

A tríade CIA é um conceito básico de segurança de computadores, pois os clientes e usuários esperam que seus dados sejam protegidos. Por exemplo, um cliente espera que as informações do cartão de crédito sejam armazenadas com segurança (confidencialidade), que os pedidos não sejam alterados nos bastidores (integridade) e que tenham acesso às informações do pedido em todos os momentos (disponibilidade).

Para fornecer CIA, os profissionais de segurança aplicam uma estratégia de defesa em profundidade. A ideia de defesa em profundidade é adicionar várias camadas de segurança para evitar que uma falha em uma única camada e faça com que todo o sistema de segurança entre em colapso. Por exemplo, um administrador do sistema não pode simplesmente ativar um firewall e considerar a rede ou o sistema seguro. É preciso também auditar contas, verificar a integridade dos binários e garantir que ferramentas maliciosas não estejam instaladas. Para implementar uma estratégia de segurança eficaz, é preciso entender as ameaças e como se defender delas.

O que é uma ameaça no que se refere à segurança do computador? As ameaças não se limitam a invasores remotos que tentam acessar um sistema sem permissão de um local remoto. As ameaças também incluem funcionários, softwares mal-intencionados, dispositivos de rede não autorizados, desastres naturais, vulnerabilidades de segurança e até corporações concorrentes.

Sistemas e redes podem ser acessados sem permissão, às vezes por acidente, ou por atacantes remotos e, em alguns casos, por meio de espionagem corporativa ou ex-funcionários. Como usuário, é importante se preparar e admitir quando um erro levou a uma violação de segurança e relatar possíveis problemas à equipe de segurança. Como administrador, é importante conhecer as ameaças e estar preparado para mitigá-las.

Ao aplicar a segurança aos sistemas, recomenda-se começar protegendo as contas básicas e a configuração do sistema e, em seguida, proteger a camada de rede de modo a aderir à política do sistema e aos procedimentos de segurança da organização. Muitas organizações já possuem uma política de segurança que abrange a configuração de dispositivos de tecnologia. A política deve incluir a configuração de segurança de estações de trabalho, desktops, dispositivos móveis, telefones, servidores de produção e servidores de desenvolvimento. Em muitos casos, procedimentos operacionais padrão (SOPs) já existem. Em caso de dúvida, pergunte à equipe de segurança.

O restante desta introdução descreve como algumas dessas configurações básicas de segurança são executadas em um sistema FreeBSD. O restante deste capítulo descreve algumas ferramentas específicas que podem ser usadas ao implementar uma política de segurança em um sistema FreeBSD.

[[security-accounts]]
=== Prevenindo Logins

Ao garantir a segurança de um sistema, um bom ponto de partida é uma auditoria de contas. Assegure-se de que o `root` tenha uma senha forte e que essa senha não seja compartilhada. Desabilite todas as contas que não precisam de acesso de para logar.

Para negar acesso de login a contas, existem dois métodos. O primeiro é bloquear a conta. Este exemplo bloqueia a conta `toor`:

[source,shell]
....
# pw lock toor
....

O segundo método é impedir o acesso ao login alterando o shell para [.filename]#/usr/sbin/nologin#. Apenas o superusuário pode alterar o shell para outros usuários:

[source,shell]
....
# chsh -s /usr/sbin/nologin toor
....

O shell [.filename]#/usr/sbin/nologin# impede que o sistema atribua um shell ao usuário quando ele tenta efetuar login.

[[security-accountmgmt]]
=== Escalonamento de Contas Permitido

Em alguns casos, a administração do sistema precisa ser compartilhada com outros usuários. O FreeBSD tem dois métodos para lidar com isso. O primeiro, que não é recomendado, é uma senha de root compartilhada usada por membros do grupo `wheel`. Com esse método, um usuário digita `su` e insere a senha para `wheel` sempre que o acesso do superusuário for necessário. O usuário deve então digitar `exit` para deixar o acesso privilegiado após terminar os comandos que requereram acesso administrativo. Para adicionar um usuário a este grupo, edite [.filename]#/etc/group# e adicione o usuário ao final da entrada `wheel`. O usuário deve ser separado por um caractere vírgula sem espaço.

O segundo e recomendado método para permitir o escalonamento de privilégios é instalar o pacote ou port package:security/sudo[]. Este software fornece auditoria adicional, controle de usuário mais refinado e pode ser configurado para bloquear os usuários para que executem apenas os comandos privilegiados especificados.

Após a instalação, use o `visudo` para editar o [.filename]#/usr/local/etc/sudoers#. Este exemplo cria um novo grupo `webadmin`, adiciona a conta `trhodes` a esse grupo e configura esse acesso de grupo para reiniciar o package:apache24[]:

[source,shell]
....
# pw groupadd webadmin -M trhodes -g 6000
# visudo
%webadmin ALL=(ALL) /usr/sbin/service apache24 *
....

[[security-passwords]]
=== Hashes de Senhas

As senhas são um mal necessário da tecnologia. Quando elas devem ser usadas, elas devem ser complexas e um poderoso mecanismo de hash deve ser usado para criptografar a versão armazenada no banco de dados de senhas. O FreeBSD suporta os algoritmos de DES, MD5, SHA256, SHA512 e Blowfish na sua biblioteca `crypt()`. O padrão de SHA512 não deve ser alterado para um algoritmo hash menos seguro, mas pode ser alterado para o algoritmo Blowfish mais seguro.

[NOTE]
====
O Blowfish não faz parte do AES e não é considerado compatível com nenhum Federal Information Processing Standard (FIPS). Seu uso pode não ser permitido em alguns ambientes.
====

Para determinar qual algoritmo de hash é usado para criptografar a senha de um usuário, o superusuário pode visualizar o hash do usuário no banco de dados de senhas do FreeBSD. Cada hash começa com um símbolo que indica o tipo de mecanismo de hash usado para criptografar a senha. Se DES for usado, não haverá símbolo de início. Para MD5, o símbolo é `$`. Para SHA256 e SHA512, o símbolo é `$6$`. Para o Blowfish, o símbolo é `$2a$`. Neste exemplo, a senha para `dru` é criptografada usando o algoritmo SHA512 padrão quando o hash começa com `$6$`. Observe que o hash criptografado, não a senha em si, é armazenado no banco de dados de senhas:

[source,shell]
....
# grep dru /etc/master.passwd
dru:$6$pzIjSvCAn.PBYQBA$PXpSeWPx3g5kscj3IMiM7tUEUSPmGexxta.8Lt9TGSi2lNQqYGKszsBPuGME0:1001:1001::0:0:dru:/usr/home/dru:/bin/csh
....

O mecanismo de hash é definido na classe de login do usuário. Para este exemplo, o usuário está na classe de login `default` e o algoritmo de hash é definido com esta linha em [.filename]#/etc/login.conf#:

[.programlisting]
....
        :passwd_format=sha512:\
....

Para alterar o algoritmo para Blowfish, modifique a linha para ficar assim:

[.programlisting]
....
        :passwd_format=blf:\
....

Em seguida, execute `cap_mkdb /etc/login.conf` conforme descrito em <<users-limiting>>. Observe que essa alteração não afetará os hashes de senha existentes. Isso significa que todas as senhas devem ser refeitas pedindo aos usuários que executem `passwd` para alterar sua senha.

Para logins remotos, a autenticação de dois fatores deve ser usada. Um exemplo de autenticação de dois fatores é "algo que você tem", como uma chave, e "algo que você conhece", como a senha para essa chave. Como o OpenSSH é parte do sistema básico do FreeBSD, todos os logins de rede devem ser sobre uma conexão criptografada e usar autenticação baseada em chave em vez de senhas. Para mais informações, consulte <<openssh>>. Os usuários do Kerberos podem precisar fazer alterações adicionais para implementar o OpenSSH em sua rede. Essas alterações são descritas em <<kerberos5>>.

[[security-pwpolicy]]
=== Aplicação de Política de Senha

Aplicar uma política de senha forte para contas locais é um aspecto fundamental da segurança do sistema. No FreeBSD, o tamanho da senha, a força da senha e a complexidade da senha podem ser implementados usando os Módulos de Autenticação Conectáveis (PAM).

Esta seção demonstra como configurar o tamanho mínimo e máximo da senha e a imposição de caracteres mistos usando o módulo [.filename]#pam_passwdqc.so#. Este módulo é aplicado quando um usuário altera sua senha.

Para configurar este módulo, torne-se o superusuário e remova o comentário da linha contendo `pam_passwdqc.so` em [.filename]#/etc/pam.d/passwd#. Em seguida, edite essa linha para corresponder à política de senha:

[.programlisting]
....
password        requisite       pam_passwdqc.so         min=disabled,disabled,disabled,12,10 similar=deny retry=3 enforce=users
....

Este exemplo define vários requisitos para novas senhas. A configuração `min` controla o tamanho mínimo da senha. Ele tem cinco valores porque este módulo define cinco tipos diferentes de senhas com base em sua complexidade. Complexidade é definida pelo tipo de caracteres que devem existir em uma senha, como letras, números, símbolos e maiúsculas e minúsculas. Os tipos de senhas são descritos em man:pam_passwdqc[8]. Neste exemplo, os três primeiros tipos de senha são desativados, o que significa que as senhas que atendem a esses requisitos de complexidade não serão aceitas, independentemente da sua duração. O `12` define uma política de senha mínima de pelo menos doze caracteres, se a senha também contiver caracteres com três tipos de complexidade. O `10` define a política de senha para também permitir senhas de pelo menos dez caracteres, se a senha contiver caracteres com quatro tipos de complexidade.

A configuração `similar` nega senhas semelhantes à senha anterior do usuário. A configuração `retry` fornece ao usuário três oportunidades para inserir uma nova senha.

Depois que este arquivo for salvo, um usuário que alterar sua senha verá uma mensagem semelhante a seguinte:

[source,shell]
....
% passwd
Changing local password for trhodes
Old Password:

You can now choose the new password.
A valid password should be a mix of upper and lower case letters,
digits and other characters.  You can use a 12 character long
password with characters from at least 3 of these 4 classes, or
a 10 character long password containing characters from all the
classes.  Characters that form a common pattern are discarded by
the check.
Alternatively, if no one else can see your terminal now, you can
pick this as your password: "trait-useful&knob".
Enter new password:
....

Se uma senha que não corresponde à política for inserida, ela será rejeitada com um aviso e o usuário terá a oportunidade de tentar novamente, até o número configurado de novas tentativas.

A maioria das políticas de senha exige que as senhas expirem depois de tantos dias. Para definir um tempo de expiração da senha no FreeBSD, defina `passwordtime` para a classe de login do usuário em [.filename]#/etc/login.conf#. A classe de login `default` contém um exemplo:

[.programlisting]
....
#       :passwordtime=90d:\
....

Portanto, para definir uma expiração de 90 dias para esta classe de login, remova o símbolo de comentário (`#`), salve a edição e execute o `cap_mkdb /etc/login.conf`.

Para definir a expiração em usuários individuais, passe uma data de expiração ou o número de dias para expirar e um nome de usuário para o comando `pw`:

[source,shell]
....
# pw usermod -p 30-apr-2015 -n trhodes
....

Como visto aqui, uma data de expiração é definida na forma de dia, mês e ano. Para obter maiores informações, consulte man:pw[8].

[[security-rkhunter]]
=== Detectando Rootkits

Um _rootkit_ é qualquer software não autorizado que tente obter acesso como `root` a um sistema. Uma vez instalado, esse software mal-intencionado normalmente abrirá outro caminho de entrada para um invasor. Realisticamente, uma vez que um sistema foi comprometido por um rootkit e uma investigação foi realizada, o sistema deve ser reinstalado do zero. Existe um tremendo risco de que mesmo o engenheiro de sistemas ou segurança mais prudente perca algo que um invasor deixou para trás.

Um rootkit faz uma coisa útil para administradores: uma vez detectado, é um sinal de que um comprometimento aconteceu em algum momento. Mas, esses tipos de aplicativos tendem a ser muito bem ocultos. Esta seção demonstra uma ferramenta que pode ser usada para detectar rootkits, package:security/rkhunter[].

Após a instalação deste pacote ou port, o sistema pode ser verificado usando o seguinte comando. Ele produzirá muitas informações e exigirá uma entrada manual da tecla kbd:[ENTER]:

[source,shell]
....
# rkhunter -c
....

Depois que o processo for concluído, uma mensagem de status será impressa na tela. Esta mensagem incluirá a quantidade de arquivos verificados, arquivos suspeitos, possíveis rootkits e mais. Durante a verificação, alguns avisos de segurança genéricos podem ser produzidos sobre arquivos ocultos, a seleção do protocolo OpenSSH e versões vulneráveis conhecidas do software instalado. Estes podem ser tratados agora ou após uma análise mais detalhada ter sido realizada.

Todo administrador deve saber o que está sendo executado nos sistemas pelos quais é responsável. Ferramentas de terceiros como o rkhunter e o package:sysutils/lsof[] e comandos nativos como o `netstat` e o `ps`, podem mostrar uma grande quantidade de informações sobre o sistema. Faça anotações sobre o que é normal, faça perguntas quando algo parecer fora do lugar e seja paranoico. Embora evitar um comprometimento seja ideal, detectar um comprometimento é imprescindível.

[[security-ids]]
=== Verificação Binária

A verificação de arquivos e binários do sistema é importante porque fornece às equipes de administração e segurança do sistema informações sobre alterações no sistema. Uma aplicação de software que monitora o sistema para alterações é chamado de Sistema de Detecção de Intrusão (IDS).

O FreeBSD fornece suporte nativo para um sistema de IDS básico. Embora os emails de segurança noturnos notifiquem o administrador sobre alterações, as informações são armazenadas localmente e há uma chance de que um usuário mal-intencionado modifique essas informações para ocultar suas alterações no sistema. Como tal, recomenda-se criar um conjunto separado de assinaturas binárias e armazená-las em um diretório de read-only, propriedade do root ou, de preferência, em um disco USB removível ou servidor rsync remoto.

O utilitário `mtree` embutido pode ser usado para gerar uma especificação do conteúdo de um diretório. Um seed, ou uma constante numérica, é usada para gerar a especificação e é necessária para verificar se a especificação não foi alterada. Isso possibilita determinar se um arquivo ou binário foi modificado. Como o valor inicial do seed é desconhecido por um invasor, disfarçar ou impossibilitar a verificação dos valores de checksum dos arquivos será difícil ou impossível. O exemplo a seguir gera um conjunto de hashes SHA256, um para cada sistema binário no diretório [.filename]#/bin# e salva esses valores em um arquivo oculto no diretório inicial do `root`, [.filename]#/root/.bin_chksum_mtree#:

[source,shell]
....
# mtree -s 3483151339707503 -c -K cksum,sha256digest -p /bin > /root/.bin_chksum_mtree
# mtree: /bin checksum: 3427012225
....

O _3483151339707503_ representa o seed. Este valor deve ser lembrado, mas não compartilhado.

Visualizar o arquivo [.filename]#/root/.bin_cksum_mtree# deve produzir uma saída semelhante à seguinte:

[.programlisting]
....
#          user: root
#       machine: dreadnaught
#          tree: /bin
#          date: Mon Feb  3 10:19:53 2014

# .
/set type=file uid=0 gid=0 mode=0555 nlink=1 flags=none
.               type=dir mode=0755 nlink=2 size=1024 \
                time=1380277977.000000000
    \133        nlink=2 size=11704 time=1380277977.000000000 \
                cksum=484492447 \
                sha256digest=6207490fbdb5ed1904441fbfa941279055c3e24d3a4049aeb45094596400662a
    cat         size=12096 time=1380277975.000000000 cksum=3909216944 \
                sha256digest=65ea347b9418760b247ab10244f47a7ca2a569c9836d77f074e7a306900c1e69
    chflags     size=8168 time=1380277975.000000000 cksum=3949425175 \
                sha256digest=c99eb6fc1c92cac335c08be004a0a5b4c24a0c0ef3712017b12c89a978b2dac3
    chio        size=18520 time=1380277975.000000000 cksum=2208263309 \
                sha256digest=ddf7c8cb92a58750a675328345560d8cc7fe14fb3ccd3690c34954cbe69fc964
    chmod       size=8640 time=1380277975.000000000 cksum=2214429708 \
                sha256digest=a435972263bf814ad8df082c0752aa2a7bdd8b74ff01431ccbd52ed1e490bbe7
....

O nome do host da máquina, a data e a hora em que a especificação foi criada e o nome do usuário que criou a especificação são incluídos neste relatório. Há um checksum, tamanho, hora e um digest SHA256 para cada binário no diretório.

Para verificar se as assinaturas binárias não foram alteradas, compare o conteúdo atual do diretório com a especificação gerada anteriormente e salve os resultados em um arquivo. Este comando requer o seed que foi usado para gerar a especificação original:

[source,shell]
....
# mtree -s 3483151339707503 -p /bin < /root/.bin_chksum_mtree >> /root/.bin_chksum_output
# mtree: /bin checksum: 3427012225
....

Isso deve produzir o mesmo checksum para [.filename]#/bin# que foi produzido quando a especificação foi criada. Se nenhuma alteração tiver ocorrido nos binários nesse diretório, o arquivo de saída [.filename]#/root/.bin_chksum_output# estará vazio. Para simular uma alteração, altere a data no arquivo [.filename]#/bin/cat# usando o `touch` e execute o comando de verificação novamente:

[source,shell]
....
# touch /bin/cat
# mtree -s 3483151339707503 -p /bin < /root/.bin_chksum_mtree >> /root/.bin_chksum_output
# more /root/.bin_chksum_output
cat changed
	modification time expected Fri Sep 27 06:32:55 2013 found Mon Feb  3 10:28:43 2014
....

Recomenda-se criar especificações para os diretórios que contêm binários e arquivos de configuração, bem como quaisquer diretórios que contenham dados sensíveis. Normalmente, as especificações são criadas para [.filename]#/bin#, [.filename]#/sbin#, [.filename]#/usr/bin#, [.filename]#/usr/sbin#, [.filename]#/usr/local/bin#, [.filename]#/etc# e [.filename]#/usr/local/etc#.

Existem sistemas de IDS mais avançados, como o package:security/aide[]. Na maioria dos casos, o `mtree` fornece a funcionalidade que os administradores precisam. É importante manter o valor inicial e a saída do checksum oculta de usuários mal-intencionados. Maiores informações sobre o `mtree` podem ser encontradas em man:mtree[8].

[[security-tuning]]
=== Otimizando o Sistema para Segurança

No FreeBSD, muitos recursos do sistema podem ser ajustados usando o `sysctl`. Alguns dos recursos de segurança que podem ser ajustados para impedir ataques de negação de serviço (DoS) serão abordados nesta seção. Mais informações sobre o uso do `sysctl`, incluindo como alterar temporariamente os valores e como tornar as alterações permanentes após o teste, podem ser encontradas em crossref:config[configtuning-sysctl,Efetuando ajustes com o sysctl(8)].

[NOTE]
====
Sempre que uma configuração é alterada com o `sysctl`, a chance de causar danos indesejados é aumentada, afetando a disponibilidade do sistema. Todas as alterações devem ser monitoradas e, se possível, testadas em um sistema de teste antes de serem usadas em um sistema de produção.
====

Por padrão, o kernel do FreeBSD é inicializado com um nível de segurança `-1`. Isso é chamado de "modo inseguro" porque as flags de arquivos imutáveis podem ser desativadas e todos os dispositivos podem ser lidos ou gravados. O nível de segurança permanecerá em `-1`, a menos que seja alterado através do `sysctl` ou por uma configuração nos scripts de inicialização. O nível de segurança pode ser aumentado durante a inicialização do sistema, definindo `kern_securelevel_enable` para `YES` no arquivo [.filename]#/etc/rc.conf#, e o valor de `kern_securelevel` para o nível de segurança desejado. Veja man:security[7] e man:init[8] para maiores informações sobre essas configurações e os níveis de segurança disponíveis.

[WARNING]
====

Aumentar o valor da variável `securelevel` pode quebrar o Xorg e causar outros problemas. Esteja preparado para fazer alguma depuração.
====

As configurações da variável `net.inet.tcp.blackhole` e `net.inet.udp.blackhole` podem ser usadas para descartar pacotes SYN de entrada em portas fechadas sem enviar uma resposta RST. O comportamento padrão é retornar um RST para mostrar que uma porta está fechada. A alteração do padrão fornece algum nível de proteção contra varreduras de portas, que são usadas para determinar quais aplicativos estão sendo executados em um sistema. Defina `net.inet.tcp.blackhole` para `2` e `net.inet.udp.blackhole` para `1`. Consulte man:blackhole[4] para obter maiores informações sobre essas configurações.

As configurações das variáveis `net.inet.icmp.drop_redirect` e `net.inet.ip.redirect` ajudam a evitar _ataques de redirecionamento_. Um ataque de redirecionamento é um tipo de DoS que envia um grande número de pacotes ICMP tipo 5. Como esses pacotes não são necessários, configure `net.inet.icmp.drop_redirect` para `1` e configure `net.inet.ip.redirect` para `0`.

O roteamento de origem é um método para detectar e acessar endereços não roteáveis na rede interna. Isso deve ser desativado, pois endereços não roteáveis normalmente não são roteáveis de propósito. Para desativar este recurso, defina `net.inet.ip.sourceroute` e `net.inet.ip.accept_sourceroute` como `0`.

Quando uma máquina na rede precisa enviar mensagens para todos os hosts em uma sub-rede, uma mensagem de solicitação echo do ICMP é enviada para o endereço de broadcast. No entanto, não há motivo para um host externo executar essa ação. Para rejeitar todas as solicitações externas de transmissão, defina `net.inet.icmp.bmcastecho` como `0`.

Algumas configurações adicionais estão documentadas em man:security[7].

[[one-time-passwords]]
== Senhas de Uso Unico

Por padrão, o FreeBSD inclui suporte para senhas de uso único em tudo (OPIE). O OPIE é projetado para evitar ataques repetidos, nos quais um atacante descobre a senha de um usuário e a usa para acessar um sistema. Como uma senha é usada apenas uma vez em OPIE, uma senha descoberta é de pouca utilidade para um invasor. O OPIE usa um hash seguro e um sistema de desafio/resposta para gerenciar senhas. A implementação do FreeBSD usa o hash MD5 por padrão.

O OPIE usa três tipos diferentes de senhas. A primeira é a senha usual UNIX(TM) ou Kerberos. A segunda é a senha única que é gerada pelo `opiekey`. O terceiro tipo de senha é a "senha secreta" que é usada para gerar senhas de uso único. A senha secreta não tem nada a fazer com ela e deve ser diferente da senha UNIX(TM).

Existem duas outras partes de dados importantes para o OPIE. Uma é o "seed" ou "chave", composta por duas letras e cinco dígitos. A outra é a "contagem de iteração", um número entre 1 e 100. O OPIE cria a senha única concatenando o seed e a senha secreta, aplicando o hash  MD5  quantas vezes forem especificadas pela contagem de iterações e transformando o resultado em seis palavras inglesas curtas que representam a senha de uso único. O sistema de autenticação controla a última senha descartável usada e o usuário é autenticado se o hash da senha fornecida pelo usuário for igual à senha anterior. Como um hash unidirecional é usado, é impossível gerar futuras senhas de uso único se uma senha usada com êxito for capturada. A contagem de iteração é diminuída após cada login bem-sucedido para manter o usuário e o programa de login em sincronia. Quando a contagem de iterações descer para `1`, o OPIE deve ser reinicializado.

Existem alguns programas envolvidos neste processo. Uma senha de uso único, ou uma lista consecutiva de senhas de uso único, é gerada passando uma contagem de iteração, um seed e uma senha secreta para o man:opiekey[1]. Além de inicializar o OPIE, o man:opiepasswd[1] é usado para alterar senhas, contagens de iteração ou seeds. Os arquivos de credenciais relevantes em [.filename]#/etc/opiekeys# são examinados pelo man:opieinfo[1] o qual imprime a iteração atual e o seed do usuário solicitante atual.

Esta seção descreve quatro tipos diferentes de operações. A primeira é como configurar senhas de uso único pela primeira vez em uma conexão segura. A segunda é como usar o `opiepasswd` em uma conexão insegura. A terceira é como efetuar login em uma conexão insegura. A quarta é como gerar um número de chaves que podem ser escritas ou impressas para uso em locais inseguros.

=== Inicializando o OPIE

Para inicializar o OPIE pela primeira vez, execute este comando a partir de um local seguro:

[source,shell]
....
% opiepasswd -c
Adding unfurl:
Only use this method from the console; NEVER from remote. If you are using
telnet, xterm, or a dial-in, type ^C now or exit with no password.
Then run opiepasswd without the -c parameter.
Using MD5 to compute responses.
Enter new secret pass phrase:
Again new secret pass phrase:

ID unfurl OTP key is 499 to4268
MOS MALL GOAT ARM AVID COED
....

A opção `-c` define o modo de console que assume que o comando está sendo executado de um local seguro, como um computador sob o controle do usuário ou uma sessão SSH para um computador sob o controle do usuário.

Quando solicitado, insira a senha secreta que será usada para gerar as chaves de login de uso único. Essa senha deve ser difícil de adivinhar e deve ser diferente da senha associada à conta de login do usuário. Deve ter entre 10 e 127 caracteres. Lembre-se desta senha.

A linha `ID` lista o nome de login (`unfurl`), a contagem de iterações padrão (`499`) e o seed padrão (`to4268`). Ao efetuar o login, o sistema lembrará esses parâmetros e os exibirá, o que significa que eles não precisam ser memorizados. A última linha lista a senha única gerada que corresponde a esses parâmetros e a senha secreta. No próximo login, use essa senha única.

=== Inicialização de uma Conexão Insegura

Para inicializar ou alterar a senha secreta em um sistema inseguro, é necessária uma conexão segura em algum lugar onde o `opiekey` possa ser executado. Isso pode ser um prompt de shell em uma máquina confiável. Uma contagem de iteração é necessária, em que 100 é provavelmente um bom valor, e o seed pode ser especificado ou a gerado aleatoriamente. Na conexão insegura, a máquina sendo inicializada, use man:opiepasswd[1]:

[source,shell]
....
% opiepasswd

Updating unfurl:
You need the response from an OTP generator.
Old secret pass phrase:
	otp-md5 498 to4268 ext
	Response: GAME GAG WELT OUT DOWN CHAT
New secret pass phrase:
	otp-md5 499 to4269
	Response: LINE PAP MILK NELL BUOY TROY

ID mark OTP key is 499 gr4269
LINE PAP MILK NELL BUOY TROY
....

Para aceitar o seed padrão, pressione kbd:[Return]. Antes de inserir uma senha de acesso, passe para a conexão segura e forneça os mesmos parâmetros:

[source,shell]
....
% opiekey 498 to4268
Using the MD5 algorithm to compute response.
Reminder: Do not use opiekey from telnet or dial-in sessions.
Enter secret pass phrase:
GAME GAG WELT OUT DOWN CHAT
....

Volte para a conexão insegura e copie a senha única gerada para o programa relevante.

=== Gerando uma Senha de Uso Único

Depois de inicializar o OPIE e efetuar login, um prompt como este será exibido:

[source,shell]
....
% telnet example.com
Trying 10.0.0.1...
Connected to example.com
Escape character is '^]'.

FreeBSD/i386 (example.com) (ttypa)

login: <username>
otp-md5 498 gr4269 ext
Password: 
....

Os prompts do OPIE fornecem um recurso útil. Se o kbd:[Enter] for pressionado no prompt de senha, o prompt ativará o echo e exibirá o que foi digitado. Isso pode ser útil ao tentar digitar uma senha manualmente a partir de uma impressão.

Neste ponto, gere a senha de uso único para responder a este aviso de login. Isso deve ser feito em um sistema confiável em que seja seguro executar o man:opiekey[1]. Existem versões deste comando para Windows(TM), Mac OS(TM) e FreeBSD. Esse comando precisa da contagem de iteração e do seed como opções da linha de comandos. Use recortar e colar no prompt de login da máquina que está sendo conectada.

No sistema confiável:

[source,shell]
....
% opiekey 498 to4268
Using the MD5 algorithm to compute response.
Reminder: Do not use opiekey from telnet or dial-in sessions.
Enter secret pass phrase:
GAME GAG WELT OUT DOWN CHAT
....

Depois que a senha descartável for gerada, continue a logar.

=== Gerando Múltiplas Senhas de Uso Único

Às vezes, não há acesso a uma máquina confiável ou conexão segura. Neste caso, é possível usar o man:opiekey[1] para gerar algumas de senhas de uso único antecipadamente. Por exemplo:

[source,shell]
....
% opiekey -n 5 30 zz99999
Using the MD5 algorithm to compute response.
Reminder: Do not use opiekey from telnet or dial-in sessions.
Enter secret pass phrase: <secret password>
26: JOAN BORE FOSS DES NAY QUIT
27: LATE BIAS SLAY FOLK MUCH TRIG
28: SALT TIN ANTI LOON NEAL USE
29: RIO ODIN GO BYE FURY TIC
30: GREW JIVE SAN GIRD BOIL PHI
....

A opção `-n 5` solicita cinco chaves em seqüência e `30` especifica qual deve ser o último número de iteração. Note que estes são impressos na ordem _reversa_ de uso. O usuário realmente paranóico pode querer escrever os resultados manualmente; caso contrário, imprima a lista. Cada linha mostra a contagem de iteração e a senha de uso único. Risque as senhas conforme elas forem usadas.

=== Restringindo o Uso de Senhas UNIX(TM)

O OPIE pode restringir o uso de senhas UNIX(TM) com base no endereço IP de uma sessão de login. O arquivo relevante é o [.filename]#/etc/opieaccess#, que está presente por padrão. Consulte man:opieaccess[5] para obter maiores informações sobre esse arquivo e sobre quais considerações de segurança você deve estar ciente ao usá-lo.

Aqui está um exemplo do arquivo [.filename]#opieaccess#:

[.programlisting]
....
permit 192.168.0.0 255.255.0.0
....

Esta linha permite que os usuários cujo endereço de origem IP (que é vulnerável a spoofing) corresponda ao valor e à máscara especificados, para usar as senhas UNIX(TM) a qualquer momento.

Se nenhuma regra do arquivo [.filename]#opieaccess# for correspondida, o padrão é negar logins que não sejam OPIE.

[[tcpwrappers]]
== TCP Wrapper

O TCP Wrapper é um sistema de controle de acesso baseado em host que estende as habilidades do crossref:network-servers[network-inetd,O super-servidor inetd]. Ele pode ser configurado para fornecer suporte de registro, mensagens de retorno e restrições de conexão para os daemons do servidor sob o controle do inetd. Consulte man:tcpd[8] para obter maiores informações sobre o TCP Wrapper e seus recursos.

O TCP Wrapper não deve ser considerado um substituto para um firewall configurado adequadamente. Em vez disso, TCP Wrapper deve ser usado em conjunto com um firewall e outros aprimoramentos de segurança para fornecer outra camada de proteção na implementação de uma política de segurança.

=== Configuração Inicial

Para ativar o TCP Wrapper no FreeBSD, adicione as seguintes linhas ao arquivo [.filename]#/etc/rc.conf#:

[.programlisting]
....
inetd_enable="YES"
inetd_flags="-Ww"
....

Então, configure corretamente o arquivo [.filename]#/etc/hosts.allow#.

[NOTE]
====
Ao contrário de outras implementações do TCP Wrapper, o uso do arquivo [.filename]#hosts.deny# foi preterido no FreeBSD. Todas as opções de configuração devem ser colocadas no arquivo [.filename]#/etc/hosts.allow#.
====

Na configuração mais simples, as políticas de conexão do daemon são configuradas para permitir ou bloquear, dependendo das opções no arquivo [.filename]#/etc/hosts.allow#. A configuração padrão no FreeBSD é permitir todas as conexões para os daemons iniciados com o inetd.

A configuração básica geralmente assume a forma de `daemon : address : action`, onde `daemon` é o daemon que o inetd iniciou, `address` é um nome de host válido ou um endereço IP ou um endereço IPv6 entre colchetes ([]) e `action` é `allow` ou `deny`. O TCP Wrapper usa uma semântica de correspondência de primeira regra, o que significa que o arquivo de configuração é varrido desde o início para uma regra correspondente. Quando uma correspondência é encontrada, a regra é aplicada e o processo de pesquisa é interrompido.

Por exemplo, para permitir conexões POP3 através do daemon package:mail/qpopper[], as seguintes linhas devem ser anexadas ao arquivo [.filename]#hosts.allow#:

[.programlisting]
....
# This line is required for POP3 connections:
qpopper : ALL : allow
....

Sempre que este arquivo for editado, reinicie o inetd:

[source,shell]
....
# service inetd restart
....

=== Configuração Avançada

O TCP Wrapper fornece opções avançadas para permitir mais controle sobre o modo como as conexões são tratadas. Em alguns casos, pode ser apropriado retornar um comentário para determinados hosts ou conexões de daemon. Em outros casos, uma entrada de log deve ser registrada ou um email enviado ao administrador. Outras situações podem exigir o uso de um serviço apenas para conexões locais. Isso tudo é possível através do uso de opções de configuração conhecidas como wildcards, caracteres de expansão e execução de comandos externos.

Suponha que uma situação ocorra onde uma conexão deva ser negada, mas uma razão deve ser enviada ao host que tentou estabelecer essa conexão. Essa ação é possível com a opção `twist`. Quando uma tentativa de conexão é feita, o `twist` executa um comando ou script shell. Existe um exemplo no arquivo [.filename]#hosts.allow#:

[.programlisting]
....
# The rest of the daemons are protected.
ALL : ALL \
	: severity auth.info \
	: twist /bin/echo "You are not welcome to use %d from %h."
....

Neste exemplo, a mensagem "You are not allowed to use _daemon name_ from _hostname_." será retornada para qualquer daemon não configurado no [.filename]#hosts.allow#. Isso é útil para enviar uma resposta de volta ao inicializador de conexão logo após a conexão estabelecida ser descartada. Qualquer mensagem a ser retornada _deve_ ser delimitada por caracteres de aspas duplas (`"`).

[WARNING]
====

Pode ser possível iniciar um ataque de negação de serviço no servidor se um invasor inunda esses daemons com solicitações de conexão.
====

Outra possibilidade é usar a opção `spawn`. Como a opção `twist`, a opção `spawn` implicitamente nega a conexão e pode ser usado para executar comandos ou scripts externos do shell. Ao contrário da `twist`, a `spawn` não enviará uma resposta ao host que estabeleceu a conexão. Por exemplo, considere a seguinte configuração:

[.programlisting]
....
# We do not allow connections from example.com:
ALL : .example.com \
	: spawn (/bin/echo %a from %h attempted to access %d >> \
	  /var/log/connections.log) \
	: deny
....

Isso negará todas as tentativas de conexão de `*.example.com` e registrará o nome do host, endereço IP e o daemon ao qual o acesso foi tentado no arquivo [.filename]#/var/log/connections.log#. Este exemplo usa os caracteres de substituição `%a` e `%h`. Consulte man:hosts_access[5] para a lista completa.

Para corresponder a cada instância de um daemon, domínio ou endereço IP, use `ALL`. Outro wildcard é o `PARANOID`, que pode ser usado para corresponder a qualquer host que forneça um endereço IP que possa ser forjado, porque o endereço IP difere do nome resolvido para o host. Neste exemplo, todas as solicitações de conexão para o Sendmail que possuem um endereço IP que varia de seu nome de host serão negadas:

[.programlisting]
....
# Block possibly spoofed requests to sendmail:
sendmail : PARANOID : deny
....

[CAUTION]
====

Usar o wildcard `PARANOID` resultará em conexões negadas se o cliente ou servidor tiver uma configuração de DNS incorreta.
====

Para saber mais sobre wildcards e sua funcionalidade associada, consulte man:hosts_access[5].

[NOTE]
====
Ao adicionar novas linhas de configuração, certifique-se de que quaisquer entradas desnecessárias para esse daemon sejam comentadas no arquivo [.filename]#hosts.allow#.
====

[[kerberos5]]
== Kerberos

O Kerberos é um protocolo de autenticação de rede que foi originalmente criado pelo Instituto de Tecnologia de Massachusetts (MIT) como uma maneira segura de fornecer autenticação em uma rede potencialmente hostil. O protocolo Kerberos usa criptografia robusta para que tanto um cliente quanto um servidor possam provar sua identidade sem enviar nenhum segredo não criptografado pela rede. O Kerberos pode ser descrito como um sistema proxy de verificação de identidade e como um sistema confiável de autenticação de terceiros. Depois que um usuário autentica com Kerberos, suas comunicações podem ser criptografadas para garantir privacidade e integridade dos dados.

A única função do Kerberos é fornecer a autenticação segura de usuários e servidores na rede. Ele não fornece funções de autorização ou auditoria. Recomenda-se que o Kerberos seja usado com outros métodos de segurança que forneçam serviços de autorização e auditoria.

A versão atual do protocolo é a versão 5, descrita na RFC 4120. Várias implementações gratuitas deste protocolo estão disponíveis, abrangendo uma ampla gama de sistemas operacionais. O MIT continua desenvolvendo o pacote Kerberos. É comumente usado no US como um produto de criptografia e, historicamente, está sujeito aos regulamentos de exportação dos US. No FreeBSD, o MITKerberos está disponível como o pacote ou port package:security/krb5[]. A implementação do Kerberos do Heimdal foi explicitamente desenvolvida fora do US para evitar regulamentações de exportação. A distribuição Kerberos do Heimdal está incluída na instalação base do FreeBSD, e outra distribuição com opções mais configuráveis está disponível como package:security/heimdal[] na Coleção de Ports.

No Kerberos, os usuários e serviços são identificados como "principals", que estão contidos em um agrupamento administrativo chamado de "realm". Um usuário principal típico teria o formato `_user_@_REALM_` (os realms são tradicionalmente em caracteres maiúsculos).

Esta seção fornece um guia sobre como configurar o Kerberos usando a distribuição Heimdal incluída no FreeBSD.

Para fins de demonstração de uma instalação do Kerberos , os namespaces serão os seguintes:

* O domínio (zona) de domínio DNS será `example.org`.
* O realm Kerberos será `EXAMPLE.ORG`.

[NOTE]
====
Use nomes de domínio reais ao configurar o Kerberos, mesmo que ele seja executado internamente. Isso evita problemas de DNS e garante a interoperabilidade com outros realms do Kerberos.
====

=== Configurando um KDC do Heimdal

O Centro de Distribuição de Chaves (KDC) é o serviço de autenticação centralizada que o Kerberos fornece, a "a parte de terceiros confiáveis" do sistema. É o computador que emite os tíquetes Kerberos, que são usados para autenticação dos clientes nos servidores. Como o KDC é considerado confiável por todos os outros computadores no realm do Kerberos, isso aumenta as preocupações com a segurança. O acesso direto ao KDC deve ser limitado.

Embora a execução de um KDC exija poucos recursos de computação, uma máquina dedicada que atua apenas como um KDC é recomendada por motivos de segurança.

Para começar, instale o pacote package:security/heimdal[] assim:

[source,shell]
....
# pkg install heimdal
....

Em seguida, edite o [.filename]#/etc/rc.conf# como a seguir:

[source,shell]
....
# sysrc kdc_enable=yes
# sysrc kadmind_enable=yes
....

Em seguida, edite o arquivo [.filename]#/etc/krb5.conf# como a seguir:

[.programlisting]
....
[libdefaults]
    default_realm = EXAMPLE.ORG
[realms]
    EXAMPLE.ORG = {
	kdc = kerberos.example.org
	admin_server = kerberos.example.org
    }
[domain_realm]
    .example.org = EXAMPLE.ORG
....

Neste exemplo, o KDC usará o nome completo do host `kerberos.example.org`. O nome do host do KDC precisa ser resolvido no DNS.

O Kerberos também pode usar o DNS para localizar os KDCs, em vez de uma seção `[realms]` no arquivo [.filename]#/etc/krb5.conf#. Para grandes organizações que possuem seus próprios servidores DNS, o exemplo acima pode ser reduzido para:

[.programlisting]
....
[libdefaults]
      default_realm = EXAMPLE.ORG
[domain_realm]
    .example.org = EXAMPLE.ORG
....

Com as seguintes linhas sendo incluídas no arquivo de zona do domínio `example.org`:

[.programlisting]
....
_kerberos._udp      IN  SRV     01 00 88 kerberos.example.org.
_kerberos._tcp      IN  SRV     01 00 88 kerberos.example.org.
_kpasswd._udp       IN  SRV     01 00 464 kerberos.example.org.
_kerberos-adm._tcp  IN  SRV     01 00 749 kerberos.example.org.
_kerberos           IN  TXT     EXAMPLE.ORG
....

[NOTE]
====
Para que os clientes possam encontrar os serviços Kerberos, eles _devem_ ter um [.filename]#/etc/krb5.conf# totalmente configurado ou um [.filename]#/etc/krb5.conf# minimamente configurado _e_ um servidor DNS corretamente configurado.
====

Em seguida, crie o banco de dados do Kerberos que contém as chaves de todos os principals (usuários e hosts) criptografados com uma senha master. Não é necessário lembrar essa senha, pois ela será armazenada no arquivo [.filename]#/var/heimdal/m-key#; Seria razoável usar uma senha aleatória de 45 caracteres para essa finalidade. Para criar a chave master, execute `kstash` e digite uma senha:

[source,shell]
....
# kstash
Master key: xxxxxxxxxxxxxxxxxxxxxxx
Verifying password - Master key: xxxxxxxxxxxxxxxxxxxxxxx
....

Depois que a chave master é criada, o banco de dados deve ser inicializado. A ferramenta administrativa do Kerberosman:kadmin[8] pode ser usada no KDC em um modo que opera diretamente no banco de dados, sem usar o serviço de rede man:kadmind[8], como `kadmin -l`. Isso resolve o problema do ovo e da galinha de tentar se conectar ao banco de dados antes de criá-lo. No prompt do `kadmin`, use o `init` para criar o banco de dados inicial do realm:

[source,shell]
....
# kadmin -l
kadmin> init EXAMPLE.ORG
Realm max ticket life [unlimited]:
....

Por fim, enquanto ainda estiver no `kadmin`, crie o primeiro principal usando `add`. Atenha-se às opções padrão para o principal por enquanto, pois elas podem ser alteradas posteriormente com `modify`. Digite `?` no prompt para ver as opções disponíveis.

[source,shell]
....
kadmin> add tillman
Max ticket life [unlimited]:
Max renewable life [unlimited]:
Principal expiration time [never]:
Password expiration time [never]:
Attributes []:
Password: xxxxxxxx
Verifying password - Password: xxxxxxxx
....

Em seguida, inicie o serviço KDC executando:

[source,shell]
....
# service kdc start
# service kadmind start
....

Embora não tenha nenhum daemon do kerberos em execução neste ponto, é possível confirmar que o KDC está funcionando obtendo um ticket para o principal que acabou de ser criado:

[source,shell]
....
% kinit tillman
tillman@EXAMPLE.ORG's Password:
....

Confirme se um ticket foi obtido com sucesso usando `klist`:

[source,shell]
....
% klist
Credentials cache: FILE:/tmp/krb5cc_1001
	Principal: tillman@EXAMPLE.ORG

  Issued                Expires               Principal
Aug 27 15:37:58 2013  Aug 28 01:37:58 2013  krbtgt/EXAMPLE.ORG@EXAMPLE.ORG
....

O ticket temporário pode ser destruído quando o teste terminar:

[source,shell]
....
% kdestroy
....

=== Configurando um Servidor para Usar o Kerberos

A primeira etapa na configuração de um servidor para usar a autenticação Kerberos é garantir que ele tenha a configuração correta no arquivo [.filename]#/etc/krb5.conf#. A versão do KDC pode ser usada como está, ou pode ser regenerada no novo sistema.

Em seguida, crie o arquivo [.filename]#/etc/krb5.keytab# no servidor. Esta é a parte principal de "Kerberizar" um serviço - ele corresponde a gerar uma chave secreta compartilhada entre o serviço e o KDC. O segredo é uma chave criptográfica, armazenada em um "keytab". O keytab contém a chave do host do servidor, que permite que ele e o KDC verifiquem a identidade um do outro. Ele deve ser transmitido para o servidor de maneira segura, pois a segurança do servidor pode ser quebrada se a chave for tornada pública. Normalmente, o [.filename]#keytab# é gerado na máquina confiável de um administrador usando o `kadmin`, e então transferido com segurança para o servidor, por exemplo, com man:scp[1]; Ele também pode ser criado diretamente no servidor, se isso for consistente com a política de segurança desejada. É muito importante que o keytab seja transmitido para o servidor de forma segura: se a chave for conhecida por outra parte, essa parte pode representar qualquer usuário para o servidor! Usar o `kadmin` diretamente no servidor é conveniente, porque a entrada para o principal do host no banco de dados do KDC também é criada usando o `kadmin`.

Naturalmente, o `kadmin` é um serviço kerberizado; um tíquete Kerberos é necessário para autenticar-se no serviço de rede, mas para garantir que o usuário que está executando o `kadmin` esteja presente (e sua sessão não tenha sido invadida), o `kadmin` solicitará a senha para obter um novo ticket. O principal autenticando no serviço kadmin deve ter permissão para usar a interface `kadmin`, conforme especificado no arquivo [.filename]#/var/heimdal/kadmind.acl#. Veja a seção intitulada "Administração Remota" em `info heimdal` para detalhes sobre a criação de listas de controle de acesso. Em vez de ativar o acesso remoto ao `kadmin`, o administrador pode conectar-se com segurança ao KDC através do console local ou por man:ssh[] e executar a administração localmente usando o `kadmin -l`.

Depois de instalar o arquivo [.filename]#/etc/krb5.conf#, use o `add --random-key` no `kadmin`. Isso adiciona o principal do host do servidor ao banco de dados, mas não extrai uma cópia da chave principal do host para um keytab. Para gerar o keytab, use `ext` para extrair a chave principal do host do servidor para seu próprio keytab:

[source,shell]
....
# kadmin
kadmin> add --random-key host/myserver.example.org
Max ticket life [unlimited]:
Max renewable life [unlimited]:
Principal expiration time [never]:
Password expiration time [never]:
Attributes []:
kadmin> ext_keytab host/myserver.example.org
kadmin> exit
....

Note que o `ext_keytab` por padrão armazena a chave extraída no arquivo [.filename]#/etc/krb5.keytab#. Isso é bom quando executado no servidor que está sendo kerberizado, mas o argumento `--keytab _path/to/file_` deve ser usado quando o keytab estiver sendo extraído em outro lugar:

[source,shell]
....
# kadmin
kadmin> ext_keytab --keytab=/tmp/example.keytab host/myserver.example.org
kadmin> exit
....

O keytab pode então ser copiado com segurança para o servidor usando o man:scp[1] ou uma mídia removível. Certifique-se de especificar um nome de keytab não padrão para evitar a inserção de chaves desnecessárias na keytab do sistema.

Neste ponto, o servidor pode ler mensagens criptografadas do KDC usando sua chave compartilhada, armazenada no arquivo [.filename]#krb5.keytab#. Agora ele está pronto para ativar os serviços de uso do Kerberos. Um dos serviços mais comuns é o man:sshd[8], que suporta o Kerberos através do GSS-API. No arquivo [.filename]#/etc/ssh/sshd_config#, adicione a linha:

[.programlisting]
....
GSSAPIAuthentication yes
....

Depois de fazer essa alteração, o man:sshd[8] deve ser reiniciado para que a nova configuração tenha efeito: `service sshd restart`.

=== Configurando um cliente para usar o Kerberos

Assim como foi no servidor, o cliente requer configuração no arquivo [.filename]#/etc/krb5.conf#. Copie o arquivo no local (com segurança) ou insira-o novamente conforme necessário.

Teste o cliente usando o `kinit`, `klist` e `kdestroy` a partir do cliente para obter, mostrar e excluir um ticket para um principal existente. Os aplicativos Kerberos também devem poder se conectar a servidores habilitados pelo Kerberos. Se isso não funcionar, mas a obtenção de um ticket ocorrer, provavelmente o problema está no servidor e não no cliente ou no KDC. No caso do man:ssh[1] kerberizado, o GSS-API está desabilitado por padrão, portanto teste usando `ssh -o GSSAPIAuthentication=yes _hostname_`.

Ao testar um aplicativo Kerberizado, tente usar um sniffer de pacote, como o `tcpdump`, para confirmar que nenhuma informação confidencial é enviada sem proteção.

Várias aplicações Kerberos cliente estão disponíveis. Com o advento de uma ponte para que aplicações usando SASL para autenticação possam usar mecanismos GSS-API, grandes classes de aplicativos clientes podem usar o Kerberos para autenticação, de clientes Jabber a clientes IMAP.

Os usuários em um realm geralmente têm seu principal Kerberos mapeado para uma conta de usuário local. Ocasionalmente, é necessário conceder acesso a uma conta de usuário local a alguém que não tenha um principal Kerberos correspondente. Por exemplo, `tillman@EXAMPLE.ORG` pode precisar de acesso à conta de usuário local `webdevelopers`. Outros diretores também podem precisar de acesso a essa conta local.

Os arquivos [.filename]#.k5login# e [.filename]#.k5users#, colocados no diretório home de um usuário, podem ser usados para resolver este problema. Por exemplo, se o seguinte [.filename]#.k5login# for colocado no diretório inicial de `webdevelopers`, os dois principals listados terão acesso a essa conta sem exigir uma senha compartilhada:

[.programlisting]
....
tillman@example.org
jdoe@example.org
....

Consulte man:ksu[1] para obter maiores informações sobre o [.filename]#.k5users#.

=== Diferenças com a implementação do MIT

A principal diferença entre as implementações do MIT e a Heimdal é que o `kadmin` tem um conjunto de comandos diferente, mas equivalente, e usa um protocolo diferente. Se o KDC for MIT, a versão Heimdal do `kadmin` não poderá ser usada para administrar o KDC remotamente, e vice versa.

Aplicações cliente também podem usar opções de linha de comando ligeiramente diferentes para realizar as mesmas tarefas. Seguir as instruções em http://web.mit.edu/Kerberos/www/[http://web.mit.edu/Kerberos/www/] é recomendado. Cuidado com os problemas de caminho: o port MIT é instalado em [.filename]#/usr/local/# por padrão, e os aplicativos do sistema FreeBSD serão executados em vez das versões do MIT se o `PATH` listar os diretórios do sistema primeiro.

Ao usar o MIT Kerberos como um KDC no FreeBSD, as seguintes edições também devem ser feitas no [.filename]#rc.conf#:

[.programlisting]
....
kdc_program="/usr/local/sbin/kdc"
kadmind_program="/usr/local/sbin/kadmind"
kdc_flags=""
kdc_enable="YES"
kadmind_enable="YES"
....

=== Dicas, Truques e Solução de Problemas do Kerberos

Ao configurar e solucionar problemas do Kerberos, tenha em mente os seguintes pontos:

* Ao usar o Heimdal ou MITKerberos do ports, certifique-se de que o `PATH` liste as versões do port dos aplicativos clientes antes das versões do sistema.
* Se todos os computadores no realm não tiverem configurações de horário sincronizadas, a autenticação poderá falhar. crossref:network-servers[network-ntp,Sincronização de Relógio com NTP] descreve como sincronizar os relógios usando o NTP.
* Se o nome do host for alterado, o `host/` principal deve ser alterado e o keytab atualizado. Isso também se aplica a entradas de keytab especiais como o `HTTP/` principal usado para o package:www/mod_auth_kerb[] do Apache.
* Todos os hosts no realm devem ser resolvidos tanto de forma direta quanto reversa no DNS ou, no mínimo, no arquivo [.filename]#/etc/hosts#. Os CNAMEs funcionarão, mas os registros A e PTR devem estar corretos e no lugar. A mensagem de erro para hosts não resolvidos não é intuitiva: `Kerberos5 refuses authentication because Read req failed: Key table entry not found`.
* Alguns sistemas operacionais que agem como clientes para o KDC não definem as permissões para o `ksu` para serem setuid `root`. Isso significa que o `ksu` não funciona. Este é um problema de permissões, não um erro do KDC.
* Com o MITKerberos, para permitir que um principal tenha uma duração de ticket maior que a duração padrão de dez horas, use `modify_principal` no man:kadmin[8] para alterar o `maxlife` do principal em questão e do `krbtgt` principal. O principal pode então usar o `kinit -l` para solicitar um ticket com uma vida útil mais longa.
* Ao executar um sniffer de pacotes no KDC para auxiliar na solução de problemas enquanto executa `kinit` de uma estação de trabalho, o Ticket de Concessão de Tickets (TGT) é enviado imediatamente, mesmo antes da digitação da senha. Isso ocorre porque o servidor Kerberos transmite livremente um TGT para qualquer solicitação não autorizada. No entanto, cada TGT é criptografado em uma chave derivada da senha do usuário. Quando um usuário digita sua senha, ela não é enviada para o KDC, ela é usada para descriptografar o TGT que o `kinit` já obteve. Se o processo de descriptografia resultar em um tíquete válido com um registro de data e hora válido, o usuário terá credenciais do Kerberos válidas. Essas credenciais incluem uma chave de sessão para estabelecer comunicações seguras com o servidor Kerberos no futuro, bem como o TGT, que é criptografado com a chave do próprio servidor Kerberos. Essa segunda camada de criptografia permite que o servidor Kerberos verifique a autenticidade de cada TGT.
* Os principals do host podem ter uma vida útil maior do ticket. Se o usuário do principal tiver uma vida útil de uma semana, mas o host ao qual está conectado tiver uma vida útil de nove horas, o cache do usuário terá um host principal expirado e o cache do ticket não funcionará como esperado.
* Ao configurar o arquivo [.filename]#krb5.dict# para evitar que senhas incorretas específicas sejam usadas, conforme descrito em man:kadmind[8], lembre-que só se aplica a entidades que tenham uma política de senha atribuída a elas. O formato usado em [.filename]#krb5.dict# é uma string por linha. Criar um link simbólico para [.filename]#/usr/shared/dict/words# pode ser útil.

=== Atenuando as Limitações do Kerberos

Uma vez que com o Kerberos a abordagem é tudo ou nada, cada serviço habilitado na rede deve ser modificado para funcionar com o Kerberos ou ser protegido contra ataques de rede. Isso impede que as credenciais do usuário sejam roubadas e reutilizadas. Um exemplo é quando o Kerberos está habilitado em todos os shells remotos, mas o servidor de email POP3 não-Kerberizado envia senhas em texto simples.

O KDC é um ponto único de falha. Por design, o KDC deve ser tão seguro quanto seu banco de dados de senhas master. O KDC não deve ter absolutamente nenhum outro serviço sendo executado e deve estar fisicamente seguro. O perigo é alto porque o Kerberos armazena todas as senhas criptografadas com a mesma chave mestra que é armazenada como um arquivo no KDC.

Uma chave mestra comprometida não é tão ruim quanto se pode temer. A chave mestra é usada apenas para criptografar o banco de dados do Kerberos e como um seed para o gerador de números aleatórios. Desde que o acesso ao KDC seja seguro, um invasor não poderá fazer muito com a chave mestra.

Se o KDC não estiver disponível, os serviços de rede não poderão ser utilizados, pois a autenticação não poderá ser executada. Isso pode ser mitigado com um único KDC master e um ou mais slaves, e com a implementação cuidadosa da autenticação secundária ou de fallback usando PAM.

O Kerberos permite que usuários, hosts e serviços se autentiquem entre si. Ele não possui um mecanismo para autenticar o KDC para os usuários, hosts ou serviços. Isso significa que um `kinit` infectado por um trojan pode registrar todos os nomes de usuário e senhas. As ferramentas de verificação de integridade do sistema de arquivos, como package:security/tripwire[], podem mitigar isso.

=== Recursos e Outras Informações

* http://www.faqs.org/faqs/Kerberos-faq/general/preamble.html[A FAQ do Kerberos]
* http://web.mit.edu/Kerberos/www/dialogue.html[Criando um Sistema de Autenticação: um Diálogo em Quatro Cenas]
* https://www.ietf.org/rfc/rfc4120.txt[RFC 4120, O Serviço de Autenticação em Rede (V5) do Kerberos]
* http://web.mit.edu/Kerberos/www/[Página Web do Kerberos MIT]
* https://github.com/heimdal/heimdal/wiki[Página web do Heimdal Kerberos]

[[openssl]]
== OpenSSL

O OpenSSL é uma implementação de software livre dos protocolos SSL e TLS. Ele fornece uma camada de transporte de criptografia sobre a camada de comunicação normal, permitindo que ela seja entrelaçada com muitos aplicativos e serviços de rede.

A versão do OpenSSL incluída no FreeBSD suporta os protocolos de segurança de redes Secure Sockets Layer 3.0 (SSLv3) e Transport Layer Security 1.0/1.1/1.2 (TLSv1/TLSv1.1/TLSv1.2) e pode ser usado como uma biblioteca de criptografia geral. No FreeBSD 12.0-RELEASE e posterior, OpenSSL também suporta Transport Layer Security 1.3 (TLSv1.3).

O OpenSSL é muitas vezes usado para encriptar a autenticação de clientes de email e proteger transações baseadas na web como pagamentos com cartões de crédito. Alguns ports, como o package:www/apache24[] e package:databases/postgresql11-server[], incluem uma opção de compilação para inserir o OpenSSL. Se selecionado, o port vai adicionar suporte ao OpenSSL da base do sistema. Para ter o port compilado com o suporte do OpenSSL do port package:security/openssl[], adicione o seguinte ao arquivo [.filename]#/etc/make.conf#:

[.programlisting]
....
DEFAULT_VERSIONS+= ssl=openssl
....

Outro uso comum do OpenSSL é fornecer certificados para uso com aplicaçõe de software. Os certificados podem ser usados para verificar as credenciais de uma empresa ou indivíduo. Se um certificado não tiver sido assinado por uma _Autoridade de Certificação_ externa ( CA ), como http://www.verisign.com[http://www.verisign.com], o aplicativo que usa o certificado produzirá um aviso. Há um custo associado à obtenção de um certificado assinado e o uso de um certificado assinado não é obrigatório, pois os certificados podem ser auto-assinados. No entanto, o uso de uma autoridade externa evitará avisos e poderá deixar os usuários mais à vontade.

Esta seção demonstra como criar e usar certificados em um sistema FreeBSD. Consulte crossref:network-servers[ldap-config,Configurando um servidor LDAP] para um exemplo de como criar uma CA para assinar seus próprios certificados.

Para obter maiores informações sobre o SSL, leia o https://www.feistyduck.com/books/openssl-cookbook/[OpenSSL Cookbook ] gratuito.

=== Gerando Certificados

Para gerar um certificado que será assinado por uma CA externa, emita o seguinte comando e insira as informações solicitadas nos prompts. Esta informação de entrada será gravada no certificado. No prompt `Common Name`, insira o nome completo para o sistema que usará o certificado. Se esse nome não corresponder ao servidor, a aplicação que estiver verificando o certificado emitirá um aviso para o usuário, tornando a verificação provida pelo certificado inútil.

[source,shell]
....
# openssl req -new -nodes -out req.pem -keyout cert.key -sha256 -newkey rsa:2048
Generating a 2048 bit RSA private key
..................+++
.............................................................+++
writing new private key to 'cert.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:PA
Locality Name (eg, city) []:Pittsburgh
Organization Name (eg, company) [Internet Widgits Pty Ltd]:My Company
Organizational Unit Name (eg, section) []:Systems Administrator
Common Name (eg, YOUR name) []:localhost.example.org
Email Address []:trhodes@FreeBSD.org

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:Another Name
....

Outras opções, como o tempo de expiração e algoritmos de criptografia alternativos, estão disponíveis ao criar um certificado. Uma lista completa de opções é descrita em man:openssl[1].

Este comando irá criar dois arquivos no diretório atual. A solicitação de certificado, [.filename]#req.pem#, pode ser enviada para uma CA que validará as credenciais inseridas, assinará a solicitação e retornará o certificado assinado. O segundo arquivo, [.filename]#cert.key#, é a chave privada do certificado e deve ser armazenado em um local seguro. Se ele cair nas mãos de outros, ele pode ser usado para representar o usuário ou o servidor.

Como alternativa, se uma assinatura de uma CA não for necessária, um certificado auto-assinado poderá ser criado. Primeiro, gere a chave RSA:

[source,shell]
....
# openssl genrsa -rand -genkey -out cert.key 2048
0 semi-random bytes loaded
Generating RSA private key, 2048 bit long modulus
.............................................+++
.................................................................................................................+++
e is 65537 (0x10001)
....

Use essa chave para criar um certificado auto-assinado. Siga os prompts usuais para criar um certificado:

[source,shell]
....
# openssl req -new -x509 -days 365 -key cert.key -out cert.crt -sha256
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:PA
Locality Name (eg, city) []:Pittsburgh
Organization Name (eg, company) [Internet Widgits Pty Ltd]:My Company
Organizational Unit Name (eg, section) []:Systems Administrator
Common Name (e.g. server FQDN or YOUR name) []:localhost.example.org
Email Address []:trhodes@FreeBSD.org
....

Isso criará dois novos arquivos no diretório atual: um arquivo de chave privada [.filename]#cert.key# e o próprio certificado, [.filename]#cert.crt#. Estes devem ser colocados em um diretório, preferencialmente sob [.filename]#/etc/ssl/#, que é legível somente pelo `root`. As permissões de `0700` são apropriadas para esses arquivos e podem ser definidas usando o `chmod`.

=== Usando Certificados

Um uso para um certificado é criptografar conexões do servidor de email Sendmail para evitar o trafego de informações de autenticação em texto não criptografado.

[NOTE]
====
Alguns clientes de email exibirão um erro se o usuário não tiver instalado uma cópia local do certificado. Consulte a documentação incluída com o software para obter maiores informações sobre a instalação do certificado.
====

No FreeBSD 10.0-RELEASE e posterior, é possível criar um certificado auto-assinado para o Sendmail automaticamente. Para habilitar isso, adicione as seguintes linhas ao arquivo [.filename]#/etc/rc.conf#:

[.programlisting]
....
sendmail_enable="YES"
sendmail_cert_create="YES"
sendmail_cert_cn="localhost.example.org"
....

Isso criará automaticamente um certificado auto-assinado, [.filename]#/etc/mail/certs/host.cert#, uma chave de assinatura, [.filename]#/etc/mail/certs/host.key#, e um certificado CA, [.filename]#/etc/mail/certs/cacert.pem#. O certificado usará o `Common Name` especificado em `sendmail_cert_cn`. Depois de salvar as edições, reinicie o Sendmail:

[source,shell]
....

# service sendmail restart
....

Se tudo correr bem, não haverá mensagens de erro no arquivo [.filename]#/var/log/maillog#. Para um teste simples, conecte-se à porta de escuta do servidor de correio usando o `telnet`:

[source,shell]
....
# telnet example.com 25
Trying 192.0.34.166...
Connected to example.com.
Escape character is '^]'.
220 example.com ESMTP Sendmail 8.14.7/8.14.7; Fri, 18 Apr 2014 11:50:32 -0400 (EDT)
ehlo example.com
250-example.com Hello example.com [192.0.34.166], pleased to meet you
250-ENHANCEDSTATUSCODES
250-PIPELINING
250-8BITMIME
250-SIZE
250-DSN
250-ETRN
250-AUTH LOGIN PLAIN
250-STARTTLS
250-DELIVERBY
250 HELP
quit
221 2.0.0 example.com closing connection
Connection closed by foreign host.
....

Se a linha `STARTTLS` aparecer na saída, tudo está funcionando corretamente.

[[ipsec]]
== VPN Sobre IPsec

O Protocolo de Segurança da Internet (IPsec) é um conjunto de protocolos que se situam no topo da camada do Protocolo da Internet (IP). Ele permite que dois ou mais hosts se comuniquem de maneira segura, autenticando e criptografando cada pacote IP de uma sessão de comunicação. A pilha de rede IPsec do FreeBSD é baseada na implementação do http://www.kame.net/[http://www.kame.net/] e suporta as sessões IPv4 e IPv6.

O IPsec é composto pelos seguintes sub-protocolos:

* _Encapsulated Securtity Payload (ESP)_: este protocolo protege os dados do pacote IP da interferência de terceiros, criptografando o conteúdo usando algoritmos de criptografia simétricos, como Blowfish e 3DES.
* _Authentication Header (AH) _: este protocolo protege o cabeçalho do pacote IP da interferência e spoofing de terceiros calculando um checksum criptográfico e gerando o hash dos campos de cabeçalho do pacote IP com uma função de hash segura. Isso é seguido por um cabeçalho adicional que contém o hash, para permitir que as informações no pacote sejam autenticadas.
* _IP Payload Compression Protocol (IPComp):_ este protocolo tenta aumentar o desempenho da comunicação comprimindo o payload IP para reduzir a quantidade de dados enviados .

Esses protocolos podem ser usados juntos ou separadamente, dependendo do ambiente.

O IPsec suporta dois modos de operação. O primeiro modo, _Modo de Transporte_, protege as comunicações entre dois hosts. O segundo modo, _Modo de túnel_, é usado para construir túneis virtuais, comumente conhecidos como redes privadas virtuais (VPNs). Consulte man:ipsec[4] para obter informações detalhadas sobre o subsistema IPsec no FreeBSD.

O suporte a IPsec é ativado por padrão no FreeBSD 11 e posteriores. Para versões anteriores do FreeBSD, adicione estas opções a um arquivo de configuração de kernel personalizado e recompile o kernel usando as instruções em crossref:kernelconfig[kernelconfig, Configurando o kernel do FreeBSD]:

[source,shell]
....
options   IPSEC        IP security
device    crypto
....

Se o suporte a depuração do IPsec for desejado, a seguinte opção de kernel também deve ser adicionada:

[source,shell]
....
options   IPSEC_DEBUG  debug for IP security
....

Este restante deste capítulo demonstra o processo de configuração de uma VPNIPsec entre uma rede doméstica e uma rede corporativa. No cenário de exemplo:

* Ambos os sites estão conectados à Internet através de um gateway que está executando o FreeBSD.
* O gateway em cada rede tem pelo menos um endereço IP externo. Neste exemplo, o endereço IP externo da LAN corporativa é `172.16.5.4` e o IP externo da LAN doméstica é `192.168.1.12`.
* Os endereços internos das duas redes podem ser endereços IP públicos ou privados. No entanto, o espaço de endereço não deve colidir. Por exemplo, ambas as redes não podem usar `192.168.1.x`. Neste exemplo, o endereço IP interno da LAN corporativa é `10.246.38.1` e o endereço do IP interno da LAN doméstica é `10.0.0.5`.

=== Configurando uma VPN no FreeBSD

Para começar, o package:security/ipsec-tools[] deve ser instalado a partir da Coleção de Ports. Este software fornece várias aplicações que suportam a configuração.

O próximo requisito é criar dois pseudo-dispositivos man:gif[4] que serão usados para encapsular pacotes e permitir que ambas as redes se comuniquem adequadamente. Como `root`, execute os seguintes comandos, substituindo _internal_ e _external_ pelos endereços IP reais das interfaces internas e externas dos dois gateways:

[source,shell]
....
# ifconfig gif0 create
# ifconfig gif0 internal1 internal2
# ifconfig gif0 tunnel external1 external2
....

Verifique a configuração em cada gateway, usando o `ifconfig`. Aqui está a saída do Gateway 1:

[.programlisting]
....
gif0: flags=8051 mtu 1280
tunnel inet 172.16.5.4 --> 192.168.1.12
inet6 fe80::2e0:81ff:fe02:5881%gif0 prefixlen 64 scopeid 0x6
inet 10.246.38.1 --> 10.0.0.5 netmask 0xffffff00
....

Aqui está a saída do Gateway 2:

[.programlisting]
....
gif0: flags=8051 mtu 1280
tunnel inet 192.168.1.12 --> 172.16.5.4
inet 10.0.0.5 --> 10.246.38.1 netmask 0xffffff00
inet6 fe80::250:bfff:fe3a:c1f%gif0 prefixlen 64 scopeid 0x4
....

Depois de concluídos, os dois endereços de IP internos devem ser acessados usando man:ping[8]:

[source,shell]
....
priv-net# ping 10.0.0.5
PING 10.0.0.5 (10.0.0.5): 56 data bytes
64 bytes from 10.0.0.5: icmp_seq=0 ttl=64 time=42.786 ms
64 bytes from 10.0.0.5: icmp_seq=1 ttl=64 time=19.255 ms
64 bytes from 10.0.0.5: icmp_seq=2 ttl=64 time=20.440 ms
64 bytes from 10.0.0.5: icmp_seq=3 ttl=64 time=21.036 ms
--- 10.0.0.5 ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max/stddev = 19.255/25.879/42.786/9.782 ms
....

[source,shell]
....
corp-net# ping 10.246.38.1
PING 10.246.38.1 (10.246.38.1): 56 data bytes
64 bytes from 10.246.38.1: icmp_seq=0 ttl=64 time=28.106 ms
64 bytes from 10.246.38.1: icmp_seq=1 ttl=64 time=42.917 ms
64 bytes from 10.246.38.1: icmp_seq=2 ttl=64 time=127.525 ms
64 bytes from 10.246.38.1: icmp_seq=3 ttl=64 time=119.896 ms
64 bytes from 10.246.38.1: icmp_seq=4 ttl=64 time=154.524 ms
--- 10.246.38.1 ping statistics ---
5 packets transmitted, 5 packets received, 0% packet loss
round-trip min/avg/max/stddev = 28.106/94.594/154.524/49.814 ms
....

Como esperado, ambos os lados têm a capacidade de enviar e receber pacotes ICMP dos endereços configurados de forma privada. Em seguida, os dois gateways devem ser informados sobre como rotear pacotes para enviar corretamente o tráfego de qualquer rede. Os seguintes comandos atingirão esse objetivo:

[source,shell]
....
corp-net# route add 10.0.0.0 10.0.0.5 255.255.255.0
corp-net# route add net 10.0.0.0: gateway 10.0.0.5
priv-net# route add 10.246.38.0 10.246.38.1 255.255.255.0
priv-net# route add host 10.246.38.0: gateway 10.246.38.1
....

Neste ponto, as máquinas internas devem ser alcançadas de cada gateway, bem como das máquinas atrás dos gateways. Novamente, use o man:ping[8] para confirmar:

[.programlisting]
....
corp-net# ping 10.0.0.8
PING 10.0.0.8 (10.0.0.8): 56 data bytes
64 bytes from 10.0.0.8: icmp_seq=0 ttl=63 time=92.391 ms
64 bytes from 10.0.0.8: icmp_seq=1 ttl=63 time=21.870 ms
64 bytes from 10.0.0.8: icmp_seq=2 ttl=63 time=198.022 ms
64 bytes from 10.0.0.8: icmp_seq=3 ttl=63 time=22.241 ms
64 bytes from 10.0.0.8: icmp_seq=4 ttl=63 time=174.705 ms
--- 10.0.0.8 ping statistics ---
5 packets transmitted, 5 packets received, 0% packet loss
round-trip min/avg/max/stddev = 21.870/101.846/198.022/74.001 ms

priv-net# ping 10.246.38.107
PING 10.246.38.1 (10.246.38.107): 56 data bytes
64 bytes from 10.246.38.107: icmp_seq=0 ttl=64 time=53.491 ms
64 bytes from 10.246.38.107: icmp_seq=1 ttl=64 time=23.395 ms
64 bytes from 10.246.38.107: icmp_seq=2 ttl=64 time=23.865 ms
64 bytes from 10.246.38.107: icmp_seq=3 ttl=64 time=21.145 ms
64 bytes from 10.246.38.107: icmp_seq=4 ttl=64 time=36.708 ms
--- 10.246.38.107 ping statistics ---
5 packets transmitted, 5 packets received, 0% packet loss
round-trip min/avg/max/stddev = 21.145/31.721/53.491/12.179 ms
....

Configurar os túneis é a parte fácil. Configurar um link seguro é um processo mais aprofundado. A seguinte configuração usa chaves RSA pré-compartilhadas (PSK). Além dos endereços IP, o arquivo [.filename]#/usr/local/etc/racoon/racoon.conf# em ambos os gateways será idêntico e será semelhante a:

[.programlisting]
....
path    pre_shared_key  "/usr/local/etc/racoon/psk.txt"; #location of pre-shared key file
log     debug;	#log verbosity setting: set to 'notify' when testing and debugging is complete

padding	# options are not to be changed
{
        maximum_length  20;
        randomize       off;
        strict_check    off;
        exclusive_tail  off;
}

timer	# timing options. change as needed
{
        counter         5;
        interval        20 sec;
        persend         1;
#       natt_keepalive  15 sec;
        phase1          30 sec;
        phase2          15 sec;
}

listen	# address [port] that racoon will listen on
{
        isakmp          172.16.5.4 [500];
        isakmp_natt     172.16.5.4 [4500];
}

remote  192.168.1.12 [500]
{
        exchange_mode   main,aggressive;
        doi             ipsec_doi;
        situation       identity_only;
        my_identifier   address 172.16.5.4;
        peers_identifier        address 192.168.1.12;
        lifetime        time 8 hour;
        passive         off;
        proposal_check  obey;
#       nat_traversal   off;
        generate_policy off;

                        proposal {
                                encryption_algorithm    blowfish;
                                hash_algorithm          md5;
                                authentication_method   pre_shared_key;
                                lifetime time           30 sec;
                                dh_group                1;
                        }
}

sainfo  (address 10.246.38.0/24 any address 10.0.0.0/24 any)	# address $network/$netmask $type address $network/$netmask $type ( $type being any or esp)
{								# $network must be the two internal networks you are joining.
        pfs_group       1;
        lifetime        time    36000 sec;
        encryption_algorithm    blowfish,3des;
        authentication_algorithm        hmac_md5,hmac_sha1;
        compression_algorithm   deflate;
}
....

Para descrições de cada opção disponível, consulte a página de manual do [.filename]#racoon.conf#.

O Banco de Dados da Política de Segurança (SPD) precisa ser configurado para que o FreeBSD e o racoon consigam criptografar e descriptografar o tráfego de rede entre os hosts.

Isso pode ser obtido com um shell script, semelhante ao seguinte, no gateway corporativo. Este arquivo será usado durante a inicialização do sistema e deve ser salvo como [.filename]#/usr/local/etc/racoon/setkey.conf#.

[.programlisting]
....
flush;
spdflush;
# To the home network
spdadd 10.246.38.0/24 10.0.0.0/24 any -P out ipsec esp/tunnel/172.16.5.4-192.168.1.12/use;
spdadd 10.0.0.0/24 10.246.38.0/24 any -P in ipsec esp/tunnel/192.168.1.12-172.16.5.4/use;
....

Uma vez que o arquivo estiver no seu lugar, o racoon pode ser iniciado em ambos os gateways usando o seguinte comando:

[source,shell]
....
# /usr/local/sbin/racoon -F -f /usr/local/etc/racoon/racoon.conf -l /var/log/racoon.log
....

A saída deve ser semelhante à seguinte:

[source,shell]
....
corp-net# /usr/local/sbin/racoon -F -f /usr/local/etc/racoon/racoon.conf
Foreground mode.
2006-01-30 01:35:47: INFO: begin Identity Protection mode.
2006-01-30 01:35:48: INFO: received Vendor ID: KAME/racoon
2006-01-30 01:35:55: INFO: received Vendor ID: KAME/racoon
2006-01-30 01:36:04: INFO: ISAKMP-SA established 172.16.5.4[500]-192.168.1.12[500] spi:623b9b3bd2492452:7deab82d54ff704a
2006-01-30 01:36:05: INFO: initiate new phase 2 negotiation: 172.16.5.4[0]192.168.1.12[0]
2006-01-30 01:36:09: INFO: IPsec-SA established: ESP/Tunnel 192.168.1.12[0]->172.16.5.4[0] spi=28496098(0x1b2d0e2)
2006-01-30 01:36:09: INFO: IPsec-SA established: ESP/Tunnel 172.16.5.4[0]->192.168.1.12[0] spi=47784998(0x2d92426)
2006-01-30 01:36:13: INFO: respond new phase 2 negotiation: 172.16.5.4[0]192.168.1.12[0]
2006-01-30 01:36:18: INFO: IPsec-SA established: ESP/Tunnel 192.168.1.12[0]->172.16.5.4[0] spi=124397467(0x76a279b)
2006-01-30 01:36:18: INFO: IPsec-SA established: ESP/Tunnel 172.16.5.4[0]->192.168.1.12[0] spi=175852902(0xa7b4d66)
....

Para garantir que o túnel esteja funcionando corretamente, mude para outro console e use o man:tcpdump[1] para exibir o tráfego de rede usando o comando a seguir. Substitua `em0` pela placa de interface de rede conforme necessário:

[source,shell]
....
# tcpdump -i em0 host 172.16.5.4 and dst 192.168.1.12
....

Dados semelhantes aos seguintes devem aparecer no console. Caso contrário, há um problema e a depuração dos dados retornados será necessária.

[.programlisting]
....
01:47:32.021683 IP corporatenetwork.com > 192.168.1.12.privatenetwork.com: ESP(spi=0x02acbf9f,seq=0xa)
01:47:33.022442 IP corporatenetwork.com > 192.168.1.12.privatenetwork.com: ESP(spi=0x02acbf9f,seq=0xb)
01:47:34.024218 IP corporatenetwork.com > 192.168.1.12.privatenetwork.com: ESP(spi=0x02acbf9f,seq=0xc)
....

Neste ponto, as duas redes devem estar disponíveis e parecem fazer parte da mesma rede. Muito provavelmente ambas as redes estão protegidas por um firewall. Para permitir que o tráfego flua entre elas, regras precisam ser adicionadas para liberar a passagem dos pacotes. Para o firewall man:ipfw[8], adicione as seguintes linhas ao arquivo de configuração do firewall:

[.programlisting]
....
ipfw add 00201 allow log esp from any to any
ipfw add 00202 allow log ah from any to any
ipfw add 00203 allow log ipencap from any to any
ipfw add 00204 allow log udp from any 500 to any
....

[NOTE]
====
Os números das regras podem precisar ser alterados dependendo da configuração atual do host.
====

Para usuários do man:pf[4] ou do man:ipf[8] , as seguintes regras devem fazer o truque:

[.programlisting]
....
pass in quick proto esp from any to any
pass in quick proto ah from any to any
pass in quick proto ipencap from any to any
pass in quick proto udp from any port = 500 to any port = 500
pass in quick on gif0 from any to any
pass out quick proto esp from any to any
pass out quick proto ah from any to any
pass out quick proto ipencap from any to any
pass out quick proto udp from any port = 500 to any port = 500
pass out quick on gif0 from any to any
....

Finalmente, para permitir que a máquina inicie o suporte para a VPN durante a inicialização do sistema, adicione as seguintes linhas ao arquivo [.filename]#/etc/rc.conf#:

[.programlisting]
....
ipsec_enable="YES"
ipsec_program="/usr/local/sbin/setkey"
ipsec_file="/usr/local/etc/racoon/setkey.conf" # allows setting up spd policies on boot
racoon_enable="yes"
....

[[openssh]]
== OpenSSH

O OpenSSH é um conjunto de ferramentas de conectividade de rede usadas para fornecer acesso seguro a máquinas remotas. Além disso, as conexões TCP/IP podem ser encapsuladas ou encaminhadas com segurança através de conexões SSH. O OpenSSH criptografa todo o tráfego para eliminar efetivamente a interceptação, o sequestro de conexão e outros ataques no nível da rede.

O OpenSSH é mantido pelo projeto OpenBSD e é instalado por padrão no FreeBSD. É compatível com os protocolos de versão 1 e 2 do SSH.

Quando os dados são enviados pela rede em um formato não criptografado, sniffers de rede posicionados em qualquer lugar entre o cliente e o servidor podem roubar as informações do usuário/senha ou os dados transferidos durante a sessão. O OpenSSH oferece uma variedade de métodos de autenticação e criptografia para evitar que isso aconteça. Mais informações sobre o OpenSSH estão disponíveis em http://www.openssh.com/[http://www.openssh.com/].

Esta seção fornece uma visão geral dos utilitários embutidos de cliente para acessar com segurança outros sistemas e transferir arquivos com segurança de um sistema FreeBSD. Em seguida, descreve como configurar um servidor SSH em um sistema FreeBSD. Maiores informações estão disponíveis nas páginas man mencionadas neste capítulo.

=== Usando os Utilitários de Cliente SSH

Para logar em um servidor SSH, use `ssh` e especifique um nome de usuário que exista naquele servidor e o endereço IP ou nome de host do servidor. Se esta for a primeira vez que uma conexão foi feita ao servidor especificado, o usuário será solicitado a primeiro verificar a impressão digital do servidor:

[source,shell]
....
# ssh user@example.com
The authenticity of host 'example.com (10.0.0.1)' can't be established.
ECDSA key fingerprint is 25:cc:73:b5:b3:96:75:3d:56:19:49:d2:5c:1f:91:3b.
Are you sure you want to continue connecting (yes/no)? yes
Permanently added 'example.com' (ECDSA) to the list of known hosts.
Password for user@example.com: user_password
....

O SSH utiliza um sistema de impressão digital de chaves para verificar a autenticidade do servidor quando o cliente se conecta. Quando o usuário aceita a impressão digital da chave digitando `yes` ao conectar-se pela primeira vez, uma cópia da chave é salva em [.filename]#.ssh/known_hosts# no diretório pessoal do usuário. Futuras tentativas de login são verificadas em relação à chave salva e o `ssh` exibirá um alerta se a chave do servidor não corresponder à chave salva. Se isso ocorrer, o usuário deve primeiro verificar por que a chave foi alterada antes de continuar com a conexão.

Por padrão, versões recentes do OpenSSH aceitam apenas conexões SSH v2. Por padrão, o cliente usará a versão 2 se possível e voltará para a versão 1 se o servidor não suportar a versão 2. Para forçar o `ssh` a usar somente o protocolo especificado, inclua `-1` ou `-2`. Opções adicionais são descritas em man:ssh[1].

Use o man:scp[1] para copiar com segurança um arquivo para ou de uma máquina remota. Este exemplo copia o arquivo [.filename]#COPYRIGHT# do sistema remoto para um arquivo com o mesmo nome no diretório atual do sistema local:

[source,shell]
....
# scp user@example.com:/COPYRIGHT COPYRIGHT
Password for user@example.com: *******
COPYRIGHT            100% |*****************************|  4735
00:00
#
....

Como a impressão digital já foi verificada para esse host, a chave do servidor é verificada automaticamente antes de solicitar a senha do usuário.

Os argumentos passados para o `scp` são semelhantes ao comando `cp`. O arquivo ou arquivos para copiar é o primeiro argumento e o destino para copiar é o segundo. Como o arquivo é buscado pela rede, um ou mais dos argumentos do arquivo assumem o formato `user@host:<path_to_remote_file>`. Esteja ciente ao copiar recursivamente diretórios que o `scp` usa a opção `-r`, enquanto `cp` usa a `-R`.

Para abrir uma sessão interativa para copiar arquivos, use o `sftp`. Consulte man:sftp[1] para obter uma lista de comandos disponíveis enquanto estiver em uma sessão `sftp`.

[[security-ssh-keygen]]
==== Autenticação Baseada em Chave

Em vez de usar senhas, um cliente pode ser configurado para se conectar à máquina remota usando chaves. Para gerar chaves de autenticação RSA, use o `ssh-keygen`. Para gerar um par de chaves pública e privada, especifique o tipo de chave e siga os prompts. Recomenda-se proteger as chaves com uma senha memorável, mas difícil de se adivinhar.

[source,shell]
....
% ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/user/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):  <.>
Enter same passphrase again:                 <.>
Your identification has been saved in /home/user/.ssh/id_rsa.
Your public key has been saved in /home/user/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:54Xm9Uvtv6H4NOo6yjP/YCfODryvUU7yWHzMqeXwhq8 user@host.example.com
The key's randomart image is:
+---[RSA 2048]----+
|                 |
|                 |
|                 |
|        . o..    |
|       .S*+*o    |
|      . O=Oo . . |
|       = Oo= oo..|
|      .oB.* +.oo.|
|       =OE**.o..=|
+----[SHA256]-----+
....

<.> Digite uma senha aqui. Pode conter espaços e símbolos.
<.> Digite novamente a senha para verificá-la.

A chave privada é armazenada no arquivo [.filename]#~/.ssh/id_rsa# e a chave pública é armazenada no arquivo [.filename]#~/.ssh/id_rsa.pub#. A chave _publica_ deve ser copiada para [.filename]#~/.ssh/ authorized_keys# na máquina remota para que a autenticação baseada em chave funcione.

[WARNING]
====

Muitos usuários acreditam que as chaves são seguras por design e usarão uma chave sem uma senha. Este é um comportamento _perigoso_. Um administrador pode verificar se um par de chaves está protegido por uma senha, visualizando a chave privada manualmente. Se o arquivo de chave privada contiver a palavra `ENCRYPTED`, o dono da chave está usando uma senha. Além disso, para proteger melhor os usuários finais, o termo `from` pode ser colocado no arquivo de chave pública. Por exemplo, adicionar `from "192.168.10.5"` na frente do prefixo `ssh-rsa` só permitirá que esse usuário específico efetue login a partir desse endereço IP.
====

As opções e arquivos variam de acordo com as diferentes versões do OpenSSH. Para evitar problemas, consulte man:ssh-keygen[1].

Se uma senha for usada, o usuário será solicitado a inserir a senha toda vez que uma conexão for feita ao servidor. Para carregar as chaves de SSH na memória e remover a necessidade de digitar a senha toda vez, use o man:ssh-agent[1] e o man:ssh-add[1].

A autenticação é feita pelo `ssh-agent`, usando as chaves privadas que estão carregadas nele. O `ssh-agent` pode ser usado para iniciar outro aplicativo como um shell ou um gerenciador de janelas.

Para usar o `ssh-agent` em um shell, inicie-o com um shell como um argumento. Adicione a identidade executando `ssh-add` e inserindo a senha para a chave privada. O usuário então poderá executar o `ssh` para se conectar em qualquer host que tenha a chave pública correspondente instalada. Por exemplo:

[source,shell]
....
% ssh-agent csh
% ssh-add
Enter passphrase for key '/usr/home/user/.ssh/id_rsa':  <.>
Identity added: /usr/home/user/.ssh/id_rsa (/usr/home/user/.ssh/id_rsa)
%
....

<.> Digite a senha para a chave.

Para usar o `ssh-agent` no Xorg, adicione uma entrada para ele em [.filename]#~/.xinitrc#. Isso fornece os serviços do `ssh-agent` para todos os programas iniciados no Xorg. Um exemplo do arquivo [.filename]#~/.xinitrc# pode ter esta aparência:

[.programlisting]
....
exec ssh-agent startxfce4
....

Isso inicia o `ssh-agent`, que, por sua vez, ativa o XFCE, sempre que o Xorg é iniciado. Uma vez que o Xorg tenha sido reiniciado para que as mudanças entrem em vigor, execute `ssh-add` para carregar todas as chaves SSH.

[[security-ssh-tunneling]]
==== Tunelamento  SSH

O OpenSSH tem a capacidade de criar um tunel para encapsular outro protocolo em uma sessão criptografada.

O comando a seguir informa ao `ssh` para criar um túnel para o telnet:

[source,shell]
....
% ssh -2 -N -f -L 5023:localhost:23 user@foo.example.com
%
....

Este exemplo usa as seguintes opções:

`-2`::
Força o comando `ssh` a usar a versão 2 para conectar-se ao servidor.

`-N`::
Indica nenhum comando ou apenas túnel. Se omitido, o `ssh` inicia uma sessão normal.

`-f`::
Força o comando `ssh` a ser executado em segundo plano.

`-L`::
Indica um túnel local no formato _localport:remotehost:remoteport_.

`user@foo.example.com`::
O nome de login para usar no servidor SSH remoto especificado.

Um túnel SSH funciona criando um socket de escuta em `localhost` na `localport` especificada. Em seguida, ele encaminha quaisquer conexões recebidas em `localport` por meio da conexão SSH com o `remotehost:remoteport` especificado. No exemplo, a porta `5023` no cliente é encaminhada para a porta `23` na máquina remota. Como a porta 23 é usada pelo telnet, isso cria uma sessão telnet criptografada através de um túnel SSH.

Esse método pode ser usado para agrupar qualquer número de protocolos TCP inseguros, como SMTP, POP3 e FTP, como visto nos exemplos a seguir.

.Criar um Túnel Seguro para SMTP
[example]
====

[source,shell]
....
% ssh -2 -N -f -L 5025:localhost:25 user@mailserver.example.com
user@mailserver.example.com's password: *****
% telnet localhost 5025
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 mailserver.example.com ESMTP
....
Isso pode ser usado em conjunto com `ssh-keygen` e contas de usuário adicionais para criar um ambiente de encapsulamento SSH mais uniforme. As chaves podem ser usadas no lugar de digitar uma senha e os túneis podem ser executados como um usuário separado.
====

.Acesso Seguro de um Servidor POP3
[example]
====
Neste exemplo, há um servidor SSH que aceita conexões de fora. Na mesma rede, existe um servidor de email que executa um servidor POP3. Para verificar o e-mail de maneira segura, crie uma conexão SSH com o servidor SSH e encaminhe para o servidor de e-mail:

[source,shell]
....
% ssh -2 -N -f -L 2110:mail.example.com:110 user@ssh-server.example.com
user@ssh-server.example.com's password: ******
....

Quando o túnel estiver ativo e em execução, aponte o cliente de e-mail para enviar solicitações POP3 para `localhost` na porta 2110. Essa conexão será encaminhada com segurança pelo encapsulamento para `mail.example.com`.
====

.Ignorando um Firewall
[example]
====
Alguns firewalls filtram as conexões de entrada e saída. Por exemplo, um firewall pode limitar o acesso de máquinas remotas às portas 22 e 80 para permitir apenas o SSH e navegação na web. Isso impede o acesso a qualquer outro serviço que use uma porta diferente de 22 ou 80.

A solução é criar uma conexão SSH com uma máquina fora do firewall da rede e usá-la para encapsular o serviço desejado:

[source,shell]
....
% ssh -2 -N -f -L 8888:music.example.com:8000 user@unfirewalled-system.example.org
user@unfirewalled-system.example.org's password: *******
....

Neste exemplo, um cliente Ogg Vorbis de streaming pode agora ser apontado para `localhost` na porta 8888, que será encaminhado para `music.example.com` na porta 8000, ignorando com êxito o firewall.
====

=== Ativando o Servidor SSH

Além de fornecer utilitários de cliente SSH embutidos, um sistema FreeBSD pode ser configurado como um servidor SSH, aceitando conexões de outros clientes SSH.

Para ver se o sshd está operando, use o comando man:service[8]:

[source,shell]
....
# service sshd status
....

Se o serviço não estiver em execução, adicione a seguinte linha ao arquivo [.filename]#/etc/rc.conf#.

[.programlisting]
....
sshd_enable="YES"
....

Isso iniciará o sshd, o programa daemon para o OpenSSH, na próxima vez que o sistema for inicializado. Para iniciá-lo agora:

[source,shell]
....
# service sshd start
....

A primeira vez que o sshd inicia em um sistema FreeBSD, as chaves de host do sistema serão criadas automaticamente e a impressão digital será exibida no console. Forneça aos usuários a impressão digital para que eles possam verificá-la na primeira vez que se conectarem ao servidor.

Consulte o man:sshd[8] para obter a lista de opções disponíveis ao iniciar o sshd e uma discussão mais completa sobre autenticação, processo de login e os vários arquivos de configuração.

Neste ponto, o sshd deve estar disponível para todos os usuários com um nome de usuário e senha no sistema.

=== Segurança do Servidor SSH

Enquanto o sshd é o recurso de administração remota mais usado para o FreeBSD, a força bruta e o drive por ataques são comuns a qualquer sistema exposto a redes públicas. Vários parâmetros adicionais estão disponíveis para evitar o sucesso desses ataques e serão descritos nesta seção.

É uma boa ideia limitar quais usuários podem efetuar login no servidor SSH e de onde usar a palavra-chave `AllowUsers` no arquivo de configuração do servidor OpenSSH. Por exemplo, para permitir que somente o `root` efetue login de `192.168.1.32`, inclua esta linha no arquivo [.filename]#/etc/ssh/sshd_config#:

[.programlisting]
....
AllowUsers root@192.168.1.32
....

Para permitir que o usuário `admin` efetue login de qualquer lugar, liste esse usuário sem especificar um endereço IP:

[.programlisting]
....
AllowUsers admin
....

Multiplos usuários devem ser listados na mesma linha, assim:

[.programlisting]
....
AllowUsers root@192.168.1.32 admin
....

Depois de fazer alterações no arquivo [.filename]#/etc/ssh/sshd_config#, informe o sshd para recarregar seu arquivo de configuração executando:

[source,shell]
....
# service sshd reload
....

[NOTE]
====
Quando essa palavra-chave é usada, é importante listar cada usuário que precisa efetuar login nesta máquina. Qualquer usuário que não esteja especificado nessa linha será bloqueado. Além disso, as palavras-chave usadas no arquivo de configuração do servidor OpenSSH fazem distinção entre maiúsculas e minúsculas. Se a palavra-chave não estiver escrita corretamente, incluindo esse detalhe, ela será ignorada. Sempre teste as alterações neste arquivo para garantir que as edições estejam funcionando conforme o esperado. Consulte o man:sshd_config[5] para verificar a ortografia e o uso das palavras-chave disponíveis.
====

Além disso, os usuários podem ser forçados a usar a autenticação de dois fatores por meio do uso de uma chave pública e privada. Quando necessário, o usuário pode gerar um par de chaves usando o man:ssh-keygen[1] e enviar ao administrador a chave pública. Este arquivo de chave será colocado no arquivo [.filename]#authorized_keys# como descrito acima na seção cliente. Para forçar os usuários a usar apenas as chaves, a seguinte opção pode ser configurada:

[.programlisting]
....
AuthenticationMethods publickey
....

[TIP]
====

Não confunda o arquivo [.filename]#/etc/ssh/sshd_config# com [.filename]#/etc/ssh/ssh_config# (observe o `d` extra no primeiro nome do arquivo). O primeiro arquivo configura o servidor e o segundo arquivo configura o cliente. Consulte o man:ssh_config[5] para obter uma listagem das configurações do cliente disponíveis.
====

[[fs-acl]]
== Listas de Controle de Acesso

As Listas de Controle de Acesso (ACLs) estendem o modelo de permissão padrão do UNIX(TM) em um compatível com o modo POSIX(TM).1e. Isso permite que um administrador aproveite um modelo de permissões mais refinado.

O kernel FreeBSD [.filename]#GENERIC# fornece suporte a ACL para sistemas de arquivos UFS. Usuários que preferem compilar um kernel personalizado devem incluir a seguinte opção em seu arquivo de configuração do kernel personalizado:

[.programlisting]
....
options UFS_ACL
....

Se esta opção não for ativada na compilação, uma mensagem de aviso será exibida ao tentar montar um sistema de arquivos com o suporte a ACL. As ACLs dependem de atributos estendidos que são suportados nativamente pelo UFS2.

Este capítulo descreve como ativar o suporte a ACL e fornece alguns exemplos de uso.

=== Ativando o Suporte a ACL

As ACLs são habilitadas pela flag administrativa de tempo de montagem, `acls`, que podem ser adicionadas ao arquivo [.filename]#/etc/fstab#. As flags de tempo de montagem também podem ser configuradas automaticamente de forma persistente usando-se o man:tunefs[8] para modificar um superbloco de flags ACLs no cabeçalho do sistema de arquivos. Em geral, é preferível usar flags de superbloco por vários motivos:

* A flag de superbloco não pode ser alterada por um remount usando `mount -u`, pois requer um `umount` completo e um `mount` completo. Isso significa que as ACLs não podem ser ativadas no sistema de arquivos raiz após a inicialização. Isso também significa que o suporte a ACL em um sistema de arquivos não pode ser alterado enquanto o sistema estiver em uso.
* Definir a flag de superbloco faz com que o sistema de arquivos seja sempre montado com a ACL ativada, mesmo que não haja uma entrada no [.filename]#fstab# ou se os dispositivos forem reordenados. Isso evita a montagem acidental do sistema de arquivos sem o suporte a ACL.

[NOTE]
====
É desejável desencorajar a montagem acidental sem que a ACL esteja habilitada porque coisas desagradáveis podem acontecer se ACLs estiverem habilitadas, e então desabilitadas e então reativadas sem limpar os atributos estendidos. Em geral, uma vez que as ACLs forem habilitadas em um sistema de arquivos, elas não devem ser desabilitadas, pois as proteções de arquivos resultantes podem não ser compatíveis com aquelas pretendidas pelos usuários do sistema e ACLs reativadas podem reconectar as ACLs anteriores aos arquivos que tiveram suas permissões alteradas, resultando em um comportamento imprevisível.
====

Os sistemas de arquivos com a ACL ativada exibirão um sinal de mais (`+`) nas configurações de permissão:

[.programlisting]
....
drwx------  2 robert  robert  512 Dec 27 11:54 private
drwxrwx---+ 2 robert  robert  512 Dec 23 10:57 directory1
drwxrwx---+ 2 robert  robert  512 Dec 22 10:20 directory2
drwxrwx---+ 2 robert  robert  512 Dec 27 11:57 directory3
drwxr-xr-x  2 robert  robert  512 Nov 10 11:54 public_html
....

Neste exemplo, o [.filename]#directory1#, [.filename]#directory2# e [.filename]#directory3# estão todos fazendo uso de ACLs, enquanto [.filename]#public_html# não está.

=== Usando ACLs

As ACLs de um sistema de arquivos podem ser visualizadas usando `getfacl`. Por exemplo, para visualizar as configurações de ACL no arquivo [.filename]#test#:

[source,shell]
....
% getfacl test
	#file:test
	#owner:1001
	#group:1001
	user::rw-
	group::r--
	other::r--
....

Para alterar as configurações de ACL neste arquivo, use `setfacl`. Para remover todos os ACLs atualmente definidos de um arquivo ou sistema de arquivos, inclua `-k`. No entanto, o método preferido é usar `-b`, pois ela deixa os campos básicos necessários para que as ACLs funcionem.

[source,shell]
....
% setfacl -k test
....

Para modificar as entradas padrões das ACLs, use `-m`:

[source,shell]
....
% setfacl -m u:trhodes:rwx,group:web:r--,o::--- test
....

Neste exemplo, não havia entradas predefinidas, pois elas foram removidas pelo comando anterior. Este comando restaura as opções padrões e atribui as opções listadas. Se um usuário ou grupo for adicionado e não existir no sistema, um erro de `Invalid argument` será exibido.

Consulte man:getfacl[1] e man:setfacl[1] para maiores informações sobre as opções disponíveis para esses comandos.

[[security-pkg]]
== Monitorando Problemas de Segurança de Terceiros

Nos últimos anos, o mundo da segurança fez muitas melhorias em como a avaliação de vulnerabilidades é tratada. A ameaça de invasão do sistema aumenta à medida que utilitários de terceiros são instalados e configurados para praticamente qualquer sistema operacional disponível atualmente.

A avaliação de vulnerabilidade é um fator importante na segurança. Enquanto o FreeBSD libera avisos para o sistema base, fazê-lo para cada utilitário de terceiros está além da capacidade do Projeto FreeBSD. Existe uma maneira de mitigar vulnerabilidades de terceiros e avisar os administradores sobre problemas de segurança conhecidos. Um utilitário do FreeBSD conhecido como pkg inclui opções explicitamente para este propósito.

O pkg pesquisa um banco de dados em busca de problemas de segurança. O banco de dados é atualizado e mantido pela equipe de segurança do FreeBSD e pelos desenvolvedores de ports.

Por favor, consulte as crossref:ports[pkgng-intro,instruções] para instalar o pkg.

A instalação fornece arquivos de configuração do man:periodic[8] para manter o banco de dados de auditoria do pkg e fornece um método programático para mantê-lo atualizado . Esta funcionalidade é ativada se `daily_status_security_pkgaudit_enable` estiver definido como `YES` em man:periodic.conf[5] . Certifique-se de que os e-mails de execução de segurança diários, que são enviados para a conta de e-mail do `root`, estejam sendo lidos.

Após a instalação e para auditar utilitários de terceiros como parte da Coleção de Ports a qualquer momento, um administrador pode optar por atualizar o banco de dados e visualizar as vulnerabilidades conhecidas dos pacotes instalados, invocando:

[source,shell]
....
# pkg audit -F
....

O pkg exibe as vulnerabilidades publicadas dos pacotes instalados:

[.programlisting]
....
Affected package: cups-base-1.1.22.0_1
Type of problem: cups-base -- HPGL buffer overflow vulnerability.
Reference: <https://www.FreeBSD.org/ports/portaudit/40a3bca2-6809-11d9-a9e7-0001020eed82.html>

1 problem(s) in your installed packages found.

You are advised to update or deinstall the affected package(s) immediately.
....

Ao apontar um navegador da web para a URL exibida, um administrador pode obter mais informações sobre a vulnerabilidade. Isto incluirá as versões afetadas, pela versão do port do FreeBSD, juntamente com outros sites que podem conter avisos de segurança.

O pkg é um poderoso utilitário e é extremamente útil quando acoplado com o package:ports-mgmt/portmaster[].

[[security-advisories]]
== Avisos de Segurança do FreeBSD

Como muitos produtores de sistemas operacionais de qualidade, o Projeto FreeBSD tem uma equipe de segurança responsável por determinar a data de fim de vida (EoL) para cada versão do FreeBSD e para fornecer atualizações de segurança para versões suportadas que ainda não atingiram sua EoL. Mais informações sobre a equipe de segurança do FreeBSD e as versões suportadas estão disponíveis na https://www.FreeBSD.org/security[página de segurança do FreeBSD].

Uma tarefa da equipe de segurança é responder às vulnerabilidades de segurança reportadas no sistema operacional FreeBSD. Quando uma vulnerabilidade é confirmada, a equipe de segurança verifica as etapas necessárias para corrigir a vulnerabilidade e atualiza o código-fonte com a correção. Em seguida, publica os detalhes como um "Aviso de Segurança". Os avisos de segurança são publicados no https://www.FreeBSD.org/security/advisories/[site do FreeBSD] e enviados para as listas de discussão http://lists.FreeBSD.org/mailman/listinfo/freebsd-security-notifications[freebsd-security-notifications], http://lists.FreeBSD.org/mailman/listinfo/freebsd-security[freebsd-security], e http://lists.FreeBSD.org/mailman/listinfo/freebsd-announce[freebsd-announce].

Esta seção descreve o formato de um alerta de segurança do FreeBSD.

=== Formato de um Comunicado de Segurança

Aqui está um exemplo de um aviso de segurança do FreeBSD:

[.programlisting]
....
=============================================================================
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

=============================================================================
FreeBSD-SA-14:04.bind                                       Security Advisory
                                                          The FreeBSD Project

Topic:          BIND remote denial of service vulnerability

Category:       contrib
Module:         bind
Announced:      2014-01-14
Credits:        ISC
Affects:        FreeBSD 8.x and FreeBSD 9.x
Corrected:      2014-01-14 19:38:37 UTC (stable/9, 9.2-STABLE)
                2014-01-14 19:42:28 UTC (releng/9.2, 9.2-RELEASE-p3)
                2014-01-14 19:42:28 UTC (releng/9.1, 9.1-RELEASE-p10)
                2014-01-14 19:38:37 UTC (stable/8, 8.4-STABLE)
                2014-01-14 19:42:28 UTC (releng/8.4, 8.4-RELEASE-p7)
                2014-01-14 19:42:28 UTC (releng/8.3, 8.3-RELEASE-p14)
CVE Name:       CVE-2014-0591

For general information regarding FreeBSD Security Advisories,
including descriptions of the fields above, security branches, and the
following sections, please visit <URL:http://security.FreeBSD.org/>.

I.   Background

BIND 9 is an implementation of the Domain Name System (DNS) protocols.
The named(8) daemon is an Internet Domain Name Server.

II.  Problem Description

Because of a defect in handling queries for NSEC3-signed zones, BIND can
crash with an "INSIST" failure in name.c when processing queries possessing
certain properties.  This issue only affects authoritative nameservers with
at least one NSEC3-signed zone.  Recursive-only servers are not at risk.

III. Impact

An attacker who can send a specially crafted query could cause named(8)
to crash, resulting in a denial of service.

IV.  Workaround

No workaround is available, but systems not running authoritative DNS service
with at least one NSEC3-signed zone using named(8) are not vulnerable.

V.   Solution

Perform one of the following:

1) Upgrade your vulnerable system to a supported FreeBSD stable or
release / security branch (releng) dated after the correction date.

2) To update your vulnerable system via a source code patch:

The following patches have been verified to apply to the applicable
FreeBSD release branches.

a) Download the relevant patch from the location below, and verify the
detached PGP signature using your PGP utility.

[FreeBSD 8.3, 8.4, 9.1, 9.2-RELEASE and 8.4-STABLE]
# fetch http://security.FreeBSD.org/patches/SA-14:04/bind-release.patch
# fetch http://security.FreeBSD.org/patches/SA-14:04/bind-release.patch.asc
# gpg --verify bind-release.patch.asc

[FreeBSD 9.2-STABLE]
# fetch http://security.FreeBSD.org/patches/SA-14:04/bind-stable-9.patch
# fetch http://security.FreeBSD.org/patches/SA-14:04/bind-stable-9.patch.asc
# gpg --verify bind-stable-9.patch.asc

b) Execute the following commands as root:

# cd /usr/src
# patch < /path/to/patch

Recompile the operating system using buildworld and installworld as
described in <URL:https://www.FreeBSD.org/handbook/makeworld.html>.

Restart the applicable daemons, or reboot the system.

3) To update your vulnerable system via a binary patch:

Systems running a RELEASE version of FreeBSD on the i386 or amd64
platforms can be updated via the freebsd-update(8) utility:

# freebsd-update fetch
# freebsd-update install

VI.  Correction details

The following list contains the correction revision numbers for each
affected branch.

Branch/path                                                      Revision
- -------------------------------------------------------------------------
stable/8/                                                         r260646
releng/8.3/                                                       r260647
releng/8.4/                                                       r260647
stable/9/                                                         r260646
releng/9.1/                                                       r260647
releng/9.2/                                                       r260647
- -------------------------------------------------------------------------

To see which files were modified by a particular revision, run the
following command, replacing NNNNNN with the revision number, on a
machine with Subversion installed:

# svn diff -cNNNNNN --summarize svn://svn.freebsd.org/base

Or visit the following URL, replacing NNNNNN with the revision number:

<URL:https://svnweb.freebsd.org/base?view=revision&revision=NNNNNN>

VII. References

<URL:https://kb.isc.org/article/AA-01078>

<URL:http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-0591>

The latest revision of this advisory is available at
<URL:http://security.FreeBSD.org/advisories/FreeBSD-SA-14:04.bind.asc>
-----BEGIN PGP SIGNATURE-----

iQIcBAEBCgAGBQJS1ZTYAAoJEO1n7NZdz2rnOvQP/2/68/s9Cu35PmqNtSZVVxVG
ZSQP5EGWx/lramNf9566iKxOrLRMq/h3XWcC4goVd+gZFrvITJSVOWSa7ntDQ7TO
XcinfRZ/iyiJbs/Rg2wLHc/t5oVSyeouyccqODYFbOwOlk35JjOTMUG1YcX+Zasg
ax8RV+7Zt1QSBkMlOz/myBLXUjlTZ3Xg2FXVsfFQW5/g2CjuHpRSFx1bVNX6ysoG
9DT58EQcYxIS8WfkHRbbXKh9I1nSfZ7/Hky/kTafRdRMrjAgbqFgHkYTYsBZeav5
fYWKGQRJulYfeZQ90yMTvlpF42DjCC3uJYamJnwDIu8OhS1WRBI8fQfr9DRzmRua
OK3BK9hUiScDZOJB6OqeVzUTfe7MAA4/UwrDtTYQ+PqAenv1PK8DZqwXyxA9ThHb
zKO3OwuKOVHJnKvpOcr+eNwo7jbnHlis0oBksj/mrq2P9m2ueF9gzCiq5Ri5Syag
Wssb1HUoMGwqU0roS8+pRpNC8YgsWpsttvUWSZ8u6Vj/FLeHpiV3mYXPVMaKRhVm
067BA2uj4Th1JKtGleox+Em0R7OFbCc/9aWC67wiqI6KRyit9pYiF3npph+7D5Eq
7zPsUdDd+qc+UTiLp3liCRp5w6484wWdhZO6wRtmUgxGjNkxFoNnX8CitzF8AaqO
UWWemqWuz3lAZuORQ9KX
=OQzQ
-----END PGP SIGNATURE-----
....

Todo comunicado de segurança usa o seguinte formato:

* Cada aviso de segurança é assinado pela chave PGP do Oficial de Segurança. A chave pública para o Oficial de Segurança pode ser verificada em crossref:pgpkeys[pgpkeys,Chaves OpenPGP].
* O nome do alerta de segurança sempre começa com `FreeBSD-SA-` (para o FreeBSD Security Advisory), seguido pelo ano em formato de dois dígitos (`14:`), seguido pelo número de aviso para aquele ano (`04.`), seguido pelo nome do aplicativo ou subsistema afetado (`bind`). O comunicado mostrado aqui é o quarto comunicado de 2014 e afeta o BIND.
* O campo `Topic` resume a vulnerabilidade.
* O campo `Category` refere-se à parte afetada do sistema, que pode ser uma de `core`, `contrib`, ou `ports`. A categoria `core` significa que a vulnerabilidade afeta um componente principal do sistema operacional FreeBSD. A categoria `contrib` significa que a vulnerabilidade afeta um software incluído no FreeBSD, como o BIND. A categoria `ports` indica que a vulnerabilidade afeta um software disponível através da coleção de ports.
* O campo `Module` refere-se ao local do componente. Neste exemplo, o módulo `bind` é afetado; Portanto, essa vulnerabilidade afeta um aplicativo instalado com o sistema operacional.
* O campo `Announced` reflete a data em que o comunicado de segurança foi publicado. Isto significa que a equipe de segurança verificou que o problema existe e que um patch foi disponibilizado no repositório do código fonte do FreeBSD.
* O campo `Credits` dá crédito ao indivíduo ou organização que encontrou a vulnerabilidade e a relatou.
* O campo `Affects` explica quais versões do FreeBSD são afetadas por esta vulnerabilidade.
* O campo `Corrected` indica a data, a hora, o deslocamento do horário e as releases que foram corrigidas. A seção entre parênteses mostra cada branch para a qual a correção foi mesclada e o número de versão da liberação correspondente dessa branch. O próprio identificador de release inclui o número da versão e, se apropriado, o nível do patch. O nível de correção é a letra `p` seguida de um número, indicando o número de seqüência do patch, permitindo que os usuários controlem quais patches já foram aplicados ao sistema.
* O campo `CVE Name` lista o número de aviso, se existir, no banco de dados público http://cve.mitre.org[cve.mitre.org] de vulnerabilidades de segurança.
* O campo `Background` fornece uma descrição do módulo afetado.
* O campo `Problem Description` explica a vulnerabilidade. Isso pode incluir informações sobre o código defeituoso e como o utilitário pode ser usado de maneira mal-intencionada.
* O campo `Impact` descreve o tipo de impacto que o problema pode ter em um sistema.
* O campo `Workaround` indica se uma solução alternativa está disponível para os administradores do sistema que não podem corrigir imediatamente o sistema.
* O campo `Solution` fornece as instruções para corrigir o sistema afetado. Este é um método testado e verificado passo a passo para obter um sistema corrigido e funcionando com segurança.
* O campo `Correction Details` exibe cada branch do Subversion afetada com o número de revisão que contém o código corrigido.
* O campo `References` oferece fontes de informações adicionais sobre a vulnerabilidade.

[[security-accounting]]
== Auditoria de Processo

A auditoria de processos é um método de segurança no qual um administrador pode controlar os recursos do sistema utilizados e sua alocação entre os usuários, fornecer monitoramento do sistema e controlar minimamente os comandos de um usuário.

A auditoria de processos tem pontos positivos e negativos. Um dos pontos positivos é que uma intrusão pode ser rastreada ao ponto de entrada. Um valor negativo é a quantidade de logs gerados pela contabilidade do processo e o espaço em disco necessário. Esta seção conduz um administrador pelos fundamentos da contabilidade de processo.

[NOTE]
====
Se uma auditoria mais detalhada for necessária, consulte crossref:audit[audit, Auditoria de Evento de Segurança].
====

=== Ativando e Utilizando a Auditoria de Processos

Antes de usar a auditoria de processos, ela deve ser ativada usando os seguintes comandos:

[source,shell]
....
# sysrc accounting_enable=yes
# service accounting start
....

As informações de auditoria são armazenadas em arquivos localizados em [.filename]#/var/account#, que são criados automaticamente, se necessário, na primeira vez em que o serviço de auditoria é iniciado. Esses arquivos contêm informações confidenciais, incluindo todos os comandos executados por todos os usuários. O acesso de escrita aos arquivos é limitado ao `root` e o acesso de leitura é limitado ao `root` e aos membros do grupo `wheel`. Para também impedir que membros do grupo `wheel` leiam os arquivos, altere a permissão do diretório [.filename]#/var/account# para permitir acesso apenas de `root`.

Uma vez ativada, a auditoria começará a rastrear informações, como estatísticas de CPU e comandos executados. Todos os logs auditados estão em um formato não legível que pode ser visualizado usando `sa`. Se executado sem nenhuma opção, o `sa` imprime informações relacionadas ao número de chamadas por usuário, o tempo total decorrido em minutos, o total de CPU e o tempo do usuário em minutos, e o número médio de operações de I/O. Consulte man:sa[8] para obter a lista de opções disponíveis que controlam a saída.

Para exibir os comandos emitidos pelos usuários, use o `lastcomm`. Por exemplo, este comando imprime todo o uso do comando `ls` pelo usuário `trhodes` no terminal `ttyp1`:

[source,shell]
....
# lastcomm ls trhodes ttyp1
....

Muitas outras opções úteis existem e são explicadas em man:lastcomm[1], man:acct[5] e man:sa[8].

[[security-resourcelimits]]
== Limites de Recursos

O FreeBSD fornece vários métodos para um administrador limitar a quantidade de recursos do sistema que um indivíduo pode usar. As cotas de disco limitam a quantidade de espaço em disco disponível para os usuários. As cotas são discutidas em crossref:disks[quotas,Cotas de Disco].

Limites para outros recursos, como CPU e memória, podem ser definidos usando um arquivo simples ou um comando para configurar um banco de dados de limites de recursos. O método tradicional define classes de login editando o arquivo [.filename]#/etc/login.conf#. Embora esse método ainda seja suportado, qualquer alteração requer um processo de várias etapas para editar esse arquivo, reconstruir o banco de dados de recursos, fazer as alterações necessárias no arquivo [.filename]#/etc/master.passwd# e reconstruir o banco de dados de senhas. Isso pode se tornar demorado, dependendo do número de usuários a serem configurados.

O comando `rctl` pode ser usado para fornecer um método mais refinado para controlar limites de recursos. Esse comando suporta mais que limites de usuário, já que também pode ser usado para definir restrições de recursos em processos e jails.

Esta seção demonstra os dois métodos para controlar recursos, começando com o método tradicional.

[[users-limiting]]
=== Configurando Classes de Login

No método tradicional, as classes de login e os limites de recursos a serem aplicados a uma classe de login são definidos no arquivo [.filename]#/etc/login.conf#. Cada conta de usuário pode ser atribuída a uma classe de login, onde `default` é a classe de login padrão. Cada classe de login possui um conjunto de recursos de login associados a ele. Um recurso de login é um par `_name_=_value_`, em que _name_ é um identificador conhecido e _value_ é uma string arbitrária que é processada de acordo, dependendo do _name_.

[NOTE]
====
Sempre que o arquivo [.filename]#/etc/login.conf# for editado, o [.filename]#/etc/login.conf.db# deve ser atualizado executando o seguinte comando:

[source,shell]
....
# cap_mkdb /etc/login.conf
....

====

Os limites de recursos diferem dos recursos de login padrão de duas maneiras. Primeiro, para cada limite, existe um limite _soft_ e um _hard_. Um limite soft pode ser ajustado pelo usuário ou aplicativo, mas não pode ser definido como superior ao limite hard. O limite hard pode ser baixado pelo usuário, mas só pode ser aumentado pelo root. Segundo, a maioria dos limites de recursos se aplica por processo a um usuário específico.

<<resource-limits>> lista os limites de recursos mais usados. Todos os limites de recursos disponíveis e capabilities são descritos em detalhes em man:login.conf[5].
[[resource-limits]]
.Limites de Recursos de Classe de Login
[cols="1,1", frame="none", options="header"]
|===
| Limite de Recurso
| Descrição

|coredumpsize
|O limite do tamanho de um arquivo core gerado por um programa é subordinado a outros limites de uso do disco, como `filesize` ou cotas de disco. Esse limite é frequentemente usado como um método menos severo de controle do consumo de espaço em disco. Como os usuários não geram arquivos core e geralmente não os excluem, essa configuração pode evitar que eles fiquem sem espaço em disco caso ocorra um grande travamento de programa.

|cputime
|A quantidade máxima de tempo de CPU que o processo de um usuário pode consumir. Os processos ofensivos serão eliminados pelo kernel. Este é um limite no _tempo_ de CPU consumido, não a porcentagem do CPU como exibido em alguns dos campos gerados pelo `top` e `ps`.

|filesize
|O tamanho máximo de um arquivo que o usuário pode possuir. Ao contrário das cotas de disco (crossref:disks[quotas,Cotas de Disco]), esse limite é imposto em arquivos individuais, não no conjunto de todos os arquivos que um usuário possui.

|maxproc
|O número máximo de processos de primeiro plano e de plano de fundo que um usuário pode executar. Esse limite pode não ser maior que o limite do sistema especificado pela variável `kern.maxproc`. Definir um limite muito pequeno pode prejudicar a produtividade de um usuário, pois algumas tarefas, como compilar um programa grande, iniciam muitos processos.

|memorylocked
|A quantidade máxima de memória que um processo pode solicitar para ser bloqueado na memória principal usando o man:mlock[2]. Alguns programas críticos do sistema, como man:amd[8], se bloqueiam na memória principal para que, se o sistema começar a fazer swap, eles não contribuam para surrar o disco.

|memoryuse
|A quantidade máxima de memória que um processo pode consumir a qualquer momento. Inclui tanto a memória principal quanto o uso de swap. Este não é um limite geral para restringir o consumo de memória, mas é um bom começo.

|openfiles
|O número máximo de arquivos que um processo pode ter aberto. No FreeBSD, os arquivos são usados para representar sockets e canais IPC, então tome cuidado para não definir isso muito baixo. O limite de todo o sistema para isso é definido por pela variável `kern.maxfiles`.

|sbsize
|O limite na quantidade de memória de rede que um usuário pode consumir. Isso geralmente pode ser usado para limitar as comunicações da rede.

|stacksize
|O tamanho máximo de uma pilha de processos. Isso por si só não é suficiente para limitar a quantidade de memória que um programa pode usar, por isso deve ser usado em conjunto com outros limites.
|===

Existem algumas outras coisas para se lembrar ao definir limites de recursos:

* Os processos iniciados na inicialização do sistema pelo [.filename]#/etc/rc# são atribuídos à classe `daemon` de login.
* Embora o arquivo [.filename]#/etc/login.conf# padrão seja uma boa fonte de valores razoáveis para a maioria dos limites, eles podem não ser apropriados para todos os sistemas. Definir um limite muito alto pode abrir o sistema para uso abusivo, enquanto que defini-lo como muito baixo pode prejudicar a produtividade.
* O Xorg utiliza muitos recursos e incentiva os usuários a executarem mais programas simultaneamente.
* Muitos limites se aplicam a processos individuais, não ao usuário como um todo. Por exemplo, definir a variável `openfiles` como `50` significa que cada processo que o usuário executa pode abrir até `50` arquivos. A quantidade total de arquivos que um usuário pode abrir é o valor de `openfiles` multiplicado pelo valor de `maxproc`. Isso também se aplica ao consumo de memória.

Para mais informações sobre limites de recursos e classes de login e capacidades em geral, consulte man:cap_mkdb[1], man:getrlimit[2] e man:login.conf[5].

=== Ativando e Configurando Limites de Recursos

A variável configurável `kern.racct.enable` deve ser configurada para um valor diferente de zero. Kernels personalizados requerem configuração específica:

[.programlisting]
....
options         RACCT
options         RCTL
....

Depois que o sistema for reinicializado no novo kernel, o `rctl` poderá ser usado para definir regras para o sistema.

A sintaxe da regra é controlada por meio do uso de um subject, subject-id, resource e action, conforme visto nesta regra de exemplo:

[.programlisting]
....
user:trhodes:maxproc:deny=10/user
....

Nesta regra, o subject é `user`, o subject-id é `trhodes`, o resource, `maxproc`, é o número máximo de processos, e a action é `deny`, que bloqueia a criação de novos processos. Isso significa que o usuário, `trhodes`, será restrito a execução de no máximo `10` processos. Outras ações possíveis incluem o registro no console, passando uma notificação para o man:devd[8] ou enviando um sigterm para o processo.

Algum cuidado deve ser tomado ao adicionar regras. Como esse usuário está restrito a `10` processos, este exemplo impedirá que o usuário execute outras tarefas depois de efetuar login e executar uma sessão `screen`. Quando um limite de recurso for atingido, um erro será impresso, como neste exemplo:

[source,shell]
....
% man test
    /usr/bin/man: Cannot fork: Resource temporarily unavailable
eval: Cannot fork: Resource temporarily unavailable
....

Como outro exemplo, uma jail pode ser impedida de exceder um limite de memória. Esta regra pode ser escrita como:

[source,shell]
....
# rctl -a jail:httpd:memoryuse:deny=2G/jail
....

As regras persistirão durante as reinicializações se tiverem sido adicionadas ao arquivo [.filename]#/etc/rctl.conf#. O formato é uma regra, sem o comando anterior. Por exemplo, a regra anterior pode ser adicionada como:

[.programlisting]
....
# Block jail from using more than 2G memory:
jail:httpd:memoryuse:deny=2G/jail
....

Para remover uma regra, use o `rctl` para removê-la da lista:

[source,shell]
....
# rctl -r user:trhodes:maxproc:deny=10/user
....

Um método para remover todas as regras é documentado em man:rctl[8]. No entanto, se for necessário remover todas as regras para um único usuário, esse comando poderá ser emitido:

[source,shell]
....
# rctl -r user:trhodes
....

Existem muitos outros recursos que podem ser usados para exercer controle adicional sobre vários `subjects`. Veja man:rctl[8] para aprender sobre eles.

[[security-sudo]]
== Administração Compartilhada com Sudo

Os administradores do sistema geralmente precisam conceder permissões avançadas aos usuários para que eles possam executar tarefas privilegiadas. A ideia de que os membros da equipe tenham acesso a um sistema FreeBSD para executar suas tarefas específicas abre desafios únicos para cada administrador. Esses membros da equipe precisam apenas de um subconjunto de acesso além dos níveis normais de usuário final; no entanto, eles quase sempre dizem ao gerenciadores que eles são incapazes de executar suas tarefas sem acesso de superusuário. Felizmente, não há motivo para fornecer tal acesso aos usuários finais porque existem ferramentas para gerenciar esse exato requisito.

Até este ponto, o capítulo de segurança cobriu o acesso a usuários autorizados e a tentativa de impedir o acesso não autorizado. Outro problema surge quando os usuários autorizados têm acesso aos recursos do sistema. Em muitos casos, alguns usuários podem precisar acessar os scripts de inicialização do aplicativo ou uma equipe de administradores precisa manter o sistema. Tradicionalmente, os usuários e grupos padrão, as permissões de arquivo e até mesmo o comando man:su[] gerenciariam esse acesso. E como os aplicativos exigiam mais acesso, à medida que mais usuários precisavam usar recursos do sistema, era necessária uma solução melhor. A aplicação mais usada atualmente é o Sudo.

O Sudo permite que os administradores configurem um acesso mais rígido aos comandos do sistema e forneçam alguns recursos avançados de log. Como uma ferramenta, ele está disponível na coleção de ports como package:security/sudo[] ou usando o utilitário man:pkg[8]. Para usar a ferramenta man:pkg[8]:

[source,shell]
....
# pkg install sudo
....

Após a conclusão da instalação, o `visudo` instalado abrirá o arquivo de configuração com um editor de texto. O uso do `visudo` é altamente recomendado, pois vem com um verificador de sintaxe incorporado para verificar se não há erros antes que o arquivo seja salvo.

O arquivo de configuração é composto de várias seções pequenas que permitem uma configuração extensiva. No exemplo a seguir, o mantenedor do aplicativo da web, user1, precisa iniciar, parar e reiniciar o aplicativo da web conhecido como _webservice_. Para conceder a este usuário permissão para executar estas tarefas, adicione esta linha ao final do arquivo [.filename]#/usr/local/etc/sudoers#:

[.programlisting]
....
user1   ALL=(ALL)       /usr/sbin/service webservice *
....

O usuário pode agora iniciar o _webservice_ usando este comando:

[source,shell]
....
% sudo /usr/sbin/service webservice start
....

Embora essa configuração permita que um único usuário acesse o serviço webservice; No entanto, na maioria das organizações, existe uma equipe inteira da Web encarregada de gerenciar o serviço. Uma única linha também pode dar acesso a um grupo inteiro. Essas etapas criarão um grupo da Web, adicionarão um usuário a esse grupo e permitirão que todos os membros do grupo gerenciem o serviço:

[source,shell]
....
# pw groupadd -g 6001 -n webteam
....

Usando o mesmo comando man:pw[8], o usuário é adicionado ao grupo webteam:

[source,shell]
....
# pw groupmod -m user1 -n webteam
....

Finalmente, esta linha no arquivo [.filename]#/usr/local/etc/sudoers# permite que qualquer membro do grupo webteam gerencie o _webservice_:

[.programlisting]
....
%webteam   ALL=(ALL)       /usr/sbin/service webservice *
....

Ao contrário do man:su[1], o Sudo requer apenas a senha do usuário final. Isso adiciona uma vantagem em que os usuários não precisarão de senhas compartilhadas, uma descoberta na maioria das auditorias de segurança e o que por si só já ruins em todos os aspectos.

Os usuários autorizados a executar aplicativos com o Sudo só inserem suas próprias senhas. Isso é mais seguro e oferece melhor controle do que o man:su[1], onde a senha de `root` é inserida e o usuário adquire todas as permissões de `root`.

[TIP]
====

A maioria das organizações está se movendo ou migrou para um modelo de autenticação de dois fatores. Nestes casos, o usuário pode não ter uma senha para entrar. O Sudo resolve estes casos com a variável `NOPASSWD`. Adicioná-lo à configuração acima permitirá que todos os membros do grupo _webteam_ gerenciem o serviço sem o requisito de senha:

[.programlisting]
....
%webteam   ALL=(ALL)       NOPASSWD: /usr/sbin/service webservice *
....

====

[[security-sudo-loggin]]
=== Logando a Saída

Uma vantagem para implementar o Sudo é a capacidade de ativar o log de sessão. Usando os mecanismos de log integrados e o comando sudoreplay incluído, todos os comandos iniciados por meio de Sudo são registrados para verificação posterior. Para ativar esse recurso, adicione uma entrada de diretório de log padrão, este exemplo usa uma variável de usuário. Existem várias outras convenções de nome de arquivo de log, consulte a página de manual do sudoreplay para obter informações adicionais.

[.programlisting]
....
Defaults iolog_dir=/var/log/sudo-io/%{user}
....

[TIP]
====

Este diretório será criado automaticamente após o logging ser configurado. É melhor deixar o sistema criar o diretório com permissões padrão apenas para estar seguro. Além disso, essa entrada também registra os administradores que usam o comando sudoreplay. Para alterar esse comportamento, leia e descomente as opções de log dentro do arquivo [.filename]#sudoers#.
====

Uma vez que esta diretiva tenha sido adicionada ao arquivo [.filename]#sudoers#, qualquer configuração de usuário pode ser atualizada com a solicitação para acessar o log. No exemplo mostrado, a entrada _webteam_ atualizada teria as seguintes alterações adicionais:

[.programlisting]
....
%webteam ALL=(ALL) NOPASSWD: LOG_INPUT: LOG_OUTPUT: /usr/sbin/service webservice *
....

Deste ponto em diante, todos os membros do grupo _webteam_ que alteram o status do aplicativo _webservice_ serão registrados. A lista de sessões anteriores e atuais pode ser exibida com:

[source,shell]
....
# sudoreplay -l
....

Na saída, para reproduzir uma sessão específica, procure a entrada `TSID=` e passe-a para o sudoreplay sem outras opções para reproduzir a sessão na velocidade normal. Por exemplo:

[source,shell]
....
# sudoreplay user1/00/00/02
....

[WARNING]
====

Enquanto as sessões são registradas, qualquer administrador pode remover as sessões e deixar apenas uma questão de por que elas fizeram isso. Vale a pena adicionar uma verificação diária por meio de um sistema de detecção de intrusão (IDS) ou software semelhante para que outros administradores sejam alertados sobre alterações manuais.
====

O `sudoreplay` é extremamente extensível. Consulte a documentação para mais informações.
