This tutorial is designed to set up the JetBrains IDEs, running on Windows, to have a good connection to the NASA NAS servers. It should be largely applicable to other IDEs as well. In this setup, we create an SSH configuration that pipes SSH traffic through the Windows Subsystem for Linux (WSL) SSH client, but makes that configuration envokable from the regular Windows SSH client.
If you just want it to work but don’t care why we need to do something special to get it to work, you can skip this section.
NAS uses a non-standard gateway server SSH command. That is, for the Secure Front End server (sfe) that you need to jump through to get to other NAS servers, NAS chose to make their own special commands that must be used on that intermediate jump server, rather than using existing, standard SSH jump commands. During this non-standard command, input is also requested from the user (they are prompted for an RSA OTP).
JetBrains uses SSHJ, an programmatic SSH library, internally for its SSH connections. Due to the non-standard NAS SSH jump server commands, the SSH connection requires a shell command. This results in us dropping out of SSHJ and calling the default SSH client on the system. SSHJ is designed to give programmatic access to SSH, not to provide arbitrary access to shell interfaces. So, to allow the RSA OTP password prompt to be visible to the user, we need to tell the default system SSH client to provide this prompt via a separate method. OpenSSH (the default SSH client on most systems), allows for the setting of an arbitrary program that will be called in the event that a user prompt is required. This “askpass” program is usually just a small GUI prompt popup program.
On macOS and Linux, just setting this askpass program during the special intermediate server command would be sufficient. Unfortunately, Windows’ default SSH client causes additional issues in this case. The Windows OpenSSH client, contrary to other OpenSSH clients, does not provide multiplexing support. Multiplexing support allows a single connection to be made to an SSH host, and then multiple virtual connections can be established through that one real connection. JetBrains takes advantage of this to open several virtual connections in the background while doing various tasks. Even on Windows, this isn’t normally a problem, because SSHJ provides its own multiplexing. However, because NAS uses a non-standard command, we switch from SSHJ to the system SSH client. Without multiplexing, this results in a huge number of RSA OTP prompts.
The workaround used here is to take advantage of the WSL SSH client. Since this is running the Linux version of OpenSSH, it does have multiplexing. So in this tutorial, we will make sure the WSL SSH client is setup properly to with an askpass program, then create a wrapper that the default Windows SSH client can use to direct traffic through that WSL client.
If NAS switches to standard SSH jump client commands, no special configuration of any sort is needed (as everything would stay within SSHJ). If the Windows version of OpenSSH implements multiplexing, the simpler workaround used on macOS and Linux can be used (which is just adding an askpass program). However, the combination of these requires a the more complex workaround here. That said, it’s not terribly complex and works nicely once set up.
You’ll need a distro installed for WSL. This tutorial will use Ubuntu, but most distros should be fine. You can list installed distros using
wsl --list
To install Ubuntu, use
wsl --install Ubuntu
The rest of the tutorial assumes you are working in your default WSL instance. You can adjust this to work in a secondary WSL if needed.
We’re about to edit your OpenSSH config file (usually stored at ~/.ssh/config). It’s a good idea to make a backup of this file first in case something goes wrong. I usually copy it and append the date (e.g., ~/.ssh/config_yyyy_mm_dd).
This assumes you have already completed the NAS SSH passthrough tutorial, and therefore have already added your SSH public key to the NAS servers.
Within your WSL instance, you’ll need to have a ~/.ssh (keep in mind, this is the one within your Linux home directory, not the Windows home directory). This may have been created previously. Here, we’ll setup pfe to have the required configuration, but other NAS front-ends are similar. In your ~/.ssh/config file, add
Host sfe
User golmsche
ForwardAgent yes
Hostname sfe6.nas.nasa.gov
IdentityFile ~/.ssh/nasa_nas
Host sfe sfe?.nas.nasa.gov
ControlMaster auto
ControlPath ~/.ssh/master-%r@sfe:%p
ControlPersist 1
ServerAliveInterval 5m
User golmsche
ForwardAgent yes
Hostname sfe6.nas.nasa.gov
IdentityFile ~/.ssh/nasa_nas
Host sfe sfe?.nas.nasa.gov sup*.nas.nasa.gov
LogLevel info
ProxyCommand none
Host pfe pfe-last pfe.nas.nasa.gov pfe-last.nas.nasa.gov
User golmsche
HostKeyAlias pfe20.nas.nasa.gov
Port 29810
ForwardAgent yes
IdentityFile ~/.ssh/nasa_nas
ProxyCommand /usr/bin/env SSH_ASKPASS_REQUIRE=force SSH_ASKPASS=/home/golmschenk/.ssh/askpass_error_on_cancel_wrapper.sh ssh -a -oCompression=no sfe ssh-balance %h
You will need to replace golmsche with your NAS username, golmschenk with your WSL username, and nasa_nas with the name of your NAS private SSH key file. Notably, in this configuration, we are always passing the key agents along with the key files, and we are adding the ASKPASS environment variables during the ProxyCommand.
In the above configuration, we reference an askpass script that should be called. Create that script at ~/.ssh/askpass_error_on_cancel_wrapper.sh, and inside it put
#!/bin/bash
result=$(ssh-askpass "$@")
if [ $? -ne 0 ] || [ -z "$result" ]; then
exit 1
fi
echo "$result"
This script still expects ssh-askpass to be installed. On Ubuntu, you can install that with
sudo apt update
sudo apt install ssh-askpass ssh-askpass-gnome
You’ll also need your NAS SSH key to be in ~/.ssh (probably duplicated from your Windows .ssh directory).
Lastly, make sure all the file permissions are correct. The ~/.ssh/askpass_error_on_cancel_wrapper.sh script needs to be excutable (if needed, run chmod +x on it). And the .ssh directory and it’s contents need to follow standard SSH file permissions.
JetBrains will be using the Windows SSH configuration file. So we still need a small wrapper on the Windows side to tell that SSH configuration to use the WSL configuration. This is relatively simple though. In your Windows .ssh/config file add
Host pfe_through_wsl
Hostname localhost
User golmsche
IdentityFile ~/.ssh/nasa_nas
ForwardAgent yes
Port 22
HostKeyAlias pfe20.nas.nasa.gov
ProxyCommand wsl ssh -W localhost:22 pfe
Again, replace golmsche with your NAS username and nasa_nas with the name of your NAS private SSH key file. Again, you need the private key file to exist in both the Windows and WSL .ssh directories. This host uses the WSL configuration to connect all the way to PFE. Then, the Windows SSH client just treats that existing connection as being on the localhost. We still need the credentials in the Windows SSH configuration, because ProxyCommand only creates a transport layer through WSL, while still SSH protocol running through the Windows SSH client.
Your connection should now be set up. As a quick test, from a new Windows terminal, you should be able to use ssh pfe_through_wsl. You should get a single RSA OTP prompt. While that connection is open, if you open another terminal and again connect with ssh pfe_through_wsl, it should connect without asking for another RSA OTP.
Similarly, you can now use the pfe_through_wsl host as your target host for the JetBrains IDEs. If no existing connection is open, it will ask for the RSA OTP a single time. JetBrains will hold open the connection, and any other connections through the IDE will not require another RSA OTP.