使用SSH隧道连接到Oracle自治数据仓库

## 为何需要SSH隧道

在我们开始介绍如何使用SSH隧道连接到Oracle自治数据仓库实例之前，我想更应该解释为什么我们必须这样做。 这是因为在某些情况下，用户的客户端机器位于公司内部网络中，出于安全考虑，通常这种网络不允许任何外部访问或仅打开非常有限的端口，例如SSH端口22。

在这种情况下（SSH端口22打开），如果用户需要访问ADW实例，尽管无法访问ADW的默认端口1522, 我们可以通过构建SSH隧道来建立连接。

## 准备工作

在这篇文章中，我假设您已经有一个名为“ADWDVD2”的ADW实例，并且您正在尝试从Oracle Data Visualization Desktop（DVD）建立与此实例的连接。 不幸的是，由于我上面提到的原因，您只能访问SSH端口22. 至少目前，我们用来连接ADW实例的端口固定为1522，这意味着在当前的网络环境下您无法直接访问ADW实例。

幸运的是SSH端口22仍然是打开的，我们可以通过构建SSH隧道来转发所有流量。要建立SSH隧道，我们需要满足3个先决条件。

1. SSH端口22是开放的。这是本文的假设前提。 
2. 客户端机器上安装了SSH客户端。本文中我们使用[Git Bash](https://git-scm.com/)来安装SSH客户端。
3. 有一台可以与目标服务正常通信的SSH服务器。假设我们已经在OCI（Oracle Cloud Infrastructure）中有一个计算实例作为SSH服务器。

**注意：在这篇文章中，我们假设客户端是Oracle Data Visualization Desktop，但SSH隧道适用于任何面临此类网络问题的客户端。**

### 安装SSH客户端

虽然Git Bash的开发是为了给Windows用户提供更加友好且一致的Git用户体验，但它同时也为我们带来了大部分*NIX工具，其中就包括SSH。

安装Git Bash非常简单，只需从[官方网站](https://git-scm.com/)下载安装包并安装即可。与您使用过的其他Windows应用程序的操作相同。一路Next即可完成典型安装。

安装Git Bash后，可以通过单击[开始]菜单中的[Git Bash]图标开始使用它。 然后bash终端将打开，您可以通过输入以下命令来检查bash和SSH客户端的版本。

```bash
$ bash --version
$ ssh -V
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100411/54eb76f3-46b8-622c-e87a-4845598c5837.png)

### SSH服务器(OCI中的计算实例)

我们使用一台OCI中的计算实例作为SSH服务器，以从客户端接收流量并将所有流量转发到目标ADW实例。

以下是连接该SSH服务器的必要信息。

 - 公共IP，您可以从OCI Web控制台获取它
 - 可以使用SSH公钥身份验证方式访问此服务器的有效用户。 比如默认用户`opc`

## 通过SSH隧道连接到ADW实例

### 如果网络不受限制，我们应该看到什么

让我们先看看如果网络不受限制，我们应该看到什么. 自然是毫无问题地创建与ADW实例的连接。

在DVD中创建Connection
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100411/e03036cc-a38c-7d6b-2ecb-d633a7a82281.png)

Select [Oracle Autonomous Data Warehouse Cloud]
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100411/e41e16e4-5101-31d5-b8fc-a0287d79c5f0.png)

输入必要的信息
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100411/ce1b14a5-d794-9b41-d389-982f8efe8a66.png)

[Client Credentials] 就是从ADW实例的Web控制台下载得到的认证文件(.zip)请参考下面屏幕截图.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100411/62ecdacf-3b3a-e98f-2fc4-284be9f41713.png)

[Username] 就是连接ADW实例的用户名. 在这里我们使用默认用户`admin`

[Service Name] 就是将要连接的ADW数据库服务. ADW实例中预置了3个数据库服务(high/medium/low), [请根据您的业务负载类型选择连接适当的数据库服务](https://docs.oracle.com/en/cloud/paas/autonomous-data-warehouse-cloud/user/connect-predefined.html#GUID-9747539B-FD46-44F1-8FF8-F5AC650F15BE). 

Connection 成功创建
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100411/7a936e7e-79af-7349-e4b8-9c4315feb90c.png)

这就是我们期待实现的动作. 

### 只有SSH端口22开放该怎么办

出于测试目的，我们使用的安装了DVD的客户端机器是一台部署了Windows 2012 R2的OCI计算实例，它位于OCI的东京地区(Tokyo region)。而我们要连接的ADW实例部署在OCI的Ashburn地区(Ashburn Region)。

现在让我们修改安全列表的出站规则，如下所示，阻止除端口22之外的所有出站流量。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100411/7c01b0aa-d35e-c053-fe2b-257184c39bb2.png)

尝试再次在DVD中创建连接。 正如预期的那样，我们收到错误“Failed to save the connection”。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100411/6834c176-8420-915d-e599-dc9bbe723d3f.png)

这并不奇怪，因为连接ADW实例的主机及端口信息是保存在认证文件(.zip)中的`tnsnames.ora`文件中的. 在这里指定了客户端连接ADW实例时所要使用的连接信息. 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100411/41ed6bb2-d859-5339-e9b6-20a70358c60f.png)

我们可以看到, 根据tnsnames.ora文件的信息, 客户端连接ADW实例时将会对host`adb.us-ashburn-1.oraclecloud.com`的端口`1522`发出请求. 根据我们设定的出站规则(Engress Rules)，只有到端口22的出站流量才会被通过。所以当我们尝试创建与ADW实例的连接时，客户端（DVD）根据`tnsnames.ora`文件中的连接信息向目标主机的1522端口发出请求时, 该请求将无法通过, 所以无法创建到ADW实例的连接. 

### 创建SSH隧道

那...如何解决这个问题呢？也许您可以联系网络管理员并请求打开端口1522？ 但这与公司的网络安全相关，这种网络级别的变化将影响同一网络中的多个用户。所以, 我猜想您的申请不会轻易获得批准。

根据我们的假定, SSH端口22是打开的, 这也就为我们使用SSH隧道提供了机会. 
实际上，我们已经为构建SSH隧道准备好了一切，1) SSH客户端已经安装完毕, 2) SSH服务器我们也已创建, 现在我们只需要打开Git Bash终端并发出如下命令来启动它即可。

```bash
$ ssh -i path-to-the-private-key -N -L local-port:target-host:target-port user@SSH-server-IP
```

看上面的命令想必您仍然感到困惑，下面的图片解释了此命令中每个选项的含义, 或许可以帮助您加深理解. 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100411/1f9fe423-172b-a787-4c2c-9e3186c662c4.png)


下面是我执行的命令

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100411/47f01d01-1406-1b4b-0f39-328a65dd5115.png)

- `adb.us-ashburn-1.oraclecloud.com：1522` 的部分容易理解，就是目标主机和目标端口。我们希望所有流量都转发到目标主机上的端口(1522)。
- `opc@SSH-server-IP` 部分是您要登录的SSH服务器。
- `11522` 这是什么？ 根据上面的解释，它是*the given port on the local (client) host is to be forwarded to the given host and port on the remote side*。它是localhost上的一个端口。实际上，我们可以使用除保留端口之外的任何端口。 在这种情况下，我们使用端口号11522。

一旦我们执行此命令，您应该看到终端会挂在那里，您不能发出其他命令。这意味着SSH隧道已经构建成功，可以使用它了。您可以使用选项`-f`将隧道置于后台，但我认为如果将它置于前台，在关闭SSH隧道时会更容易。 你只需按下`Ctrl + C`或点击终端窗口上的`X`即可。

现在SSH隧道已准备好，在客户端机器中，到本地主机（127.0.0.1）端口11522的任何流量都将被发送到SSH服务器，然后服务器则将所有流量转发到目标主机上的目标端口。

### 通过SSH隧道创建连接

还记得客户端(DVD)参考的`tnsnames.ora`文件吗？ 我们只需编辑它并使客户端将所有请求都发送到localhost的端口11522上，然后SSH隧道将会处理剩下的事情. 

如下面的屏幕截图所示，将数据库服务`adwdvd2_high`中的`host`和`port`更新为`127.0.0.1`和`11522`。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100411/fd98332a-bd3d-d1a8-952c-a2f1c5ea2ae7.png)

在DVD中创建连接并将服务名称指定为“adwdvd2_high”
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100411/0b79d53e-e91c-3ca2-315d-7c0cccd72532.png)

Connection 成功创建
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100411/700716c4-83f2-e8af-b38d-57ce88ad1358.png)

始终创建的Connection我们可以创建Data Set
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100411/1c8a9c05-0fb8-0ce2-5f1d-90832633f821.png)

尽管我们知道会失败，但我觉得测试一下失败案例会更加完整. 让我们尝试创建一个不使用SSH隧道的到数据库服务`adwdvd2_low`的连接。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100411/51f34d10-6649-baf6-49b6-de8c6ecb2a31.png)

根据上面的测试, SSH隧道非常有效。无论何时, 当您需要连接到ADW实例以创建报表时, 只需启动SSH隧道即可开启您的创作之旅.

## 清理工作

确实没什么好清理的, 您只需按下 `Ctrl + C` 来关闭SSH隧道即可. 或者您可以直接点击Git Bash窗口右上角的`X`就可以了. 

## 参考资料

- [Oracle Data Visualization Desktop](https://www.oracle.com/middleware/technologies/oracle-data-visualization-desktop.html)
- [Git Bash](https://git-scm.com)
- [Explain Shell](https://explainshell.com/explain?cmd=ssh+-i+path-to-the-private-key+-N+-L+local-port%3Atarget-host%3Atarget-port+user%40SSH-server-IP)

## 其他语言版本

- [中文](#)
- [英文](https://qiita.com/teiketu/items/c485bec6fc73f3dfd28a#)
- [日文](https://qiita.com/tnagakub/items/495781887f3bd8488d08)