前回はCaddy 2のセットアップをしました。実際はWebサーバーを組み合わせて使います。NginxをupstreamサーバにしてCaddyのバックエンドに接続します。
通常のコンテナまたは複数サイトで運用する場合
stream {
map $ssl_preread_server_name $name {
mx.example.com mail_backend;
forwardproxy.example.com caddy;
}
upstream mail_backend {
server 10.0.0.1:2443;
}
upstream caddy {
server 10.0.0.1:443;
}
server {
listen 443;
#resolver 1.1.1.1;
proxy_connect_timeout 1s;
proxy_timeout 3s;
proxy_pass $name;
#proxy_protocol on;
ssl_preread on;
}
log_format basic '$ssl_preread_server_name $remote_addr [$time_local] '
'$protocol $status $bytes_sent $bytes_received '
'$session_time "$upstream_addr" '
'"$upstream_bytes_sent" "$upstream_bytes_received" "$upstream_connect_time"';
access_log /var/log/nginx/stream.access.log basic;
error_log /var/log/nginx/stream.error.log;
}
Caddyにポート80を振りました。証明書の取得に必要と思われます。
server {
listen 80;
server_name forwardproxy.example.com;
location / {
proxy_pass http://10.0.0.1:80;
proxy_read_timeout 240;
proxy_buffering off;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# proxy_set_header X-Forwarded-Host $host;
# proxy_set_header X-Forwarded-Server $host;
}
}
lxcのコンテナなのでNginxとCaddyのポートの競合は避けられます。
{
"admin": {
"listen": ":3019",
"disabled": true
},
"logging": {
"logs": {
"": {
"writer": {
"output": "file",
"filename": "/var/log/caddy/caddy.log",
"roll": true,
"roll_size_mb": 10,
"roll_gzip": true,
"roll_local_time": false,
"roll_keep": 10,
"roll_keep_days": 90
},
"encoder": {"format": "json"},
"level": "INFO"
},
"default": {
"level": "INFO"
}
}
},
"apps": {
"http": {
"servers": {
"httpserver": {
"listen": ["[::]:80"],
"routes": [{
"handle": [{
"handler": "static_response",
"headers": {"Location": ["https://example.com/"]},
"status_code": 301
}]
}]
},
"fwdproxy": {
"listen": ["[::]:443"],
"listener_wrappers": [
],
"logs": {},
"routes": [{
"handle": [{
"handler": "subroute",
"routes": [{
"handle": [
{
"allowed_ports": [
443
],
"auth_pass_deprecated": "pass",
"auth_user_deprecated": "user",
"handler": "forward_proxy",
"hide_ip":true,
"hide_via":true,
"probe_resistance":{
}
}
]
}, {
"match": [{"host": ["example.com"]}],
"handle": [{
"handler": "file_server",
"root": "/var/www/caddy"
}]
}]
}],
"terminal": true
}],
"tls_connection_policies": [{
"match": {"sni": ["example.com"]},
"cipher_suites": ["TLS_CHACHA20_POLY1305_SHA256"],
"curves": ["x25519"]
}]
}
}
},
"tls": {
"certificates": {
"automate":[
"example.com"
]
}
}
}
}
Systemdユニットです。
[Unit]
Description=Caddy
Documentation=https://caddyserver.com/docs/
After=network.target network-online.target
Requires=network-online.target
[Service]
Type=notify
#User=root
#Group=root
User=caddy
Group=caddy
ExecStart=/usr/local/bin/caddy run --environ --config /etc/caddy/caddy.json
ExecReload=/usr/local/bin/caddy reload --config /etc/caddy/caddy.json
TimeoutStopSec=5s
LimitNOFILE=1048576
LimitNPROC=512
PrivateTmp=true
ProtectSystem=full
AmbientCapabilities=CAP_NET_BIND_SERVICE
[Install]
WantedBy=multi-user.target
OpenVZ Debian 9の場合
OpenVZの準仮想環境の場合はかなり手段が限られてきます。今回はUnix Domain Socketを使いました。
stream {
map $ssl_preread_server_name $name {
mail.example.com mail_backend;
www.example.com www_backend;
forwardproxy.example.com caddy;
}
upstream mail_backend {
server 127.0.0.1:81;
}
upstream www_backend {
server 127.0.0.1:82;
}
upstream caddy {
server unix:/dev/shm/caddy-https.socket;
}
server {
listen 443;
proxy_connect_timeout 1s;
proxy_timeout 3s;
proxy_pass $name;
#proxy_protocol on;
ssl_preread on;
}
log_format basic '$ssl_preread_server_name $remote_addr [$time_local] '
'$protocol $status $bytes_sent $bytes_received '
'$session_time "$upstream_addr" '
'"$upstream_bytes_sent" "$upstream_bytes_received" "$upstream_connect_time"';
access_log /var/log/nginx/stream.access.log basic;
error_log /var/log/nginx/stream.error.log;
}
server {
listen 80;
server_name forwardproxy.example.com;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# proxy_set_header X-Forwarded-Host $host;
# proxy_set_header X-Forwarded-Server $host;
location / {
proxy_pass http://unix:/dev/shm/caddy-http.socket;
proxy_read_timeout 240;
proxy_buffering off;
proxy_redirect off;
}
}
{
"admin": {
"listen": ":3019",
"disabled": true
},
"logging": {
"logs": {
"": {
"writer": {
"output": "file",
"filename": "/var/log/caddy/caddy.log",
"roll": true,
"roll_size_mb": 50,
"roll_gzip": true,
"roll_local_time": false,
"roll_keep": 10,
"roll_keep_days": 90
},
"encoder": {"format": "json"},
"level": "INFO"
},
"default": {
"level": "INFO"
}
}
},
"apps": {
"http": {
"servers": {
"httpserver": {
"listen": [":88"],
"routes": [{
"handle": [{
"handler": "static_response",
"headers": {"Location": ["https://example.com/"]},
"status_code": 301
}]
}]
},
"fwdproxy": {
"listen": ["unix//dev/shm/caddy-https.socket"],
"logs": {},
"routes": [{
"handle": [{
"handler": "subroute",
"routes": [{
"handle": [
{
"allowed_ports": [
443, 8004
],
"auth_pass_deprecated": "pass",
"auth_user_deprecated": "user",
"handler": "forward_proxy",
"hide_ip":true,
"hide_via":true,
"probe_resistance":{
}
}
]
}, {
"match": [{"host": ["example.com"]}],
"handle": [{
"handler": "file_server",
"root": "/var/www/caddy"
}]
}]
}],
"terminal": true
}],
"tls_connection_policies": [{
"match": {"sni": ["example.com"]},
"cipher_suites": ["TLS_AES_128_GCM_SHA256"],
"curves": ["x25519"]
}]
}
}
},
"tls": {
"certificates": {
"automate":[
"example.com"
]
}
}
}
}
Systemdユニットです。User,GroupをNginxと合わせます。
[Unit]
Description=Caddy
Documentation=https://caddyserver.com/docs/
After=network.target network-online.target
Requires=network-online.target
[Service]
Type=simple
#Type=notify
#User=root
#Group=root
User=www-data
Group=www-data
#ExecStartPre=
ExecStart=/usr/local/bin/caddy run --environ --config /etc/caddy/caddy.json
ExecReload=/usr/local/bin/caddy reload --config /etc/caddy/caddy.json
ExecStopPost=/bin/rm -f /dev/shm/caddy-*.socket
TimeoutStopSec=5s
LimitNOFILE=1048576
LimitNPROC=512
PrivateTmp=true
ProtectSystem=full
AmbientCapabilities=CAP_NET_BIND_SERVICE
#AmbientCapabilities=CAP_SYS_ADMIN,CAP_CHOWN,CAP_NET_BIND_SERVICE
[Install]
WantedBy=multi-user.target
SystemdでDomain Socketを取り除いてくれない場合は手動で行います。
# /bin/rm -f /dev/shm/caddy-*.socket