序章

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

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

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

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

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

前提条件

このチュートリアルを完了するには、3台のUbuntu16.04サーバーを起動する必要があります。 これらにweb-server app-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をインストールします。 アセットパイプラインなどのいくつかの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チュートリアルの「CreateProductionDatabase User 」セクションの最初のコマンド( app-server のセットアップにも使用)をスキップし、残りのコマンドに従います。データベースユーザーのパスワードを変更するセクション。 database-server に設定するPostgreSQLロールの名前とパスワードは、app-serverのPostgreSQLインストールで設定したものと同じである必要があることに注意してください。

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

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

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

  1. sudo adduser tunnel

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

  1. sudo su tunnel

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

  1. ssh-keygen

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

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

  1. exit

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

  1. sudo su tunnel
  2. ssh-keygen
  3. 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ファイルを開き、次の行を追加します。

  1. 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ユーザーの公開鍵を表示します。

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

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

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

  1. sudo su tunnel

システムのクリップボードのキーをapp-serverauthorized_keysファイルに追加します。 次のコマンドを使用して、1つのステップでこれを行うことができます。 tunnel_ssh_publickey_copied_from_web_serverをシステムのクリップボードの公開鍵に置き換えることを忘れないでください。

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

その後、authorized_keysファイルのアクセス許可を変更して、ファイルへの不正アクセスを防止します。

  1. chmod 600 /home/tunnel/.ssh/authorized_keys

次に、sammyユーザーに戻ります。

  1. exit

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

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

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

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

次に、 app-serverの公開鍵をauthorized_keysファイルに追加し、そのアクセス許可を調整します。

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

次に、sammyユーザーに戻ります。

  1. exit

次に、SSHを使用して最初の接続をテストし、web-serverからtunnelユーザーとしてapp-serverに接続します。

  1. sudo su tunnel
  1. ssh tunnel@app-server

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

Output
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

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

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

  1. exit
  2. exit

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

  1. sudo su tunnel
  1. ssh tunnel@database-server

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

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

  1. exit
  2. exit

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

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

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

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