SSHトンネルを使用した3層Railsアプリケーションでの通信の保護

提供:Dev Guides
移動先:案内検索

序章

Webアプリケーションは、多くの場合、次の3つの異なる層で設計されています。

  • 最初の層はプレゼンテーション層で、これはユーザーに表示されるものです。
  • 次は、アプリケーションのビジネスロジックを提供するアプリケーション層です。
  • 最後に、データレイヤーは、アプリケーションに必要なデータを格納します。

Ruby on Rails アプリケーションでは、これはプレゼンテーション層用のWebサーバー、アプリケーション層用のRailsサーバー、およびデータ層用のデータベースに大まかにマップされます。 この設定では、アプリケーション層はデータ層と通信してアプリケーションのデータを取得し、プレゼンテーション層を介してユーザーに表示されます。

これらすべてのアプリケーションを単一のサーバーにインストールすることは可能ですが、各レイヤーを独自のサーバーに配置すると、アプリケーションのスケーリングが容易になります。 たとえば、Railsサーバーがボトルネックになった場合、他の2つのレイヤーに影響を与えることなくアプリケーションサーバーを追加できます。

このチュートリアルでは、3つの別々のサーバーに独自のソフトウェアセットをインストールし、各サーバーとそのコンポーネントが相互に通信して機能するように構成し、SSHトンネルを使用してサーバー間の接続を保護することにより、Railsアプリを3層構成でデプロイします。 ソフトウェアスタックの場合、プレゼンテーション層のWebサーバーとして Nginx 、アプリケーション層のRailsアプリケーションサーバーとして Puma 、およびアプリケーション層のPostgreSQLを使用します。データ層のデータベース。

前提条件

このチュートリアルを完了するには、3台のUbuntu16.04サーバーを起動する必要があります。 これらにweb-serverapp-server 、および database-server という名前を付け、それぞれでプライベートネットワークを有効にする必要があります。

3つのサーバーにはそれぞれ、sudo権限を持つroot以外のユーザーと、SSH接続を許可するように構成されたファイアウォール(初期サーバーセットアップガイドを使用して構成できます)が必要です。 このチュートリアルのコンテキストでは、各サーバーのsudoユーザーの名前はsammyです。

さらに、3つのサーバーには、それぞれ独自の構成要件があります。

  • Webサーバーの場合:
    • NginxWebサーバーをインストールして構成します。 これを行うには、 Ubuntu16.04にNginxをインストールする方法に関するチュートリアルに従ってください。
  • app-server の場合:
    • Ubuntu 16.04 にNode.jsをインストールする方法で説明されているように、公式PPAを使用してNode.jsをインストールします。 Asset PipelineなどのいくつかのRails機能はJavaScriptランタイムに依存しており、Node.jsがこの機能を提供します。
    • RubyonRailsフレームワークをインストールします。 これを行うには、 Ubuntu16.04でrbenvを使用してRubyonRailsをインストールする方法に関するガイドに従ってください。 このチュートリアルに従うときは、Rubyの最新バージョン(この記事の執筆時点ではRuby 2.5.1)を必ずインストールしてください。
    • チュートリアルUbuntu14.04のRubyonRailsアプリケーションでPostgreSQLを使用する方法の最初のセクションに示されているようにPostgreSQLをインストールします。 このセクションでは、この3層セットアップに必要な別のパッケージであるlibpq-devのインストール方法についても説明します。
    • Pumaを使用してRailsアプリをデプロイします。 デプロイする独自のアプリがない場合は、PumaとNginxを使用してRailsアプリをデプロイする方法のガイドに従ってサンプルアプリをデプロイしてください。 この前提条件の「rbenv-varsプラグインのインストール」セクションで、database-serverにPostgreSQLをインストールするときに使用する値を反映するようにデータベースユーザーとパスワードを設定する必要があることに注意してください。 また、「本番データベースの作成」セクションが機能するには、ポート3000がファイアウォールを通過できるようにする必要があります。 最後に、この前提条件チュートリアルの最後の2つのステップである「PumaUpstartスクリプトの作成」と「Nginxのインストールと構成」を完了する必要はありません。
  • データベースサーバーの場合:
    • PostgreSQLデータベースソフトウェアをインストールして構成します。 これを行う方法については、 Ubuntu16.04にPostgreSQLをインストールして使用する方法に関するガイドに従ってください。 この前提条件のチュートリアルに従うときに、superuser権限を持つRailsアプリのPostgreSQLロールと、PostgreSQLロールと同じ名前のデータベースを作成します。 このチュートリアル全体を通して、PostgreSQLの役割とデータベースは両方ともsammyと呼ばれます。
    • 新しく作成されたPostgreSQLロールのパスワードを設定します。 Pumaチュートリアルの「本番データベースユーザーの作成」セクションの最初のコマンド( app-server のセットアップにも使用)をスキップし、残りのコマンドに従います。データベースユーザーのパスワードを変更するセクション。 database-server に設定するPostgreSQLロールの名前とパスワードは、app-serverのPostgreSQLインストールで設定したものと同じである必要があることに注意してください。

ステップ1—SSHトンネルのユーザーを作成する

SSHトンネルは暗号化された接続であり、あるサーバーのポートから別のサーバーのポートにデータを送信できるため、2番目のサーバーのリスニングプログラムが最初のサーバーで実行されているように見えます。 SSHトンネル専用のユーザーがいると、セットアップのセキュリティが向上します。侵入者がサーバーの1つで sammy ユーザーにアクセスした場合、侵入者はサーバー内の他のサーバーにアクセスできなくなります。 3層のセットアップ。 同様に、侵入者が tunnel ユーザーにアクセスした場合、Railsアプリディレクトリ内のファイルを編集したり、sudoコマンドを使用したりすることはできません。

各サーバーで、tunnelという名前の追加ユーザーを作成します。 tunnel ユーザーの唯一の機能は、サーバー間の通信を容易にするSSHトンネルを作成することです。したがって、 sammy とは異なり、 tunnel sudoを指定しないでください。特権。 また、 tunnel ユーザーは、Railsアプリディレクトリへの書き込みアクセス権を持ってはなりません。 各サーバーで次のコマンドを実行して、tunnelユーザーを追加します。

sudo adduser tunnel

web-server マシンで、tunnelユーザーに切り替えます。

sudo su tunnel

tunnel ユーザーとして、SSHキーペアを生成します。

ssh-keygen

キーをデフォルトの場所に保存し、キーのパスフレーズを作成しないでください。パスフレーズを作成すると、後でサーバー間にSSHトンネルを作成するときに認証が複雑になる可能性があります。

キーペアを作成したら、sammyユーザーに戻ります。

exit

次に、 app-server に切り替えて、同じコマンドを再度実行します。

sudo su tunnel
ssh-keygen
exit

これで、チュートリアルの残りの部分で必要になるすべてのユーザーが構成されました。 ネットでは、SSHトンネルの作成プロセスを合理化するために、tunnelユーザーごとに/etc/hostsファイルにいくつかの変更を加えます。

ステップ2—Hostsファイルの構成

このチュートリアル全体を通して、コマンドでapp-serverまたはdatabase-serverのいずれかのIPアドレスを参照する必要がある場合がよくあります。 これらのIPアドレスを毎回覚えて入力する必要はなく、app-serverおよびdatabase-serverのプライベートIPを各サーバーの/etc/hostsに追加できます。ファイル。 これにより、後続のコマンドでアドレスの代わりに名前を使用できるようになり、SSHトンネルの設定プロセスがはるかにスムーズになります。

簡単にするために、このチュートリアルでは、app-serverdatabase-serverのプライベートIPアドレスの両方を/etc/hostsに追加するように指示していることに注意してください。 ]3つのサーバーのそれぞれにファイルします。 技術的には、 app-serverまたはdatabase-serverのプライベートIPアドレスを独自のhostsファイルに追加する必要はありませんが、追加する必要はありません。 t問題を引き起こします。 ここで説明する方法は、速度と利便性のために選択されたものです。

まず、app-serverdatabase-serverのプライベートIPアドレスを見つけます。 DigitalOceanドロップレットを使用している場合は、コントロールパネルに移動して、これらのドロップレットの名前をクリックします。 ドロップレット固有のページでは、パブリックIPアドレスとプライベートIPアドレスの両方がページの上部に表示されます。

次に、各サーバーで、お気に入りのテキストエディタで/etc/hostsファイルを開き、次の行を追加します。

sudo nano /etc/hosts

/ etc / hosts

. . .
app-server_private_ip app-server
database-server_private_ip database-server

各サーバーのこのファイルにこれらの行を追加することにより、通常これらのサーバーのIPアドレスを使用する必要があるコマンドでapp-serverおよびdatabase-serverという名前を使用できます。 この機能を使用してSSHキーを設定し、各tunnelユーザーが他のサーバーに接続できるようにします。

ステップ3—SSHログインの設定

これで、 tunnel ユーザーと、3つのサーバーすべてに更新された/etc/hostsファイルができたので、サーバー間のSSH接続の作成を開始する準備が整いました。

この手順を実行するときは、ピラミッドのような3つの層について考えてください。下部にデータベースサーバー、中央にアプリサーバーがあります。上部にあるweb-server。 Railsアプリに必要なデータにアクセスするには、app-serverdatabase-serverに接続できる必要があり、web-serverが必要です。 app-server に接続できるので、ユーザーに何かを提示できます。

したがって、各 tunnel ユーザーのSSH公開キーをその「下」のサーバーに追加するだけで済みます。つまり、 web-server tunnelユーザーを追加する必要があります。 app-server に公開鍵を設定し、 app-server tunnelユーザーの公開鍵をdatabase-serverに追加します。 これにより、階層間に暗号化されたSSHトンネルを確立し、ネットワーク上の盗聴者が階層間を通過するトラフィックを読み取らないようにすることができます。

このプロセスを開始するには、/home/tunnel/.ssh/id_rsa.pubにあるweb-servertunnelユーザーの公開鍵を上の/home/tunnel/.ssh/authorized_keysファイルにコピーします。 app-server

web-server で、次のコマンドを使用して、ターミナルにtunnelユーザーの公開鍵を表示します。

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

テキスト出力を選択し、システムのクリップボードにコピーします。

別のターミナルセッションでapp-serverにSSHで接続し、トンネルユーザーに切り替えます。

sudo su tunnel

システムのクリップボードのキーをapp-serverauthorized_keysファイルに追加します。 次のコマンドを使用して、1つのステップでこれを行うことができます。 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

次に、 app-server/home/tunnel/.ssh/id_rsa.pubにあります)に tunnel ユーザーの公開鍵を表示し、/home/tunnel/.ssh/authorized_keysファイルに貼り付けます。 データベースサーバー

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

database-server でSSHキーペアを生成しなかったため、/home/tunnel/.sshフォルダーを作成し、そのアクセス許可を調整する必要があります。

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

次に、 app-serverの公開鍵を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-serverからtunnelユーザーとしてapp-serverに接続します。

sudo su tunnel
ssh tunnel@app-server

web-serverからapp-serverに初めて接続すると、接続しているマシンが信頼できることを確認するように求めるメッセージが表示されます。 「yes」と入力して、app-serverの信頼性を受け入れます。

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

app-server からウェルカムバナーが表示され、コマンドプロンプトにapp-serverにログインしていることが示されます。 これにより、web-serverからapp-serverへのSSH接続が正しく機能していることが確認されます。

app-server へのSSH接続を終了し、 tunnel ユーザーを終了して、web-serverのsammy[に戻ります。 X150X]ユーザー:

exit
exit

次に、次の同じ手順に従って、app-serverからdatabase-serverへのSSH接続をテストします。

sudo su tunnel
ssh tunnel@database-server

database-serverの信頼性も受け入れます。 database-server からウェルカムバナーとコマンドプロンプトが表示されると、app-serverからdatabase-serverへのSSH接続がわかります。期待どおりに動作しています。

database-server へのSSH接続を終了してから、tunnelユーザーを終了します。

exit
exit

手順で設定したSSH接続は、3つのサーバー層間の安全な通信を可能にするSSHトンネルの基礎を形成します。 ただし、現在の形式では、これらの接続はクラッシュに対して脆弱であるため、信頼性は低くなります。 ただし、いくつかの追加ソフトウェアをインストールし、サービスとして機能するようにトンネルを構成することで、これらの脆弱性を軽減できます。

ステップ4—データベースサーバーへの永続的なSSHトンネルを設定する

最後の手順では、ローカルサーバーからリモートサーバーのコマンドプロンプトにアクセスしました。 SSHトンネルを使用すると、ローカルホストのポートからリモートホストのポートにトラフィックをトンネリングすることで、これ以上のことができます。 ここでは、SSHトンネルを使用して、app-serverdatabase-serverの間の接続を暗号化します。

このチュートリアルのすべての前提条件を順守すると、app-serverdatabase-serverの両方にPostgreSQLがインストールされます。 ポート番号の衝突を防ぐには、これらのサーバー間のSSHトンネルを構成して、app-serverのポート5433から[のポート5432に接続を転送する必要があります。 X187X]データベースサーバー。 後で、Railsアプリケーション( app-server でホストされている)を再構成して、database-serverで実行されているPostgreSQLのインスタンスを使用します。

app-serversammyユーザーとして開始し、手順1で作成したtunnelユーザーに切り替えます。

sudo su tunnel

次のフラグとオプションを指定してsshコマンドを実行し、app-serverdatabase-serverの間にトンネルを作成します。

ssh -f -N -L 5433:localhost:5432 tunnel@database-server
  • -fオプションは、sshをバックグラウンドに送信します。 これにより、トンネルがバックグラウンドプロセスとして実行され続けている間に、既存のプロンプトで新しいコマンドを実行できます。
  • -Nオプションは、sshにリモートコマンドを実行しないように指示します。 これは、ポートを転送するだけなので、ここで使用されます。
  • -Lオプションの後に、構成値5433:localhost:5432が続きます。 これは、ローカル側のポート5433app-server )からのトラフィックがリモートのlocalhostのポート5432に転送されることを指定しますサーバー( database-server )。 ここでのlocalhostは、リモートサーバーの観点からのものであることに注意してください。
  • コマンドの最後の部分であるtunnel@database-serverは、接続するユーザーとリモートサーバーを指定します。

SSHトンネルを確立した後、sammyユーザーに戻ります。

exit

この時点で、トンネルは実行されていますが、トンネルが稼働していることを確認するためにトンネルを監視しているものはありません。 プロセスがクラッシュすると、トンネルがダウンし、Railsアプリがデータベースと通信できなくなり、エラーが発生し始めます。

より信頼性の高いセットアップを行うため、今のところ作成したトンネルを強制終了します。 接続はバックグラウンドで行われるため、接続を切断するにはプロセスIDを見つける必要があります。 すべてのトンネルはtunnelユーザーによって作成されるため、現在のプロセスを一覧表示し、キーワード「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シェルを起動してから、autosshプログラムを実行します。

ファイルを保存して閉じてから、systemd構成をリロードして、新しいサービスファイルが確実に取得されるようにします。

sudo systemctl daemon-reload

db-tunnelサービスを有効にして、サーバーが起動するたびにdatabase-serverへのトンネルが自動的に開始されるようにします。

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

トンネルが稼働しているので、 database-server への接続をpsqlでテストして、正しく機能していることを確認できます。

psqlクライアントを起動し、localhostに接続するように指示します。 また、SSHトンネルを介して database-server 上のPostgreSQLインスタンスに接続するには、ポート5433を指定する必要があります。 以前に作成したデータベース名を指定し、プロンプトが表示されたらデータベースユーザー用に作成したパスワードを入力します。

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を押します。

最後に、app-serverdatabase-serverの間のトラフィックを暗号化する永続的で信頼性の高いSSHトンネルができました。 app-serverのRailsアプリがdatabase-server のPostgreSQLインスタンスと通信するのはこのトンネルを経由するため、トンネルのセキュリティ機能が重要です。

ステップ5—リモートデータベースを使用するためのRailsの構成

app-serverからdatabase-serverへのトンネルが設定されたので、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

database-server で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

終了したら、このファイルを保存して閉じます。

Railsアプリをデプロイしたapp-serverではなく、 database-server でPostgreSQLインスタンスを使用しているため、データベースを再度セットアップする必要があります。 。

app-server で、アプリのディレクトリに移動し、rakeコマンドを実行してデータベースをセットアップします。

注:このコマンドは、既存のデータベースから新しいデータベースにデータを移行しません。 データベースにすでに重要なデータがある場合は、それをバックアップしてから、後で復元する必要があります。


cd /home/sammy/appname
rake db:setup

このコマンドが完了すると、Railsアプリは暗号化されたSSHトンネルを介してdatabase-server上のPostgreSQLインスタンスとの通信を開始します。 次に行うことは、管理を容易にするためにPumaをsystemdサービスとして構成することです。

ステップ6—Pumaの構成と開始

手順4でdb-tunnelサービスを設定する方法と同様に、Puma( app-serverにインストールしたサーバーソフトウェアの一部としてインストールしたサーバーソフトウェア)を実行するようにsystemdを構成します。前提条件)サービスとして。 Pumaをサービスとして実行すると、サーバーの起動時に自動的に起動したり、サーバーがクラッシュした場合に自動的に再起動したりできるため、展開がより堅牢になります。

/lib/systemd/system/ディレクトリ内にpuma.serviceという名前の新しいファイルを作成します。

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

Pumaのsystemdドキュメントから改作された次のコンテンツを新しいファイルに追加します。 UserWorkingDirectory、およびExecStartディレクティブで強調表示されている値を更新して、独自の構成を反映させてください。

/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を使用してWebページのコンテンツにアクセスして印刷し、正しく提供されていることを確認します。 次のコマンドは、curlに、ポート9292app-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インスタンスを使用するように正しく構成されていることを確認したら、間のSSHトンネルの設定に進むことができます。 web-serverおよびapp-server

ステップ7—アプリケーションサーバーへのSSHトンネルの設定と永続化

app-server が稼働しているので、web-serverに接続できます。 手順4で行ったプロセスと同様に、別のSSHトンネルを設定してこれを行います。 このトンネルにより、 web-server 上のNginxは、暗号化された接続を介してapp-server上のPumaに安全に接続できます。

ウェブサーバーautosshをインストールすることから始めます。

sudo apt-get install autossh

/lib/systemd/system/ディレクトリにapp-tunnel.serviceという名前の新しいファイルを作成します。

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

このファイルに次のコンテンツを追加します。 ここでも、キーラインはExecStartで始まるものです。 ここで、この行は、 web-serverのポート9292を、Pumaがリッスンしているapp-serverのポート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が実行中であり、web-serverとapp-server[の間に実際の暗号化トンネルを作成する別のsshプロセスを開始したことを示しています。 X195X]。

これで2番目のトンネルが稼働し、web-serverapp-server間の通信が暗号化されます。 3層のRailsアプリを起動して実行するために必要なことは、Pumaにリクエストを渡すようにNginxを構成することだけです。

ステップ8—Nginxを構成する

この時点で、必要なすべてのSSH接続とトンネルが設定され、3つのサーバー層のそれぞれが相互に通信できるようになります。 このパズルの最後のピースは、セットアップを完全に機能させるためにPumaにリクエストを送信するようにNginxを構成することです。

web-server で、/etc/nginx/sites-available/appnameに新しいNginx構成ファイルを作成します。

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

次のコンテンツをファイルに追加します。 このNginx構成ファイルは、PumaとNginxを使用してRailsアプリをデプロイする方法のガイドに従った場合に使用したものと似ています。 主な違いは、アップストリームアプリの場所です。 ローカルソケットファイルを使用する代わりに、この構成はNginxがポート9292でリッスンしているSSHトンネルを指すようにします。

/ etc / nginx / sites-available / appname

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

Nginxsites-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チュートリアルに従った場合、app-serverにNginxとPostgreSQLがインストールされているはずです。 両方とも、他の2つのサーバーで実行されている別々のインスタンスに置き換えられたため、これらのプログラムは冗長です。 したがって、これらのパッケージをapp-serverから削除する必要があります。

sudo apt remove nginx
sudo apt remove postgresql

これらのパッケージを削除した後は、ファイアウォールルールを更新して、不要なトラフィックがこれらのポートにアクセスしないようにしてください。

Railsアプリは現在本番環境にあります。 Webブラウザでweb-serverのパブリックIPにアクセスして、実際の動作を確認してください。

http://web-server_public_IP/tasks

結論

このチュートリアルに従うことで、Railsアプリケーションを3層アーキテクチャにデプロイし、ウェブサーバーからアプリサーバー、およびからの接続を保護しました。 app-serverからdatabase-serverへの暗号化されたSSHトンネル。

アプリケーションのさまざまなコンポーネントを別々のサーバーに配置すると、サイトが受信するトラフィックの量に基づいて、各サーバーに最適な仕様を選択できます。 これを行うための最初のステップは、サーバーが消費しているリソースを監視することです。 サーバーのCPU使用率を監視する方法については、CPU監視ガイドを参照してください。 1つの層のCPUまたはメモリの使用量が非常に多い場合は、その層のサーバーのサイズを単独で変更できます。 サーバーサイズの選択に関する詳細なアドバイスについては、アプリケーションに適したドロップレットの選択に関するガイドを参照してください。

次のステップとして、 web-server にSSL証明書をインストールして、ユーザーからweb-serverへの接続を保護する必要があります。 手順については、 NginxLet'sEncryptチュートリアルをご覧ください。 また、SSHトンネルの使用について詳しく知りたい場合は、このガイドを確認してください。