diff options
-rwxr-xr-x | tests/basic/mount-nfs-auth.t | 166 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-volume-set.c | 20 | ||||
-rw-r--r-- | xlators/nfs/server/src/nfs.c | 68 |
3 files changed, 248 insertions, 6 deletions
diff --git a/tests/basic/mount-nfs-auth.t b/tests/basic/mount-nfs-auth.t index 55fe9327d0e..3e466170365 100755 --- a/tests/basic/mount-nfs-auth.t +++ b/tests/basic/mount-nfs-auth.t @@ -4,8 +4,7 @@ . $(dirname $0)/../nfs.rc cleanup; - -## Start and create a volume +## Check whether glusterd is running TEST glusterd TEST pidof glusterd TEST $CLI volume info @@ -102,6 +101,14 @@ function stat_nfs () { ls $N0/ } +# Restarts the NFS server +function restart_nfs () { + PID=$(ps aux | grep nfs | grep sbin/glusterfs | awk '{print $2}') + CMD=$(ps ax | grep nfs | grep sbin/glusterfs | awk '{$1=$2=$3=$4="";print $0}') + kill $PID + $CMD +} + setup_cluster # run preliminary tests @@ -122,7 +129,7 @@ TEST umount $N0 ## Disallow host TEST export_deny_this_host TEST netgroup_deny_this_host -sleep 2 +EXPECT_WITHIN $NFS_EXPORT_TIMEOUT "1" is_nfs_export_available ## Technically deauthorized this host, but since auth is disabled we should be ## able to do mounts, writes, etc. @@ -136,9 +143,156 @@ TEST umount $N0 export_allow_this_host netgroup_allow_this_host -# -# Most functional tests will get added with http://review.gluster.org/9364 -# +## Restart NFS with auth enabled +$CLI vol stop $V0 +TEST $CLI vol set $V0 nfs.exports-auth-enable on +$CLI vol start $V0 +EXPECT_WITHIN $NFS_EXPORT_TIMEOUT "1" is_nfs_export_available + +## Mount NFS +TEST do_mount $V0 +## Disallow host +TEST export_deny_this_host +TEST netgroup_deny_this_host + +## nfs-server is not enable to load the changes in the export/netgroup files +## dynamically, a restart is required. + +$CLI vol stop $V0 +$CLI vol start $V0 +EXPECT_WITHIN $NFS_EXPORT_TIMEOUT "1" is_nfs_export_available + +## Writes should not be allowed, host is not authorized +TEST ! small_write +## Unmount so we can test mount +TEST umount $N0 +## Subsequent ounts should not be allowed, host is not authorized +TEST ! do_mount $V0 + +## Reauthorize host +TEST export_allow_this_host +TEST netgroup_allow_this_host +$CLI vol stop $V0 +$CLI vol start $V0 +EXPECT_WITHIN $NFS_EXPORT_TIMEOUT "1" is_nfs_export_available + +TEST do_mount $V0 +TEST umount $N0 + +## Allow host in netgroups but not in exports, host should be allowed +TEST export_deny_this_host +TEST netgroup_allow_this_host +$CLI vol stop $V0 +$CLI vol start $V0 +EXPECT_WITHIN $NFS_EXPORT_TIMEOUT "1" is_nfs_export_available +TEST do_mount $V0 +TEST small_write +TEST big_write +TEST umount $N0 + +## Allow host in exports but not in netgroups, host should be allowed +TEST export_allow_this_host +TEST netgroup_deny_this_host +$CLI vol stop $V0 +$CLI vol start $V0 +EXPECT_WITHIN $NFS_EXPORT_TIMEOUT "1" is_nfs_export_available +TEST do_mount $V0 +TEST umount $N0 + +## Finally, reauth the host in export and netgroup, test mount & write +TEST export_allow_this_host_l1 +TEST netgroup_allow_this_host +$CLI vol stop $V0 +$CLI vol start $V0 +sleep 2 +TEST do_mount $V0L1 +TEST small_write + +## Failover test: Restarting NFS and then doing a write should pass +bg_write +TEST restart_nfs +TEST wait $BG_WRITE_PID +TEST small_write +TEST umount $N0 + +## Test deep mounts +TEST do_mount $V0L1 +TEST small_write +TEST umount $N0 + +TEST export_allow_this_host_ro +TEST netgroup_deny_this_host +$CLI vol stop $V0 +$CLI vol start $V0 +EXPECT_WITHIN $NFS_EXPORT_TIMEOUT "1" is_nfs_export_available +TEST do_mount $V0 +TEST ! small_write # Writes should not be allowed +TEST ! create # Create should not be allowed +TEST stat_nfs # Stat should be allowed +TEST umount $N0 + +TEST export_deny_this_host +TEST netgroup_deny_this_host +TEST export_allow_this_host_l1 # Allow this host at L1 +$CLI vol stop $V0 +$CLI vol start $V0 +EXPECT_WITHIN $NFS_EXPORT_TIMEOUT "1" is_nfs_export_available +TEST ! do_mount $V0 #V0 shouldnt be allowed +TEST do_mount $V0L1 #V0L1 should be +TEST umount $N0 + +## Test wildcard hosts +TEST export_allow_wildcard +$CLI vol stop $V0 +$CLI vol start $V0 +EXPECT_WITHIN $NFS_EXPORT_TIMEOUT "1" is_nfs_export_available +TEST do_mount $V0 +TEST small_write +TEST umount $N0 + +## Test if path is parsed correctly +## by mounting host:vol/ instead of host:vol +TEST do_mount $V0/ +TEST small_write +TEST umount $N0 + +TEST export_allow_this_host_with_slash +$CLI vol stop $V0 +$CLI vol start $V0 +EXPECT_WITHIN $NFS_EXPORT_TIMEOUT "1" is_nfs_export_available + +TEST do_mount $V0 +TEST small_write +TEST umount $N0 +TEST do_mount $V0/ +TEST small_write +TEST umount $N0 + + +## Turn off exports authentication +$CLI vol stop $V0 +TEST $CLI vol set $V0 nfs.exports-auth-enable off +$CLI vol start $V0 + +TEST export_deny_this_host # Deny the host +TEST netgroup_deny_this_host +$CLI vol stop $V0 +$CLI vol start $V0 +EXPECT_WITHIN $NFS_EXPORT_TIMEOUT "1" is_nfs_export_available + +TEST do_mount $V0 # Do a mount & test +TEST umount $N0 + +## Turn back on the exports authentication +$CLI vol stop $V0 +TEST $CLI vol set $V0 nfs.exports-auth-enable on +$CLI vol start $V0 +EXPECT_WITHIN $NFS_EXPORT_TIMEOUT "1" is_nfs_export_available +## Do a simple test to set the refresh time to 20 seconds +TEST $CLI vol set $V0 nfs.auth-refresh-interval-sec 20 + +## Do a simple test to see if the volume option exists +TEST $CLI vol set $V0 nfs.auth-cache-ttl-sec 400 ## Finish up TEST $CLI volume stop $V0 diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-set.c b/xlators/mgmt/glusterd/src/glusterd-volume-set.c index 891801fd755..4d9dce47a13 100644 --- a/xlators/mgmt/glusterd/src/glusterd-volume-set.c +++ b/xlators/mgmt/glusterd/src/glusterd-volume-set.c @@ -1527,6 +1527,26 @@ struct volopt_map_entry glusterd_volopt_map[] = { .op_version = 3 }, + /* Cli options for Export authentication on nfs mount */ + { .key = "nfs.exports-auth-enable", + .voltype = "nfs/server", + .option = "nfs.exports-auth-enable", + .type = GLOBAL_DOC, + .op_version = GD_OP_VERSION_3_7_0 + }, + { .key = "nfs.auth-refresh-interval-sec", + .voltype = "nfs/server", + .option = "nfs.auth-refresh-interval-sec", + .type = GLOBAL_DOC, + .op_version = GD_OP_VERSION_3_7_0 + }, + { .key = "nfs.auth-cache-ttl-sec", + .voltype = "nfs/server", + .option = "nfs.auth-cache-ttl-sec", + .type = GLOBAL_DOC, + .op_version = GD_OP_VERSION_3_7_0 + }, + /* Other options which don't fit any place above */ { .key = "features.read-only", .voltype = "features/read-only", diff --git a/xlators/nfs/server/src/nfs.c b/xlators/nfs/server/src/nfs.c index 4de81769fff..27dad2221a9 100644 --- a/xlators/nfs/server/src/nfs.c +++ b/xlators/nfs/server/src/nfs.c @@ -875,8 +875,58 @@ nfs_init_state (xlator_t *this) } nfs->exports_auth = GF_NFS_DEFAULT_EXPORT_AUTH; + if (dict_get(this->options, "nfs.exports-auth-enable")) { + ret = dict_get_str (this->options, "nfs.exports-auth-enable", + &optstr); + if (ret == -1) { + gf_log (GF_NFS, GF_LOG_ERROR, "Failed to parse dict"); + goto free_foppool; + } + + ret = gf_string2boolean (optstr, &boolt); + if (ret < 0) { + gf_log (GF_NFS, GF_LOG_ERROR, "Failed to parse bool " + "string"); + goto free_foppool; + } + + if (boolt == _gf_true) + nfs->exports_auth = 1; + } + nfs->auth_refresh_time_secs = GF_NFS_DEFAULT_AUTH_REFRESH_INTERVAL_SEC; + if (dict_get (this->options, "nfs.auth-refresh-interval-sec")) { + ret = dict_get_str (this->options, + "nfs.auth-refresh-interval-sec", &optstr); + if (ret < 0) { + gf_log (GF_NFS, GF_LOG_ERROR, "Failed to parse dict"); + goto free_foppool; + } + + ret = gf_string2uint (optstr, &nfs->auth_refresh_time_secs); + if (ret < 0) { + gf_log (GF_NFS, GF_LOG_ERROR, "Failed to parse uint " + "string"); + goto free_foppool; + } + } + nfs->auth_cache_ttl_sec = GF_NFS_DEFAULT_AUTH_CACHE_TTL_SEC; + if (dict_get (this->options, "nfs.auth-cache-ttl-sec")) { + ret = dict_get_str (this->options, + "nfs.auth-cache-ttl-sec", &optstr); + if (ret < 0) { + gf_log (GF_NFS, GF_LOG_ERROR, "Failed to parse dict"); + goto free_foppool; + } + + ret = gf_string2uint (optstr, &nfs->auth_cache_ttl_sec); + if (ret < 0) { + gf_log (GF_NFS, GF_LOG_ERROR, "Failed to parse uint " + "string"); + goto free_foppool; + } + } /* TODO: Make this a configurable option in case we don't want to read * exports/netgroup files off disk when they change. */ @@ -1905,5 +1955,23 @@ struct volume_options options[] = { .description = "Sets the number of non-idempotent " "requests to cache in drc" }, + { .key = {"nfs.exports-auth-enable"}, + .type = GF_OPTION_TYPE_BOOL, + .description = "Set the option to 'on' to enable exports/netgroup " + "authentication in the NFS server and mount daemon." + }, + + { .key = {"nfs.auth-refresh-interval-sec"}, + .type = GF_OPTION_TYPE_INT, + .description = "Frequency in seconds that the daemon should check for" + " changes in the exports/netgroups file." + }, + + { .key = {"nfs.auth-cache-ttl-sec"}, + .type = GF_OPTION_TYPE_INT, + .description = "Sets the TTL of an entry in the auth cache. Value is " + "in seconds." + }, + { .key = {NULL} }, }; |