在使用SSH隧道的三层Rails应用程序中确保通信安全

Web应用程序通常由三个不同层构建:表示层(用户看到的内容),提供应用程序业务逻辑的应用程序层以及存储应用程序数据的数据层。在本教程中,您将在三层配置中部署Rails应用程序,方法是在三台独立的服务器上安装一套独特的软件,配置每台服务器及其组件,以便安全高效地进行通信和运行。

介绍

Web应用程序通常由三个不同的层次构建而成:

  • 第一层是表示层 ,这是用户看到的。
  • 接下来是应用程序层 ,它提供了应用程序的业务逻辑
  • 最后, 数据层存储应用程序所需的数据。

Ruby on Rails应用程序中,它将松散地映射到表示层的Web服务器,应用程序层的Rails服务器以及数据层的数据库。 在此设置中,应用程序层与数据层通信以检索应用程序的数据,然后通过表示层将其显示给用户。

虽然可以将所有这些应用程序安装在单个服务器上,但将每个图层放到其自己的服务器上可以更容易地扩展应用程序。 例如,如果Rails服务器成为瓶颈,则可以添加更多应用程序服务器,而不会影响其他两个层。

在本教程中,您将在三层配置中部署Rails应用程序,方法是在三台独立的服务器上安装一套独特的软件,配置每台服务器及其组件,以实现通讯和功能连接,并通过SSH隧道保护它们之间的连接。 对于软件,您将使用Nginx作为表示层上的Web服务器, Puma作为应用程序层上的Rails应用程序服务器, PostgreSQL作为数据层上的数据库。

先决条件

为了完成本教程,您需要启动三个Ubuntu 16.04服务器。 将这些Web服务器应用程序服务器数据库服务器命名,并且每个服务器都应启用“专用网络”。

三台服务器中的每台服务器都应该有一个具有sudo权限的非root用户以及一个配置为允许SSH连接的防火墙(可以使用我们的初始服务器设置指南进行配置)。 在本教程的上下文中,每台服务器上的sudo用户名为sammy

另外,三台服务器中的每一台都有自己独特的配置要求:

  • 网络服务器上

  • 应用程序服务器上

    • 按照如何在Ubuntu 16.04上安装Node.js中的说明,使用官方PPA 安装Node.js。 少数Rails功能(如资产管道)依赖于JavaScript运行时,Node.js提供此功能。
    • 安装Ruby on Rails框架。 要做到这一点,请按照我们关于如何在Ubuntu 16.04上使用rbenv安装Ruby on Rails的指南 在您遵循本教程时,请务必安装在撰写本文时为Ruby 2.5.1的最新版本的Ruby。
    • 安装PostgreSQL,如我们教程的第一部分所示, 如何在Ubuntu 14.04上使用PostgreSQL和Ruby on Rails应用程序 本节还介绍如何安装libpq-dev ,这是三层安装所需的另一个软件包。
    • 使用Puma部署Rails应用程序。 如果您没有自己部署的应用程序,请按照我们关于如何使用Puma和Nginx部署Rails应用程序的指南来部署示例应用程序。 请注意,在此先决条件的“安装rbenv-vars插件”部分中,必须设置数据库用户和密码以反映在数据库服务器上安装PostgreSQL时使用的值。 此外,您必须允许通过防火墙的端口3000才能“创建生产数据库”部分工作。 最后,您不需要完成本先决条件教程“创建Puma Upstart脚本”和“安装并配置Nginx”的最后两个步骤。
  • 数据库服务器上

    • 安装并配置PostgreSQL数据库软件。 按照我们关于如何在Ubuntu 16.04上安装和使用PostgreSQL的指南,获取有关如何执行此操作的说明。 在您遵循本先决条件教程时,请为您的Rails应用程序创建具有superuser权限的PostgreSQL角色,以及与PostgreSQL角色具有相同名称的数据库。 在本教程中,PostgreSQL角色和数据库都称为sammy
    • 为新创建的PostgreSQL角色设置密码。 跳过Puma教程的“ 创建生产数据库用户 ”部分中的第一条命令(您也可以使用它来设置应用服务器 ),然后按照该部分中的其余命令更改数据库用户的密码。 请注意,您为数据库服务器设置的PostgreSQL角色名称和密码应该与您在应用服务器的PostgreSQL安装中设置的相同。

第1步 - 为SSH隧道创建用户

SSH隧道是加密连接,可以将数据从一台服务器上的端口发送到另一台服务器上的端口,使得它看起来好像第一台服务器上的监听程序正在运行。 为SSH隧道提供专用用户有助于提高设置的安全性:如果入侵者可以访问其中一台服务器上的sammy用户,则他们将无法访问三层设置中的其他服务器。 同样,如果入侵者访问隧道用户,他们既不能编辑Rails应用程序目录中的文件,也不能使用sudo命令。

在每台服务器上,创建一个名为tunnel的额外用户。 隧道用户的唯一功能是创建SSH隧道以促进服务器之间的通信,因此,与sammy不同,不要授予隧道 sudo权限。 此外, 隧道用户不应具有对Rails应用程序目录的写入权限。 在每台服务器上运行以下命令以添加隧道用户:

sudo adduser tunnel

Web服务器上,切换到隧道用户。

sudo su tunnel

作为隧道用户,生成一个SSH密钥对:

ssh-keygen

将密钥保存在默认位置,不要为密钥创建密码,因为这样做可能会在以后在服务器之间创建SSH隧道时使身份验证复杂化。

创建密钥对后,返回sammy用户:

exit

现在切换到应用程序服务器并再次执行相同的命令:

sudo su tunnel
ssh-keygen
exit

您现在已经配置了本教程其余部分所需的所有用户。 Net,您将对每个隧道用户的/etc/hosts文件进行一些更改,以简化创建SSH隧道的过程。

第2步 - 配置主机文件

在本教程中,有很多时候您必须在命令中引用应用程序服务器数据库服务器的IP地址。 您不必每次都记住并输入这些IP地址,您可以将应用程序服务器数据库服务器的私有IP添加到每个服务器的/etc/hosts文件中。 这将允许您在随后的命令中使用它们的名称来代替它们的地址,并且将使建立SSH隧道的过程更平滑。

请注意,为了简单起见,本教程将指导您将应用程序服务器数据库服务器的私有IP地址添加到三台服务器上的每台服务器上的/etc/hosts文件中。 虽然技术上没有必要将应用服务器数据库服务器的私有IP地址添加到自己的hosts文件中,但这样做不会导致任何问题。 这里描述的方法仅仅是为了速度和方便而选择的。

首先,找到你的应用服务器数据库服务器的私有IP地址。 如果您使用的是DigitalOcean Droplet,请导航至您的控制面板并点击这些Droplets的名称。 在任何特定于Droplet的页面上,公共和私人IP地址都显示在页面顶部附近。

然后在每台服务器上,使用您最喜欢的文本编辑器打开/etc/hosts文件并追加以下行:

sudo nano /etc/hosts
/ etc / hosts文件
. . .
app-server_private_ip app-server
database-server_private_ip database-server

通过将这些行添加到每个服务器上的此文件,可以在通常需要您使用这些服务器的IP地址的命令中使用名称app-serverdatabase-server 您将使用此功能来设置SSH密钥,以便您的每个隧道用户都可以连接到其他服务器。

第3步 - 设置SSH登录

既然您在所有三台服务器上都有一个隧道用户和一个更新的/etc/hosts文件,您就可以开始在它们之间创建SSH连接了。

当你经历这一步时,想象三层Pyramid,底层是数据库服务器 ,中间是应用 服务器 ,顶层是网络服务器 应用程序服务器必须能够连接到数据库服务器才能访问Rails应用程序所需的数据,并且Web服务器必须能够连接到应用程序服务器,以便它可以向用户呈现内容。

因此,您只需要将每个隧道用户的SSH公钥添加到服务器的“下面”,这意味着您必须将Web服务器 隧道用户的公钥添加到应用 服务器 ,并将应用服务器 隧道用户的公钥添加到数据库服务器 这将允许您在层之间建立加密的SSH隧道,并防止网络中的任何窃听者读取它们之间传递的流量。

要开始此过程,请将位于/home/tunnel/.ssh/id_rsa.pubWeb服务器上的隧道用户的公钥复制到应用服务器上的/home/tunnel/.ssh/authorized_keys文件中。

Web服务器上 ,使用以下命令在终端中显示隧道用户的公钥:

sudo cat /home/tunnel/.ssh/id_rsa.pub

选择文本输出并将其复制到系统的剪贴板。

在单独的终端会话中将SSH登录到应用服务器 ,然后切换到隧道用户:

sudo su tunnel

将系统剪贴板中的密钥附加到应用程序服务器上的authorized_keys文件中。 您可以使用以下命令一步完成此操作。 请记住使用系统剪贴板中的公钥替换tunnel_ssh_publickey_copied_from_web_server

echo "tunnel_ssh_publickey_copied_from_web-server" >> /home/tunnel/.ssh/authorized_keys

之后,修改authorized_keys文件的权限以防止对其进行未经授权的访问:

chmod 600 /home/tunnel/.ssh/authorized_keys

然后返回到sammy用户:

exit

接下来,在位于/home/tunnel/.ssh/id_rsa.pub应用程序服务器上显示隧道用户的公用密钥 - 并将其粘贴到数据库服务器上的/home/tunnel/.ssh/authorized_keys文件中:

sudo cat /home/tunnel/.ssh/id_rsa.pub
sudo su tunnel

由于您未在数据库服务器上生成SSH密钥对,因此您必须创建/home/tunnel/.ssh文件夹并调整其权限:

mkdir /home/tunnel/.ssh
chmod 700 /home/tunnel/.ssh

然后将应用程序服务器的公钥添加到authorized_keys文件并调整其权限:

echo "tunnel_ssh_publickey_copied_from_app-server" >> /home/tunnel/.ssh/authorized_keys
chmod 600 /home/tunnel/.ssh/authorized_keys

然后返回到sammy用户:

exit

接下来,使用SSH从您的Web服务器连接到应用程序 服务器 ,以隧道用户身份测试第一个连接:

sudo su tunnel
ssh tunnel@app-server

当您第一次从网络服务器连接到应用程序服务器时 ,您会看到一条消息,要求您确认要连接的计算机是否可信。 输入“yes”接受应用服务器的真实性:

The authenticity of host '111.111.11.111 (111.111.11.111)' can't be established.
ECDSA key fingerprint is fd:fd:d4:f9:77:fe:73:84:e1:55:00:ad:d6:6d:22:fe.
Are you sure you want to continue connecting (yes/no)? yes

您将看到来自应用程序服务器的欢迎横幅,命令提示符将显示您已登录到应用程序服务器 这证实了从Web服务器应用程序服务器的SSH连接正常运行。

从SSH连接退出到应用程序服务器 ,然后退出隧道用户以返回到您的Web服务器sammy用户:

exit
exit

接下来,按照这些相同的步骤来测试从应用程序服务器数据库服务器的SSH连接:

sudo su tunnel
ssh tunnel@database-server

接受数据库服务器的真实性。 当您看到来自数据库服务器的欢迎横幅和命令提示符时,您会知道从应用服务器数据库服务器的SSH连接按预期工作。

从SSH连接退出到数据库服务器 ,然后退出隧道用户:

exit
exit

您在该步骤中设置的SSH连接形成了SSH隧道的基础,这将启用您的三个服务器层之间的安全通信。 然而,在目前的形式下,这些连接很容易发生崩溃,因此它们不如其可靠。 通过安装一些额外的软件并将隧道配置为一项服务,您可以减轻这些漏洞。

第4步 - 建立一个持久的SSH隧道到数据库服务器

在最后一步中,您从本地服务器访问远程服务器上的命令提示符。 通过将本地主机端口的流量通过隧道传输到远程端口,SSH隧道可以让您做更多的事情。 在这里,您将使用SSH隧道来加密您的应用程序服务器数据库服务器之间的连接。

如果您遵循本教程的所有先决条件,则您将在应用程序服务器数据库服务器上安装PostgreSQL。 要防止端口号发生冲突,您必须在这些服务器之间配置SSH隧道,以将应用服务器的端口5433的连接转发到数据库服务器上的端口5432 稍后,您将重新配置您的Rails应用程序(托管在您的应用程序服务器上 )以使用在数据库服务器上运行的PostgreSQL实例。

应用服务器上的sammy用户开始,切换到您在第1步中创建的隧道用户:

sudo su tunnel

使用以下标志和选项运行ssh命令以在应用程序服务器数据库服务器之间创建隧道:

ssh -f -N -L 5433:localhost:5432 tunnel@database-server
  • -f选项将ssh发送到后台。 这允许您在现有提示中运行新命令,同时隧道作为后台进程继续运行。
  • -N选项告诉ssh不执行远程命令。 这是因为你只想转发端口。
  • -L选项后面跟着配置值5433:localhost:5432 这指定来自本地端( 应用服务器 )的端口5433流量被转发到本地主机在远程服务器( 数据库服务器 )上的端口5432 请注意,这里的localhost是从远程服务器的角度来看的。
  • 命令的最后一部分tunnel@database-server指定要连接的用户和远程服务器。

建立SSH隧道后,返回sammy用户:

exit

此时,隧道正在运行,但没有看到它确保它保持运行。 如果进程崩溃,隧道将关闭,Rails应用程序将不再能够与其数据库通信,并且您将开始看到错误。

杀死你现在创建的隧道,因为我们要做出更可靠的设置。 由于连接在后台,您将不得不找到它的进程ID来杀死它。 由于每个隧道都是由隧道用户创建的,因此您可以通过列出当前进程并过滤关键字'tunnel'的输出来找到其进程ID:

ps axu | grep tunnel

这将返回类似下面的输出:

tunnel   21814  0.0  0.1  44920   692 ?        Ss   14:12   0:00 ssh -f -N -L 5433:localhost:5432 tunnel@database-server
sammy    21816  0.0  0.2  12916  1092 pts/0    S+   14:12   0:00 grep --color=auto tunnel

通过运行kill命令及其进程ID来停止进程:

sudo kill 21814

要维护应用程序服务器和数据库之间的持久SSH连接,请安装autossh autossh是一个程序,用于启动和监视SSH连接,并在连接断开或停止传输时重新启动它:

sudo apt-get install autossh

systemd是Ubuntu上的默认init系统 ,意味着它在系统引导后管理进程。 您可以使用systemd创建一个服务,以便在服务器重新启动时管理并自动启动SSH隧道。 为此,在/lib/systemd/system/目录中创建一个名为db-tunnel.service的文件,这是存储systemd单元文件的标准位置:

sudo nano /lib/systemd/system/db-tunnel.service

将以下内容添加到新文件以配置systemd进行管理的服务:

/lib/systemd/system/db-tunnel.service

[Unit]
Wants=network-online.target
After=network-online.target

[Service]
User=tunnel
WorkingDirectory=/home/tunnel
ExecStart=/bin/bash -lc 'autossh -N -L 5433:localhost:5432 tunnel@database-server'
Restart=always
StandardInput=null
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=%n
KillMode=process

[Install]
WantedBy=multi-user.target

这里的关键是ExecStart 这指定命令的完整路径以及为了启动过程而需要执行的参数。 在这里,它启动一个新的bash shell,然后运行autossh程序。

保存并关闭该文件,然后重新加载systemd配置以确保它获取新的服务文件:

sudo systemctl daemon-reload

启用db-tunnel服务,以便在服务器启动时自动启动到数据库服务器的隧道:

sudo systemctl enable db-tunnel.service

然后,开始服务:

sudo systemctl start db-tunnel.service

再次运行以下命令检查隧道是否启动:

ps axu | grep tunnel

在输出中,您会看到这次运行的进程更多,因为autossh现在正在监视隧道:

tunnel   25925  0.0  0.1   4376   704 ?        Ss   14:45   0:00 /usr/lib/autossh/autossh -N -L 5432:localhost:5432 tunnel@database-server
tunnel   25939  0.2  1.0  44920  5332 ?        S    14:45   0:00 /usr/bin/ssh -L 61371:127.0.0.1:61371 -R 61371:127.0.0.1:61372 -N -L 5432:localhost:5432 tunnel@database-server
sammy    25941  0.0  0.2  12916  1020 pts/0    S+   14:45   0:00 grep --color=auto tunnel

现在通道已启动并运行,您可以使用psql测试与数据库服务器的连接,以确保它正常工作。

启动psql客户端并告诉它连接到localhost 您还必须指定端口5433以通过SSH隧道连接到数据库服务器上的PostgreSQL实例。 指定您之前创建的数据库名称,并键入您在出现提示时为数据库用户创建的密码:

psql -hlocalhost -p5433 sammy

如果您看到类似以下输出的内容,则数据库连接已正确设置:

psql (9.5.10)
SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off)
Type "help" for help.

sammy=#

要关闭PostgreSQL提示符,请键入\q ,然后按ENTER

最后,您拥有持久可靠的SSH隧道,可以加密应用服务器数据库服务器之间的流量。 隧道的安全功能是关键,因为它是在这个隧道上,您的应用服务器上的Rails应用程序将与您的数据库服务器上的PostgreSQL实例进行通信。

第5步 - 配置Rails以使用远程数据库

现在已经建立了从应用程序服务器数据库服务器的隧道,您可以将其用作安全通道,让Rails应用程序通过隧道连接到数据库服务器上的PostgreSQL实例。

打开应用程序的数据库配置文件:

nano /home/sammy/appname/config/database.yml

更新production部分,以便将端口号指定为环境变量。 它现在应该看起来像这样:

/home/sammy/appname/config/database.yml
. . .
production:
  <<: *default
  host: localhost
  adapter: postgresql
  encoding: utf8
  database: appname_production
  pool: 5
  username: <%= ENV['APPNAME_DATABASE_USER'] %>
  password: <%= ENV['APPNAME_DATABASE_PASSWORD'] %>
  port: <%= ENV['APPNAME_DATABASE_PORT'] %>

保存并关闭此文件,然后打开应用程序目录中的.rbenv-vars文件并编辑环境变量:

nano /home/sammy/appname/.rbenv-vars

如果您在数据库服务器上为PostgreSQL角色设置了不同的名称和密码,请立即将其替换(在下面的示例中,PostgreSQL角色名为sammy )。 另外,添加一个新行来指定数据库端口。 进行这些更改后,您的.rbenv-vars文件应如下所示:

/home/sammy/appname/.rbenv-vars

SECRET_KEY_BASE=secret_key_base
APPNAME_DATABASE_USER=sammy
APPNAME_DATABASE_PASSWORD=database_password
APPNAME_DATABASE_PORT=5433

完成后保存并关闭该文件。

因为您现在在数据库服务器上使用PostgreSQL实例,而不是在部署Rails应用程序的应用程序服务器上使用PostgreSQL实例,所以必须重新设置数据库。

应用程序服务器上 ,导航到您的应用程序目录并运行rake命令来设置数据库:

注意:此命令不会将现有数据库中的任何数据迁移到新数据库。 如果您的数据库中已有重要数据,则应备份并稍后恢复。

cd /home/sammy/appname
rake db:setup

一旦该命令完成,您的Rails应用程序将通过加密的SSH隧道开始与数据库服务器上的PostgreSQL实例进行通信。 接下来要做的就是将Puma配置为systemd服务,以便管理。

第6步 - 配置和启动Puma

与您在第4步中设置db-tunnel服务的方式类似,您将配置systemd作为服务运行Puma(您安装在应用程序服务器上的服务器软件,作为先决条件的一部分)。 将Puma作为服务运行,可以在服务器启动或自动重启时自动启动,如果它崩溃的话,可以帮助您的部署更健壮。

/lib/systemd/system/目录下创建一个名为puma.service的新文件:

sudo nano /lib/systemd/system/puma.service

将以下内容(来自Puma的systemd文档 )修改为新文件。 请务必更新UserWorkingDirectoryExecStart指令中突出显示的值以反映您自己的配置:

/lib/systemd/system/puma.service

[Unit]
Description=Puma HTTP Server
After=network.target

[Service]
# Foreground process (do not use --daemon in ExecStart or config.rb)
Type=simple

# Preferably configure a non-privileged user
User=sammy

# The path to the puma application root
# Also replace the "<WD>" place holders below with this path.
WorkingDirectory=/home/sammy/appname

# Helpful for debugging socket activation, etc.
# Environment=PUMA_DEBUG=1

Environment=RAILS_ENV=production

# The command to start Puma.
ExecStart=/home/sammy/.rbenv/bin/rbenv exec bundle exec puma -b tcp://127.0.0.1:9292

Restart=always

[Install]
WantedBy=multi-user.target

保存并关闭文件。 然后重新加载systemd ,启用Puma服务,并启动Puma:

sudo systemctl daemon-reload
sudo systemctl enable puma.service
sudo systemctl start puma.service

之后,通过检查服务状态确认Puma正在运行:

sudo systemctl status puma.service

如果它正在运行,您将看到类似于以下的输出:

puma.service - Puma HTTP Server
   Loaded: loaded (/lib/systemd/system/puma.service; enabled; vendor preset: enabled)
   Active: active (running) since Tue 2017-12-26 05:35:50 UTC; 1s ago
 Main PID: 15051 (bundle)
    Tasks: 2
   Memory: 31.4M
      CPU: 1.685s
   CGroup: /system.slice/puma.service
           └─15051 puma 3.11.0 (tcp://127.0.0.1:9292) [appname]

Dec 26 05:35:50 app systemd[1]: Stopped Puma HTTP Server.
Dec 26 05:35:50 app systemd[1]: Started Puma HTTP Server.
Dec 26 05:35:51 app rbenv[15051]: Puma starting in single mode...
Dec 26 05:35:51 app rbenv[15051]: * Version 3.11.0 (ruby 2.4.3-p205), codename: Love Song
Dec 26 05:35:51 app rbenv[15051]: * Min threads: 5, max threads: 5
Dec 26 05:35:51 app rbenv[15051]: * Environment: production

接下来,使用curl访问并打印网页的内容,以便检查它是否正确地被服务。 以下命令告诉curl访问刚刚在端口9292上的app-server上启动的Puma服务器:

curl localhost:9292/tasks

如果你看到类似下面的代码,那么它确认Puma和数据库连接都正常工作:

...

<h1>Tasks</h1>

<table>
  <thead>
    <tr>
      <th>Title</th>
      <th>Note</th>
      <th colspan="3"></th>
    </tr>
  </thead>

  <tbody>
  </tbody>
</table>

...

一旦您可以确认您的Rails应用程序由Puma提供服务并且已正确配置为在数据库服务器上使用远程PostgreSQL实例,则可以继续设置Web服务器应用程序服务器之间的SSH隧道。

第7步 - 设置SSH持续通道并持久保存到应用服务器

现在应用程序服务器已启动并运行,您可以将其连接到Web服务器 与您在第4步中执行的过程类似,您将通过设置另一个SSH隧道来执行此操作。 该隧道将允许Web服务器上的Nginx通过加密连接安全地连接到应用服务器上的Puma。

首先在网络服务器上安装autossh

sudo apt-get install autossh

/lib/systemd/system/目录下创建一个名为app-tunnel.service的新文件:

sudo nano /lib/systemd/system/app-tunnel.service

将以下内容添加到此文件。 关键路线是以ExecStart开头的ExecStart 在这里,这一行将网络服务器上的端口9292转发到Puma正在监听的应用程序服务器上的端口9292

/lib/systemd/system/app-tunnel.service

[Unit]
StopWhenUnneeded=true
Wants=network-online.target
After=network-online.target

[Service]
User=tunnel
WorkingDirectory=/home/tunnel
ExecStart=/bin/bash -lc 'autossh -N -L 9292:localhost:9292 tunnel@app-server'
Restart=always
StandardInput=null
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=%n
KillMode=process

[Install]
WantedBy=multi-user.target

注意: ExecStart行中的端口号与上一步中为Puma配置的端口号相同。

重新加载systemd以便读取新的服务文件,然后启用并启动app-tunnel服务:

sudo systemctl daemon-reload
sudo systemctl enable app-tunnel.service
sudo systemctl start app-tunnel.service

检查隧道是否启动:

ps axu | grep tunnel

你应该看到类似下面的输出:

tunnel   19469  0.0  0.1   4376   752 ?        Ss   05:45   0:00 /usr/lib/autossh/autossh -N -L 9292:localhost:9292 tunnel@app-server
tunnel   19482  0.5  1.1  44920  5568 ?        S    05:45   0:00 /usr/bin/ssh -L 54907:127.0.0.1:54907 -R 54907:127.0.0.1:54908 -N -L 9292:localhost:9292 tunnel@app-server
sammy    19484  0.0  0.1  12916   932 pts/0    S+   05:45   0:00 grep --color=auto tunnel

这个过滤的进程列表显示autossh正在运行,并且它启动了另一个ssh进程,它在web-serverapp-server之间创建实际的加密通道。

您的第二条隧道现在已经启动,并正在加密您的网络服务器应用程序服务器之间的通信。 为了让您的三层Rails应用程序正常运行,您需要做的就是配置Nginx将请求传递给Puma。

第8步 - 配置Nginx

此时,所有必需的SSH连接和隧道都已建立,并且您的三个服务器层中的每一个都可以相互通信。 这个难题的最后一部分是让你配置Nginx向Puma发送请求,以使设置完全正常运行。

网络服务器上 ,在/etc/nginx/sites-available/ appname创建一个新的Nginx配置文件:

sudo nano /etc/nginx/sites-available/appname

将以下内容添加到文件中。 这个Nginx配置文件与您使用的配置文件类似,如果您按照关于如何部署Puma和Nginx的Rails应用程序的指南。 主要区别在于上游应用程序的位置; 而不是使用本地套接字文件,该配置将Nginx指向监听端口9292的SSH隧道:

在/ etc / nginx的/网站可用/应用程序的名字
upstream app {
    server 127.0.0.1:9292;
}

server {
    listen 80;
    server_name localhost;

    root /home/sammy/appname/public;

    try_files $uri/index.html $uri @app;

    location @app {
        proxy_pass http://app;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;
    }

    error_page 500 502 503 504 /500.html;
    client_max_body_size 4G;
    keepalive_timeout 10;
}

保存并关闭此文件,然后启用该站点并使更改处于活动状态。

首先,删除默认网站:

sudo rm /etc/nginx/sites-enabled/default

切换到Nginx sites-enabled目录:

cd /etc/nginx/sites-enabled

sites-enabled目录中创建一个符号链接 ,以便在刚才创建的sites-available目录中创建文件:

sudo ln -s /etc/nginx/sites-available/appname appname

测试你的Nginx配置的语法错误:

sudo nginx -t

如果有任何错误报告,请返回并检查您的文件,然后再继续。

当你准备好时,重新启动Nginx,以便它读取你的新配置:

sudo systemctl restart nginx

如果您在先决条件中遵循Puma教程,则应该在应用服务器上安装Nginx和PostgreSQL。 这两个程序都被另外两台服务器上运行的独立实例所取代,所以这些程序是多余的。 因此,您应该从应用程序服务器中删除这些软件包:

sudo apt remove nginx
sudo apt remove postgresql

删除这些软件包后,请务必更新您的防火墙规则,以防止任何不需要的流量访问这些端口。

您的Rails应用程序正在投入生产。 在网页浏览器中访问您的网络服务器的公共IP,以查看它的实际运行情况:

http://web-server_public_IP/tasks

结论

通过遵循本教程,您已经将您的Rails应用程序部署在三层体系结构中,并使用加密的SSH隧道保护从Web服务器应用程序服务器以及从应用程序服务器数据库服务器的连接。

通过将应用程序的各个组件放在不同的服务器上,您可以根据网站收到的流量来为每台服务器选择最佳规格。 这样做的第一步是监视服务器消耗的资源。 有关如何监视服务器CPU使用情况的说明,请参阅我们的CPU监视指南 如果您发现某一层的CPU或内存使用率非常高,则可以单独调整该层上的服务器大小。 有关选择服务器大小的更多建议,请参阅我们的关于为您的应用程序选择正确的Droplet的指南。

作为紧接着的一步,您还应该通过在Web服务器上安装SSL证书,确保用户与Web服务器之间的连接。 查看Nginx的Let's Encrypt教程以获取相关说明。 另外,如果您想了解更多关于使用SSH隧道的信息,请查看本指南


分享按钮