azure-relay-bridge/examples/sqlserver
Pavel Iakovenko 387a967f9c
Run as a service on macOS (#84)
* Run as a service on macOS

* macOS Launchd documentation updates

* Pin mysql to 8.0.35 to get around libssl and libicu dependency errors

* MySql pinning no longer needed

* AzIdentity 1.11.0
2024-04-12 21:30:38 -04:00
..
Deploy-Relay.ps1 Update Deploy-Relay.ps1 2022-09-22 00:09:14 -07:00
README.md Run as a service on macOS (#84) 2024-04-12 21:30:38 -04:00
client_config.yml SQL Server example 2022-09-21 10:40:52 -07:00
relay-resource-template.json SQL Server example 2022-09-21 10:40:52 -07:00
server_config.yml SQL Server example 2022-09-21 10:40:52 -07:00

README.md

Azure Relay Bridge - Microsoft SQL Server example

This directory contains a set of sample files illustrating how to bridge SQL clients to a remote SQL Server instance in a private network via Azure Relay.

  Private Network A          │          │      Private Network B
                             │          │
                             │          │
                             │          │
         TCP:127.0.0.2:1433  │          │             TCP:localhost:1433
┌──────────┐      ┌────────┐ │          │   ┌────────┐    ┌─────────────┐
│          │      │        │ │          │   │        │    │             │
│  Client  ├──────►azbridge├─┼──────┐ ┌─┼───►azbridge├────► SQL Server  │
│ (sqlcmd) │      │        │ │      │ │ │   │        │    │             │
└──────────┘      └────────┘        │ │     └────────┘    └─────────────┘
                                 ┌──▼─┴───┐
                                 │  sql   │
                                 │        │
azbridge -f ./client_config.yml  │        │ azbridge -f ./server_config.yml
                                 └────────┘
sqlcmd -S tcp:127.0.0.2,1433    Azure Relay
                                 Namespace

Relay Setup

First, create an Azure Relay namespace with a Hybrid Connection named "sql".

The included Azure Powershell script Deploy-Relay.ps1can be called with the name of the namespace and the Azure region, for instance, and deploys the included resource template:

$result=./Deploy-Relay.ps1 mynamespacename westeurope
echo $result.Outputs.sendListenConnectionString.Value

An equivalent, explicit script using Azure CLI looks like this:

export _NS=mynamespacename
az group create --name $_NS --location westeurope
az relay namespace create -g $_NS --name $_NS
az relay hyco create -g $_NS --namespace-name $_NS --name sql
az relay namespace authorization-rule create -g $_NS --namespace-name $_NS -n sendlisten --rights Send Listen
az relay namespace authorization-rule keys list -g $_NS --namespace-name $_NS -n sendlisten --out tsv --query "primaryConnectionString"

Customizing the config files

The template deployment returns a connection string from the sendListenConnectionString value. The last line of the CLI script yields a connection string as well.

These connection strings are associated with a namespace-wide shared access signature rule called "sendlisten" that confers both the "Listen" and "Send" permission at once.

The client_config.yml and server_config.yml files each have a line as follows. Replace the placeholder with the connection string in those files.

AzureRelayConnectionString : <<insert connection string>>

The remaining content of client_config.yml sets up a local forwarder bound to address 127.0.0.2 with TCP port 1433 mapped to hybrid connection "sql". The logical port name is set to "tds", which allows for the TCP port number here to differ from that on the server.

LocalForward :
   - BindAddress: 127.0.0.2
     BindPort: 1433
     PortName: tds
     RelayName: sql

LogLevel: INFO

Using the add-hostname PowerShell command (Windows) or the addhost bash function (Linux) that are installed with azbridge, you can easily map that address to a local host name alias. You must run that command as administrator.

Bash:

addhost 127.0.0.2 localsql

Powershell:

add-hostname 127.0.0.2 localsql

The remaining server_config.yml file sets up a remote forwarder that binds the hybrid connection "sql" with logical port "tds" to the SQL server endpoint on "localhost", port 1433.

RemoteForward :
   - RelayName: sql
     Host: localhost
     PortName: tds
     HostPort: 1433

LogLevel: INFO

Running the bridge

To run the bridge, you can now run

azbridge -f ./client_config.yml

on the client side where the SQL client will run.

You run

azbridge -f ./server_config.yml

on the server side where SQL server runs.

To verify the bridge, you can now connect through it from the client side, for instance with sqlcmd:

sqlcmd -S tcp:127.0.0.2,1433 -P <<password>> -U <<username>>

With the host name alias use

sqlcmd -S tcp:localsql,1433 -P <<password>> -U <<username>>

Mind that if you enable TLS (Encryption) for SQL Server (as you should), the host name alias you configure must match the remote SQL server's host name in order for the certificate validation on the client to function correctly. Concretely, if the SQL Server's host name on its local network is "sql.corp.example.com", that exact name must be used for the host name alias.

The Azure Relay tunnel is always TLS protected, independent of the SQL server configuration.

Running the bridge as a Windows Service or Linux daemon

Windows Service

On Windows, if you install the tool with the MSI installer, the bridge is registered as a Windows Service as "azbridgesvc".

To run either the client or the server side in that service, merge the configuration file snippets above into the $env:ProgramData\Microsoft\Azure Relay Bridge\azbridge_config.svc.yml file, which is described in CONFIG.md.

Since the service might be used with multiple Azure Relay namespaces and or differentiated permissions, you can define local connection strings for each local and remote forwarder:

RemoteForward :
   - RelayName: sql
     Host: localhost
     PortName: tds
     HostPort: 1433
     ConnectionString: <<connection string>>

The file requires administrative permissions to change.

Linux SystemD daemon

On Linux, the service is registered with systemd as "azbridge.service" and can be managed with systemctl if the tool was installed via the DEB or RPM packages.

To run either the client or the server side in that daemon, merge the configuration file snippets above into the /etc/azbridge/azbridge_config.svc.yml file, which is described in CONFIG.md.

The file requires administrative permissions to change.

As with Windows above, you can also override connection strings at the forwarder level on Linux.

MacOS Launchd daemon

On MacOS, the service is registered with Launchd as "com.azure.relay.bridge" and can be managed with launchctl.

To run either the client or the server side in that daemon, merge the configuration file snippets above into the /etc/azbridge/azbridge_config.svc.yml file, which is described in CONFIG.md.

The file requires administrative permissions to change.

As with Windows and Linux above, you can also override connection strings at the forwarder level on macOS.