Remote virtual machine access using port forwarding and SSH private/public keys

Virtualization technology allows us to create multiple virtual machines (VMs) on the same physical machine. 

  A virtual machine operates like a software program running on a computer, simulating the behavior of an independent machine.  

In essence, it establishes a computer within another computer.  

When operating within a window on the host computer, a virtual machine offers users an experience that’s nearly identical to using a separate computer. 

For many software developers, using a virtual machine is preferable for easy cross-platform compatibility purposes; they also offer greater security, flexibility, and scalability.  

When setting up your virtual machine, you can access its graphic user interface (GUI) to interact with the virtual machine separately from the other machine(s) or operating systems on your physical computer.  

However, relying solely on the GUI may not always be practical if you’re a software developer, especially if you need to access a VM remotely.  

In such cases, you should use the Secure Shell protocol (SSH) to execute remote logins or commands securely over an unsecured network.  

Parallels Desktop enables remote access to virtual machines with SSH and port forwarding. 

By default, Parallels Desktop operates in shared network mode, which works “out of the box” and does not require any specific configuration.  

Parallels Desktop will work as a virtual router for your virtual machines when you use this networking mode. However, it also means that the VMs cannot be accessed from external computers. 

  The port forwarding (also known as port mapping) functionality allows computers on your local network and the Internet to connect to any virtual machines that use the shared networking mode.  

According to the port-forwarding rule, the connection to a specific port on your Mac will be redirected to a specific port of your virtual machine. 

 To gain remote access to a VM via port forwarding, you must first configure Parallels Desktop to accept the connection using a port forwarding rule.  

This is achieved by following the process outlined below. 

Establishing port forwarding rules 

Note: Port forwarding is only available in Parallels Desktop for Mac Pro and Parallels Desktop Business Edition. 

1. Open the Parallels Desktop Command Center 

2. Select the VM you want to access remotely  

Then, click the Configure button. 

3. Once the Configuration window opens, select the Hardware tab 

Then the Network option on the left side, then click “Advanced.” 

4. Click on the “Open Networking Preferences” button 

5. Click the Add (+) button below the Port forwarding rules list 

6. In the displayed window, perform the following actions 

  7. Click OK to add the rule 

Checking port forwarding 

To check that the rule works properly, enable, e.g., SSH on your virtual machine (some Linux distributions have it enabled by default). 

As an example for SSH, use the following rule: 

Protocol  TCP 
Source Port Choose a different port number between 1024 to 49151 for each VM 
Forward to Choose your virtual machine 
Destination Port 22 

To make sure that port forwarding is enabled from your Mac inside a virtual machine, use one of the following scenarios (in these examples, port 8081 is redirected to a Linux VM, and port 8888 is to a Windows VM) : 
 

Scenario 1: connect from the same Mac 

 
In Terminal, type in the following command and press Enter: 

ssh -l <your_VM_username> -p <source_port> 127.0.0.1 

Enter the password for the user in the virtual machine and press Enter: 

Scenario 2: connect from another Mac or PC in the same network 

In Terminal (on Mac) or PowerShell (on Windows), type in the following command and press Enter: 

ssh -l <your_VM_username> -p <source_port> <host_machine_IP_address> 

Enter the password for the user in the virtual machine and press Enter. 

To check that you logged into the virtual machine, execute the following command in Terminal

uname -a 

If you successfully log into the virtual machine, you will see a Linux kernel version. 

The same method can also be used to set up an SSH port forward for a Windows machine by adding that to the port forwarding list: 

You can run a “systeminfo” command to verify the system you are on. 

Using SSH key pairs 

Now we have the systems tested and working using password authentication, we can make them more secure.   

SSH public/private keypairs offer a more secure, convenient, and scalable authentication mechanism than traditional password-based methods.  

By leveraging SSH keypairs, organizations can strengthen their security posture and ensure secure remote access to their systems, eliminating the need to transmit passwords over the network.  

With keypairs, the private key remains securely stored on the user’s computer.  

In contrast, the public key is stored on the server, significantly reducing the risk of interception by malicious actors.  

Because the keypairs are generated using cryptographic solid algorithms, they are much longer than passwords, making them highly resistant to brute force attacks. 

Once SSH keypairs are set up, users can seamlessly log in to SSH-enabled systems without entering a password, adding convenience for automated processes and scripts. 

Generating SSH public/private keys 

The SSH key pair consists of two cryptographic keys: public and private keys.  

These keys are mathematically related but are designed so that it is computationally infeasible to derive the private key from the public key. 

The public key is shared securely with the server or system you want to access.  

It can be freely distributed and stored on several servers or systems and is provided when you attempt to connect to a server. 

The private key is kept securely on your local computer or device. It should never be shared with anyone else.  

This key is used to decrypt encrypted messages with the corresponding public key, and when you attempt to connect to a server, your local SSH client uses your private key to prove your identity. 

When you attempt to connect to a server using SSH, the server sends a message encrypted with your public key.  

Your SSH client decrypts this message using your private key and sends back a response.  

If the server can successfully decrypt your response using your public key, it knows you possess the corresponding private key, allowing you to access the system. 

SSH keypairs are typically generated using cryptographic algorithms such as RSA or DSA.  

Your local SSH client software can generate these keys for you. The keys are often stored in files (e.g., “id_rsa” for the private key and `id_rsa.pub` for the public key) in a hidden .ssh directory in your user’s home directory. 

Creating SSH keypairs 

To explain how to generate and use the SSH keypairs, I have three systems: a Mac, which is my local machine; an Ubuntu VM, which will be the remote machine; and a Mac VM, which will use the port forwarding rules.  

Each system has a different theme for the terminal windows to make it easier to follow. 

First, I will check my local machine to ensure no local keys exist, using the command: 

ls ~/.ssh/id_* 

As no matches were found, no keys were present on our local machine. If they are present, you should back them up in case they are accidentally removed or lost. 

Next, we can generate our SSH key on the local machine.  

To do this, type in the command:  

ssh-keygen 

The command replies that it is generating a public/private keypair using rsa as the default encryption.  

If you wish to use a different algorithm you can use the -t flag to select from the following alternatives: dsa, ecdsa, ecdsa-sk, ed25519, ed25519-sk.  

I will also add a comment using the -C flag so that I can quickly identify what the key is for.  

My command line would look like this:  

ssh-keygen -C "Test for SSH Keys on Mac & Ubuntu" 

By default, the file is saved in my user directory in the .ssh folder, so I hit enter to accept that.  

I also hit enter for the passphrase question, which adds an extra layer of security but also means I would have to enter it each time I connect. I am trying to avoid that in this example. 

Retrieving the public key 

If we rerun the ls command, we can see two files in the .ssh directory: the private and public keys. 

Move into the .ssh directory, open the contents of the public file, and copy them so that we can add them to the remote machine in a file called authorized_keys. 

cd .ssh 

ls -la 

cat id_rsa.pub 

Adding the public key to the remote machine 

To enable SSH access to a remote machine, you must upload the public key from your SSH key pair onto the remote server. This allows the remote machine to decrypt connections initiated by your local computer, which uses its corresponding private key for encryption. 

On the remote machine, go to your home directory and check if the .ssh subdirectory exists: 

cd ~ 
ls -al ~ 

If it does exist cd into that directory, and if it doesn’t, create the subdirectory, and then go into it and check to see if the authorized_keys file exists:  

mkdir .ssh 
cd .ssh 
ls -al 

If the authorized_keys file does not exist, create one using the following command:  

touch authorized_keys 

Then edit the file using your editor of choice to add the public key copied from the local machine. 

If you already have an authorized_keys file in the directory with content, add your new key on a new line and save the file. 

Putting it all together 

Now that our private and public keys are created, we need to check that they work.  

Check the IP address of your virtual machine from the Parallels devices-> networking tab 

Now ssh into that system from your local host that has the private key installed on it: 

ssh <user>@<ip address> 

And as you can see, we are logged in without providing a password. 

As we have set up port forwarding on our local host, we should also be able to access the Ubuntu VM from a different system, but going through the host machine and using the port that was assigned at the beginning of this article, that being 8081 of the Mac system. 

If I go to my Mac VM running on the same host, I can copy a key to the Ubuntu box, but this time, instead of cut/paste, I will use the ssh-copy-id command to add to my authorized_keys file on the Ubuntu system, but using port 8081 of my host system: 

ssh-copy-id -p <port> <user>@<ip address> 

We can check the key was correctly added by going back to the Ubuntu VM, and checking the authorized_keys file:

 

The text highlighted in red is the new key from the Mac on the VM. If we return to that VM, we can execute the ssh command displayed at the end of the ssh-copy-id command message to access the Ubuntu VM system from my Mac’s VM system via my host Mac: 

And as you can see from the command prompt at the end, I am back on the Ubuntu System. 

Ready to try it yourself? Sign up now for a free 14-day trial to see how easy it is to implement port forwarding and secure key pairs using Parallels Desktop Pro.