3つの仕組みは止める場所と見る中身が違う
OSのファイアウォール、事業者側のパケットフィルタ(セキュリティグループ)、WAFは、どれも不要な通信を止める仕組みです。違いは2つあります。1つは通信を止める場所です。もう1つは、通信のどの部分を見て判断するかです。前の2つは送信元IPアドレス、ポート番号、プロトコルを見ます。WAFは、Webへのリクエストの中身を見ます。
| 名称 | 動く場所 | 判断に使う情報 | 止める通信の例 |
|---|---|---|---|
| OSのファイアウォール(ufw/firewalld) | サーバーのOSの中 | IPアドレス、ポート、プロトコル | 22番ポートへのSSH接続を、自宅以外のIPから受け付けない |
| パケットフィルタ/セキュリティグループ | 事業者のネットワーク上(サーバーの手前) | IPアドレス、ポート、プロトコル | 3306番(MySQL)への接続がサーバーに届く前に破棄する |
| WAF | Webサーバーの手前、または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範囲だけに制限します。
つながらないときの確認順
内側から外側へ順に確認すると、原因の層を絞り込めます。
sudo ss -tlnpで、アプリケーションが目的のポートで待ち受けているか確認します。待ち受けアドレスが127.0.0.1なら、0.0.0.0などに変更します。- サーバー内で
curl -v http://localhost:ポート番号を実行し、アプリケーションが応答するか確認します。 sudo ufw status verboseまたはsudo firewall-cmd --list-allで、OS側の許可を確認します。- コントロールパネルで、事業者側のフィルタまたはセキュリティグループの許可を確認します。
- 外部の端末から
nc -zv サーバーのIP ポート番号で、ポートに到達できるか確認します。 - ポートに到達できるのにWebだけ失敗する場合は、WAFのログで拒否された記録がないか確認します。
自分の環境で決めておくこと
まず、自分のサーバーに3つのうちどれがあるかを確認します。共用レンタルサーバーなら、通常OSのファイアウォールは事業者が管理します。利用者が触るのはWAFの設定です。VPSやクラウドなら、OSと事業者側の両方を自分で設定します。その上で、公開するポートと接続元をまとめた一覧を作ります。両方の設定をその一覧に合わせてください。一覧があれば、変更時に設定が食い違わず、つながらないときにもどの層を見るべきか判断できます。