Skip to content

Investigate adding HTTPS support #24

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

Closed
shepmaster opened this issue Jul 15, 2016 · 21 comments
Closed

Investigate adding HTTPS support #24

shepmaster opened this issue Jul 15, 2016 · 21 comments
Labels
enhancement Something new the playground could do
Milestone

Comments

@shepmaster
Copy link
Member

No description provided.

@shepmaster shepmaster added the enhancement Something new the playground could do label Jul 15, 2016
@shepmaster shepmaster added this to the equivalence milestone Sep 14, 2016
@gsingh93
Copy link

Any update on this? Should just take a few minutes to throw a letsencrypt cert on the server.

@shepmaster
Copy link
Member Author

One thing I like about the playground is that I'm trying to push as much Rust as I can. To that end, I'd like to have the SSL terminate at the Iron server. That's the main thing I'd like to investigate. If you have some knowledge around that, that would be great to share!

Getting a certificate should be easy, as you say. There's also the issue of keeping it up to date; don't Let's Encrypt certificates have a short lifetime?

@gsingh93
Copy link

To that end, I'd like to have the SSL terminate at the Iron server

Is this what you're looking for: https://github.com/iron/iron/blob/master/examples/https.rs

There's also the issue of keeping it up to date; don't Let's Encrypt certificates have a short lifetime?

They do, which I think is a pretty good thing for security reasons. Most people setup a cron script that runs the renewal command every two months or so.

Btw, the reason I commented here was a friend decided not to use this site in his blog post since it didn't have HTTPS. So people definitely want this :)

@shepmaster
Copy link
Member Author

decided not to use this site in his blog post since it didn't have HTTPS

Part of the reason I haven't been proactive about this is because I don't really see this point. You are still sending your code to a relatively untrusted place (I trust myself and my code, but you know...), so why does it matter if someone sees your code en route?

Do you know any further details about your friends underlying rationale?

To clarify, having someone care is more impetus for me to change it, regardless of why. I'm just curious for my own sake.

@gsingh93
Copy link

Good question. Privacy is only one aspect of TLS. The other is trust that the site you're communicating with is the one you're expecting to be communicating with. So I trust you and your site, and I believe that the code running on your server matches the code in this repo. However, with HTTP, anyone can MITM that connection and serve different code to me. That code could do malicious things, like profile my browser, test for CVEs, try to phish me ("login with Facebook to share your code there!"), etc. By serving with a TLS cert, I can trust I'm being served your code, no one else's.

This might feel like a bit of a stretch to some people, but given how easy it is these days to setup HTTPS with almost no downsides, there really is no reason to risk it. My friend and I also work as security engineers, so we have a bit of an obligation to push for stuff like this too :)

@shepmaster
Copy link
Member Author

I've it all implemented locally, but there's problems during deployment:

  1. Let's Encrypt provides PEM files, hyper-native-tls requires PKCS12. Fixable, but annoying considering the 90-day window.
  2. hyper-native-tls appears to load the certificate once at initialization. That means the server needs to restart every ~90 days or I have to implement my own thing that reloads every so often.
  3. hyper-native-tls uses openssl, which is notoriously annoying to cross-compile to MUSL.

@shepmaster
Copy link
Member Author

By serving with a TLS cert, I can trust I'm being served your code, no one else's.

So long as you trust my skills to adequately secure my server through other avenues, such as SSH 😈

@shepmaster
Copy link
Member Author

I've a temporary server up and running at https://play.integer32.com/. I need to do more work to not make it a hassle to deploy, but does the SSL look SSL-y enough for your security engineer selves?

@gsingh93
Copy link

hyper-native-tls appears to load the certificate once at initialization. That means the server needs to restart every ~90 days or I have to implement my own thing that reloads every so often.

Yea, even nginx/apache needs to be reloaded when renewing, but the renew commands have pre-hook and post-hook commands you can use if that helps: https://certbot.eff.org/docs/using.html#renewing-certificates

Let's Encrypt provides PEM files, hyper-native-tls requires PKCS12. Fixable, but annoying considering the 90-day window.

Huh, it's weird they only support PKCS12. Might just be something the haven't had time to look at yet. In any case, I think the post hook command above with an openssl one-liner should be able to make this less annoying.

but does the SSL look SSL-y enough for your security engineer selves

Yes it looks good :)

@shepmaster
Copy link
Member Author

pre-hook and post-hook commands

Unfortunately, trying to use certbot just showed a big ol' "don't use this on Amazon Linux", so I went with acme.sh for now. It doesn't appear to have hooks of the same shape, so I might have to find another client if I want that...

Actually getting the server to a place where it's easily restartable in an automated fashion would require me to graduate from my poor run-it-in-tmux style too.

something the haven't had time to look at yet

That's my bet as well. I've opened sfackler/hyper-native-tls#3 to see if they'd be interested, and sfackler/hyper-native-tls#4 to see if an auto-reloading thing would be useful at all.

Yes it looks good :)

Yay! Now to iterate on the deployment. Once that's solid enough, I'll set up the HTTP->HTTPS redirect.

@joshtriplett
Copy link
Member

@shepmaster I highly recommend https://github.com/diafygi/acme-tiny as a small, self-contained implementation. I use that on my server, and run it as a separate user, pointed at a separate directory that my web server is configured to serve as /.well-known/acme-challenge.

Your server configuration mostly seems fine; however, there are a couple of weak cipher suites you should disable: TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, and TLS_RSA_WITH_3DES_EDE_CBC_SHA . (Anything with "3DES" in the name.) See https://www.ssllabs.com/ssltest/analyze.html?d=play.integer32.com for more info.

Finally, ideally you'd have native support for the ACME protocol, to allow in-process renewal. See https://crates.io/crates/acme-client for that. I'd love to see a drop-in mechanism to integrate this with a Rust webserver (iron or otherwise). But until then, out-of-process and certificate reloading seems fine.

@shepmaster
Copy link
Member Author

@joshtriplett thanks!

there are a couple of weak cipher suites you should disable

Hmm. I didn't do anything to especially enable these, so I'm guessing that's the default from hyper-native-tls? It might be nice to drop them the same advice if so. I'm not actually sure how to control the cipher suites at the moment 😺 .

@shepmaster
Copy link
Member Author

For future readers, one thing to note is that there are now two deployments: play.integer32.com and play.rust-lang.org. I don't have any control over the rust-lang.org one, AFAIK that's behind an nginx load balancer. I do have control over the integer32.com one. Most of the HTTPS discussion here pertains the the latter.

@joshtriplett
Copy link
Member

@shepmaster If you're using the default from hyper-native-tls and you get those ciphers enabled, please do file a bug on hyper-native-tls to disable those by default.

@sfackler
Copy link
Member

@joshtriplett native-tls on Linux is using https://wiki.mozilla.org/Security/Server_Side_TLS#Intermediate_compatibility_.28default.29, which whitelists 3DES suites (at the lowest priority) for clients that don't support AES. The server picks the suite based on its own preference so they'll only be selected if the client indicates it doesn't support AES at all.

@sfackler
Copy link
Member

On the server side, I'd only recommend native-tls as the "easiest thing that just works". Supporting all platforms mean that the APIs are very limited - in particular we can't even let you select which ciphers you want because that decision is made at the system level on Windows. Using openssl directly is probably the better option there.

@repnop
Copy link

repnop commented Aug 22, 2018

I hope this is the correct place to ask, but is there a reason why the play.rust-lang.org playground doesn't default to HTTPS? I've noticed that going to that URL without something like the HTTPS Everywhere extension sends you right to and HTTP URL by default.

@shepmaster
Copy link
Member Author

doesn't default to HTTPS

Heh, mostly because I forgot to switch that on after bootstrapping the server's HTTP certificate with Let's Encrypt. Lemme see if I can flip that.

@repnop
Copy link

repnop commented Aug 22, 2018

Awesome, thanks :)

@shepmaster
Copy link
Member Author

Fixed!

@shepmaster
Copy link
Member Author

For the original purpose of this question, it's just easier to use nginx as a frontend.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Something new the playground could do
Projects
None yet
Development

No branches or pull requests

5 participants