在使用SSH隧道的三层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”接受应用服务器的真实性:

OutputThe 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

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

Outputtunnel   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现在正在监视隧道:

Outputtunnel   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

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

Outputpsql (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

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

Outputpuma.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和数据库连接都正常工作:

Output...

<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

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

Outputtunnel   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隧道的信息,请查看本指南

赞(52) 打赏
未经允许不得转载:优客志 » 系统运维
分享到:

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏