Personalizando o BASH

O BASH é uma interface de interação(shell) e também uma linguagem de programação. Existem outras alternativas de shell, mas no GNU/Linux o BASH é o mais utilizado.

Por ser uma linguagem de programação, obiviamente, o BASH possui suporte a variáveis. Essas variáveis podem ser do tipo local ou global.

As variáveis locais são válidas apenas no shell onde foram criadas, não é possível que um ‘processo filho’ utilize as variáveis locais de um ‘processo pai’. A sintaxe para definir uma variável local é:



nomeVariavel='valor'

Para acessar o valor de uma variável é necessário utilizar o sinal ‘$’, veja um exemplo:



nomeVariavel='valor'

echo $nomeVariavel

# imprime valor

É importante salientar, que diferente de outras linguagens, não deve haver espaços entre o nome da variável, o sinal de igual(=) e o valor da variável.

Para tonar uma variável local acessível para ‘processos filhos’ é utilizado o comando ‘export’, assim:



export nomeVariavel='valor'

As variáveis globais são aquelas acessíveis por todos os porcessos, geralmente essas variáveis contém valores com informações e configurações do BASH. Por exemplo:

  • $PS1 Define a string do prompt do BASH
  • $PATH Define o caminho utilizado para encontrar os programas
  • $HOME Define o diretório home do usuário

O comando ‘env’ lista as variáveis globais e o comando ‘set’ lista todas as variáveis.

Para automatizar a configuração de variáveis é possível utilizar alguns arquivos especiais. São eles:

  • /etc/profile
  • /etc/bashrc
  • ~/.bash_profile
  • ~/.bash_login
  • ~/.profile
  • ~/.bashrc
  • ~/.bash_logout

O arquivo ‘/etc/profile’ é executado durante o processo de autenticação. O arquivo ‘/etc/bashrc’ é executado quando o BASH é inicializado.

Por exemplo, quando é realizado o login através do terminal com ‘ctrl + alt + F2’, o arquivo ‘/etc/profile’ e o arquivo ‘/etc/bashrc’ serão executados porquê ocorreu o login e o bash foi inicializado. Quando é aberto um shell através da interface gráfica( xterm ), apenas o arquivo ‘/etc/bashrc’ será executado porquê o BASH foi inicializado, mas não houve login.

Os arquivos ‘/etc/profile’ e ‘/etc/bashrc’ são executados para todos os usuários, ou seja, a configuração realizada neles ocorre em todos os usuários do sistema. Em alguns casos é necessário realizar configurações especifcas por usuário, para isso existem os arquivos ‘~/.bash_profile’, ‘~/.bash_login’, ‘~/.profile’, ‘~/.bashrc’ e ‘~/.bash_logout’.

Esses arquivos ficam na pasta home de cada usuário. Na maioria das vezes apenas alguns desses arquivos são necessários e realmente estão na pasta home do usuário. Porém, é acerto afirmar que algum deles estará na pasta home de cada usuário do sistema.

Esses arquivos são executados assim:

Depois do ‘/etc/profile’: Primeiramente é procurado o arquivo ‘~/.bash_profile’, se esse não existir, é procurado o ‘~/.bash_login’, se esse também não existir, é procurado ‘~/.bash_login’. Perceba que apenas um desses arquivos será executado… Quando um desses arquivos é encontrado, ele é executado e o BASH para de procurar.

Depois do ‘/etc/bashrc’: ‘~/.bashrc’

Antes do logout: ‘~/.bash_logout’

Esse artigo termina aqui, mas vale lembrar que no Ubuntu existem algumas diferenças… No Ubuntu existe o arquivo ‘/etc/bash.bashrc’ e o arquivo ‘/etc/environment’. Fica como ‘lição de casa’ pesquisar o que cada um deles faz 🙂

Agendar tarefas no GNU/Linux

Nesse artigo quero mostrar como agendar tarefas no GNU/Linux… Para realizar os exemplos estou utilizando o Ubuntu 12.04.

No GNU/Linux existem duas alternativas para criar agendamentos de tarefas. O at, que é indicado quando a tarefa agendada deve ser executada uma única vez e o cron, que é utilizado quando a tarefa deve ser executada regularmente (de tempos em tempos).

At

A sintaxe para utilizar o comando at é a seguinte: at horário caminho_completo_comando

Na posição do horário é possível utilizar vários tipos de formatos. No arquivo /usr/share/doc/at/timespec existe uma lista com todos os formatos.

Veja um exemplo de como agendar uma tarefa no at para hoje às 20 horas:



at 8pm

Nesse momento será aberto um novo shell onde o comando deve ser digitado. No meu Ubuntu esse shell possui a seguinte aparência:



at 8pm
warning: commands will be executed using /bin/sh
at>

Após terminar de digitar o comando, utilize o atalho ctrl + d para salvar o agendamento. Esse atalho indica o final de arquivo( EOF ), ou seja, o at entende que o comando foi digitado e deve ser salvo(agendado).

Com isso, o comando foi agendado… Para visualizar a lista de comandos agendados com o at é usado o comando atq ou at -l. Veja um exemplo da saída desse comando:


atq
9 Mon Feb 8 20:00:00 2015 a paulo

Apesar de listar as tarefas agendadas com o horário de execução, através desse comando não é possível verificar quais os comandos serão executados em cada tarefa. Para tanto, é possível visualizar os detalhes de cada tarefa com o seguinte comando:


at -c 9

Onde o número 9 é o id da tarefa. O id é o primeiro número que aparece para cada tarefa listada pelo atq.

Já para remover um comando previamente agendado, é utilizado o comando atrm. A sintaxe desse comando é a seguinte: atrm id

Veja um exemplo onde a tarefa agendada para às 20 horas é removida:


atrm 9

Para definir quais usuários podem ou não executar tarefas no at existem 2 arquivos de controle, são eles: /etc/at.allow e /etc/at.deny

Se o arquivo /etc/at.allow não existir, o arquivo /etc/at.deny será verificado… Se nenhum dos 2 arquivos existirem, apenas o usuário root poderá criar tarefas agendadas.

Cron

Para agendar tarefas no cron é utilizado o comando: crontab -e

O comando crontab -e abre um arquivo (tabela) onde deve ser digitado o comando que vai ser agendado. Essa tabela possui a seguinte aparência no meu sistema:


...
# m h dom mon dow command

Nessa tabela temos 6 campos, da direita para esquerda são: Minuto, hora, dia do mês, mês, dia da semana e comando.

Veja um exemplo de como agendar uma tarefa que vai ser executada todos os dias às 20 horas:


# m h dom mon dow command

0 20 * * * echo 'paulo' > /dev/pts/0

Nessa tabela é possível utilizar alguns caracteres especiais, por exemplo, o * indica que para essa coluna o comando deve ser executado em todos os casos… Além desse, é possível utilizar os seguintes caracteres:

  • ( , ) Para indicar mais de um valor, por exemplo, no mês 5 e 6 é igual a 5,6
  • ( – ) Para indicar um intervalo, por exemplo, do dia 10 até o dia 20 é igual a 10-20
  • ( / ) Para indicar um passo(incremento), por exemplo, executar a cada 5 minutos é igual a */5

Veja um exemplo onde uma tarefa é agendada para executar nos dias 3, 6, 7 e 8, iniciando às 20h e que seja repetida a cada 2 minutos até às 21h:


# m h dom mon dow command

*/2 20 3,6-8 * * echo 'paulo' > /dev/pts/0

Da mesma forma que acontece com o at, existem 2 arquivos para controlar quem pode agendar tarefas no cron, são eles: /etc/cron.allow e /etc/cron.deny. Porém, se nenhum dos 2 existir, diferente do que acontece com o at, todos os usuários poderão agendar tarefas no cron.

Além de escrever comandos diretamente na tabela cron, também é possível agendar tarefas usando as seguintes pastas: /etc/cron.hourly, /etc/cron.daily, /etc/cron.weekly e /etc/cron.monthly.

Para agendar uma tarefa, basta criar um shell script e move-lo para a pasta correspondente… O script será executado conforme a pasta. De hora em hora(cron.hourly). Diariamente(cron.daily). Semanalmente(cron.weekly). Mensalmente(cron.monthly)

Bom pessoal, obviamente, esse artigo não mostra todas as possibilidades desses comandos, mas vou encerrar por aqui… Quem tiver interesse em saber mais pode verificar os links a seguir e ler o manual de cada comando através do comando man, veja um exemplo: man at

http://www.dltec.com.br/blog/linux/agendando-tarefas-com-o-comando-at-no-linux/ http://www.vivaolinux.com.br/artigo/Usando-cron-e-crontab-para-agendar-tarefas

Administração de usuários no Ubuntu 12.04

Nesse artigo vou escrever sobre a administração de usuários no GNU/Linux. Estou usando o Ubuntu 12.04 para realizar os testes, mas tudo deve ocorrer normalmente em outras distribuições.

No GNU/Linux existem 4 arquivos que são usados para administrar usuários, são eles:

  • /etc/passwd
  • /etc/shadow
  • /etc/group
  • /etc/gshadow

Observaçãp: Você pode consultar o manual desses arquivos com o seguinte comando: man 5 nome_arquivo.

O arquivo /etc/passwd é responsável por armazenar informações da conta de cada usuário. Ele segue a seguinte estrutura:


usuario : x : id_usuario : id_grupo_primario : infos( gecos ) : caminho_home : caminho_shell

Para ver o conteúdo desse arquivo execute o seguinte comando no terminal:


getent /etc/passwd

O arquivo /etc/shadow armazena as senhas dos usuários ( na verdade um hash delas ) e infomações relacionadas ao tempo de validade das senhas.

Antigamente o arquivo passwd guardava a senha do usuário, mas por segurança essa informação foi migrada para o shadow. Assim, a senha no arquivo passwd foi substituida por um x, indicando dessa forma que o sistema faz uso do arquivo shadow.

Para visualizar o conteúdo do arquivo /etc/shadow você também pode usar o comando getent, mas é necessário utilizar o usuário root( sudo ) ou um usuário que esteja no grupo shadow.

O arquivo /etc/group armazena informações sobre os grupos do sistema. Ele segue a seguinte estrutura:


grupo : x : id_grupo : usuarios_dentro_do_grupo

Da mesma forma que os arquivos anteriores, é possível usar o comando getent para visualizar o conteúdo desse arquivo.

O arquivo /etc/gshadow é responsável por armazenar as senhas dos grupos.

Conhecendo as estruturas desses arquivos e tendo as permissões necessárias é possível fazer qualquer tipo de admnistração de usuários no GNU/Linux. Porém, não é recomendado alterar esses arquivos manualmente, o ideal é utilizar os seguintes comandos:

  • chage
  • passwd
  • usermod
  • groupmod
  • useradd
  • userdel
  • groupadd
  • groupdel

O comando chage serve para alterar caracteristicas da senha do usuário.

Veja a saida do comando ‘chage -l paulo’ no meu sistema:



Última mudança de senha : Out 28, 2014
Senha expira : nunca
Senha inativa : nunca
Conta expira : nunca
Número mínimo de dias entre troca de senhas : 0
Número máximo de dias entre troca de senhas : 99999
Número de dias de avisos antes da expiração da senha : 7

Essas informações também podem ser alteradas com o comando chage, por exemplo, com o comando a baixo altera a data de expiração da conta:


sudo chage -E 11/09/2020 paulo # a data está no padrão mm/dd/aaaa

Para saber mais utilize o comando man chage.

No GNU/Linux além de um arquivo passwd, também existe um comando com esse mesmo nome. O comando passwd serve para alterar a senha de um usuário. ( evidente que é necessário permissões de administrador para trocar a senha de outro usuário ). O seguinte comando altera a senha do usuário ‘paulo’:


passwd paulo

Tendo as devidas permissões também é possível bloquear a conta de um usuário com o comando passwd. Veja:


sudo passwd -l paulo #bloqueia
sudo passwd -u paulo #desbloqueia

Através do comado usermod também é possível alterar várias informações da conta de um usuário. Entre outras, é possível alterar os grupos, o diretório home e o shell do usuário:


sudo usermod -G adm,cdrom,sudo paulo # altera os grupos
sudo usermod -d /home/paulo2 paulo # altera o home
sudo usermod -s /bin/csh paulo # altera o shell

Veja mais com o comando man usermod.

Assim como o usermod serve para fazer alterações nos usuários o comando groupmod faz alterações nos grupos:


groupmod -n novo antigo

Esse comando altera o nome do grupo ‘antigo’ para ‘novo’.

O comando useradd é utilizado para inserir um novo usuário no sistema. Veja:


sudo useradd -m -s /bin/bash paulo

Nesse exemplo o -m é para criar o diretório home e o -s é para especificar o shell do novo usuário. Depois de criar o usuário ainda é necessário utilizar o comando passwd para especificar uma senha, somente depois disso o usuário poderá ser usado.

Para remover um usuário no sistema é utilizado o comando userdel assim:


sudo userdel -r paulo

É importante utilizar o -r para garantir que o diretório home do usuário será removido.

O comando groupadd serve para adicionar um grupo no sistema, veja o exemplo:


sudo groupadd grupo

E para remover um grupo é usado o comando groupdel:


sudo groupdel grupo

Para remover um grupo que seja primário de algum usuário é necessário primeiro excluir o usuário com o comando userdel.

Feito, por hoje é isso! Existem vários outros comandos que são utéis para admnistração de usuários no GNU/Linux, segue mais alguns comandos para quem quiser saber mais: id, finger, chfn, adduser( debian-like ), who, users, fuser …

T+

Sistema de arquivos

O sistema de arquivos do GNU/Linux pode ser representado como uma árvore de cabeça para baixo… No topo dessa arvore fica o diretório raiz( / ).  Dentro do diretório raiz encontramos os seguinte diretórios:

bin Arquivos executáveis
boot Arquivos essências para a carga do sistema. É aqui que fica a imagem do kernel
dev Arquivos que representam dispositivos do sistema
etc Arquivos de configuração do sistema
home Diretórios dos usuários
lib Bibliotecas do sistemas. Usadas pelos programas e módulos do kernel
mnt Diretório para montagem de dispositivos ( Em alguns casos existe o diretório media com a mesma utilidade )
proc Informações do sistema e dos processos atuais
opt Programas que não fazem parte da distribuição
root Diretório do super usuário ( root )
sbin Programas do super usuário ( programas/comandos de administração )
tmp Arquivos temporários. O conteúdo desse diretório é apagado a cada reboot
usr Programas usados pelos usuários
var Arquivos variáveis. Logs e arquivos de email

Essa estrutura foi definida por um padrão de mercado criado pelo comunidade em 1994, chamado Filesystem Hierarchy Standard ( FHS ). As distribuições não precisam seguir esse padrão, mas existe uma grande conscientização sobre a importância desse padrão.

GNU/Linux – Trabalhando com textos

Oi pessoal, tudo bem? Hoje vou mostrar alguns comandos do GNU/Linux para trabalhar com arquivos de texto. O GNU/Linux possui uma grande quantidade de comandos para trabalhar com arquivos de textos, mas nesse artigo vou escrever apenas sobre os seguintes comandos:

 

    • cat
    • tac
    • cut
    • head
    • tail
    • join
    • nl
    • tr

 

Apesar de não aparecerem nessa lista, existem 2 comandos( linguagens ) que precisam ser lembrados… O primeiro deles é o awk, já escrevi sobre ele aqui, e o outro é o sed, que vou dedicar um artigo exclusivo futuramente.

Bem, feito a declaração inicial, vejamos os comandos desse aritgo.

cat

O comando cat serve para visualizar, concatenar e criar arquivos.

Para visualizar um arquivo utilize o comando cat da seguinte forma:

cat caminho_para_o_arquivo

Veja:

 


cat /etc/passwd

Para concatenar arquivos utilize o comando cat assim:

cat arquivo1 arquivo2 arquivo3 >> arquivo123.

Veja:


cat /etc/environment /etc/profile >> arquivo_final

Para criar arquivos utilize o comando cat da seguinte maneira:

cat > arquivo.

Veja:


cat > arquivo

O prompt vai ser aberto para digitação, para encerrar a escrita utilize ‘ctrl + d’

tac

O comando tac funciona da mesma forma que o comando cat, porém coloca as linhas na ordem contrária.

cut

O comando cut serve para cortar partes de um arquivo de texto. Esse comando geralmente é usado com arquivos do tipo CSV.

Veja:


cut -d : -f 1 /etc/passwd

Dessa forma o comando cut vai mostrar apenas a primeira coluna (primeiro campo de cada linha).

-d Delimitador
-f O campo que vai ser exibido

head

O comando head serve para visualizar um arquivo a partir do inicio( cabeça ). É possível limitar a quantidade de linhas que serão exibidas da seguinte maneira:


head -n 10 /etc/passwd

Nesse exemplo a saída vai ser as 10 primeiras linhas do arquivo /etc/passwd

tail

O comando tail serve para visualizar um arquivo a partir do final( cauda ). Da mesma forma que o head é possível limitar a quantidade de linhas que serão exibidas da seguinte maneira:


tail -n 10 /etc/passwd

Nesse exemplo a saída vai ser as 10 últimas linhas do arquivo /etc/passwd

join

O comando join faz a junção de arquivos que tenham um campo com índice comum.

Veja:

arquivo1

1 paulo
2 andre
3 junior

arquivo2

1 10
2 9
3 10

 


join -j 1 arquivo1 arquivo2

A saída vai ser:

1 paulo 10
2 andre 9
3 junior 10

nl

O comando nl serve para numerar as linhas de um arquivo, veja:


nl /etc/passwd

tr

O comando tr é um tradutor… Com ele é possível substituir um caracterer por outro…

veja:


cat /etc/passwd | tr a-z A-Z

Esse comando vai alterar as letras minúsculas do arquivo /etc/passwd para maiúsculas.

Outra possibilidade desse comando é retirar caracteres repetidos, por exemplo:


echo "paaaaaaulo" | tr -s a

E também é possível apagar caracteres de um arquivo, assim:


echo "paulo" | tr -d a

Chegamos ao fim de mais um artigo… Claro que existem várias outras possibilidades para esses comandos, para saber mais, utilize o comando man.

Assim:

man nome_comando

Segue alguns links:

http://www.prminformatica.com.br/2014/01/awk.html
http://thobias.org/doc/inc_sed.html

Como montar um servidor LTSP no Ubuntu

O que é LTSP?

Nessa semana eu tive que instalar um servidor LTSP em uma escola aqui da minha cidade. Utilizei o sistema Ubuntu e o processo de instalação e configuração foi extremamente simples. Segue algumas imagens de como ficou o laboratório:

Observação: Algumas máquinas nas imagens não estão utilizando o servidor LTSP

Nesse artigo vou mostrar os passos que usei para ter o servidor e todos as máquinas clientes funcionando. No meu caso, a maioria dos clientes são equipamentos especializados chamados thin client, mas também é possível utilizar computadores comuns, desde que eles tenham suporte ao boot pela rede (sendo necessário apenas um mínimo de memória ram e não sendo necessário ter um HD na máquina ). Para o servidor é necessário ter duas placas de rede, um bom processador e quanto mais memória ram melhor. Para calcular a quantidade mínima de memória do servidor utilizei a seguinte fórmula: 2GB + (numeroClientes * 512MB).

Os passos necessários são:

1 – Instalar o Ubuntu com a seguinte tabela de partições: *valores aproximados

100MB /dev/sda1 /boot
16GB /dev/sda2 swap
250GB /dev/sda3 /
250GB /dev/sda4 /home

Observação: Você pode alterar as partições conforme a sua necessidade.

2 – Configurar a rede através do arquivo /etc/network/interfaces:

 
auto eth0
iface eth0 inet dhcp

auto eth1
iface eth1 inet static
address 192.168.0.1
netmask 255.255.255.0

Observação: A interface de rede eth0 fica conectada na internet e a eth1 nos clientes.

3 – Instalar os serviços:

 
sudo apt-get install ltsp-server-standalone openssh-server

4 – Configurar os arquivos /etc/ltsp/dhcpd.conf e /etc/default/isc-dhcp-server

O arquivo /etc/ltsp/dhcpd.conf já estava preenchido, foi necessário apenas adaptar as configurações de rede. Esse arquivo têm essa aparência:


authoritative;

subnet 192.168.0.0 netmask 255.255.255.0 {
    range 192.168.0.20 192.168.0.250;
    option domain-name "example.com";
    option domain-name-servers 192.168.0.1;
    option broadcast-address 192.168.0.255;
    option routers 192.168.0.1;
#    next-server 192.168.0.1;
#    get-lease-hostnames true;
    option subnet-mask 255.255.255.0;
    option root-path "/opt/ltsp/i386";
    if substring( option vendor-class-identifier, 0, 9 ) = "PXEClient" {
        filename "/ltsp/i386/pxelinux.0";
    } else {
        filename "/ltsp/i386/nbi.img";
    }
}

No arquivo /etc/default/isc-dhcp-server foi necessário apenas configurar a interface de rede que se conecta nos clientes:

 
INTERFACES=”eth1″

5 – Criar os usuários para os clientes.

 
sudo adduser

6 – Criar e atualizar a imagem do sistema para os clientes:

 
sudo ltsp-build-client --arch i386 #esse cria a imagem dos clientes, vai demorar :)

sudo ltsp-update-sshkeys 

sudo ltsp-update-image

Observação: No primeiro comando, também é possível usar o parâmetro –dist para especificar um versão diferente do ubuntu. Exemplo: lucid ou precise.

7 – Reiniciar o servidor

 
sudo reboot

8 – Configurar os clientes para dar boot pela rede

Observação: Isso pode ser feito de várias maneiras diferentes dependendo da bios dos clientes. Procure onde é configurada a ordem de boot e altere para LAN, network ou PXE.

Pronto, se você seguiu os passos de forma correta, o seu servidor LTSP já está funcionando.

Segue alguns links para ajudar e complementar esse artigo:

http://www.hardware.com.br/termos/pxe
https://www.youtube.com/watch?v=LJt9VIqWfDY
https://fedorahosted.org/k12linux/wiki/InstallGuide

Precisa trabalhar com arquivos de texto ? AWK!

Eae pessoal, nos últimos meses eu tive que usar bastante a linguagem C para manipular arquivos de texto (txt). Apesar de ser uma linguagem poderosa, trabalhar com esses arquivos em C pode ser bem complicado. Pensando nisso, quero mostrar nesse artigo uma linguagem mais especialiazada em manipulação de arquivos de texto ( lembre-se, para quem só sabe usar martelo, tudo é prego ).

Essa linguagem é a AWK, ela foi criada em 1977 pelos cientistas Alfred Aho, Peter J. Weinberger e Brian Kernighan no laboratório Bell Labs.

Para criar os exemplos vou utilizar o arquivo “/etc/passwd”, e para que tudo ocorra de forma segura fiz uma copia desse arquivo para pasta home do meu usuário. Faça você também:



cp /etc/passwd $HOME

O meu arquivo passwd têm essa aparência:


saned:x:110:120::/home/saned:/bin/false
ntp:x:111:121::/home/ntp:/bin/false
rtkit:x:114:123:RealtimeKit,,,:/proc:/bin/false
mdm:x:108:112:Gnome Display Manager:/var/lib/mdm:/bin/false
paulo:x:1000:1000:paulo:/home/paulo:/bin/bash

Perceba que é um arquivo CSV separado por ‘:’ . Cada linha desse arquivo representa um usuário do sistema, sendo que os campos estão organizados assim:

login: senha : Id do usuario : Id do grupo : extras : pasta home : shell

Para iniciar, vou apenas usar o AWK para imprimir o arquivo no terminal, para isso digite o seguinte comando ( no terminal ) :



awk '{ print }' $HOME/passwd

O AWK fez a leitura de cada linha (uma por uma) do arquivo passwd e imprimiu na saida padrão( monitor ). Isso não é muito util, afinal, o comando cat também pode fazer isso e com uma sintaxe mais simples ( cat $HOME/passwd ). Agora vou tentar algo um pouco mais elaborado, vou imprimir o arquivo novamente, mas apenas o primeiro campo (login).



awk -F: '{ print $1 }' $HOME/passwd

Dessa vez eu utilizei o parametro -F, que especifica o separador de campos utilizado no arquivo ( nesse caso :, sem isso, o separador padrão é o TAB ou ” ” ) e passei a variável $1 ( que representa o primeiro campo ) para o print. Para cada campo da linha que esta sendo processada existe uma variável $n, onde n é a posicao do campo apartir do 1, A variavel $0 contém a linha inteira.

Para o próximo exemplo quero imprimir apenas quem utiliza o shell Bash:



awk -F: '{ if( $7 == "/bin/bash" ) print $1 }' $HOME/passwd

Obs. AWK utiliza os mesmos operadores condicionais e lógicos do C

Funcionou, mas ainda é possível melhorar a aparência dessa saída:



awk -F: ' { if( $7 == "/bin/bash" ) printf "%s usa o shell %s n", $1, $7 }' $HOME/passwd

Obs. Perceba que o printf do AWK é quase igual ao do C, ele aceita vários formatos, por exemplo: %d, %i, %f, %s e outros.

Assim fica melhor, né? No próximo exemplo quero finalizar a saída com a quantidade de campos encontrados:



awk -F: '{ if( $7 == "/bin/bash" ) { printf "%s usa o shell %s n", $1, $7; total++ } } END { printf "Total de registros %d n", total }' $HOME/passwd

Nesse exemplo utilizei o bloco END, esse bloco é executado depois que o AWK processou todo conteúdo do arquivo. Diferente do C em AWK não é necessário instanciar uma variavel. Na primeira vez que uma variável é mencionada o AWK automaticamente cria uma instância e atribui um valor inicial, para números esse valor é 0 e para strings é “”.

Caso seja necessário também é possível especificar um bloco BEGIN que é executado antes do AWK processe o conteúdo do arquivo.

O exemplo anterior ficou um pouco grande para ser executado direto no terminal, para facilitar a escrita, é possivel utilizar a AWK em forma de script, para isso basta criar um arquivo que inicie com a linha “#!/usr/bin/awk -f” e escrever os comandos nas linhas seguintes. Vai ser necessário fazer algumas adaptações, exemplo anterior em forma de script fica assim:


#!/usr/bin/awk -f

BEGIN {
FS=":";
}

{
if( $7 == "/bin/bash") {

printf "%s usa o shell %s n", $1, $7;
total++;
}
}

END {
printf "Total de registros %d n", total
}

A principal diferença é que no lugar de especificar o separador através do parametro -F, utilizo a variavel padrão FS, dentro do bloco BEGIN.

Salvei o script no arquivo teste.awk, depois dei permissão de execução para ele através do comando “chmod +x teste.awk” e para executar basta escrever no terminal “./teste.awk $HOME/passwd” . Assim fica parecido com shell script, né? ( não sabe o que é shell script? clique aqui )

Continuando, agora eu quero mostrar apenas as linhas onde o login tenha menos de 4 letras:


#!/usr/bin/awk -f

BEGIN {
FS=":";
}

{
if( length( $1 ) < 4) {

printf "%s n", $1;
total++;
}
}

END {
printf "Total de registros %d n", total
}

Nesse exemplo utilizei a função length que retorna o tamanho de uma string. Algumas das funções do AWK para trabalhar com strings são:

index( s1, s2 ) retorna a posição da string s1 na string s2
gsub( sO, sS, s ) substitui a string original sO pela a string substituta sS na sting s
length( s ) retorna o tamanho da string s
split( s, v, d ) quebra a string s usando o delimitador d e coloca no vetor v
substr( s, i, f ) retorna a parte da string s que inicia na posição i e termina na posição f

AWK também têm funções para trabalhar com números, alguma delas são:

sqrt( n ) raiz quadrada
sen( n ) seno
cos( n ) cosseno
int( n ) a parte inteira de n

No próximo exemplo vou redirecionar a saída para um arquivo e vou alterar o shell de todos os usuários que usam o “/bin/sh” para o “/bin/bash”:


#!/usr/bin/awk -f

BEGIN {
FS=":";
}

{
if( $7 == "/bin/sh") $7 = "/bin/bash";

for( i = 1; i < 8; i++ ) printf "%s:", $i >> "bkp";

print "" >> "bkp"; #pra quebrar a linha
}

Obs1. A AWK também possui uma instrução while, que assim como o for tem uma sintaxe idêntica a do C
Obs2. Os comentários em AWK são feitos com #

O exemplo anterior foi escrito ao estilo C propositalmente, eu queria mostrar como é a instrução for, o jeito AWK de fazer isso é utilizando a função gsub, assim:



#!/usr/bin/awk -f
{
gsub( "/bin/sh", "/bin/bash", $0 )

print $0 > "bkp"
}

Pessoal por hoje é isso, tem muito mais para mostrar sobre o AWK, mas fica para um próximo artigo. Para quem quiser continuar estudando o AWK, aqui fica alguns links…

http://www.inf.pucrs.br/~manssour/AWK/
http://pt.wikipedia.org/wiki/AWK
http://br-linux.org/artigos/awk_intro.htm

Bitwise. Escovar Bits

Oi, tudo bem? Depois de um tempo parado com as postagens do blog, hoje vou mostrar como trabalhar com operadores de bits em C. Essa técnica é conhecida como bitwise (e também como “escovar bits”), trata-se basicamente de usar alguns operadores para alterar a sequência de bits de uma variável.

Em C, cada variável têm um tipo, e cada um desses tipos têm um tamanho diferente( quantidade de bits ). Por exemplo, uma variável do tipo char têm o tamanho de 8 bits ( o que equivale a 1 byte ) e uma variável do tipo int geralmente têm 32 bits ( 4 bytes ).

Os principais operadores bitwise são:

  • Operador & ( and )
  • Operador | ( or )
  • Operador ^ ( xor )
  • Operador ~ ( not )
  • Operador >> ( right shift )
  • Operador << ( left shift )

Esses operadores funcionam da seguinte maneira:

& (and)

O operador & compara os bits de cada variável um por um, quando os dois bits (um da variável ‘a’ e outro da variável ‘b’) são iguais a 1 (bit ligado) o retorno é 1, caso contrário o retorno é 0.



char a = 1; // 0000 0001
char b = 5; // 0000 0101

char c = a & b; // 0000 0001

| (or)

O operador | também compara os bits de cada variável um por um, quando pelo menos um dos bits é igual a 1 o retorno é 1, caso contrário o retorno é 0.



char a = 1; // 0000 0001
char b = 5; // 0000 0101

char c = a | b; // 0000 0101

^ (xor)

O operador ^ compara os bits de forma que se os 2 bits( um da variável ‘a’ e outro da variável ‘b’ ) forem iguais ele retorna 0, caso contrario ele retorna 1.



char a = 1; // 0000 0001
char b = 5; // 0000 0101

char c = a ^ b; // 0000 0100

~ (not)

O operador ~ inverte os bits de uma variável, onde era 1 fica 0 e onde era 0 fica 1.



char a = 1; // 0000 0001

char b = ~a; // 1111 1110

<< (left shift) e >> (right shift)

Os operadores << e >> fazem o deslocamentos dos bits para direita e para a esquerda. Preenchendo o restante com 0.



char a = 1; // 0000 0001
char b = a << 2; // 0000 0100

char c = b >> 2; // 0000 0001

Nesses exemplos, utilizei os valores em base 10, mas em C, também é possível especificar valores em binario e hexadecimal. Para isso basta usar a seguinte sintaxe:



char a = 0b101; // binario
char b = 0xff; // hexa

Para tentar apresentar melhor esses operadores vou usar como exemplo um controle de quartos de um hotel. Nesse controle só é necessário saber se o quarto está livre ou se está ocupado. O hotel vai ter 8 quartos e vou armazenar as informações em uma única variável do tipo char, ou seja, cada bit vai representar um quarto. Esse não é um exemplo realista, mas com ele é possível ter uma idéia de como trabalhar com operadores de bits.

O programa inicia assim:



int main(int argc, char **argv)
{
char hotel;

hotel = 0b101; //temos 2 quartos ocupados ( 0000 0101 )

return 0;
}

O primeiro passo é desenvolver uma função para verificar se um determinado quarto está ocupado:



// o quarto é um valor entre 0 e 7 inclusive,
// seria importante testar esse valor
int estaOcupado( char hotel, int quarto )
{
char teste = 1; // 0000 0001

// rotaciona para que o bit ligado fique no quarto desejado
teste = teste << quarto;

// se o retorno for diferente de 0 o quarto esta ocupado
return hotel & teste;
}

int main(int argc, char **argv)
{
char hotel;

hotel = 0b101;

if( estaOcupado( hotel, 0 ) )
printf(" O quarto 0 esta ocupado n" );

return 0;
}

Agora vou desenvolver uma função para ocupar um quarto



void ocuparQuarto( char* hotel, int quarto )
{
char teste = 1; // 0000 0001

teste = teste << quarto;

// o bit ligado do teste garante que o quarto vai ficar ocupado,
// os outros bits do teste estão desligados e não vão alterar o hotel
*hotel = *hotel | teste;
}

int estaOcupado( char hotel, int quarto )
{
char teste = 1; // 0000 0001

teste = teste << quarto;

return hotel & teste;
}

int main(int argc, char **argv)
{
char hotel;

hotel = 0b101;

if( estaOcupado( hotel, 1 ) )
printf(" O quarto 1 esta ocupado n" );
else
printf(" O quarto 1 nao esta ocupado n" );

ocuparQuarto( &hotel, 1 );

if( estaOcupado( hotel, 1 ) )
printf(" O quarto 1 esta ocupado n" );
else
printf(" O quarto 1 nao esta ocupado n" );

return 0;
}

Por último tenho uma função para liberar um quarto:



void liberarQuarto( char* hotel, int quarto )
{
char teste = 1; // 0000 0001

teste = teste << quarto;

// inverte o teste, 0000 0001 fica 1111 1110
teste = ~teste;

// o bit desligado do teste garante que o quarto vai ser liberado,
// os bits ligados do teste não alteram o hotel.
*hotel = *hotel & teste;
}

void ocuparQuarto( char* hotel, int quarto )
{
char teste = 1; // 0000 0001

teste = teste << quarto;

*hotel = *hotel | teste;
}

int estaOcupado( char hotel, int quarto )
{
char teste = 1; // 0000 0001

teste = teste << quarto;

return hotel & teste;
}

int main(int argc, char **argv)
{
char hotel;

hotel = 0b101;

if( estaOcupado( hotel, 1 ) )
printf(" O quarto 1 esta ocupado n" );
else
printf(" O quarto 1 nao esta ocupado n" );

ocuparQuarto( &hotel, 1 );

if( estaOcupado( hotel, 1 ) )
printf(" O quarto 1 esta ocupado n" );
else
printf(" O quarto 1 nao esta ocupado n" );

liberarQuarto( &hotel, 1 );

if( estaOcupado( hotel, 1 ) )
printf(" O quarto 1 esta ocupado n" );
else
printf(" O quarto 1 nao esta ocupado n" );

return 0;
}

Bom pessoal é isso, sei que o exemplo não é muito real, mas vou deixar alguns links para quem quiser saber mais sobre a arte de escovar bits. Até a próxima postagem 🙂

http://www.diogomatheus.com.br/blog/php/operadores-bitwise-bit-a-bit/
http://samuca.wordpress.com/2007/03/26/operadores-bitwise/
http://blog.bsoares.com.br/aspnet/operacoes-binarias

Permissões especiais: SUID, SGID e STICKY

Hoje quero mostrar as permissões especiais do linux: SUID, SGID e STICKY. Esses bits podem ser aplicados em determinadas situações para se conseguir um comportamento bem especifico.

Esses bits têm as seguintes características:

SUID

Esse bit só pode ser aplicado em arquivos executáveis. Basicamente, quando esse bit está ativado o arquivo é executado com as permissões do dono dele e não com as permissões de quem executou. Por exemplo, um arquivo executável onde o dono é o root e o bit SUID está ativado, sempre roda com as permissões do root, ou seja, qualquer usuário pode executa-lo com privilégios de administrador.

SGID

O bit SGID quando é aplicado em um arquivo executável, funciona de forma parecida com o SUID, mas é usada a permissão do grupo do arquivo e não do dono. Além disso, esse bit pode ser aplicado em diretórios, quando isso acontece, tudo que for criado dentro desse diretório terá o grupo dele, ou seja, se o diretório pai tem o bit SGID ativado, tudo que for criado dentro dele terá o seu grupo e não o do usuário que criou.

STICKY

O bit STICKY geralmente é utilizado em diretórios públicos (777) onde todos os usuários podem gravar e apagar arquivos. Esse bit altera a capacidade dos usuários apagarem arquivos/diretórios dos quais não sejam donos, ou seja, o bit STICKY interfere na permissão de apagar arquivos/diretórios, permitindo apenas que o usuário apague os seus arquivos/diretorios (onde ele é dono), mesmo que ele tenha a permissão necessária para apagar arquivos de outros usuários. (o root obviamente não sofre esse bloqueio )

Como aplicar essas permissões

Para ativar esses bits você pode usar o comando chmod de forma octal colocando um digito a mais no inicio da sequencia de dono, grupo e outros.( X777 )

Para ativar o SUID : chmod 4777

Para ativar o SGID : chmod 2777

Para ativar o STICKY : chmod 1777

OBS: não precisa ser sempre X777, as 3 últimas você define como quiser, dependendo das permissões que for aplicar para o dono, grupo e outros

Exemplos

SUID

Perceba que tem ‘s’ no lugar do ‘x’ na sequencia de permissões do dono. Ele representa SUID ativado

SGID

Perceba que tem ‘s’ no lugar do ‘x’ na sequencia de permissões do grupo. Ele representa SGID ativado

STICKY

Perceba que tem ‘t’ no lugar do ‘x’ na sequencia de permissões do outros. Ele representa STICKY ativado

Saib mais…
http://www.vivaolinux.com.br/artigo/Entendendo-as-permissoes-no-Linux
http://pt.wikipedia.org/wiki/Sistema_octal

Configuração básica do Squid no Fedora

Eae pessoal, dessa vez quero mostrar como configurar rapidamente um servidor de proxy Squid. Vou mostrar o básico para o Squid funcionar, no final deixo alguns links para quem quiser se aprofundar no assunto, beleza? Dessa vez vou utilizar o Fedora.

Um servidor de proxy tem basicamente duas funções: Agilizar o processo de entrega de requisições web e filtrar o conteúdo que os usuários tem acesso. Existem duas maneiras de configurar o servidor Squid, manualmente e transparente.

Quando você usa configuração manual é necessário especificar para todos os clientes(geralmente navegadores) que eles devem fazer uso do proxy. Já quando você faz a configuração de forma transparente não existe a necessidade de especificar que os clientes utilizem o proxy. Na verdade, os clientes não sabem da existência dele.

Em um proxy configurado de forma manual e tendo como cliente um navegador o processo de requisição seria (+ ou -) assim:

NAVEGADOR > SERVIDOR_PROXY > SITE V

NAVEGADOR < SERVIDOR_PROXY < SITE

Ou seja, o navegador faz a requisição da página para o servidor proxy, esse realiza a filtragem e se for o caso( se for aprovado ) requisita a página para o site e devolve para o navegador.

E se proxy for transparente o processo de requisição de uma página é o seguinte:

NAVEGADOR > FIREWALL > SERVIDOR_PROXY > SITE V

NAVEGADOR < SERVIDOR_PROXY < SITE

Nesse caso o navegador não sabe da existência do proxy, então faz a requisição normalmente para o roteador padrão( por isso não é necessário configurar o navegador), o firewall da rede então identifica essa operação e desvia o fluxo para o proxy para que ele faça a filtragem e se for o caso a requisição para o site.

Nesse tutorial vou mostrar como fazer a configuração manual. O ideal é que você instale e configure o servidor em uma máquina e use outra como cliente, se você não tiver outra máquina disponível utilize o virtualbox para criar uma máquina virtual. (Nunca usou o virtual box? aqui têm um tutorial).

Na máquina que vai ser o servidor use o seguinte comando para instalar o Squid: ( O servidor deve ser Fedora, o cliente pode se qualquer sistema, ok?)

 
sudo yum install squid -y

Com o Squid instalado no servidor abra com um editor de texto o arquivo “/etc/squid/squid.conf” :

 
sudo nano /etc/squid/squid.conf

Veja que já existe bastante conteúdo nesse arquivo, mas não se preocupe a maior parte dele não será alterada. A idéia é ser simples e rápido, então não vou fazer muitas configurações, vou mudar somente o necessário. A configuração completa para colocar o proxy em ‘produção’ fica para um próximo artigo.

Vou iniciar configurando o cache, para isso altere a seguinte linha no arquivo squid.conf:

 
#cache_dir ufs /var/spool/squid 100 16 256

Essa linha faz o ajuste do cache em disco: O 100 especifca o tamanho do cache em MB, o 16 a quantidade de diretórios e o 256 a quantidade de subdiretórios que o Squid pode criar. Você pode alterar os valores conforme achar necessário, apenas se certifique de tirar o ‘#’ do inicio da linha. Este ‘#’ comenta a linha, com ele essa instrução não é avaliada pelo Squid.

Em seguida coloque essa linha abaixo da anterior( em baixo da cache_dir…):

 
visible_hostname nome_do_seu_servidor_aqui

Essa linha especifica o hostname do Squid e também vai aparecer nas páginas de informação.

Pronto, salve o arquivo e você já têm o cache do seu Squid configurado. O próximo passo é configurar as regras de filtragem. Essas regras são definidas através dos comandos ‘acl’ e ‘http_access’. Veja a documentação para encontrar todas as ‘acls’ possíveis. http://www.squid-cache.org/

As ‘acls’ são escritas da seguinte forma:

 
acl < nome_da_acl > < tipo_acl > < parâmetro >

Veja alguns exemplos de ‘acls’:

 

# acl de origem, representa o ip do cliente que acessa o proxy
acl rede_local src 192.168.0.0/24

# acl de destino, representa o destino da requisição
acl meu_blog dstdomain .prmjuniorblog.blogspot.com.br

# acl de expressão regular, verifica se a palavra jogo esta na url
acl words url_regex jogo

Para iniciar a configuração da filtragem coloque um ‘#’ (comentar) as seguintes linhas: (Elas estão permitindo acesso total para a rede local e para o próprio servidor, vamos tirar esse acesso.)

 
#No seu elas devem estar sem o '#' na frente, coloque.
#http_access allow localnet
#http_access allow localhost

Agora é possível criar regras personalizadas. A configuração que vou utilizar vai estabelecer algumas palavras proibidas e se o Squid encontrar alguma delas o acesso será negado, para isso procure no arquivo “/etc/squid/squid.conf” a seguinte linha:

 
http_access deny all

Digite os comando abaixo antes dela:

 

# a sua rede, -ALTERE- para a faixa de IP que você usa. Use o comando ifconfig para ter essa informação
acl rede_local src 192.168.0.0/24
#as palavras proibidas
acl proibidas url_regex -i "/etc/squid/proibidas"

Criei duas ‘acls’, a primeira representa o IP da sua rede local, ou seja a faixa de ip dos computadores clientes e a segunda representa as palavras proibidas. O “-i” garante que a busca pelas palavras não vai considerar diferença entre maiusculas e minusculas, e o endereço “/etc/squid/proibidas” é o arquivo onde as palavras serão armazenadas( uma por linha ). Para testar crie o arquivo “/etc/squid/proibidas” e coloque a palavra baixaki dentro dele. Salve as modificações no “/etc/squid/squid.conf”, abra um terminal e execute o comando abaixo:

 

sudo echo "baixaki" > /etc/squid/proibidas

Depois de executar esse comando o arquivo das palavras proibidas já estará criado e contendo a palavra baixaki. Volte a abrir o arquivo “squid.conf” e digite o seguinte logo abaixo das linhas anteriores:

 

#nega que a rede acesse requisições que tenham as palavras proibidas em qualquer lugar da url
http_access deny rede proibidas
#permite que a rede acesse o restante
http_access allow rede

OBS: Se uma regra bloquear o acesso, esse vai ficar bloqueado, mesmo que uma regra abaixo libere

Com isso a filtragem está pronta, use o seguinte comando para verificar erros de digitação na configuração:



squid -k parse

Se for mostrado algum erro tente corrigi-lo( se não souber arrumar deixe um comentário 🙂 .Quando a configuração estiver ok, inicie o Squid com o comando:

 

sudo service squid start

OBS: para que o Squid inicie sempre com o Fedora, use o comando “sudo chkconfig squid on”

Agora é necessário configurar o navegador do cliente para usar o proxy. Aqui têm tutorial explicando como fazer isso em vários navegadores. Você vai precisar do ip do servidor, se não souber, use o comando ifconfig.

Segue uma imagem de como ficou no meu Firefox

Feito, tente navegar… o Baixaki deve ser o único site bloqueado. Se quiser fazer outros bloqueios não é necessário alterar o “/etc/squid/squid.conf”, basta alterar o arquivo das palavras proibidas.

Se você preferir ter um arquivo com palavras liberadas, ou seja, acessa somente os sites que tiverem uma das palavras na url, crie o arquivo liberadas e altere as seguintes linhas no “/etc/squid/squid.conf”:

 
# cria a acl
acl liberadas url_regex -i "/etc/squid/liberadas"
#nega acesso a qualquer url que não tenha uma das palavras liberadas
http_access deny rede !liberadas

Saiba mais…
http://pt.wikipedia.org/wiki/Proxy
http://www.sourcebrasil.org/tutoriais/visualizar/instalacao-e-configuracao-do-servidor-proxy-squid.html
http://www.youtube.com/watch?v=fgOw-3PV_sQ