The is a module for managing the exporting and mounting of NFS devices. It provides all the infrastructure needed to share folders over the network.
The module is broken into two parts: the server and the client. It supports security with either krb5 or stunnel, but not both, as these security services conflict at a system level. It also manages firewall and TCP wrapper settings, when enabled.
This module is a component of the System Integrity Management Platform, a compliance-management framework built on Puppet.
If you find any issues, they may be submitted to our bug tracker.
This module is optimally designed for use within a larger SIMP ecosystem, but it can be used independently:
- When included within the SIMP ecosystem, security compliance settings will be managed from the Puppet server.
- If used independently, all SIMP-managed security subsystems are disabled by
default and must be explicitly opted into by administrators. See the
SIMP
simp_optionsmodule for more detail.
The nfs module installs NFS packages, configures services for the
NFS server and/or client and manages most NFS configuration files.
The only requirement is to include the nfs module and its dependencies
in your modulepath.
- If you are using any of the
nfsmodule's optional dependencies, e.g.autofs, please also include those modules in the module path as well. The list of optional dependencies can be found in thenfsmodule'smetadata.jsonfile undersimp/optional_dependencies.
You can use the nfs module to manage NFS settings for a node that is a NFS
client, a NFS server or both.
Including one or more nfs::client::mount defines in a node's manifest
will automatically include the nfs::client class, which, in turn, will
ensure the appropriate packages are installed and appropriate services
are configured and started.
Including one or more nfs::server::export defines in a node's manifest
and setting the hiera below will automatically include the nfs::server
class, which, in turn, will ensure the appropriate packages are installed and
appropriate services are configured.
nfs::is_server: true
nfs::is_client: falseIncluding one or more nfs::server::export or nfs::client::mount defines
in a node's manifest and setting the hiera below will automatically include
the nfs::server and nfs::client classes. This will, in turn, ensure
the appropriate packages are installed and appropriate services are configured
for both roles.
nfs::is_server: trueTo export /srv/nfs_share, add the following to the NFS server's manifest:
nfs::server::export { 'nfs4_root':
client => [ <trusted networks> ]
export_path => '/srv/nfs_share',
require => File['/srv/nfs_share']
}
file { '/srv/nfs_share':
ensure => 'directory',
owner => 'root',
group => 'root',
mode => '0644'
}Be sure to set the following in hiera, as well:
nfs::is_server: trueTo mount /srv/nfs_share statically to /mnt/nfs on the NFS client using
NFSv4, add the following to the NFS client's manifest:
$mount_dir = '/mnt/nfs'
nfs::client::mount { $mount_dir:
nfs_server => '<NFS server IP>',
remote_path => '/srv/nfs_share',
autofs => false
}
# mount directory must exist if not using autofs
file { $mount_dir:
ensure => 'directory',
owner => 'root',
group => 'root',
mode => '0644'
}
File[$mount_dir] -> Nfs::Client::Mount[$mount_dir]To automount /exports/data as /data using an direct mount,
add the following to the NFS client's manifest:
nfs::client::mount { '/data':
nfs_server => '<NFS server IP>',
remote_path => '/exports/data'
}To automount /exports/apps as /apps using an indirect mount with key
substitution, add the following to the NFS client's manifest:
nfs::client::mount { '/apps':
nfs_server => '<NFS server IP>',
remote_path => '/exports/apps',
autofs_indirect_map_key => '*',
autofs_add_key_subst => true
}Please reference the SIMP documentation for details on how to implement this feature.
WARNING
This functionality requires some manual configuration and when keys change may require manual purging of the
gssproxycache.
This module, used with the SIMP krb5 module,
can automatically use kerberos to secure the exported filesystem. The module
can create and manage the entire kerberos configuration automatically, but
check the krb5 module itself if you want more control.
Modify the examples provided above to include the following hieradata on all nodes:
simp_options::kerberos: true
nfs::secure_nfs: true
krb5::config::dns_lookup_kdc: false
krb5::kdc::auto_keytabs::global_services:
- 'nfs'On the node intended to be the KDC, include the following class:
include 'krb5::kdc'On the NFS server and client nodes, add the following to each node's manifest:
# If your realm is not your domain name then change this
# to the string that is your realm
$myrealm = upcase($facts['domain'])
krb5::setting::realm { $myrealm:
admin_server => <KDC fqnd>,
default_domain => $myrealm
}SIMP does not have kerberos set up to work automatically with LDAP yet. You must add a principal for each user you want to give access to the krb5 protected directories. To do this log onto the KDC and run:
kadmin.local
# Note the prompt is now kadmin.local!
kadmin.local: add_principal -pw <password> <username>
...
kadmin.local: exitWhen the user logs on after kerberos has been configured they must run:
kinitIt will ask them for their password. Once the have done this they should be able to access any shares from that realm.
When use of kerberos is not viable, but you want to encrypt NFS traffic,
you can configure the NFS server and client to use stunnel automatically
on NFSv4 connections.
This module uses the SIMP stunnel module
for stunnel management.
In this scenario, we will consider a site with one NFS server.
To enable use of stunnel at the NFS server, set the following in hieradata:
nfs::is_server: true
nfs::stunnel: trueTo export /srv/nfs_share, add the following to the NFS server's manifest:
nfs::server::export { 'nfs4_root':
client => [ <trusted networks> ]
export_path => '/srv/nfs_share',
# This MUST be set to true due to a NFS exports processing bug.
# See description in nfs::server::export.
insecure => true,
require => File['/srv/nfs_share']
}
file { '/srv/nfs_share':
ensure => 'directory',
owner => 'root',
group => 'root',
mode => '0644'
}To enable use of stunnel at the NFS client, set the following in hieradata:
nfs::stunnel: trueTo mount /srv/nfs_share statically to /mnt/nfs on the NFS client,
add the following to the NFS client's manifest:
$mount_dir = '/mnt/nfs'
nfs::client::mount { $mount_dir:
nfs_server => '<NFS server IP>',
remote_path => '/srv/nfs_share',
autofs => false
}
# mount directory must exist if not using autofs
file { $mount_dir:
ensure => 'directory',
owner => 'root',
group => 'root',
mode => '0644'
}
File[$mount_dir] -> Nfs::Client::Mount[$mount_dir]In this simple case, the mount manifest looks exactly the same as in the unencrypted case. Only the hieradata has changed.
In this scenario, we will consider a site with two NFS servers. The example shown can be extrapolated to any number of NFS servers.
The first NFS server will be configured exactly as is done with the single server example above.
Server 1 hieradata:
nfs::is_server: true
nfs::stunnel: trueServer 1 manifest:
nfs::server::export { 'nfs4_root':
client => [ <trusted networks> ]
export_path => '/srv/nfs_share',
# This MUST be set to true due to a NFS exports processing bug
insecure => true,
require => File['/srv/nfs_share']
}
file { '/srv/nfs_share':
ensure => 'directory',
owner => 'root',
group => 'root',
mode => '0644'
}The second NFS server requires a little more configuration.
To enable use of stunnel at this NFS server and prevent port conflicts with Server 1 on any client that wants to mount from both servers over stunnel, set the following in hieradata:
nfs::is_server: true
nfs::stunnel: true
# The nfsd port must be unique among all NFS servers at the site.
# The stunnel nfsd port is configured here for consistency, but
# could be left at the default.
nfs::nfsd_port: 2050
nfs::stunnel_nfsd_port: 20500To export /srv/nfs_share2, add the following to Server 2's manifest:
nfs::server::export { 'nfs4_root':
client => [ <trusted networks> ]
export_path => '/srv/nfs_share2',
# This MUST be set to true due to a NFS exports processing bug
insecure => true,
require => File['/srv/nfs_share2']
}
file { '/srv/nfs_share2':
ensure => 'directory',
owner => 'root',
group => 'root',
mode => '0644'
}To enable use of stunnel at the NFS client, set the following in hieradata:
nfs::stunnel: trueTo mount /srv/nfs_share from Server 1 statically to /mnt/nfs
and /srv/nfs_share2 from Server 2 statically to /mnt/nfs2,
add the following to the NFS client's manifest:
# this mount uses the defaults, because Server 1 uses nfs
# module defaults
$mount_dir = '/mnt/nfs'
nfs::client::mount { $mount_dir:
nfs_server => '<NFS Server 1 IP>',
remote_path => '/srv/nfs_share',
autofs => false
}
# this mount sets ports to match those of Server 2
$mount_dir2 = '/mnt/nfs2'
nfs::client::mount { $mount_dir2:
nfs_server => '<NFS Server 2 IP>',
remote_path => '/srv/nfs_share2',
autofs => false,
nfsd_port => 2050,
stunnel_nfsd_port => 20500
}
# mount directories must exist if not using autofs
file { [ $mount_dir, $mount_dir2 ]:
ensure => 'directory',
owner => 'root',
group => 'root',
mode => '0644'
}
File[$mount_dir] -> Nfs::Client::Mount[$mount_dir]
File[$mount_dir2] -> Nfs::Client::Mount[$mount_dir2]NFSv3 traffic cannot be encrypted with stunnel because of two key reasons:
-
The NFS client sends the NFS server Network Status Manager (NSM) notifications via UDP, exclusively.
stunnelonly handles TCP traffic.- Loss of these notification may affect NFS performance.
-
In multi-NFS-server environments, there is no mechanism to configure
rpcbindto use a non-standard port.- NFSv3 heavily relies upon
rpcbindto determine the side-band channel ports in use on the NFS nodes. This includes thestatdandlockdports used in NSM and NLM, respectively. - A unique
rpcbindport per server is required in order for a NFS client to be able tunnel its server-specific RPC requests to the appropriate server.
- NFSv3 heavily relies upon
Despite this limitation, this module still fully supports unencrypted NFSv3 and allows the NFS server and client to use unencrypted NFSv3 concurrently with stunneled NFSv4.
-
If a NFS server is configured to both allow NFSv3 and to use stunnel, it will accept unencrypted NFSv3 connections, unencrypted NFSv4 connections and stunneled NFSv4 connections.
The hieradata for this configuration is:
nfs::is_server: true nfs::nfsv3: true nfs::stunnel: true
-
If a NFS client is configured to both allow NFSv3 and to use stunnel, it can use unencrypted NFSv3 mounts and stunneled NFSv4 mounts.
The hieradata for this configuration is:
nfs::nfsv3: true nfs::stunnel: true
This module can be configured to automatically add firewall rules and allow
NFS services in TCP wrappers using the
SIMP iptables module and the
SIMP tcpwrappers module,
respectively.
To enable these features on the NFS server and NFS client nodes, add the following to their hieradata:
simp_options::firewall: true
simp_options::tcpwrappers: truePlease refer to the REFERENCE.md.
This module does not yet manage the following:
-
/etc/nfsmounts.conf -
gssproxyconfiguration- If you are using a custom keytab location, you must fix the
cred_storeentries in/etc/gssproxy/24-nfs-server.confand/etc/gssproxy/99-nfs-client.conf. - If a node's keytab has changed content and the old keytab entries
are no longer valid, you will have to manually clear the
gssproxycredential cache usingkdestroy -c <gssproxy cache>. Simply restarting thegssproxyservice does not clear the cache and re-read the keytab!
- If you are using a custom keytab location, you must fix the
-
RDMA packages or its service
-
idmapdconfiguration for theumich_ldaptranslation method- If you need to configure this, consider using
nfs::idmapd::config::contentto specify full contents of the/etc/idmapd.conffile.
- If you need to configure this, consider using
This module does not address an intermittent systemd issue in which the
rpc.statd NFSv3 daemon is not always stopped when the rpc-statd service is
stopped. When this occurs,
-
systemdno longer has a record of that daemon's PID and cannot fix the problem. -
The
rpc-statdservice cannot be subsequently started.- When the service tries to start another instance of
rpc.statd, the new instance detects the running instance and then immediately exits with a failed exit code.
- When the service tries to start another instance of
-
You must manually kill the running
rpc.statddaemon to recover.
SIMP Puppet modules are generally intended for use on Red Hat Enterprise Linux
and compatible distributions, such as CentOS. Please see the metadata.json file
for the most up-to-date list of supported operating systems, Puppet versions,
and module dependencies.
Please read our Contribution Guide.
This module includes Beaker acceptance tests using the SIMP Beaker Helpers. By default the tests use Vagrant with VirtualBox as a back-end; Vagrant and VirtualBox must both be installed to run these tests without modification. To execute the tests run the following:
bundle install
bundle exec rake beaker:suitesPlease refer to the SIMP Beaker Helpers documentation for more information.