DigitalOceanクラウドファイアウォールで安全なWebアプリインフラストラクチャを構成する方法

前書き

DigitalOceanクラウドファイアウォールは、ネットワークレベルで強力なファイアウォールサービスを提供し、サーバーがアプリケーションを提供してデータを保存するという仕事を自由に行えるようにします。 このチュートリアルでは、2サーバーのWordpressとMySQLのセットアップをクラウドファイアウォールを使用するように調整し、このサービスが提供できる利点のいくつかを示します。 開始する前にこのファイアウォールサービスの背景について詳しく知りたい場合は、Introduction To DigitalOcean Cloud Firewallsのチュートリアルをお読みください。

前提条件

このチュートリアルを開始する前に、How To Set Up a Remote Database to Optimize Site Performance with MySQL on Ubuntu 16.04で概説されているインフラストラクチャを作成しておく必要があります。 これにより、PHPとWordPressがインストールされたNginx Webサーバーと、スタンドアロンのMySQLサーバーの2つのサーバーが残ります。 このチュートリアル全体を通して、これらのサーバーをそれぞれfrontend-01およびdatabase-01と呼びます。

現在のファイアウォールの状況

現在、両方のサーバーでufwユーティリティを使用してファイアウォールが設定されています。 ufwは、Linuxのiptablesファイアウォールエンジンの使いやすいラッパーです。 ここで両方のサーバーにログインし、ファイアウォールのステータスを確認しましょう。

まず、Webサーバーでは、frontend-01

sudo ufw status verbose
OutputStatus: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), disabled (routed)
New profiles: skip

To                         Action      From
--                         ------      ----
22/tcp (OpenSSH)           ALLOW IN    Anywhere
80,443/tcp (Nginx Full)    ALLOW IN    Anywhere
22/tcp (OpenSSH (v6))      ALLOW IN    Anywhere (v6)
80,443/tcp (Nginx Full (v6)) ALLOW IN    Anywhere (v6)

出力では、Default:の後に、ファイアウォールがデフォルトですべての着信接続を拒否し、すべての発信接続を許可していることが示されています。 さらに、ポート22(SSH)、80(HTTP)、および443(HTTPS)への着信IPv4およびIPv6 TCP接続(ALLOW IN)を許可する4つのルールがあります。

データベースサーバーdatabase-01で同じことをしましょう。

sudo ufw status verbose
OutputStatus: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), disabled (routed)
New profiles: skip

To                         Action      From
--                         ------      ----
22/tcp (OpenSSH)           ALLOW IN    Anywhere
3306                       ALLOW IN    Anywhere
22/tcp (OpenSSH (v6))      ALLOW IN    Anywhere (v6)
3306 (v6)                  ALLOW IN    Anywhere (v6)

この出力は似ていますが、2つのNginxポートを標準のMySQLポートであるポート3306に交換しました。 現在の設定がわかったので、交換を計画しましょう。

クラウドファイアウォールプラン

1つは特定のサーバーごとに調整された2つのクラウドファイアウォールを作成し、1つをfrontend-01に、もう1つをdatabase-01に適用することもできますが、ルールの編成方法に対してより柔軟なアプローチを採用します。 。

最初に、このシステム(おそらくキャッシュサーバー)に3番目のタイプのサービスを追加する必要がある将来に備えて、自分自身を準備したいです。 そこで、物理サーバーではなく、役割に基づいてファイアウォールルールを分割します。 各ドロップレットに複数のクラウドファイアウォールを適用できるため、これらのファイアウォールをきめ細かくモジュール化することは問題ではありません。

[.note]#Note:クラウドファイアウォールの構築に関するベストプラクティスのより詳細な調査が必要な場合は、How To Organize DigitalOcean Cloud Firewalls
#をお読みください。

少し分解すると、両方のサーバーに実際に複数の機能があることがわかります。 Webページまたはデータベース情報を提供する主要な機能があり、SSHサービスによって提供される管理機能もあります。 managementファイアウォール、frontendファイアウォール、およびdatabaseファイアウォールを作成することは理にかなっています。

Webサービスまたはデータベースサービスを複数のホストに拡張する将来のシナリオを処理するために、DigitalOceanのタグ付け機能を使用して、ロールレットをロール別に整理します。 タグは、ドロップレットに適用してそれらを分類し、サーバーのグループ全体を一度にアドレス指定できる単純なラベルです。 クラウドファイアウォールサービスは、タグ内のすべてのドロップレットにファイアウォールルールを適用できるため、正しいファイアウォールルールが既に設定されている新しいドロップレットを簡単にプロビジョニングできます。

追加のボーナス(およびufwを使用して動的に行うのが難しいこと)は、クラウドファイアウォールがタグに基づいてインバウンドアクセスを制限できることです。 したがって、たとえば、databaseサーバーは、frontendサーバーからのみアクセス可能である必要があります。 現在のufwセットアップでは、データベースはネットワーク上の誰にでも開かれています。 frontendでタグ付けされたドロップレットのみにロックします。

設定する必要がある3つのファイアウォールを、わかりやすい言葉でまとめてみましょう。

  • Management:は、任意のホストからTCPポート22へのインバウンドトラフィックを許可します

  • Frontend:は、任意のホストからTCPポート80および443へのインバウンドトラフィックを許可します

  • Database:は、frontendタグ付きサーバーからのみTCPポート3306へのインバウンドトラフィックを許可します

このチュートリアルでは、発信トラフィックをまったく制限しません。 悪い考えではありませんが、基本となるオペレーティングシステムの自動更新メカニズムやその他の重要な機能を壊さないように注意する必要があります。

新しいファイアウォールの計画ができたので、始めましょう。

[[step-1 -—- tagging-our-servers]] ==ステップ1—サーバーにタグを付ける

最初に、ファイアウォールルールの準備として、ロールレットにロールのタグを付けます。 DigitalOceanコントロールパネルに移動します。 デフォルトのビューは、ドロップレットのリストです。 frontend-01ドロップレットの右側にあるMoreボタンをクリックし、Add tagsを選択します。

Select "Edit Tags"

このドロップレットのタグを入力できるテキストボックスがポップアップ表示されます。 frontendと入力し、Add Tagsボタンをクリックします。

Tag Editing Interface

データベースサーバーについても同じことを行い、databaseタグを付けます。 タグがドロップレットリストに表示されます。

Droplet List with Tags

将来のドロップレットを作成するときに、初期プロビジョニングプロセス中にこれらのタグを適用できます。 ドロップレットは、対応するファイアウォールルールを自動的に継承します。

次のステップでこれらのルールを設定します。

[[step-2 -—- creating-cloud-firewalls]] ==ステップ2—クラウドファイアウォールの作成

クラウドファイアウォールを設定します。 最初にfrontendファイアウォールを実行し、次にdatabase、次にmanagementを実行します。 この順序により、Webサイト訪問者のサービスが中断することはありませんが、一時的に新しいSSH接続を確立することができなくなります。 これは、すでに確立された接続には影響しません。

ファイアウォールサービスは、DigitalOceanコントロールパネルのNetworkingセクションで利用できます。 そこに到達したら、Firewallsタブをクリックし、次にCreate Firewallボタンをクリックして開始します。

フロントエンドファイアウォールの作成

Create Firewallページで、Nameに入力し、Inbound Rulesを構成し、ファイアウォールを適用するドロップレットを選択する必要があります。 Outbound Rulesセクションはそのままにしておきます。

最初にfrontendファイアウォールを作成しているので、frontend-fwNameフィールドに入力します。

[.note]#Note:ファイアウォール名の末尾に-fwを追加して、それらを明確にします。 コントロールパネルのインターフェースはアイコンを使用してリソースタイプを区別しますが、コマンドラインまたはAPIを使用していて、たとえば複数のfrontendアイテムがある場合、混乱する可能性があります。

次に、Inbound RulesセクションからデフォルトのSSHルールを削除する必要があります。 柔軟性を高めるために、このルールをmanagementファイアウォールに分割します。 ページの右側にあるDeleteリンクを使用して、SSHルールを今すぐ削除します。

次に、New ruleドロップダウンをクリックして、HTTPを選択します。 これにより、正しいプロトコル(TCP)とポート(80)が自動入力され、デフォルトですべてのIPv4およびIPv6アドレスからのトラフィックが許可されます。 これが私たちが欲しいものです。

HTTPSを有効にしている場合は、上記のプロセスを繰り返して2番目のルールを作成し、今回はHTTPSを選択します。 Inbound Rulesセクションは次のようになります。

Inbound Rules for frontend-fw

最後に、Apply to Dropletsフィールドで、frontendの入力を開始し、自動提案されたときにfrontendタグを選択します。

Apply to "frontend" tag

Create Firewallボタンをクリックします。 新しいファイアウォールが作成され、frontendタグが付いたすべてのドロップレットに適用されます。 更新されたファイアウォールの概要ページに戻り、新しいファイアウォールが表示されます。

Firewall summary with the frontend rule listed

次に、databaseファイアウォールを作成します。

Database Firewallの作成

[ファイアウォール]ページで、もう一度Create Firewallをクリックします。 プロセスは、frontendファイアウォールの場合とほとんど同じです。

Nameフィールドにdatabase-fwと入力します。

Inbound Rulesで、デフォルトのSSHルールを削除します。 次に、ドロップダウンを使用して、MySQLを選択して新しいルールを作成します。 デフォルトのMySQLルールが作成され、すべてのIPからポート3306へのアクセスが許可されます。 SourcesフィールドからAll IPv4All IPv6を削除します。 フロントエンドサーバーのみがデータベースにアクセスできるようにします。 Sourcesボックスにfrontendと入力し始め、自動提案されたら%(​​t7)sタグを選択します。 これで、そのタグが適用されたすべてのドロップレットは、データベースサーバーへのアクセスを許可されます。 他のすべてのIPはブロックされます。

Outbound Rulesはそのままにしておきます。 Apply to Dropletsの下で、このファイアウォールをdatabaseタグに適用し、Create Firewallをクリックします。 もう一度、ファイアウォールの概要ページに戻ります。

Firewall summary with database-fw and frontend-fw rules in place

両方のファイアウォールがそれぞれ1つのドロップレットに適用されることを示していることに注意してください。 Webサイトをロードしても、正常にロードされるはずです。 次に、SSHを介して管理を再度有効にします。

管理ファイアウォールの作成

最後にもう一度Create Firewallをクリックします。 Nameフィールドにmanagement-fwを追加します。

このファイアウォールに必要なのはデフォルトのSSHルールだけです。 これにより、すべてのIPがポート22に接続できるようになります。

または、SSHルールのSourcesフィールドを、接続元の特定のIPに変更することもできます。 たとえば、オフィスに静的IPがあり、SSHアクセスをオフィスからの接続のみに制限する場合は、そのIPをSourcesに入れ、All IPv4All IPv6を置き換えます。 将来IPが変更された場合、管理アクセスを復元するためにこの1つのルールを更新する必要があります。これは、事前に計画し、ルールをモジュール化するもう1つの利点です。

Apply to Dropletsの下に、frontendタグとdatabaseタグの両方を追加し、Create Firewallをクリックします。 最後のファイアウォールの概要を見てみましょう。

Firewall summary with all rules in place

この時点で、クラウドファイアウォールは完全に機能しているはずですが、ホストベースのufwファイアウォールもアクティブになっています。 それらを無効にして、接続をテストしましょう。

[[step-3 -—- dropping-the-host-firewalls]] ==ステップ3—ホストファイアウォールの削除

両方のホストでufwファイアウォールを無効にする必要があります。 まず、frontend-01で:

sudo ufw disable
OutputFirewall stopped and disabled on system startup

次に、database-01で:

sudo ufw disable
OutputFirewall stopped and disabled on system startup

これにより、現在のファイアウォールが停止し、すべてのルールが消去され、起動時にルールが再度有効になりません。

この時点で、すべての接続が復元されます。 サーバーの1つに新しいSSHセッションを作成してみてください。 次に、Webサイトをロードして、Webサーバーがまだデータベースに接続し、ブラウザーにWebページを返していることを確認します。

ただし、すべてのサービスに接続できるからといって、実際にはファイアウォールが機能しているとは限りません。 ファイアウォールが実際に配置されていることを確認するために、もう少しテストを行いましょう。

[[step-4 -—- testing-our-firewalls]] ==ステップ4—ファイアウォールのテスト

ファイアウォールをテストするために、3番目のサーバーにログインし、nmapというユーティリティを使用してWebサーバーとデータベースサーバーをスキャンします。 nmapは、ホストをスキャンして、開いている、閉じている、またはフィルタリングされているポートを通知するポートスキャナーです。

frontend-01およびdatabase-01サーバーと同じリージョンにある別のUbuntu16.04サーバーにログインします。 次に、nmapをインストールします。

sudo apt-get update
sudo apt-get install nmap

次に、nmapを使用してWebサーバーのパブリックIPをスキャンします。

nmap -Pn frontend-01_public_ip
OutputStarting Nmap 7.01 ( https://nmap.org ) at 2017-06-05 17:08 UTC
Nmap scan report for 203.0.113.11
Host is up (0.0022s latency).
Not shown: 997 filtered ports
PORT    STATE SERVICE
22/tcp  open  ssh
80/tcp  open  http
443/tcp open  https

Nmap done: 1 IP address (1 host up) scanned in 4.54 seconds

filtered portsに関する出力に注意してください。 ファイアウォールが機能していなかった場合、これらはclosed portsとして表示されます。 Filteredは、nmapが接続して、ポートが開いているか閉じているかを判断できないことを意味します。

また、予想どおり、SSH、HTTP、およびHTTPSポートが開いていることにも注意してください。

次に、データベースサーバーをスキャンします。 そのように設定した場合は、MySQLデータベースがリッスンするものであるため、必ずDropletのプライベートIPを使用してください。

nmap -Pn database-01_private_ip
OutputStarting Nmap 7.01 ( https://nmap.org ) at 2017-06-05 17:21 UTC
Nmap scan report for 198.51.100.20
Host is up (0.0024s latency).
Not shown: 999 filtered ports
PORT   STATE SERVICE
22/tcp open  ssh

Nmap done: 1 IP address (1 host up) scanned in 8.17 seconds

以前と同様に、ほとんどのポートがフィルタリングされていることがわかります。 ただし、SSHポートは開いているとのみ表示され、MySQLポートは使用できません。 データベースアクセスをfrontendでタグ付けされたサーバーのみに制限したことを思い出してください。 DigitalOceanコントロールパネルに戻り、nmapを使用しているサーバーにfrontendタグを追加します。 次に、コマンドを再実行します。

nmap -Pn database-01_private_ip
OutputStarting Nmap 7.01 ( https://nmap.org ) at 2017-06-05 17:22 UTC
Nmap scan report for 198.51.100.20
Host is up (0.0033s latency).
Not shown: 998 filtered ports
PORT     STATE SERVICE
22/tcp   open  ssh
3306/tcp open  mysql

Nmap done: 1 IP address (1 host up) scanned in 4.46 seconds

MySQLポートが開いていると表示されます。 両方のサーバーがCloud Firewallルールによって保護されていることを確認しました。 これで、コントロールパネルに戻り、ドロップレットのfrontendタグを削除することで、このテストサーバーの元のファイアウォール設定を復元できます。

結論

このチュートリアルでは、ufwファイアウォールの設定を柔軟で強力なネットワークベースのクラウドファイアウォール構成に置き換えました。 doctlまたはDigitalOcean APIを介したクラウドファイアウォールの使用の詳細については、次の記事を参照してください。

Related