Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 20 Mar 2020 12:29:23 -0700
From:      John-Mark Gurney <jmg@funkthat.com>
To:        Rick Macklem <rmacklem@uoguelph.ca>
Cc:        "freebsd-current@FreeBSD.org" <freebsd-current@FreeBSD.org>
Subject:   Re: TLS certificates for NFS-over-TLS floating client
Message-ID:  <20200320192923.GK4213@funkthat.com>
In-Reply-To: <YTBPR01MB337407CFCBE26DBAB1BC985ADDF40@YTBPR01MB3374.CANPRD01.PROD.OUTLOOK.COM>
References:  <YTBPR01MB3374EFF14948CB8FEA1B5CCDDDE50@YTBPR01MB3374.CANPRD01.PROD.OUTLOOK.COM> <20200319191605.GJ4213@funkthat.com> <YTBPR01MB337407CFCBE26DBAB1BC985ADDF40@YTBPR01MB3374.CANPRD01.PROD.OUTLOOK.COM>

next in thread | previous in thread | raw e-mail | index | archive | help
Rick Macklem wrote this message on Thu, Mar 19, 2020 at 23:41 +0000:
> John-Mark Gurney wrote:
> >Rick Macklem wrote this message on Wed, Mar 04, 2020 at 03:15 +0000:
> >> I am slowly trying to understand TLS certificates and am trying to figure
> >> out how to do the following:
> >> -> For an /etc/exports file with...
> >> /home -tls -network 192.168.1.0 -mask 255.255.255.0
> >> /home -tlscert
> >
> >Are you looking at implementing draft-cel-nfsv4-rpc-tls?
> Yes. The 2 week out of date (I can only do commits once in a while these days) can
> be found in FreeBSD's subversion under base/projects/nfs-over-tls.

Nifty.

And looks like you know about the ktls stuff, nice...

> >> This syntax isn't implemented yet, but the thinking is that clients on the
> >> 192.168.1 subnet would use TLS, but would not require a certificate.
> >> For access from anywhere else, the client(s) would be required to have a
> >> certificate.
> >>
> >> A typical client mounting from outside of the subnet might be my laptop,
> >> which is using wifi and has no fixed IP/DNS name.
> >> --> How do you create a certificate that the laptop can use, which the NFS
> >>        server can trust enough to allow the mount?
> >> My thinking is that a "secret" value can be put in the certificate that the NFS
> >> server can check for.
> >> The simplest way would be a fairly long list of random characters in the
> >> organizationName and/or organizationUnitName field(s) of the subject name.
> >> Alternately, it could be a newly defined extension for X509v3, I think?
> >>
> >> Now, I'm not sure, but I don't think this certificate can be created via
> >> a trust authority such that it would "verify". However, the server can
> >> look for the "secret" in the certificate and allow the mount based on that.
> >>
> >> Does this sound reasonable?
> >
> >Without a problem statement or what you're trying to accomplish, it's
> >hard to say if it is.
> The problem I was/am trying to solve was a way for NFS clients without a
> fixed IP/DNS name could have a certificate to allow access to the NFS server.
> As suggested by others, having a site local CA created by the NFS admin. seemed

Yes, I totally agree w/ this as the best solution.  It also allows
private hostnames to be used w/o leaking outside the org..

It'd be nice to have better tooling around the CA though.  I still
haven't found any good tools that make a CA simple to use for small
installs...  (and by simple, I mean single init command, and single
command to issue a cert or generate a key/cert pair, all of them are
like, make all thesse directories, edit these files, and run these
comlicated commands)

Another option is to just use self sign certs and manually add each
one for a host, not sure how difficult this would be in code...  This
would probably be easiest w/ a small number of clients, eliminates the
difficulty of doing a CRL/OSCP, as if a client gets compromised, you
just delete their cert till a new one is issued...

> to be the best solution. The server can verify that the certificate was issued by
> the local CA. Unfortunately, if the client is compromised and the certificate is copied
> to another client, that client would gain access.

This is why CRLs/OSCP is necessary, but there isn't anything you can do
to prevent that.  This is both a better situation than what we have
today (no auth/confidentiality), and if you tie the cert to an IP, it's
of limited use, and better than today...

> --> I've thought of having the client keep the certificate encrypted in a file and
>        require the "user" of the client type in a passphrase to unencrypt the certificate
>        so that it can be used by the daemon in the client that handles the client side
>        of the TLS handshake, but I have not implemented this.
>        --> This would at least subvert the simple case of the certificate file being copied
>               to a different client and being used to mount the NFS server, but if the
>               client is compromised, then the passphrase could be captured and...

Exactly.  Just make sure that it's clear how to handle a revoked
certificate when this happens, and you're good...

> >> Also, even if the NFS client/server have fixed IP addresses with well known
> >> DNS names, it isn't obvious to me how signed certificates can be acquired
> >> for them?
> >> (Lets Encrypt expects the Acme protocol to work and that seems to be
> >>  web site/http specific?)
> >
> >There is DNS challenges that can be used.  I use them to obtain certs
> >for SMTP and SIP servers...  using nsupdate, this is relatively easy to
> >automate pushing the challenges to a DNS server, and I now use DNS
> >challenges for everything, including https.
> Since my internet connection is a single dynamically assigned IP from the phone
> company, I doubt this would work for me (which I why I say I don't know how
> to do this). I suspect there are ways and it would be nice if you could document
> this, so I can put it in a howto document.
> - An actual example using the nsupdate command would be nice.
> Thanks, rick

This partly depends upon how you host your DNS for your domain.  Many
DNS providers allow dynamic update, though not everyone uses the standard
TSIG nsupdate method.  If they do, you can deploy updates via:
    (echo add "_acme-challenge.${DOMAIN}" 100 TXT "${TOKEN_VALUE}"; echo send) | nsupdate -v -l -k "${keyfile}"

and remove them via:
    (echo del "_acme-challenge.${DOMAIN}" 100 TXT "${TOKEN_VALUE}"; echo send) | nsupdate -v -l -k "${keyfile}"

The above lines are the ones that I use in my hook.sh that I use w/
dehydrate.

There might be a few additional options to nsupdate required, but I use
this method to provide priv sep for my updates, so that the the acme
client can run entirely as it's own user w/o sudo privs or anythingelse.

As I run my own DNS via bind, I wanted to limit what records that key
could update, so I also had to add the following to my master zone entry:
                update-policy {
                        grant acme.key. name _acme-challenge.example.com TXT;
                        grant acme.key. name _acme-challenge.www.example.com TXT;
                        grant acme.key. name _acme-challenge.sip.example.com TXT;
                };

Even with a dynamic IP, you could run a "hidden master" locally, and use
TSIG to push updates to your provider for public view.

> > Thanks for any help with this, rick

-- 
  John-Mark Gurney				Voice: +1 415 225 5579

     "All that I will do, has been done, All that I have, has not."



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