aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2008-12-23 15:21:37 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2008-12-23 15:21:37 -0500
commitd740351bf0960e89ce1aef45cfe00167cb0f9e5b (patch)
tree9b0838d5105942d0b061c26cad68aa0380a3ce7c /fs/nfs
parent542fcc334adfea36d407cbf698d549fcb2bf6b91 (diff)
NFS: add "[no]resvport" mount option
The standard default security setting for NFS is AUTH_SYS. An NFS client connects to NFS servers via a privileged source port and a fixed standard destination port (2049). The client sends raw uid and gid numbers to identify users making NFS requests, and the server assumes an appropriate authority on the client has vetted these values because the source port is privileged. On Linux, by default in-kernel RPC services use a privileged port in the range between 650 and 1023 to avoid using source ports of well- known IP services. Using such a small range limits the number of NFS mount points and the number of unique NFS servers to which a client can connect concurrently. An NFS client can use unprivileged source ports to expand the range of source port numbers, allowing more concurrent server connections and more NFS mount points. Servers must explicitly allow NFS connections from unprivileged ports for this to work. In the past, bumping the value of the sunrpc.max_resvport sysctl on the client would permit the NFS client to use unprivileged ports. Bumping this setting also changes the maximum port number used by other in-kernel RPC services, some of which still required a port number less than 1023. This is exacerbated by the way source port numbers are chosen by the Linux RPC client, which starts at the top of the range and works downwards. It means that bumping the maximum means all RPC services requesting a source port will likely get an unprivileged port instead of a privileged one. Changing this setting effects all NFS mount points on a client. A sysadmin could not selectively choose which mount points would use non-privileged ports and which could not. Lastly, this mechanism of expanding the limit on the number of NFS mount points was entirely undocumented. To address the need for the NFS client to use a large range of source ports without interfering with the activity of other in-kernel RPC services, we introduce a new NFS mount option. This option explicitly tells only the NFS client to use a non-privileged source port when communicating with the NFS server for one specific mount point. This new mount option is called "resvport," like the similar NFS mount option on FreeBSD and Mac OS X. A sister patch for nfs-utils will be submitted that documents this new option in nfs(5). The default setting for this new mount option requires the NFS client to use a privileged port, as before. Explicitly specifying the "noresvport" mount option allows the NFS client to use an unprivileged source port for this mount point when connecting to the NFS server port. This mount option is supported only for text-based NFS mounts. [ Sidebar: it is widely known that security mechanisms based on the use of privileged source ports are ineffective. However, the NFS client can combine the use of unprivileged ports with the use of secure authentication mechanisms, such as Kerberos. This allows a large number of connections and mount points while ensuring a useful level of security. Eventually we may change the default setting for this option depending on the security flavor used for the mount. For example, if the mount is using only AUTH_SYS, then the default setting will be "resvport;" if the mount is using a strong security flavor such as krb5, the default setting will be "noresvport." ] Signed-off-by: Chuck Lever <chuck.lever@oracle.com> [Trond.Myklebust@netapp.com: Fixed a bug whereby nfs4_init_client() was being called with incorrect arguments.] Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/client.c11
-rw-r--r--fs/nfs/super.c12
2 files changed, 18 insertions, 5 deletions
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index 27190337fc13..3a69cacc4fa4 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -627,7 +627,8 @@ static int nfs_init_client(struct nfs_client *clp,
627 * Create a client RPC handle for doing FSSTAT with UNIX auth only 627 * Create a client RPC handle for doing FSSTAT with UNIX auth only
628 * - RFC 2623, sec 2.3.2 628 * - RFC 2623, sec 2.3.2
629 */ 629 */
630 error = nfs_create_rpc_client(clp, timeparms, RPC_AUTH_UNIX, 0, 0); 630 error = nfs_create_rpc_client(clp, timeparms, RPC_AUTH_UNIX,
631 0, data->flags & NFS_MOUNT_NORESVPORT);
631 if (error < 0) 632 if (error < 0)
632 goto error; 633 goto error;
633 nfs_mark_client_ready(clp, NFS_CS_READY); 634 nfs_mark_client_ready(clp, NFS_CS_READY);
@@ -969,7 +970,8 @@ error:
969static int nfs4_init_client(struct nfs_client *clp, 970static int nfs4_init_client(struct nfs_client *clp,
970 const struct rpc_timeout *timeparms, 971 const struct rpc_timeout *timeparms,
971 const char *ip_addr, 972 const char *ip_addr,
972 rpc_authflavor_t authflavour) 973 rpc_authflavor_t authflavour,
974 int flags)
973{ 975{
974 int error; 976 int error;
975 977
@@ -983,7 +985,7 @@ static int nfs4_init_client(struct nfs_client *clp,
983 clp->rpc_ops = &nfs_v4_clientops; 985 clp->rpc_ops = &nfs_v4_clientops;
984 986
985 error = nfs_create_rpc_client(clp, timeparms, authflavour, 987 error = nfs_create_rpc_client(clp, timeparms, authflavour,
986 1, 0); 988 1, flags & NFS_MOUNT_NORESVPORT);
987 if (error < 0) 989 if (error < 0)
988 goto error; 990 goto error;
989 memcpy(clp->cl_ipaddr, ip_addr, sizeof(clp->cl_ipaddr)); 991 memcpy(clp->cl_ipaddr, ip_addr, sizeof(clp->cl_ipaddr));
@@ -1034,7 +1036,8 @@ static int nfs4_set_client(struct nfs_server *server,
1034 error = PTR_ERR(clp); 1036 error = PTR_ERR(clp);
1035 goto error; 1037 goto error;
1036 } 1038 }
1037 error = nfs4_init_client(clp, timeparms, ip_addr, authflavour); 1039 error = nfs4_init_client(clp, timeparms, ip_addr, authflavour,
1040 server->flags);
1038 if (error < 0) 1041 if (error < 0)
1039 goto error_put; 1042 goto error_put;
1040 1043
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 2b0c8e132b54..e05a77be3068 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -75,6 +75,7 @@ enum {
75 Opt_acl, Opt_noacl, 75 Opt_acl, Opt_noacl,
76 Opt_rdirplus, Opt_nordirplus, 76 Opt_rdirplus, Opt_nordirplus,
77 Opt_sharecache, Opt_nosharecache, 77 Opt_sharecache, Opt_nosharecache,
78 Opt_resvport, Opt_noresvport,
78 79
79 /* Mount options that take integer arguments */ 80 /* Mount options that take integer arguments */
80 Opt_port, 81 Opt_port,
@@ -129,6 +130,8 @@ static const match_table_t nfs_mount_option_tokens = {
129 { Opt_nordirplus, "nordirplus" }, 130 { Opt_nordirplus, "nordirplus" },
130 { Opt_sharecache, "sharecache" }, 131 { Opt_sharecache, "sharecache" },
131 { Opt_nosharecache, "nosharecache" }, 132 { Opt_nosharecache, "nosharecache" },
133 { Opt_resvport, "resvport" },
134 { Opt_noresvport, "noresvport" },
132 135
133 { Opt_port, "port=%u" }, 136 { Opt_port, "port=%u" },
134 { Opt_rsize, "rsize=%u" }, 137 { Opt_rsize, "rsize=%u" },
@@ -514,7 +517,8 @@ static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss,
514 { NFS_MOUNT_NONLM, ",nolock", "" }, 517 { NFS_MOUNT_NONLM, ",nolock", "" },
515 { NFS_MOUNT_NOACL, ",noacl", "" }, 518 { NFS_MOUNT_NOACL, ",noacl", "" },
516 { NFS_MOUNT_NORDIRPLUS, ",nordirplus", "" }, 519 { NFS_MOUNT_NORDIRPLUS, ",nordirplus", "" },
517 { NFS_MOUNT_UNSHARED, ",nosharecache", ""}, 520 { NFS_MOUNT_UNSHARED, ",nosharecache", "" },
521 { NFS_MOUNT_NORESVPORT, ",noresvport", "" },
518 { 0, NULL, NULL } 522 { 0, NULL, NULL }
519 }; 523 };
520 const struct proc_nfs_info *nfs_infop; 524 const struct proc_nfs_info *nfs_infop;
@@ -1035,6 +1039,12 @@ static int nfs_parse_mount_options(char *raw,
1035 case Opt_nosharecache: 1039 case Opt_nosharecache:
1036 mnt->flags |= NFS_MOUNT_UNSHARED; 1040 mnt->flags |= NFS_MOUNT_UNSHARED;
1037 break; 1041 break;
1042 case Opt_resvport:
1043 mnt->flags &= ~NFS_MOUNT_NORESVPORT;
1044 break;
1045 case Opt_noresvport:
1046 mnt->flags |= NFS_MOUNT_NORESVPORT;
1047 break;
1038 1048
1039 /* 1049 /*
1040 * options that take numeric values 1050 * options that take numeric values