Recommendations for Azure Bastion shareable links

Azure Bastion just got a new feature in preview called “Shareable Links”. Without this feature, in order to grant a user access to use Azure Bastion to connect to a virtual machine, you will need to delegate reader access in Azure. At minimum you’ll need “reader” on the bastion host itself, on the virtual network connected to the VM and the VM itself.

While these permissions are not “scare”, it leaves you with permissions to handle somehow. The new sharable links feature, however, eliminates this by allowing you to create – well – a link that you can share that directly allows a user to connect to a VM using Azure Bastion.

The user will be sent directly to a view like below, typing a username and password, and they are in.

This is super neat, and also super single factor! I’m not saying don’t use this, as this absolutely has its use cases, but it can be wise to at least do one of the following: Deny use or Audit use.

Why? Well, any user that has contributor access to an Azure bastion host, can essentially plant a permanent backdoor into your systems, by generating a shareable link. They will still require a username and password to sign into the server, of course.

As you can see, a url will be generated per virtual machine.

Let’s start with the Deny method. The following Azure Policy denies the use of the feature completely on the Azure Bastion Host side, now allowing the enablement of the feature:

{
  "mode": "All",
  "policyRule": {
    "if": {
		"allOf": [{
            "field": "type",
            "equals": "Microsoft.Network/bastionHosts"
          },
          {
            "field": "Microsoft.Network/bastionHosts/enableShareableLink",
            "equals": "true"
          }
        ]
    },
    "then": {
      "effect": "deny"
    }
  },
  "parameters": {
  }
}

And for the audit? Well, you can easily change the effect above to “audit”, however, that will only allow you to audit the enablement of the feature on the bastion host level.

What I would really like is to be able to audit each and every url created through this method. But; the urls are not types in their own right, they are simply returned from the getShareableLinks action:

az rest --url https://management.azure.com/subscriptions/49a743cb-1b0b-4bbd-9986-f9fcf513526f/resourceGroups/bastion/providers/Microsoft.Network/bastionHosts/goodwbastion/getShareablelinks?api-version=2021-05-01 --method POST

So, I can currently find no way of auditing the urls. I guess solutions like this exists, but it just feels wrong..

Another solution would be to monitor the Azure activity log with Log Analytics, and alert whenever someone creates a url:

The problem is that this does not really tell you which VM the url was enabled for.

This feature is still in preview, and I hope there will be more features available such as:

  • Better logging
  • Azure policy auditing
  • Preauthentication with separate Azure RBAC role, with possibility of enforcing MFA

Want a list of all your Bastion shareable links? Script below helps you:

$enabledbastions = az graph query --graph-query "resources | where type == 'microsoft.network/bastionhosts' | where properties.enableShareableLink == true"
$enabledbastions | ConvertFrom-Json | Select-Object -ExpandProperty data | ForEach-Object{
    $bastionname = $_.name
    $urls = az rest --url "https://management.azure.com/$($_.id)/getShareablelinks?api-version=2021-05-01" --method POST | ConvertFrom-Json
    if($urls.value) {
        $urls.value | ForEach-Object {
            [PSCustomObject] @{
                Bastion = $bastionname
                VM = $_.vm.id
                Url = $_.bsl
            }
        }
    }
}

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s