Last active
August 28, 2025 00:22
-
-
Save segfo/2e88a3e77e3d2fb5cefc79d527330224 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # 同じディレクトリに .env を作ってください。 | |
| # .envのサンプルはgistのコメントに書きます。 | |
| services: | |
| # パスワードマネージャ 不要なら消してね | |
| vaultwarden: | |
| image: vaultwarden_arm64:1.34.3 | |
| container_name: vaultwarden | |
| user: '1000:1000' | |
| ports: | |
| - 8080:80 | |
| environment: | |
| - DOMAIN=${VAULTWARDEN_DOMAIN} | |
| - SIGNUPS_ALLOWED=${VAULTWARDEN_SIGNUPS_ALLOWED} | |
| - ROCKET_PORT=80 | |
| - EXPERIMENTAL_CLIENT_FEATURE_FLAGS=ssh-key-vault-item,ssh-agent | |
| volumes: | |
| - ./vw-data:/data | |
| restart: unless-stopped | |
| # DNS型広告ブロッカー | |
| pihole: | |
| image: pihole/pihole:latest | |
| container_name: pihole | |
| cap_add: | |
| - NET_ADMIN | |
| environment: | |
| - TZ=${TZ} | |
| - PIHOLE_UID=${PUID} | |
| - PIHOLE_GID=${PGID} | |
| volumes: | |
| - ./etc/pihole:/etc/pihole | |
| - ./etc/dnsmasq.d:/etc/dnsmasq.d | |
| ports: | |
| - "53:53/tcp" | |
| - "53:53/udp" | |
| restart: unless-stopped | |
| # pi-holeのUI用のリバプロ。TLS通信の終端の役割をしている。不要なら消してね | |
| nginx: | |
| image: nginx:latest | |
| container_name: nginx | |
| depends_on: | |
| - pihole | |
| ports: | |
| - 10443:443 | |
| volumes: | |
| - ./nginx/conf.d:/etc/nginx/conf.d | |
| - ./nginx/certs:/etc/nginx/certs | |
| restart: unless-stopped | |
| # ローカルCA、生成したTLS証明書をNginxに食わせる | |
| stepca: | |
| image: smallstep/step-ca | |
| container_name: stepca | |
| volumes: | |
| - ./step-ca:/home/step | |
| ports: | |
| - 8443:443 # ACME endpoint | |
| restart: unless-stopped | |
| networks: | |
| internal_net: | |
| driver: bridge |
Author
Author
.envのサンプル
compose.ymlとCA初期化・運用スクリプトと共用です。
.env
# CA 設定
CA_DNSNAME=local-ca.local
CA_NAME=LocalCA
# ディレクトリ(スクリプトの場所を基準に補完)
STEP_CA_DIR=step-ca
CERT_DIR=nginx/certs
# サーバ情報
SERVERS="server.local"
O=Local
OU=Local
# Step CLI / CA
STEP_CA_URL=https://$CA_DNSNAME:8443
STEP_CLI_IMAGE=smallstep/step-cli:latest
STEP_CA_IMAGE=smallstep/step-ca:latestCAの初期化とサイト毎に証明書を作成するスクリプト
CAの初期化
環境依存の内容は compose.yml と同じディレクトリの .env に書いてください。
ca-setup.sh
#!/bin/bash
set -eu
# スクリプトの存在するディレクトリ
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && cd ../ && pwd)"
# .env の読み込み
source "$SCRIPT_DIR/.env"
# 相対パスを補完
STEP_CA_DIR="$SCRIPT_DIR/$STEP_CA_DIR"
CERT_DIR="$SCRIPT_DIR/$CERT_DIR"
PASSWORD_FILE="$STEP_CA_DIR/secrets/password"
mkdir -p "$STEP_CA_DIR/secrets"
docker compose down stepca || true
# 自動パスワード生成
openssl rand -base64 32 > "$PASSWORD_FILE"
chmod 600 "$PASSWORD_FILE"
# Step CA を非対話で初期化
docker run --rm \
-v "$STEP_CA_DIR":/home/step \
"$STEP_CA_IMAGE" \
step ca init \
--deployment-type="standalone" \
--name "$CA_NAME" \
--dns "$CA_DNSNAME" \
--address ":443" \
--provisioner "admin@$CA_DNSNAME" \
--password-file /home/step/secrets/passwordサイト毎の証明書作成
create-cert.sh
#!/bin/bash
set -eu
# スクリプトの存在するディレクトリ
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && cd ../ && pwd)"
# .env の読み込み
source "$SCRIPT_DIR/.env"
# 相対パスを補完
STEP_CA_DIR="$SCRIPT_DIR/$STEP_CA_DIR"
CERT_DIR="$SCRIPT_DIR/$CERT_DIR"
PASSWORD_FILE="$STEP_CA_DIR/secrets/password"
mkdir -p "$CERT_DIR"
docker compose up stepca -d
for SERVER in $SERVERS; do
echo "=== request cert for: $SERVER ==="
# CSR / キー作成
docker run --rm -v "$CERT_DIR":/certs alpine:3.18 \
sh -c "apk add --no-cache openssl >/dev/null 2>&1 && \
openssl req -new -newkey ec:<(openssl ecparam -name secp521r1) -nodes \
-keyout /certs/$SERVER.key \
-out /certs/$SERVER.csr \
-subj '/C=JP/O=$O/OU=$OU/CN=$SERVER' \
&& chmod 600 /certs/$SERVER.key && chmod 644 /certs/$SERVER.csr"
# CSR を CA に送信して署名
docker run --rm \
-v "$STEP_CA_DIR":/home/step:ro \
-v "$CERT_DIR":/certs \
--network host \
"$STEP_CLI_IMAGE" \
step ca sign /certs/$SERVER.csr /certs/$SERVER.crt \
--ca-url "$STEP_CA_URL" \
--root /home/step/certs/root_ca.crt \
--password-file /home/step/secrets/password \
--not-after 24h \
--force
done
docker compose down nginx;docker compose up nginx -d最後、定期的にTLS証明書を自動更新するスクリプト
crontab -e でこれを実行するようにしておくと、12時間ごとに証明書が更新されます。
* */12 * * * /path/to/server/scripts/cert-renew-and-reload.sh > /dev/null 2>&1
cert-renew-and-reload.sh
#!/bin/bash
set -eu
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && cd ../ && pwd)"
source "$SCRIPT_DIR/.env"
# 相対パスを絶対パスに補完
STEP_CA_DIR="$SCRIPT_DIR/$STEP_CA_DIR"
CERT_DIR="$SCRIPT_DIR/$CERT_DIR"
PASSWORD_FILE="$STEP_CA_DIR/secrets/password"
mkdir -p "$CERT_DIR"
changed=false
for SERVER in $SERVERS; do
echo "=== request cert for: $SERVER ==="
CRT_FILE="$CERT_DIR/$SERVER.crt"
KEY_FILE="$CERT_DIR/$SERVER.key"
TMP_CRT="$CERT_DIR/.${SERVER}.crt.tmp"
TMP_KEY="$CERT_DIR/.${SERVER}.key.tmp"
docker run --rm \
-v "$STEP_CA_DIR":/home/step:ro \
-v "$CERT_DIR":/certs \
--network host \
"$STEP_CLI_IMAGE" \
step ca certificate "$SERVER" "/certs/.${SERVER}.crt.tmp" "/certs/.${SERVER}.key.tmp" \
--ca-url "$STEP_CA_URL" \
--root /home/step/certs/root_ca.crt \
--not-after 24h \
--password-file /home/step/secrets/password || {
echo "warning: certificate request failed for $SERVER"
continue
}
chmod 644 "$TMP_CRT" || true
chmod 600 "$TMP_KEY" || true
mv -f "$TMP_CRT" "$CRT_FILE"
mv -f "$TMP_KEY" "$KEY_FILE"
echo "issued/updated: $CRT_FILE $KEY_FILE"
changed=true
done
if [ "$changed" = true ]; then
echo "reloading nginx container..."
docker exec nginx nginx -s reload || {
echo "warning: nginx reload failed"
}
else
echo "no certificate changes; skip reload"
fi
Author
スマホのモバイル回線からPi-HoleにDNS解決させる方法
コンセプト
Tailscale VPNにスマホを参加させて、スプリットトンネルを構成します。
DNSクエリのみをVPNに通過させて、解決させてそれ以外のトラフィックは直接インターネットに出すことでVPN側に不要なトラフィックを発生させません。もう一つのメリットとして通信パケットのカプセル化が必要以上にされないと思うので(諸説)通信(量|料)の節約にもつながるかも。
広告ブロックのみを主眼に置いた構成です。
Tailscaleの設定
- Tailscaleの管理画面のDNS設定内の「MagicDNS」を有効にする
sudo tailscale ipを確認する- Tailscaleの管理画面のDNS設定内の「Global nameservers」に2で確認したIPアドレスを書く
Pi-Holeの設定
Pi-Hole > SYSTEM > Settings > DNS(DNS Settings画面) で作業をします
DNS Settings
設定モードをExpertモードにしてください(Basicモードだと設定できません)
Interface settings > Potentially dangerous optionsブロックの
Permit all origins を選択します。(まぁファイアウォールで制御していれば問題なしです)
これで、TailscaleからのDNSリクエストをPi-holeで処理できます。
Author
Nignxの設定ファイル
# nginx が $connection_upgrade を理解するように map を追加
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 443 ssl;
server_name server.local;
ssl_certificate /etc/nginx/certs/server.local.crt;
ssl_certificate_key /etc/nginx/certs/server.local.key;
# Docker の内部DNS を使う(コンテナ内では 127.0.0.11 が Docker DNS)
resolver 127.0.0.11 valid=30s;
# upstream を変数で指定すると起動時に解決しない(リクエスト時に解決される)
set $upstream_host "pihole:80";
location / {
proxy_pass http://$upstream_host;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# WebSocket 等が必要なら以下も
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}
Author
ディレクトリ構成
server
├── .env <環境変数(compose.ymlとLocalCA構築・運用スクリプト共用)>
├── compose.yml
├── etc <piholeのフォルダ>
│ ├── dnsmasq.d
│ └── pihole
├── logs <TLS証明書の再発行スクリプトのログなど>
├── nginx <TLSの終端・リバースプロキシ>
│ ├── certs <各サーバの証明書>
│ │ ├── server.crt
│ │ ├── server.csr
│ │ └── server.key
│ └── conf.d <リバプロの構成ファイル>
│ └── pihole.conf <pihole用>
├── scripts
│ ├── ca-setup.sh
│ ├── cert-renew-and-reload.sh
│ └── create-cert.sh
├── step-ca <scripts/ca-setup.shを実行すると作成される>
└── vw-data <vaultwardenのDBデータ>
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Tailscaleのログインセッションについて
10日くらい継続して接続されているとき、サーバが再起動すると再認証が必要になる。
再認証は以下のコマンドで行う
sudo tailscale loginデーモンのステータス確認
sudo systemctl status tailscale-funnel.serviceデーモンの再起動
sudo systemctl restart tailscale-funnel.service