Garret, On 10/5/20 19:45, Garret Wilson wrote: > On 10/5/2020 2:42 PM, Christopher Schultz wrote: >> … >> Sure, it can contain S3 credentials and you can pick-up your key and >> certificate (or, better yet, the whole keystore) there, but at that >> point you have "moved" the problem outside of Tomcat, right? > > No, not at all. The major problems are: > > 1. Generating the certificate automatically. > 2. Feeding the certificate to Tomcat automatically. > > If the "extra" thing I have to do is specify an environment variable > with the name of the S3 bucket to use as a certificate state, then that > is a teeny, tiny problem. That is not really even a problem. > > Can you imagine if in my spring boot application I could run it using > "java -jar my-app.jar --cert-work-bucket my-bucket" and it would just go > get a certificate automatically?
What if your Docker container would just run certbot on launch? >> You can have a "certificate renewal service" that writes to S3. > > I want it built into my application as a module. You just include the > module, specify the domain name (and maybe a couple of other details > needed by RFC 8555, such as a contact email), and boom, it all happens > automatically. > > Why does it have to be more difficult than that? It shouldn't be. Fair enough. >> I suppose you could put that directly into Tomcat, but Tomcat is not >> likely to ship with an Amazon-specific feature built-into it. > > > Read my original email. I never intended to put this directly into > standalone Tomcat (although if you want to put it into Tomcat you're > welcome to). I want to use this with an application running on embedded > Tomcat. Spring Boot is a prime example. I'll just extend the Spring Boot > embedded Tomcat module and extend/modify that as needed. If that > requires modifying Tomcat code, fine. > >> Another idea would be to use embedded Tomcat (or, at your suggestion, >> Spring Boot) and fetch the keystore from some "standard" location of >> your choosing. Again, that would be (appropriately, IMO) outside Tomcat >> code. > > That was always the intention. In my introduction to my original email I > explained that the modern approach is moving away from something like > standalone Tomcat to self-contained executables that run their own > servers, whether embedded Tomcat or whatever. (I was late to the party, > and even two years ago I wasn't getting it.) I'm not sure I'd say "modern approach". It's certainly popular these days, for sure. >> 1. Does acme4j allow me to verify my certificate behind another port? >> (e.g. ElasticBeanstalk deploys a JAR behind NGINX port 5000 by >> default. I'm still reading RFC 8555 to find out if the ACME server >> has to connect back on a certain port for verification.) >> 2. Once I have the Let's Encrypt certificate, can I convert to PKCS12 >> for Tomcat completely in the application without shelling out to >> openssl or keytool? I'm hoping Bouncy Castle and/or acme4j-util will >> allow me to do that. >> This can be done, but it's non-trivial. For example, Tomcat contains >> code to package PEM-encoded DER files (good old OpenSSL-style =====BEGIN >> CERTIFICATE===== things) into an in-memory keystore to configure JSSE. >> It seems like it would be straightforward, but it turns out not to be in >> all cases. YMMV. > > Non-trivial as it may be, it /only needs to be done once/. If I have a > converter, then I can use it a thousand times. A million times. And > suddenly the deployment becomes a piece of cake. > > In reality, today's style of handling SSL is what matches your > description of "It seems like it would be straightforward, but it turns > out not to be …". So why do we keep doing all this difficult, manual, > tedious, not-trivial stuff to deploy certificates the hard way, when we > could put our efforts into a single no-trivial task of making a > converter so that Tomcat can use the Let's Encrypt certificates > directly? We do it once. It's hard, but then everything else is easy. I > don't get why we want to spend another decade doing it the hard way when > we can spend one year on a different hard task and then do SSL the easy > way for the other nine. > > (The frustration isn't directed at you. It's just in general in software > development I see the industry—why does the most basic of things have to > be so difficult?) > >> 3. Once I have the PKCS12, how do I feed it to the embedded Tomcat? >> If it's a file on the disk, it's easy: just use the path. > > Can I pass it in memory? If not, why not? How is memory less accessible > than a file? Yes, you can pass it in-memory, but you have to arrange to load the key material from somewhere into memory. And sometimes the key material can be in a surprising series of formats. >>> Chris, where can I get more information on the latter questions about >>> getting this certificate to Tomcat once I have it? >> This mailing list is a good place to start (and likely finish). > > Of course I really super-appreciate the help on this mailing list, and > I'll be asking lots more questions. But I also don't want to ask things > you've already answered elsewhere. I thought sure in one of your > ApacheCon 2019 presentations you mentioned you had made more progress > than the ApacheCon 2018 slides, such as auto-reloading or something. If > there is further documentation let me know. Not auto-reloading, but reloading the SSLHostConfig does indeed work, now. If you had an on-disk keystore, the configuration doesn't change but it needs to be reloaded. You can do that via JMX by calling the reload() (or similar?) method on that MX bean. If you build the keystore in-memory, I'm not exactly sure what you'd need to do in order to get Tomcat to bounce the SSLSocketFactory in that way. >> Go back to my presentation on Let's Encrypt and you'll see how to use >> openssl to convert to a keystore if that's what you want. > > I want to make any conversions completely in the application without > depending on some utility installed in the OS. So no making a shell call > to openssl. If OpenSSL can do something, why can't Java? It can. >> Or, better >> yet, skip that step entirely and use the PEM-encoded DER files that >> Let's Encrypt already provides to you. > > I have no idea what a PEM-encoded DER file is, but I'll certainly learn. This: -----BEGIN CERTIFICATE----- stuff -----END CERTIFICATE----- It's an easier format IMHO to deal with than, say, a PKCS12 keystore. Wonderfully, and somewhat surprisingly (to me, who finds Java's crypto APIs needlessly complicated), Java can load these trivially: java.security.cert.CertificateFactory.getInstance("X.509").generateCertificates([inputstream]); This returns a Collection<Certificate> which you can simply iterate through and do whatever. For loading keys, it's not as straightforward. :( > And if it means that Tomcat can directly use something provided by Let's > Encrypt with no conversion required, than that's awesome! > > So what's the problem? One piece of code talks to Let's Encrypt and > stores this DER file thing on S3. Another piece of code pulls the DER > file from S3 and starts up an embedded Tomcat with it. (All in same app, > as needed.) Seems straightforward to me. You also need to periodically re-execute the ACME request in case the application has been running long enough for the certificate to "age". So you'd better do it on startup and also every X days or whatever. >> You just have to work-out >> file-permissions issues. > > I still don't get why files have to be involved. I pulled a DER file > from S3. Sorry. I think of that as a "file". > I have it in memory. Embedded Tomcat is running in memory. They > are in the same JVM. Why do I have to put something in a file? You'll have to see what is required to tell Tomcat to reload an SSLHostConfig that was programmatically-created. That's over my head at this point. >> What you have to remember is that AWS is often MORE EXPENSIVE than >> running your own stuff. > > It shouldn't be, in general. Part of the whole cloud value proposition > is that you only pay for what you use. Yes, but if you need 100% utilization then you ave to pay for it. Like you are seeing with e.g. ELB charges. The ELB has to be up even if your application isn't running any active nodes. > The problem here is that this big SSL antipattern hurdle is making me > need to use things I don't need for a tiny app. I'm wanting to remove > that hurdle. If you'd bite the ELB bullet, you could just get free auto-renewing certificates from Amazon. *shrug* >> I hear that. I still don't understand how you are supposed to get OS >> updates working for an application deployed into Elastic Beanstalk. > > See > https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/environment-platform-update-managed.html > . > > But I don't want to over-focus on Elastic Beanstalk. > > The issue here is that I want a standalone app with embedded Tomcat that > automatically 100% configures SSL. For now Elastic Beanstalk is just one > vehicle to run that app. In the future we may have platforms (if we > don't already) that completely hide the OS, and the JAR is just running > as a service. > > We have the same sort of thing with static sites on AWS. Remember that > static site generator, Guise Mummy, I showed off at ApacheCon 2019? I > finished it, and all my sites are now using it. Guise Mummy generates > and deploys a static site to S3, but then configures CloudFront to cache > and serve it with edge access around the world, with HTTPS. (See > https://www.globalmentor.com/ as an example.) What web server is serving > those files? What OS is hosting the web server? I have no idea. It's > irrelevant. How do I update the OS? I don't need to. For all practical > purposes there is no OS. My site consists of static files, and AWS is > hosting them. So your web server is S3. > Eventually the same should go for my JAR file. I give AWS my JAR file. > AWS starts up my JAR file. It has HTTPS automatically. I shouldn't have > to do a single thing. > > We are almost there, except for this huge SSL problem where I have to do > basically what I did in 2000 to get SSL turned on. (Maybe it's a little > easier. Not much.) > >> Really, I'm speaking from a position of profound ignorance on this >> point. I really have no idea how this stuff is supposed to work and >> I haven't put any time into discovering the real answers. > > > Chris, I'm learning all this stuff too. I had to get over a bunch of > gotchas to get this S3->CloudFront with automatic SSL stuff working for > a static site. And you can see from my Stack Overflow question > https://stackoverflow.com/q/63650514 that I naively approached Elastic > Beanstalk from the same view, thinking it would transparently handle > everything for me. It doesn't. But that's where we want to go eventually. ELB ~= CloudFront, right? If CloudFront handles your SSL for you, why not let ELB do it for you in this context? It doesn't have to be as hard as you are making it sound. And your application shouldn't have to deal with this. You ave decided that your application should handle it, and so you are making more work for yourself (and your application). If you separate those concerns, you will have a simpler system. Well, it's a more complicated system overall, but each part is simpler. > So I have a lot to learn. One of the first things I'm learning is that > SSL is a problem Everywhere. All the gazillions of cute demos don't > include SSL. If you do set up SSL, you have to jump through all these > hoops, or pay lots extra to have a load balancer. Really, there isn't an > easy SSL solution for anything in the cloud that I can find that isn't a > static site. If you know of something, then please go answer my Server > Fault question: https://serverfault.com/q/1036276 . > > If nobody else will do this, I will do this. It needs to be done, > because I don't enjoy playing sysadmin just to set up SSL when I'd > rather be writing applications and deploying them. If you are building a Docker container and it won't kill you to have anything running on it besides "java -jar myapp.jar" then I would suggest that you set things up using the process I detailed in that 2019 ACNA presentation you mentioned. It would require that you: 1. Fetch files from S3 on Docker deployment (this seeds the node with any existing keys + certs) 2. Run certbot on Docker deployment (which may decide not to update if the files are fresh enough) 3. Configure cron to call the script included with the ACNA 2019 presentation once per week 4. That cron script needs to be updated to push any new files generated by certbot -> S3 5. Profit Or you could build a bunch of Java code because you want your application itself to handle this. -chris --------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org