【VPS初期構築ガイド⑤】firewalld・SELinuxの基本理解と安全な設定
(AlmaLinux 10/X-SERVER VPS対応)
VPSを安全に運用するために最も重要なのは、「外部から守ること」よりも、まず“内部の防御を整える”こと です。
本章では、VPSを立ち上げた直後に必ず実施すべき
- firewalld(ローカルFirewall)の設定
- SELinuxの正しい扱い方
を「誤解されやすいポイント」に絞って分かりやすく解説します。
⚙️ 前提条件
このシリーズは、初心者向けに必要最小限の内容でまとめています。
- 対応環境:AWS・さくらのVPS・X-SERVER VPSなど主要環境で再現可能
- 前提知識:Linuxの基本コマンドとvi操作を理解していること
- 想定ユーザー:Windowsユーザー(Macの場合はクライアント側の用語や実行コマンドが一部異なりますが、サーバー操作は同じ手順で実施可能)
💡 参考記事
基礎操作が不安な方は、こちらを先にチェックしておくと理解がスムーズです👇
👉 難しくない、慣れれるだけ!VPSで始めるLinuxサーバーの構築前に覚える基本コマンドとviの使い方
👉 前章:第4章:【VPS初期構築ガイド④】SSHセキュリティ(root禁止・鍵認証・ポート変更)
1. はじめに:なぜ firewalld と SELinux が必要なのか?
結論から言うと、VPSで安全に運用したいなら
🔥 外側ファイアウォール(コントロールパネル)だけでは防御できない
という事実を理解する必要があります。
ConoHa / さくら / XSERVER などのコントロールパネル上で行える、「ポート開閉」「ファイアウォール設定」機能 はすべて…
🔥 外側(外周)のフィルタリングだけ
= サーバー内部の通信・プロセスは守れない
特に Web サーバーでは 80 / 443 のポートは全世界に開放必須 のため、
外側ファイアウォールでは次の攻撃は防げません:
- bot・クローラーの大量アクセス
- WordPressの脆弱性攻撃
- Laravelのファイルアップロード攻撃
- 不正スクリプトによる外部通信
- 踏み台(Outbound攻撃)
そのため、内部の防御として firewalld と SELinux は必須になります。
2. firewalld の設定(ローカルFirewall)
外側FWでは守れない部分を補うのが firewalld です。
firewalld が必要な理由(重要)
✔ ① 80/443 の攻撃は外側FWでは絶対に止められない
HTTP/HTTPSは常に開けておく必要があるため、
攻撃は必然的にこのポートへ集中します。
22番(SSH)や3306番(MySQL)などのポートは
外部ファイアウォールで 接続元IPを制限することで安全に閉じる ことができます。
しかし 80/443(HTTP/HTTPS) は
Web公開のため全IPアドレスを受け入れる必要があり、
*外側FWでは防御できない攻撃がすべて通過します。
✔ ② 侵害後の「内部からの不正アクセス」を制御できるのは firewalld だけ
外側FWは outbound を制御できません。
踏み台化、マルウェアの外部接続などは firewalld が最後の防衛ライン です。
✔ ③ ブラックリスト(IPセット)の運用が可能
攻撃元IPをまとめて遮断できます。
2.1.ブラックリスト(FireHOL)の導入例
wget -O /tmp/firehol_level1.netset https://iplists.firehol.org/files/firehol_level1.netset
sudo firewall-cmd --permanent --new-ipset=blocklist --type=hash:net
sudo firewall-cmd --permanent --ipset=blocklist --add-entries-from-file=/tmp/firehol_level1.netset
sudo firewall-cmd --permanent --add-rich-rule='rule source ipset=blocklist drop'
sudo firewall-cmd --reload
# 確認
sudo firewall-cmd --ipset=blocklist --get-entries | head
sudo firewall-cmd --list-rich-rules
⚠️ これだけで 数万〜数十万の既知攻撃元IPを自動で遮断 できます。
2.2.firewalld の基本操作
現在の設定
firewall-cmd --list-all
サービスの許可
HTTP/HTTPSの許可 の場合
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
任意のポートの許可
firewall-cmd --permanent --add-port=8080/tcp
特定のIPアドレスのアクセス許可
# 192.168.1.1 のIPアドレスを許可
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.1" accept'
# 192.168.1.0 ~ 192.168.1.255 のネットワークを許可(CIDR指定)
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" accept'
特定のIPアドレスのアクセス拒否
# 192.168.1.1 のIPアドレスを拒否
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.1" drop'
# 192.168.1.0 ~ 192.168.1.255 のネットワークを拒否(CIDR指定)
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" drop'
アクセス拒否したIPアドレスを復活させる
# 192.168.1.1 のIPアドレスを拒否を解除
firewall-cmd --permanent --remove-rich-rule='rule family="ipv4" source address="192.168.1.1" drop'
# 192.168.1.0 ~ 192.168.1.255 のネットワークを拒否を解除(CIDR指定)
firewall-cmd --permanent --remove-rich-rule='rule family="ipv4" source address="192.168.1.0/24" drop'
設定の反映
firewall-cmd --reload
3. SELinux について(誤解を解消する章)
SELinux は「disable にするもの」と誤解されがちですが、
本番環境では Enforcing(有効)で運用するのが安全の基本 です。
理由はシンプルで、
SELinux は“攻撃後の動き”を止める唯一の仕組み
(firewalldが攻撃前、SELinuxが攻撃後)
という役割を持つためです。
✔ なぜ disable すると動くのか?(よくある誤解)
SELinux は
❌ 何かを“壊す”
ではなく
✔ “怪しい挙動を止める”
だけです。
disable にすると「危険な動作も全部許可される」ので動くように見えるだけ。
3.1. SELinux の状態確認
sestatus
getenforce
3.2. Webアプリ(Laravel / WordPress)で必要になる基本設定
アプリケーションが書き込みを行うディレクトリに適切な SELinux ラベル(type)を付けます。
Laravel の典型例
sudo semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/html/storage(/.*)?"
# public/storage(symlink)の実体にもラベル付与
sudo semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/html/public(/.*)?"
# 反映
sudo restorecon -Rv /var/www/html
たったこれだけで「SELinux が Laravel を邪魔する」という問題の8割は解決します。
3.3. SELinuxのよく使うコマンド
# 登録済みルールの確認
sudo semanage fcontext -l | grep -E "^/var/www/html"
# 既存ルールと衝突(-aがエラー)する場合は -m で更新
sudo semanage fcontext -m -t httpd_sys_rw_content_t "/var/www/html(/.*)?"
# ルールを削除したい場合
sudo semanage fcontext -d "/var/www/html/storage(/.*)?"
3.4. SELinux はログを見て原因を特定できる
アプリが動かないとき、SELinuxの拒否(AVC)ログを見ると解決できます。
sudo ausearch -m avc -ts recent
sudo aureport -avc
初心者が最も触らない場所ですが、
ここを見る習慣があるだけで「SELinuxを無効化する必要」は無くなります。
3.5. よく使う SELinux ブール値(必要なときだけ ON)
🔵 HTTPD(Apache / Nginx+php-fpm)に関する bool 値
sudo setsebool -P httpd_can_network_connect on
用途
- Laravel / WordPress が外部APIへ接続
- LINE webhook
- Stripe / PayPal
- 外部認証(OAuth etc)
デフォルト: OFF
安全性: 必要なときだけ ON(常時ONでも比較的安全な部類)
DBに直接接続する(MySQL / PostgreSQL)
sudo setsebool -P httpd_can_network_connect_db on
用途
php-fpm(httpd_t)が ローカル以外の DB に接続 する場合
(WebサーバとDBが別ホスト構成など)
**デフォルト:**OFF
注意:
“なんでもかんでも外に接続できる” より制限は緩いが、
必要なときだけ ON にすること。
メール送信(contactフォームなど)
sudo setsebool -P httpd_can_sendmail on
用途
- WordPress の mail()
- Laravel の sendmail 経由送信
- システムメール通知
デフォルト: OFF
注意:
sendmail を許可すると、攻撃者に WebShell 等を置かれた場合、
スパム送信の踏み台にされるリスク が高まります。
本番環境では 必要なときだけ ON にしてください。
推奨:
Webサーバーからのメール送信は、
外部SMTP(専用メールサーバ・API)を利用するほうが安全 です。
public_content_rw_t への書き込みを許可(非推奨)
sudo setsebool -P httpd_unified on
用途
httpd が public_content_rw_t タイプに書き込めるかどうか。
ポイント(重要)
- ON にすると 「httpd がどこにでも書き込める世界」 に近づく
- つまり セキュリティが大幅に弱くなる
安全運用の基本:
httpd_unified = off(デフォルトのまま)
必要箇所だけ httpd_sys_rw_content_t を付けるのが最も安全
ユーザーのホームディレクトリ配下を公開する
sudo setsebool -P httpd_enable_homedirs on
用途
- /home/user/public_html を使った昔ながらのユーザーWeb公開
- 現代ではほぼ使わない
デフォルト: OFF
推奨: 本番環境では 使わない
🔵 3.x.2 FTP 系(vsftpd 併用時の SELinux bool)
FTPを残している環境では、以下の bool が関わります。
パッシブモードを許可(PASV接続)
sudo setsebool -P ftpd_use_passive_mode on
用途
NAT / FW の内側で FTP を動かす場合に必須
デフォルト: OFF
注意: FTP自体が非推奨なので、SFTPへの移行を前提に一時利用するべき
匿名 / 仮想ユーザの書き込み
sudo setsebool -P ftpd_anon_write on
用途
匿名FTPサーバ(ほぼ使わない)
仮想ユーザFTP(レガシーな構成)
デフォルト: OFF
超注意事項:
これは“世界中から書き込める設定”になり得る。
本番環境ではほぼ禁止レベル。
🔥 ⚠️ FTP/FTPS を残す場合の注意
FTP は以下の点で SELinux と相性が悪い:
- 実行ラベルが HTTP とは完全に別
- 書き込み権限の競合が発生
- SFTP で代替が可能
- 暗号化が弱い(FTPS設定ミスは危険)
結論:本番では SFTP 一択
FTPを残すなら「最小限の bool + 最小限の fcontext」で整えるのが必須。
まとめ(bool 値運用の原則)
| 方針 | 内容 |
|---|---|
| 最小権限 | 必要な bool のみ ON。不要なら OFF。 |
| 外部接続は厳密に |
httpd_can_network_connect などは理由があるときだけ |
| public_content_rw_t を使わない |
httpd_sys_rw_content_t で必要箇所だけ書き込み可に |
| FTPよりSFTPを使う | FTP残す場合は bool を厳選 |
| ログを見る習慣を | ausearch -m avc -ts recent |
3.6. SELinux タイプ(ラベル)の理解
初心者〜中級者が最もつまずく部分なので、一枚表に整理します👇
| SELinuxタイプ | 主な用途 | 読み書き対象 | 説明 |
|---|---|---|---|
| public_content_t | 公開データ(誰でも読み取り可) | 読み取りのみ | セキュア。最も安全な公開領域 |
| public_content_rw_t | 複数サービスから共有書き込み | 読み書き可 | リスク高。慎重に使う |
| httpd_sys_content_t | HTTPDが読むだけ | 読み取りのみ | ほぼ全てのWebコンテンツに使用 |
| httpd_sys_rw_content_t | HTTPDが読み書き | 読み書き可 | Laravel/WordPress の uploads, storage |
| ftpd_anon_rw_t | FTP匿名書き込み | 読み書き可 | FTPサービス専用 |
| ftpd_home_dir_t | FTPユーザホーム | 読み書き可 | 仮想ユーザ用 |
3.7. 開発〜本番までの運用ポリシー(実務ベストプラクティス)
あなたの表を整理し、Qiita向けに最適化したもの👇
🧭 開発〜本番までの SELinux / FTP / 権限設計の運用指針
| フェーズ | FTPの扱い | SELinux方針 | 権限設計 | 補足 |
|---|---|---|---|---|
| 🧪 開発 | FTPS/SFTP 許可 |
public_content_rw_t 多用可 |
開発者が書ける | 機能優先 |
| 🚀 ステージング | 限定ディレクトリのみ許可 |
ftpd_anon_rw_t 縮小 |
一部 ReadOnly化 | 本番想定テスト |
| 🔒 本番 | 原則FTP禁止 |
httpd_sys_content_t 中心 |
Webアプリのみ書込 | 安定運用・監査性重視 |
3.8. SELinux 運用指針まとめ
| ポリシー | 内容 |
|---|---|
| Enforcing維持 | disable しない。開発中の一時的確認のみ Permissive |
| 読み取り専用がデフォルト | httpd_sys_content_t |
| 書き込み箇所を限定 |
httpd_sys_rw_content_t に必要な範囲だけ付与 |
| ブール値は最小限 ON |
httpd_can_network_connect など |
| ログ確認を習慣化 |
ausearch, audit2why
|
| symlink も実体へラベル付け | storage/public など Laravel特有の罠 |
3.9. SELinuxは怖くない
「SELinuxを有効にすると動かなくなる」「FTPが使えなくなる」
という声をよく聞きますが、実際には “使い方を整えれば怖くない仕組み” です。
特に FTP/FTPS と HTTP を同じディレクトリで扱う構成は
パーミッションや SELinux ラベルが衝突しやすく、
結果として SELinuxを無効化(disable)して運用してしまうケース が多く見られます。
ですが、現在は SFTP(SSHベース)への移行が推奨 されており、
ほとんどの運用環境で FTP を残す必要はありません。
もしレガシーな理由で FTP を消せず、
「仕方なく disable にしている」場合は──
🔒 SELinuxは必ず有効(Enforcing)で運用することを強く推奨します。
SELinuxは“攻撃後の動作”を止める最後の安全装置です。
FTPとの兼ね合いで困っている場合でも、
- 適切な fcontext の設定
- 適切なタイプの選択
- FTP専用ラベルの理解
- SFTP への段階的移行
で、SELinux を disable にする理由は無くなります。
3.10. もし SELinux を無効化しているなら…「まずは Permissive(ログだけ)」に戻そう
過去のトラブル対応やレガシー構成の都合で、
SELinux を disable(完全無効化) にしているケースは少なくありません。
しかし disable は“防御ゼロ”であり、万が一侵害されてもログすら残りません。
そこで、すぐに Enforcing を目指さなくてもよいので、
まずは以下のように Permissive(警告ログだけ残すモード) に戻すことを強く推奨します。
# 現在の状態確認
sudo getenforce
# Permissive(警告ログのみ)
sudo setenforce 0
# Enforcing(ポリシーを強制)
sudo setenforce 1
❗ 注意
setenforce で切り替えられるのは Enforcing ⇄ Permissive の一時的変更のみ です。
再起動すると /etc/selinux/config の設定に戻ります。また、Disabled では SELinux モジュール自体がロードされていないため、
setenforce は機能しません。
Disabled から復帰する場合は /etc/selinux/config を修正し、 再起動が必須 です。
再起動後も Permissive を維持したい場合:
sudo vi /etc/selinux/config
設定ファイルを変更する (Enforcing推奨)
# Enforcing にする(本番環境はこの設定が基本)
SELINUX=enforcing
# Permissive にする(ログだけ残したい場合)
SELINUX=permissive
# Disabled(完全無効化 — 本番では非推奨)
SELINUX=disabled
✔ Permissive のメリット
- セキュリティログ(AVC)が必ず残る
- 何がブロックされているか可視化できる
- 侵害された際の「行動ログ」が追える
- Enforcing への復帰準備ができる
- disable と違って「安全への道が残る」
✔ Enforcing は最終目標でOK
まずは “動きを止めずにログだけ取る” を始めるだけで
セキュリティレベルは大きく向上します。
SELinux には3つの状態
| モード | 動作 | 用途 |
|---|---|---|
| Enforcing | ポリシーを強制し、違反行動をブロックする | 本番環境の推奨設定 |
| Permissive | 違反行動をログに書くが、ブロックしない | トラブル調査・移行期間用 |
| Disabled | 完全に無効化(ログも残らない) | 非推奨(使うべきではない) |
4. まとめ(Qiita向けの簡潔なまとめ)
- 外側ファイアウォールは「外周」しか守れない
- 80/443 は常に開放されるため、攻撃は必ず通過する
- 内部防御(firewalld)は必須
- SELinux は disable が誤解(Laravel / WP でも問題なく使える)
- セキュリティは 外側FW × firewalld × SELinux の多層防御 が基本
firewalld が“攻撃前”を守り、SELinux が“侵害後”を抑え込む。
VPS運用では
「外側FW → firewalld → SELinux」
という多層防御が最も費用対効果が高く、安全です。
SELinuxは難しく見えて実はシンプル。
“書き込み箇所を限定し、ログを読むだけ” で、安全性は劇的に向上します。
次章では、より安全な運用のための fail2banによる不正アクセス防止と監査ログ(auditd)の活用 を解説します。
👉 「守る前に整える」【VPS初期構築ガイド⑥】- 第6章:fail2banによる不正アクセス防止と監査ログ(auditd)の活用