やりたいこと
Debianマシンがいっぱいあるので (というリクエスト) 、aptのダウンロードをキャッシュしたい。
前提
- OpenWRTルーター (じゃなくてもいいけど適当なLinuxルーター) がある。
- そこにDebianマシンがぶら下がっている。
- HTTPをキャッシュしたいという目的であればDebianに限らない。
- そこにDebianマシンがぶら下がっている。
方針
- 外に出ようとするHTTP 80番行きのリクエストをDNATでハイジャックして、OpenWRTで変わりに応答する。
- 今回はOpenWRTマシン上でNginxをdocker-composeする。
作業
docker-composeを使えるようにする
opkg install docker dockerd docker-compose
nginxを設定する
適当に /opt/nginx_cache とかつくる。
# docker-compose.yml
services:
nginx-proxy-cache:
image: nginx:1.25-alpine
container_name: nginx-proxy-cache
restart: unless-stopped
network_mode: "host"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- ./cache:/var/cache/nginx
-
network_mode: "host"にすることで、docker0から外向きにFORWARDする設定の手間を省いています。
# nginx.conf
worker_processes auto;
events { worker_connections 1024; }
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
resolver 1.1.1.1 valid=30s; # DNSリゾルバ(必要に応じて社内DNSに変更)
# ログフォーマット(必要なフィールドは適宜追加)
log_format docker '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'upstream_cache:$upstream_cache_status upstream_time:$upstream_response_time';
# キャッシュストレージ定義
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=mycache:200m max_size=10g inactive=7d use_temp_path=off;
# 対象ホストだけキャッシュするための map
map $host $cache_zone {
default off;
~^(.+\.)?deb\.debian\.org$ mycache;
~^(.+\.)?security\.debian\.org$ mycache;
# 必要なら他のDebianミラーも追加:
# ~^(.+\.)?ftp\.debian\.org$ mycache;
}
server {
listen 8080 default_server;
server_name _;
access_log /dev/stdout docker;
error_log /dev/stderr warn;
# 大きなファイル対応
client_max_body_size 0;
location / {
# 動的ホスト名を使うプロキシのために resolver が必要(上で指定済)
# キャッシュのON/OFFを map で切り替える
proxy_cache $cache_zone;
proxy_cache_key "$host$request_uri";
proxy_cache_valid 200 301 302 12h;
proxy_cache_valid 404 1m;
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
proxy_cache_lock on;
# タイムアウト等
proxy_connect_timeout 5s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
# バッファ(必要に応じ調整)
proxy_buffering on;
proxy_buffers 8 16k;
proxy_buffer_size 32k;
# 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;
# HTTP/1.1 keepalive
proxy_http_version 1.1;
proxy_set_header Connection "";
# proxy_pass に変数を使う($host をそのまま解決して接続する)
proxy_pass http://$host$request_uri;
# デバッグ用ヘッダ
add_header X-Cache-Status $upstream_cache_status;
}
}
}
-
1.1.1.1はお好みで変えてください。 -
8080で待ち受ける設定です。
OpenWRTのFirewallでHTTPハイジャックを設定
Network -> Firewall -> Port ForwardsでAdd
- Protocol: TCP
- Source zone: lan = Debianがぶら下がる側
- External port: 80
- Destination: wan = インターネット側
- Internal IP address: キャッシュのNginxが動いているサーバー (今回は自分自身)
- Internal port 8080 (nginxの設定)
Enjoy
docker-compose logs -f を見ながらDebianをインストールしてみましょう!
