Azure – Configure Windows 10 VM as SSH Server for Reverse Tunneling

azuresshwindows 10

Purpose:
Expose web apps running on local machine to the outside world using reverse tunneling (ngrok like service).

I have a Windows 10 Pro VM running on Azure. I've installed OpenSSH server there and I've tested it by using local port forwarding and dynamic port forwarding (socks proxy). Both work fine.

But I don't seem to get the reverse tunneling working.

This is the command I'm using on my local machine:

ssh -R 5002:localhost:5002 xx.xx.xx.xxx

Where,
xx.xx.xx.xxx is the public IP of the Win10 VM on Azure.
5002 is the port where my web app is running on my local machine and I also want to keep the same port for the Azure VM.

The above command prompts me for entering the password and upon entering it, it shows the following prompt on the terminal, which probably indicates that connection was successful.

me@VMW10Pro C:\Users\me>

But when I try to access my locally running web app like the following, nothing happens:

https://xx.xx.xx.xxx:5002/myapp

I also tried, with no luck:

http://xx.xx.xx.xxx:5002/myapp

Here's how I configured the inbound port rules for the Azure VM:
enter image description here

And here's how the outbound port rules look like. I've even allowed all ports temporarily.
enter image description here

And this is the sshd_config file on the Azure VM. The only change I made was setting GatewayPorts to yes:

# This is the sshd server system-wide configuration file.  See
# sshd_config(5) for more information.

# The strategy used for options in the default sshd_config shipped with
# OpenSSH is to specify options with their default value where
# possible, but leave them commented.  Uncommented options override the
# default value.

#Port 22
#AddressFamily any
#ListenAddress 0.0.0.0
#ListenAddress ::

#HostKey __PROGRAMDATA__/ssh/ssh_host_rsa_key
#HostKey __PROGRAMDATA__/ssh/ssh_host_dsa_key
#HostKey __PROGRAMDATA__/ssh/ssh_host_ecdsa_key
#HostKey __PROGRAMDATA__/ssh/ssh_host_ed25519_key

# Ciphers and keying
#RekeyLimit default none

# Logging
#SyslogFacility AUTH
#LogLevel INFO

# Authentication:

#LoginGraceTime 2m
#PermitRootLogin prohibit-password
#StrictModes yes
#MaxAuthTries 6
#MaxSessions 10

#PubkeyAuthentication yes

# The default is to check both .ssh/authorized_keys and .ssh/authorized_keys2
# but this is overridden so installations will only check .ssh/authorized_keys
AuthorizedKeysFile  .ssh/authorized_keys

#AuthorizedPrincipalsFile none

# For this to work you will also need host keys in %programData%/ssh/ssh_known_hosts
#HostbasedAuthentication no
# Change to yes if you don't trust ~/.ssh/known_hosts for
# HostbasedAuthentication
#IgnoreUserKnownHosts no
# Don't read the user's ~/.rhosts and ~/.shosts files
#IgnoreRhosts yes

# To disable tunneled clear text passwords, change to no here!
#PasswordAuthentication yes
#PermitEmptyPasswords no

#AllowAgentForwarding yes
#AllowTcpForwarding yes
GatewayPorts yes
#PermitTTY yes
#PrintMotd yes
#PrintLastLog yes
#TCPKeepAlive yes
#UseLogin no
#PermitUserEnvironment no
#ClientAliveInterval 0
#ClientAliveCountMax 3
#UseDNS no
#PidFile /var/run/sshd.pid
#MaxStartups 10:30:100
#PermitTunnel no
#ChrootDirectory none
#VersionAddendum none

# no default banner path
#Banner none

# override default of no subsystems
Subsystem   sftp    sftp-server.exe

# Example of overriding settings on a per-user basis
#Match User anoncvs
#   AllowTcpForwarding no
#   PermitTTY no
#   ForceCommand cvs server

Match Group administrators
       AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys

The sshd_config file on my local machine also looks the same as above with GatewayPorts set to yes.

Please note: I'm no expert with networking stuff. There are other tutorials and how-tos available on doing the same with Linux VMs. But I just want to make use of the existing Windows VM.

Any help would be much appreciated.

Best Answer

I've figured out the solution. It was two-fold:

  1. I used ssh -R '*:5002:localhost:5002' xx.xx.xx.xxx instead of ssh -R 5002:localhost:5002 xx.xx.xx.xxx. The asterisk makes sshd to listen to port 5002 on all interfaces. Otherwise it would just listen on the loopback interface.
  2. I also had to allow port 5002 in the Windows Defender Firewall of the Azure Win10 VM.

And that made it work. I can now access my web app running locally on port 5002 over the internet by accessing it using the Azure VM public IP: https://xx.xx.xx.xxx:5002/myapp

Note: I enabled IP Forwarding on both the network interface (Azure) and in the VM OS following the suggestion by John Hanley in the comments above. But after applying the two steps mentioned above, I disabled IP Forwarding to see if it still worked and it did.