SSHトンネルを使用した3層Railsアプリケーションでの通信の保護
序章
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をインストールします。 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インストールで設定したものと同じである必要があることに注意してください。
- PostgreSQLデータベースソフトウェアをインストールして構成します。 これを行う方法については、 Ubuntu16.04に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-serverとdatabase-serverのプライベートIPアドレスの両方を/etc/hosts
に追加するように指示していることに注意してください。 ]3つのサーバーのそれぞれにファイルします。 技術的には、 app-serverまたはdatabase-serverのプライベートIPアドレスを独自のhosts
ファイルに追加する必要はありませんが、追加する必要はありません。 t問題を引き起こします。 ここで説明する方法は、速度と利便性のために選択されたものです。
まず、app-serverとdatabase-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-serverがdatabase-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-serverのtunnelユーザーの公開鍵を上の/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-serverのauthorized_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-serverとdatabase-serverの間の接続を暗号化します。
このチュートリアルのすべての前提条件を順守すると、app-serverとdatabase-serverの両方にPostgreSQLがインストールされます。 ポート番号の衝突を防ぐには、これらのサーバー間のSSHトンネルを構成して、app-serverのポート5433
から[のポート5432
に接続を転送する必要があります。 X187X]データベースサーバー。 後で、Railsアプリケーション( app-server でホストされている)を再構成して、database-serverで実行されているPostgreSQLのインスタンスを使用します。
app-serverのsammyユーザーとして開始し、手順1で作成したtunnelユーザーに切り替えます。
sudo su tunnel
次のフラグとオプションを指定してssh
コマンドを実行し、app-serverとdatabase-serverの間にトンネルを作成します。
ssh -f -N -L 5433:localhost:5432 tunnel@database-server
-f
オプションは、ssh
をバックグラウンドに送信します。 これにより、トンネルがバックグラウンドプロセスとして実行され続けている間に、既存のプロンプトで新しいコマンドを実行できます。-N
オプションは、ssh
にリモートコマンドを実行しないように指示します。 これは、ポートを転送するだけなので、ここで使用されます。-L
オプションの後に、構成値5433:localhost:5432
が続きます。 これは、ローカル側のポート5433
( app-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-serverとdatabase-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ドキュメントから改作された次のコンテンツを新しいファイルに追加します。 User
、WorkingDirectory
、および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
に、ポート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インスタンスを使用するように正しく構成されていることを確認したら、間の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-serverとapp-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トンネルの使用について詳しく知りたい場合は、このガイドを確認してください。