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>