Compartilhando arquivos com NFS

O NFS (Network File System), é um protocolo que permite compartilhar sistemas de arquivos entre máquinas Linux. O NFS foi originalmente implementado para ser um sistema de arquivos substituto para máquinas clientes sem disco. O NFS demonstrou ser bem projetado e muito útil como uma solução genérica para compartilhamento de arquivos. O NFS é quase transparente para os usuários e é “sem estado”, o que significa que nenhuma informação é perdida quando um servidor NFS trava. Os clientes podem simplesmente aguardar o servidor retornar e depois continuar como se nada tivesse acontecido.

O cliente NFS tem por finalidade tornar o acesso remoto transparente para o usuário do computador, e esta interface cliente e servidor, executada pelo NFS através dos protocolos Cliente-Servidor, fica bem definida quando o usuário ao chamar um arquivo/diretório no servidor, lhe parece estar acessando localmente, sendo que está trabalhando com arquivos remotos. Para que os clientes tenham acesso aos arquivos, é feita uma requisição ao servidor que, dependendo das permissões do cliente, responde confirmando a requisição. A partir desse ponto a hierarquia de diretórios e arquivos remotos passa a fazer parte do sistema de arquivos local da máquina.

O NFS executa sobre o protocolo RDP (Remote Procedure Call) da Sun, que define uma maneira independente do sistema para os processos se comunicarem através de uma rede. Um efeito colateral vantajoso dessa arquitetura é que ela permite o uso do UDP ou do TCP como o protocolo subjacente de transporte. O NFS utilizava originalmente o UDP, pois esse era o que apresentava melhor desempenho nas LANs e computadores dos anos 80. Embora o NFS faça a sua própria remontagem de sequencia de pacotes e verificação de erros, faltam no UDP e no NFS os algoritmos de controle de congestionamento que são essenciais para um bom desempenho em uma grande rede IP.

Para reparar esses potenciais problemas, todos os sistemas modernos agora permitem utilizar o TCP em vez do UDP como o transporte para o NFS. Essa opção foi explorada pela primeira vez como uma maneira de ajudar o NFS a trabalhar através de roteadores e da Internet. Entretanto, o consenso atual parece ser o de que o TCP normalmente é a melhor opção para trafégo NFS local também. Ao longo do tempo, a maioria das razões originais de preferir UDP ao TCP foi se evaporando sob a luz quente das CPU’s rápidas das memórias baratas e das placas de rede mais inteligentes.

O Linux suporta o serviço NFS para o TCP desde o kernel 2.4. Grande parte dos servidores que suporta o TCP geralmente aceitará conexões em ambos os protocolos de transporte, de modo que a decisão entre TCP e UDP é tomada pelo cliente. O cliente especifica sua preferência como uma opção para o comando mount (para montagens manuais) ou em um arquivo de configuração como **/etc/fstab**.

O NFS é uma maneira conveniente para acessar arquivos em uma rede e, portanto possui grande potencial para provocar problemas de segurança. Sob diversos aspectos, o NFS é um informante de tudo o que há ou houve de errado com a segurança do Unix e Linux. Na essência o protocolo foi originalmente projetado sem nenhuma preocupação com relação a segurança; e a conveniência tem seu preço. Felizmente, o Linux, suporta uma série de recursos que reduzem e isolam os problemas de segurança dos quais o NFS tradicionalmente sofria.

O acesso aos volumes NFS é concedido por um arquivo chamado **/etc/exports** que enumera os nomes de hosts (ou endereços IP) de sistemas que devem ter acesso aos sistemas de arquivos de um servidor. Como acontece nos sistemas de arquivos locais, o controle de acesso em nível de arquivo em sistemas de arquivos NFS é controlado de acordo com o UID, o GID e as permissões do arquivo, mas o servidor NFS confia no cliente para informá-lo sobre quem está acessando arquivos.

Obs: Caso seu ambiente já tenha instalado um firewall de rede uma boa ideia é bloquear acesso às portas 2049 TCP e UDP, que são utilizadas pelo NFS. Também é recomendado bloquear acesso ao daemon portmap, que normalmente ouve nas portas TCP e UDP 111. Fica implícito nessas preocupações, mas vale a pena mencionar explicitamente que sistemas de arquivos NFS não devem ser exportados para máquinas não-locais (com exceção do WebNFS) ou exportados para a Internet aberta.

Do lado do servidor iremos instalar os seguintes pacotes:

# apt-get install nfs-common nfs-kernel-server

Agora já podemos verificar a existência do arquivo /etc/exports:

# cat /etc/exports
# /etc/exports: the access control list for filesystems which may be exported
# to NFS clients. See exports(5).
#
# Example for NFSv2 and NFSv3:
# /srv/homes hostname1(rw,sync,no_subtree_check) hostname2(ro,sync,no_subtree_check)
#
# Example for NFSv4:
# /srv/nfs4 gss/krb5i(rw,sync,fsid=0,crossmnt,no_subtree_check)
# /srv/nfs4/homes gss/krb5i(rw,sync,no_subtree_check)

Para esse exemplo irei compartilhar um diretório somente com arquivos .txt. da minha máquina Desktop e jogar todos esses arquivos para um diretório que iremos compartilhar. Para isso inserimos a seguinte linha no arquivo /etc/exports:

/home/tadeu/texto 192.168.1.111 (rw,root_squash,sync)

O endereço 192.168.1.111 é a máquina que irá receber o compartilhamento. Importante notar as opções de compartilhamento em parenteses:

rw – leitura e escrita;
root_squash – não permite que o usuário se torne root no servidor;
sync – sincronização automática de arquivos no filesystem.

Startamos o serviço:

# /etc/init.d/nfs-kernel-server start
* Exporting directories for NFS kernel daemon… exportfs: No options for /home/tadeu/texto 192.168.1.111: suggest 192.168.1.111(sync) to avoid warning
exportfs: /etc/exports [1]: Neither ‘subtree_check’ or ‘no_subtree_check’ specified for export “192.168.1.111:/home/tadeu/texto”.
Assuming default behaviour (‘no_subtree_check’).
NOTE: this default has changed since nfs-utils version 1.0.x

exportfs: No host name given with /home/tadeu/texto (rw,root_squash,sync), suggest *(rw,root_squash,sync) to avoid warning
exportfs: /etc/exports [1]: Neither ‘subtree_check’ or ‘no_subtree_check’ specified for export “*:/home/tadeu/texto”.
Assuming default behaviour (‘no_subtree_check’).
NOTE: this default has changed since nfs-utils version 1.0.x

[ OK ]
* Starting NFS kernel daemon [ OK ]

Verificamos os compartilhamentos:

# showmount -e 192.168.1.100
-bash: showmount: comando não encontrado

Verificamos que os utilitários do NFS não estão instalados na máquina cliente.

# yum install nfs-utils.i686

Agora verificamos novamente:

# showmount -e 192.168.1.100
clnt_create: RPC: Program not registered

Ops, parece que há algo de errado. Vamos entender o que está acontecendo. O Linux usa uma combinação de suporte do NFS a nível de kernel e processos daemon para prover os compartilhamentos, entretanto esse suporte NFS deve estar habilitado no kernel do Linux para funcionar. O NFS usa Remote Procedure Calls (RPC) para roteador os pedidos entre clientes e servidores, isso significa que o serviço portmap (ou rpcbind) deve estar habilitado e rodando em seus níveis de execução (runlevels) corretos para que a comunicação NFS ocorra.

Verificando os serviços na máquina cliente que irá receber o compartilhamento que os daemon’s rpcbind e o nfs estam parados:

# /etc/rc.d/init.d/rpcbind status
rpcbind está parado

# service nfs status
rpc.svcgssd está parado

Agora startamos ambos:

# /etc/rc.d/init.d/rpcbind start
Iniciando o rpcbind: [ OK ]

# service nfs start
Iniciando os serviços NFS: [ OK ]
Iniciando as quotas NFS: [ OK ]
Iniciando o NFS mountd: [ OK ]
Iniciando o servidor NFS: [ OK ]
Iniciando o RPC idmapd: [ OK ]

E garantimos que os daemons iniciem com o sistema:

# chkconfig rpcbind on
# chkconfig nfs on

Agora vamos buscar compartilhamentos NFS:

# showmount -e 192.168.1.100
Export list for 192.168.1.100:
/home/tadeu/texto (everyone)

Voilá!

Vamos criar um diretório aonde esse sistema de arquivos será montado:

# mkdir -p /home/tadeu/nfs_texto

E agora montamos o sistema de arquivos:

# mount -t -o soft nfs 192.168.1.100:/home/tadeu/texto /home/tadeu/nfs_texto/

A opção -o soft evita que o gerenciador de arquivos do cliente trave caso o servidor fique fora do ar. Vamos testar:

# cd nfs_texto/
# ls -la
total 112
-rw-r–r–. 1 root root 568 Abr 29 08:59 arquivos_zona_dns_do_blog.txt
-rw-r–r–. 1 root root 311 Abr 29 08:59 blog.txt
-rw-r–r–. 1 root root 4 Abr 29 08:59 chrome_shutdown_ms.txt
-rwxr-xr-x. 1 root root 128 Abr 29 08:59 dores e a vida.txt
-rwxr-xr-x. 1 root root 152 Abr 29 08:59 educação.txt
-rwxr-xr-x. 1 root root 1057 Abr 29 08:59 Estudo_postfix.txt
-rwxr-xr-x. 1 root root 1459 Abr 29 08:59 exercicios_script.txt
-rwxr-xr-x. 1 root root 120 Abr 29 08:59 link_coração_cerebro.txt
-rw-r–r–. 1 root root 87 Abr 29 08:59 metro.txt
-rw-r–r–. 1 root root 1296 Abr 29 08:59 nfs_blog.txt
-rwxr-xr-x. 1 root root 832 Abr 29 08:59 Ninguém melhor.txt
-rwxr-xr-x. 1 root root 1306 Abr 29 08:59 Oraçoes.txt
-rwxr-xr-x. 1 root root 17 Abr 29 08:59 Puppet – MySQL.txt
-rwxr-xr-x. 1 root root 609 Abr 29 08:59 sha256sum.txt
-rw-r–r–. 1 root root 2694 Abr 29 08:59 sobre_blog.txt

Agora para deixarmos esse compartilhamento permanente adicionaremos esse ponto de montagem no /etc/fstab:

192.168.1.100:/home/tadeu/texto /home/tadeu/nfs_texto nfs defaults 0 0

Para desativar os compartilhamentos no servidor:

# exportfs -va

Referências:
Manual Completo do Linux – Guia do Administrador, segunda edição.
http://pt.wikipedia.org/wiki/Network_File_System