Please, Java, connect to this stupid thing one more time.

Gushi
11 min readJul 3, 2021

--

As a sysadmin, I come across ancient systems running modern OSes. For what I do, this is fine: the bare level OS and a couple of low-CPU daemons often do not need miner-level CPU power. Often, even the CPU of an embedded system would be fine.

Our greater need is for remote access. If the thing dies (or stops responding to SSH), we need to be able to reboot it, or see what’s on the console, or even worse, reinstall it. We need remote consoles. And when those happen, we usually need to run sometimes-old-and-crusty Java Apps.

Java was conceived by Sun Microsystems (when there was a Sun Microsystems) to be a universal runs-on-everything sort of language. The idea was that instead of running a heavy-lifting central webserver, compiled universal code could run on the end user’s machine. Used in a browser, it was sold as “safe” because everything ran sandboxed and couldn’t arbitrarily touch files on your computer. Since then, of course, the infosec industry has declared Java to be a security nightmare, and actively deprecated its use, at least for running in-browser applets.

My first experience with Java was waiting for an applet to run for a few minutes and use all my CPU to display a reflective lake. It was at that point that I realized it was pointless.

Note: There’s also this thing called Javascript. They’re not the same language, at all, and are barely even related. Javascript is not “java light” — it’s not like comparing, say, sh with bash. For our purposes, let’s ignore Javascript entirely.

We’ve moved on: browser plugins like Flash and Shockwave and even the venerable Java have become largely a thing of the past. Hell, Netflix used to require Flash to distribute their content and now they display using entirely HTML5. You can show video streams using only HTML, complete with all the DRM and HDCP that the copyright holders require.

But some server manufacturers decided “Hey, wouldn’t it be cool if our piece of hardware just handed you an app that you could run? That seems nice and cross-platform and future proof.” LOL

For so many problems like this, the answer really is: “Keep an old VM around.” I have a Windows XP VM that I have to break out regularly. Some iLOMs require ActiveX controls and IE6. Some APC power strips require key strengths so weak that they’re no longer in shipping versions of OpenSSH (Here’s a flamewar about that). VMware VCenter 5 requires Flash (but 99% of things will run without it). Heck, Cisco UCS servers required Flash just to log in and display anything (not just the virtual console) — and their tech notes say “Um, yeah you should upgrade”, and now not only will Flash not run in a modern browser, but Adobe won’t let you download it for any machine. So instead, you’d have to trust a third party download site.

But for regular use, being able to bring up Java without needing a VM is still worthwhile. At least, if they’d stop moving the security Goalposts.

There seems to be this weird corporate illusion at Adobe and Oracle that none of these technologies were ever used to manage production machines, and it was all just to run web content like games or Joe Cartoon that have moved on or died.

I would dearly love some box deep in a preference pane that says “I’m a sysadmin, I know what I’m doing, please just let me Do The Thing.” Until that exists, there’s this article.

For years, the process of capturing another device’s VGA screen, and displaying it in real time to the user was outside the scope of what anything but Java could do. And while I could go into every case of techno necromancy I’ve ever done, the iDrac 6 and earlier, the HP ILo, and the management controllers on most SuperMicro machines are all Java. And all can be made to work on a modern machine. So that’s what I’m talking about here.

Step Zero: Install Java and figure out where the hell your java_home is.

Sun Recently changed their license for Java, saying that it was free for personal and development use, but that commercial or professional use requires a purchased license. Just for the sake of argument, I tried looking up the price, but Oracle’s store was down for maintenance for several days. Perfect. Download the latest one for your OS, in whatever way makes you happy.

Every other guide out there will talk about %JAVA_HOME% or $JAVA_HOME or the like is, but not tell you where to find it. It changes based on both your OS version and your Java version. Lots of programs helpfully say to check env or whatnot, but I’ve never found it populated. Typing java -version won’t tell you either, but this command will spew out a bunch of info about your Java install, and java.home will be in there. (I’ve edited it slightly to make it fit):

java -XshowSettings:properties -versionjava -XshowSettings:properties -version 2>&1|grep java.home

On my Mac, I added a “grep” command to make it neater. This might work on Linux, probably not on Windows.

Here’s what it looks like on my Mac. You’re going to need to muck around under here. (Medium wouldn’t format it right).

Step One: Find Java’s list of disallowed ciphers, and rip it out.

Part of launching a JNLP is downloading more code (as a .jar file) from the server and running it. The problem here is even if you tell Java to trust the cert, it will fail to connect with a mysterious “unable to access resource” error, because the SSL/TLS connection won’t work. We need to set Java’s security expectations back to the point where SSLv3 is still acceptable and an RSA1024 key with an MD4 signature on it is just fine.

You may need root access for this. This voids your warranty. I am doing this assuming you know where you’re connecting to and this is your ONLY use for Java.

Somewhere under java_home (see above) you have a java.security file, and it has helpful lines like this, to try and keep you safe (these are screenshots, Medium’s formatting butchered it):

or:

or:

Comment these out. Add a # to the beginning of each line here. If they are multi-line, add a # to the beginning of every line.

(Optional) Step Two: Keep Java’s Certs-checker Happy

There are two kinds of public keys involved in Java apps — the key used to sign the .jar file (often, not replaceable at all), and the key used to sign the SSL session. You’d think since it’s an SSL session, that Java would just use the certs baked into your system’s Keychain, right? You’d be wrong.

Since at the day job we have a central CA that signs all our SSL certs with long lifetimes, I managed to import our iDrac root cert into the Java trust store. (Cribbed from this page). It’s not a perfect answer, as Java will still complain about not being able to check cert revocation — but we’re running in Circa 2002 mode, where all browsers came with CRLs, but never checked them. Well, they came with a build-time CRL check, but not much else. (That said, our tiny little perl-script-based CA doesn’t even produce a CRL, and nobody makes a good free open-source OCSP responder).

To do that, you need your root cert, the location of Java’s cacerts file (same path as the java.security file on my machine), and this command:

sudo keytool -import -alias dayjob-idrac -keystore ./cacerts -file ~/Desktop/iDRACCA2.pem

Where “alias” is just any name, and the cacerts file is the one I mentioned.

This command will prompt you for a password for the java.security store —the default is: changeit (and I’m quite sure that nobody ever does).

You *can* also in theory import this via the Java control panel (It asks, bizarrely, for .p12 files or .csr files), but the user-control panel cannot import to the system store.

You still need to tell Java to not try to check cert revocation in the preferences pane. (I attempted to figure out a way to do it with OSX’s defaults command, but the data structures are a bit weird for a one-liner. Using the stupid prefs UI is safer.)

Obviously, I’m telling you to turn off yet more security checks. You are a sysadmin. You want this thing to work, especially after multiple reboots and multiple attempts to call the datacenter staff and make sure the thing is still running while your users are complaining that it’s down.

You’ll notice here that there’s a few options to enable older SSL types. That said, I don’t seem to have any problem connecting to them because I think our overrides to the “master” java.security file causes us to not need to apply further tweaks here.

(Optional) Step Three: The Java site Exception List

Back in the day, Java had a security slider that you could set: “Low, Medium, High, and Very High”. Now, it can only be set to High or Very High. And while I get that this makes sense from an Infosec point of view as well as a marketing POV (“we don’t want people to think our product is insecure”), it’s as dumb as the fast food places that only have sizes medium and large — or the coffee place that calls their smallest drink Tall. It’s optics.

Even with all this SSL trickery we’re doing, some sites do worse things, where the Site Exception List is required. Here’s Oracle’s List of things that it overrides —.jar files missing permissions atributes and the like.

The ONE place you can now say “here, please just let this work, a developer did something stupid 10 years ago” is the exception site list. In the normal world, you have to manually enter things into this, in the Java control panel, by URL

You can’t paste. You can’t put in something like http(s)?, and you can’t put in whole netblocks like 10.0.0.0/24 or *.myjob.com. No globs. No wildcards. No CIDR. No host resolutions.

If a site might do both HTTP and HTTPS, you need to enter both. If you have a site that you sometimes connect to via IP and sometimes via hostname, you need both of those. So potentially, that’s four lines *per system*.

The trick however, is while normally, you’d have to enter these one by one, and get warnings like the one above, there’s a workaround. Unlike some of the other overrides, the Java exception list is just a plain text file, that you could perhaps generate with a perl script, or distribute to your coworkers.

On my Mac, it’s located in:

~/Library/Application Support/Oracle/Java/Deployment/security/exception.sites

But if you cd ~Library/Application\ Support, and then do a find . | grep exception.sitesyou should find it pretty easily. Unlike the system defaults you’ve edited earlier, these are user prefs, so they’ll be in your homedir and you don’t need root access to edit them.

If you can’t find it, add an entry via the control panel first to make sure it exists. Feel free to add an entry or two with your favorite text editor, and then see if they show up in the Java control panel. They did for me, but all of this is at your own risk. If that works, then you could in theory write a script to manage/populate those exceptions, or distribute it to your team via git.

(Optional) Step Four: Dealing with MacOS Gatekeeper

Gatekeeper is a MacOS feature that you might know about but maybe not by that name. It‘s controlled by this bit of the Security and Privacy preferences pane:

In older versions of MacOS, there was a third option: Anywhere. That option doesn’t exist anymore, and while it *might* be possible to override it (here’s a way to restore the “open from anywhere” option.)

When you click a .jnlp file, your mac sees that file as new app to ask about. Anyone that’s used a remote console, however, knows that your auth credentials are baked in to that jnlp so they are effectively one-time-use files.

(Yes, I would love a single .jnlp that gave you a terminal app that could log in to any iDrac6 — it doesn’t exist).

So you have this dance that goes “iDrac hands you a .jnlp file” →”open your downloads folder” →“attempt to open the jnlp” → “get a warning from the OS” → “visit the Security control panel and say ‘open anyway’” → “click YES I’M SURE”…

Try this sometime when you’re trying to manage upgrades on a dozen machines. You’ll go crazy.

Here’s my solution:

.jnlp files are Java Web Start files. You can open them from the command line without having to muck with gatekeeper at all. You can completely sidestep finder and gatekeeper if you’re comfortable in a terminal.

So, if you cd to your ~/downloads folder, you can just pump a script that says:

ls -trc | tail -1 | xargs javaws

And it will always open the last modified file with Java Web Start. If you have a shell with history, you can just hit the up-arrow and do it again. Or add a shell alias.

Step Five: Upgrade your stuff.

Remember that in order to do everything we’ve talked about above, we’ve lowered the security bar. The Ciphers and Key Strengths you’re telling Java it’s okay to use may already have been broken. In our case, we also have VPNs and IP-based ACL’s in place that help with this in a belt-and-suspenders approach, and we trust our transit providers, but this is not a forever answer.

The stuff in this article is Duct Tape. Upgrading is the One True Answer, but that’s often frought with Layer 8 and Layer 9 problems, justifying to management that you need the new server just so you can get a stable console on the 0.01 percent use case can be a hard sell to anyone.

That said, if you ever find yourself managing a server that was hand-deployed by the elders of the internet (they know who I am!) on a handshake deal in a datacenter halfway around the world with i386-based technology that’s been dutifully doing its job since the George W. Bush Administration, maybe this can help you, too.

--

--

Gushi
Gushi

Written by Gushi

Gushi/Dan Mahoney is a sysadmin/network operator in Northern Washington, working for a global non-profit, as well as individually.

No responses yet