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_options
module 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
nfs
module'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 thenfs
module'smetadata.json
file 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: false
Including 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: true
To 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: true
To 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
gssproxy
cache.
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: exit
When the user logs on after kerberos has been configured they must run:
kinit
It 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: true
To 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: true
To 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: true
Server 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: 20500
To 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: true
To 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.
stunnel
only handles TCP traffic.- Loss of these notification may affect NFS performance.
-
In multi-NFS-server environments, there is no mechanism to configure
rpcbind
to use a non-standard port.- NFSv3 heavily relies upon
rpcbind
to determine the side-band channel ports in use on the NFS nodes. This includes thestatd
andlockd
ports used in NSM and NLM, respectively. - A unique
rpcbind
port 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: true
Please refer to the REFERENCE.md.
This module does not yet manage the following:
-
/etc/nfsmounts.conf
-
gssproxy
configuration- If you are using a custom keytab location, you must fix the
cred_store
entries in/etc/gssproxy/24-nfs-server.conf
and/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
gssproxy
credential cache usingkdestroy -c <gssproxy cache>
. Simply restarting thegssproxy
service 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
-
idmapd
configuration for theumich_ldap
translation method- If you need to configure this, consider using
nfs::idmapd::config::content
to specify full contents of the/etc/idmapd.conf
file.
- 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,
-
systemd
no longer has a record of that daemon's PID and cannot fix the problem. -
The
rpc-statd
service 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.statd
daemon 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:suites
Please refer to the SIMP Beaker Helpers documentation for more information.