-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCaddyfile
141 lines (126 loc) · 3.4 KB
/
Caddyfile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
{
email youractualemail@example.com
acme_dns vultr {$VULTR_API_KEY}
# Global TLS preferences
servers {
protocol {
experimental_http3 # Better performance on modern clients
strict_sni_host # Require valid SNI
protocols tls1.3 tls1.2 # Prefer 1.3, allow 1.2
cipher_suites {
tls1.3 TLS_AES_256_GCM_SHA384 TLS_CHACHA20_POLY1305_SHA256
tls1.2 TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
}
curves x25519 secp384r1
}
}
}
# Shared security header configuration
(security_headers) {
header {
# Enable HSTS with longer max-age
Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" # 2 years
# Prevent clickjacking
X-Frame-Options "SAMEORIGIN"
# Prevent XSS attacks
X-XSS-Protection "1; mode=block"
# Prevent MIME-sniffing
X-Content-Type-Options "nosniff"
# CSP
Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-eval' 'wasm-unsafe-eval'; style-src 'self' 'unsafe-inline';"
# Restrict referrer information
Referrer-Policy "strict-origin-when-cross-origin"
}
}
# Shared reverse proxy configuration
(proxy_config) {
health_uri /health
health_interval 30s
health_timeout 10s
health_status 200
}
# TLS configuration snippet
(tls_config) {
tls {
dns vultr {$VULTR_API_KEY}
protocols tls1.3 tls1.2 # Prefer 1.3, allow 1.2
must_staple # Enable OCSP stapling
key_type p384 # Use stronger elliptic curve
}
}
# Custom error pages
(error_pages) {
handle_errors {
@maintenance expression `{http.error.status_code} == 503`
handle @maintenance {
root * /opt/arkfile/webroot/errors
try_files /maintenance.html
file_server
}
@not_found expression `{http.error.status_code} == 404`
handle @not_found {
root * /opt/arkfile/webroot/errors
try_files /404.html
file_server
}
# Default error response
respond "{http.error.status_code} {http.error.status_text}"
}
}
# Production site
arkfile.net {
encode gzip
import tls_config
import security_headers
# Try production service first
reverse_proxy localhost:{$PROD_PORT} {
import proxy_config
@unavailable expression `{upstream.status} == 503`
handle_response @unavailable {
# If prod is down but test is up, suggest test environment
reverse_proxy localhost:{$TEST_PORT} {
import proxy_config
@test_up expression `{upstream.status} != 503`
handle_response @test_up {
respond `Production environment is currently unavailable.
Test environment is available at: https://test.arkfile.net` 307 {
header Location https://test.arkfile.net
}
}
}
}
}
log {
output file /var/log/caddy/prod-access.log
format json
}
import error_pages
}
# Test site
test.arkfile.net {
encode gzip
import tls_config
import security_headers
reverse_proxy localhost:{$TEST_PORT} {
import proxy_config
@unavailable expression `{upstream.status} == 503`
handle_response @unavailable {
# If test is down but prod is up, suggest prod environment
reverse_proxy localhost:{$PROD_PORT} {
import proxy_config
@prod_up expression `{upstream.status} != 503`
handle_response @prod_up {
respond `Test environment is currently unavailable.
Production environment is available at: https://arkfile.net` 307 {
header Location https://arkfile.net
}
}
}
}
}
log {
output file /var/log/caddy/test-access.log
format json
}
import error_pages
}