letsencrypt / acme-spec

ACME Specification
1.13k stars 112 forks source link

allow ports other than 443. #33

Closed dnozay closed 8 years ago

dnozay commented 9 years ago

see also issue #19.

practical examples:

dnozay commented 9 years ago

The argument brought forward was need to prove administrative control over a machine.

kuba commented 9 years ago

Port 8080 is available to any user of the system. Say you give me a shell account on your machine. Would you like me to be able to register certificates for your domains? Definitely not.

ACME protocol is HTTP-server (or app) agnostic, so I don't see any point in discussing uwsgi, Apache etc. here.

Therefore, I believe that this bug report does not bring any value and should be closed as duplicate of #19.

dnozay commented 9 years ago

@kuba, i am not going to give you a shell account nor am I going to disable selinux, nor am I also going to have iptables not running. You are making assumptions about who the set of users of the system can be.

kuba commented 9 years ago

On the other hand, you are making assumptions on what the system has: selinux (non-standard) or iptables (also non-standard, i.e. appropriate firewall rules). Also, mind that there is a lot of software that you run as non-root that might bite you if exploited; you don't have to give me shell access.

Port < 1024 is a fairly good assumption, though not perfect.

dnozay commented 9 years ago

dude, if I can't even make assumptions about my own systems...

kuba commented 9 years ago

The question is how do you communicate to ACME server that it is safe to validate something on non-privileged ports. Not everyone has the same super secure setup as you.

dnozay commented 9 years ago

conversely: you cannot build on the premise that root is using port 443; an attacker could be running an ACME client and already control port 443. Therefore port 443 is irrelevant to the equation.

If a sysadmin wants to use port 443, then it's the sysadmin job to help secure that port. If a sysadmin wants to use port N, then it's the sysadmin job to secure port N.

e.g.

# good luck bob.
sudo sysctl -w net.ipv4.ip_local_port_range="65000 65000"
ravisorg commented 9 years ago

@dnozay You might want to take a moment and meditate on exactly what you're asking here, it's really not a good idea.

kuba commented 9 years ago

@dnozay Okay, while you're meditating, here is a little scenario for you to play with. Imagine you are an ACME server and you get a request to provide a certificate for example.com. What do you do? You can assume that none of the ports is assumed to be controlled by root.

dnozay commented 9 years ago

@dnozay You might want to take a moment and meditate on exactly what you're asking here, it's really not a good idea.

@kuba, @ravisorg, please keep it courteous. If you want to hurt people's feelings by calling them ignorant (my interpretation) on social media, at least back it up with some facts. I'm just trying to help here.

An administrator controls which ports are open for regular users to consume - this includes ephemeral ports / ports in the local port range. As I did show previously you can control that with sysctl. Effectively, root can control all ports if they want to. On your machine the local port range may start at 1024, on my machine it may start at whatever I decide.

Here is something stupid (stupid only because I am ignorant of a good use case for it) that a sysadmin could do:

sudo sysctl -w net.ipv4.ip_local_port_range="1 1024"

With the above regular users can control port 443 without administrative control of the machine.

@dnozay Okay, while you're meditating, here is a little scenario for you to play with. Imagine you are an ACME server and you get a request to provide a certificate for example.com. What do you do? You can assume that none of the ports is assumed to be controlled by root.

Same here, I would assume none of the ports to be controlled by root.

kuba commented 9 years ago

@dnozay Okay, let's assume none of the ports is controlled by root, you are ACME server. How do you validate me?

dnozay commented 9 years ago

@kuba I don't know, I am not writing the specs.

kuba commented 9 years ago

Despite all the madness above, I had an idea and for some time now...

Current ACME protocol does not state that explicitly, but all defined validations require ACME server to perform domain resolution to IP address before connecting to the client. I claim, that implicitly the protocol relies on the security of the DNS system.

On this assumption, without weakening the security, we could extend the current protocol to look up predefined TXT record, say acme.port and use it to contact ACME client instead of the default 443. This would not only allow to use any privileged port < 1024 (#19) but any valid TCP/UDP port number. The latter has a useful property that it would not require clients to run as privileged users, closing possibility of various OS exploits due to the bugs in the client software... Of course, care should be taken and administrator will have to remember to secure the port before setting the record. I feel like requiring low TTL on such record would be beneficial from the security point of view.

TXT acme.port should be optional, and ACME server would fall back to the standard 443. This way we give more flexibility for more tech-savy users, while still maintaining the goal of the protocol, i.e. making it easier to acquire certificates.

Note that another benefit of the TXT acme.port solution is that administrators can run the protocol and create certificates without taking down existing services running on port 443.

What do you think?

CC: @jdkasten

ravisorg commented 9 years ago

@dnozay My apologies, I wasn't meaning to insult you. I was trying to say you might want to step back and view your request more globally, instead of concentrating on your server and your setup. For example, take into account shared servers (like GoDaddy, but also little mom and pop shops that don't have full time sysadmins) where malicious users that have access to the system may be able to do things unexpected.

You comment that your system is secure. It might be. It might not be as secure as you think. But regardless I would suggest that most servers in the wild are not well secured, and by assuming they are (or saying "well, that's root's fault for not securing it then") makes us all less secure by potentially allowing unauthorized people to obtain trusted certificates. Certificates that your browser will now trust, because the verification system was made weaker.

Verification is the weak point in the CA system - it needs to be made as strong as possible, even if it makes your specific case slightly less convenient for you.

Specifically in this case:

Let me know if I'm wildly misunderstanding your argument or if I've missed anything. I haven't had any caffeine today and I may be a little off ;)

jdkasten commented 9 years ago

It is difficult to separate out the eventual Let's Encrypt policy from what other CAs might want to do in the future. Mind you that any deviation from the "standards" poses additional risk on the CA system as a whole. The initial challenges were posed to be strictly stronger validations of existing CA practices.

I wrote up a bit of background on current validation methods and some CA background in an earlier question if you are interested. validation methods

In regards to @kuba, It seems reasonable, but I would have a few concerns.

It seems a bit heavy to me. Since there is already an existing DNS challenge, the only time someone would use it is if they were preparing to get a certificate sometime in the future and wanted to setup the initial phase now. The process requires two steps whereas if you already have ready access to DNS, you can always just perform the DNS challenge.

This technique may also lead to some prolonged attacks that may not be as easy to detect for the user. There is no sense of when the modification to the TXT record actually occurred and everything else seems to be fine. (This would still require some unprivileged box access, but this is the threat model we are trying to stop)

Finally, the CA will likely want to control which ports it thinks is valid for the current challenge.

Remember, as a client, you have to satisfy the CA and the CA is on the hook for any mistakes in verification. I know the Let's Encrypt CA will take additional policy measures to improve security and avoid misissuance.

What is more likely is that the challenges will allow the CA to specify a port to perform the challenge on... especially when ACME CAs begin issuing for different services.

normanr commented 9 years ago

btw, instead of TXT acme.port you may want to use SRV _acme._tcp as that is what SRV records are for :-)

coderanger commented 9 years ago

Would love to see this in the context of infrastructure automation. It would be much easier for Chef/Puppet/etc to spin up a little web server on a new port (but still <1024) rather than having to sort out what is listening on 443 already and interact with it to complete the verification. This could allow a more generic approach from automation/tooling.

dol commented 9 years ago

@kuba The idea with an optional DNS records sound like a good solution. As @normanr mentioned prefer SRV over TXT.

This is a very useful feature. In this case, we could offload the DVSNI traffic to an different port.

coolaj86 commented 9 years ago

The idea of SRV _acme._tcp sounds great to me, but I worry it will be too complicated for the average joe, which is kinda who we're targeting with letsencrypt, isn't it? I mean, we want to lower the barrier to get more people on the encryption bus, right?

Why not just allow some other privileged port < 1024?

Here's what I see:

Also, I definitely hear the argument for not allowing a user on a system request certs on behalf of that system... but I kinda disagree. Shared hosts generally don't allow their users to listen on random ports. Despite the history of linux being "multi-user", in practice I don't see it.

My motto is kinda "if you trust me enough to give me your credit card to have access to my system, you can trust that if you screw it up I'm gonna charge that lovely card of yours". If you're letting random untrusted users on your box, you've got... two problems... y'know?

coolaj86 commented 9 years ago

It looks like port 4 is ripe for an RFC https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml

And 6,8,10,12,14,16,26,28,30,32,34,36,40,60.

In all seriousness, I'd say port 81 is quite a catch. 442 or 444 would have been nicer, but hey, 81 ain't bad.

I'm quite surprised how sparse it gets as you go further out, but there are definitely enough ports for use and if silly one-off microsoft technologies that no one will ever use again can get through IANA, I'm sure something as monumental and web-worthy as LetsEncrypt can.

Yvi71 commented 9 years ago

I would also love to see an option to use an alternative port, just for the reason not to take down a service that already works on 443.

ac000 commented 9 years ago

To me, the argument of it's running on a root initiated port so it's good seems rather weak.

I see lots of chat here about insecure servers, well if that's the case assuming root is OK seems somewhat flawed. So I don't really see a big difference with using a port < 1024 or not.

Simply sending an email to an address at the domain seems just as good/bad to me and a lot less faffing about.

kelunik commented 9 years ago

Allowing other ports to remove the downtime for (re)validation is a good idea, especially if domain validation will take place on every renewal to make sure it's always the same process and not another process once a year.

I also think that restricting it to ports < 1024 is a must, at least by default, as it's secure by default then.

DavidLutton commented 9 years ago

Mumble seems to support CA provided TLS Certs. Some Community - Let's Encrypt discussion and recent Mumble release on Cipher Suites Seem to be indicate compatible suites, not sure if Mumble plays well with sharing ports, SSL endpoints et al, also given that it is live group voice chat that it would reduce quality of service & increase total latency through an endpoint service.

Mumble can be set to any port >1024, runs as reduced user on Ubuntu. Cannot claim ports "Server: TCP Listen on [::]:2 failed: The address is protected"

mvdkleijn commented 9 years ago

Apart from the whole discussion above where there are parts that make sense and parts that don't...

I think/hope everyone here can agree that:

  1. Causing downtime for (re)validation is silly and just not acceptable.
  2. ACME / letsencrypt is validating ownership of a domain, not the service(s) running on it so tying it to a certain port used by existing services seems inappropriate.
  3. Defining a default port is a good thing.
  4. Using port 443 for (re)validation while at the same time trying to get as many people to use that port (effectively that's what letsencrypt is trying to do) seems... counterproductive.

So... :+1: for using a separate, dedicated and registered port.

ravisorg commented 9 years ago

@mvdkleijn seems like a very sensible person. I would have to agree with everything there.

This might be a whacky idea with all sorts of unintended side effects that I haven't got enough caffeine in my bloodstream to see at the moment, but why not allow the client to specify the (re)validation port when making the request? By default (defaults are a good thing!) it could be 443, but if the client specifies an acceptable alternate port (<1024) then the validation service uses that port instead. This would solve pretty much any server configuration, as the client could always select a port not in use by other services at the time.

jdkasten commented 9 years ago

I am in favor of allowing the server to specify a set of ports to be used.

Of note, the CABForum Validation working group is currently attempting to enumerate a set of acceptable ports to perform DV.

jsha commented 9 years ago

@mvdkleijn: Note that the current spec does not require any downtime for revalidation. It is specifically designed so the your can provision a file or a DVSNI responder on your web server without taking it down.

Also, this early draft of the protocol has been replaced by the official IETF repo: https://github.com/ietf-wg-acme/acme. Let's do further discussion over there!

kelunik commented 9 years ago

Would have been nice if just the ownership had moved, so all issues and all history would have been retained.

@jsha Note, that it's not just providing a file, as we need a special content-type header, too. It would be nice to have the LE client really in a standalone mode, the current standalone mode is only suited for the first issuance. That way we don't need ACME support in every web server but can just always use it as standalone software for certificate management.

mvdkleijn commented 9 years ago

@ravisorg I would prefer to keep things simple. Lets just register a port with IANA for the standalone client. Allowing for choosing a set of ports is possible of course, but I would prefer a clearly defined and registered port.

@jsha I was under the impression that an automated update of the certificates would require downtime for validation. I'll reread.

I'm not a big fan of the DVSNI option personally. Seems overly complex to me.

The file option would be nice and possible (and at least simple) if not for the special header which seems unnecessary. A special header would make it more complex to set things up for the user who might not know how to set it up.

I was unaware the spec moved, especially concerning any discussion since there appears none in that repo. (0 issues)

I agree with @kelunik that the client needs a true standalone option for revalidation which would allow it to be tech neutral-ish.

For me personally, my ideal setup would have a completely standalone client manage the certificates for me and let me do the rest. I just don't like the idea of a third party app changing the configuration of my webserver. Seems just too fragile.

jdkasten commented 9 years ago

@mvdkleijn No, updates for the validation do not require downtime. If you are required to change the configuration, most webservers allow you to simply reload ('graceful restart')

@mvdkleijn @kelunik Given that the validation is currently required to be on port 80, 443 you are going to need to interact with the existing webserver. An option is currently being worked on. that might be of interest to you. https://github.com/letsencrypt/letsencrypt/pull/757

Finishing this off or additional PRs are always welcome. Though this discussion should be taking place at https://github.com/letsencrypt/letsencrypt

FYI, updates to certificates in the linked client modify a symlink so that configuration files don't have to change after installation.

Finally, if you do choose to modify config files, all configuration files are backed up before writing out to them. If installation fails, it reverts the configuration changes (or you can manually tell it to rollback to the original configuration)

coolaj86 commented 9 years ago

@jdkasten If Apache is currently using port 443, no number of graceful restarts in all the world will help the letsencrypt client, which also needs to run on port 443.

Or are you saying that updates don't run on 443?

Also, since it's in python instead of go (or even node), it's painfully slow. It takes whole seconds on a decent machine and something in the order of 30 seconds on a Raspberry Pi or similar.

kelunik commented 9 years ago

@coolaj86 There's another mode which just updates and reloads the Apache config to provide the validation payload IIRC, so there's no need for a restart.

jdkasten commented 9 years ago

@coolaj86 I think you misunderstood me. Yes, as I mentioned, as it stands you are going to have to interact in some way with the running webserver. Reload only avoids terminating existing connections and should not result in any downtime while serving the validation challenge.

@coolaj86 Yes, more clients should be written. There was never meant to only be a single client. There are many different use cases which will require varied clients.

coderanger commented 9 years ago

Interacting with the running Apache means you need to make assumptions about the Apache (or Nginx, or whatever) config structure. Using a secondary port would mean you could do this with no assumptions at all about the state of the system. Drop on a responder client, run the validation, shut it down, done. For stuff like Chef and Puppet integration this is hugely important.

dol commented 9 years ago

One idea to solve this problem without customizing/reloading the web server is to use iptables/PF to redirect traffic from the Let's Encrypt Validation Authority to a different internal port. On this port the acme client listens for challenge request and will perform the challenge.

iptables --table nat --append PREROUTING --protocol tcp 
               --source <Validation Authority IP address> --dport 443 \
               --jump REDIRECT --to-ports <ACME client port>

For this to work the Validation Authority IP addresses should be known.

kelunik commented 9 years ago

@coderanger Exactly, we could drop all Nginx and Apache related code / support then.

It's

@dol IP addresses of LE might change and be dynamic to prevent certain attacks, so that doesn't work.

coderanger commented 9 years ago

Even if the iptables trick did work, I would be very unhappy doing stuff like that in production :-P

mvdkleijn commented 9 years ago

What @coderanger described so eloquently and @kelunik nicely lists is exactly what I had in mind.

A letsencrypt client that messes with Apache's (or whatever) configuration is fine for simple use cases but for people with more complex setups or requirements, such a client would quickly break.

The ip tables trick is great from a theoretical pov but it makes my skin crawl for production. Also it'd be a definite no-go for less knowledgeable users.

mvdkleijn commented 9 years ago

@jdkasten So basically what you're saying is someone should write an open source ACME client that is a true standalone client doing what we specified earlier?

Wouldn't that potentially impact (user or service) security and hence usefulness of letsencrypt? One scenario that pops into my mind would be how you would explain to your users that a client written by a third party has a security issue in it. Assuming you're even aware of said client.

kelunik commented 9 years ago

@mvdkleijn ACME isn't limited to LE, there may be other CAs supporting it. Generally, other clients would handle security issues like any other software.

coderanger commented 9 years ago

@mvdkleijn Yes, having multiple client implementations is part of the idea. I'll be writing one in Ruby regardless, but it would be easier to not have to redo all the Apache/Nginx integration if possible.

analogic commented 8 years ago

@kelunik +1

I am curious why LE staff have choosen the more problematic way to cooperate with client systems instead of JUST getting the cert without web server dependencies. Isnt it easier to make one simple portable utility which will handle all comunication through dedicated port than messing with various systems with various webservers in various environments? When i first heard about LE I thought i would just add "/usr/sbin/le -d example.com -o /etc/ssl/example.com && killall -HUP httpd" to cron, open one port on firewall and forget about it... Well this is far from it

My1 commented 8 years ago

talking about records, why not just allow to make the entire validation with a record, like TXT or srv or whatever where you store some value that the le client wants you to store?

kelunik commented 8 years ago

@My1 That's another challenge that's available, but it's not that easy to automate.

My1 commented 8 years ago

if wen keep the challenge the same and just check whether or not it's still there it would be no problem, similar to the port setting a direct DNS challenge could be used optionally if you dont want LE to "mess" with your webserver's config, similar to webroot

hardie commented 8 years ago

Just a reminder that discussion of the protocol is at ietf@acme.org, since change control moved to the IETF.

regards,

Ted

On Mon, Nov 9, 2015 at 4:04 PM, My1 notifications@github.com wrote:

if wen keep the challenge the same and just check whether or not it's still there it would be no problem, similar to the port setting a direct DNS challenge could be used optionally if you dont want LE to "mess" with your webserver's config, similar to webroot

— Reply to this email directly or view it on GitHub https://github.com/letsencrypt/acme-spec/issues/33#issuecomment-154972736 .

kelunik commented 8 years ago

Unfortunately, there's nobody active there.

bifurcation commented 8 years ago

What @hardie meant to say was acme@ietf.org, where there is a bunch of active discussion right now.

bviktor commented 8 years ago

Guys, we really don't care if the port needs to be <1024. Then make it 444, 456, 865, 1023, whatever. Just don't require us to stop the webserver for this.