Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 16 Mar 2022 21:08:03 -0400
From:      mike tancsa <mike@sentex.net>
To:        Rick Macklem <rmacklem@uoguelph.ca>, FreeBSD Questions <freebsd-questions@freebsd.org>
Subject:   Re: nfsv4 export and foot shooting
Message-ID:  <08bc0654-23e4-02a9-40cf-ac6bc8128687@sentex.net>
In-Reply-To: <YT2PR01MB9730F16FBF11ADD26D7533A9DD119@YT2PR01MB9730.CANPRD01.PROD.OUTLOOK.COM>
References:  <f118ab28-f829-649d-9f0f-cfe6eb80294e@sentex.net> <4252a479-3caf-df88-2c8a-c5dc88616bd5@sentex.net> <YT2PR01MB9730F16FBF11ADD26D7533A9DD119@YT2PR01MB9730.CANPRD01.PROD.OUTLOOK.COM>

next in thread | previous in thread | raw e-mail | index | archive | help
response below

On 3/16/2022 4:38 PM, Rick Macklem wrote:
> mike tancsa <mike@sentex.net> wrote:
>> OK, I *think* I see what might be going on and not sure if more
>> documentation is needed in the man page to flag this or this is very
>> much the way its supposed to work.
>>
>> My UFS server in the example below, has just one file system mounted. So
>> in this case,
>> /dev/gpt/rootfs   /       ufs rw      1       1
>>
>> On another server, which is ZFS based, I can have an exports file that
>> is "safe" as so
>> V4: /
>> /nano-images   -network 192.168.0.0/24
>> /usr/src   -ro -network 192.168.0.0/24
>>
>>
>> This is safe as each of those export lines are mount points on their own
> "safe" is a relative term. If all your exports line(s) refer to server mount points
> and not subdirectories within a server mount point, then things are
> "less confusing".
>
>> So if I have an exports file consisting of
>>
>> V4: /
> This actually (by necessity) allows some access to "/", but nothing
> that can modify the file system (just enough so that an NFSv4 client
> can traverse "/" to find the file systems that are exported.
>
>> /nano-images   -network 192.168.0.0/24
>> /usr/src   -ro -network 192.168.0.0/24
>>
>> things work as expected from a client POV.  The client in 192.168.0.0/24
>> can mount /usr src and nano-images, but NOT mount / and see data.
>> but if I add
> Kinda true. A malicious client can lookup file names in "/", but cannot
> do Readdir or Read.
>
> If the V4: line were
> V4: /usr/src ...
> then "/" would not be accessible in any way. But then /nano-images
> would not be accessible.
>
> Ideally, an NFSv4 server is configured with a directory where the only
> things under it are mounted file systems to be exported. Then that
> directory is specified as the root for V4.
> For your example, you might create a directory called "/export and then
> mount the file systems under it as:
> /export/usr/src
> /export/nano-images
>
> and use an exports file of:
> /export/nano-images   -network 192.168.0.0/24
> /export/usr/src   -ro -network 192.168.0.0/24
> V4: /export
>
>> /usr/obj -ro   -network 192.168.0.0/24
>> which is just a subdirectory of /, a client in /usr/obj is able to mount
>> / with nfsv4
> Yes. The exports hang off of the mount point structures in the kernel,
> so a directory refers to the file system that directory is in.
>
> The only place the actual directory gets checked is in mountd, for the
> NFSv3 MNT RPC.
> --> All a malicious client needs to do is "guess" the file handle of a
>        root directory (hint, it's i-node #2) and it can do a NFSv3 mount
>        without doing a MNT RPC.
>
> The man page refers to these checks as "administrative controls"
> (A term I think was inverted by Robert Watson). I, personally,
> wish they had never existed, since they aren't really enforced,
> but Sun did it that way in 1985 and BSD (CSRG in those days)
> wanted it to be compatible.
> --> Since NFSv4 does not use the MNT protocol, these
>         "administrative controls" do not apply to NFSv4.
>
>> My guess its supposed to work this way, but is there a way to prevent it
>> from working that way ?
> As above "yes" and "no".
>
> Conceivably, you could do a re-engineering of file system mounting in
> the kernel to allow "submounts" that refer to a subtree of a server's file
> system and hang exports information off those.
> --> There would still be weird situations, like hard links to the file
>        from outside the subtree for the submount...
> Not something I have any interest in trying to do.
>
> You are welcome to suggest patches to exports.5. Others have tried
> to clarify the above, but it is just plain confusing.
> --> Maybe it should state "if you are going to be using NFSv4, only
>        export server file system mount points (although enforcing that
>        would be a POLA violation).
>
> rick
>
Thank you very much for the detailed response Rick!  Its quite helpful.  
With Andrea's suggestion, I added a nullfs mount on my server to move 
the directories into a "safer" location

0{build13}% cat /etc/fstab
# Custom /etc/fstab for FreeBSD VM images
/dev/gpt/rootfs   /       ufs     rw      1       1
/dev/gpt/swapfs  none    swap    sw      0       0
/dev/gpt/efiesp /boot/efi       msdosfs     rw      2       2
/usr/obj    /nfs/usr/obj    nullfs    ro    0    0
/usr/src    /nfs/usr/src    nullfs    ro    0    0
0{build13}%

and for exports, added

% cat /etc/exports
V4: /nfs
/usr/src /usr/obj  -maproot=root -ro -network 192.168.0.0/16,10.0.0.0/8

so on the client, I can do

mount_nfs -onfsv4 buildserver:/usr/src /usr/src

mount_nfs -onfsv4 buildserver:/usr/obj /usr/obj

and if I do

  mount_nfs -onfsv4 buildserver:/ /mnt

just shows

ls -l /mnt/usr/
total 16
drwxr-xr-x   4 root  wheel  -  512 Mar 16 15:43 .
drwxr-xr-x   3 root  wheel  -  512 Mar 16 15:43 ..
drwxrwxr-x   3 root  wheel  -  512 Mar 16 05:56 obj
drwxr-xr-x  28 root  wheel  - 1024 Mar 15 15:52 src

what I expect.


I wonder if adding a new paragraph after the one that has the sentence 
"The third form has the
      string ``V4:'' followed by a single absolute path name, to specify the
      NFSv4 tree root.  This line does not export any file system, but 
simply
      marks where the root of the server's directory tree is for NFSv4 
clients."

I think the consequences of this are not entirely obvious as someone not 
overly familiar with nfs and especially someone used to v3.  The 
sentence "The line does not export any file system" I think further can 
be miss interpreted meaning that subsequent export lines limit the 
exports to the stated directories, which they dont.

Perhaps in a new paragraph

Note with NFSV4. The client can mount a path above the stated directory 
based on choice of the root if that subdirectory is part of the same 
file system. Given a server with a single ufs file system of / and an 
exports file of that has say /usr/home exported, a client that can mount 
/usr/home,  could also mount / on the server. While the exports file
V4:/
/usr/home -maproot=root -network 10.0.0.0/8

might be read as /usr/home being exported, it in fact means / can be 
mounted by 10.0.0.0/8


     ---Mike




>       ---Mike
>
>
>
>
>
>
> On 3/16/2022 10:37 AM, mike tancsa wrote:
>> I am trying to get my head around the nfsv4 way of thinking about the
>> exports format and cant quite see how the best way to do it is.  I
>> have a build server where I build world and packages daily. Ideally,
>> on a client machine, I would like to mount /usr/src and /usr/obj
>> read-only so I can install world from there.
>>
>> For nfsv4, the export line says I need to specify the root directory
>> first. But I dont want to export all of /
>>
>> Is there no way to just export /usr/src and /usr/obj and nothing above
>> it ?
>>
>> It seems if I just have
>>
>> V4:/
>> /usr/src /usr/obj -ro -network 192.168.0.0/16
>>
>> 192.168.0.0/16 is able to mount / from the server which is not what I
>> want
>>
>> If I put V4:/usr it will work, but then 192.168.0.0/16 can still
>> access /usr/bin etc on the server.
>>
>> having an export file with JUST
>>
>> V4: /
>>
>> sort of makes sense in that no one can mount anything
>>
>> but progressing to
>>
>> V4:/
>> /usr/src /usr/obj -ro -network 192.168.0.0/16
>>
>> means that 192.168.0.0/16 can mount /usr/src and /usr/obj, but also /
>> which seems counter intuitive.
>>
>> The server's rc.conf is just
>>
>>
>> nfsv4_server_enable="YES"       # Enable support for NFSv4
>> nfsv4_server_only="YES"
>> nfs_server_enable="YES"
>>
>> This is 13.1-STABLE. The server is UFS
>
>
>



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?08bc0654-23e4-02a9-40cf-ac6bc8128687>