Apache (Webサーバ)
作成: Shintaro / Acia
対象OS: Debian 13 (Sakura VPS)
1. 概要
- 目的: サーバ上の Apache を、
*:80の来訪を apex → https へ誘導し、https://example.comは当面空(非公開)とし、https://www.example.comで配信する構成に統一する。 - 証明書: Let’s Encrypt(webroot方式)で SAN に
example.com/www.example.com/mail.example.comを同居させた 1枚 を利用。 - ACME: すべての vhost で ACME チャレンジ(
/.well-known/acme-challenge/)への到達を 例外的に許可。 - 自動更新: certbot timer/cron と deploy hook(堅牢版) で Apache / Postfix / Dovecot を安全に再読込。
- 本章は 証明書取得「前」 と 取得「後」 の作業を明確に分離する。
- Mermaid 図は削除・省略・改変せず保持する(VSCode互換のラベルに調整)。
2. 前提 / DNS / Firewall
- UFW:
Apache(80/tcp) /Apache Secure(443/tcp) を許可済 - さくらVPS: パケットフィルタで 80/443 を許可
- DNS 要件: 下表のとおり VPS グローバルIPへ向ける
| FQDN | レコード | 値 |
|---|---|---|
example.com | A | VPSグローバルIP |
www.example.com | A | 同上 |
mail.example.com | A | 同上(将来の Postfix/Dovecot も同サーバでTLS使用) |
3. Apache のインストール
sudo apt update
sudo apt install -y apache2
sudo a2enmod ssl rewrite
sudo systemctl enable apache2
sudo systemctl start apache2
4. 事前ステップ(証明書取得の準備:HTTP構成)
4.1 ドキュメントルート / ACME webroot の作成
sudo mkdir -p /var/www/www.example.com
echo '<h1>Hello from www.example.com</h1>' | sudo tee /var/www/www.example.com/index.html >/dev/null
sudo mkdir -p /var/www/letsencrypt/.well-known/acme-challenge
sudo chown -R root:root /var/www
sudo chmod -R 755 /var/www
4.2 ACME スニペット(全 vhost 共通で include)
ファイル: /etc/apache2/snippets/acme.conf
%% HTTP段階 ACME 例外許可(簡素ラベル。VSCode互換) flowchart LR C[Client] -->|HTTP 80| Any80["*:80 (HTTP vhosts)"] Any80 -->|ACME challenge| Webroot[ACME webroot] Any80 -->|301| Apex["example.com:80"] Any80 -->|301| WWW["www.example.com:80"] classDef http fill:#fde68a,stroke:#111111,color:#111111,stroke-width:2px class Any80,Apex,WWW http
Alias /.well-known/acme-challenge/ /var/www/letsencrypt/.well-known/acme-challenge/
<Directory "/var/www/letsencrypt/.well-known/acme-challenge/">
Options None
AllowOverride None
Require all granted
</Directory>
4.3 HTTP VirtualHost(:80)
- ファイル:
/etc/apache2/sites-available/000-default.conf(受け皿 → apex http へ)
<VirtualHost *:80>
Include /etc/apache2/snippets/acme.conf
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/\.well-known/acme-challenge/
RewriteRule ^ http://example.com%{REQUEST_URI} [R=301,L]
</VirtualHost>
- ファイル:
/etc/apache2/sites-available/example.com.conf(apex→httpsへ誘導、ACMEは例外許可)
<VirtualHost *:80>
ServerName example.com
Include /etc/apache2/snippets/acme.conf
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/\.well-known/acme-challenge/
RewriteRule ^ https://example.com%{REQUEST_URI} [R=301,L]
</VirtualHost>
- ファイル:
/etc/apache2/sites-available/www.example.com.conf(www→httpsへ誘導、ACMEは例外許可)
<VirtualHost *:80>
ServerName www.example.com
Include /etc/apache2/snippets/acme.conf
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/\.well-known/acme-challenge/
RewriteRule ^ https://www.example.com%{REQUEST_URI} [R=301,L]
</VirtualHost>
4.4 サイト有効化と Apache reload(HTTP段階)
sudo a2ensite 000-default.conf example.com.conf www.example.com.conf
sudo systemctl reload apache2
5. 証明書の取得(Let’s Encrypt / webroot)
5.1 certbot インストールと発行
sudo apt install -y certbot
sudo certbot certonly --webroot -w /var/www/letsencrypt --cert-name example.com -d example.com -d www.example.com -d mail.example.com
5.2 証明書の確認
sudo certbot certificates
openssl x509 -in /etc/letsencrypt/live/example.com/fullchain.pem -noout -text | grep -E 'Subject:|DNS:'
%% 証明書発行フロー(簡素ラベル)
sequenceDiagram
participant Certbot
participant DNS as DNS (domain → VPS)
participant Apache
participant ACME as Let's Encrypt
Certbot->>DNS: SAN = { apex, www, mail }
Certbot->>Apache: webroot = /var/www/letsencrypt
ACME-->>Apache: HTTP-01
Apache-->>ACME: 200 (allow ACME challenge)
ACME-->>Certbot: issue certificate (SANs on one cert)
Certbot->>Apache: deploy hook reload
補足: vHost を新規追加・名称変更した場合は、再度
sudo a2ensite <file>.conf && sudo systemctl reload apache2を実行して反映する。
6. 事後ステップ(証明書取得後:HTTPS構成)
6.1 example.com-ssl.conf(apex https → wwwへ恒久リダイレクト)
ファイル: /etc/apache2/sites-available/example.com-ssl.conf
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerName example.com
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
Redirect permanent / https://www.example.com/
</VirtualHost>
</IfModule>
6.2 www.example.com-ssl.conf(配信本体)
ファイル: /etc/apache2/sites-available/www.example.com-ssl.conf
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerName www.example.com
DocumentRoot /var/www/www.example.com
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
<Directory /var/www/www.example.com>
Options -Indexes
AllowOverride None
Require all granted
</Directory>
</VirtualHost>
</IfModule>
6.3 サイト有効化と Apache reload(HTTPS段階)
sudo a2ensite example.com-ssl.conf www.example.com-ssl.conf
sudo systemctl reload apache2
6.4 最終構成図(HTTP/HTTPS ルーティング)
%%{init: {"theme":"base","themeVariables":{"background":"transparent","fontFamily":"system-ui, sans-serif","primaryTextColor":"#111827","lineColor":"#2563eb","clusterBkg":"#f8fafc","clusterBorder":"#64748b","edgeLabelBackground":"#ffffff"}}}%%
%% 最終状態ルーティング(簡素ラベル)
flowchart LR
C[Client] -->|HTTP 80| D80["000-default :80"]
C -->|HTTP 80| A80["example.com :80"]
C -->|HTTP 80| W80["www.example.com :80"]
C -->|HTTPS 443| A443["example.com :443"]
C -->|HTTPS 443| W443["www.example.com :443"]
subgraph HTTP80["HTTP (80)"]
D80 -->|301| A80
A80 -->|301| A443
W80 -->|301| W443
class D80,A80,W80 http
end
subgraph HTTPS443["HTTPS (443)"]
A443 -->|301| W443
W443 -->|200| Site((/var/www/www.example.com))
class A443,W443 https
end
C -.->|ACME challenge| D80
C -.->|ACME challenge| A80
C -.->|ACME challenge| W80
class C client
classDef client fill:#dbeafe,stroke:#1d4ed8,color:#111827,stroke-width:2px
classDef http fill:#fef3c7,stroke:#b45309,color:#111827,stroke-width:2px
classDef https fill:#dcfce7,stroke:#15803d,color:#111827,stroke-width:2px
style HTTP80 fill:#fff7ed,stroke:#c2410c,color:#111827,stroke-width:2px
style HTTPS443 fill:#f0fdf4,stroke:#15803d,color:#111827,stroke-width:2px
style Site fill:#ffffff,stroke:#475569,color:#111827,stroke-width:2px
linkStyle default stroke:#2563eb,stroke-width:2px,color:#111827
7. 自動更新と deploy hook(堅牢版)
7.1 timer/cron の確認と dry-run
systemctl list-timers | grep certbot || cat /etc/cron.d/certbot
sudo certbot renew --dry-run
7.2 deploy hook(Apache/Postfix/Dovecot を安全に reload)
ファイル: /etc/letsencrypt/renewal-hooks/deploy/000-reload-services.sh
#!/bin/bash
# certbot による証明書更新後に呼ばれるフック
# 目的:Apache / Postfix / Dovecot を安全にリロード(無ければスキップ)
set -e
log() { logger -t certbot-deploy "$*"; }
services=(apache2 postfix dovecot)
for svc in "${services[@]}"; do
if systemctl list-unit-files --type=service | awk '{print $1}' | grep -qx "${svc}.service"; then
if systemctl reload "${svc}" 2>/dev/null; then
log "reloaded ${svc}"
elif systemctl try-reload-or-restart "${svc}" 2>/dev/null; then
log "try-reload-or-restart ${svc}"
else
log "WARN: failed to reload/restart ${svc} (continuing)"
true
fi
else
log "skip ${svc}: service not installed"
fi
done
chmod +x /etc/letsencrypt/renewal-hooks/deploy/000-reload-services.sh
8. 検証コマンド(例)
# 80系
curl -I http://<IP>/
curl -I http://example.com/
curl -I http://www.example.com/
# 443系(証明書検証をスキップするなら -k)
curl -I -k https://example.com/
curl -I -k https://www.example.com/
# ACME到達性
curl -I http://example.com/.well-known/acme-challenge/test
curl -I http://www.example.com/.well-known/acme-challenge/test
curl -I http://mail.example.com/.well-known/acme-challenge/test
9. 運用・注意点
- 80番/
/.well-known/acme-challenge/の例外許可を 常に維持(HTTP-01更新のため) - SANの増減がある場合は、再発行時に“全SAN列挙” を忘れない
/etc/letsencrypt/live/example.com/を Apache/メールで共用(鍵の権限: Postfix/Dovecot 側でssl-certグループを活用)- バックアップ:
/etc/apache2/,/etc/letsencrypt/,/var/www/を定期同期
10. 将来拡張(メールサーバ)
mail.example.comを同一証明書でTLS化(Postfix/Dovecot)- 鍵読み取り権限:
sudo usermod -aG ssl-cert postfix
sudo usermod -aG ssl-cert dovecot
- deploy hook は本書の堅牢版を流用(すでに導入済)
変更履歴
| 日付 | 編集者 | 内容 |
|---|---|---|
| 2025-09-30 | Shintaro / Acia | 初版作成(Apache SSL統合構成:SAN, webroot, deploy hook)。 |
| 2025-10-28 | Acia | 章構成を「証明書取得前/後」で分離。a2ensite とディレクトリ作成手順を追記。Mermaid 図を維持。 |
| 2025-10-28 | Acia | vHost設定ファイルのフルパスを各セクションに明記し、再現性を向上。 |