![[Linux] LAN内HTTPS完全ガイド:mkcert・nginx・Apacheの実践手順](https://humanxai.info/images/uploads/linux-nginx-02.webp)
1. public_html vs HTTPS
-
public_html はコンテンツの置き場所
(ApacheのDocumentRootやmod_userdir、nginxのroot)。 -
HTTPS は通信の暗号化&相手の真正性確認鍵と証明書をサーバに設定する作業
(nginxならssl_certificate/ssl_certificate_key、ApacheならSSLCertificateFile/SSLCertificateKeyFile)。
つまり「public_html か mkcert か」ではなく、どちらも必要
public_html にサイトを置き、mkcert等で作った証明書をサーバ設定に組み込む。
2. なぜ LAN では mkcert が速くてラク?
mkcert はローカルCA(認証局)を生成し、そこから**SAN(Subject Alternative Name)**入りのサーバ証明書を即席で発行します。
SANに IP(例:192.168.0.1)やホスト名(nas.home.arpa / localhost) を複数登録できるので、ブラウザの「CNのみはNG」チェックにも引っかかりません。
mkcert の基本手順
- CAを作り各OSの信頼ストアへ登録:
mkcert -install
- サーバ用の証明書を発行(IPやホスト名を全部入れる):
mkcert 192.168.0.1 localhost nas.home.arpa
# => 例: 192.168.0.1+2.pem / 192.168.0.1+2-key.pem
- 生成した 証明書(.pem)と秘密鍵(-key.pem) をサーバの安全な場所へ配置し、Webサーバに設定。
コツ:
mkcert -CAROOT でローカルCAの格納ディレクトリがわかります。
そこで rootCA.pem を取り出し、他端末に配布して信頼させます(後述)。
3. 代替パターンと選び方(ざっくり)
-
完全ローカル(社内/LAN限定):
- もっとも簡単 → mkcert。
- モバイルアプリ等、ユーザーCAを信頼しないクライアントが混ざるなら後述のDNS-01や組織CAも検討。
-
LANだが“公的に信頼される証明書”を使いたい:
- Let’s EncryptのDNS-01 で自分のドメイン名の証明書を取得→LAN内DNS(スプリットDNS)でそのFQDNをプライベートIPに解決。
- 長所:配布不要で多くのクライアントが即信頼。短所:DNS更新の自動化が必要。
-
組織的に運用(更新自動化・失効管理・mTLS等):
- step-ca(Smallstep) で社内ACMEサーバを立てる。
- Caddy の内部CA機能でローカル自動HTTPS。
- Traefik + mkcert で開発環境を束ねる、など。
注意:Let’s EncryptはlocalhostやプライベートIP(192.168.x.xなど)には発行しません。 2025年にIPアドレス証明書が始まりつつありますが、主にパブリックIP向けで超短命(短期間)プロファイル。LANのプライベートIP用途には不向きです。したがって、LANでサクッとやるなら mkcert が現実解です。
4. nginx 設定例(HTTP→HTTPSリダイレクト+HTTP/2)
証明書を /etc/nginx/certs/lan.pem、鍵を /etc/nginx/certs/lan-key.pem に置いた例。
# 80番は常にHTTPSへ
server {
listen 80;
server_name 192.168.0.1 nas.home.arpa localhost;
return 301 https://$host$request_uri;
}
# 443番(TLS)
server {
listen 443 ssl http2;
# HTTP/3 も使うなら(nginx 1.25+ & http_v3_module ビルド必須)
# listen 443 quic reuseport; # 実装状況により調整
# add_header Alt-Svc 'h3=":443"; ma=86400' always;
server_name 192.168.0.1 nas.home.arpa localhost;
ssl_certificate /etc/nginx/certs/lan.pem;
ssl_certificate_key /etc/nginx/certs/lan-key.pem;
# モダンTLSの素振り
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
root /var/www/public_html; # ← 置き場所(public_html 等)
index index.html index.htm;
location / {
try_files $uri $uri/ =404;
}
}
ディレクトリ構成を変えたいなら root を、バーチャルホスト名を変えたいなら server_name を調整。**public_html は単なる“置き場所”**で、HTTPSの有無とは独立です。
再起動
sudo nginx -t && sudo systemctl reload nginx
5. Apache 設定例(mod_ssl+HTTP/2)
証明書・鍵は /etc/apache2/certs/ に配置した例。mod_ssl と mod_http2 を有効化します。
sudo a2enmod ssl http2
<VirtualHost *:80>
ServerName 192.168.0.1
Redirect permanent / https://192.168.0.1/
</VirtualHost>
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerName 192.168.0.1
DocumentRoot "/var/www/public_html"
SSLEngine on
SSLCertificateFile "/etc/apache2/certs/lan.pem"
SSLCertificateKeyFile "/etc/apache2/certs/lan-key.pem"
# HTTP/2 を有効化
Protocols h2 http/1.1
<Directory "/var/www/public_html">
Require all granted
Options Indexes FollowSymLinks
AllowOverride All
</Directory>
</VirtualHost>
</IfModule>
Per-Userのpublic_html(mod_userdir) を使う場合でも、HTTPSは同様に443のVirtualHost側でSSLEngine onと証明書を指定します。置き場所の考え方は変わりません。
再起動:
sudo apachectl configtest && sudo systemctl reload apache2
6. クライアントに“信頼”を配る(macOS / Windows / iOS / Android)
mkcertを実行した端末は -install 済みなのでOK。他の端末で証明書警告が出る場合、rootCA.pem をインストール&“信頼”に設定します。
- macOS:
- rootCA.pem をダブルクリック→**キーチェーン(システム)**に追加→証明書の詳細で「常に信頼」。
- Windows:MMCの**「Trusted Root Certification Authorities」**にインポート。
- iOS / iPadOS:rootCA.pem を端末に配布してプロファイルとしてインストール→設定 > 一般 > 情報 > 証明書信頼設定 でフル信頼をON。
- Android:設定 > セキュリティ > 認証情報のインストール でユーザーCAとしてインポート。ただし多くのアプリ(API 24+)は“ユーザーCA”を既定で信頼しません。ブラウザはOKでもアプリがNGというのは普通に起きます。→ 公的証明書(DNS-01)か、社内CA(step-ca)+MDM配布を検討。
セキュリティ:rootCA.pemの乱配布は厳禁。意図しない端末にインストールすると、その端末は**“あなたのCAが発行した全サイト”を信用してしまいます。用途ごとにCAを分け、不要になったら各端末から削除**しましょう。
7. LANでも“公的”証明書を使いたい場合(Let’s Encrypt / DNS-01)
- FQDN(例:nas.example.com)を用意。
- DNSプロバイダのAPIやacme-dnsを使って DNS-01チャレンジで検証→証明書取得。
- スプリットDNSで、社内からnas.example.comはプライベートIPに解決させる。
- これなら配布いらずでモバイルアプリもほぼ問題なく動きます。
ただし localhostやプライベートIPは対象外。IPアドレス証明書の一般提供が広がっても、LANのRFC1918アドレス向けは現実的ではありません。
8. もっと本格的に:社内CA / 自動化
- step-ca(Smallstep):自社ドメイン向けのプライベートACME。短期証明書・mTLS・失効・ロールベース運用まで柔軟。
- Caddy:tls internal で内部CAから自動発行。ローカルの自動HTTPSが超手軽。
- Traefik + mkcert:複数サービスのローカル開発を一括HTTPS化。
9. ネーミングの話(.localの落とし穴)
- .local は**mDNS(Bonjour)**用途で特殊。衝突や解決順の問題が出やすい。
- 無難なのは home.arpa(家庭内用途)か、自分の保有ドメインのサブドメイン。
- ドキュメント/テスト専用には .test/.example/.invalid/.localhost などのSpecial-Useも。
10. よくある落とし穴と対処
- SAN不足:IPやホスト名を全部mkcertに渡す。CNだけは不可。
- HSTSを安易に有効化:開発/LANでは**preloadやincludeSubDomainsは避ける**。消しづらい“常時HTTPS縛り”でハマる元。
- HTTP/3を一気に導入:nginxはビルドやlistenパラメータに癖。まずはHTTP/2で十分。
- 混在コンテンツ:HTTPの画像/JSを呼んでブロックされがち。相対パスかHTTPSに統一。
- 秘密鍵の権限:chmod 600などで最小権限。Git等に絶対入れない。
11. 動作確認ワンライナー
# 証明書のSAN/チェーンを確認
openssl s_client -connect 192.168.0.1:443 -servername 192.168.0.1 -showcerts </dev/null
# HTTP/2 で応答するか
curl -I --http2 https://192.168.0.1/
付録:
最小 nginx / Apache パス差し替えメモ
- nginx:root で置き場所(/var/www/public_html 等)を指定。
- Apache:DocumentRoot または mod_userdir(UserDir public_html)。HTTPSは*:443のVirtualHost側に証明書を指定。
参考・出典(主要な根拠)
- mkcert の使い方・CA 配布:公式 README(インストール/-CAROOT/モバイル注意)。
- nginx の HTTPS/証明書設定(ssl_certificate 等)&サンプル。
- Apache の SSL 設定(SSLCertificateFile ほか)と HTTP/2 有効化(Protocols h2 http/1.1)。 (LinuxBabe)
- Let’s Encrypt のチャレンジ種別(DNS-01 はサーバ非公開でもOK/IPアドレス検証は不可)。 (Let’s Encrypt)
- localhost には発行できない(Let’s Encrypt FAQ)。 (Let’s Encrypt)
- Let’s Encrypt の IP アドレス証明書(2025/07 公開;短命・段階的提供、主にパブリックIP向け)。 (Let’s Encrypt)
- Caddy のローカル自動 HTTPS(内部CA)。 (HTTPS-Only Standard)
- 社内CA/ACME の選択肢:Smallstep step-ca 概要。 (Smallstep)
- Android の「ユーザーCAは既定で信頼しない」設計(Network Security Config)。 (Android Developers)
- iOS の「フル信頼」有効化手順。 (Appleサポート)
- .local は mDNS 用の特殊ドメイン(衝突しやすい)/Special-Useドメイン。 (IETF Datatracker)
- 家庭内なら home.arpa が無難(RFC 8375)。 (RFC エディタ)
💬 コメント