1

A similar question was answered here, and the option of opening an SSH tunnel was lightly touched, but the consensus was that VPN tunnels would be the easiest solution, which is true if the client is an "internal" user. This question is a little more specific for external customers. Some problems with the VPN solution are:

  • Other trafic trying to run through the VPN connection
  • Customers could potentially "see" each others networks (can be resolved by closing most ports on the firewall)
  • Windows Updates often break the VPN connectivity

All of these issues can be fixed, but it has proven to be a clunky solution.

The most obvious option would be to wrap all database access into API calls or use a 3rd-party ODBC driver. I am looking for a solution using TLS tunnels (SSL has been deprecated) in the same way Azure database connections are established.

I have previously used the netsh command in Windows to change the port of a local service. Could TLS tunneling be added in a similar fashion?

On the client side there already is native support by adding Encrypt=True to the connection string. This is a screenshot of the SSMS client options: enter image description here

So my main questions are:

  • What are the steps to enable a TLS tunneled (non-standard) port to SQL server
    • On the SQL server service (if any)
    • On the Machine running SQL server (can we use something like the netsh tool or do we need to install a proxy of some sort?)
    • On the Firewall
  • Would we need to purchase any "special" type of certificate (we don't want to use self-signed in order to prevent man-in-the-middle attacks) or would the same kind as regular websites use also work?
  • Anything else we should keep in mind in order to smoothly roll this out to thousands of clients?
Louis Somers
  • 616
  • 6
  • 15

1 Answers1

1

in the same way Azure database connections are established

Essentially Azure (assuming you mean Azure SQL, and not SQL Server installed in an Azure VM or other options) opens the virtual SQL server's interface address to the world and you control access with settings in the security/firewall section of the portal (or the related API calls).

To mimic this with an on-prem SQL server set a port-forwarding rule on your edge firewall to allow connections to the SQL instance's TCP port (1433 for the default instance, unless you've changed it), with rules to only allow connections from specific source addresses (to mimic the rules settable in Azure). If you have multiple instances you will want to have them on fixed ports or you will need to check/reconfigure your port forwarding rules every time instances are restarted. If you have multiple public IP addresses you can make each instance be on the standard port 1433 if you desire, by having each on a different address, or mimic the same port numbering seen internally.

Opening SQL Server to your clients directly is usually not recommended though, a VPN or tunnelling arrangement is preferred. Even if a direct connection to SQL Server is secure enough, a zero-day SQL authentication flaw or a leaked SQL password doesn't immediately expose you to danger as an attacker will need to authenticate at the prior level before launching any exploits against you.

SSH has been deprecated

What do you mean by that? Ruled out by your company's policies? SSH itself is very much not deprecated, and is in fact gaining wider support as MS are including a native port of OpenSSH in future Windows Server versions so there will be no need to use other options (Cygwin, a Linux or other unix-a-like VM, Windows Subsystem for Linux, a separate unix-a-like machine) if you don't need them for other reasons.

Could SSH tunneling be added

The ODBC driver you link to specifically mentions support for SSH based tunnelling, so yes. You'll have to check their documentation for how to go about this.

To use SSH tunnels more manually instead of a 3rd party driver you just need an SSH server running on the same network, configured to allow tunnelling, and the SSH port open via your firewall the same way you would do for allowing direct SQL Server connections from the outside. You will then need to manage the accounts/passwords/keys on that SSH service. Accessing the SQL instance(s) via the tunnel is then as simple as ssh user@111.111.111.111 -L1433:222.222.222.222:1433 where 111.111.111.111 is the relevant public address (or DNS name for it) and 222.222.222.222 is the internal address of the SQL server. The client then connects to localhost (127.0.0.1). If they have a local instance listening on port 1433 then they'll need to change the tunnel specification to something else, for instance -L12345:222.222.222.222:1433 then they would connect to locathost:12345.

I'll not go into further detail as we are off-topic for your question title "using TLS tunnels" as SSH is not TLS-based.

multi-tennant environment

You might need to flesh out your question to include what you mean by this, as the phrase could refer to one or more of several things (multiple clients using the same DBs, using different DBs on the same instances, using different instances on the same servers/network, ...).

TLS Tunneling via Proxy (with regard to the updated question)

Simple TLS proxies for plain services do exist, I've heared of a number inthe past but I'm no expert as I've never had the need to use them (using SSH or VPNs instead for non-web traffic and HTTP specific tools for HTTPS). With that sort of solution you need one half of the proxy installed on the client machines, as well as the server half inside the firewall (with port mapping(s) through to it) at the server end. The client-side accepts the plain connection, makes an encrypted link to its server side through which the transfers are proxied, and the server-side makes the real (plain) connection to the server.

https://github.com/square/ghostunnel is the first example that came from a quick search for "TLS proxy". You'll no doubt find others with a deeper search.

But, the need for client-side installation may make this sort of solution a no-go for your clients.

Built In Encryption Support

A quick test locally suggests that the encryption options "just work". If you have not installed a "proper" certificate on the server the client's connection will need to use the "trust server certificate" option but this leaves you vulnerable to MitM attacks.

https://docs.microsoft.com/en-us/sql/database-engine/configure-windows/enable-encrypted-connections-to-the-database-engine suggests setting it up to use a real validated certificate is not difficult (the "Server Authentication" requirement is covered by certificates as normally issued for HTTPS). SSL certificates for single names are cheap these days, in fact another quick search suggests that it isn't difficult to use LE's free certificates: https://sqlsunday.com/2017/11/22/encrypting-tds-with-letsencrypt/

As MS seem to think this feature is secure enough for Azure SQL and I've not heard the hoo-hah you'd expect from it not being, this is probably the way to go unless your clients are using software that doesn't support encrypted TDS connections.

Make sure that you enable the "force encryption" option for each SQL Server instance otherwise your clients may forget and leave their transmissions open.

David Spillett
  • 22,534
  • 42
  • 66
  • 1
    Sorry I mixed SSH up with SSL and TLS, edited those... I mentioned the ODBC driver because that's not the option I'm looking for, I just want to know how to set up a secure tunnel directly to SQL server rather than a VPN into the whole network. Doing the port forwarding to 1433 is part of the solution, but doing that alone would not be a good idea (exposing the service). That's why I need a different port to accept only TLS (encrypted) connections and then have everything forwarded to SQL's port 1433. `netsh` can do the port-swap part of that, I'm trying to find out how to add the TLS part. – Louis Somers Jan 23 '19 at 15:33
  • With multi-tenant I mean multiple clients using different DB's on the same instance and sometimes the same (read-only) db (but I think that is irrelevant to my question) – Louis Somers Jan 23 '19 at 15:33
  • As for the SSH part, I want authentication to be done by SQL server, but the secure connection by a TLS tunnel, just like you can browse any https:// site without logging in. Sorry about mentioning SSH, I really meant SSL/TLS. But thanks for the answer. I'm afraid it will most likely not work directly from a connection string without having some proxy client like the 3rd party odbc driver. – Louis Somers Jan 23 '19 at 15:40
  • 1
    SSH/TLS, mixing up TLAs is an easy mistake to make. I've added quick notes WRT TLS via proxy and built-in support, though you may need to read further to see if these options are sufficient and suitable as I've never used them myself the way you are proposing. – David Spillett Jan 23 '19 at 17:49
  • Thank you David, I wonder how you found that [link](https://docs.microsoft.com/en-us/sql/database-engine/configure-windows/enable-encrypted-connections-to-the-database-engine). I spent hours searching before asking the question here (I guess the "SSH" keyword thew me off). The idea is indeed to "force" encryption. I also have mixed feelings about direct exposure of SQL Server, but VPN has been a really rough ride so far. We may go for the proxy solution after all, which is an option we did not really consider so far. Again thanks for all the time and effort you took to answer my questions! – Louis Somers Jan 24 '19 at 22:00