0

I'm trying to connect to my Mongo CosmosDB instance through Azure Bastion. Our IT department blocks all outbound traffic thats not on port 443 so in order for me to be able to access anything I have to tunnel it through port 443 first.

I have a bit of script that looks like this:

  COSMOS_ID=$(az cosmosdb list --resource-group $RES_NAME | jq -r '.[] | .id')
  az network bastion tunnel \
    --resource-group $RES_NAME \
    --name $RES_NAME \
    --target-resource-id $COSMOS_ID \
    --resource-port 10255 \
    --port 10255 \
    --debug

Which emits this output:

Opening tunnel on port: 10255
Tunnel is ready, connect on port 10255
Ctrl + C to close

I'm then using mongo compass and the connection string found in the azure portal, replacing the cosmosdb host name with localhost, immediately upon attempting to connect I see this error in the terminal, and the tunnel process exits:

Exception in thread Thread-1 (_start_tunnel):
Traceback (most recent call last):
  File "/usr/local/Cellar/python@3.10/3.10.4/Frameworks/Python.framework/Versions/3.10/lib/python3.10/threading.py", line 1009, in _bootstrap_inner
    self.run()
  File "/usr/local/Cellar/python@3.10/3.10.4/Frameworks/Python.framework/Versions/3.10/lib/python3.10/threading.py", line 946, in run
    self._target(*self._args, **self._kwargs)
  File "/usr/local/Cellar/azure-cli/2.37.0/libexec/lib/python3.10/site-packages/azure/cli/command_modules/network/custom.py", line 8482, in _start_tunnel
    tunnel_server.start_server()
  File "/usr/local/Cellar/azure-cli/2.37.0/libexec/lib/python3.10/site-packages/azure/cli/command_modules/network/tunnel.py", line 184, in start_server
    self._listen()
  File "/usr/local/Cellar/azure-cli/2.37.0/libexec/lib/python3.10/site-packages/azure/cli/command_modules/network/tunnel.py", line 117, in _listen
    auth_token = self._get_auth_token()
  File "/usr/local/Cellar/azure-cli/2.37.0/libexec/lib/python3.10/site-packages/azure/cli/command_modules/network/tunnel.py", line 104, in _get_auth_token
    raise exp
msrestazure.azure_exceptions.CloudError: Unexpected internal error

If I enable debug logging I get a lot of output but these are the last 3 lines before the exception:

urllib3.connectionpool: Starting new HTTPS connection (1): bst-210816cd-d967-41ee-8f90-31ee6af4574d.bastion.azure.com:443
urllib3.connectionpool: https://bst-210816cd-d967-41ee-8f90-31ee6af4574d.bastion.azure.com:443 "POST /api/tokens HTTP/1.1" 500 None
msrest.exceptions: Unexpected internal error

I have added the bastion subnet to cosmosdb's firewall and I have added the port to the NSG... I think. The problem I'm having is just not knowing if I misconfigured something or if this is just completely not supported.

Should I be able to just tunnel directly to cosmos? If not then why not, or what other solutions would be available for me to connect to cosmos tunneled through port 443?

justin.m.chase
  • 13,061
  • 8
  • 52
  • 100
  • I don't see a mention of this, but did you add a private endpoint to that cosmosDB also? Might be worth looking into? I have noe xperience with Azure Bastion, but if what I read here: https://learn.microsoft.com/en-us/azure/bastion/connect-ip-address is correct, pretty much anything accessible from the VNET the bastion is deployed on would work. Maybe connecting on IP instead of ID works better? Unfortunatly the 500 error doesn't help much. – Marco Aug 30 '22 at 05:39
  • It gives me an error saying "The AzureBastionSubnet is restricted and cannot be used with a private endpoint". – justin.m.chase Aug 30 '22 at 13:18

2 Answers2

2

As I found this question when searching for a solution having the same problem, and after some fiddling, The answer is, yes you can!

It took some experimenting but it works with 2 tunnels. Connect to the bastion host (which is also a VM) with enabling an ssh-tunnel to itself to connect via another more sophisticate ssh client and then use this ssh client to "lay" the tunnel to the DB:

  • You need ssh capability on the bastion host which you should already have if you can connect via az network bastion ssh
  • maybe put your pub ssh-key to ~/.ssh/authorized_keys (with the usual restricted directory and file permissions) to enable pwd less auth
  • login via:

az network bastion tunnel --name $the_bastion_host_name --resource-group $your_resource_group --target-resource-id /subscriptions/$your_subscription_id/resourceGroups/$the_resource_group_name/providers/Microsoft.Compute/virtualMachines/$the_jumphost_resource_name --resource-port "22" --port "2222"

  • replace the vars accordingly to your setup, subscription and resource names
  • the last command should connect to your bastion/jump host and also open a tunnel @port 2222@localhost to connect via another ssh client!
  • keep this running/open
  • have your (cosmos) db connection string ready (from azure portal)
  • login via standard ssh client (or adjust using putty or similar):

ssh -L 20255:$your_db_name.mongo.cosmos.azure.com:10255 -p 2222 the_bastion_host_account_name@localhost

  • so we connect via ssh on port 2222 at localhost (which is actually sshd at the bastion host by the command before) with our bastion host username (+credentials) and open the local port 20255 to be tunneled by bastion host's sshd to the (cosmos) db instance's Port 10255 in the remote vnet
  • can use other local ports by changing the 1st port after the -L but adjust the connection string in the next step
  • adjust according to your db-name/host and Port (which should be 10255 default)
  • have the db connection string handy (again)
  • now use your local client to connect to: mongodb://azure_dbname:leaveTheBase64CodedCredentialsfromAzurePortalHere==@localhost:10255/?ssl=true&replicaSet=globaldb&retrywrites=false&maxIdleTimeMS=120000&appName=@db_app_name_from_azure_portal@
  • in nosql-booster I had to deselect replicaset and use "single server" even if "replicaSet=global" in the azure portal db connection string. But the connection initiation failed with some protocol errors when using replica-set setup
A. Furtner
  • 21
  • 3
  • I see... that is actually pretty close to what I ended up doing. I created a pod in my kubernetes cluster that is simply running a socks 5 proxy. I then use `kubectl port-forward ...` to open ports on my localhost but theoretically if I were to just run that same socks5 proxy on a VM then I could use bastion, it would be very similar to that. Thanks. – justin.m.chase Jan 09 '23 at 19:00
0

The answer is no, you can't. It only works with VMs.

The solution I came up with is to essentially create a VM, run sockd on it, use bastion to establish the port forwarding, then configure your local client to use a socks5 proxy to localhost.

justin.m.chase
  • 13,061
  • 8
  • 52
  • 100