#!/sbin/sh # # Check if any local file systems are being exported to 'localhost'. # Check the local host is in a netgroups entry in its own exports file. # # See: http://www.cert.org/advisories/CA-1994-15.html # # I did not attempt to unroll the netgroup file to see if the host is # self-referencing. # Check if /etc/exports file exists test ! -f /etc/exports && return # Check export option access list for an instance of 'localhost', # the host name, the loopback IP, or a netgroup that could contain # any of these. # # $1 Exported directory # $2 Export option # $3 Colon-separated export setting # function check_access { HOSTNAME=$(hostname) echo ${3} |\ awk -F':' '{ for ( i=1; i<=NF; i++ ) { print $i } }' |\ while read ACCESS do # Check if NFS server is exporting to itself if [[ ${ACCESS%.?*} = "localhost" ]] then echo "WARNING: export of ${1} uses 'localhost' for ${2} option" elif [[ ${ACCESS%.?*} = ${HOSTNAME} ]] then echo "WARNING: export of ${1} uses '${HOSTNAME}' for ${2} option" elif [[ ${ACCESS} = "127.0.0.1" ]] then echo "WARNING: export of ${1} uses '127.0.0.1' for ${2} option" elif [[ ${ACCESS#@} != ${ACCESS} ]] then # Use of netgroup would be bad if it allows NFS server to export # to itself. So operator needs to check... echo "CAUTION: export of ${1} uses netgroup '${ACCESS}' for ${2} option" fi done } # Check the -options- for the exports file entry # # $1 Exported directory # $2 Comma-separated export options # function check_options { # Parse the individual options echo $2 |\ awk -F',' '{ for ( i=1; i<=NF; i++ ) { print $i } }' |\ while read OPTION do # Process export options that use a host or access entry case ${OPTION%=?*} in rw|root|access) check_access $1 ${OPTION%=?*} ${OPTION#?*=} ;; esac done } # Find entries in exports file with 2 or more fields sed -e "s/#.*$//" /etc/exports |\ awk -F'-' '{ if ( NF > 1 ) { printf " \n", $1, $2 } }' |\ while read DIRECTORY OPTIONS do # Check arguments for NFS server self-reference check_options ${DIRECTORY} ${OPTIONS} done