Network File System(NFS) é um protocolo que tem como objetivo compartilhamento de arquivos entre sistemas linux/unix, desenvolvido pela Sun Microsystems em 1980. Ele permite que você monte sistemas de arquivos através da internet na sua máquina local e a partir disso a transfẽrencia de arquivos é realizada já que a partição vai estar montada no seu sistema como se fosse local.
Para montar dispositivos remotos é necessário que o daemon portmap esteja ativo tanto no cliente como no servidor.
Um ponto no NFS é que não é necessário autenticação o que é relativamente ruim do ponto de vista da segurança contudo ainda teriamos as permissões (UGO) para fazer uma fina camada de segurança.
O sistema qual eu realizei o deploy foi o Minibian que está instalado num raspberry pi 3 b que faz parte de um projeto de pseudo Storage, ainda não ta pronto porque eu como o bom cyberpunk não sou rico(na verdade nem um pouco rico) o suficiente pra comprar todos os discos de uma vez contudo provavelmente dentro dos próximos 20 dias já vou ter todo o hardware necessário e então vou implementar um raid alien e provavelmente usar um samba ao invés do nfs. Mas isso não importa, o que importa é que o Minibian é baseado em Raspbian-based e logo utiliza apt, e então os comandos são válidos também em todos os debians e falando de redhat based, só altera o gerenciador de pacote que no caso seria o yum.
Os procedimentos abaixo se tratam de instalar os pacotes, configurar o fstab devido ao fato que eu estou usando um HD externo de 2TB plugado via USB por uma gaveta e depois então é necessário configurar o nfs em si.
Instalação
$ sudo apt-get install nfs-kernel-server nfs-common portmap -y
$ systemctl enable nfs-kernel-server && systemctl start nfs-kernel-server && systemctl status nfs-kernel-server
$ systemctl enable portmap && systemctl start portmap && systemctl status portmap
Serviços envolvidos:
- rpc.nfsd -> Próprio NFS
- rpc.lockd -> Gerencia os bloqueios
- rpc.stad -> Network Status Monitor
- rpc.mountd -> Responsavel pelas montagens
- rpc.quota -> Referente à quotas.
Configuração
Conforme mencionado anteriormente, eu estou usando um disco externo, então utilizando o comando fsdisk para identificar o disco:
root@minibian:/home/operador# fdisk -l
--- Saída Omitida ---
Device Boot Start End Sectors Size Id Type
/dev/sda1 2048 3907029165 3907027118 1.8T 83 Linux
O disco já foi devidamente formatado então não irei entrar nesse aspecto.
Por medidas de precaução irei usar o UUID do disco ao invés do arquivo de bloco, então com o comando blkid podemos identificar a UUID do disco:
root@minibian:/home/operador# blkid
/dev/mmcblk0: PTUUID="ec688fc9" PTTYPE="dos"
/dev/mmcblk0p1: SEC_TYPE="msdos" UUID="BD97-35E6" TYPE="vfat" PARTUUID="ec688fc9-01"
/dev/mmcblk0p2: UUID="f55adb7f-6d96-4e27-a51d-a27fafa58214" TYPE="ext4" PARTUUID="ec688fc9-02"
/dev/sda1: UUID="80475ea9-1f4f-461b-95e4-69fd2ee5d438" TYPE="ext4" PARTUUID="6e697373-01"
Então identifcando o UUID, agora vamos ao fstab criar a entrada para a montagem automatica dessa partição:
$ sudo vim /etc/fstab
E então adicionando a seguinte linha no arquivo:
UUID=80475ea9-1f4f-461b-95e4-69fd2ee5d438 /media/storage ext4 errors=continue,defaults 0 0
Não pretendo explicar os registros no fstab também mas vou fazer uma observação para no campo options o argumento erros, a opção setada como continue define que em caso de algum problema na montagem ele simplesmente deixa pra lá, isso é importante pois dependendo da configuração o sistema pode não iniciar pois vai ficar preso na tentativa de montagem.
Agora com o sistema configurado no /etc/fstab, vamos realizar a montagem:
$ sudo mount /media/storage
Caso não ocorra nenhum erro podemos continuar, o proxímo passo é configurar o NFS, para realizar isso é relativamente simples.
O arquivo de configuração principal é o /etc/exports, segue abaixo um exemplo de configuração:
# /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)
/media/storage/ 10.10.10.0/24(rw,sync,no_root_squash)
A estrutura é simples, primeiro é qual é o diretório, depois então quem poderá acessar e as opções para aquele host, no caso acima eu define uma rede inteira porém poderia ser definido vários hosts da seguinte forma:
/media/storage/ 10.10.10.105(ro,sync,no_root_squash) 10.10.10.25(rw,sync,no_subtree_check)
Agora sobre as opções que podem ser atribuidas a cada host:
- ro -> Read Only
- rw -> Read Write
- sync -> Confirma solicitações ao diretório compartilhado somente após a confirmação das alterações.
- no_subtree_check -> Quando um diretório compartilhado é um subdiretório de um arquivo de sistemas largo, o nfs executa verificações em cada diretório abaixo, isso aumenta a confiança, essa opção desabilita essa verificação o que dá um ganho em desempenho porém como sempre diminui a segurança
- subtree_check -> Está opção verifica a cada requisição de um arquivo cliente, se tal arquivo está exporado em um sub diretório
- root_squash(default) -> Todas as requisições serão feitas como se fossem pelo usuário nobody.
- no_root_squash -> Permite que o usuário de id 0(root) monte o diretório, útil para quando se está usando compartilhando a raiz porém totalmente insano fazer isso. E todas as requisições serão feitas como se fossem pelo usuário root.
Outra observação é que você não deve espaçar o host das opções, caso você faça isso, o host vai possuir permissões default, que seria readonly. Nesse cênario tem duas vertentes, se você fizer isso:
/directory 192.168.10.0/24 (rw)
Ele vai entender que é para liberar readonly para toda a rede /24 e rw para qualquer um que não seja daquela rede.
Depois de configuardo o arquivo /etc/exports é necessário executar o seguinte comando para que o diretório fique exposto para montagem:
$ sudo exportfs -a
Para verificar os compartilhamentos execute:
root@minibian:/home/operador# exportfs -v
/media/storage 10.10.10.0/24(rw,wdelay,no_root_squash,no_subtree_check,sec=sys,rw,no_root_squash,no_all_squash)
Para desabilitar o compartilhamento execute:
root@minibian:/home/operador# exportfs -ua
Outras utilidades do comando exportfs
- -r -> reexport all directories
- -a -> export or unexport all directories
- -ua -> de-activate the export list(unexport all)
Outra forma de verificar se os diretórios foram exportados é consultando a tabela do kernel de exportação:
cat /proc/fs/nfs/exports
Client-Side
Bom, agora no lado cliente é necessário montar o diretório remoto e conforme mencionado anteriormente é necessário ter aqueles daemons lá do portmap rodando e também os utils do nfs, caso não tenha instalado, segue abaixo:
$ sudo apt-get install nfs-common portmap -y
Agora realizando uma verificação no servidor NFS com o comando showmount:
user@Hope:~$ showmount -e 10.10.10.8
Export list for 10.10.10.8:
/media/storage 10.10.10.0/24
Outras opções do comando showmount:
- showmount –exports -> Show active export list
- showmount –directories -> Show directoreis that are mounted by remote clients
- showmount –all -> Show both client-names and directories
- showmount -> Show names of clients with active mounts
Isso significa que o bagulho ta pronto pra ser usuado no diretório /media/storage pra todos os hosts da rede 10.10.10.0/24.
Outra forma de verificar é utilizando o rpcinfo
user@Hope:~$ rpcinfo -p 10.10.10.8 | grep nfs
100003 2 tcp 2049 nfs
100003 3 tcp 2049 nfs
100003 4 tcp 2049 nfs
100003 2 udp 2049 nfs
100003 3 udp 2049 nfs
100003 4 udp 2049 nfs
Outra forma de verificar um serviço em especifico:
ruser@Hope:~$ sudo rpcinfo -u 192.168.1.8 nfs
program 100003 version 2 ready and waiting
program 100003 version 3 ready and waiting
program 100003 version 4 ready and waiting
Algumas opções do rpcinfo
- -u -> Força a utilização de UDP
- -p -> Exibe uma lista de programas rpc registrados
- -t -> Força a utilização de TCP
Caso não retorne nenhuma entrada referente à nfs, temos um problema, Quorra.
Und jetzt endet, para montar a partição é necessário usar nada mais que o comando mount da seguinte forma:
$ sudo mount -t nfs 10.10.10.8:/media/storage/ /mnt
Para realizar algumas outras verificações pode-se executar o comando nfsstat, esse comando mostra estatísticas de uso de compartilhamentos. Pode ser utilizado tanto no cliente como no servidor.
No servidor:
root@minibian:/home/operador# nfsstat
Server rpc stats:
calls badcalls badclnt badauth xdrcall
120660 0 0 0 0
Server nfs v4:
null compound
2 0% 120683 99%
Server nfs v4 operations:
op0-unused op1-unused op2-future access close commit
0 0% 0 0% 0 0% 19 0% 46 0% 3817 0%
create delegpurge delegreturn getattr getfh link
9 0% 0 0% 0 0% 116753 24% 66 0% 0 0%
lock lockt locku lookup lookup_root nverify
0 0% 0 0% 0 0% 31 0% 0 0% 0 0%
open openattr open_conf open_dgrd putfh putpubfh
46 0% 0 0% 0 0% 0 0% 120617 25% 0 0%
putrootfh read readdir readlink remove rename
5 0% 0 0% 18 0% 0 0% 0 0% 2 0%
renew restorefh savefh secinfo setattr setcltid
0 0% 0 0% 2 0% 0 0% 104 0% 0 0%
setcltidconf verify write rellockowner bc_ctl bind_conn
0 0% 0 0% 116318 24% 0 0% 0 0% 0 0%
exchange_id create_ses destroy_ses free_stateid getdirdeleg getdevinfo
5 0% 4 0% 3 0% 0 0% 0 0% 0 0%
getdevlist layoutcommit layoutget layoutreturn secinfononam sequence
0 0% 0 0% 0 0% 0 0% 2 0% 120666 25%
set_ssv test_stateid want_deleg destroy_clid reclaim_comp
0 0% 0 0% 0 0% 2 0% 3 0%
Client rpc stats:
calls retrans authrefrsh
0 0 0
Algumas opções do nfsstat
| rpc | nfs | both
server | -sr | -sn | -s
client | -cr | -cn | -c
both | -r | -n | -nr
No cliente:
Quorra@HowDoesTheSunLookslike:~/Downloads$ sudo nfsstat -m
[sudo] password for user:
/mnt from 10.10.10.8:/media/storage
Flags: rw,relatime,vers=4.2,rsize=131072,wsize=131072,namlen=255,hard,proto=tcp,timeo=600,retrans=2,sec=sys,clientaddr=10.10.10.105,local_lock=none,addr=10.10.10.8
Bom é isso, em breve irei postar a implementação do meu projeto utilizando samba e raid.
