User:GNUtoo/E350M1/diskless nfs

From ParabolaWiki
Jump to: navigation, search

1 Create the client's share

Create the rootfs:

export root=/srv/nfs/untrusted64
mkdir -p $root
pacstrap -c -d $root base mkinitcpio-nfs-utils nfs-utils
sed s/nfsmount/mount.nfs4/ "$root/usr/lib/initcpio/hooks/net" > "$root/usr/lib/initcpio/hooks/net_nfs4"
cp $root/usr/lib/initcpio/install/net{,_nfs4}

Now you'll have to edit $root/etc/mkinitcpio.conf:

nano $root/etc/mkinitcpio.conf
  • Add nfsv4 to MODULES=""
  • Add /usr/bin/mount.nfs4 to BINARIES=""
  • Add net_nfs4 to HOOKS="" between block and filesystems

Then re-generate the initramfs:

arch-chroot $root
mkinitcpio -p linux-libre
exit

2 Server NFS exports service

2.1 /etc/exports

/srv/nfs		*(rw,fsid=0,no_root_squash,no_subtree_check)
/srv/nfs/untrusted64	*(rw,no_root_squash,no_subtree_check)

2.2 Start and enable NFS

systemctl start nfs-mountd
systemctl start nfs-idmapd
systemctl start rpcbind
systemctl start nfs-server

2.3 Test it

mount -t nfs4 $serverip:untrusted64 /mnt/
umount /mnt/

2.4 Secure it

2.4.1 Restricting to an interface

2.4.1.1 Iptables rules

Look at rpcinfo to find the ports used by your nfs daemon

rpcinfo -p

Then restrict to the network interface you want:

export allowed_interface="eth0"

iptables -A INPUT -p tcp -m tcp --dport 111 -j ACCEPT -i ${allowed_interface}
iptables -A INPUT -p udp -m udp --dport 111 -j ACCEPT -i ${allowed_interface}

iptables -A INPUT -p tcp -m tcp --dport 54064 -j ACCEPT -i ${allowed_interface}
iptables -A INPUT -p udp -m udp --dport 54064 -j ACCEPT -i ${allowed_interface}

iptables -A INPUT -p tcp -m tcp --dport 20048 -j ACCEPT -i ${allowed_interface}
iptables -A INPUT -p udp -m udp --dport 20048 -j ACCEPT -i ${allowed_interface}

iptables -A INPUT -p tcp -m tcp --dport 2049 -j ACCEPT -i ${allowed_interface}
iptables -A INPUT -p udp -m udp --dport 2049 -j ACCEPT -i ${allowed_interface}

iptables -A INPUT -p udp -m udp --dport 42503 -j ACCEPT -i ${allowed_interface}
iptables -A INPUT -p tcp -m tcp --dport 34038 -j ACCEPT -i ${allowed_interface}

iptables -A INPUT -p tcp -m tcp --dport 111 -j DROP
iptables -A INPUT -p udp -m udp --dport 111 -j DROP

iptables -A INPUT -p tcp -m tcp --dport 54064 -j DROP
iptables -A INPUT -p udp -m udp --dport 54064 -j DROP

iptables -A INPUT -p tcp -m tcp --dport 20048 -j DROP
iptables -A INPUT -p udp -m udp --dport 20048 -j DROP

iptables -A INPUT -p tcp -m tcp --dport 2049 -j DROP
iptables -A INPUT -p udp -m udp --dport 2049 -j DROP

iptables -A INPUT -p udp -m udp --dport 42503 -j DROP
iptables -A INPUT -p tcp -m tcp --dport 34038 -j DROP
2.4.1.2 Test the rules

showmount -e $serverip shouldn't show anything or should block if the incomming packet doesn't come from the allowed interface. If it does, then it will look like that:

$ showmount -e 192.168.2.1
Export list for 192.168.2.1:
/srv/nfs/untrusted64 *
/srv/nfs             *

2.5 Use it

Before securing the NFS export, you gave access to it to anybody that could reach your server.

  • Disable NFS temporarly for security reasons (you'll need to chroot inside the NFS share from your host).
  • Re-create the the client's rootfs before using it

3 Boot it

Now that the server serve the NFS rootfs, you will need to somehow:

  • Make the client load a kernel image
  • Make the client load an initramfs
  • Pass the right command line arguments for the kernel

For the first boot, prefer the fallback initramfs, because it will probably contains the NIC's kernel module, while the normal one probably won't.

Once booted regenerate the initramfs from the client. Don't chroot inside the nfs rootfs from the server once the client has touched it.

To load a kenrel image with some parameters and the initramfs, many ways are possible:

  • Make them load trough grub on a bootable media(like an USB key).
  • Use ipxe and http
  • Chainload ipxe trough pxe and use http