Como o servidor em nuvem impacta a segurança da sua empresa?

 Clusterweb, ClusterWeb, Leitura Recomendada, Profissional de TI  Comentários desativados em Como o servidor em nuvem impacta a segurança da sua empresa?
fev 282019
 

A segurança é um dos pontos de destaque de um servidor em nuvem. Há diversos fatores que contribuem para isso, como a ausência do risco de roubo ou dano de equipamentos, além do isolamento de dados vindos de conexões não-seguras, por exemplo.

Mais do que isso, porém, o servidor em nuvem garante vantagens para seu negócio porque conta com o aporte de uma empresa especializada e de uma equipe capacitada para fazer a gestão e garantir a segurança e acessibilidade dos dados em diversos níveis.

Ficou interessado e quer saber mais a respeito? Acompanhe!

Continue reading »

set 132017
 

A sigla RAID significa montar arranjos com mais que um disco rígido num storage ou servidor, objetivando assim redundância e/ou performance no sistema de forma econômica. O array de discos é utlizado por servidores, workstations, storages e outros sistemas computacionais para melhor performance e maior segurança no armazenamento de informações. Na prática, dois ou mais discos rígidos são associados de forma lógica para obter-se algum tipo de benefício. Continue reading »

SEGURANÇA DE WEB APIS DISTRIBUÍDAS

 Apache2, Clusterweb, ClusterWeb, Hospedagem, Leitura Recomendada, Linux, Profissional de TI, Segurança, Ubuntu  Comentários desativados em SEGURANÇA DE WEB APIS DISTRIBUÍDAS
jan 292017
 

RESUMO

 

Artigo faz parte da disciplina de “Segurança de Sistemas”, do professor Elgio Schlemer.

Neste artigo são descritas as formas de autenticação e autorização de REST apis distribuídas, os motivos que aumentam a complexidade de desenvolvimento dessas futures em web services escalonados e as soluções baseadas nas melhores práticas em relação à essas arquiteturas.

Também é abordado a importância da criação de sistemas seguros, evidências que demonstram como esse problema impacta desde pequenas startups até grandes empresas, a gravidade da ciência do nível de criticidade e risco em relação aos softwares desenvolvidos e a importância de expor apenas recursos que sejam realmente necessários.

Serão mencionados também os perigos relacionados aos ataques de Man-in-the-middle, negação de serviço, SQL inject, JSON inject e os métodos utilizados para combatê-los.

INTRODUÇÃO

Informações sigilosas são expostas diariamente e esse problema não atinge apenas jovens startups que não tem o devido investimento na área, com frequência surgem notícias de grandes empresas que são hackeadas e acabam vazando dados indesejados. Somente neste ano, o Yahoo! afirmou que quinhentos milhões de contas foram hackeadas. No Dropbox foram mais de sessenta milhões e a Anatel teve seu banco de dados invadido. Inclusive grandes organizações como NASA e ESA não ficam fora dessa lista.

Softwares com suas arquiteturas baseados em micro serviços, orquestração e coreografias são termos cada vez mais citados na comunidade de desenvolvimento web. E todas as abordagens tem uma característica em comum: REST APIs. Elas estão por toda a parte.

Com o crescimento exponencial de estratégias digitais em mobilidade, cloud computing, mídias sociais e dispositivos inteligentes da Internet das Coisas, empresas de todos os tamanhos e setores estão desenvolvendo e expondo seus Web Services. Mas como sempre no mundo da computação, nem tudo são flores: junto com várias vantagens relacionadas à utilização de APIs distribuídas, também existem grandes problemas a serem resolvidos, e uma das maiores dificuldades é a segurança desses sistemas.

SELinux – Segurança em Servidores GNU/Linux

 Firewall, Redes, Segurança  Comentários desativados em SELinux – Segurança em Servidores GNU/Linux
maio 302013
 
O SELinux

O Security-Enhanced LinuxSELinux – foi desenvolvido pela Agência Nacional de Segurança dos EUA (NSA). Logo no início, seu objetivo principal era tornar-se um sistema operacional capaz de fornecer controles avançados de acesso para os órgãos militares dos Estados Unidos.

Porém, com o passar do tempo, a NSA identificou que seria mais lógico aprimorar um sistema de controle de acesso obrigatório, e adicioná-los a um sistema operacional já existente.

A opção pelo GNU/Linux surgiu devida à facilidade e flexibilidade de incorporar tal framework ao Kernel do sistema. Logo depois, sistemas que traziam a plataforma Unix, também usufruíram desta tão poderosa ferramenta.

Altamente implementado e refinado em cima da arquitetura MAC (Mandatory Access Control), provendo maior segurança a arquivos, diretórios, processos, sistema de arquivos, entre outros objetos, através de regras providas pelo SELinux.

Vale ressaltar, que este nível de segurança vai além da arquitetura DAC (Discretionary Access Control) que está associada à permissão de arquivos e ACLs (Access Control List’s) do GNU/Linux, como exemplo, as permissões MAC podem ser aplicadas até ao usuário root, limitando ações do mesmo.

Em um conceito prático, imaginemos que a conta de sistema associada ao serviço HTTP foi comprometida, o SELinux através de regras pré estabelecidas, limita este comprometimento apenas ao serviço HTTP, impossibilitando o comprometimento de outros serviços, ou até mesmo, do próprio sistema operacional.

Depois deste breve conceito, vamos à prática.

Lembrando que mais informações do SELinux, podem ser obtidas na Wiki do Projeto:

Ou, na página oficial da NSA:

Modo de operação do SELinux (conceito e prática)

Basicamente, o SELinux pode operar em três tipos diferentes, que são:

  • Enforcing – As regras do SELinux estão aplicadas, e está sendo gerado Logs de todas as operações do mesmo;
  • Permissive – As regras do SELinux estão desativadas, porém, está gerando Logs de todas as operações do mesmo (útil para Troubleshoot de aplicações);
  • Disabled – As regras e os Logs do SELinux estão completamente desativados.

Obs.: Para nossos testes, estou utilizando o CentOS 6.3.

Visualizando o status do SELinux:

# sestatus

Saída do comando:

SELinux status:            enabled
SELinux mount:            /selinux
Current mode:             enforcing
Mode from config file:   enforcing
Policy version:              24
Policy from config file:   targeted

Caso se queira visualizar apenas o Current mode do SELinux, utilize o comando:

# getenforce

Saída do comando:

Enforcing

Perceba que este comando traz apenas o modo de operação do SELinux.

Para alterarmos o modo de operação temporário do SELinux (apenas Enforcing e Permissive), utilizaremos o seguinte comando:

# setenforce MODO_DE_OPERAÇÂO

Ex.:

# setenforce permissive

Logo, visualize o status do SELinux:

# sestatus

SELinux status:            enabled
SELinux mount:            /selinux
Current mode:             permissive
Mode from config file:   enforcing
Policy version:              24
Policy from config file:   targeted

Obs.: Para desabilitar, ou alterar, o ‘current mode’ do SELinux por completo, é necessário editar o arquivo de configuração do SELinux (/etc/selinux/config) e alterar a variável:

‘SELINUX=’.

* Apenas como fonte de informação:

  • Em alguns casos com o SELinux habilitado, podemos nos deparar com serviços que, por algum motivo, não estão funcionando.
  • Alguns administradores, simplesmente desativam o SELinux por completo (Modo Disabled), para resolver o “problema”.
  • Porém, para um Troubleshoot eficaz, não é necessário desativar o SELinux por completo comprometendo a segurança do sistema, e sim, deixá-lo em modo “Permissive”; com isso, as regras serão desativadas, porém, todo registro das atividades (logs) continuarão sendo armazenadas.
Contextos de segurança

Em uma explicação básica, um contexto é um valor de dado assumido pelos objetos de uma classe.

Nome, Idade e Peso, são exemplos de contextos do objeto “Pessoa”. Cor, Categoria e Modelo, são possíveis contextos do objeto “Carro”. No caso, os contextos da arquitetura DAC são: Tipo, Dono, Grupo e Outros.

Ex.:

# ls –ld /etc

Saída do comando:

drwxr-xr-x

Onde:

  • d = Diretório (Tipo)
  • rwx = Permissão para o dono do arquivo (Dono)
  • r-x = Permissão para o grupo do do arquivo (Grupo)
  • r-x = Permissão para os outros objetos do sistema (Outros)

No caso da arquitetura MAC, os contextos mudam de características, conforme: Usuário, Papel, Tipo e Nível.

Onde:

  • Usuário (user_u) – O campo usuário, indica o nome do usuário do SELinux, por exemplo, o usuário “system_u”, indica processos, arquivos de configuração e daemons do sistema.
  • Papel (role_r) – O campo papel, é uma forma de agrupar diferentes permissões a um determinado usuário (uma espécie de grupo).
  • Tipo (type_t) – O campo tipo (também conhecido como domínio), indica qual é permissão primária de determinado objeto do SELinux, essa é a primeira etapa de verificação de permissão do sistema MAC.
  • Nível (s*:c*) – O campo nível, indica em qual categoria determinado objeto se encontra, com relação à segurança. O mesmo utiliza a politica MCS/MLS (Multi-Category Security/ Multi-Level Security).

    Por exemplo, o nível s0:c0 indica um objeto Confidencial para todos os que possuírem o mesmo nível.

Na prática, com o mesmo diretório /etc:

# ls –Zd

Saída do comando:

System_u:object_r:etc_t:s0

Onde:

  • system_u =Usuário SELinux dono do objeto
  • object_r = Papel (ou papel) do SELinux
  • etc_t = Domínio (ou tipo) do SELinux
  • s0 = Nível de segurança do SELinux

Visualizando contextos MAC nos objetos do sistema

Para visualizar todos os processos que estão rodando no sistema, juntamente com os contextos do SELinux, vamos utilizar o comando abaixo:

# ps auxZ

Perceba que apenas adicionando a opção “Z” no comando ps, já é suficiente para visualizarmos os contextos de todos os processos do SELinux. Isto vale para outros comandos também, como por exemplo, o comando ls.

Vamos visualizar o contexto de um arquivo ou diretório qualquer do sistema:

# ls –Z /boot

Saída do comando:

system_u:object_r:boot_t:s0

Isso vale também para o comando id, que nos traz informações de um determinado usuário:

Ex.:

# id –Z

Saída do comando:

unconfined_u: unconfined_r: unconfined_t:s0-s0:c0.c1023ls

Perceba que neste caso, todo o contexto está definido como: unconfined_*

…Isto indica que o SELinux não terá influência alguma no objeto correspondente.

O comando Semanage

Para um bom entendimento do SELinux, é necessário explorar o mesmo por completo, o comando semanage traz uma série de opções para que isso aconteça.

Primeiro, devemos instalar o conjunto de pacotes, que traz (além de vários outros) o comando Semanage:

# yum install policycoreutils-python

Com o Semanage instalado em nossa máquina, vamos listar todos os usuários, nível de MLS/MCS e papéis (roles) do SELinux:

# semanage user –l

Onde: -l = list

Saída do comando:

    Labeling   MLS/       MLS/                         
SELinux User    Prefix     MCS Level  MCS Range                      SELinux Roles
git_shell_u     user       s0         s0                             git_shell_r
guest_u         user       s0         s0                             guest_r
root            user       s0         s0-s0:c0.c1023                 staff_r sysadm_r system_r unconfined_r
staff_u         user       s0         s0-s0:c0.c1023                 staff_r sysadm_r system_r unconfined_r
sysadm_u        user       s0         s0-s0:c0.c1023                 sysadm_r
system_u        user       s0         s0-s0:c0.c1023                 system_r unconfined_r
unconfined_u    user       s0         s0-s0:c0.c1023                 system_r unconfined_r
user_u          user       s0         s0                             user_r
xguest_u        user       s0         s0                             xguest_r

Pergunta: “ual a função de cada usuário? Permissão? Acessos e etc…?

Vamos a um overview rápido e objetivo de cada um:

  • guest_u: Este perfil é usado para usuários que precisam ser rigorosamente controlados. O guest_u só pode fazer login usando o terminal. O mesmo não tem acesso a recursos de rede, programas setuid, setgid, su, sudo e interface gráfica.
  • xguest_u: Este perfil é idêntico à do ‘guest_u’. A exceção é que ‘xguest_u’, os usuários só conseguem fazer login na interface gráfica.
  • user_u: Assemelha a um usuário comum sem privilégios administrativos. Este usuário pode fazer login usando interface gráfica e terminal, tem acesso aos recursos da rede, mas não pode usar programas setuid e setgid.
  • staff_u: Este usuário é idêntico ao ‘user_u’, exceto que o ‘staff_u’ pode acessar os programas setuid e setgid. O ‘staff_u’ também pode fazer STAT em todos os processos do sistema, entre outros pequenos privilégios extras, em comparação com ‘user_u’.
  • sysadm_u: Este usuário é projetado para realizar login como root. Muito utilizado em ambientes multi nível de segurança, onde não há o objeto ‘unconfined_u’.
  • unconfined_u: O ‘unconfined_u’ é, em muitas vezes, isentos de regras do SELinux.

    Usuários reais do GNU/Linux, exceto o usuário root, não devem ser mapeados para o grupo de usuários ‘unconfined_u’. Em muitos cenários com que os usuários não são confinados, o mesmos criam um buraco na segurança do sistema operacional.

  • system_u: Este perfil de usuário do SELinux está reservado para o sistema. Os usuários do GNU/Linux não devem ser mapeado para o usuário SELinux ‘system_u’, geralmente este usuário esta atrelado a processos, configurações e daemons.

Agora que já sabemos as reais permissões dos usuários do SELiux, vamos listar todos os usuários do sistema que estão atrelados aos usuários e permissões do SELinux:

# semanage login –l

Saída do comando:

Login Name                SELinux User              MLS/MCS Range           
__default__               unconfined_u              s0-s0:c0.c1023          
root                      unconfined_u              s0-s0:c0.c1023          
system_u                  system_u                  s0-s0:c0.c1023

Apenas como fonte de conhecimento, vamos criar um usuário chamado “teste”, e referenciá-lo ao usuário “guest_u” do SELinux:

# useradd –c “Usuário Teste” –d /home/teste –m –k /etc/skel –s /bin/bash teste
# passwd teste
# semanage login –a –s guest_u teste

Onde:

  • -a = add
  • -s = selinux user

Logo, liste os logins novamente:

# semanage login –l

Login Name                SELinux User              MLS/MCS Range           
__default__               unconfined_u             s0-s0:c0.c1023          
root                      unconfined_u                 s0-s0:c0.c1023          
system_u                  system_u                  s0-s0:c0.c1023         
teste                       guest_u                      s0

Perceba que agora, o usuário “teste”, está atrelado ao usuário do SELinux “guest_u”, obtendo automaticamente as mesmas permissões do mesmo.

Tente logar na área gráfica com o usuário “teste”. Depois tente logar com o mesmo usuário, em algum terminal.

Perceba que as permissões do usuário “guest_u” do SELinux, não permitem o login na área gráfica, somente no terminal.

Agora, experimente atrelar o usuário “teste” ao usuário “xguest_u”. Neste momento, o usuário “teste” tem as devidas permissões para acessar a área gráfica.

Para remover o usuário “teste” das diretivas do SELinux, basta executar o comando:

# semanage login -d teste

Onde: -d = delete

Continuando com o comando semanage, vamos listar todos os contextos aplicados no sistema:

# semanage fcontext –l

Assim, fica muito mais fácil saber se determinado objeto ou serviço, está atrelado às politicas MAC do SELinux.

Mais informações sobre o comando semanage:

# semanage – -help

Os comandos Chcon e Restorecon

Diversas vezes, nos deparamos com problemas de permissão de contextos no SELinux, isto acontece frequentemente, ainda mais em serviços que têm uma alta rotatividade de objetos, como File Servers e FTP.

Para resolver este problema, utilizaremos o comando chcon, sua função nada mais é do que alterar contextos em objetos.

Para os nossos testes com o chcon, vamos criar um arquivo denominado “teste.txt” dentro do diretório /etc:

# touch /etc/teste.txt

Verifique os contextos deste arquivo:

# ls -Z /etc/teste.txt

Saída do comando:

-rw-r–r–. root root unconfined_u:object_r:etc_t:s0 /etc/teste.txt

Perceba que o usuário está definido como “unconfined_u”. Imagine agora, que precisamos alterar (por algum motivo qualquer) para o usuário “user_u”. Vamos utilizar o seguinte comando:

# chcon -u user_u /etc/teste.txt

Onde: -u = user

# ls -Z /etc/teste.txt

Saída do comando:

-rw-r–r–. root root user_u:object_r:etc_t:s0 /etc/teste.txt

Perceba que, agora o arquivo está com o contexto de usuário definido para “user_u”.

Caso precisamos (por algum motivo qualquer) alterar o domínio (type) deste objeto, para “tmp_t”:

# chcon -t tmp_t /etc/teste.txt

Onde: -t = type

# ls -Z /etc/teste.txt

Saída do comando:

-rw-r–r–. root root user_u:object_r:tmp_t:s0 /etc/teste.txt

Pronto, o arquivo está com seu domínio alterado, assim, todos os objetos que tem acesso ao domínio “tmp_t”, terão acesso ao arquivo /etc/teste.txt.

Em um último teste do comando chcon, imaginamos que você queira clonar o contexto de outro objeto?! O chcon também faz isso:

# chcon –reference /var /etc/teste.txt
# ls -Z /etc/teste.txt

Saída do comando:

-rw-r–r–. root root system_u:object_r:var_t:s0 /etc/teste.txt

Obs.: Caso você queira aplicar contextos recursivamente, basta inserir a opção “-R” no comando chcon.

Em muitos casos, queremos deixar o objeto de acordo com as regras do domínio (type) no qual o mesmo está armazenado. Poderíamos utilizar o chcon e copiar todos os contextos, ou utilizar um comando que faz exatamente isso. Este comando é o restorecon, vamos vê-lo em detalhes:

# restorecon -F /etc/teste.txt

Com este comando, o arquivo “teste.txt” herdará todos os contextos do diretório /etc (local onde o mesmo está armazenado). Útil, não?! =)

Os comandos chcon e restorecon, são extremamente úteis e complexos, para um maior detalhamento dos mesmos, leia a Man Page oficial:

# man chcon
# man restorecon

Variáveis booleanas

As variáveis booleanas nada mais são, do que ligar(1) ou desligar(0) determinada ação (seja temporário ou não).

Um exemplo seria, imaginamos que determinada aplicação necessita de acesso a gravação no sistema, caso não existisse as variáveis booleanas, teríamos que reescrever o código do SELinux para permitir tal ação!

As mesmas são extremamente úteis para qualquer um que queira administrar o SELinux.

Para uma prática eficiente com as variáveis booleanas, é só lembrar dos termos 0 e 1, ou para ficar mais fácil: nã0 e s1m. =)

Vamos à mais um case!

Vamos instalar um serviço de FTP (apenas de exemplo), e gerenciar as variáveis booleanas:

# yum install vsftpd

E, adicionar aos níveis de execução:

# chkconfig –level 2345 vsftpd on

Agora, vamos reiniciar o serviço:

# service vsftpd restart

Agora que já temos o serviço devidamente instalado, vamos gerenciar as variáveis booleanas.

Primeiro, vamos listá-las:

# getsebool -a

Onde: -a = all

– Pergunta: Apenas com o nome das variáveis, fica difícil saber para que cada uma serve?
– Resposta: Para um maior detalhamento, vamos utilizar o semanage novamente:

# semanage boolean -l

Onde: -l = list

Perceba que agora, temos os nomes das variáveis, e também uma breve descrição de cada uma delas.

Vamos filtrar as variáveis para tudo que atrela-se ao serviço FTP:

# semanage boolean -l | grep ftp

Saída do comando:

ftp_home_dir                   (off  ,  off)  Allow ftp to read and write files in the user home directories
tftp_anon_write                (off  ,  off)  Allow tftp to modify public files used for public file transfer services.
allow_ftpd_full_access         (off  ,  off)  Allow ftp servers to login to local users and read/write all files on the system, governed by DAC.
allow_ftpd_use_cifs            (off  ,  off)  Allow ftp servers to use cifs used for public file transfer services.
allow_ftpd_use_nfs             (off  ,  off)  Allow ftp servers to use nfs used for public file transfer services.
allow_ftpd_anon_write          (off  ,  off)  Allow ftp servers to upload files,  used for public file transfer services. Directories must be labeled public_content_rw_t.
ftpd_use_passive_mode          (off  ,  off)  Allow ftp servers to use bind to all unreserved ports for passive mode
ftpd_connect_db                (off  ,  off)  Allow ftp servers to use connect to mysql database
httpd_enable_ftp_server        (off  ,  off)  Allow httpd to act as a FTP server by listening on the ftp port.

Por padrão, o serviço VSFTPD não permite o total gerenciamento de arquivos para o usuário anonymous, isso devido às restrições do SELinux!

Caso você queira dar tal permissão para o usuário anonymous (ou outros usuários), basta setar a variável: allow_ftpd_full_access

Com ela é possível dar controle total a qualquer usuário que conecte no FTP (lembrando que esse é apenas mais um teste).

– Pergunta: E como fazer isso?
– Resposta: Simples, utilizaremos o comando setsebool.

# setsebool -P allow_ftpd_full_access 1

Onde:

  • -P = Indica que será aplicada á alteração permanente, sem a opção ‘-P’ no próximo reboot, tudo será restaurado para o seu padrão!
  • 1 = Ativa a variável (lembre-se: s1m e nã0)

Pronto! Seu servidor FTP está dando controle total para qualquer usuário. Feliz agora?!

Bom, eu não ficaria, pois estamos abrindo um furo na segurança do sistema. Portanto, vamos desativar a variável booleana correspondente:

# setsebool -P allow_ftpd_full_access 0

Onde: 0 = Desativar a variável.

Lembre-se: As variáveis booleanas são extremamente importantes para a boa administração do SELinux, liste e teste cada uma delas, assim tudo ficara mais fácil. 😉

O comando Semodule

Assim, como o próprio sistema GNU/Linux, o SELinux opera em formato modular, ou seja, caso precise adicionar exceções, ou aprimoramento, de regras no SELinux para determinadas aplicações, como por exemplo um MTA, ou um servidor Web, não será necessária a recompilação do próprio sistema SELinux.

E sim, adicionar um código externo (módulo) que indique tal ação. Este módulo pode ser fornecido tanto pela equipe que administra a aplicação, quanto construída pelo próprio administrador do SELinux.

Obs.: Não confunda os módulos do SELinux com as variáveis booleanas. Os módulos são funções acrescentadas nas regras de determinada aplicação, já as variáveis booleanas, são permissões referentes à comunicação entre aplicação e objetos do sistema.

O comando que gerencia tais módulos no SELinux, é o Semodule, e sua utilização é muito simples.

Para listar os módulos do SELinux:

# semodule -l

Onde: -l = list

Saída do comando (resumida):

abrt    1.2.0
accountsd       1.0.0
ada     1.4.0
afs     1.5.3
aiccu   1.0.0
aide    1.5.0
aisexec 1.0.0
amanda  1.12.0
amavis  1.10.3
amtu    1.2.0
apache  2.1.2
apcupsd 1.6.1
arpwatch        1.8.1
asterisk        1.7.1
audioentropy    1.6.0
automount       1.12.

Caso precisemos desabilitar determinado módulo, como por exemplo, o módulo do Asterisk, utilizaremos a seguinte sintaxe do comando semodule:

# semodule -d asterisk

Onde: -d = disable

Agora, vamos listar os módulos, filtrando apenas o módulo do Asterisk:

# semodule -l | grep asterisk

Saída do comando:

asterisk       1.7.1   Disabled

Perceba que este módulo está presente, porém sem qualquer funcionalidade.

Para remover o módulo por completo, utilize o comando:

# semodule -r asterisk

Onde: -r = remove

# semodule -l

Listando novamente os módulos, perceba que o mesmo não se encontra mais na listagem.

– Pergunta: E se eu precisar do módulo do Asterisk novamente, o que eu faço?
– Resposta: Por padrão, os arquivos de módulo do SELinux terminam com extensão “.pp” (Package Policy), portanto, para instalar um módulo no sistema SELinux, é necessário ter tal arquivo em mãos.

Simples, não?! Agora basta achar tal arquivo “.pp” do Asterisk.

Por padrão, o diretório /usr/share/selinux/targeted/ contém diversos arquivos de pacotes de políticas (*.pp).

Estes arquivos estão inclusos no pacote “selinux-policy”, e são utilizados para construir o arquivo de política.

Em diversas distribuições, como o CentOS e Red Hat, tais arquivos podem estar compactados, porém, a descompactação não se faz necessária para instalação.

Como estamos trabalhando com módulos defaults, o arquivo “.pp” do Asterisk está armazenado neste diretório, portanto, vamos reativá-lo:

# cd /usr/share/selinux/targeted/ # semodule -i asterisk.pp.bz2

Onde: -i = Install

# semodule -l | grep asterisk

Perceba que não precisamos habilitar o módulo novamente, apenas com a instalação do mesmo, ele já fica em modo enable.

Caso o módulo não fique em modo enable, basta executar o comando semodule com a opção “-e”, seguida do nome do módulo, no nosso caso, seria o “asterisk”.

Para mais opções do comando semodule, basta executar:

# man semodule

Auditoria e logs

Com relação à auditoria e depuração de Logs, o SELinux lida muito bem com isso, a começar pelo pacote Setroubleshoot, a junção de diversos aplicativos é uma “Mãe” para qualquer administrador SELinux. A ferramenta demonstra os alertas de AVC do SELinux, e ainda diz qual comando pode corrigir o mesmo.

Falando em AVC, sigla para Access Vector Cache (e não para Acidente Vascular Cerebral), que nada mais é do que alertas de acessos bloqueados sejam elas de aplicação ou usuários do sistema.

Primeiramente, vamos instalar o pacote “Setroubleshoot”.

Obs.: Caso tenha interface gráfica no servidor, o mesmo irá instalar um pequeno utilitário, que alerta toda vez que um AVC acontecer.

# yum install setroubleshoot

Antes de qualquer coisa, vamos gerar o nosso próprio AVC.

– Pergunta: Mas como assim, o nosso próprio AVC?
– Resposta: Bom, esta é uma tarefa fácil, uma simples alteração de porta padrão de um determinado serviço, como o HTTP, por exemplo, deve gerar um Alerta de Access Denied.

Vamos aos testes:

Instale o serviço HTTP no Servidor:

# yum install –y httpd

Abra o arquivo de configuração:

# vim /etc/httpd/conf/httpd.conf Altere a seguinte linha do arquivo: Listen 80

Para:

Listen 8888

Logo, reinicie o serviço HTTP:

# service httpd restart

Pronto, nosso AVC foi gerado com êxito. =)

O primeiro comando para verificação de AVC’s, é o ausearch:

# ausearch –m avc | grep httpd

Onde: -m = message

Saída do comando (resumida):

type=AVC msg=audit(1344678620.633:26191): avc: denied { name_bind } for pid=9429 comm=”httpd” src=8888 scontext=unconfined_u:system_r:httpd_t:s0 tcontext=system_u:object_r:port_t:s0
tclass=tcp_socket

Perceba que a saída do comando demonstra claramente, o motivo dele ter alarmado tal AVC.

– Pergunta: (Bruno, beleza!) Eu “já sei” o que aconteceu pela saída do log, mas agora eu quero que a porta 8888 seja padrão do serviço HTTP, irá continuar gerando AVC’s?
– Resposta: Não, não, porém para que isso aconteça, é necessário informar ao SELinux, que a porta padrão do serviço HTTP mudou.

Existem duas maneiras de se fazer isso, uma é utilizar o comando semanage com a opção “port”, a outra é o que iremos ver abaixo.

Primeiro, vamos utilizar o comando selatert para analisar os logs:

# sealert –a /var/log/audit/audit.log | grep httpd

Onde:

  • -a = Analyze File
  • /var/log/audit/audit.log = O arquivo que será analisado

Saída do comando (resumida):

SELinux is preventing /usr/sbin/httpd from name_bind access on the tcp_socket.
If you want to allow /usr/sbin/httpd to bind to network port 8888
where PORT_TYPE is one of the following: ntop_port_t, http_cache_port_t, http_port_t, puppet_port_t, jboss_messaging_port_t, jboss_management_port_t.
If you believe that httpd should be allowed name_bind access on the tcp_socket by default.
# grep httpd /var/log/audit/audit.log | audit2allow -M mypol

Analisando a saída, perceba que além de detalhar a possível causa do AVC, ele sugere (caso você realmente queira), indicar a alteração de porta padrão do serviço HTTPD para 8888 ao SELinux.

Vamos utilizar o comando que ele sugeriu:

# grep httpd /var/log/audit/audit.log | audit2allow -M mypol

Onde:

  • grep httpd /var/log/audit/audit.log = Indica que iremos filtrar a palavra httpd, mediante o arquivo de logs.
  • audit2allow = Utilizado para Gerar políticas do SELinux para permitir regras, a partir de logs negados.
  • -M = Cria um arquivo de Módulo, com a saída do audit2allow
  • mypol = Nome do arquivo de Módulo, podendo ter qualquer nome.

Saída do comando:

******************** IMPORTANT ***********************
To make this policy package active, execute:
semodule -i mypol.pp

Perceba que a saída do comando deixa bem claro que, caso você queira tornar tal módulo ativo, é necessário que você o instale via semodule.

Porém, caso você liste o diretório corrente, irá perceber que existem 2 arquivos mypol:

# ls

Saída do comando:

mypol.te mypol.pp

O arquivo “mypol.te” indica um tipo de arquivo de execução (Type Enforcement), ou seja, ele tem toda instrução do que será executado/alterado no sistema através do arquivo “mypol.pp”.

Já o arquivo “mypol.pp”, nada mais é o que o pacote de politicas (Package Policy), ou o módulo propriamente dito.

Agora que sabemos qual arquivo instalar, vamos utilizar o semodule para isso:

# semodule -i mypol.pp

Depois de alguns segundos, o arquivo foi instalado com êxito. Será?

Liste os módulos, e veja você mesmo:

# semodule –l | grep ^m

Saída do comando:

mailman 1.7.2
matahari    1.0.0
mediawiki   1.0.0
memcached   1.1.2
milter  1.1.1
modemmanager    1.0.1
mono    1.6.1
mozilla 2.1.1
mpd 1.0.0
mplayer 2.1.0
mrtg    1.8.0
munin   1.7.0
mypol   1.0
mysql   1.11.3

Olha só, o nosso modulo “mypol” instalado e habilitado no sistema. Ou seja, funcionou! =D

Vale reforçar que, a criação de módulos com o “audit2allow”, só é aconselhada caso você saiba realmente o que esteja fazendo, utilizar o “audit2allow” apenas para resolver os alertas de AVC do SELinux, estará causando um grande furo de segurança ao sistema.

Bom galera, é isso.

O artigo foi básico, em relação à complexidade do SELinux, porém, espero que tenha sido útil para aqueles que estão começando com esta tão poderosa ferramenta.

Meu muito obrigado, e até a próxima! =D

Udev – Funcionamento e Regras

 Linux, Redes, Sistemas de Armazenamento  Comentários desativados em Udev – Funcionamento e Regras
maio 302013
 
Detecção e ativação de dispositivos e a função do udev nesse processo

Introdução

Udev (Userspace devfs) é um sistema de arquivos presente desde o kernel 2.6 e substitui o devfs completamente.

É responsável por gerenciar os arquivos de dispositivos do diretório /dev, criando e removendo os mesmos dinamicamente. O udev também tem função do hotplug, trabalhando em conjunto com o HAL (Hardware Abstraction Layer), adicionando os dispositivos conforme são instalados na máquina. Sem ele, seria impossível acessar seu pendrive, webcam e impressora, por exemplo, quando conectados.

Funcionamento

Entendendo como os dispositivos são detectados e adicionados no sistema GNU/Linux.

O sistema GNU/Linux faz uso do kernel e de serviços para detectar e adicionar dispositivos ao sistema, para que os mesmos fiquem disponíveis para uso do usuário e do próprio sistema.

Abaixo, é mostrada a hierarquia no processo de detecção e adição de dispositivos:

Linux: Udev - Funcionamento e Regras

Como visto na figura acima, existe todo um processo até os dispositivos estarem disponíveis para uso do sistema e/ou usuários, que vai desde a detecção do device pelo kernel até a criação de um arquivo de dispositivo no diretório /dev pelo udev.

Todo processo começa com o kernel detectando os dispositivos e exportando informações sobre os mesmos para o sistema de arquivos virtual Sysfs (que está montado no diretório /sys) e ao mesmo tempo, enviando um evento para o daemon do serviço udev.

O evento informa ao udev uma ação no dispositivo, esta ação pode ser um adição, remoção ou alteração de um dispositivo conectado à máquina.

Quando o udev é informado pelo kernel sobre o evento, trata de usar as informações do diretório /sys para identificar o device conectado, carregar o módulo correto e criar um arquivo especial no diretório /dev com exceção da placa de rede que é tratada no kernel.

Aí você pergunta: E o HAL?

Simples, o HAL é um serviço que informa aos programas do sistema se um dispositivo está disponível, foi alterado ou removido a todo tempo.

Na verdade, o HAL já não é essencial para este trabalho, pois algumas distribuições atualmente, conseguem fazer todo este trabalho somente pelo udev, ou em conjunto com o serviço D-Bus. No entanto, para outras distribuições, isso torna-se essencial.

É importante destacar que todo este processo de detectar e ativar os devices explicado anteriormente, não só acontece em Hotplug, ou seja, os dispositivos são instalados com o sistema em uso, mas também em Coldplug, os dispositivos são conectados (instalados) com a máquina desligada e o sistema, quando em uso, detecta-os.

Observe que quem realmente faz o trabalho de hotplug, é o udev.

Os arquivos de dispositivos criados no diretório /dev nada mais são que arquivos especiais, obtidos pela combinação de dois endereços do kernel, um chamado de major number e outro de minor number.

Sendo que:

  • major number → É usado para identificar uma categoria de dispositivos.
  • minor number → Identifica o dispositivo.

Veja na figura abaixo, um exemplo destes números:

Hierarquia dos dispositivos e chaves do udev

Hierarquia dos dispositivos

Antes de começar a trabalhar com regras no udev, é necessário saber como o kernel representa os dispositivos em sua estrutura. O kernel do Linux organiza e representa os dispositivos conectados à máquina em uma estrutura de árvore, ou seja, existe uma hierarquia onde cada device é “filho” de um device “pai”.

Toda esta estrutura está exposta no diretório /sys contendo informações de cada device. Para poder ter mais detalhes sobre os devices, use o comando udevadm e poderá ver todas as chaves dos dispositivos.

Veja o exemplo do arquivo de dispositivo /dev/usb/lp0 da minha máquina, que representa a impressora, rodando o comando abaixo como root:

# udevadm info -a -p $(sudo udevadm info -q path -n /dev/usb/lp0)

A saída do comando mostra bem a organização e hierarquia do device. Sendo que /dev/usb/lp0 é filho do device “usb”, e neste device o kernel nomeia-o de “lp0”, justamente o nome dado pelo udev, que por sua vez é filho do device pai, também chamado de “usb” e o kernel nomeia-o de “2-2:1.1”, carregando o driver “usblp”, que por sua vez é filho do device “pci” e o kernel nomeia-o neste subsistema de “0000:00:1d.0”, carregando o driver “uhci_hcd”.

Veja o exemplo do arquivo de dispositivo /dev/sda que representa o primeiro disco rígido da minha máquina:

# udevadm info -a -p $(sudo udevadm info -q path -n /dev/sda)

O device /dev/sda nesta hierarquia, é filho do device “block”, ou seja, é um dispositivo de bloco e o kernel nomeia-o de “sda”, que por sua vez, é filho do device chamado de “scsi”, e o kernel nomeia-o de “0:0:0:0”, carregando o driver “sd”, que por sua vez é filho do device chamado também de “scsi”, e o kernel nomeia-o de “target0:0:0”.

Observe que, na hierarquia mostrada na saída do comando udevadm, os devices de baixo são pais dos de cima “filhos”.

As chaves do udev

Chaves no udev são informações de dispositivos e podem ser classificadas em dois tipos, existindo as chaves de combinação e de atributos. Ambas serão abordadas a seguir, e o seu uso torna-se necessário para aplicar as regras do udev.

As chaves de combinação mais usadas, são as listadas abaixo:

  • KERNEL → Esta chave informa o nome atribuído pelo kernel ao dispositivo em questão;
  • SUBSYSTEM → Chave que informa o tipo de dispositivo, seja o dispositivo pai ou filho;
  • DRIVER → Chave que informa o driver para o dispositivo;
  • ATTR → Esta chave tem informações adicionais sobre o dispositivo;
  • OWNER → Usuário que será o proprietário do dispositivo criado no /dev;
  • GROUP → Grupo do dispositivo criado no /dev;
  • MODE → Atribui a umask padrão para o dispositivo criado em /dev.

Além das chaves de combinação já vistas, é possível usar outras descritas abaixo:

  • NAME → Esta chave contém o nome que será usado para o dispositivo;
  • SYMLINK → Nesta chave, configura-se um link simbólico;
  • RUN → Adiciona um programa que será executado;
  • ACTION → Ação do evento do dispositivo, se o dispositivo está sendo conectado, removido ou alterado.

Chaves de combinação KERNELS, SUBSYSTEMS e DRIVERS, contêm informações similares às chaves de combinação apresentadas acima, no entanto, estas chaves de combinação são usadas em dispositivos pais (parent devices).

As chaves de atributo ATTR, contêm informação adicional a um dispositivo e a chave de atributo ATTRS é similar a ATTR, no entanto, é usada em devices pais (parent devices).

A observação é que em uma regra, não pode ser atribuído mais de uma chave de atributo e/ou de combinação de dispositivos “pai” (device parent) junto à chave de combinação “filho” e nem combinar chaves de atributos de diferentes dispositivos pais em um único dispositivo pai. Caso isso aconteça, a regra não irá funcionar.

Para a regra funcionar, podemos colocar uma ou mais chaves de combinação “filho” seguida de uma chave de atributo ou de combinação “pai” na mesma regra e/ou, caso queira atribuir mais de uma chave de atributo “pai”, é necessário informar o dispositivo a qual ela pertence, basta usar a chave de combinação “pai” SUBSYSTEMS.

Se ficou confuso, na próxima página irei exemplificar para ter um melhor entendimento.

Para aplicar as regras, além das chaves já mencionadas, podemos fazer uso de strings e é necessário usar operadores. Veja abaixo as strings e operadores que podemos usar.

Strings que podem ser usadas nas regras:

  • * → Corresponde a tudo naquela posição (é similar ao coringa asterisco).
  • ? → Qualquer caractere naquela posição.
  • [] → Corresponde a qualquer caractere especificado dentro dos colchetes.

    Por exemplo, a sequência de caracteres ‘tty[SR]’ iria corresponder tanto ‘ttyS’ quanto a ‘ttyR’. Você pode também especificar intervalos usando a faixa através do caractere ‘-‘. Se o primeiro caractere após o ‘[‘ é um ‘!’, há uma exceção.

Operadores mais usados nas regras:

  • == → Compara se é igual (atribui uma valor de igualdade);
  • != → Compara se é diferente (atribui um valor de diferença);
  • = → Atribui um valor à chave (é usado quando se quer mudar o nome do device, por exemplo);
  • += → Adiciona um valor à chave e pode manter uma lista de entradas – Pode, por exemplo, usar na chave RUN e especificar vários comandos.

Depois de toda esta explicação, vamos começar a aplicar as regras na próxima página.

Regras do udev

O udev é muito poderoso quanto à aplicação das regras, pois permite desde nomear um dispositivo até executar aplicações, e/ou scripts quando conectamos ou desconectamos, ou quando o dispositivo é alterado.

Para aplicar tais regras, é necessário ter informações obtidas através das chaves de cada device.

Os arquivos que contém as regras do udev estão contidos no diretório /etc/udev/rules.d e devem ter a extensão “.rules”, caso algum arquivo dentro do diretório não use essa extensão, o seu conteúdo não será processado.

Eles são lidos em ordem numérico alfabética, por exemplo: se dentro do diretório /etc/udev/rules.d, temos os arquivos “025_usb- regras.rules” e “035_usb-regras.rules”, o arquivo “025_usb-regras.rules” será lido antes que o “035_usb-regras.rules”.

Agora, sintaxe das regras e exemplos de regras que funcionam e não funcionam.

Cada arquivo com extensão “.rules” tem regras que seguem a seguinte sintaxe:

<chave de combinação>, <chave de combinação e ou chave de atributo>, <Ação>

Para obter as informações de cada chave dos devices, usamos o comando udevadm para pegar um relatório.

Não vou entrar em detalhes de uso do comando, mas deixo o link para o manual:

Será usado, para extrair o relatório, a opção “info” que é utilizada para obter informações e “-p”, que indica a localização do dispositivo, e “-a” irá listar informações das propriedades do dispositivo.

Vou listar as propriedades do arquivo de dispositivo /dev/sdc1 que é meu pendrive da SanDisk, usando o comando udevadm como root:

# udevadm info -a -p $(udevadm info -q path -n /dev/sdc1)

looking at device '/devices/pci0000:00/0000:00:1d.7/usb1/1-8/1-8:1.0/host4/target4:0:0/4:0:0:0/block/sdc/sdc1':
  KERNEL=="sdc1"
  SUBSYSTEM=="block"
  DRIVER==""
  ATTR{partition}=="1"
  ATTR{start}=="2048"
  ATTR{size}=="7852032"
  ATTR{ro}=="0"
  ATTR{alignment_offset}=="0"
  ATTR{discard_alignment}=="0"
  ATTR{stat}=="      54      112      426       36        5        1       48        0        0       36       36"
  ATTR{inflight}=="       0        0"
looking at parent device '/devices/pci0000:00/0000:00:1d.7/usb1/1-8/1-8:1.0/host4/target4:0:0/4:0:0:0/block/sdc':
  KERNELS=="sdc"
  SUBSYSTEMS=="block"
  DRIVERS==""
  ATTRS{range}=="16"
  ATTRS{ext_range}=="256"
  ATTRS{removable}=="1"
  ATTRS{ro}=="0"
  ATTRS{size}=="7856127"
  ATTRS{alignment_offset}=="0"
  ATTRS{discard_alignment}=="0"
  ATTRS{capability}=="51"
  ATTRS{stat}=="     251     1491     2002      216        5        1       48        0        0      216      216"
  ATTRS{inflight}=="       0        0"
  ATTRS{events}=="media_change"
  ATTRS{events_async}==""
  ATTRS{events_poll_msecs}=="-1"
looking at parent device '/devices/pci0000:00/0000:00:1d.7/usb1/1-8/1-8:1.0/host4/target4:0:0/4:0:0:0':
  KERNELS=="4:0:0:0"
  SUBSYSTEMS=="scsi"
  DRIVERS=="sd"
  ATTRS{device_blocked}=="0"
  ATTRS{type}=="0"
  ATTRS{scsi_level}=="0"
  ATTRS{vendor}=="SanDisk "
  ATTRS{model}=="Cruzer Blade"
  ATTRS{rev}=="8.02"
  ATTRS{state}=="running"
  ATTRS{timeout}=="30"
  ATTRS{iocounterbits}=="32"
  ATTRS{iorequest_cnt}=="0x2763"
  ATTRS{iodone_cnt}=="0x2763"
  ATTRS{ioerr_cnt}=="0x19"
  ATTRS{modalias}=="scsi:t-0x00"
  ATTRS{evt_media_change}=="0"
  ATTRS{queue_depth}=="1"
  ATTRS{queue_type}=="none"
  ATTRS{max_sectors}=="240"
looking at parent device '/devices/pci0000:00/0000:00:1d.7/usb1/1-8/1-8:1.0/host4/target4:0:0':
  KERNELS=="target4:0:0"
  SUBSYSTEMS=="scsi"
  DRIVERS==""
looking at parent device '/devices/pci0000:00/0000:00:1d.7/usb1/1-8/1-8:1.0/host4':
  KERNELS=="host4"
  SUBSYSTEMS=="scsi"
  DRIVERS==""
looking at parent device '/devices/pci0000:00/0000:00:1d.7/usb1/1-8/1-8:1.0':
  KERNELS=="1-8:1.0"
  SUBSYSTEMS=="usb"
  DRIVERS=="usb-storage"
  ATTRS{bInterfaceNumber}=="00"
  ATTRS{bAlternateSetting}==" 0"
  ATTRS{bNumEndpoints}=="02"
  ATTRS{bInterfaceClass}=="08"
  ATTRS{bInterfaceSubClass}=="06"
  ATTRS{bInterfaceProtocol}=="50"
  ATTRS{modalias}=="usb:v0781p5567d0200dc00dsc00dp00ic08isc06ip50"
  ATTRS{supports_autosuspend}=="1"

Veja que não postei toda a saída do comando pois é muito longa. Agora, abaixo mostro duas regras:

ACTION==”add”, SUBSYSTEM==”block”, KERNEL==”sd??”, ATTRS{vendor}==”SanDisk”, DRIVERS==”usb-storage”, SYMLINK+=”PENDRIVE”
ACTION==”add”, SUBSYSTEM==”block”, KERNEL==”sd??”, ATTRS{vendor}==”SanDisk”, SYMLINK+=”PENDRIVE”

Ambas as regras têm a ação de criar um link para a partição do pendrive. No entanto, somente a segunda regra irá funcionar.

Explicação da primeira regra:

  • 1º → É conferido se o dispositivo que está sendo conectado;
  • 2º → É conferido se o dispositivo conectado é do tipo bloco (armazenamento), ou seja, se filho do dispositivo de bloco;
  • 3º → É conferido se o nome do dispositivo atribuído pelo kernel na chave de combinação KERNEL “filho” é igual a o informado na regra;
  • 4º → Verifica em um dos atributos “pais” se existe o atributo com valor SanDisk, isso garante que a regra só será executada se o pendrive for do fabricante SanDisk;
  • 5º → Verifica se o driver carregado em um dos devices parents é igual ao especificado;
  • 6º → Caso tudo esteja certo na regra, o link chamado PENDRIVE é atribuído à partição do pendrive.

Mesmo toda informação conferindo na primeira regra, não pode funcionar, pois foi atribuído junto à chave de combinação do dispositivo filho (como já foi informado na segunda página), uma chave de atributo (ATTRS) e outra de combinação (DRIVERS) de dispositivos “pais”.

Deixo mais uma vez claro, que a regra não irá funcionar caso seja atribuído mais de uma chave de atributo ou de combinação de um parent device junto à uma chave de combinação de um device filho.

A segunda regra tem quase todos as chaves da primeira regra, com exceção da chave de combinação DRIVERS de um dispositivo pai. E esta regra irá funcionar por que apenas uma chave, seja de atributo ou de combinação (no exemplo, uma foi de atributo) de dispositivo pai está atribuída junto às chaves de combinação do dispositivo filho que são ACTION, SUBSYSTEM e KERNEL.

Agora, veja um exemplo de regra usada para executar um script:

ACTION==”add”, SUBSYSTEM==”block”, KERNEL==”sd??”, SUBSYSTEMS==”usb”, RUN+=”/usr/local/bin/usb-mount.sh”

Veja que esta regra é similar às duas mostradas anteriormente. No entanto, o valor atribuído à chave de combinação SUBSYSTEM do dispositivo filho, indica que deve ser aplicada a um dispositivo de bloco, ou seja, de armazenamento.

E a chave de combinação (do device parent) SUBSYSTEMS, indica que a regra só será aplicada a dispositivos pais do tipo USB; dessa forma, a regra só será aplicada a um pendrive, HD externo e/ou cartão de memória, e não a discos rígidos internos, por exemplo.

Veja abaixo, o conteúdo do script /usr/local/bin/usb-mount.sh:

#!/bin/bash
usb="/dev/"$(ls -1 /sys/block/"$(ls -1 /sys/block |grep sd |tail -1)" |grep sd |tail -1)""
tipo=$(blkid -o list "$usb" |awk -F" " '{print $2}' |tail -1)
label=$(blkid -o list "$usb" |awk -F" " '{print $3}' |tail -1)
dir="/media/"$label""
[ -d "$dir" ]&& sleep 1 || mkdir "$dir"
if [ "$tipo" = "ext3" ];then
mount -t "$tipo" -o relatime,noexec,rw,nodev,user "$usb" "$dir"
elif [ "$tipo" = "ext4" ];then
mount -t "$tipo" -o relatime,noexec,rw,nodev,user "$usb" "$dir"
elif [ "$tipo" = "vfat" ];then
mount -t "$tipo" -o relatime,noexec,rw,user,umask=0022,uid=1000,gid=1000 "$usb" "$dir"
elif [ "$tipo" = "ntfs" ];then
mount -t ntfs-3g -o relatime,noexec,rw,user,umask=0022,uid=1000,gid=1000 "$usb" "$dir"
elif [ "$tipo" = "xfs" ];then
mount -t "$tipo" -o relatime,noexec,rw,nodev,user "$usb" "$dir"
elif [ "$tipo" = "jfs" ];then
mount -t "$tipo" -o relatime,noexec,rw,nodev,user "$usb" "$dir"
elif [ "$tipo" = "btrfs" ];then
mount -t "$tipo" -o relatime,noexec,rw,nodev,user "$usb" "$dir"
fi

A finalidade do script é montar o pendrive, HD externo ou cartões de memória desabilitando a execução de executáveis, dando mais segurança quando “espetar” um destes dispositivos na máquina (afinal, nunca se sabe o que pode ter em um HD externo ou pendrive de alguém, não é verdade?) evitando a execução de vírus e outras pragas.

Podemos também renomear dispositivos como placas de rede. Para ver como fazer isso, veja a saída do comando udevadm para o dispositivo Wlan0 e em seguida, irei mostrar uma regra para isso:

# udevadm info -a -p /sys/class/net/wlan0

looking at device '/devices/pci0000:00/0000:00:1d.7/usb1/1-8/1-8:1.0/net/wlan0':
  KERNEL=="wlan0"
  SUBSYSTEM=="net"
  DRIVER==""
  ATTR{addr_assign_type}=="0"
  ATTR{addr_len}=="6"
  ATTR{dev_id}=="0x0"
  ATTR{ifalias}==""
  ATTR{iflink}=="5"
  ATTR{ifindex}=="5"
  ATTR{type}=="1"
  ATTR{link_mode}=="1"
  ATTR{address}=="00:1a:3f:7c:2e:f4"
  ATTR{broadcast}=="ff:ff:ff:ff:ff:ff"
  ATTR{carrier}=="0"
  ATTR{dormant}=="0"
  ATTR{operstate}=="down"
  ATTR{mtu}=="1500"
  ATTR{flags}=="0x1003"
  ATTR{tx_queue_len}=="1000"
  ATTR{netdev_group}=="0"
looking at parent device '/devices/pci0000:00/0000:00:1d.7/usb1/1-8/1-8:1.0':
  KERNELS=="1-8:1.0"
  SUBSYSTEMS=="usb"
  DRIVERS=="ath9k_htc"
  ATTRS{bInterfaceNumber}=="00"
  ATTRS{bAlternateSetting}==" 0"
  ATTRS{bNumEndpoints}=="06"
  ATTRS{bInterfaceClass}=="ff"
  ATTRS{bInterfaceSubClass}=="00"
  ATTRS{bInterfaceProtocol}=="00"
  ATTRS{modalias}=="usb:v0CF3p7015d0202dcFFdscFFdpFFicFFisc00ip00"
  ATTRS{supports_autosuspend}=="0"

O adaptador USB está recebendo este nome de “wlan0” porque, quando o sistema o detectou, o udev atribuiu a regra abaixo:

SUBSYSTEM==”net”, ACTION==”add”, DRIVERS==”?*”, ATTR{address}==”00:1a:3f:7c:2e:f4″, ATTR{dev_id}==”0x0″, ATTR{type}==”1″, KERNEL==”wlan*”, NAME=”wlan0″

Mas, com estas informações da saída do comando udevadm podemos mudar o nome do device para, por exemplo, Wireless0 como mostra a regra abaixo:

SUBSYSTEM==”net”, ACTION==”add”, DRIVERS==”?*”, ATTR{address}==”00:1a:3f:7c:2e:f4″, ATTR{dev_id}==”0x0″, ATTR{type}==”1″, KERNEL==”*”, NAME=”wireless0″

Explicando a regra:

  • 1º → É verificado se o dispositivo filho conectado é do tipo net (rede);
  • 2º → Verifica se o dispositivo acabou de se conectado;
  • 3º → Na chave de combinação DRIVERS informa que pode ser usado qualquer driver para o respectivo device parent;
  • 4º → Na chave de atributo ATTR{address} é verificado o endereço MAC address do device;
  • 5º e 6º → São verificados mais duas chaves de atributos da mesma (note que ambas foram atribuídas junto ao dispositivo filho, por isso a regra funciona);
  • 7º → Na chave KERNEL é verificado qual o nome atribuído pelo kernel, no exemplo informei que pode ser qualquer um;
  • 8º → Na última chave de combinação informei o novo nome do dispositivo que é wireless0.

Podemos fazer muitas personalizações, além das quais já foram mostradas, podemos, por exemplo, automatizar um processo de backup toda vez que o dispositivo for conectado à máquina de forma similar à regra acima, que executa um script.

Após aplicar uma regra em um dos arquivos com extensão “.rules”, torna-se necessário reiniciar o serviço do udev para as alterações entrarem em vigor (pelo menos nas distribuições Debian e CentOS, por exemplo).