Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 28 Mar 2020 16:10:49 +0000
From:      Rick Macklem <rmacklem@uoguelph.ca>
To:        John-Mark Gurney <jmg@funkthat.com>
Cc:        Alexander Leidinger <Alexander@leidinger.net>, "freebsd-current@FreeBSD.org" <freebsd-current@FreeBSD.org>
Subject:   Re: TLS certificates for NFS-over-TLS floating client
Message-ID:  <QB1PR01MB36492D4F29B339AB3E205FF3DDCD0@QB1PR01MB3649.CANPRD01.PROD.OUTLOOK.COM>
In-Reply-To: <20200328065331.GU4213@funkthat.com>
References:  <QB1PR01MB3649ADE4950B2A35CBD57BEBDDCF0@QB1PR01MB3649.CANPRD01.PROD.OUTLOOK.COM> <QB1PR01MB3649F248F7D4C5B21630963FDDCF0@QB1PR01MB3649.CANPRD01.PROD.OUTLOOK.COM>, <20200328065331.GU4213@funkthat.com>

next in thread | previous in thread | raw e-mail | index | archive | help
John-Mark Gurney wrote:=0A=
>Rick Macklem wrote this message on Thu, Mar 26, 2020 at 14:33 +0000:=0A=
>> John-Mark Gurney wrote:=0A=
>> [lots of stuff snipped]=0A=
>> >Rick Macklem wrote:=0A=
>> >> I had originally planned on some "secret" in the certificate (like a =
CN name=0A=
>> >> that satisfies some regular expression or ???) but others convinced m=
e that=0A=
>> >> that wouldn't provide anything beyond knowing that the certificate wa=
s=0A=
>> >> signed by the appropriate CA, so I have not implemented anything.=0A=
>> >=0A=
>> >Yeah, having a "secret" in the CN doesn't make sense, but what does mak=
e=0A=
>> >sense is allowing the exports line to specify what the CN should contai=
n=0A=
>> >to be authenticated...=0A=
>> >=0A=
>> >Say as a corp, you issue personal certificates to everyone.  This is=0A=
>> >because you require everyone to sign and/or encrypt their email w/=0A=
>> >S/MIME.  Each cert includes the email address of that person, so you=0A=
>> >could simply do something like:=0A=
>> >/home/alice -tlscert -tlsroot /etc/company.pem -email alice@example.com=
=0A=
>> >=0A=
>> >And anyone who has the certificate w/ alice@example.com that was signed=
=0A=
>> >by the public key in /etc/company.pem would be granted access to the=0A=
>> >export /home/alice.=0A=
>> >=0A=
>> >If it allowed ANY cert signed by the CA specified, then that introduces=
=0A=
>> >an authentication problem, as now if Malory is a coworker of Alice=0A=
>> >could also access Alice's home directory...=0A=
>> >=0A=
>> >IMO, this is one auth feature that MUST be supported...=0A=
Here's what I have just coded up:=0A=
- If an option is set for the server TLS handshake daemon and it gets a ver=
ified=0A=
  certificate from the client=0A=
  - It looks at the CN and if it is of the form "user@domain", it tries to =
translate=0A=
    "user@domain" to a POSIX <uid,gid_list> using the same mechanism that=
=0A=
    nfsuserd(8) currently uses. ("user@domain" is what NFSv4 uses for a fil=
e Owner.)=0A=
    - Then all RPCs on this TCP connection are done using the <uid,gid_list=
> above,=0A=
       ignoring the authenticator in the RPC message header. (Yes, similar =
to the=0A=
       -mapall exports option.)=0A=
I have also added a "-tlscnuser" exports option that would require all clie=
nts=0A=
to have the above form of certificate. (Without this exports option, the ab=
ove=0A=
would work assuming the daemon option is set, but other mounts would be=0A=
allowed as well.)=0A=
=0A=
The problem of handling multiple "user" domains has never been solved.=0A=
(That is what your -tlsroot option was intended to do assuming a 1 to 1=0A=
 relationship between CA root and username domains, I think?)=0A=
The problem is that getpwnam(3) needs to know how to look up user names=0A=
for these different "domain" values. (Now, both nfsused(8) and this daemon=
=0A=
only strips off the default domain, if it matches, and then hands the rest =
of=0A=
the string to getpwnam(2).)=0A=
=0A=
Although "user@domain" isn't exactly an email address, they often are the=
=0A=
same string in practice.=0A=
=0A=
I have not yet posted to nfsv4@ietf.org to see what they think.=0A=
However, I don't think there is any changes in the draft required to do thi=
s.=0A=
Also, I think interoperability should be ok, since it is controlled by whoe=
ver=0A=
issues the certificate for the client and the NFS client will normally just=
=0A=
handle this certificate opaquely.=0A=
=0A=
Btw, the server TLS handshake daemon does do a SSL_CTX_set_client_CA_list()=
,=0A=
so it tells the client which CA (usually only one) that it wants a certific=
ate for.=0A=
=0A=
>> The draft does not address user authentication, only machine authenticat=
ion.=0A=
>> --> ie. The certificate is used to decide if a system can do a mount.=0A=
>>       Users are still identified via user credentials in the RPC message=
 header.=0A=
>>       For AUTH_SYS, that still means <uid,gid,...>.=0A=
>>       Otherwise, you need to use Kerberos (sec=3Dkrb5[ip]).=0A=
>>       You could use "tls,sec=3Dkrb5" for a mount, but the only advantage=
 that=0A=
>>       might have over "sec=3Dkrb5p" is performance, if there is hardware=
 assist=0A=
>>       for TLS or something like that.=0A=
>>=0A=
>> >Now that I reread your comments, it sounds like any certificate would b=
e=0A=
>> >allowed in #2 as long as it is valid, and that would only be marginally=
=0A=
>> >better than verification by IP, and in some ways worse, in that now any=
=0A=
>> >user could pretend to be any other user, or you have to do something=0A=
>> >crazy like have a CA per user.=0A=
>> The case where I see #2 is useful is where this discussion started some =
weeks ago.=0A=
>> The example I started with was:=0A=
>> /home -tls -network 192.168.1.0 -mask 255.255.255.0=0A=
>> /home -tlscert=0A=
>>=0A=
>> This says that machines on the local lan can mount and do not need to ha=
ve=0A=
>> certificates, but must use TLS so data is encrypted on the wire.=0A=
>> Mounts from anywhere else (presumably laptops) are allowed so long as th=
ey have a=0A=
>> certificate signed by me (as in the site local CA).=0A=
>> I trust these machines enough that I am willing to allow them to use AUT=
H_SYS,=0A=
>> which is what 99.9...% of NFS mounts do now.=0A=
>> (So, I'd agree that the site local certificate is not a lot better than =
IP address=0A=
>>  for client machine identity, just that it is an alternative that can be=
 useful.=0A=
>>  Without TLS, a line like "/home" allows anyone to mount /home from anyw=
here=0A=
>>  and I think you'd agree that few NFS admins. will want to do that. I'm =
assuming=0A=
>>  no external firewall for this example.)=0A=
>>=0A=
>> Now, your suggestion of identifying a user via the CN and then having th=
e=0A=
>> server do all RPCs for the mount as that user is an interesting one.=0A=
>> My concern w.r.t. implementing it would be interoperability.=0A=
>> Put another way, if other servers such as Linux, Netapp,... don't adopt =
it=0A=
>> (and they won't until there is a draft/RFC specifying it), it would be=
=0A=
>> FreeBSD server specific and I'd like to avoid that.=0A=
>> There was some discussion w.r.t. user authentication via certificates=0A=
>> during development of the draft, but they decided to defer that work for=
=0A=
>> now, so they could get something in place for machine authentication fir=
st.=0A=
>> (If I understood the discussion on nfsv4@ietf.org.)=0A=
>=0A=
>There's a fine line between machine and user authentication when you can=
=0A=
>add -mapall=3Dsomeuser.  :)=0A=
Yes, I agree. You can argue what I've coded as explained above is just serv=
er=0A=
implementation and has nothing to do with the draft, which covers what goes=
=0A=
"on-the-wire", similar to "-mapall".=0A=
=0A=
>Yes, a certificate may be used to identify a machine, but if any machine=
=0A=
>can be identified by any cert as it appears that #2 is proposed to do, the=
n=0A=
>you're not actually identifying a machine, you're identifying group of=0A=
>machines...  Though per the draft, this is explicitly allowed.=0A=
>=0A=
>It'd be nice to be able to identify particular machines though, and be=0A=
>able to set the options based upon that..=0A=
Well, the only thing the server has to use for exports(5) is the client's I=
P address.=0A=
In a sense, you can say that "alice@example.com" identifies the machine tha=
t=0A=
Alice uses.=0A=
=0A=
At least, it means that if the certificate with "alice@example.com" in it i=
s copied=0A=
to a different machine, that machine will access the NFS server as "alice" =
as well=0A=
and cannot access files that Alice cannot access.=0A=
=0A=
>> >I'm wonder if your use of the term secret was the problem, and not the=
=0A=
>> >idea...  Anything that goes in the client cert is by definition public.=
..=0A=
>> >TLS prior to 1.3 sends the client cert in clear text...  But keying=0A=
>> >based upon the contents of the cert is fine, as that's the point of=0A=
>> >what a cert is..  It's trusting the CA to say that the CN and other=0A=
>> >fields in the cert corresponds to this user, and you can use parts of=
=0A=
>> >the cert, like the CN to decide which user the public key in the cert=
=0A=
>> >corresponds to.=0A=
>=0A=
>Rick Macklem wrote this message on Thu, Mar 26, 2020 at 14:59 +0000:=0A=
>> Sorry about the top post, but I thought of a few things to add to my=0A=
>> last post to this thread...=0A=
>> 1 - I agree that for systems like laptops, the line between machine and=
=0A=
>>      user authentication is fuzzy.=0A=
>=0A=
>yep, exactly.  IMO, laptops are more important for this work, and where=0A=
>you want to identify per machine at a finer grain level than server=0A=
>machines...=0A=
>=0A=
>> 2 - I do like your idea of having an exports(5) option that specifies a =
CN=0A=
>>       that identifies a user and then does all RPCs as that user.=0A=
>>       I'm not sure if an issuer needs to be specified (or even can be sp=
ecified),=0A=
>>       since the CAfile argument to the rpctlssd daemon determines if a c=
ertificate=0A=
>>       from a particular CA will verify and the verification must happen =
before the=0A=
>>       exports(5) export options can be applied. (Basically, certificate =
verification=0A=
>>       happens via a NULL RPC that does a STARTTLS when a TCP connection =
to=0A=
>>       the server is first established.)=0A=
>=0A=
>Yeah, this will need some work, but IMO is fine as a future=0A=
>improvement...=0A=
>=0A=
>Yeah, this could be a bit tricky from a code perspective.. I don't know=0A=
>how well most SSL libraries are being able to auth client certs via=0A=
>different roots after the fact...  One option, but maybe not a great=0A=
>option would be to verify the cert after the connection is established..=
=0A=
>=0A=
>You could extract the cert identify the candidate export lines, and=0A=
>then attempt a cert verification w/ a specified root if a default one=0A=
>isn't specified...  Not exactly clean, but as long as the client can't=0A=
>proceed without this check, shouldn't be a major problem...=0A=
Well, the certificate verification normally occurs during the handshake=0A=
using the location information provided via SSL_CTX_load_verify_locations()=
.=0A=
However, this does not included checking for specific fields in the certifi=
cate.=0A=
=0A=
The daemon could pass the subjectName from the certificate into the kernel=
=0A=
for use by the exports(5) handling code later, but then another upcall to a=
=0A=
daemon needs to be done to translate the subjectName to <uid,gid_list>.=0A=
Since even nfsuserd(8) only knows how to do this for a default domain,=0A=
that would be a lot more work and I don't think it gains anything at this=
=0A=
time.=0A=
getpwnam(3) needs to be done in userland and is a little bit scary to do,=
=0A=
since it could get hung on a broken LDAP server or similar.=0A=
If done by the TLS handshake daemon, that means new mounts hang, but=0A=
at least current mounts keep working.=0A=
=0A=
>> 3 - I'll post to nfsv4@ietf.org to see what others think of this, since =
it would not=0A=
>>       require any changes to the draft/RFC.=0A=
>> 4 - Although it does require a revision to the export_args structure, I =
think it is=0A=
>>      worth doing even if others don't implement it.=0A=
Oh, and implementing what is described above did not require the export_arg=
s structure to be revised.=0A=
=0A=
rick=0A=
=0A=
Thanks.  Let me know if you'd like code reviews as well...=0A=
=0A=
> Again, thanks for your comments, rick=0A=
=0A=
And thanks for doing the work!=0A=
=0A=
--=0A=
  John-Mark Gurney                              Voice: +1 415 225 5579=0A=
=0A=
     "All that I will do, has been done, All that I have, has not."=0A=



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?QB1PR01MB36492D4F29B339AB3E205FF3DDCD0>