-
Notifications
You must be signed in to change notification settings - Fork 1.9k
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
Programmatic keyfile creation and PEM file import #1826
Comments
We can only accept code when submitted via a pull request with a git sign-off against a user that also has a filed Eclipse ECA. (The folks in Eclipse Legal are real sticklers to this, sorry) See: /CONTRIBUTING.md |
I know, but last time I did, it was a mess. SO, do not copy-paste this code, be inspired to create your own :) It will take 30 minutes, no more. Seeing everytime the boring process based on keytool & openssl is DEPRESSING. |
I think it is worthwhile streamlining pem processing |
Here is the relevant jetty documentation. I see your code gives replacements for the command line utilities referenced in the documentation, but I'm not entirely sure how that is less depressing than the existing command line tools. That code would still need to be packaged so it could be run from the command line, and thus we'd just have different command line tools (and running java from the command line can be depressing in it's own right). Am I missing something here? |
Oh yes :) Maybe am I biased because we always deploy Jetty in standalone, aka from our own For https, we need one certificate (or more), a PEM file is the common form of certificate delivery by providers and by the game changer "let's encrypt". So, if you can create dynamically your keystore from a PEM file with one line of code (or one line in an xml/ini file, if you preffer...) it's far easier and faster than dealing with command line tools. Isn't this pseudo code simplier to understand than the method from Oracle ?
|
OK I'm going to have to ponder on this for a while... to work out exactly how we might use something like this. I can see that for some use-cases it would be very useful, but it is still difficult to make general purpose. I'll edit the issue name to make it easier for others to find in the meantime... |
Maybe just consider cases when you want to setup https without using a PEM certificate ;) |
Sure, that's simpler, but why not go a step further and have...
...and it adds all the certs in the letsencrypt directory and does everything necessary. It could have optional arguments for domain/path/key/cert in case anyone needs granular control, but I'd expect the overwhelming majority to leave everything as default. It may well be useful to have more generic PEM functionality also, but I don't see any reason not to make supporting Let's Encrypt certificates as simple and hassle free as possible. |
Hi,
Sure, for this purpose I use Acme4J :
https://shredzone.org/maven/acme4j/index.html
but I don't think that retreiving certificates is something that we want
built-in a webserver.
Regards,
Guillaume
Le mer. 5 juin 2019 à 01:02, Peter Boughton <notifications@github.com> a
écrit :
… Isn't this pseudo code simplier to understand than the method from Oracle
<https://docs.oracle.com/cd/E35976_01/server.740/es_admin/src/tadm_ssl_convert_pem_to_jks.html>
?
File pkey = new File("/etc/letsencrypt/live/mywebsite.com/privkey.pem");
File pcert = new File("/etc/letsencrypt/live/mywebsite.com/fullchain.pem");
KeyStore k = PEMImporter.createKeyStore(pkey, pcert, PASSWORD);
sslContextFactory.setKeyStore(k);
Sure, that's simpler, but why not go a step further and have...
sslContextFactory.addLetsEncryptCerts();
...and it adds all the certs in the letsencrypt directory and does
everything necessary.
It could have optional arguments for domain/path/key/cert in case anyone
needs granular control, but I'd expect the overwhelming majority to leave
everything as default.
It may well be useful to have more generic PEM functionality also, but I
don't see any reason not to make supporting Let's Encrypt certificates as
simple and hassle free as possible.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#1826>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAJNKV5I6XV7INUZVY4TLALPY3X65ANCNFSM4D3HRAPQ>
.
|
I'm not asking for Jetty to do certificate management. Your proposal is to avoid the horrible process of converting PEM certificates to a keystore - which I fully agree with - but I'm suggesting it should go further and also have a single simple switch to tell Jetty "I use Let's Encrypt with default settings, go ahead and connect my keys and certificates". |
This issue has been automatically marked as stale because it has been a full year without activity. It will be closed if no further activity occurs. Thank you for your contributions. |
This issue has been closed due to it having no activity. |
I think we need to give this one more attempt. LetsEncrypt is now widespread, and we use it for our own website, where we do have a script that runs on The problem is that in Java everything is based on the concept of a While it'll be easy to write an importer utility class, we also want to be able to do this using properties for a standalone Jetty. @gregw how about this: startd/ssl.ini
We do the conversion internally from the 2 paths in PEM format to a PKCS12 keyStore and we should be good even with Thoughts? |
Sure, it's the way to go. I would add that it could be interesting to add a setting to specify the delay to consider that the pem files should be reloaded. In the case of of letsencrypt, the certificates are provided as symlinks pointing to the last "version" of the files (updated with a cron). So it could be good, to "refresh" the SslContext without having to restart Jetty. In production, at start the webserver uses the PEM importer I shared ; and our standalone webserver is restarted every day with cron. Auto reloading of the SslContext could be great to avoid the 3 seconds downtime. |
I use jetty to host two different domains, requiring two different certificates from LetsEncrypt. This In my opinion, the above approach isn't as simple for the user as it could be. A much simpler approach would be to have a certbot module for Jetty, that would monitor the This would mean that the only configuration a user would need to do is to add the Jetty certbot module, and everything would be automagically configured and updated when certbot renews the certificates. |
@knaccc good points. |
However, |
Oops, yes, well caught :) It's pretty easy to have a 1-line bash script as a --post-hook on certbot to use openssl to convert the pem files to a pkcs12 keystore file and place it inside jetty, after which a future hot-reload module would detect the change and perform the reload. I'd suggest the main reason people struggle is that it's difficult to google a tutorial on how to do this. So I guess the Java code for doing the equivalent of what openssl would otherwise do is really only required for people without the ability to run openssl. |
Permissions are a common problem with known common solutions which apply equally to all servers/software. So the documentation for the new module(s) can include an explanation with an example snippet such as:
Something similar would be needed for both a generic PEM module which was manually configured, as well as for an automatic letsencrypt module that scanned the directory. The latter would also require running |
@lachlan-roberts what is the status of this one? |
@gregw @lachlan-roberts I'm not sure we can do much here. The idea to support two PEM files instead of 1 KeyStore file won't work easily due to file permissions. As there is a million ways to skin and setup files, permissions, hooks, etc. I'm not convinced there is much we can do here -- but I can be convinced otherwise. |
What do you mean by "there is a million ways to skip and setup files, permissions, hooks" ? Nginx and Apache provide a simple (builtin) way to use pem files. I don't understand why on Jetty it should not be as easy. I'm still quite perplexed about assertion like "it can be done by external tools". |
It's not a problem throwing an exception if you can't read a file. Nginx and Apache link to the OpenSSL library. Java does not link it, so Jetty does not have a mean immediately available to read PEM files. Sure we can do it, but again see the comment above. My point is that ok, we can write in Java the tool to convert from PEM to KeyStore. Let's take the LetsEncrypt case: upon renew by What do you suggest? |
It's the same with Apache & Nginx, file permissions are granted as needed (through file permission or a group).
Sure, but Java can read PEM using X509Certificate as shown in my first message. In the case of a standard or EV certificat renewal, ie a certificat you renew and copy every year (or 2...) on your server, it's more "user friendly" to just copy the new PEM without having to remember the openssl and the keytool error prone syntax. In the case of cerbot, it all depends of the logic you use/need. |
I am missing your point, sorry.
You have to remember what you copy and where, point being you have to remember something and that is error prone. The ideal solution would be to automate everything. That's what the All of that is external to Jetty anyway. I don't think implementing a PEM-to-KeyStore tool in Java is any better than What do you think we should change in Jetty? |
I think we can close this one. We now have the |
Humm... so you are stating that a post-hook has to create a keystore? Why not, but it will expose the keystore password in the post-hook script. Ouch. |
That is exposed anyway because it's necessary to create a KeyStore. Your example code in the first comment will have to be invoked with an exposed password, or it should generate a password that needs to be exposed to Jetty in I don't see a way around? |
Sure, but it's a bit more "hidden" in a jar file if its generated. I will look at how the "ssl-reload" works to use it to monitor the files and reload the keystore from PEMs. But I'm still a bit perplexed to see how a standard thing like loading a pem file (as other webserver do) with a so short code addition, is not included (a bit like JSON in the JRE...). |
Because:
On the other hand:
|
I noticed this has been closed, but I think it is still possible to have this kind of option built in into Jetty itself. When I use jetty with pem files I use my own library to easily configure the ssl configuration, maybe this can be integrated. What do you guys think? I am using the following snippet: import nl.altindag.ssl.SSLFactory;
import nl.altindag.ssl.jetty.util.JettySslUtils;
import nl.altindag.ssl.pem.util.PemUtils;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import javax.net.ssl.X509ExtendedKeyManager;
import javax.net.ssl.X509ExtendedTrustManager;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
X509ExtendedKeyManager keyManager = PemUtils.loadIdentityMaterial(Paths.get("/path/to/your/chain.pem"), Paths.get("/path/to/your/private-key.pem"));
X509ExtendedTrustManager trustManager = PemUtils.loadTrustMaterial(Paths.get("/path/to/your/some-trusted-certificate.pem"));
SSLFactory sslFactory = SSLFactory.builder()
.withIdentityMaterial(keyManager)
.withTrustMaterial(trustManager)
.build();
SslContextFactory.Server sslContextFactory = JettySslUtils.forServer(sslFactory);
}
} See here for the library itself: sslcontext-kickstart It parses the pem files and creates an inmemory keystore object which will be used to construct the keymanager/trustmanager. So no need for a post-hook with openssl. |
Hi,
Certificates providers are using the PEM format.
Their documentation and the Jetty wiki is always refering a painful method using keytools and openssl.
Here is the better way you could include in the documentation, or better in the util package, following the code I wrote years ago (public domain :) ) and used in production.
Hoping it could help.
Best regards,
Guillaume
The text was updated successfully, but these errors were encountered: