If you ever want to connect to a virtual machine in Azure from a corporate network and you don’t have a dedicated line or dedicated IP, you’ll likely run into issues. You’ll be behind a corporate proxy and won’t be able to get out easily, nor can you expect anyone to allow you access to all SSH or RDP ports on the external network.

When I was dealing with this, I considered how to approach it. One option is to connect to a Linux server via the serial port (which you can use if you click on “Connect” in Azure and then select more options). However, the serial port has two problems: first, you can’t transfer files (although theoretically, you could insert BASE64 encoded text), and second, the whole console behaves a bit oddly—for example, when you press the up arrow in the console to view previous commands, everything gets a bit messed up. So, this isn’t an optimal solution.

The second option is to use the Azure Portal CLI. I’m talking about the CLI that’s available directly on the portal web pages. If you open it and, for example, run curl ifconfig.me or curl api.ipify.org, you should get your IP address, which you can then whitelist in the NSG (Network Security Group) and connect directly from the portal. The environment is a bit more comfortable, but for me, it would disconnect and log me out after five minutes, and after reconnecting, the public IP would change, so I had to allow it again—so this also isn’t an optimal solution. Not to mention, the web console is problematic when copying, highlighting, or pasting text; a local terminal emulator is simply better.

The last option I tried, and probably the best, is to connect from your own terminal. I considered using the az ssh vm command, but it didn’t work for me behind a proxy server. When I used the --debug switch, I understood why: it doesn’t use websockets (as I would expect, since that’s the behavior with AWS), but instead uses the local ssh client with a direct connection. See below.

cli.azext_ssh.ssh_utils: Running ssh command C:\WINDOWS\System32\openSSH\ssh.exe xxx.xxx.xxx.xxx -l user -i C:\Users\xxx\xxx\id_rsa -o CertificateFile="C:\xxxx\xxx\id_rsa.pub-aadcert.pub" -vvv

So, that’s not the way either. The last option (and definitely not free) is to use a Bastion host, which you can create with the click of a button. Since 2022, Bastion supports a handy feature called native client.

Native Client

This allows you to connect quite easily even with a proxy (when you have the appropriate environment variables set, like HTTP_PROXY and HTTPS_PROXY) and tunnel the connection over websockets. So, in Windows Terminal and Azure CLI, you just need to enter this command, and you have a full-featured console even behind a firewall. You can get the machine’s Resource ID by displaying its JSON; I couldn’t find it directly in the console, but on the portal, you can extract the JSON quite easily.

az network bastion ssh --name "bastion" --resource-group "rg" --target-resource-id "/subscriptions/.../virtualMachines/..." --auth-type AAD

Bastion Settings

Of course, you can also use tunnel mode to tunnel SSH, RDP, or another port, and use your own SSH client.

This solution (although it requires payment for Bastion) seems to me personally the most elegant and convenient for connecting to machines when you’re behind a proxy.