Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"NullConfigurator" Implementation #63

Closed
jdkasten opened this issue Nov 23, 2014 · 22 comments
Closed

"NullConfigurator" Implementation #63

jdkasten opened this issue Nov 23, 2014 · 22 comments

Comments

@jdkasten
Copy link
Contributor

This has been a highly requested feature. We would like to allow all servers to receive a trusted certificate even if the project doesn't fully support their system with proper configuration.

This would involve creating a new "NullConfigurator" class (I am not tied to the name, you may call it what you like :) ). This class would essentially only perform challenges for a given domain name and output the certificate, key, and chain file at the end. (in the current working directory)

In order to perform the challenges you will have use a crypto library or spin up a lightweight server to help you perform the challenges. The challenges are at the bottom of the document here - https://github.com/letsencrypt/acme-spec/blob/master/draft-barnes-acme.txt

It would be the admins job to install the certificate, but this would enable all webserver to attain a certificate, no matter what system they are running.

(If you only want to contribute by supporting one of the challenges to begin with.. it would still be a major help.)

@kuba
Copy link
Contributor

kuba commented Nov 23, 2014

Would that mean we could drop root privileges?

@jdkasten
Copy link
Contributor Author

@kuba I like the thought process! Unfortunately, we still have to prove authoritative control to the CA. This involves listening/controlling arbitrary data on port 443 (the port that generally serves HTTPS) which requires root permissions.

I imagine it would work something like this.
instantiate NullConfigurator()
... go through the normal client process of creating a key and requesting authorization over the domain to the webserver.
NullConfigurator.perform({"type":"dvsni", ...} ) is finally called.
NullConfigurator checks to see if any other process is attached to 443. If so, prompt the user to temporarily stop process... or give a list of known webservers that NullConfigurator knows how to stop/restart
Attach to port 443 and perform the challenges.
Kill off the process used to perform the challenges
If the user did already have a webserver on 443 - prompt the user to reenable their webserver or do it automatically.

Instead of installing the cert, deploy_cert() might just move it into their current working directory.

@PAStheLoD
Copy link

Why not just prompt the admin to make letsencrypt reachable via 443 on an arbitrarily chosen path? (So any traffic on 443 can just go on its merry way, and adding and removing a / can be done with reloads (both nginx, apache, and I guess for other servers too).)

@schoen
Copy link
Contributor

schoen commented Nov 24, 2014

Hi @kuba, @PAStheLoD,

Some existing CAs allow people to verify control over a name by some mechanisms that require less privilege, but the protocol that we're working with is trying to require proof that the party requesting the cert actually has the ability to reconfigure the TLS listener there. The default validation mode is described at

https://github.com/letsencrypt/acme-spec/blob/master/draft-barnes-acme.md#domain-validation-with-server-name-indication

and proving administrative control over the server is actually a design goal.

I'm hoping to start working on this soon and make a simple TLS listener that serves the specified synthetic DVSNI cert and then disconnects.

@PAStheLoD
Copy link

Thanks for the link and the explanation.

So if someone just wants the key and cert files without disrupting a preexisting service, then their best bet is redirecting the traffic from the CA to a VM/container (with let's say iptables). Which is not terribly difficult and an acceptable trade-off.

@kuba
Copy link
Contributor

kuba commented Nov 25, 2014

Thanks for the info, @schoen, @jdkasten.

@PAStheLoD NullConfigurator is meant to free you from having to set up this kind of redirection or dependence on Apache, etc.

@dnozay
Copy link
Contributor

dnozay commented Nov 27, 2014

@jdkasten, is knowing the host ssh key enough to prove control over the server? This would help in scenarios where hosts are configured by something like puppet and people may want to generate certs ahead of time.

@jdkasten
Copy link
Contributor Author

@dnozay Our goal is to offer strictly stronger challenges than the status quo. I tried to answer your questions at #83. I am not overly familiar with puppet, but if you can arbitrarily reconfigure and restart a webserver, you can obtain a certificate. The correct place for this discussion, (which I see you have already posted) is on the ACME Spec.

@mirabilos
Copy link

This is not sufficient, I will not permit any software to run as root, or on port 443, on my webserver, even temporarily, especially as your software will likely not run on MirBSD anyway.

Please support a fully manual mode.

@PAStheLoD
Copy link

Just use a container/jail/VM. That's manual enough; but for the "Uh, I know UNIX" juniors who will gladly run anything they can copy-paste into a terminal that starts with curl ... and ends with | bash it's better than no-certs, hm?

@mirabilos
Copy link

“Just use” is no option (especially not on my production server – Pentium 233-MMX, 128 MiB RAM).

If only those “curl | sudo bash”-idiots are your target group, please state so clearly on the front and about page. Thanks.

@schoen
Copy link
Contributor

schoen commented Dec 12, 2014

Hi @mirabilos,

You're welcome to help port the client to MirBSD!

There is no requirement to use our software in particular, and the protocol is openly published and may be standardized at IETF. You can also develop your own client software, which we also encourage. However, proving root-equivalent control of a server is likely to be a security requirement of the Let's Encrypt CA in order to prevent misissuance of certs. In particular, we don't think that an unprivileged user of a shared host should be able to cause issuance of certs for DNS names that resolve to that host.

We are definitely not expecting or encouraging people to run either an unauthenticated or an unreviewable copy of our software. Our hope is that most users will get the software in an official package from their operating system distributor, and we would encourage people to help us port it as widely as possible, or to write their own equivalent interoperable software.

@mirabilos
Copy link

schoen dixit:

However, proving root-equivalent control of a server is likely to be a
security requirement of the Let's Encrypt CA in order to prevent
misissuance of certs. In particular, we don't think that an

Yes, but that’s the reason I, as others, am asking for a manual mode.
I can do everything to httpd.conf that your client could also do.
The webserver could just instruct me what changes it wants.

unprivileged user of a shared host should be able to cause issuance of
certs for DNS names that resolve to that host.

Indeed, which would the manual mode also prevent, as long as the
things that are requested require root.

bye,

//mirabilos

exceptions: a truly awful implementation of quite a nice idea.
just about the worst way you could do something like that, afaic.
it's like anti-design. that too… may I quote you on that?
sure, tho i doubt anyone will listen ;)

@schoen
Copy link
Contributor

schoen commented Dec 12, 2014

Oh, I'm sorry, I misunderstood what you meant there.

I think a mode that tells the user what changes to make to the browser configuration is possible but won't be a high development priority for us in comparison to supporting more servers, because so far we expect almost all users will be willing to run some client as root in order to obtain a cert. We would be happy to accept a patch to add this mode in the meantime, though.

Another possibility for people who don't want to run our software as root is to find a way to bind a privileged TCP port and pass the bound socket to an unprivileged process (which I think there are standard tools and techniques to do). In that case the standalone client would be able to run as a normal user (or as "nobody") when given a file descriptor attached to a socket bound to TCP port 443. This is somewhat less development effort and I'd be happy to look into this mechanism in the near future if people are interested in it. Then the client would be able to accept privileged TCP connections to show that someone with root-equivalent access invoked the client, but the client wouldn't be able to modify any files or directories on the system.

For example, there seem to be tools like "privbind" and "bind_port" to help people do this, and I think some versions of the traditional inetd daemon can also be configured this way.

@schoen
Copy link
Contributor

schoen commented Dec 12, 2014

Here's a whole list of tools that support this approach:

http://earthwithsun.com/questions/710253/allow-non-root-process-to-bind-to-port-80-and-443

I think it would be quite feasible to make the standalone configurator work in conjunction with some of these tools.

@mirabilos
Copy link

schoen dixit:

Another possibility for people who don't want to run our software as
root is to find a way to bind a privileged TCP port and pass the bound
socket to an unprivileged process (which I think there are standard
[…]
For example, there seem to be tools like "privbind" and "bind_port" to
help people do this, and I think some versions of the traditional
inetd daemon can also be configured this way.

But this is totally counter-productive as it would require the admin
to stop httpd for that (and for longer than the quick restart for a
manual config change takes).

bye,

//mirabilos

"Using Lynx is like wearing a really good pair of shades: cuts out
the glare and harmful UV (ultra-vanity), and you feel so-o-o COOL."
-- Henry Nelson, March 1999

@ThomasWaldmann
Copy link
Contributor

what's the current state of this? @schoen ?

@schoen
Copy link
Contributor

schoen commented Jan 31, 2015

Hi folks, I have just made an initial commit on the "standalone_authenticator" branch. We tested this today and succeeded in getting cert issuance from the demo server (although please note that there is not yet any UI path to invoke this configurator -- we temporarily modified main.py to call into this instead of the Apache configurator).

This implementation creates a subprocess which then listens on CONFIG.PORT (default 443) and performs specified DVSNI challenges there. My preference (which I'll write up in a longer document) is to use pure-Python implementations of a small number of TLS protocol handshake messages (instead of a complete TLS implementation), but for backwards compatibility with existing verifiers, which use ordinary TLS implementations, I have also written code to use PyOpenSSL (which will be a new dependency for this branch). The reason for selecting PyOpenSSL is that it has support for SNI on the server side, which we need for a complete DVSNI implementation.

@schoen
Copy link
Contributor

schoen commented Jan 31, 2015

@jdkasten is working on the UI aspect, probably initially providing the user with a menu of available configurators, and we'll also look at the name under which the Let's Encrypt client was run (e.g. lets-encrypt-standalone, lets-encrypt-apache, lets-encrypt-nginx...) to decide which configurator to use.

@kuba
Copy link
Contributor

kuba commented Jan 31, 2015

re PyOpenSSL: #164

@schoen
Copy link
Contributor

schoen commented Feb 6, 2015

I submitted PR #232 to merge the standalone authenticator.

@schoen
Copy link
Contributor

schoen commented Feb 11, 2015

This is now implemented via the merge of #232. Soon we will also have a user interface available to invoke it. :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants