3つの仕組みは止める場所と見る中身が違う

OSのファイアウォール、事業者側のパケットフィルタ(セキュリティグループ)、WAFは、どれも不要な通信を止める仕組みです。違いは2つあります。1つは通信を止める場所です。もう1つは、通信のどの部分を見て判断するかです。前の2つは送信元IPアドレス、ポート番号、プロトコルを見ます。WAFは、Webへのリクエストの中身を見ます。

名称動く場所判断に使う情報止める通信の例
OSのファイアウォール(ufw/firewalld)サーバーのOSの中IPアドレス、ポート、プロトコル22番ポートへのSSH接続を、自宅以外のIPから受け付けない
パケットフィルタ/セキュリティグループ事業者のネットワーク上(サーバーの手前)IPアドレス、ポート、プロトコル3306番(MySQL)への接続がサーバーに届く前に破棄する
WAFWebサーバーの手前、またはWebサーバーのモジュールHTTPリクエストのURL、パラメータ、ヘッダーSQLインジェクションを狙った文字列を含むリクエストを拒否する

OSのファイアウォール:サーバー自身が門番になる

ufwとfirewalldは、Linuxカーネルのパケット処理機能(netfilter)を扱いやすくする管理ツールです。ufwはUbuntuで標準的に使われます。firewalldはRHEL系(AlmaLinux、Rocky Linuxなど)で標準的に使われます。どちらも、パケットがサーバーに届いた後でOSが受け入れるかどうかを決めます。

# ufw:SSHとHTTPSを許可して有効化
sudo ufw allow 22/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status verbose

# firewalld:HTTPSを恒久的に許可して反映
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
sudo firewall-cmd --list-all

この仕組みはサーバーと一緒に動きます。事業者や環境を移っても、同じ設定を持っていけます。弱点は、設定を誤ってSSHを閉じると自分も締め出されることです。ufwを有効にする前に、SSHのポートを許可してください。

パケットフィルタ/セキュリティグループ:サーバーの手前で止める

VPSやクラウドの多くは、コントロールパネルから設定する通信フィルタを用意しています。名称は事業者で異なります。AWSでは「セキュリティグループ」、さくらのVPSでは「パケットフィルター」と呼びます。見る情報はOSのファイアウォールとほぼ同じです。違いは、事業者のネットワーク上で処理されることです。拒否された通信はサーバーに届きません。

OSの外にあるため、サーバー内の設定を誤っても効き続けます。OSの設定ミスでSSHに入れなくなっても、こちらはパネルから変更できます。一方で、存在を知らないと原因に気づけません。VPSによっては初期状態で一部のポートしか許可していないため、OS側で開けただけではつながりません。

WAF:Webリクエストの中身を検査する

WAF(Web Application Firewall)は、HTTP/HTTPSの通信の中身を検査します。ポート443への接続を許可した後で、そのリクエストが攻撃に見えるかどうかを判断します。例えば、検索パラメータに不審なSQL文が含まれる場合や、スクリプトを埋め込もうとする文字列がある場合に拒否します。

形態は3つあります。1つ目はAWS WAFやCloudflareのように、サーバーの手前で動くサービスです。2つ目はApacheやnginxに組み込むModSecurityのようなモジュールです。3つ目は、共用レンタルサーバーのコントロールパネルにあるWAF機能です。どの形態でも、対象はWebの通信だけです。SSHやデータベースの通信は検査しません。

実際に起きるつまずき

ポートを開けたのにつながらない

外からの通信は、事業者側のフィルタ、OSのファイアウォール、アプリケーションの順に通ります。すべてで許可されていないと届きません。ufwで8080番を開けても、セキュリティグループで閉じていればつながりません。もう1つ多い原因は、アプリケーションが127.0.0.1(サーバー自身からの接続)だけで待ち受けている状態です。この場合は、どちらのフィルタを開けても外からは届きません。

二重に設定して混乱する

両方で設定すると、片方だけ変更して食い違いが起きます。SSHのポート番号を変えたときが典型です。OS側だけ新しいポートを開け、事業者側を変え忘れると、ログインできなくなります。対策として、役割を決めておきます。例えば、事業者側では公開するポートの大枠を決め、OS側では同じ方針に加えて接続元IPの制限をかけます。変更するときは必ず両方を確認する、という運用ルールも合わせて決めます。

Dockerにも注意が必要です。Dockerはiptablesを直接書き換えます。そのため、-pで公開したポートはufwの拒否ルールを通らず、外から届くことがあります。事業者側のフィルタも併用すると、この抜けを防げます。

WAFがあるからOSのファイアウォールは不要だと誤解する

WAFはWebの通信しか見ません。SSH、MySQL、管理用のポートへの攻撃は、WAFがあっても防げません。また、サーバーの手前で動くWAFは、攻撃者がサーバーのIPアドレスに直接アクセスすれば素通りされます。手前のWAFを使う場合は、OSか事業者側のフィルタで、Webのポートへの接続をWAF事業者が公開するIP範囲だけに制限します。

つながらないときの確認順

内側から外側へ順に確認すると、原因の層を絞り込めます。

  1. sudo ss -tlnpで、アプリケーションが目的のポートで待ち受けているか確認します。待ち受けアドレスが127.0.0.1なら、0.0.0.0などに変更します。
  2. サーバー内でcurl -v http://localhost:ポート番号を実行し、アプリケーションが応答するか確認します。
  3. sudo ufw status verboseまたはsudo firewall-cmd --list-allで、OS側の許可を確認します。
  4. コントロールパネルで、事業者側のフィルタまたはセキュリティグループの許可を確認します。
  5. 外部の端末からnc -zv サーバーのIP ポート番号で、ポートに到達できるか確認します。
  6. ポートに到達できるのにWebだけ失敗する場合は、WAFのログで拒否された記録がないか確認します。

自分の環境で決めておくこと

まず、自分のサーバーに3つのうちどれがあるかを確認します。共用レンタルサーバーなら、通常OSのファイアウォールは事業者が管理します。利用者が触るのはWAFの設定です。VPSやクラウドなら、OSと事業者側の両方を自分で設定します。その上で、公開するポートと接続元をまとめた一覧を作ります。両方の設定をその一覧に合わせてください。一覧があれば、変更時に設定が食い違わず、つながらないときにもどの層を見るべきか判断できます。