-
Notifications
You must be signed in to change notification settings - Fork 306
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
Let's Encrypt Integration #1047
Comments
Not sure whether this is appropriate to hijack this - but it is related, as it covers the TLS integration. At work I have a gateway system for which access is protected by a custom CA which is configured to regularly create a CRL. Big problem: I have to restart the gateway system to reload the CRL. If I'm not mistaken this is also true for changes to the trust- and keystores. So to sum it up it would be nice if the TLS implementation would dynamicly adapt to changes to the trust-/keystores and CRLs. |
How would you see this working from a user perspective. What steps would you see them doing? @matthiasblaesing dynamically reacting to keystore changes is doable but is an enhancement request can you raise an issue for that? |
@smillidge: See https://caddyserver.com/docs/automatic-https For Payara Micro one could use whatever Payara Micro is using for configuration. Having this in Payara Micro would be really a killer feature. "The simplest way to run your Java application in production." (in your face Spring Boot! :))) |
Cool picture. As long as people realise it probably won't work seamlessly behind a proxy, it would be a great feature to have. |
Internal issue id |
If you would use and enable this, you could maybe also enable secure admin by default? |
"The simplest way to run your Java application in production."
While we're at it, if on-the-fly certificate reload and change would be possible, I would actually prefer doing it through asadmin CLI in a scriptable fashion (sample script being part of the payara package). |
Hi all, I'd like to contribute to the LetsEncrypt integration if I can. What I have so far is a servlet filter that responds to the LetsEncrypt-challenge (installed via default-web.xml) and a post processing Java application that updates the GF keystore when it gets triggered by the acme renew process. It just sends an e-mail when the SSL certificates have been renewed and I have to manually restart the server: I do have an issue with the web admin console after the keystore update, because it breaks the login. What I do to solve it is basically disabling secure admin, restart the server, enable secure admin again, restart the server. It would be good to have a mBean that does whatever gets done during this process, i.e. reloading the SSL certificates from the keystore file and fixing the login keys if secure admin is enabled. My post processing Java program could then simply call that mBean to finish the job. I'm happy to provide the mBean (empty body for the server side to get finished by someone who knows GF) and the full source of my LE code. I think this is a viable approach, because it requires minimal effort on the Glassfish code. Cheers, |
Hey @a-genius that's great! Community contributions are very gratefully received. I can't see that we have any signed CLA from you. If you haven't already signed and emailed on back to us, could you do that so that we can accept your PR when it's ready? If you'd like to contribute unfinished code, then I guess probably @arjantijms or @smillidge would need to review it and see if we can schedule in some time to work on it ourselves (we're pretty busy lately!) Thanks again |
@a-genius while the idea is great, I think Servlet Filters might bee executed too late (JASPIC is loaded before any filters). I think you will probably need to implement it in a lower level tier (Grizzly filters, Tomcat valves or similar). |
My vote goes for a Custom A couple of factors to consider before you opt for any approach:
Ideally, the solution chosen would be usable with little to no modifications in all scenarios (where it makes sense, that is). For this it is imperative that the (externally visible) callback URL is configurable.
|
I'm sure that there are many ways to integrate GF with LetsEncrypt. My idea was to interfere with the application server as little as possible. That is why I didn't consider a library like acme4j for this job - the application server should not implement the acme protocol itself. This would be another burden that needed maintenance. The acme-challenge filter The acme-challenge filter can be installed if one has a web-application at the root-context of each (virtual) domain set up at your server. If someone can't use that filter, they may need to use DNS validation, or someone implements a different mechanism to achieve the goal, e.g. for JASPIC ( I never used it so I can't help here). The post processor is a Java stand-alone application. It gets started by the certbot tool and just copies the received certificate (which is a pem-file that contains the cert chain and another one that contains the private key) into the GF keystore. It doesn't need any connection to the outside world, so it will run happily on localhost as well. The only part that is missing is getting the server reading in the new certificate. If it had an mBean API that triggers the re-load, the post-processor could just call it once its finished. That way no server restart would be required and the integration would be complete. If the mBean is the only change, users who don't need that integration don't have to handle all that stuff. It'd still be a good feature, for instance one could trigger a re-load manually using JVisualVM after an update of the keystore. I think this is a good place to discuss different approaches. |
There a couple of requirements together here. The first is Let's Encrypt integration which would require the challenge filter. The second is a simple way to add a certificate to the keystore and configure it without a restart. I would like to add the ability to load any certificate into the keystore as an asadmin command. In that way the certs could be loaded into the keystore, the configuration refreshed and the keystore replicated across all running instances in the domain. Keystore manager is here https://github.com/payara/Payara/blob/0ff8de27c0083a6fd8118f6a7caf7a53e27ba04c/nucleus/admin/server-mgmt/src/main/java/com/sun/enterprise/admin/servermgmt/KeystoreManager.java |
I have glanced through the preferred ways of integrating letsencrypt. They mention two basic scenarios: with shell access or without.
Another possibility is embedding a minimalistic web-server into asadmin (see @AdamBien 's https://github.com/AdamBien/nano web server). Chances are with this approach we would not need to write a certbot plugin and could do with the existing webroot (https://certbot.eff.org/docs/using.html#webroot) plugin for certbot. Once the cert is ready, we would use asadmin in both cases to upload it to payara. What do you think? |
I'll try to do the asadmin command (unless someone will be faster).
|
Tried to implement an |
I like the idea to have an asadmin command for reloading the keys. As expected, some others have the same problem, maybe we can learn something from their ideas, e. g. Jetty: |
Never mind, I think I got it. This helped a lot: https://www.youtube.com/watch?v=gByztPUkqyY |
@ratcashdev if you put a branch out on GitHub somewhere I can help if you have issues |
That's very welcome. I hope it's ok if I fork my branch from 4.1.2.174. I have just tried the master, but asadmin throws exceptions there. Trying to go through the path of least resistance. I have just managed to build/add the example service and run it. Should not take long to make it import keys. |
@smillidge Question: Is there a way to call KeystoreManager.KeystoreExecutor inside server-mgmt from the 'service-exemplar.jar' (the payara AdminCommand example deployment fragment)? I could only make it work by copying server-mgmt.jar into glassfish/modules but it seems wrong because normally it's inside lib/asadmin/ |
Phew, a month already since the last post. I finally managed to put the code for the filter and the post-processor on github: https://github.com/a-genius/schnerpfel |
Part of it is done, but I don't really like how it is done and I am waiting for @smillidge to answer my former question. |
I am back working on this. Prliminary results here: https://github.com/ratcashdev/Payara/commit/94af56eb341558e48042234d7783fa522414363e
|
@ratcashdev I don't really understand why you need to use keytool or the Java equivalent code. After the LetsEncrypt post-process run (see https://github.com/a-genius/schnerpfel/tree/master/gfTools) the new certificate will be in the Payara/Glassfish keystore already. All the new command should do is to reload the cert and to reconfigure the listener. Unless you want to reimplement everything... |
quoting @smillidge from a couple of posts above:
That's exactly what I did: ability to load PEM and .KEY files into the keystore as an asadmin command. The configuration and listener restart can already be done with the existing asadmin commands. The seamless SSL configuration reload will be done in a separate PR, if at all possible. |
yeah we actually have a task for this sprint to simplify SSL handling so the as admin command will be create as I envisage an administration console section for keystore management. On the specific question of using keytool directly from the source. There's no need to do that in fact I was thinking of refactoring all that to use the apis. I suspect that is really old code from the days when there was no java api to modify the keystore. |
On the question of modifying server-mgmt. go for it that is the best place to put the code. |
"I would like to add the ability to load any certificate into the keystore as an asadmin command. In that way the certs could be loaded into the keystore, the configuration refreshed and the keystore replicated across all running instances in the domain." These are two different tasks and there should be two asadmin-commands for them in my opinion:
"The configuration and listener restart can already be done with the existing asadmin commands." Which command is that? |
@smillidge hi, should the new API that is not using keytool allow empty keystore or private key passwords (specifically |
I would refuse it. Also in Payara the private key password must be the same as the keystore password. |
The following commands do not (YET, unfortunately) reload the keystore:
|
@smillidge submitted a PR for the keypair import: #2599 Please have someone have a look on it. Thanks. |
another PR: #2635 . With this change the above commands (setting listener to disabled and then enabled) would reload the keystores and activate the new key/alias/ssl setting without restarting the whole app-server. |
#2635 got merged. @a-genius also did quite a bit of work.
@smillidge what would be the next step for Let's Encrypt integration? How would you suggest to integrate the filter? |
Is the filter a servlet filter? One option is to add it to the admin console web application however that would mean exposing that to the internet for this to work automatically. How do you envisage this working with Let's Encrypt, would a user expose the admin console to the Internet? |
@a-genius only published the complied jars, not the sources, so can't tell, if its a servlet filter or not. |
@smillidge I have re-read the ACME certbot documentation and have an idea.
This is nicely scriptable and repeatable every 90 days using CRON and the only missing element is the actual (empty) WAR, and/or the script calling asadmin and the certbot. Obviously, it assumes the user already has an account with LetsEncrypt, has his keypair available to be used by certbot, etc. But Certbot helps with all that. Another possibility would be to use ACME4J inside asadmin and not rely on the certbot at all. A bit more programming, but nothing terribly serious. This would add ~400Kb of extra dependency to ASADMIN (acme4j - 100kb + jose4j - 252kB and slf4j - 40Kb if not already available) and the related risks (outdated acme4j, need to update the distribution just to make LE integration working, etc.) I really like the former approach much much more. Edit: Certbot is only supported on Linux. If we wanted to be cross-platform, we would need to go the acme4j route. |
"a-genius only published the complied jars, not the sources, so can't tell, if its a servlet filter or not." The leChallengeFilter is a servlet filter that should be added to the default-web.xml. This requires a web application at the root context of every virtual host that shall be verified by Letsencrypt. All documentation and source code is on my github repository. I mentioned it in the accompanying readme.md, but it may not be obvious enough: "The zip-files contain source, binaries and property-files." It may not work for every possible setup, as a few people mentioned (see further up this thread). I got my cert updated two times since I installed it and it worked fine; I just have to restart the server manually. It would be much better just to trigger a reload of the cert without restarting the connector. |
Simplifying further. Certbot would then be used like this: Afterwards you can undeploy the war: and upload the keys, etc. I think it won't get simpler than that. No coding necessary to achieve full integration and automation. |
Here's a PoC script using python (as it is cross-platform and certbot anyway requires python): https://gist.github.com/ratcashdev/1b09877d37e02ef5170bf9e60c377f34 Usage: Example: First run must be manual (account creation, etc). The subsequent calls could be done without user interaction. |
@smillidge have a look on this please, if it's worthy for a PR. |
I'm not too familiar with Python so can't comment on the script. Feel free to make the PR and I can get it reviewed |
submitted as: #2727 |
This issue is already closed :). I hope that that’s what you mean |
lol |
For anyone finding this issue please note that the current script uses different arguments than listed above. (for instance -d is domain dir and not the domain you want to create a certificate for) It also has a few issues that need to be tweaked before it will work correctly: Once you've manually ran it once to create and insert your certificate you should add "-n" to the certbot_call_args, else it will ask you what to do if your cert isn't due to be renewed yet. I'm assuming you eventually want to run it from cron with unattended mode enabled. Here is my file that seems to work well: |
@thirion I am happy that you found this thread and the script. At least someone found it useful (even though it seems it's not really working trouble free). Back when I was writing this (especially the in-place deployoment: #1047 (comment)) it worked for me to deploy the dir named as it was in the script. If it does not work now, maybe something changed on Payara's side. The LetsEncrypt must have changed a lot too. |
Please raise a new issue if there are problems with the script as we are shipping and therefore maintaining it. |
An integration with Let's Encrypt for easy to use & secure HTTPS could be a killer feature. Configuring TLS is PITA in most application containers.
For inspiration see Caddy
Also: https://github.com/shred/acme4j
The text was updated successfully, but these errors were encountered: