quinta-feira, 15 de março de 2012

Permissões de arquivos no linux

No linux, todo arquivo possui suas permissões, que representam o nível de acesso para o dono do arquivo, para o grupo ao qual ele pertence e para os demais usuários.

As permissões são representadas por esse conjunto de letras na primeira linha da listagem vertical (ls -l):

-rw-------  1 sauron sauron     1675 2012-03-14 21:42 arquivo_1
-rwxr-xr-x  1 sauron sauron      396 2012-03-14 21:42 arquivo_2

r -> read, permissão de leitura do arquivo
w -> write, permissão de escrita no arquivo
x -> execute, permissão de execução do arquivo (no caso de um diretório, significa abrir/entrar o diretório)

Para alterar essas permissões utilizamos o comando chmod. Existem duas formas de alterar as permissões de um arquivo:

- Utilizando as letras que representam as operações (mais simples)
- Utilizando a representação octal (mais eficiente)

Utilizando as letras

Como foi mostrado antes, cada operação é representada por uma letra:

r -> read
w -> write
x -> execute

Cada usuário/categoria é, também, representado por uma letra:

u -> dono do arquivo. É a opção padrão.
g -> grupo ao qual o dono do arquivo pertence
o -> outros usuários (que não se encaixem nas opções anteriores)
a -> todos os usuários (aplica a permissão em todos os níveis: u, g e o)

Para alterar as permissões, utilizamos dois operadores:

+ -> adicionar permissão
- -> remover permissão

Exemplos:

sauron@mordor:~$ ls -l arquivo
-rw-r--r-- 1 sauron sauron 0 2012-03-15 20:10 arquivo
sauron@mordor:~$ chmod u-w arquivo
sauron@mordor:~$ ls -l arquivo
-r--r--r-- 1 sauron sauron 0 2012-03-15 20:10 arquivo
sauron@mordor:~$ chmod +w arquivo
sauron@mordor:~$ ls -l arquivo
-rw-r--r-- 1 sauron sauron 0 2012-03-15 20:10 arquivo
sauron@mordor:~$ chmod a+x arquivo
sauron@mordor:~$ ls -l arquivo
-rwxr-xr-x 1 sauron sauron 0 2012-03-15 20:10 arquivo
sauron@mordor:~$ chmod g-r,o-r arquivo
sauron@mordor:~$ ls -l arquivo
-rwx--x--x 1 sauron sauron 0 2012-03-15 20:10 arquivo


Utilizando o modo octal

Apesar de simples de aprentar, alterar as permissões utilizando as letras dá um pouco de trabalho. A maneira mais eficiente de fazer isso é utilizando o modo octal.
No modo octal, cada grupo de permissões possui uma representação octal, que é definida pela presença ou não de determinada permissão (bit ligado ou desligado).
Tabela representando o modo octal:

Permissão Bits ligados/desligados Representação octal
---0000
--x0011
-w-0102
-wx0113
r--1004
r-x1015
rw-1106
rwx1117

Exemplos:

sauron@mordor:~$ ls -l arquivo
-rw-r--r-- 1 sauron sauron 0 2012-03-15 20:10 arquivo
sauron@mordor:~$ chmod 666 arquivo
sauron@mordor:~$ ls -l arquivo
-rw-rw-rw- 1 sauron sauron 0 2012-03-15 20:10 arquivo
sauron@mordor:~$ chmod 600 arquivo
sauron@mordor:~$ ls -l arquivo
-rw------- 1 sauron sauron 0 2012-03-15 20:10 arquivo
sauron@mordor:~$ chmod 777 arquivo
sauron@mordor:~$ ls -l arquivo
-rwxrwxrwx 1 sauron sauron 0 2012-03-15 20:10 arquivo
Para criar um novo usuário no Linux utilizamos o comando adduser  seguido do nome do novo usuário (é necessário ser root para executar esse comando):

sauron@mordor:~$ sudo adduser novo_usuario
Adicionando o usuário `novo_usuario' ...
Adicionando novo grupo `novo_usuario' (1002) ...
Adicionando novo usuário `novo_usuario' (1002) ao grupo `novo_usuario' ...
Criando diretório pessoal `/home/novo_usuario' ...
Copiando arquivos de `/etc/skel' ...

Também é criado um novo grupo para este usuário, com o mesmo nome do usário.
Será pedido a senha do novo usário (e a confirmação de senha também):

Digite a nova senha UNIX:
Redigite a nova senha UNIX:
passwd: senha atualizada com sucesso

Então será pedido as informações do usuário, que normalmente não são necessárias. Para deixá-las em branco basta apertar ENTER:

Modificando as informações de usuário para nome_do_usuario
Informe o novo valor ou pressione ENTER para aceitar o padrão
Nome Completo []:
Número da Sala []:
Fone de Trabalho []:
Fone Doméstico []:
Outro []:
Esta informação está correta?[S/n] s

Pronto. Usuário criado.
Para remover um usuário, utilizamos o comando deluser (também é necessário ser root):

ricardo@mordor:~$ sudo deluser novo_usuario
Removendo o usuário `novo_usuario' ...
Aviso: grupo `novo_usuario' não possui mais membros.
Concluído.

Você deve apagar a pasta do usuário manualmente (/home/novo_usuário):

sauron@mordor:~$ sudo rm -rf /home/novo_usuario/

Restaurando o GRUB 2

Se você instalar o Windows em uma máquina que já tinha o linux instalado, vai ser necessário reinstalar o GRUB na MBR.

Como você não vai conseguir fazer o boot pelo linux instalado (a máquina inicia direto no windows), é necssário dar boot por um Live CD, utilizando a opção 'Experimentar o Ubuntu'.

Após ter iniciado o sistema pelo live cd, o primeiro passo é identificar a partição onde o linux está instalado, para isso utilizamos o comando fdisk:

ubuntu@ubuntu:~$ sudo fdisk -l

Disco /dev/sda: 1000.2 GB, 1000204886016 bytes
255 heads, 63 sectors/track, 121601 cylinders, total de 1953525168 setores
Unidades = setores de 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Identificador do disco: 0x031d6b18

 Dispositivo Boot Início Fim Blocos Id Sistema
/dev/sda1 * 2048 206847 102400 7 HPFS/NTFS/exFAT
/dev/sda2 206848 195311615 97552384 7 HPFS/NTFS/exFAT
/dev/sda3 195311616 203311103 3999744 82 Linux swap / Solaris
/dev/sda4 203311104 1953523711 875106304 83 Linux

 Disco /dev/sdb: 4105 MB, 4105175040 bytes
255 heads, 63 sectors/track, 499 cylinders, total de 8017920 setores
Unidades = setores de 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Identificador do disco: 0x00501804

 Dispositivo Boot Início Fim Blocos Id Sistema
/dev/sdb1 * 63 8017919 4008928+ b W95 FAT32 

Neste exemplo podemos perceber que a instalação do linux está na partição 4 do disco sda. Então nós montamos esta partição:

ubuntu@ubuntu:~$ sudo mount /dev/sda4 /mnt 
Depois de montá-la, deizemos ao grub para se instalar nela:

ubuntu@ubuntu:~$ sudo grub-install --root-directory=/mnt /dev/sda
Installation finished. No error reported. 

Depois de instalar o grub, desmonte a partição e reinicie o sistema:

ubuntu@ubuntu:~$ sudo umount /mnt
ubuntu@ubuntu:~$ sudo reboot

Agora o grub está instalado na MBR.
Caso a máquina inicie direto no linux, sem aparecer o menu do grub, vai ser necessário atualizar as configurações do grub, executando o seguinte comando

sauron@mordor:~$ sudo update-grub2

Agora é só reiniciar que vai aparecer o menu para escolher entre Linux e Windows.

Esperando jockey-backend para sair

Após instalar o Ubuntu 12.04 beta, o apt-get não estava funcionando. Ele indicava que já estava sendo efetuada uma atualização do sistema (não conseguindo obter a trava).
No Ubuntu Software Center tinha um processo em execução relacionado ao Jockey. Este é um sistema para certos tipos de drivers. E ele parecia estar travado, ou executando de forma muito lenta.
Para resolver esse problema, a melhor forma foi remover o jockey.
Primeiro pára o processo no Ubuntu Software Center, depois executa esse comando:

sauron@mordor:~$ sudo apt-get remove jockey-gtk

Agora pode usar o apt-get normalmente.

quarta-feira, 14 de março de 2012

Login SSH com chave privada

Para evitar o fato de memorizar senhas dos usuário para fazer login SSH, ou ficar adicionando as chaves públicas ao authorized_keys do servidor, uma saída é utilizar chave privada para fazer o login via SSH. Este é o método utilizado para fazer login nos servidores da Amazon.

Vamos começar configurando as permissões de acesso no servidor, depois passaremos para o cliente (máquina local).
O primeiro passo é criar um diretório chamado .ssh na pasta home do usuário (no servidor).

sauron@mordor:~$ mkdir .ssh

Quando o diretório é criado, ele fica com permissão do tipo 755 (drwxr-xr-x). Mas nehum outro usuário deve ter acesso a esse arquivo (nem mesmo para leitura). Então nós alteramos as permissões do diretório com o comando chmod:

sauron@mordor:~$ chmod 700 .ssh

Agora só o dono do diretório (o usuário atual) é que tem permissão no diretório (drwx------).

O próximo passo é gerar a chave privada. Para isso nó utilizamos um aplicativo que vem junto com o ssh chamado ssh-keygen:

sauron@mordor:~$ ssh-keygen -f private-key
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in private-key.
Your public key has been saved in private-key.pub.
The key fingerprint is:
21:b3:c9:31:a3:c4:00:5c:fe:a6:c2:4e:57:75:87:e8 sauron@mordor
The key's randomart image is:
+--[ RSA 2048]----+
|o.o.             |
| ..o    . .      |
|   .o *o.o .     |
|   ..ooO...      |
|    .++ES        |
|.   +            |
| + o             |
|o o              |
| .               |
+-----------------+

A opção -f serve para indicar o nome do arquivo, neste caso eu chamei de private-key. Vai ser pedido uma passphrase para gerar a chave, mas você pode deixar em branco.
Depois disso serão criados os arquivos private-key e private-key.pub, representando a chave privada e chave pública, respectivamente.

Agora devemos renomear o arquivo private-key.pub para authorized_keys, e colocá-lo no diretório .ssh que nós criamos.

sauron@mordor:~$ mv private-key .ssh/authorized_keys

Este arquivo vai estar com a permissão do tipo 644, devemos deixá-lo como 600:

sauron@mordor:~$ chmod 600 .ssh/authorized_keys

Sobrou o arquivo private-key, que será utilizado como chave de acesso ao servidor. Então devemos copiá-lo para a máquina local (cliente). Você pode utilizar o comando scp para fazer a transferência do arquivo do servidor para o cliente. Mas podemos evitar esse trabalho simplesmente copiando o conteúdo do arquivo para a área de transferência e depois criar um arquivo no cliente (com o mesmo nome, private-key) e colar o conteúdo copiado nele.

sauron@mordor:~$ cat private-key
-----BEGIN RSA PRIVATE KEY-----
MIIEoQIBAAKCAQEAwDg2czXOQX7Ns6GYL+luTTFXeHewumb866VcUX9eHBzXSFBY
NyBcOGq2tlm289JLMZHxo4YIObFRfTZ9IOnpQEmYtBV5x+ypTBcPXOkFLivj5bAT
t1PNK1AkHjXzUZY0eTTLkMuNSW0rD4vV7E3HqIb3UIZ7PiDCefzrMMUeytRXbUd0
2OyXxsqX7ROWtsoaykOc/0IGGItyG5NTcPepKMPGYixkKWeicFlvJUBQAItuMRBq
kSBMssD0j1IYeYlCmkRk7eLecKuI3edwqKvbpntSgbSlmsff5AHA+vhW99nfkiWz
8UOeEuqZOncVYjP655lJZIdgk+hkDtCLfIkVwwIBIwKCAQEAurpDhdx/OE9Le0yF
Ndtydt95ivftgeBjaJIB6MTfE/7CgMMT3ceqCutSZ/9hRKBmTWkz4K4WnnG84AkL
1tSZcaaUVyrOEqtiobAAS6CIsIJoW3fYo3X6gdjSoQE1gnSoALbxopnZtQr2oWNE
1ux4z5kNgWyyPFpWhSGUA32o4kjuRl9pput+iDd/USu/HYBjc1FpDOvpiUq0LJpd
7PP6Wh52BAhzY2hOeMpMLQacbp4ZEAQMVU+wRugCLyuzfSZhmOgV1+WjHdROyso0
glkzogIa1g4RaggVMMPnmWI2mWfe3G2ESki+ne9o2/DwnjK8J3t4BLxmWM2QdIox
m9yR+wKBgQDr5Fdn7nHO2NCBOQ7qMWfOYeHx8c87Ass4LFi3GuyhMcNEbiGdSEpo
i5ne2yZGq1FH1TWBQ53o7QXP/xDyx1KYhn4kA5n6yDBjB3yq5+5G5AbgEo4tix+U
VoOBG6dDClsSSCgE8h4zNGSGG/rEPsejslFmnr13mBSQPX66XxbazwKBgQDQmtkg
KA/kyype74TRMk8TNW++6Y8AU7cXDJu0Hlsr5YbMOy9BCdd/s7MUslb+41sqrUAn
5qFMba4xX7JHR/iQ50/QE5E0NvNrUPT5HHDQjJ907ScLyCeBCHhY/ag2E1ekG8ku
WFMA/7VFSyJogJJ3Zv19z/jpCdMKaGk0oqXCzQKBgFDgkv8P7IFu6GbRu/iF97R5
VMf7Inqh30Z1msJvoZZaNFH536Ojwb1xsRk1MbHUVmHFcW4lz72TF++KprmjbMaU
gwUIjJB/JohaVqD/D93KhgOulyWOyP+ooh2jFMaHNSrW6SZEYiAvOGh+nx62cFVh
tYJFDcKairUcZfbBhC3DAoGAEeFjEWKFBPt4qQ03RSGRv9FhWYG7zNP5wCWm8i58
1+B5RLSdpn0vun0d+nWvr3KSySTK/BsVI87jC4vcFL0GrVWnwWDDTZ5PYPhPgxEQ
++7L1tJ/sI1/uppTdVeSE0N8imjIGepQQeoIOSOyffxkU2CZYo4rRyy6UVloGnRX
WdcCgYBhCMnOJ80wTWnFDfZ6VJwxnkcPf6V9G/P0EP5BpWnP355pjnhhSDyGk+eJ
tkDxKPy7l18+sLqV8PNbeHdQpA4YGBkP1CSiPhPcap4jYOot+hcLu7fn7ApVl/jd
yhAR7GpXE0x/5VE4zyB3vEqTPQTggZ/nuUUqbU5HFj83iFDgzg==
-----END RSA PRIVATE KEY-----

Copie o conteúdo do seu arquivo e cole no novo arquivo na máquina local.
Este novo arquivo do cliente deve ter a permissão do tipo 600:

sauron@local:~$ chmod 600 private-key

Depois que fizer isso você deve excluir o arquivo private-key do servidor:

sauron@mordor:~$ rm private-key

Agora você já tem a chave privada na máquina local (arquivo private-key), e o servidor já está preparado para aceitar essa chave como válida (através do arquivo .ssh/authorized_keys).

Para logar no servidor, utilizamos o seguinte comando:

sauron@local:~$ ssh -i private-key sauron@ip_do_servidor

Pronto, logando no servidor com chave privada.

terça-feira, 6 de março de 2012

Usango a gem twitter-bootstrap-rails com MongoDB

Com esse novo railscast ficou muito fácil criar um admin com um layout amigável.
Como é explicado no vídeo, basta alguns comandos e você terá todo o css gerado para sua página admin (a gem também altera algumas partes do html, que no meu caso tive que consertar).
A gem funciona perfeitamente bem quando você usa o mysql como banco de dados. Mas, e se você usar o Mongo? Foi o que aconteceu comigo, a gem simplesmente não funciona.
Analisando as mensagens de erro, descobri que o motivo estava na função columns, que é uma função estática das classes que representam os models. Algo como:

User.columns

Essa função retorna, entre outras coisas, o nome de cada coluna da respectiva tabela (no caso users) e o seu tipo, assim a gem pode montar os formulários automagicamente.
Mas como o mongo não tem esse conceito de tabela, essa função simplesmente não existe. Logo, é necessário criá-la.
Vamos lá, não é difícil. Começamos criando uma nova classe na pasta models (app/models):


class MongoDBColumn
  attr_accessor :name, :type

  def initialize args
    args.each do |k,v|
      instance_variable_set("@#{k}", v) unless v.nil?
    end
  end
end

Coloque o nome do arquivo de mongodbcolumns.rb. Essa classe simula uma coluna no mongo, assim como o mysql possui a classe Mysql2Column, que é a classe que retorna o nome e o tipo de cada coluna.

Agora, em cada model que você quiser gerar admin, você precisa criar a função estática columns. Vou citar como exemplo um model que representa os contatos que os usuários fazem (formulário de contato, ou fale conosco).

Logo no começo do arquivo contact.rb, adicione essa linha:

require 'mongodbcolumns.rb'

Depois, no final da classe (mas antes do end), cria a função columns:


def self.columns
  return Array.new([
    MongoDBColumn.new(:name => 'name', :type => :string),
    MongoDBColumn.new(:name => 'email', :type => :string),
    MongoDBColumn.new(:name => 'subject', :type => :string),
    MongoDBColumn.new(:name => 'message', :type => :text)
  ])
end

Neste caso estou simulando uma tabela com quatro columnas (name, email, subject e message), as três primeiras do tipo string e a última do tipo text (os campos no formulário vão ser gerados de acordo com o tipo da tabela, igual o scaffold faz).

Pronto, agora é só rodar o generate do bootstrap:

rails g bootstrap:themed admin/contacts -f

Estou usando admin/contacts porque quero que as views sejam geradas dentro da pasta admin. Você pode remover esse admin/ se quiser as views na pasta da aplicação mesmo.

Como eu disse no começo, o gerador altera algumas coisas nas views. No meu caso deu problema no arquivo _form.html.erb. Logo na primeira linha:

<%= form_for @contact, :html => { :class => 'form-horizontal' } do |f| %>

Como estou usando a pasta admin, minha rota é um pouco diferente. Em vez de @contact, eu utilizo [:admin, @contact]. É só alterar essa linha para:

<%= form_for [:admin, @contact], :html => { :class => 'form-horizontal' } do |f| %>

Agora está tudo funcionando.