1433ポートが遮断された社内環境から Azure SQL Database へ接続する方法

# 概要
Azure SQL Database へ SSMS（SQLServer Management Studio）やODBC、JDBCで接続したい！
でも社内からは1433ポートが塞がれていてアクセスできない。。
そんなときに役立つのがSSHポートフォワーディング（トンネリング）です。Azure SQL Database へSSHポートフォワーディングで接続する際はSSMS（SQLServer Management Studio）・JDBCなどのデータベース接続側で必要な設定があります。

1. 準備
1. SSH接続ツールによるポートフォワーディング設定
1. データベース接続ツールの設定
    1. SSMS（SQLServer Management Studio）による接続
    1. JDBCによる接続
1. 追記：SQLServerホスト名による接続（ポートフォワーディング下でFQDNを指定する方法）

# 準備

## 「SQLServer」と「SQLデータベース」
Azure SQL Database では「SQLServer」「SQLデータベース」の2つのキーワードがあります。それぞれ異なるものですので注意しましょう。本項では「SQLServer」⇒「YourSQLServer」、「SQLデータベース」⇒「AccountDB」を用います。この2つを**自分の環境のものに置き換え**てください。

- 「SQLServer」
    - Azure SQL Database データベースインスタンスを稼働する仮想マシンです。
    - 本項では「**YourSQLServer**」を仮定します。この場合 SQLServer(FQDN) は「**YourSQLServer**.***database.windows.net***」となります。
- 「SQLデータベース」
    - SQLServerではデータベースインスタンス上に「データベース」を複数作成することができます。（Azure SQL Database ではSQLデータベース単位で時間課金が発生しますので注意しましょう。
    - 本項では「**AccountDB**」を仮定します。

![AzurePortalAllResources.png](https://qiita-image-store.s3.amazonaws.com/0/66448/c9324911-d983-547e-3cd5-4d04f5e3e01c.png)

## SSH中継サーバ
SSHポートフォワーディング用の中継サーバを用意しましょう。本項では中継サーバの詳細には触れません。留意点として、中継サーバをどこに配置するかで**SQLServer**のファイヤウォール設定が異なりますので注意が必要です。

- 中継サーバをAzure上の同一リソースグループに配置する
    - 追加設定は必要ありません
- 中継サーバをAzure別リソースグループに配置する
    - **SQLServer**の「ファイアウォールと仮想ネットワーク」にて、中継サーバが属する「仮想ネットワーク」のアクセス許可を追加する
    - または、**SQLServer**の「ファイアウォールと仮想ネットワーク」にて、中継サーバのIPアドレスを追加する
- 中継サーバをAzure外に配置する
    - **SQLServer**の「ファイアウォールと仮想ネットワーク」に中継サーバのIPアドレスを追加する


# SSH接続ツールによるポートフォワーディング設定
ここではPuTTYを使ってSSHポートフォワーディングを行う例を示します。**Azure SQL Database へのポートフォワーディングにあたって特別な設定や注意は不要**です。慣れている方は本項を読み飛ばして構いません。

- 「***接続＞SSH＞トンネル***」より「源ポート」「送り先」を設定して「追加」を押下します。
    - 「**源ポート**」…**自分のPCでSQL Databaseへの接続を待機するポート番号**を設定します。ポート番号は他と重複しない番号を指定してください。ここでは「11433」を指定しています。
    - 「**送り先**」…接続先 Azure SQL Database の「***SQLServer(FQDN)：1433***」を設定します。「***YourSQLServer.database.windows.net:1433***」形式で記載してください。

![PuTTY_SSH_Portfowarding.png](https://qiita-image-store.s3.amazonaws.com/0/66448/5192f5a3-ffd3-12d3-4eb2-f58414aa0aa5.png)


※ここで追加した設定は、「***カテゴリ＞セッション***」に保存しておきます（「ホスト名（SSHホスト名）」「ポート番号（通常22）」を設定し、「セッション一覧」に「mysshhost_mssql_portfowarding」等を記入し「保存」を実施する。）


# データベース接続ツールの設定

## JDBCによる接続

- jdbc:sqlserver://***localhost:11433***;database=**AccountDB**;encrypt=true;hostNameInCertificate=*.database.windows.net;loginTimeout=30;
    - 「***localhost:11433***」…***localhost*** および、SSHポートフォワーディングで設定したポート番号（ここでは***11433***）を指定します。
    - 「**AccountDB**」…SQLデータベースを指定します。
    - 「***encrypt=true***」…Azure SQL Database では必ず***true***に設定します。
    - 「***hostNameInCertificate=\*.database.windows.net;***」…この指定がないとAzure上で稼働する実サーバのFQDNを特定出来ません。SSHポートフォワーディングにおいて**一番重要な設定**です。

![SQLWorkBench_AzureSQLDatabase.png](https://qiita-image-store.s3.amazonaws.com/0/66448/514b8cf4-857f-49af-f246-67afa32460ae.png)


## SSMS（SQLServer Management Studio）からの接続

### SSMSログイン設定（1／3）

- 「サーバー名」…「***localhost, 11433***」のように、***localhost*** および、SSHポートフォワーディングで設定したポート番号（ここでは***11433***）を指定します。
- 「ログイン」「パスワード」に正しい値を指定してください。

![SSMS_SSH_Portfowarding1of3.PNG](https://qiita-image-store.s3.amazonaws.com/0/66448/05f71176-4932-26c6-7196-6629cc07b25d.png)


### SSMSログイン設定（2／3）

- 「データベースへの接続」…SQLデータベースを指定します（本項では「AccountDB」）。
- 「暗号化接続」（ON）
- 「サーバー証明書を信頼する」（ON）

![SSMS_SSH_Portfowarding2of3.PNG](https://qiita-image-store.s3.amazonaws.com/0/66448/38e0d95b-9e0a-4eca-bff1-da3f2fdaadbb.png)

### SSMSログイン設定（3／3）

- 「追加の接続パラメーター」
    - SQLServer(FQDN)を指定します（本項では「SERVER=**YourSQLServer**.database.windows.net」）。
    - この指定がないとAzure上で稼働する実サーバのFQDNを特定出来ません。SSHポートフォワーディングにおいて**一番重要な設定**です。

![SSMS_SSH_Portfowarding3of3.PNG](https://qiita-image-store.s3.amazonaws.com/0/66448/4a2d9702-e084-bcc6-ff99-fb20e31e865e.png)


# 追記：SQLServerホスト名による接続（ポートフォワーディング下でFQDNを指定する方法）

## 概要
SSMS（SQLServer Management Studio）などのツールでは、各種シーン（例:Import、Export、スクリプト生成など）でホスト名・ポート番号およびSQLServer認証を求められるシーンがあり、そうしたシーンでは大抵本項で示したような「追加の接続パラメーター」でSQLServer(FQDN)を入力する手段が用意されていません。「ホスト名=localhost,1433」「追加の接続パラメーター=**YourSQLServer**.database.windows.net」が指定したくても後者が入力できないシーンが多いのです。
そうしたシーンで有用なのがhostsファイルへSQLServer(FQDN)を登録する方法です。ローカルWindowsのhostsファイルへ下記のように設定を追加することで、ホスト名・ポート番号を指定するだけで「追加の接続パラメーター」が不要となります。設定が直感的になるというメリットもありますが、そもそもSSMSのインポート/エクスポートのように「追加の接続パラメーター」の設定手段が提供されないシーンではこの方法を使わざるを得ません。
一方で、SQLDatabaseごとに都度hostsファイル登録するのは面倒ですし保守性の問題やそもそもhostsファイルへの書き込みはUAC昇格が必要になるため環境によってはファイル編集できないことがあります。例えばJDBCのようにSQLServer(FQDN)を要求しないプロトコルしか使わないのであればhostsファイルにFQDN登録を行う必要はありません。

## ローカルマシンhostsファイルへのSQLServer(FQDN)の追加
hostsファイル（*C:\Windows\System32\drivers\etc\hosts*）
`127.0.0.1       YourSQLServer.database.windows.net` << 行を追加する

注）hostsファイルの編集を行う際は、notepad.exe等のテキスト編集アプリケーションを右クリック>その他>「管理者として実行」より起動して編集・保存すること。システム管理者であっても、UAC未昇格の状態で同ファイルを保存することはできない。

## 各種ツールにおける接続要領

* ホスト名　**YourSQLServer**.database.windows.net
* ポート番号　SSH接続ツールで設定した「源ポート」（例:11433）

注）ホスト名がオリジナルのSQLServer(FQDN)であるため一見ダイレクトにSQLDatabaseへ接続しているようにみえるが、あくまでSSHポートフォワーディングとしてSSHプロトコルのトンネリング下で接続を行う。そのため、ポート番号にはSQLDatabaseサービス標準の1433ではなく、SSH接続ツールに設定したポート番号を指定すること。