Encontrar arquivos de sistema já é um assunto bem corriqueiro nos nossos artigos. Porém, hoje iremos abordar uma outra forma de localizar arquivos em seu sistema Linux apresentando mais uma ferramenta. FHSO FHS (do inglês Filesystem Hierarchy Standard, ou Hierarquia Padrão de Sistemas de arquivos) é o padrão que define a localização dos arquivos e diretórios. Entretanto, já abordamos o assunto FHS neste quadro você pode dissecar ainda mais esse assunto acessando os post’s abaixo: Localizando arquivosVocê já conheceu as funcionalidades do comando find (objetivo 103.3), porém, iremos neste artigo conhecer o comando locate. Sua utilização é simples: localizar arquivos a partir de um banco de dados. Esse banco de dados deve ser atualizado periodicamente, com o comando updatedb (executado com o superusuário root). Exemplo: # locate *.odt
O arquivo de configuração do updatedb é o /etc/updatedb.conf. Nele, constam informações como quais diretórios e sistemas de arquivos serão ignorados na atualização do banco de dados. WhichProcura por um comando em diretórios e na variável de ambiente PATH. # which yum
WhereisLocaliza o arquivo binário, o código-fonte e a página do manual para um comando. # whereis rpm
|
Prosseguindo nos objetivos da Certificação LPI, hoje vamos para a
segunda parte dessa série de artigos. Para poder ver como começamos
esse assunto, só clicar aqui. Vamos lá?!
uniq
Esse comando mostra o conteúdo, suprimindo linhas sequenciais
repetidas. Utilizando a opção -u, mostra apenas as linhas que não se
repetem.
cut
Imensamente utilizado em arquivos de script, corta (ou seja, exibe)
colunas ou campos selecionados a partir de um ou mais arquivos. O
arquivo-fonte não é modificado. Extremamente útil quando se necessita um
acesso rápido a um recorte vertical de um arquivo. Por padrão, os
recortes são delimitados por um caracter tab.
Opções frequentemente utilizadas:
- -b list – Exibe os bytes nas posições list;
- -c list – Exibe os caracteres nas colunas list;
- -d delim – Define o delimitador de campos para -f;
- -f list – Exibe os campos de list.
Exemplificando:
Visualizar os nomes de usuários (no primeiro campod delimitado por vírgula) de /etc/passwd:
# cut -d: -f1 /etc/passwd
paste
Concatena arquivos lado a lado, na forma de colunas:
# paste arquivo1.txt arquivo2.txt
join
Semelhante ao paste, entretanto trabalha especificando campos no formato join -1 CAMPO -2
CAMPO <arquivo um> <arquivo dois>, sendo, CAMPO é o
número indicando qual campo nos respectivos arquivos (primeiro e
segundo) deve ser correlacionado. Por exemplo, relacionar as linhas de
arq1, cujo primeiro campo (coluna 1) seja igual ao primeiro campo de
arq2:
# join -1 1 -2 1 arq1 arq2
sort
Ordena alfabeticamente um lista de arquvios. Utilizando a opção -n, ordena-se numericamente e -r inverte o resultado.
fmt
Formata o texto com uma extensão especificada, preenchendo linhas e
removendo caracteres da nova linha. Se forem especificados múltiplos
arquivos na linha de comando, eles serão concatenados.
Opções interessantes na utilização do comando descrito acima:
- -w : Indica o número de caracteres por linha;
- -s: Quebra linhas grandes, mas não as preenche;
- -u: Um espaço entre palavras e dois espaços entre sentenças.
pr
O comando pr imprime na tela o arquivo com paginação. Este comando
formata um arquivo texto para uma saída paginada com cabeçalho, margens e
largura definidos.
As opções mais utilizadas são:
- -a: Exibe colunas no sentido horizontal;
- -d: Expecifica espaçamento duplo;
- -l n: Formata o número de linhas na página para o valor n;
- -o n: Especifica o número de espaços da margem esquerda.
tr
Converte caracteres. Sua utilização difere-se dos comandos citados
anteriormente, pois os mesmos utilizam como entrada padrão ou indicando
um arquivo. O comando tr usa apenas a entrada padrão.
Exemplo: converter todas as letras minúsculas para maiúsculas:
# echo abc | tr ‘[a-z]‘ ‘[A-Z]‘
Com isso, encerramos mais um objetivo. No próximo artigo iremos abordar sobre o gerenciamento básico de arquivos.
***Artigo de Deividson Ludolf
|
Neste artigo, abordarei o backup e a recuperação do MBR em Linux.
Este tipo de backup é especialmente útil a usuários que têm vários
sistemas operacionais instalados em um mesmo computador (multi-boot). A
recuperação do MBR a partir do backup pode também ser utilizada para
eliminar alguns tipos de vírus que afetam o MBR, como alguns bootkits,
ou, ainda, para recuperar o MBR caso ele venha a ser corrompido,
alterado ou mesmo perdido.
Em sistemas multi-boot, tendo o backup do MBR previamente feito e
atualizado, é possível instalar ou reinstalar o MS-Windows após os
outros sistemas operacionais, não sendo necessário instalá-lo primeiro
para evitar que ele sobrescreva o MBR, impedindo a inicialização do
computador a partir de outros sistemas operacionais.
1. O MBR
O MBR (Master Boot Record ou, em português, Registro Mestre de
Inicialização) corresponde aos 512 bytes armazenados no primeiro setor
do HD master do computador. Resumidamente falando, são os primeiros 512
bytes do HD master. O MBR armazena, estruturadamente, os seguintes
dados:
- Os primeiros 446 bytes armazenam o Setor de Boot;
- Os 64 bytes seguintes armazenam a Tabela de Partições do HD;
- Os 2 bytes finais são reservados para Assinatura.
Ao ligar o computador, o sistema realiza, nesta ordem, os seguintes passos:
- Executa um teste automático dos componentes eletrônicos da placa-mãe
do computador, este teste chama-se POST (Power On Self Test);
- Carrega dados do BIOS (Basic Input Output System) e faz a reprogramação do suporte de I/O;
- Lê o MBR e executa o carregador de boot (boot loader) registrado nos
primeiros 446 bytes do MBR; o carregador de boot inicializará o sistema
operacional adequado, ou o selecionado pelo usuário em computadores com
multi-boot.
2. Problemas mais frequentes relacionados ao MBR
Os problemas mais frequentes que afetam o MBR são:
- Infecção ou corrupção do MBR em virtude da ação de vírus fazendo,
muitas vezes, com que o seu HD pareça estar em branco (parecendo uma
perda total dos dados armazenados no HD) ou impedindo a inicialização do
sistema; há também um tipo especial de vírus, conhecidos como bootkits,
que ficam gravados no MBR e podem ser inicializados antes do sistema
operacional da máquina, permanecendo em execução após a inicialização do
sistema operacional, e sendo mais difíceis de detectar;
- Crashs do MBR que ocorrem, em muitos casos, devido a quedas de energia elétrica;
- Modificação do Setor de Boot do MBR quando da instalação do
MS-Windows em computadores com multi-boot, impedindo o boot a partir de
outros sistemas operacionais previamente instalados no mesmo computador.
3. Backup do MBR em Linux
O backup do MBR deve ser feito sempre em uma mídia externa. O mais
comum é fazê-lo em um pendrive. Nunca faça e/ou mantenha o backup do MBR
no próprio HD da máquina, pois, em caso de problemas com o MBR, o seu
backup não terá nenhuma utilidade!
Mantenha o seu backup do MBR atualizado. Sempre após reparticionar o
seu HD (ou excluir alguma partição existente), redimensionar partições
existentes, reformatar alguma partição com um tipo de sistema de
arquivos diferente do anterior ou, ainda, instalar ou reinstalar algum
sistema operacional ou carregador de boot, teste para verificar se tudo
está funcionando conforme o planejado e, em caso positivo, faça ou
atualize o backup do MBR do computador.
O backup do MBR pode ser feito a partir do Linux já instalado em seu HD ou a partir de um Live CD da distro Linux
de sua preferência. Neste último caso, não será necessário instalá-lo
no computador, bastando apenas inicializar o computador a partir do Live
CD.
Para fazer o backup do MBR em um pendrive, no Linux, siga os seguintes passos:
- Abra o Terminal;
- Logue-se como usuário root utilizando o comando su;
- Digite e execute um dos seguintes comandos, conforme o tipo do HD master de seu computador:
# dd if=/dev/sda of=/media/USB/MBR.bkp bs=512 count=1
# dd if=/dev/hda of=/media/USB/MBR.bkp bs=512 count=1
Pronto! O backup do MBR de seu computador já está salvo no pendrive.
Importante! Note que, em minha máquina, o backup do
MBR (arquivo MBR.bkp) foi salvo no pendrive montado no ponto de montagem
(diretório) /media/USB/. Verifique, em seu computador, a localização
correta do ponto de montagem (diretório) de seu pendrive.

Se você quiser verificar o tipo de arquivo gerado pelo processo de
backup do MBR, utilize o comando a seguir (não é necessário estar logado
como usuário root para executar este comando):
$ file /media/USB/MBR.bkp
Veja a saída do comando file sobre o arquivo de backup do MBR gerado
em minha máquina, na qual tenho dual-boot com os sistemas operacionais openSUSE Linux e MS-Windows Server 2003:

4. Recuperação do MBR com Linux em Live CD
Para recuperar o MBR de seu computador, após ocorrer algum problema
com o mesmo, será necessário inicializar a máquina a partir do Live CD
da distro Linux de sua preferência e ter em mãos a mídia externa, um
pendrive, no qual está salvo o backup mais atualizado do MBR.
Após inicializar a máquina a partir do Live CD do Linux, e ter
montado o pendrive contendo o backup do MBR, execute os seguintes
comandos para recuperar o MBR de seu computador:
- Abra o Terminal;
- Logue-se como usuário root utilizando o comando su;
- Digite e execute um dos seguintes comandos, conforme o tipo do HD master de seu computador:
# dd if=/media/USB/MBR.bkp of=/dev/sda
# dd if=/media/USB/MBR.bkp of=/dev/hda
Pronto! O MBR de seu computador já está recuperado. Agora,
reinicialize a máquina a partir do HD (não do Live CD do Linux) e
verifique se o boot, ou multi-boot, do sistema está funcionando
corretamente e se todas as partições do HD foram detectadas com sucesso.
Importante! Note que, em minha máquina, o backup do MBR (arquivo
MBR.bkp) foi salvo no pendrive montado no ponto de montagem (diretório)
/media/USB/. Verifique, em seu computador, a localização correta do
ponto de montagem (diretório) de seu pendrive, bem como o nome correto
do arquivo de backup do MBR salvo no pendrive.

5. Instalação do MS-Windows após o Linux em computadores com multi-boot
Quando o MS-Windows é instalado ou reinstalado após outros sistemas
operacionais em um computador com multi-boot, a instalação do MS-Windows
simplesmente sobrescreve o Setor de Boot do MBR, registrando o seu
próprio carregador de boot, impedindo que computador boot a partir dos
sistemas operacionais previamente instalados.
Para instalar ou reinstalar o MS-Windows após o ter Linux previamente
instalado em um mesmo computador e poder continuar utilizando o
multi-boot para escolher qual sistema operacional será utilizado, siga
os seguintes passos:
- Faça o backup do MBR;
- Instale ou reinstale o MS-Windows mesmo após ter o Linux instalado na máquina;
- Reinicialize o computador a partir do Live CD do Linux e recupere o
backup do MBR, executando no Terminal do Linux, como usuário root, um
dos comandos abaixo, conforme o tipo de HD master de sua máquina:
# dd if=/media/USB/MBR.bkp of=/dev/sda bs=446 count=1
# dd if=/media/USB/MBR.bkp of=/dev/hda bs=446 count=1
- Reinicialize normalmente o computador a partir do HD;
- Caso o carregador de boot (de multi-boot) anterior à instalação ou
reinstalação do MS-Windows não liste o MS-Windows, basta entrar no
Linux, que estava previamente instalado em sua máquina, e instale ou
atualize a configuração do carregador de boot (de multi-boot) do Linux,
geralmente o GRUB, para que o MS-Windows seja detectado e adicionado à
lista de opções de sistemas operacionais bootáveis do carregador de boot
(de multi-boot).
Pronto! Você já tem o MS-Windows instalado ou reinstalado e o computador em multi-boot.
Importante! Estes procedimentos são válidos se você
somente instalar ou reinstalar o MS-Windows, não são aplicáveis caso
altere o layout (esquema de particionamento) do HD da máquina. Note que,
em minha máquina, o backup do MBR (arquivo MBR.bkp) foi salvo no
pendrive montado no ponto de montagem (diretório) /media/USB/.
Verifique, em seu computador, a localização correta do ponto de montagem
(diretório) de seu pendrive, bem como o nome correto do arquivo de
backup do MBR salvo no pendrive. *** Artigo de Roberto Rodrigues Junior
|
Olá, pessoal! Hoje eu resolvi fazer algo que estava no meu
dashboard há um bom tempo: explicar o básico para se levantar uma
aplicação Rails e Nginx em um servidor Linux. Minha intenção é passar os
caminhos básicos de como configurar o Nginx, o Passenger e o RVM em um
servidor Linux. O processo é relativamente simples.
Antes de começar o processo de instalação, é necessário que você
possua acesso de administrador do sistema, ou seja, acesso ao usuário
root. Caso você não possua esse nível de acesso, os comandos abaixo não
darão certo.
Algumas distribuições não permitem o acesso direto ao usuário root,
exigindo que você tenha uma conta de usuário normal e só então, a partir
dele, mudar o nível de acesso para o root, isso normalmente é feito
através do comando sudo. Se for o seu caso, sugiro rodar o comando sudo su - que fará você mudar o nível de privilégios para administrador do sitema, aí é só seguir os passos abaixo.
Instalando o RVM
O processo de instalação do RVM não possui muitos mistérios, basta seguir o processo de instalação disponível no site do RVM. Mas para que você não tenha dúvidas, segue a linha a ser executada:
curl -L https://get.rvm.io | bash -s stable --ruby
Este comando fará a instalação do RVM no sistema, e logo em seguida a
instalação da a última versão do Ruby disponível (no momento, a versão
mais atual é a 1.9.3-p194).
A instalação do RVM requer o uso do curl , portanto é preciso ter ele instalado, verifique como instalar esse software em sua distribuição/versão de Linux.
Caso ocorra algum erro na instalação do Ruby é bem provável que seja
pela ausência de alguma dependência na distribuição utilizada. Para
fazer um levantamento e identificar se falta algo, rode o comando rvm requirements . Siga os procedimentos informados e após terminar tente novamente instalar o Ruby :
rvm install 1.9.3 #ou a versão que deseja
Instalando o Passenger
Esse talvez seja o passo mais fácil. O passenger é uma gem que por
sua vez possui um script que auxilia em todo o processo, como estamos
fazendo a instalação em um ambiente servidor nós podemos instalar a gem
sem os arquivos de documentação:
gem install passenger --no-ri --no-rdoc
Pronto, agora já temos o passenger instalado. Entretanto, ele sozinho
não fará muita coisa por você, ou melhor, por sua aplicação. Vamos
agora instalar o Nginx.
Instalando o Nginx
Infelizmente não podemos utilizar o Nginx provido pela distribuição
Linux que você está usando, isso porque o Nginx não possui o suporte a
módulos, algo que o Apache tem, que seria a possibilidade de instalar o
Nginx e depois apenas os módulos que necessários (php, ruby, etc.). Para
o nosso caso será necessário (re)compilar o Nginx habilitando o suporte
ao Passenger e é justamente isso que vamos abordar no próximo tópico.
Instalando o Nginx com suporte ao Passenger (usando o assistente)
Nós utilizaremos o instalador provido pela gem passenger .
Esse script fará todo o trabalho sujo por você, baixando o Nginx,
configurando e compilando. Esse processo é recomendado para aqueles que
estão começando e querem algo funcional de forma simples. Vamos lá
então:
passenger-install-nginx-module
O script fará uma série de perguntas, vou documentar cada uma delas e explicar para que você se sinta seguro.
Logo no início será apresentado um texto informativo sobre o que será
realizado durante o processo de instalação. Nessa primeira parte será
solicitado que você pressione <ENTER> para continuar, ou <CTRL>-C caso tenha se arrependido e queira abortar a instalação. É óbvio que vamos continuar, então, <ENTER> .
Logo em seguid,a o script fará um checklist sobre todas as
dependências necessárias para compilar o Passenger e o Nginx. Dntre os
itens verificados estão: compilador, make, curl ou wget, headers do Ruby
(bibliotecas necessárias para compilação), rubygems, rack, openssl,
zlib, etc. Caso algum deles esteja faltando, o script fará o alerta e
mostrará o que fazer para resolver as dependências. Se for o seu caso,
instale as dependências e depois volte a executar o comando passenger-install-nginx-module novamente.
Após o checklist de dependências, o script solicitará qual o método você utilizará para instalar o Nginx + Passenger:
Automatically download and install Nginx?
Nginx doesn't support loadable modules such as some other web servers do,
so in order to install Nginx with Passenger support, it must be recompiled.
Do you want this installer to download, compile and install Nginx for you?
1. Yes: download, compile and install Nginx for me. (recommended)
The easiest way to get started. A stock Nginx 1.0.10 with Passenger
support, but with no other additional third party modules, will be
installed for you to a directory of your choice.
2. No: I want to customize my Nginx installation. (for advanced users)
Choose this if you want to compile Nginx with more third party modules
besides Passenger, or if you need to pass additional options to Nginx's
'configure' script. This installer will 1) ask you for the location of
the Nginx source code, 2) run the 'configure' script according to your
instructions, and 3) run 'make install'.
Whichever you choose, if you already have an existing Nginx configuration file,
then it will be preserved.
Selecione a opção 1 e pressione <ENTER> . Nesta
opção será feito o download e compilação do Nginx com suporte ao
Passenger pelo próprio script. Logo após será feito um novo
questionamento, desta vez sobre qual será o local onde o Nginx será
instalado. Eu prefiro escolher um local diferente por questões de gosto e
costume, em meus processos de instalação eu utilizo o path /usr/local/nginx – fique a vontade para escolher qual deles utilizar.
Where do you want to install Nginx to?
Please specify a prefix directory [/opt/nginx]: /usr/local/nginx
Faça a sua escolha e pressione <ENTER> para dar início a compilação, agora é só esperar finalizar o processo.
Ao finalizar a compilação e instalação do Nginx, o script exibe
alguns parâmetros que devem ser definidos na configuração do Nginx para
ativar o Passenger. Nós não precisamos nos preocupar com isso agora,
pois o script de instalação já injetou essas diretivas no arquivo de
configuração do Nginx, mas vale a pena registrar para não ter dúvidas:
Nginx with Passenger support was successfully installed.
The Nginx configuration file (/usr/local/nginx/conf/nginx.conf)
must contain the correct configuration options in order for Phusion Passenger
to function correctly.
This installer has already modified the configuration file for you! The
following configuration snippet was inserted:
http {
...
passenger_root /usr/local/rvm/gems/ruby-1.9.3-p194/gems/passenger-3.0.15;
passenger_ruby /usr/local/rvm/wrappers/ruby-1.9.3-p194/ruby;
...
}
After you start Nginx, you are ready to deploy any number of Ruby on Rails
applications on Nginx.
Pressione <ENTER> e outra mensagem informativa será exibida. Desta vez é exibido um trecho de configuração da seção server
dos arquivos de configuração do Nginx – essa seção é utilizada
justamente para configurar uma aplicação/site no Nginx. Ela não é
inserida automaticamente, precisaremos setar isso quando da configuração
de nossa aplicação.
Organizando a instalação
Vamos agora dar uma organizada para termos menos trabalho no futuro,
até para melhorar a manutenção. Como é padrão das distribuições Linux,
os arquivos de configuração devem ficar no path /etc . Sendo assim, ficaria melhor se a configuração do Nginx ficasse em /etc/nginx . Vamos criar um link simbólico dos arquivos de configuração do Nginx para o /etc/nginx :
ln -s /usr/local/nginx/conf /etc/nginx
Outra melhoria que podemos fazer é colocar o binário do Nginx em um
path globalmente reconhecido pelo Linux. Para isso vamos criar outro
link simbólico:
ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin/nginx
Configurando o Nginx
O Nginx é instalado com um arquivo default de configuração. Não vou
cobrir todo esse processo, no lugar eu sugiro que você baixe e use o
arquivo de configuração abaixo:
user www-data;
worker_processes 4;
pid /var/run/nginx.pid;
events {
worker_connections 512;
multi_accept on;
}
http {
sendfile on;
tcp_nopush on;
tcp_nodelay on;
# Paths para o passenger e o ruby utilizados
passenger_root /usr/local/rvm/gems/ruby-1.9.3-p194/gems/passenger-3.0.15;
passenger_ruby /usr/local/rvm/wrappers/ruby-1.9.3-p194/ruby;
# Vide mais configurações em: http://www.modrails.com/documentation/Users%20guide%20Nginx.html
passenger_max_pool_size 4;
passenger_max_instances_per_app 2;
passenger_pool_idle_time 10;
passenger_log_level 2;
# Buffer
client_body_buffer_size 8K;
client_header_buffer_size 1k;
client_max_body_size 5m;
large_client_header_buffers 2 1k;
# Timeouts
client_body_timeout 10;
client_header_timeout 10;
keepalive_timeout 15;
send_timeout 10;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
##
# Logging Settings
##
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
##
# Gzip Settings
##
gzip on;
gzip_disable "msie6";
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
# Para melhorar a organização os .conf foram separados em conf.d e sites-enabled (no estilo do Apache)
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
A seguir vamos criar algumas pastas para organizar melhor os arquivos de configuração:
mkdir /etc/nginx/conf.d
mkdir /etc/nginx/sites-enabled
mkdir /etc/nginx/sites-available
Configurando seu domínio
Pronto! Quase tudo configurado. Agora só falta configurar o Nginx
para responder pelo domínio de seu site e para isso usaremos a diretiva server – vamos utilizar como exemplo o meu domínio almirmendes.com. Vamos criar um arquivo em /etc/nginx/sites-available/ com o nome do seu domínio (o nome não importa, pode ser qualquer um):
vim /etc/nginx/sites-available/almirmendes.com
Eu tenho, no Gist abaixo, uma configuração que você pode utilizar
como exemplo, apenas lembre-se de trocar as entradas que tiverem
almirmendes.com pelo seu domínio:
server {
listen 80;
server_name almirmendes.com www.almirmendes.com;
# Este é o path onde está hospedada sua aplicação Rails, ele pode ficar onde você quiser, entretanto
# é comum coloca-los em uma pasta na home de algum usuário ou mesmo em /var/www/. Independente disto
# o que é necessário aqui é que você adicione o path da pasta public de sua aplicação Rails.
# Importantíssimo, se você utiliza o Capistrano para fazer deploy de sua aplicação, lembre-se de adicionar
# o current antes do public
root /home/m3nd3s/almirmendes.com/public;
passenger_enabled on;
# Comente a linha acima e descomente a abaixo se utiliza capistrano
# root /home/m3nd3s/almirmendes.com/current/public;
#error_page 404 /404.html;
# Forcando o www na url
if ($host !~* ^www\.) {
rewrite ^(.*)$ http://www.$host$1 permanent;
}
#Configuracao de expiracao para imagens e outros arquivos
location ~* \.(ico|css|js|swf|html|htm)(\?[0-9]+)?$ {
if (-f $request_filename) {
access_log off;
expires 5d;
break;
}
}
location ~* /(images|system|public) {
if (-f $request_filename) {
access_log off;
expires 5d;
break;
}
}
location ~ /\. { deny all; }
}
Agora vamos fazer um link simbólico do arquivo almirmendes.com
para a pasta `/etc/nginx/sites-enabled/. Se reparar no arquivo de
configuração acima, no gist 3482847, ela é a única que está sendo lida
pelo Nginx. Esta é a forma que temos para ativar uma configuração nova
de site. Com isso habilitaremos o site:
ln -s /etc/nginx/sites-available/almirmendes.com /etc/nginx/sites-enabled/almirmendes.com
Se algum dia precisar desativar o site, basta remover o link simbólico em /etc/nginx/sites-enabled/almirmendes.com . Você ainda terá o arquivo de configuração intacto em /etc/nginx/sites-available .
Para testar a configuração, use o seguinte comando:
nginx -t
Se no resultado do comando acima aparecer algo semelhante ao exibido
abaixo é sinal de que está tudo correto, agora só falta inicializarmos o
Nginx:
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
Script de inicialização do Nginx
Por fim, falta só adicionar ao sistema o script de inicialização do Nginx. Sugiro que baixe o que está disponível neste link e salve-o em /etc/init.d/nginx . :
chmod +x /etc/init.d/nginx # permissão de execução para o script
service nginx start #inicializa o nginx
Existem inúmeras outas informações a serem adicionadas ao artigo,
entretanto não queria deixá-lo ainda maior. Espero que ajude você a
configurar o Nginx. Qualquer dúvida, estou a disposição.
Abraços! *** Artigo de Almir m3nd3s
|
Recentemente, algumas pessoas começaram a se perguntar como Arakoon,
nossa loja de chave-valor distribuída, lida com o drive no qual os
dados são armazenados. Para ser mais claro, isso se resume à forma como Tokyo Cabinet
(que usamos atualmente como implementação de banco de dados) envia
solicitações de gravação para o kernel, e como ele processa essas
informações mais tarde, após traduzir os pedidos de nível de sistema de
arquivos em operações de escrita na camada do bloco.
É importante saber isso devido ao uso de drives SSD – pense em
nivelamento de desgaste e outras questões vêm com esses dispositivos.
O rastreamento de como o aplicativo grava dados em um arquivo pode ser conseguido usando a ferramenta strace, buscando por chamadas write(2) e pwrite(2) (embora isso não seja necessariamente suficiente: o aplicativo pode ser escrito em um arquivo usando mapeamentos de memória mmap(2)).
Entretanto, na maioria dos carregamentos, isso não corresponde à
forma como os pedidos de bloco são enviados para o hardware: as
gravações podem ser bufferizadas, reordenadas etc. O que desejamos é uma
maneira de reunir informações de solicitações de gravação na camada do
bloco do kernel.
No Linux, pode-se usar SystemTap
(que possui algumas semelhanças com o DTrace em Solaris) para fazer um
hook no kernel no tempo de execução e recolher estatísticas, ou muitas
outras informações. Também é possível escrever um script que se liga aos
pontos de rastreio ou chamadas de função, então processa a informação
recebida.
Não vou entrar na instalação de SystemTap, uma vez que isso dependerá
da distribuição que você está rodando. Note que você pode não precisar
de acesso root para executar os scripts (você também nem deveria!): no
meu sistema Fedora 16, tudo o que eu tinha que fazer era colocar o meu
usuário nos grupos stapsys, stapusr e stapdev
(embora eu não tenha certeza de que realmente preciso estar em todos
aqueles…). Você vai precisar depurar arquivos de símbolos de seu kernel
disponível em execução, entre outras coisas (na minha experiência de
tentar executar um script em um sistema onde alguns pré-requisitos estão
faltando, isso resultará na ferramenta stap dizendo o que você precisa).
Escrever scripts SystemTap às vezes requer algum conhecimento interno
do kernel, para saber onde fazer o hook. Uma vez que quis reunir
algumas estatísticas sobre chamadas de nível de bloco, eu sabia que
tinha que procurar por chamadas no subsistema «bio», abreviação de
“Block IO “. Por sorte, SystemTap vem com algumas combinações
predefinidas de hooks, chamados de ‘tapsets’. Elas são armazenadas (no
meu sistema, pelo menos) em /usr/share/systemtap/tapset. Um desses arquivos é chamado ioblock.stp,
o que parece interessante. Já que eu estava com muita preguiça para
procurar a documentação, abri o arquivo em um paginador e li por ele. O
tap ioblock.request parecia interessante, o que dá acesso a um valor size. Depois de ler alguns exemplos de scripts SystemTap, eis o que eu criei:
global writes
probe ioblock.request {
if(bio_rw_num(rw) == BIO_WRITE)
writes[devname] <<< size
}
probe end {
printf("\n")
foreach([devname] in writes-) {
printf("Device: %s\n", devname)
println(@hist_log(writes[devname]))
}
}
Executar isso usando a ferramenta stap, e fechar depois de um tempo (usando CTRL-C), fornece o seguinte resultado:
$ stap -v blockio.stp
Pass 1: parsed user script and 92 library script(s) using 210196virt/30852res/3136shr kb, in 140usr/20sys/251real ms.
Pass 2: analyzed script: 3 probe(s), 21 function(s), 2 embed(s), 2 global(s) using 452960virt/226472res/92556shr kb, in 1500usr/100sys/2541real ms.
Pass 3: translated to C into "/tmp/stapeJldxD/stap_e40cc31c16b7dd290dabd43749c577a4_12507_src.c" using 452960virt/226600res/92684shr kb, in 10usr/0sys/12real ms.
Pass 4: compiled C into "stap_e40cc31c16b7dd290dabd43749c577a4_12507.ko" in 1780usr/350sys/2595real ms.
Pass 5: starting run.
^C
Device: sda5
value |-------------------------------------------------- count
0 |@@@@@@@@@@@@@@@ 30
1 | 0
2 | 0
~
256 | 0
512 | 0
1024 | 1
2048 | 0
4096 |@@@@@@@@@@@@@@@@@@@@@@@@@@@ 54
8192 |@@@ 7
16384 |@ 3
32768 | 0
65536 | 0
Device: dm-2
value |-------------------------------------------------- count
0 |@@ 5
1 | 0
2 | 0
~
256 | 0
512 | 0
1024 |@ 2
2048 | 0
4096 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 58
8192 |@@@@@@@ 14
16384 |@@@ 6
32768 | 0
65536 | 0
Device: dm-4
value |-------------------------------------------------- count
0 |@ 2
1 | 0
2 | 0
~
256 | 0
512 | 0
1024 |@ 2
2048 | 0
4096 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 58
8192 |@@@@@@@ 14
16384 |@@@ 6
32768 | 0
65536 | 0
Device: dm-1
value |-------------------------------------------------- count
1024 | 0
2048 | 0
4096 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 50
8192 | 0
16384 | 0
Device: sda
value |-------------------------------------------------- count
1024 | 0
2048 | 0
4096 |@@ 2
8192 | 0
16384 | 0
Pass 5: run completed in 10usr/50sys/15274real ms.
Isso é um histograma de solicitações de gravação bio para todos os
dispositivos de bloco no meu sistema, enquanto o script estava sendo
executado. Caso veja um monte de pedidos menores do que o tamanho da
página em um dispositivo SSD (isso depende do hardware), você pode
querer dar uma olhada nos padrões de gravação do seu aplicativo (embora,
mesmo assim, as coisas possam não ser tão ruins quanto parecem à
primeira vista, pois o drive SSD poderia executar lotes, remapeamento e
qualquer outra coisa internamente).
Observe que a saída do script exibido acima não retrata o
comportamento de Arakoon ou Tokyo Cabinet: ela mostra uma sessão padrão
de desktop, (rodando Google Chrome, Evolution, Empathy, Skype e mais
alguns aplicativos), durante um período de tempo muito curto. O teste
foi executado em um sistema Fedora 16 para laptop, contendo um hard
drive spinning usando uma combinação de Ext4 e XFS em vários volumes
LVM2 no kernel 3.2.7-1.fc16.x86_64.
***
Texto original de Nicolas Trangez, disponível em http://blog.incubaid.com/2012/03/06/tracing-block-device-write-request-sizes-in-linux-using-systemtap/
|
Todos conhecem o Nagios e sua capacidade e
flexibilidade para realizar monitoramento de ambientes de redes. Há
situações em que o admin Nagios necessita visualizar informações e
executar ações em sua interface.
Há também empresas onde várias pessoas possuem acesso ao sistema,
porém, nem sempre todas elas sabem exatamente o que estão fazendo,
podendo, por exemplo, desabilitar notificações ou mesmo verificações de
hosts e serviços, prejudicando sensivelmente o monitoramento. É
necessário limitar as ações de cada um dentro do sistema.
O que nem todos sabem é que é possível conceder permissões
específicas aos usuários, isolando os comandos administrativos da
interface. Outra excelente possibilidade é a de autenticar os usuários
em bases LDAP, como o Active Directory.
Combinaremos estas duas possibilidades neste artigo, onde descrevo
como realizar esta autenticação centralizada e como “separar os
administradores, dos usuários visualizadores ou read-only”.
Neste artigo teremos o seguinte cenário:
- Servidor Windows Server 2008 R2 com Active Directory - IP 10.100.1.2
- Servidor Centos 6.2 com Nagios Core instalado e funcional - IP 10.100.1.5
Configuração do Windows Server 2008 R2
Para iniciarmos, configuramos o Active Directory de forma organizada,
com o domínio fictício "pi4.com.br". Criamos os usuários do domínio em
uma Unidade Organizacional denominada "pi4":

Cada usuário possui a permissão de acesso, conforme descrito na imagem acima.
Criamos também uma Unidade Organizacional específica, denominada
"nagios", um usuário "nagios", para consultar a base de usuários e
grupos do AD e um grupo "nagiosusers", onde estão contidos os usuários
com permissão de acesso ao Nagios:

Assim concluímos a fase de configuração do Nagios no AD.
Configuração do Linux CentOS 6.2
Aqui assumimos que o Nagios esteja instalado e funcional, com autenticação habilitada (default).
Utilizamos neste cenário o quickstart, encontrado aqui.
Se o Nagios e o Apache foram instalados de forma diferente do
demonstrado no quickstart, talvez os arquivos estejam localizados em
diretórios diferentes; porém nada muda em relação á configuração. Basta
adaptar o path dos arquivos.
Primeiro, vamos configurar o Apache, que é o responsável em realizar
a autenticação no AD. Tenho o hábito de não substituir arquivos de
configuração e sim renomeá-los (faça como preferir), então:
Criamos um novo arquivo nagios.conf no mesmo local:
E inserimos nele o conteúdo a seguir:
ScriptAlias /nagios/cgi-bin "/usr/local/nagios/sbin"
<Directory "/usr/local/nagios/sbin">
Options ExecCGI
AllowOverride None
Order allow,deny
Allow from all
AuthBasicProvider ldap
AuthType Basic
AuthzLDAPAuthoritative off
AuthName "Nagios - Active Directory Authentication"
AuthLDAPURL "ldap:// 10.100.1.2:3268/dc=pi4,dc=com,dc=br?sAMAccountName?sub?(objectClass=*)"
AuthLDAPBindDN "cn=nagios,ou=nagios,dc=pi4,dc=com,dc=br"
AuthLDAPBindPassword P@ssw0rd
Require ldap-group cn=nagiosusers,ou=nagios,dc=pi4,dc=com,dc=br
</Directory>
Alias /nagios "/usr/local/nagios/share"
<Directory "/usr/local/nagios/share">
Options None
AllowOverride None
Order allow,deny
Allow from all
AuthBasicProvider ldap
AuthType Basic
AuthzLDAPAuthoritative off
AuthName "Nagios - Active Directory Authentication"
AuthLDAPURL "ldap:// 10.100.1.2:3268/dc=pi4,dc=com,dc=br?sAMAccountName?sub?(objectClass=*)"
AuthLDAPBindDN "cn=nagios,ou=nagios,dc=pi4,dc=com,dc=br"
AuthLDAPBindPassword P@ssw0rd
Require ldap-group cn=nagiosusers,ou=nagios,dc=pi4,dc=com,dc=br
</Directory>
# Fim do arquivo: /etc/httpd/conf.d/nagios.conf
Neste ponto, é necessário recarregar o Apache:
Pronto, o Apache já está pronto para autenticar os usuários no AD.
Permissionando os usuários no Nagios
Agora configuraremos o arquivo do Nagios que determina os níveis de
permissão de acesso. Vamos fazer uma cópia do arquivo original:
Editamos o arquivo:
E alteramos apenas as linhas necessárias:
use_authentication=1
authorized_for_system_information=user1,user2
authorized_for_configuration_information=user1,user2
authorized_for_system_commands=user1,user2
authorized_for_all_services=user1,user2,user3,user4
authorized_for_all_hosts=user1,user2,user3,user4
authorized_for_all_service_commands=user1,user2
authorized_for_all_host_commands=user1,user2
authorized_for_read_only=user3,user4
Observe onde cada usuário está citado para que a permissão seja dada corretamente. Neste ponto recarregamos o Nagios:
O Nagios também está pronto para autenticar seus usuários no AD e
permitir acesso administrativo ou read-only, de acordo com cada
permissão.
Testando as permissões no Nagios
Quando acessarmos a interface do Nagios, teremos:

Logando como usuário Administrador
Quando logarmos no sistema com um dos usuários com poderes
administrativos (user1 e user2) e clicarmos sobre um host ou serviço,
teremos como resultado algo semelhante a isto:

Observe a indicação em destaque do usuário logado no canto superior
esquerdo e o menu de comandos na lateral direita da tela, demonstrando o
acesso administrativo.
Ao acessarmos a opção "Configuration", no menu esquerdo, temos a tela a seguir:

Logando como usuário Read-Only
Se logarmos no sistema como um usuário com permissão apenas read-only
e clicarmos em um host ou serviço, teremos a apresentação das
informações de status, porém o menu de comandos não é apresentado e há a
informação de que o usuário atual não possui permissão para executar
comandos:

Quando o mesmo usuário read-only tenta acessar a opção "Configuration",
que acessamos anteriormente como usuário Administrador, ele receberá a
mensagem:
 Com estas configurações, nós dividimos os usuários com permissões específicas de acesso.
Testando a Permissão de Acesso na Interface do Nagios
Mas e se um usuário do AD que não faz parte do grupo "nagiosusers"
tentar logar no sistema? Simples. O Apache não o encontrará no grupo do
AD descrito no arquivo nagios.conf (Apache) e repetirá a tentativa de
autenticação até que a mensagem (que é bem clara) seja exibida:
"Autorização requerida. O servidor não pode verificar se você está
autorizado a acessar a página requisitada". Ou em bom português:
"Acesso Negado".
 Permitindo novos usuários
Para permitir que um novo usuário tenha acesso ao Nagios, é
necessário inserí-lo no grupo "nagiosusers" e dar as devidas permissões
no arquivo cgi.cfg. Em seguida, recarregar o Nagios (apenas o Nagios e
apenas reload) como descrito anteriormente. É essencial que os dois
passos sejam realizados, caso contrário, não funcionará corretamente,
ou o usuário não poderá se logar (mesmo com as permissões dadas no
arquivo cgi.cfg) ou pode se logar e não conseguir visualizar ou
executar qualquer ação dentro do sistema (ser membro do grupo
"nagiosusers" no AD).
Conclusão
Com estas configurações é possível gerar diferentes níveis de
acessos, ou seja, diferentes níveis de usuários read-only, diferentes
níveis de administradores e até criar um superadmin com acesso total.
Basta combinar as permissões.
***
Fonte: Nagios 3 Enterprise Network Monitoring (Max
Schubert, Derrick Bennett, Jonathan Gines, Andrew Hay, John Strand) -
Free e-book *** Artigo de Celso Faria
|
Esta é a última parte da série “Sequestro de chamadas de sistema
Linux”. Até agora, nós criamos um módulo de kernel carregável simples
que registra um dispositivo de caractere miscellaneous. Isso significa
que nós temos tudo que precisamos para corrigir a tabela de chamadas do
sistema. Quase tudo, para ser honesto. Nós ainda temos que preencher a
função our_ioctl e acrescentar algumas declarações ao nosso
arquivo de origem. Ao final deste artigo, seremos capazes de interceptar
qualquer chamada de sistema em nosso sistema.
Tabela de chamada de sistema
A tabela de chamada de sistema é simplesmente uma área no espaço de
memória do kernel que contém endereços de handlers de chamada do
sistema. Na verdade, um número de chamada de sistema é um offset nessa
tabela. Isso significa que quando chamamos sys_write (para ser mais
preciso - quando libc chama sys_write) em um sistema de 32 bits e passa o
número 4 em registo EAX antes de int 0x80, ele
simplesmente diz ao kernel para ir para a tabela de chamada do sistema,
obter o valor no offset 4 do endereço da tabela de chamada do sistema e
chamar a função para a qual o endereço aponta. Pode ser o número 1 em RAX no caso de um sistema de 64 bits (e syscall em vez de int 0x80). Os números de chamada de sistema são definidos em arch/x86/include/asm/unistd_32.h e arch/x86/include/asm/unistd_64.h
para plataformas de 32 e de 64 bits, respectivamente. Neste artigo,
vamos lidar com chamada de sistema sys_open, que é o número 5 para
sistemas de 32 bits e o número 2 para sistemas de 64 bits.
Devido ao fato de os kernels modernos não exportarem mais o símbolo
sys_call_table, teremos de encontrar, nós mesmos, a sua localização na
memória. Existem algumas maneiras "obscuras" de encontrar a localização
sys_call_table de forma programática, mas elas podem ou não funcionar.
Especialmente a forma como são escritas. Portanto, vamos usar a forma
mais simples e mais segura - leia a sua localização a partir do arquivo
/boot/System.map. Por razões de simplicidade, vamos apenas usar o grep e
pegar o endereço. No meu computador, o comando grep "sys_call_table" /boot/System.map (você deve verificar o nome do arquivo no seu sistema, como no meu é /boot/System.map-2.6.38-11-generic) dá a saída "ffffffff816002e0 R sys_call_table". Adicionar a variável global unsigned long * sys_call_table = (unsigned long*) 0xYour_Address_Of_Sys_call_table.
Preparativos
Vamos começar, como de costume, fazendo novas inclusões ao nosso código. Desta vez, os arquivos de inclusão são:
#include <linux/highmem.h>
#include <asm/unistd.h>
O primeiro é necessário devido ao fato de que a tabela de chamada de
sistema está localizada na área somente leitura da memória em kernels
modernos, e teremos que modificar os atributos de proteção da página de
memória que contêm o endereço da chamada de sistema que queremos
interceptar. O segundo é autoexplicativo após o parágrafo anterior. Não
vamos usar valores codificados para chamadas de sistema, em vez disso,
vamos usar os valores definidos no header unistd.h.
Agora vamos definir dois valores, que seriam usados como argumento cmd para a função our_ioctl. Um vai nos dizer para corrigir a tabela, outro dirá para corrigi-la restaurando o valor original.
#define IOCTL_PATCH_TABLE 0x00000001
#define IOCTL_FIX_table 0x00000004
Adicione mais uma variável global int is_set=0, que será utilizada como flag informando se a chamada do sistema real (0) ou personalizada (1) está em uso.
É importante salvar o endereço do sys_open original já que
não vamos implementar integralmente o nosso, em vez disso, nossa função
vai registrar informações sobre os argumentos de chamada e, em seguida,
realizar a chamada (original) real. Portanto, nós definimos uma função
ponteiro (para chamada original) e uma função (para chamadas
personalizadas):
asmlinkage int (*real_open)(const char* __user, int, int);
asmlinkage int custom_open(const char* __user file_name, int flags, int mode)
{
printk("interceptor: open(\"%s\", %X, %X)\n", file_name,
flags,
mode);
return real_open(file_name, flags, mode);
}
Você observou o atributo "asmlinkage". Bem, ele é, na
verdade, uma definição para o atributo. Não vamos nos aprofundar dessa
vez, vou apenas dizer que esse atributo informa ao compilador como ele
deve passar argumentos para a função, uma vez que está sendo chamado de
um código assembly. O macro "__user" significa que o argumento
está no espaço do usuário e a função deve executar determinadas
operações para copiar para o espaço do kernel quando necessário. Nós não
precisamos disso, o que significa que podemos ignorá-lo por agora.
Outra função crucial é o conjunto que nos permitirá modificar os
atributos de memória de proteção de página diretamente. Alguém pode
dizer que o dele é arriscado, mas, na minha opinião, isso é menos
arriscado que realmente fazer uma correção na tabela de chamada de
sistema como ela é; em primeiro lugar, dependente da arquitetura, e
sabemos que as arquiteturas não mudam drasticamente; em segundo, nós
usamos as funções do kernel para isso.
int make_rw(unsigned long address)
{
unsigned int level;
pte_t *pte = lookup_address(address, &level);
if(pte->pte &~ _PAGE_RW)
pte->pte |= _PAGE_RW;
return 0;
}
int make_ro(unsinged long address)
{
unsigned int level;
pte_t *pte = lookup_address(address, &level);
pte->pte = pte->pte &~ _PAGE_RW;
return 0;
}
pte_t significa typedef struct {unsigned long pte} pte_t e representa page table entry. Embora seja simplesmente um unsigned long, ele é declarado como struct, a fim de evitar o uso indevido de tipo.
pte_t * lookup_address (unsigned long address, unsigned int *level)
é fornecido pelo kernel e executa todo o trabalho sujo para gente, além
de retornar um ponteiro para page table entry que descreve a page que contém o endereço. Esta função aceita os seguintes argumentos:
address - o endereço na memória virtual; level - ponteiro para valores inteiros sem assinatura que aceitam o nível do mapeamento.
Vamos ao que interessa
Estamos quase lá. A única coisa que resta é a implementação real da função our_ioctl. Adicione as seguintes linhas:
switch(cmd)
{
case IOCTL_PATCH_TABLE:
make_rw((unsigned long)sys_call_table);
real_open = (void*)*(sys_call_table + __NR_open);
*(sys_call_table + __NR_open) = (unsigned long)custom_open;
make_ro((unsigned long)sys_call_table);
is_set=1;
break;
case IOCTL_FIX_TABLE:
make_rw((unsigned long)sys_call_table);
*(sys_call_table + __NR_open) = (unsigned long)real_open;
make_ro((unsigned long)sys_call_table);
is_set=0;
break;
default:
printk("Ooops....\n");
break;
}
E estas linhas para a função cleanup_module:
if(is_set)
{
make_rw((unsigned long)sys_call_table);
*(sys_call_table + __NR_open) = (unsigned long)real_open;
make_ro((unsigned long)sys_call_table);
}
O nosso módulo de interceptor está pronto. Bem, quase pronto, pois precisamos compilá-lo. Faça isso, como de costume - faça.
Teste
Finalmente temos o nosso módulo configurado e pronto para usar, mas
temos que criar um aplicativo do "cliente" , o código que vai
"conversar" com o nosso módulo e dizer a ele o que fazer. Felizmente,
isso é muito mais simples do que o resto do trabalho que fizemos aqui.
Crie um novo arquivo de origem e digite as seguintes linhas:
/* Define ioctl commands */
int main(void)
{
int device = open("/dev/interceptor", O_RDWR);
ioctl(device, IOCTL_PATCH_TABLE);
sleep(5);
ioctl(device, IOCTL_FIX_TABLE);
close(device);
return 0;
}
salve como s manager.c e compile-o com o gcc -o manager manager.c.
Carregue o módulo, execute ./manager e depois descarregue o módulo quando o manager sair. Se você emitir o comando dmesg | tail, se você vir linhas que contenham "interceptor: open (bla bla bla)", então você saberá que essas linhas foram produzidas pelo nosso handler.
Agora somos capazes de interceptar chamadas de sistema em kernels modernos, apesar do fato de que sys_call_table
já não é exportado. Embora nós lidamos com estruturas de baixo nível,
que normalmente só são usadas pelo kernel, este ainda é um método
relativamente seguro, desde que seu módulo seja compilado com o kernel
em execução.
Espero que este artigo tenha sido útil. Vejo vocês na próxima!
⁂
Texto original de Alexey Lyashko, disponível em http://syprog.blogspot.com.br/2011/10/hijack-linux-system-calls-part-iii.html
|
Esta é a última parte da série “Sequestro de chamadas de sistema
Linux”. Até agora, nós criamos um módulo de kernel carregável simples
que registra um dispositivo de caractere miscellaneous. Isso significa
que nós temos tudo que precisamos para corrigir a tabela de chamadas do
sistema. Quase tudo, para ser honesto. Nós ainda temos que preencher a
função our_ioctl e acrescentar algumas declarações ao nosso
arquivo de origem. Ao final deste artigo, seremos capazes de interceptar
qualquer chamada de sistema em nosso sistema.
Tabela de chamada de sistema
A tabela de chamada de sistema é simplesmente uma área no espaço de
memória do kernel que contém endereços de handlers de chamada do
sistema. Na verdade, um número de chamada de sistema é um offset nessa
tabela. Isso significa que quando chamamos sys_write (para ser mais
preciso - quando libc chama sys_write) em um sistema de 32 bits e passa o
número 4 em registo EAX antes de int 0x80, ele
simplesmente diz ao kernel para ir para a tabela de chamada do sistema,
obter o valor no offset 4 do endereço da tabela de chamada do sistema e
chamar a função para a qual o endereço aponta. Pode ser o número 1 em RAX no caso de um sistema de 64 bits (e syscall em vez de int 0x80). Os números de chamada de sistema são definidos em arch/x86/include/asm/unistd_32.h e arch/x86/include/asm/unistd_64.h
para plataformas de 32 e de 64 bits, respectivamente. Neste artigo,
vamos lidar com chamada de sistema sys_open, que é o número 5 para
sistemas de 32 bits e o número 2 para sistemas de 64 bits.
Devido ao fato de os kernels modernos não exportarem mais o símbolo
sys_call_table, teremos de encontrar, nós mesmos, a sua localização na
memória. Existem algumas maneiras "obscuras" de encontrar a localização
sys_call_table de forma programática, mas elas podem ou não funcionar.
Especialmente a forma como são escritas. Portanto, vamos usar a forma
mais simples e mais segura - leia a sua localização a partir do arquivo
/boot/System.map. Por razões de simplicidade, vamos apenas usar o grep e
pegar o endereço. No meu computador, o comando grep "sys_call_table" /boot/System.map (você deve verificar o nome do arquivo no seu sistema, como no meu é /boot/System.map-2.6.38-11-generic) dá a saída "ffffffff816002e0 R sys_call_table". Adicionar a variável global unsigned long * sys_call_table = (unsigned long*) 0xYour_Address_Of_Sys_call_table.
Preparativos
Vamos começar, como de costume, fazendo novas inclusões ao nosso código. Desta vez, os arquivos de inclusão são:
#include <linux/highmem.h>
#include <asm/unistd.h>
O primeiro é necessário devido ao fato de que a tabela de chamada de
sistema está localizada na área somente leitura da memória em kernels
modernos, e teremos que modificar os atributos de proteção da página de
memória que contêm o endereço da chamada de sistema que queremos
interceptar. O segundo é autoexplicativo após o parágrafo anterior. Não
vamos usar valores codificados para chamadas de sistema, em vez disso,
vamos usar os valores definidos no header unistd.h.
Agora vamos definir dois valores, que seriam usados como argumento cmd para a função our_ioctl. Um vai nos dizer para corrigir a tabela, outro dirá para corrigi-la restaurando o valor original.
#define IOCTL_PATCH_TABLE 0x00000001
#define IOCTL_FIX_table 0x00000004
Adicione mais uma variável global int is_set=0, que será utilizada como flag informando se a chamada do sistema real (0) ou personalizada (1) está em uso.
É importante salvar o endereço do sys_open original já que
não vamos implementar integralmente o nosso, em vez disso, nossa função
vai registrar informações sobre os argumentos de chamada e, em seguida,
realizar a chamada (original) real. Portanto, nós definimos uma função
ponteiro (para chamada original) e uma função (para chamadas
personalizadas):
asmlinkage int (*real_open)(const char* __user, int, int);
asmlinkage int custom_open(const char* __user file_name, int flags, int mode)
{
printk("interceptor: open(\"%s\", %X, %X)\n", file_name,
flags,
mode);
return real_open(file_name, flags, mode);
}
Você observou o atributo "asmlinkage". Bem, ele é, na
verdade, uma definição para o atributo. Não vamos nos aprofundar dessa
vez, vou apenas dizer que esse atributo informa ao compilador como ele
deve passar argumentos para a função, uma vez que está sendo chamado de
um código assembly. O macro "__user" significa que o argumento
está no espaço do usuário e a função deve executar determinadas
operações para copiar para o espaço do kernel quando necessário. Nós não
precisamos disso, o que significa que podemos ignorá-lo por agora.
Outra função crucial é o conjunto que nos permitirá modificar os
atributos de memória de proteção de página diretamente. Alguém pode
dizer que o dele é arriscado, mas, na minha opinião, isso é menos
arriscado que realmente fazer uma correção na tabela de chamada de
sistema como ela é; em primeiro lugar, dependente da arquitetura, e
sabemos que as arquiteturas não mudam drasticamente; em segundo, nós
usamos as funções do kernel para isso.
int make_rw(unsigned long address)
{
unsigned int level;
pte_t *pte = lookup_address(address, &level);
if(pte->pte &~ _PAGE_RW)
pte->pte |= _PAGE_RW;
return 0;
}
int make_ro(unsinged long address)
{
unsigned int level;
pte_t *pte = lookup_address(address, &level);
pte->pte = pte->pte &~ _PAGE_RW;
return 0;
}
pte_t significa typedef struct {unsigned long pte} pte_t e representa page table entry. Embora seja simplesmente um unsigned long, ele é declarado como struct, a fim de evitar o uso indevido de tipo.
pte_t * lookup_address (unsigned long address, unsigned int *level)
é fornecido pelo kernel e executa todo o trabalho sujo para gente, além
de retornar um ponteiro para page table entry que descreve a page que contém o endereço. Esta função aceita os seguintes argumentos:
address - o endereço na memória virtual; level - ponteiro para valores inteiros sem assinatura que aceitam o nível do mapeamento.
Vamos ao que interessa
Estamos quase lá. A única coisa que resta é a implementação real da função our_ioctl. Adicione as seguintes linhas:
switch(cmd)
{
case IOCTL_PATCH_TABLE:
make_rw((unsigned long)sys_call_table);
real_open = (void*)*(sys_call_table + __NR_open);
*(sys_call_table + __NR_open) = (unsigned long)custom_open;
make_ro((unsigned long)sys_call_table);
is_set=1;
break;
case IOCTL_FIX_TABLE:
make_rw((unsigned long)sys_call_table);
*(sys_call_table + __NR_open) = (unsigned long)real_open;
make_ro((unsigned long)sys_call_table);
is_set=0;
break;
default:
printk("Ooops....\n");
break;
}
E estas linhas para a função cleanup_module:
if(is_set)
{
make_rw((unsigned long)sys_call_table);
*(sys_call_table + __NR_open) = (unsigned long)real_open;
make_ro((unsigned long)sys_call_table);
}
O nosso módulo de interceptor está pronto. Bem, quase pronto, pois precisamos compilá-lo. Faça isso, como de costume - faça.
Teste
Finalmente temos o nosso módulo configurado e pronto para usar, mas
temos que criar um aplicativo do "cliente" , o código que vai
"conversar" com o nosso módulo e dizer a ele o que fazer. Felizmente,
isso é muito mais simples do que o resto do trabalho que fizemos aqui.
Crie um novo arquivo de origem e digite as seguintes linhas:
/* Define ioctl commands */
int main(void)
{
int device = open("/dev/interceptor", O_RDWR);
ioctl(device, IOCTL_PATCH_TABLE);
sleep(5);
ioctl(device, IOCTL_FIX_TABLE);
close(device);
return 0;
}
salve como s manager.c e compile-o com o gcc -o manager manager.c.
Carregue o módulo, execute ./manager e depois descarregue o módulo quando o manager sair. Se você emitir o comando dmesg | tail, se você vir linhas que contenham "interceptor: open (bla bla bla)", então você saberá que essas linhas foram produzidas pelo nosso handler.
Agora somos capazes de interceptar chamadas de sistema em kernels modernos, apesar do fato de que sys_call_table
já não é exportado. Embora nós lidamos com estruturas de baixo nível,
que normalmente só são usadas pelo kernel, este ainda é um método
relativamente seguro, desde que seu módulo seja compilado com o kernel
em execução.
Espero que este artigo tenha sido útil. Vejo vocês na próxima!
⁂
Texto original de Alexey Lyashko, disponível em http://syprog.blogspot.com.br/2011/10/hijack-linux-system-calls-part-iii.html
|
Nós todos sabemos que os drivers de dispositivo
são as mãos do sistema operacional que tornam possível para o kernel
lidar com hardware. Sabemos também que existem dois tipos de
dispositivos - character e block, dependendo da forma como eles lidam
com transmissões de dados, mas o que dispositivo "miscellaneous"
significa? Para colocar de uma maneira simples - ele significa que ele
significa. Por um lado, isso pode ser um driver que lida com hardware
simples; por outro, é a forma como o Linux nos permite criar
dispositivos virtuais, como uma das maneiras de se comunicar com os
módulos do kernel, que é exatamente o que precisamos para capturar
chamadas do sistema Linux.
Neste artigo, vamos criar um dispositivo simples de caractere
virtual, que será usado por um processo de espaço do usuário para
instruir o nosso módulo do kernel se ele deve sequestrar ou restaurar
determinada chamada de sistema. Esse dispositivo virtual será controlado
com a função ioctl. Para simplificar, eu decidi não adicionar
read/write handlers a esse dispositivo, pois não é realmente necessário
para o que estamos prestes a fazer. Embora seja um recurso bom de ter.
Diversos dispositivos são representados com struct miscdevice, que é declarado em /include/linux/miscdevice.h como
struct miscdevice
{
int minor;
const char *name;
const struct file_operations *fops;
struct list_head list;
struct device *parent;
struct device *this_device;
const char *nodename;
mode_t mode;
};
Bem grande, hein? No entanto, só devemos cuidar dos três primeiros membros da estrutura:
minor representa o menor número do dispositivo. É preferível defini-lo como MISC_DYNAMIC_MINOR (pelo menos para o nosso módulo) a menos que você precise que algum número específico seja usado. name é o nome do nosso dispositivo que deve aparecer no sistema de arquivos /dev struct file_operations é um conjunto de ponteiros para implementações correspondentes de funções IO e um ponteiro para o módulo proprietário. Essa estrutura é muito grande para ser apresentada aqui, mas você pode encontrá-la em /include/linux/fs.h
Então, antes de tudo, adicione outro arquivo de inclusão ao seu código (que já escrevi no artigo anterior), com
#include <linux/miscdevice.h>
Em seguida, devemos adicionar handlers personalizados para funções e variáveis globais em que estejamos interessados, ou seja, open, release, ioctl e a variável in_use.
int in_use = 0;
static int our_open(struct inode *inode, struct file *file)
{
if(in_use)
return -EBUSY;
in_use++;
printk("device has been opened\n");
return 0;
}
static int our_release(struct inode *inode, struct file *file)
{
in_use--;
printk("device has been closed\n");
return 0;
}
static int our_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
int retval = 0;
return retval;
}
Agora é hora de criar struct file_operations e struct miscdevice e preencher os campos relevantes:
static const struct file_operations our_fops =\
{
.owner = THIS_MODULE,
.open = &our_open,
.release = &our_release,
.unlocked_ioctl = (void*)&our_ioctl,
.compat_ioctl = (void*)&our_ioctl
}
Uma pergunta razoável seria: "Por que vamos definir unlocked_ioctl e compat_ioctl com o mesmo valor e onde diabos é o ioctl regular?". Não há nada especial sobre isso. unlocked_ioctl é usado em plataformas de 64 bits e compat_ioctl
em 32 bits ou no modo de compatibilidade, e é totalmente normal
apontá-las para o mesmo local, desde que a função handler não atrapalhe
os tipos acima. Quanto ao ioctl, ele simplesmente não está lá mais...
static struct miscdevice our_device = \
{
MISC_DYNAMIC_MINOR,
"interceptor",
&our_fops
};
Depois de tudo isso, devemos fazer um pequeno ajuste para a nossa função init_module, inserindo o seguinte código:
int retval = misc_register(&our_device);
Você também deve mudar "return 0;" para "return retval;". O código acima diz ao sistema para registrar um dispositivo miscellaneous descrito pela estrutura miscdevice com o kernel. No caso, ao campo menor é atribuído MISC_DYNAMIC_MINOR
(nosso caso exatamente), e o kernel preenche com números aleatórios (do
nosso ponto de vista), caso contrário, o menor número solicitado é
usado.
Nossa função cleanup_module deveria ter esta linha adicionada:
misc_deregister(&our_device);
a fim de cancelar o nosso dispositivo e removê-lo a partir do sistema.
Nota importante: funções do kernel retornam 0 no caso de sucesso, ou um código de erro no caso de falha.
Por agora, temos um modulo de trabalho do kernel que registra um
dispositivo miscellaneous quando carregado e o cancela quando
descarregado. Construa-o agora com o comando make. Carregue-o com insmod e verifique o conteúdo do sistema de arquivo /dev.
Você verá que há um novo dispositivo chamado "interceptor" com o número
10 como número principal e que sempre tem sido atribuído como menor
número. Você pode descarregá-lo agora.
Se desejar, você pode tentar abrir e fechar o dispositivo /dev/interceptor de um processo do usuário e verificar o log com dmesg | tail.
Você irá visualizar as linhas "device has been opened" e "device has
been closed", respectivamente. Você também pode tentar abrir o
dispositivo a partir de dois processos de usuário ao mesmo tempo, então
você vai ver que apenas um processo pode abri-lo com sucesso.
No próximo artigo, vamos adicionar algum código ao nosso módulo, o
que tornaria possível para ele realmente corrigir o sys_call_table e
substituir as chamadas originais com wrappers personalizados.
Espero que este artigo tenha sido útil. Vejo vocês na próxima!
⁂
Texto original de Alexey Lyashko, disponível em http://syprog.blogspot.com.br/2011/10/hijack-linux-system-calls-part-ii.html
|
Alguma vez você já tentou pesquisar no Google
por "fragmentando tabela da chamada de sistema Linux"? Existem centenas,
senão milhares, de mensagens em relação a esse problema. A maioria
delas está desatualizada, pois se refere a kernels mais antigos (aqueles
que ainda exportam sys_call_table), outras são sobre a adição
de chamada de sistema personalizado e recompilar o kernel. Há algumas
que abrangem kernels modernos, mas são sucintas e, principalmente, te
dão apenas uma ideia geral de como ele funciona. Decidi fazer uma
descrição profunda do processo e fornecer um exemplo que funciona.
Essa descrição consiste em três partes: Módulos, Miscellaneous
Character Drivers e System Call Table. Apesar de a segunda parte ser
opcional, ela tornaria o seu espaço de código do kernel mais flexível e
utilizável a partir da perspectiva do espaço do usuário.
- Módulos - essa parte segue imediatamente este preâmbulo e aborda os conceitos básicos dos módulos do kernel carregáveis.
- Miscellaneous Character Drivers - aqui procuro fornecer explicação aprofundada sobre o que é, como funciona e, o mais importante, como ele pode ser usado.
- System Call Table - essa vai ser a parte mais curta, uma vez que só inclui a estrutura da tabela de chamadas do sistema.
Então, vamos mergulhar no negócio.
Módulos do kernel carregáveis
Módulos de kernel carregáveis (LKMs, abreviação do inglês) são
simplesmente extensões para o kernel básico em seu sistema operacional
que pode ser carregado/descarregado em tempo real, sem a necessidade de
recompilar o kernel ou de reiniciar o sistema. Esse recurso existe em
todos os principais sistemas operacionais (Windows, Linux, MacOS), mas
vamos nos concentrar apenas no Linux, de preferência com o kernel 2.6.38
(já que este é o único que eu testei em exemplos) e superior.
Vá em frente, abra seu editor de código preferido e comece adicionando os arquivos de include necessários:
#include <linux/version.h>
#include <linux/module.h>
Basicamente, isso é tudo que você precisa para construir um módulo
simples do kernel que pode ser carregado e descarregado. Iremos, no
entanto, adicionar alguns inclusões de módulos mais tarde.
Há mais duas coisas que nós, incondicionalmente, precisamos implementar - Inicialização e rotinas de limpeza. Aqui vamos nós:
static int __init init_module(void)
{
printk(KERN_INFO "We are in kernel space\n");
return 0;
}
Essa é a nossa rotina de inicialização. Se você precisa configurar
quaisquer variáveis ou fazer outros arranjos que são cruciais para o
módulo, você deve fazer isso aqui.
static void __exit cleanup_module(void)
{
printk(KERN_INFO "Elvis has left the building\n");
return;
}
Por outro lado, a rotina acima é usada para limpar a bagunça que nós
produzimos com o nosso módulo. Ela é chamada antes de o módulo ser
descarregado.
Como você observou, usamos a função printk aqui - uma das
funções mais robustas exportadas pelo kernel do Linux, geralmente usada
para mensagens de saída de log/diagnóstico. Você pode obter a sua saída
com o comando dmesg.
Use macros module_init e module_exit para traçar essas rotinas:
module_init(init_module);
module_exit(cleanup_module);
E a última coisa - adicionar mais algumas informações ao módulo usando os seguintes macros:
MODULE_LICENSE("GPL");
MODULE_AUTHOR("your name goes here");
MODULE_VERSION("this string is up to you");
MODULE_DESCRIPTION("describe this module here");
É isso aí. Acabamos de construir um skeleton kernel module. Agora
temos que compilá-lo. Mas o problema é que você não pode compilar os
módulos do kernel da forma que faria com seus aplicativos. Simplesmente
porque eles não são aplicativos simples. Você tem que criar um arquivo
makefile especial, destacando que é um makefile para um módulo do
kernel:
obj-m := name_of_the_module.o
KDIR := /lib/modules/`uname -r`/build
PWD := `pwd`
default:
make -C $(KDIR) M=$(PWD) modules
Execute o comando make e você terá o módulo compilado pronto para ser
conectado. Tudo que você precisa fazer agora é tentar carregar o módulo
no kernel, e nós temos o comando insmod para esse fim. Use um dos seguintes, dependendo se sua distro é baseada em debian ou em Red Hat, respectivamente:
sudo insmod ./your_module_name.ko
or
su -c "insmod ./your_module_name.ko"
Será solicitada a sua senha ou a senha do root (depende do comando
emitido); depois disso, você deve obter a janela de comandos. Se você
não receber nenhuma notificação de erro, significa que o módulo foi
carregado com êxito, caso contrário, como de costume, verifique o seu
código e verifique-o contra suas fontes de kernel. Use o seguinte código
para descarregar o módulo:
sudo rmmod your_module_name
or
su -c "rmmod your_module_name"
Você não precisa da extensão ". ko" aqui. Se não receber
qualquer notificação de erro, está tudo bem. Mas se receber, isso
significaria que, por algumas razões, o sistema é incapaz de descarregar
o módulo. A mensagem mais frequente que eu costumava obter era sobre o
meu módulo estando ocupado. Às vezes, mesmo rmmod -f não pode
resolver esse problema, e você tem que reiniciar a máquina a fim de
tirar o seu módulo das mãos de kernel. Claro, você tem que verificar o
seu código depois disso, por razões possíveis.
Agora digite "dmesg | tail" para obter o final do log do kernel. As últimas duas linhas devem conter as strings que passamos para função printk
ou a razão de não ser capaz de descarregar o módulo. É importante
executar esse comando antes de reiniciar em caso de erro a fim de ver a
razão, caso contrário, você não encontrará essa entrada.
Conclusão
Então acabamos de construir nosso módulo mais simples. Na prática,
isso não é verdade, já que o módulo mais simples não deve conter printk :). Somos (espero) capazes de carregar e descarregá-lo.
No próximo artigo, vamos adicionar um dispositivo virtual, que seria
responsável pela interação com um processo de usuário e executaria todas
as operações de aplicação de patches/correção.
Espero que este artigo tenha sido útil. Vejo vocês na próxima!
⁂
Texto original de Alexey Lyashko, disponível em http://syprog.blogspot.com.br/2011/10/hijack-linux-system-calls-part-i.html
|
Alguma vez você já tentou pesquisar no Google
por "fragmentando tabela da chamada de sistema Linux"? Existem centenas,
senão milhares, de mensagens em relação a esse problema. A maioria
delas está desatualizada, pois se refere a kernels mais antigos (aqueles
que ainda exportam sys_call_table), outras são sobre a adição
de chamada de sistema personalizado e recompilar o kernel. Há algumas
que abrangem kernels modernos, mas são sucintas e, principalmente, te
dão apenas uma ideia geral de como ele funciona. Decidi fazer uma
descrição profunda do processo e fornecer um exemplo que funciona.
Essa descrição consiste em três partes: Módulos, Miscellaneous
Character Drivers e System Call Table. Apesar de a segunda parte ser
opcional, ela tornaria o seu espaço de código do kernel mais flexível e
utilizável a partir da perspectiva do espaço do usuário.
- Módulos - essa parte segue imediatamente este preâmbulo e aborda os conceitos básicos dos módulos do kernel carregáveis.
- Miscellaneous Character Drivers - aqui procuro fornecer explicação aprofundada sobre o que é, como funciona e, o mais importante, como ele pode ser usado.
- System Call Table - essa vai ser a parte mais curta, uma vez que só inclui a estrutura da tabela de chamadas do sistema.
Então, vamos mergulhar no negócio.
Módulos do kernel carregáveis
Módulos de kernel carregáveis (LKMs, abreviação do inglês) são
simplesmente extensões para o kernel básico em seu sistema operacional
que pode ser carregado/descarregado em tempo real, sem a necessidade de
recompilar o kernel ou de reiniciar o sistema. Esse recurso existe em
todos os principais sistemas operacionais (Windows, Linux, MacOS), mas
vamos nos concentrar apenas no Linux, de preferência com o kernel 2.6.38
(já que este é o único que eu testei em exemplos) e superior.
Vá em frente, abra seu editor de código preferido e comece adicionando os arquivos de include necessários:
#include <linux/version.h>
#include <linux/module.h>
Basicamente, isso é tudo que você precisa para construir um módulo
simples do kernel que pode ser carregado e descarregado. Iremos, no
entanto, adicionar alguns inclusões de módulos mais tarde.
Há mais duas coisas que nós, incondicionalmente, precisamos implementar - Inicialização e rotinas de limpeza. Aqui vamos nós:
static int __init init_module(void)
{
printk(KERN_INFO "We are in kernel space\n");
return 0;
}
Essa é a nossa rotina de inicialização. Se você precisa configurar
quaisquer variáveis ou fazer outros arranjos que são cruciais para o
módulo, você deve fazer isso aqui.
static void __exit cleanup_module(void)
{
printk(KERN_INFO "Elvis has left the building\n");
return;
}
Por outro lado, a rotina acima é usada para limpar a bagunça que nós
produzimos com o nosso módulo. Ela é chamada antes de o módulo ser
descarregado.
Como você observou, usamos a função printk aqui - uma das
funções mais robustas exportadas pelo kernel do Linux, geralmente usada
para mensagens de saída de log/diagnóstico. Você pode obter a sua saída
com o comando dmesg.
Use macros module_init e module_exit para traçar essas rotinas:
module_init(init_module);
module_exit(cleanup_module);
E a última coisa - adicionar mais algumas informações ao módulo usando os seguintes macros:
MODULE_LICENSE("GPL");
MODULE_AUTHOR("your name goes here");
MODULE_VERSION("this string is up to you");
MODULE_DESCRIPTION("describe this module here");
É isso aí. Acabamos de construir um skeleton kernel module. Agora
temos que compilá-lo. Mas o problema é que você não pode compilar os
módulos do kernel da forma que faria com seus aplicativos. Simplesmente
porque eles não são aplicativos simples. Você tem que criar um arquivo
makefile especial, destacando que é um makefile para um módulo do
kernel:
obj-m := name_of_the_module.o
KDIR := /lib/modules/`uname -r`/build
PWD := `pwd`
default:
make -C $(KDIR) M=$(PWD) modules
Execute o comando make e você terá o módulo compilado pronto para ser
conectado. Tudo que você precisa fazer agora é tentar carregar o módulo
no kernel, e nós temos o comando insmod para esse fim. Use um dos seguintes, dependendo se sua distro é baseada em debian ou em Red Hat, respectivamente:
sudo insmod ./your_module_name.ko
or
su -c "insmod ./your_module_name.ko"
Será solicitada a sua senha ou a senha do root (depende do comando
emitido); depois disso, você deve obter a janela de comandos. Se você
não receber nenhuma notificação de erro, significa que o módulo foi
carregado com êxito, caso contrário, como de costume, verifique o seu
código e verifique-o contra suas fontes de kernel. Use o seguinte código
para descarregar o módulo:
sudo rmmod your_module_name
or
su -c "rmmod your_module_name"
Você não precisa da extensão ". ko" aqui. Se não receber
qualquer notificação de erro, está tudo bem. Mas se receber, isso
significaria que, por algumas razões, o sistema é incapaz de descarregar
o módulo. A mensagem mais frequente que eu costumava obter era sobre o
meu módulo estando ocupado. Às vezes, mesmo rmmod -f não pode
resolver esse problema, e você tem que reiniciar a máquina a fim de
tirar o seu módulo das mãos de kernel. Claro, você tem que verificar o
seu código depois disso, por razões possíveis.
Agora digite "dmesg | tail" para obter o final do log do kernel. As últimas duas linhas devem conter as strings que passamos para função printk
ou a razão de não ser capaz de descarregar o módulo. É importante
executar esse comando antes de reiniciar em caso de erro a fim de ver a
razão, caso contrário, você não encontrará essa entrada.
Conclusão
Então acabamos de construir nosso módulo mais simples. Na prática,
isso não é verdade, já que o módulo mais simples não deve conter printk :). Somos (espero) capazes de carregar e descarregá-lo.
No próximo artigo, vamos adicionar um dispositivo virtual, que seria
responsável pela interação com um processo de usuário e executaria todas
as operações de aplicação de patches/correção.
Espero que este artigo tenha sido útil. Vejo vocês na próxima!
⁂
Texto original de Alexey Lyashko, disponível em http://syprog.blogspot.com.br/2011/10/hijack-linux-system-calls-part-i.html
|
Veja neste artigo a instalação do sistema de detecção de intrusão na rede
Snort, logando no banco de dados MySQL através do BarnYard2 e
visualizando os logs e gráficos gerenciais pelo Snorby, rodando no
servidor Web Apache2, tudo isso dentro do Debian.
Instalando o MySQL
Instalando o MySQL:
Durante a instalação, será pedida a senha para o usuário root do
MySQL, mas, se houver algum problema, configure a senha do root do MySQL
com o comando:
Vamos criar o banco de dados e o usuário para acessá-lo:
Já no shell do MySQL:
CREATE DATABASE snort; GRANT all privileges ON snort.* TO snort@localhost IDENTIFIED BY 'senha_snort_mysql'; flush privileges; QUIT
Instalando o SNORT
Instalando o SNORT:
# apt-get install snort-mysql snort-rules-default
Criando as tabelas para o snort:
Agora vamos configurar o SNORT editando o arquivo /etc/snort/snort.debian.conf.
Primeiro, configure a rede interna no parâmetro já existente:
DEBIAN_SNORT_HOME_NET=”127.0.0.0/16,192.168.0.0/24”
Interface usada:
DEBIAN_SNORT_INTERFACE=”eth0”
Vamos dizer para o SNORT usar o banco de dados do MySQL, editando o arquivo /etc/snort/database.conf e coloque:
output database: log, mysql, user=snort password=snort_pwd dbname=snort host=localhost
Remova o arquivo de “pendência” do banco de dados para o snort:
Reinicie o SNORT e pronto, já está funcionando e registrando no MySQL:
Instalando o BarnYard2
Baixe o banryard2 e instale:
Vamos configurar o arquivo /etc/snort/database.conf. Comente com “#” a linha que diz respeito ao MySQL:
Adicione a linha:
output unified2: filename snort.out, limit 128
Agora vamos editar o arquivo /etc/snort/barnyard2.conf:
config daemon config hostname: localhost config interface: eth0 config logdir: /var/log/barnyard2/ config waldo_file: /var/barnyard2/waldo
Acrescente no final a linha:
output database: log, mysql, user=snort password=senha_snort_mysql dbname=snort host=localhost
Vamos criar as pastas para o uso do barnyard2:
Vamos reiniciar o SNORT:
Iniciando o BarnYard2:
*** Os comandos acima para inicialização do BarnYard2 deverão ser executados sempre na inicialização do sistema, sugiro colocá-los no /etc/rc.local ***
Instalando o Apache2
Instale o apache e alguns requisitos:
Instalando o SNORBY
Vamos instalar os requisitos para o Snorby:
Instale o wkhtmltopdf:
Instalando o ruby:
Vemos a versão instalada:
ruby 1.9.2p290 (2010-08-18 revision 29036) [i686-linux]
Instalamos os gems:
Instalando Snorby:
Editamos o arquivo de configuração do banco de dados:
snorby: &snorby adapter: mysql username: snort password: senha_snort_mysql host: localhost
Editamos o arquivo de configuração do Snorby:
development: domain: localhost:3000 wkhtmltopdf: /usr/sbin/wkhtmltopdf
test: domain: localhost:3000 wkhtmltopdf: /usr/sbin/wkhtmltopdf
production: domain: localhost:3000 wkhtmltopdf: /usr/sbin/wkhtmltopdf
Já no shell do MySQL:
GRANT all privileges ON snorby.* TO snort@localhost; flush privileges; QUIT
Instalando o Snorby:
Vamos criar o acesso do usuário snort no banco de dados do Snorby:
Edite o arquivo /etc/snort/barnyard2.conf e acrescente a linha:
output database: log, mysql, user=snort password=senha_snort_mysql dbname=snorby host=localhost
Editando o Apache2
Instalando o módulo passenger:

Vamos criar o arquivo do módulo para o Apache2:
Adicione no arquivo:
LoadModule passenger_module /usr/local/lib/ruby/gems/1.9.1/gems/passenger-3.0.3/ext/apache2/mod_passenger.so
Vamos habilitar o módulo:
Adicione no arquivo:
<IfModule mod_passenger.c> PassengerRoot /usr/local/lib/ruby/gems/1.9.1/gems/passenger-3.0.3 PassengerRuby /usr/local/bin/ruby </IfModule>
Instalando o módulo:
Reinicie o apache2:
Edite o arquivo /etc/apache2/sites-available/default:
<Virtualhost *:80> # ServerName infosegura DocumentRoot /var/www/snorby/public/
<Directory /var/www/snorby/public> RailsBaseURI / Options +ExecCGI FollowSymLinks -MultiViews AllowOverride all Order allow,deny Allow from all </Directory>
Reinicie o apache2:
Vamos reiniciar o SNORT:
Iniciando o Snorby:
*** Os comandos acima para inicialização do Snorby deverão ser executados sempre na inicialização do sistema, sugiro colocá-los no /etc/rc.local ***
Acesse pelo navegador o Snorby: http://<ip_snorby>
Coloque o usuário e senha:
- Usuário: snorby@snorby.org
- Senha: snorby

Tela principal, na qual o “Dashboard” é atualizado a cada 30 min e os eventos são atualizados imediatamente:

Verifique se o Snorby Worker está funcionando clicando em “Administration > Administrator Menu > Worker & Job Queue".

Dica
Crie o script abaixo para executar o Barnyard2 na inicialização do sistema:
#!/bin/sh
case $1 in start) printf "starting $0..." cd /etc/snort barnyard2 -d /var/log/snort -f snort.out echo -e 'OK' ;; stop) printf "stopping $0..." killall barnyard2 echo -e 'OK' ;; restart) $0 stop $0 start ;; *) echo "usage: $0 (start|stop|restart)" ;; esac Para executar acrescente no /etc/rc.local: /caminho/nome_script_barnyard2 start
Para executar o Snorby na inicialização do sistema, crie o script:
#!/bin/bash
cd /var/www/snorby /usr/local/bin/ruby script/delayed_job start -e production
Para executar acrescente no /etc/rc.local:
/caminho/nome_script_snorby
Atualizar o Snorby
O projeto Snorby está em constante desenvolvimento, por isso, se quiser atualizar o seu, é necessário o RAKE:
Entre no diretório de instalação do Snorby:
Vamos utilizar o GIT para a atualização. Diga a ele que seus arquivos estão nesse diretório...
Verifica as atualizações disponíveis:
Atualize as dependências:
Edite o arquivo com as credenciais de acesso ao banco de dados MySQL e coloque o usuário e senha de acesso ao banco do Snorby:
Atualize o Snorby:
Acesse pelo navegador o Snorby: http://<ip_snorby>
Referências:
|
Neste artigo abordaremos um tema fundamental para
administradores de sistemas GNU/Linux e também para usuários avançados
deste sistema: o gerenciamento de pontos de montagem em modo Shell.
Todas as técnicas explanadas neste artigo são aplicáveis a qualquer
distro GNU/Linux.
Espero que este artigo seja útil ao maior número possível de profissionais e usuários do GNU/Linux.
1. FHS - O padrão hierárquico do sistema de arquivos do GNU/Linux
FHS (Filesystem Hierarchy Standard) é o padrão estabelecido pela LSB (Linux Standard Base)
o qual define a estrutura (hierarquia) de diretórios para sistemas
GNU/Linux certificados por este instituto, bem como a localização de
cada tipo de arquivo dentro desta estrutura. O padrão FHS é originário
do sistema Unix.
Dentre as vantagens proporcionadas pelo FHS para sistemas GNU/Linux, destaco as seguintes:
- Facilitar a administração de sistemas baseados em GNU/Linux,
independente da distro adotada, pois proporciona uma estrutura de
diretórios padronizada.
- Proporcionar segurança ao sistema, pois arquivos binários
específicos e fundamentais à administração do sistema são localizados em
diretórios específicos do FHS cujo acesso e execução são restritos ao
usuário root, impedindo sua utilização ou remoção indevidas.
- Facilitar o desenvolvimento de softwares para a plataforma
GNU/Linux, pois define a localização de arquivos específicos como as
bibliotecas compartilhadas do sistema.
Destas vantagens, a que mais nos interessa para o âmbito deste artigo
é a primeira, referente à administração de sistemas GNU/Linux.
Veja na figura a seguir os diretórios do FHS abaixo do diretório raiz (/) do sistema:

2. Pontos de montagem: diretórios “recipientes”
Para podermos ter acesso a dados em discos e partições
(leitura/gravação) precisamos antes montar tal disco ou partição em um
determinado ponto de montagem previamente criado dentro da estrutura de
diretórios do FHS em um sistema GNU/Linux. As montagens poderão ser
feitas manual ou automaticamente, conforme explanarei mais adiante.
Ponto de montagem é um diretório, preferentemente vazio, que será o
“recipiente” do sistema de arquivos do disco ou partição ao qual
queremos ter acesso.
No FHS há dois diretórios indicados para a criação de pontos de montagem:
A maioria dos administradores de sistemas GNU/Linux prefere utilizar o
diretório /media/ para criar pontos de montagem. E eu também.
Portanto,utilizarei este diretório para a criação de pontos de montagem.
3. Identificando discos e partições para montagem: o utilitário blkid
Agora que você já sabe o que são o FHS e pontos de montagem, é
necessário saber identificar os dispositivos (discos e partições)
detectados pelo GNU/Linux para poder montá-los. Basicamente, o GNU/Linux
detecta estes dispositivos automaticamente nos seguintes momentos:
- Na da inicialização do sistema são detectados os dispositivos já
conectados ao sistema (coldplug: conectados à frio) ou já disponíveis
no próprio hardware do computador, como é o caso de partições existentes
no HD.
- Após o sistema já estar inicializado, serão detectados todos os
dispositivos USB, como pendrives, que forem conectados ao sistema
(hotplug: conectados à quente) ou novas partições que forem criadas no
HD, bem como CD/DVD's que forem inseridos.
Obs.: Note que quando você estiver utilizando um desktop (ambiente
gráfico, como GNOME, KDE, XFCE, dentre outros) no GNU/Linux, a montagem
de dispositivos USB (como pendrives) e CD/DVD's é, geralmente, feita
automaticamente, assim que estes forem conectados ou inseridos no
sistema. Para o âmbito deste artigo, considerarei que esta
característica de montagem automática esteja desabilitada no sistema.
Os dispositivos detectados pelo GNU/Linux são identificados como
arquivos especiais dentro do diretório /dev/ do FHS. Para montagem de um
dispositivo (disco ou partição), precisaremos obter as seguintes
informações sobre o mesmo:
- A identificação atribuída ao dispositivo pelo GNU/Linux dentro do diretório /dev/ do FHS.
- O tipo do sistema de arquivos utilizado pelo dispositivo.
Para obter estas informações, abra um Shell (Terminal) do GNU/Linux,
logue-se como superusuário (su) e digite o seguinte comando:
# /sbin/blkid

No exemplo acima, o utilitário blkid identificou os seguintes dispositivos montáveis em meu sistema
01 - hda: um HD master com cinco partições:
- hda1: primeira partição com o tipo de sistema de arquivos NTFS na qual tenho o MS-Windows instalado.
- hda2: segunda partição com o tipo de sistema de arquivos VFAT (FAT32) a qual é utilizada pelo MS-Windows como memória virtual.
- hda5: quinta partição com o tipo de sistema de arquivos Ext3 na qual tenho o CentOS instalado.
- hda6: sexta partição com o tipo de sistema de arquivos SWAP a qual é utilizada pelo CentOS como memória virtual.
- hda7: sétima partição com o tipo de sistema de arquivos NTFS na qual
mantenho documentos e arquivos compartilhados entre os sistemas CentOS e
MS-Windows
02 - sda: um Pendrive (dispositivo USB) com uma única partição:
- sda1: única partição deste dispositivo com o tipo de sistema de arquivos VFAT (FAT32).
03 - hdc: uma unidade de CD/DVD (tipo de sistema de arquivos iso9660).
4. Montagens manuais de discos e partições: o comando mount
Para a montagem de discos e partições os passos a serem seguidos são:
a) Abrir o Shell (Terminal) do GNU/Linux e logar-se como superusuário (su);
b) Identificar o dispositivo que será montado e o tipo de sistema de arquivos do mesmo utilizando o utilitário blkid:
# /sbin/blkid
c) Criar, caso ainda não exista, o ponto de montagem correspondente dentro do diretório /media/ do FHS com o comando mkdir:
# mkdir /media/<ponto_montagem>, onde:
• <ponto_montagem>: é o ponto de montagem, isto é, o diretório “recipiente” para a montagem do dispositivo.
Ex.: # mkdir /media/Docs
d) Montar o dispositivo com o comando mount cuja sintaxe geral é a seguinte:
# mount -t <tipo_sistema_arquivos> <dispositivo> <ponto_montagem>, onde:
• <tipo_sistema_arquivos>: é o tipo de sistema de arquivos
utilizado pelo dispositivo (disco ou partição) a ser montado; esta
informação é obtida com o comando blkid.
• <dispositivo>: é identificação do dispositivo pelo GNU/Linux, por exemplo, /dev/hda1, /dev/sda1, /dev/hdc.
• <ponto_montagem>: é o ponto de montagem (diretório “recipiente”) no qual o dispositivo será montado.
Ex.: # mount -t ntfs-3g /dev/hda7 /media/Docs
Para que fique bem claro a montagem manual de discos e partições apresentarei os três exemplos a seguir:
Exemplo 1 – Montagem de uma partição NTFS local:
Estando logado como superusuário (su) no Shell para montar a partição
/dev/hda7 identificada pelo GNU/Linux como /dev/hda7, a qual utiliza o
tipo de sistema de arquivos NTFS, em um ponto de montagem chamado Docs
(/media/Docs), a sequência de comandos é a seguinte:
# /sbin/blkid # mkdir /media/Docs # mount -t ntfs-3g /dev/hda7 /media/Docs

Obs.: Note que o tipo de sistema de arquivos utilizado pelo
dispositivo /dev/hda7 informado pelo utilitário blkid é NTFS. Porém,
montei informando o tipo ntfs-3g. A explicação para isso é que o tipo
ntfs padrão do comando mount é correspondente ao tipo NTFS utilizado
pelo MS-Windows 2000. A partição em questão foi formatada utilizando o
MS-Windows 7 o qual utiliza um formato NTFS mais recente.
Exemplo 2 – Montagem de um pendrive (dispositivo USB):
Estando logado como superusuário (su) no Shell, para montar um
pendrive identificado pelo GNU/Linux como /dev/sda1 o qual utiliza o
tipo de sistema de arquivos VFAT (FAT32) em um ponto de montagem chamado
USB (/media/USB), a sequência de comandos é a seguinte:
# /sbin/blkid # mkdir /media/USB # mount -t vfat /dev/sda1 /media/USB

Exemplo 3 – Montagem de uma imagem ISO de DVD armazenada no HD local:
Estando logado como superusuário (su) no Shell, para montar um
arquivo de imagem ISO do DVD do CentOS localizada na partição NTFS
(/media/Docs/SO/CentOS-5.4-i386-bin-DVD.iso) de meu HD em um ponto de
montagem chamado ISO (/media/ISO), a qual já está montada, a sequência
de comandos é a seguinte:
# /sbin/blkid # mkdir /media/ISO # mount -t iso9660 -o loop /media/Docs/SO/CentOS-5.4-i386-bin-DVD.iso /media/ISO

Obs.: Note que o tipo de sistema de arquivos utilizado por CD's e
DVD's é iso9660. Para que seja possível navegar pelos diretórios da
imagem ISO como em um diretório normal no sistema é necessário utilizar o
parâmetro -o loop.
5. Desmontagem de discos e partições: o comando umount
Para desmontar um disco ou partição montado no sistema o comando a
ser utilizado é o umount. Para executá-lo, você deverá estar logado em
um Shell (Terminal) do GNU/Linux como usuário superusuário (su) e o
dispositivo (disco ou partição) a ser desmontado não poderá estar em
uso.
Há duas formas de de desmontar um dispositivo com o comando umount:
01 - Informando o ponto de montagem a ser desmontado:
# umount <ponto_montagem>, onde:
- <ponto_montagem>: é o ponto de montagem (diretório “recipiente”) no qual o dispositivo (disco ou partição) foi montado.
Ex.: # umount /media/Docs

02 - Informando o dispositivo a ser desmontado:
# umount <dispositivo>, onde:
- <dispositivo>: é a identificação do dispositivo (disco ou
partição) atribuída ao mesmo pelo GNU/Linux, a qual pode ser obtida com o
utilitário blkid já explanado neste artigo.
Ex.: # /dev/hda7

Obs.: Antes de desmontar dispositivos USB no qual você tenha feito
alterações nos dados armazenados (gravações de dados), execute o comando
sync para fazer uma desmontagem mais segura do dispositivo, evitando
perdas de dados. O comando sync grava no dispositivo todos os dados
armazenados em buffers. Veja um exemplo na figura a seguir:

É isso!
artigo publicado originalmente no iMasters, por Roberto Rodrigues Junior
|
Fonte: Tecnoblog Mark Shuttleworth, fundador da Canonical, afirmou ao The Register
que a proposta do software é abandonar o ciclo de novas versões a cada
seis meses e passar para um modelo de atualizações diárias, no estilo rolling release
- uma modalidade em que as atualizações ocorrem de forma continuada,
sem que seja necessário reinstalar parte do sistema a cada atualização
maior.
Outras distribuições Linux já utilizam esse modelo, como o Gentoo, o Arch e o PCLinuxOS.
Mark
também comentou que o interesse da Canonical é fazer o Ubuntu
acompanhar a velocidade de desenvolvimento de novos softwares e
serviços. "Em um mundo orientado para a internet, precisamos estar
preparados para lançar uma novidade por dia", afirmou Mark.
Agora é aguardar e ver como esse modelo será implementado.
Por Paulo Graveheart
notícia publicada originalmente no iMasters, em 25 de novembro de 2010.
|
A Fundação Linux agora possui seu próprio cartão de crédito, que já está
disponível para consumidores americanos que quiserem apoiar a
iniciativa e os produtos da organização. O cartão funciona sob a
bandeira Visa e surgiu da parceria entre o banco UMB e a CardPartner,
uma empresa que permite que ONGs criem seus cartões de cédito para
arrecadar fundos. De acordo com a Fundação,
o cartão não possui taxa anual, e o usuário ganha pontos é medida que o
utiliza. Cada ativação do cartão dará US$ 50 para a Fundação Linux, que
também receberá uma pequena porcentagem das transações feitas com ele. A
receita será utilizada em "eventos técnicos da entidade e no
financiamento das viagens dos membros da comunidade open-sorce, de modo a
acelerar a inovação do Linux". O cartão provavelmente não estará
disponível fora dos Estados Unidos por causa da dificuldade de
encontrar parceiros em outros países, afirmou a Fundação Linux. Com informações de Geek
notícia publicada originalmente no iMasters, em 03 de novembro de 2010.
|