Backing Up with NFS and rsync

Assumptions & Prerequisites

  • Fresh install of RedHat/CentOS/Fedora on the server
  • minimal install profile
  • Security is not taken into account

Setup

A system running RedHat/CentOS/Fedora, but any Linux distribution will work with the proper modifications. Just to get something up and running, I did a minimal install of CentOS 6.4. The CentOS server will have a partition mounted at /mnt/backup which will be shared via NFS.

The machine that contains the files that we want to back up will mount the NFS share which is found on the server (/mnt/backup). I chose to have static IPs for the computers but you can use your own addressing scheme or DHCP.

  • Server Configuration
    • IP Address: 192.168.1.112
    • Netmask: 255.255.255.0
    • Gateway: 192.168.1.1
    • The backup directory that will be shared via NFS is /mnt/backup
    • IPTables is running
    • SELinux is running
  • Client
    • IP Address: 192.168.1.111
    • Netmask: 255.255.255.0
    • Gateway: 192.168.1.1
    • NFS mount directory: /mnt/nfs

Server Configuration

If need be, change eth0 to the name of your network interface.

ONBOOT=yes
BOOTPROTO=static
IPADDR=192.168.1.112
NETMASK=255.255.255.0
HOSTNAME=backup
GATEWAY=192.168.1.1
ifconfig eth0
route -n
ping google.com

IPTables Configuration

By default, iptables is installed and configured to only allow ssh connections. We will need to create a new rule which allows connections to TCP port 2049 and UDP port 53027.

# iptables -I INPUT -p tcp -s 192.168.1.111 --dport nfs -j ACCEPT
# iptables -I INPUT -p udp -s 192.168.1.111 --dport nfs -j ACCEPT
# service iptables save

If you do not want to use iptables, then stop the service and disable it from starting at boot:

# service iptables stop
#/sbin/chkconfig --level 2345 iptables off

SELInux Configuration

RedHat documentation states that all NFS policies are confined to default, meaning that no additional configuration or booleans need to be set.

NFS Server Setup and Configuration

Install the NFS server and client. If you want to have your backup directory some place else, substitute /mnt/backup with the desired location.

# yum -y install nfs-utils
# mkdir /mnt/backup
# chown nfsnobody:nfsnobody /mnt/backup
# /sbin/chkconfig --level 345 nfs on

On line 3, you're changing the permission of the backup directory so that it can be written to.

/mnt/backup 192.168.1.111(rw,root_squash)
exportfs -a

In the exports file, we're telling NFS to not allowing the root user access. Since we're not allowing root access, we will need to setup a user and create a directory in the exported directory with the proper permissions.

# useradd -s /bin/bash -m paulus
# passwd paulus
# mkdir /mnt/backup/paulus
# chmod paulus:paulus /mnt/backup/paulus

Client Configuration

No configuration is required. However, if you want to mount the NFS share on boot you will need to edit the fstab file.

192.168.1.112:/mnt/backup     /mnt/backup     rw,hard,intr     0     0

You should be familiar with the rw mount option. I'm using hard and intr. The hard option prevents corrupt data being written to the remote server. This can happen if there are any network connectivity issues. In the event that the NFS server is unreachable, then the program accessing the file will wait. However, you won't be able to kill the process except for a sure kill. Adding the intr option allows the process to be killed. To see a list of options view the man pages for the mount and nfs commands.

If you don't want to have the NFS share mounted at boot, run the following command.

mount -t nfs 192.168.1.112:/mnt/backup /mnt/nfs

rsync

Now that the NFS server is up and configured we can start backing up. The example below assumes that we have the NFS share mounted at /mnt/backup.

rsync -az /home /mnt/backup
rsync -az --progress /home/mnt/backup

The above will copy the home directory to the remote server. The resulting tree structure on the remote server will be /mnt/backup/home. If you add a trailing slash, it will copy all the files and directories in /home to /mnt/backup. The -a is saying you want to archive the directory and is equivelent to using -rlptgoD

  • -r, --recursive; recurse into directories
  • -l, --links; copy symlinks as symlinks. (You can use the -L, --copy-links to convert the links into files. Additionally specifying --copy-unsafe-links will trun links pointing to files outside of the tree into files  or --copy-safe-links will ignore links that point outside of the tree.)
  • -p, --perms; preserve permissions
  • -t, --times; preserve modification times
  • -g, --group; preserve group
  • -o, --owner; preserve owner
  • -D; same as --devices (causes rsync to transfer character and block device files to the remote system to recreate these devices.), --specials (causes rsync to transfer special files such as named sockets and fifos.)

Other options that you might find useful are:

  • --progress; Shows the progress of the operation.
  • --delete; Removes any files from the destination that aren't in the source.
  • -n, --dry-run; Shows you what's going to happen with out actually doing anything.
  • --exclude, --exclude-from; List of files and/or directories that you don't want to transfer. The first is the command line version. The second, allows you to create a file with a list of files and directories (one per line)

Troubleshooting

  • If you're unable to see the files, make sure the file system is actually mounted. 
    # cat /proc/mount
    # mount | grep nfs
    
  • Remount the file system
  • If the server is returning Permission denied:
    • Make sure that the volumes are exported. Try re-running exportfs on the server. (exportfs -ra)
    • If you are trying to mount the file system as rw and the export file has the volume exported as ro.
    • Check /proc/fs/nfs/exports or /var/lib/nfs/etab making sure the clients are correct.
    • You can not export a child and a parent. For example:
      /mnt/backup 192.168.1.111(rw)
      /mnt/backup/other_directory 192.168.1.111(rw)
  • Verify that NFS is actually running
       program vers proto   port  service
        100000    4   tcp    111  portmapper
        100000    3   tcp    111  portmapper
        100000    2   tcp    111  portmapper
        100000    4   udp    111  portmapper
        100000    3   udp    111  portmapper
        100000    2   udp    111  portmapper
        100024    1   udp  47994  status
        100024    1   tcp  36487  status
        100005    1   udp  38727  mountd
        100005    1   tcp  50962  mountd
        100005    2   udp  37566  mountd
        100005    2   tcp  39548  mountd
        100005    3   udp  55141  mountd
        100005    3   tcp  46667  mountd
        100003    2   tcp   2049  nfs
        100003    3   tcp   2049  nfs
        100003    4   tcp   2049  nfs
        100227    2   tcp   2049  nfs_acl
        100227    3   tcp   2049  nfs_acl
        100003    2   udp   2049  nfs
        100003    3   udp   2049  nfs
        100003    4   udp   2049  nfs
        100227    2   udp   2049  nfs_acl
        100227    3   udp   2049  nfs_acl
        100021    1   udp  38521  nlockmgr
        100021    3   udp  38521  nlockmgr
        100021    4   udp  38521  nlockmgr
        100021    1   tcp  35931  nlockmgr
        100021    3   tcp  35931  nlockmgr
        100021    4   tcp  35931  nlockmgr
    
  • On the client, make sure that NFS4 is enabled
    ffffffffa1391900 t nfs4_check_openmode  [nfsd]
    ffffffffa1391a70 t __nfs4_file_get_access       [nfsd]
    ffffffffa1391bc0 t nfs4_set_lock_denied [nfsd]
    ffffffffa1391d80 t nfs4_alloc_stid      [nfsd]
    ffffffffa1391ec0 t nfs4_access_to_omode [nfsd]
    ffffffffa1392300 t __nfs4_file_put_access       [nfsd]
    ffffffffa1392370 t nfs4_file_put_access [nfsd]
    ffffffffa1392490 t nfs4_get_vfs_file.isra.76    [nfsd]
    ffffffffa13928f0 t nfs4_share_conflict.isra.68  [nfsd]
    ffffffffa1393290 t nfs4_preprocess_seqid_op     [nfsd]
    ffffffffa13aa650 d nfs4_disable_idmapping       [nfsd]
    ffffffffa13a7248 r __param_nfs4_disable_idmapping       [nfsd]
    ffffffffa13a2000 r __param_str_nfs4_disable_idmapping   [nfsd]
    ... snip