IN THIS ARTICLE
Outlines how to create NFS Exports with multiple IP restrictions and user mappings
REQUIREMENTS
- Cluster running Qumulo Core version 2.7.8 and above to provide a restrictions JSON file
- Cluster running Qumulo Core version 2.12.6 and above for the nfs_mod_export_host_access command
- Command line (CLI) tools installed via APIs & Tools tab
GLOSSARY
UID: User Identity Number (uidNumber) used to identify NFS users
GID: Group Identity Number (gidNumber) used to identify NFS user groups
Host: The IP address of the system running the NFS client software connecting to the Qumulo File System
Subnet: A network segment encompassing multiple hosts
Export: An NFS access mount point to the Qumulo File System as defined by the Qumulo administrator
DETAILS
IP RESTRICTIONS
IP restrictions allow access control to a particular NFS export to only the IP addresses of the hosts on an access list. A range of IP addresses or entire subnets can be specified in the access list and any connection attempts coming from an IP address not covered in the access list will be denied access.
The IP restrictions will be enforced in the order they are written from top to bottom. Once a condition is met then that rule is applied. Be aware of this behavior as you create your list of rules. To prevent unintended results, list IP-specific rules at the top of the list and Subnet-wide rules at the bottom.
USER MAPPING
User Mapping (or User Squashing) is the process of converting the incoming UID of an NFS user into the UID Number specified in the NFS export's settings. When NFS operations are performed on an export with User Mapping enabled, those operations will be performed as the UID/GID specified in the export's settings.
User Mapping is possible for two types of users:
- Root or UID 0
- All other users / UIDs
Note that Root or UID 0 is the only individual user to whom specific rules can be applied. Every other non-Root UID will be handled by the All set of rules. Using the All value in the user_mapping key, all non-root incoming UID values will be remapped to the desired UID/GID value to ensure consistent file ownership.
ROOT SQUASHING
Whenever an NFS user is logged in as local Root or performs a file operation as a sudoer, UID 0 is sent over NFS as the user identity. This would normally grant the NFS user the same rights as the local Qumulo Admin including the ability to read, delete and modify any object in the File System.
Root Squashing is enabled via the root or 0 value in the user_mapping key. With Root Squashing, this UID is remapped to the desired value to prevent unauthorized root access to an NFS Export, to specific Hosts and Subnets or to ensure consistent file ownership.
Through using IP restrictions, it is possible to create a list that allows specific Hosts to act as Root/Sudoers while restricting all other Hosts.
QQ COMMANDS
The following QQ commands are available to manage NFS exports via the Qumulo API:
Command | Description |
qq nfs_add_export
|
Add a new NFS export |
qq nfs_delete_export
|
Delete an export |
qq nfs_get_export
|
Get an exports details based on ID |
qq nfs_list_exports
|
List all NFS exports |
qq nfs_mod_export
|
Modify an export (2.7.8 or above) |
qq nfs_mod_export_host_access
|
Add, remove, or modify individual host restriction entries (2.12.6 or above) |
INSPECT EXPORT RESTRICTIONS
To inspect restrictions from the Qumulo API, use the following qq command:
qq nfs_list_exports
qq nfs_get_export --export-path /
Example output of qq nfs_list_exports --export-path /:
ID: 1
Export Path: /
FS Path: /
Description: A neat root export.
32 bit mode: False
Host Access:
ID Hosts Access Options
== ============================ ===================================================
1 10.120.252.10 rw, insecure, all_squash, anonlocal=guest
2 10.120.253.20, 10.120.253.21 rw, insecure, no_root_squash
3 10.120.253.0/24 rw, insecure, root_squash, anonuid=994, anongid=994
Note that the option names have been chosen to correspond to equivalent options in a standard /etc/exports configuration. See below for a detailed description of their meanings.
Note that prior to Qumulo Core 2.12.6, this command provided the same information, but formatted it as a JSON object.
MODIFY EXPORT RESTRICTIONS (2.12.6 OR ABOVE)
For older versions, it is necessary to configure restrictions with a JSON file; see instructions below.
The export restrictions list can be modified with the “qq nfs_mod_export_host_access” command. This command requires that the export be identified using either the --id or --export-path option, and then a subcommand to add, modify, or remove and entry.
Add a New Entry
The “add_entry” subcommand will add a new entry, at the specified position. It has the following options, whose names have been chosen to be familiar to those accustomed to /etc/exports:
--hosts 1.1.1.1 fd00:0:0:42::/64 | The hosts to which this entry applies. ‘*’ matches all. May be IP addresses, CIDR masks (e.g. 10.1.2.0/24), or ranges (e.g. 10.2.3.23-47, fd00::42:1fff-c000). Multiple values may be given, separated by spaces. |
--insert-after N | Specify which item in the existing list (as displayed in “qq nfs_get_export”) the new entry should follow. “0” means the beginning of the list. If not specified, the entry is added to the end of the list. |
--rw --ro |
Specify whether hosts matching this entry should be granted read+write or read-only access. --rw is the default if neither are given. |
--no-root-squash |
Specify whether hosts matching this entry should be granted read+write or read-only access. --rw is the default if neither are given.Specify whether, root, everyone, or nobody should be squashed. --no-root-squash is the default if none is given. If --root-squash or --all-squash is specified, the user to map to must also be specified (see below). |
--anon-local <username> | Squashed users should be mapped to the local user with the given username. Note that the local guest user is the same as nobody. |
--anon-uid ### --anon-gid ### |
Squashed users should be mapped to the specified posix UID and GID. |
--secure --insecure |
Whether or not connections from unprivileged source ports (i.e. those over 1024) are permitted. Note that --secure has little practical security benefit in many environments, and will make access by OSX clients difficult, as they use unprivileged ports by default. |
For example, in order to allow read+write access to hosts in the 10.1.42.0/24 subnet with root access squashed to guest (which is the same as nfsnobody):
qq nfs_mod_export_host_access --export-path /export add_entry --hosts 10.1.42.0/24 --root-squash --anon-local guest
Host Access:
ID Hosts Access Options
== ============ ==========================================
1 10.1.42.0/24 rw, insecure, root_squash, anonlocal=guest
Modify an Existing Entry
The “modify_entry” subcommand can be used to modify any part of an existing entry. The entry to modify is identified by its position, as shown in “qq nfs_get_export”, which is specified with the --position argument. Otherwise, this command has the same arguments as are given when adding an entry. Any option not specified will be left unchanged.
For example, to broaden the entry created in the previous example to cover all hosts:
qq nfs_mod_export_host_access --export-path /export modify_entry --position 1 --hosts '*'
Remove an Existing Entry
The “remove_entry” subcommand can be used to remove an entry. The entry to remove is identified by its position, as shown in “qq nfs_get_export”, which is specified with the --position argument. If the list has only one entry, it is not possible to remove that entry.
For example, to remove the second entry from an export’s restrictions:
qq nfs_mod_export_host_access --export-path /export remove_entry -p 2
EXPORT RESTRICTIONS VIA JSON RESTRICTIONS FILE (2.12.5 AND BELOW)
This is the only method available for setting restrictions in Qumulo Core 2.12.5 and below. While it will work in later versions, “qq nfs_mod_export_host_access” should be preferred in most circumstances.
The application of IP restrictions and User mapping rules requires the creation of a JSON file including the following keys to be referenced.
read_only: Input True or false value to determine whether the NFS export is writeable or read-only
host_restrictions: List of IPs and Subnets (individual IPs before subnets) that are allowed access to the export
- IPs not covered in any host_restrictions key in the JSON file will be denied access
user_mapping: List of incoming UIDs to be remapped
- root - Intercepts only incoming UID 0 and remaps it
- all - Every incoming UID will be remapped
- none - No UIDs are remapped and only Host restrictions are enforced. If the key value "none" is selected then it is not necessary to add a map_to_user_id key.
map_to_user: Select what user incoming UIDs covered in the user_mapping key will be remapped to. This may be either a local user, or a posix UID. If a UID is given, the map_to_group field must also be specified. This field is a JSON object with the following format:
- {"id_type": "LOCAL_USER", "id_value": "<username>"}
- {"id_type": "NFS_UID", "id_value": "###"}
map_to_group: Select which posix GID will be applied when the incoming UID is mapped to a posix UID. This field is a JSON object with the following format:
- {"id_type": "NFS_GID", "id_value": "###"}
Please note that multiple JSON objects (Groups of complete restriction rules) need to be separated by a comma after the object’s closing curly brace as outlined in the example below.
{
"restrictions": [
{
"host_restrictions": ["10.120.252.10"],
"read_only": false,
"user_mapping": "all",
"map_to_user": {"id_type": "LOCAL_USER", "id_value": "guest"}
},
{
"host_restrictions": ["10.120.253.20","10.120.253.21"],
"read_only": false,
"user_mapping": "none"
},
{
"host_restrictions": ["10.120.253.0/24"],
"read_only": false,
"user_mapping": "root",
"map_to_user": {"id_type": "NFS_UID", "id_value": "994"},
"map_to_group": {"id_type": "NFS_GID", "id_value": "994"}
}
]
}
This sample JSON file indicates the following:
- Host 10.120.252.10 will have any incoming UID mapped to Local User guest
- Host 10.120.253.20 will not be subjected to any UID remapping and use the UID as provided by the NFS client
- Subnet 10.20.253.0/24 will have any incoming UID 0 users remapped to UID 994 and GID 994
APPLY THE RESTRICTIONS
Implementing the restrictions to the NFS export(s) can be done in multiple ways. To create an NFS export with restrictions via the API, use the command below.
qq nfs_add_export --export-path / --fs-path / --restrictions /path/to/restrictions.json
To apply a list of restrictions to an existing NFS export, first r etrieve the export ID from the list of exports using the following command:
qq nfs_list_exports
Modify the NFS export using the ID and path to the restricitons.json:
qq nfs_mod_export --id 5 --restrictions /path/to/restrictions.json
Once the rules have been applied, the JSON file is no longer required and can be deleted but it should be saved elsewhere for your own documentation.
VERIFY NFS RESTRICTIONS
To verify the restriction from an NFS client, use the showmount command below:
showmount -e ip.of.qumulo.node (Or FQDN of cluster)
Example output:
showmount -e 10.120.249.58
Exports list on 10.120.249.58:
/ Everyone
/admin_files 10.220.246.80 10.0.0.0/10
/files Everyone
/replicate 10.120.253.21 10.120.253.0/24
VERIFY NFS RESTRICTIONS FROM THE QUMULO API
To verify restriction from the Qumulo API, use the following qq command:
qq nfs_list_exports
Example output:
qq nfs_list_exports
[
{
"description": "",
"export_path": "/",
"fs_path": "/",
"id": "1",
"restrictions": [
{
"host_restrictions": [],
"map_to_user_id": "0",
"read_only": false,
"user_mapping": "NFS_MAP_NONE"
}
]
},
{
"description": "",
"export_path": "/Home",
"fs_path": "/users/Home",
"id": "7",
"restrictions": [
{
"host_restrictions": [],
"map_to_user_id": "0",
"read_only": false,
"user_mapping": "NFS_MAP_NONE"
}
]
}
RESOLUTION
You should now be able successfully create NFS Exports with multiple IP restrictions and user mappings
ADDITIONAL RESOURCES
QQ CLI: Admins, Users and Groups
Like what you see? Share this article with your network!
Comments
0 comments
Please sign in to leave a comment.