-
Notifications
You must be signed in to change notification settings - Fork 103
/
nginx.conf.txt
executable file
·679 lines (600 loc) · 19.9 KB
/
nginx.conf.txt
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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
# -*- awk -*-
# eotk (c) 2017 Alec Muffett
# EMACS awk mode works quite well for nginx configs
# ---- BEGIN HARD/CLASSIC SWITCH ----
%%IF %HARD_MODE%
# *HARD* configuration
# swap domain names for onions via brute-force, with whitelisted repairs...
%%ELSE
# *CLASSIC* configuration
# swap domain names for onions via targeted regular expressions...
%%ENDIF
# ---- END HARD/CLASSIC SWITCH ----
# logs and pids
pid %PROJECT_DIR%/nginx.pid;
error_log %LOG_DIR%/nginx-error.log %NGINX_SYSLOG%;
# TODO: notes for custom 403 error-handling pages:
# https://www.cyberciti.biz/faq/unix-linux-nginx-custom-error-403-page-configuration/
# https://nginx.org/en/docs/http/ngx_http_core_module.html#error_page
# performance
%%IF %IS_SOFTMAP%
worker_processes %SOFTMAP_NGINX_WORKERS%; # softmap
%%ELSE
worker_processes %NGINX_WORKERS%; # hardmap
%%ENDIF
worker_rlimit_nofile %NGINX_RLIM%;
events {
worker_connections %NGINX_RLIM%;
}
http {
# nginx fails without large enough buckets (sigh)
map_hash_bucket_size %NGINX_HASH_BUCKET_SIZE%;
# dns for proxy (sigh)
resolver %NGINX_RESOLVER% valid=%NGINX_TIMEOUT%s;
resolver_timeout %NGINX_TIMEOUT%s;
# we walk a line between keeping it small and flooding resources...
proxy_buffering on;
# for initial; impacts SSL header
proxy_buffer_size %NGINX_BLOCK_SIZE%;
# for rest of response
proxy_buffers %NGINX_BLOCK_COUNT% %NGINX_BLOCK_SIZE%;
# how much can be busy sending to client?
proxy_busy_buffers_size %NGINX_BLOCK_BUSY_SIZE%;
# where to stash oversize requests?
client_body_temp_path /tmp/nginx-body-%PROJECT%;
client_max_body_size 4m;
# in case we want to start spooling responses locally
proxy_temp_path /tmp/nginx-proxy-%PROJECT%;
proxy_max_temp_file_size %NGINX_TMPFILE_SIZE%;
proxy_temp_file_write_size %NGINX_BLOCK_SIZE%;
%%IF %NGINX_CACHE_SECONDS%
# nginx caching static responses for %NGINX_CACHE_SECONDS% seconds
# - this is a lightweight cache to reduce "storms", hence the global
# approch of "cache everything for a small number of seconds"
# https://nginx.org/en/docs/http/ngx_http_proxy_module.html
proxy_cache_path /tmp/nginx-cache-%PROJECT% levels=1:2 keys_zone=%PROJECT%:%NGINX_CACHE_SIZE%;
proxy_cache %PROJECT%;
proxy_cache_min_uses %NGINX_CACHE_MIN_USES%;
proxy_cache_revalidate on;
proxy_cache_use_stale timeout updating;
proxy_cache_valid any %NGINX_CACHE_SECONDS%s; # "any" includes 404s, etc
# content-types to not cache
map $http_content_type $no_cache_content_type {
%%CSV %NO_CACHE_CONTENT_TYPE%
%1% 1;
%%ENDCSV
default 0;
}
# hosts not to cache
map $http_host $no_cache_host {
hostnames;
%%CSV %NO_CACHE_HOST%
%1% 1;
%%ENDCSV
default 0;
}
# so, should we skip caching this stuff for some reason?
proxy_no_cache $no_cache_content_type $no_cache_host;
proxy_cache_bypass $no_cache_content_type $no_cache_host;
%%ELSE
# nginx caching disabled
%%ENDIF
# logs
access_log %LOG_DIR%/nginx-access.log;
# global settings
server_tokens off;
# allow/deny (first wins)
allow "unix:";
deny all;
# rewrite these content types; text/html is implicit
subs_filter_types
application/javascript
application/json
application/x-javascript
text/css
text/javascript
text/xml
%%IF %EXTRA_SUBS_FILTER_TYPES%
# extra_subs_filter_types
%EXTRA_SUBS_FILTER_TYPES%
%%ELSE
# no extra_subs_filter_types
%%ENDIF
;
#==================================================================
%%IF %HARD_MODE%
# ---- BEGIN HARD MODE CODE ----
%%IF %PRESERVE_CSV%
# preserve subs (save-phase): 1=description,2=re,3=i_or_empty,4=replacement
%%CSV %PRESERVE_CSV%
# saving regexp '%2%' as '%1%' for replacement with '%4%' (%3%)
subs_filter
(%PRESERVE_PREAMBLE%)(%2%)\\b
$1%PRESERVE_BEFORE%%1%%PRESERVE_AFTER%
g%3%r
;
%%ENDCSV
%%ELSE
# no preserve subs (save-phase)
%%ENDIF
%%BEGIN
# HARD-MODE: %DNS_DOMAIN% -> %ONION_ADDRESS%
subs_filter
\\b%DNS_DOMAIN_RE2%\\b
%ONION_ADDRESS%
gir
;
%%IF %HARD_MODE% > 1
# HARD-MODE-EXTRA: %DNS_DOMAIN_RE% -> %ONION_ADDRESS_RE%
subs_filter
\\b%DNS_DOMAIN_RERE2%\\b
%ONION_ADDRESS_RE2%
gir
;
%%ENDIF
%%END
%%IF %FOREIGNMAP_CSV%
# foreignmap subs: 1=onion,2=re,3=re2,4=dns,5=re,6=re2
%%CSV %FOREIGNMAP_CSV%
# for %4% -> %1%
subs_filter
\\b%6%\\b
%1%
gir
;
%%ENDCSV
%%ELSE
# no foreignmap subs
%%ENDIF
%%IF %PRESERVE_CSV%
# preserve subs (restore-phase): 1=description,2=re,3=i_or_empty,4=replacement
%%CSV %PRESERVE_CSV%
# restoring '%1%' with '%4%'
subs_filter
%PRESERVE_BEFORE%%1%%PRESERVE_AFTER%
%4%
g
;
%%ENDCSV
%%ELSE
# no preserve subs (restore-phase)
%%ENDIF
# ---- END HARD MODE CODE ----
#------------------------------------------------------------------
%%ELSE
#------------------------------------------------------------------
# ---- BEGIN CLASSIC MODE CODE ----
# subs_filter: these patterns bear some explanation; the goal is to
# work regular expressions really hard in order to minimise the
# number of expressions which are used in the basic config, so the
# basic pattern is to capture zero/more "sub." in "//sub.foo.com"
# and interpolate that into "//sub.xxxxxxxx.onion"; so far?
# but it turns out that some JSON libraries like to "escape" the
# forward slashes in JSON content, leading to input like (literal)
# "http:\/\/sub.foo.com\/foo.html" - so you need to add the
# backslashes, but then you need to escape the backslashes, except
# they need double-escaping in the regexp because of string
# interpolation; hence 4x backslash -> 1x matched character
# likewise we use the "_RE2" form of the re-escaped domain name in
# order to coerce the regexp to match literal dots, not wildcards.
# there seems to be some sort of shortcut at play here; the trailing
# "\\b" also seems to work as "\b" however that would apparently
# break the double-escaping that is necessary/works everywhere else
# in subs_filter.
# also, regrettably, named capture groups appear not to work, we're
# fortunate that there appear not to be more than 9 capture groups
# by default, lest "$1" bleed into the subsequent digits of an onion
# address: $1234567abcdefghij.onion
# finally: some sites encode // with %-encoded "2F" in URIs...
%%BEGIN
# for %DNS_DOMAIN% -> %ONION_ADDRESS% anchored by // or \/\/
subs_filter
(/|\\\\/\\\\)/(([-0-9a-z]+\\.)+)?%DNS_DOMAIN_RE2%\\b
$1/$2%ONION_ADDRESS%
gir
;
# for %DNS_DOMAIN% -> %ONION_ADDRESS% anchored with hex-encoded slashes
subs_filter
%%2F%%2F(([-0-9a-z]+\\.)+)?%DNS_DOMAIN_RE2%\\b
%%2F%%2F$1%ONION_ADDRESS%
gir
;
%%END
%%IF %FOREIGNMAP_CSV%
# foreignmap subs: 1=onion,2=re,3=re2,4=dns,5=re,6=re2
%%CSV %FOREIGNMAP_CSV%
# for %4% -> %1% anchored by // or \/\/
subs_filter
(/|\\\\/\\\\)/(([-0-9a-z]+\\.)+)?%6%\\b
$1/$2%1%
gir
;
# for %4% -> %1% anchored with hex-encoded slashes
subs_filter
%%2F%%2F(([-0-9a-z]+\\.)+)?%6%\\b
%%2F%%2F$1%1%
gir
;
%%ENDCSV
%%ELSE
# no foreignmap subs
%%ENDIF
# ---- END CLASSIC MODE CODE ----
%%ENDIF
#==================================================================
# o_to_d_lookup -> if cannot remap, return input. note: old versions
# of lua-plugin cannot cope with code like o_to_d_mappings[o[1]]
# because of `long bracket syntax`; the `[o[` freaks it out.
# See: https://github.com/openresty/lua-nginx-module/issues/748
init_by_lua_block {
-- helper functions for elsewhere
slog = function (s) -- in case of manual debugging
ngx.log(ngx.ERR, s)
return
end
has_suffix = function (s, x)
return string.sub(s, -string.len(x)) == x
end
-- mapping onions to dns
o_to_d_mappings = {}
%%BEGIN
o_to_d_mappings["%ONION_ADDRESS%"] = "%DNS_DOMAIN%"
%%END
o_to_d_lookup = function (m)
local k = m[1] -- see note above re: array syntax
return ( o_to_d_mappings[k] or k )
end
onion_to_dns = function (i)
if i == nil or i == "" then
return i
end
if (type(i) == "table") then
local j, k, result
result = {}
for j, k in ipairs(i) do
table.insert(result, onion_to_dns(k))
end
return result
end
local o, num, errs = ngx.re.gsub(i, "\\b([a-z2-7]{16}(?:[a-z2-7]{40})?\\.onion)\\b", o_to_d_lookup, "io")
return o
end
-- mapping dns to onions, for experimentation
d_to_o_mappings = {}
%%BEGIN
d_to_o_mappings["%DNS_DOMAIN%"] = "%ONION_ADDRESS%"
%%END
d_to_o_lookup = function (m)
local k = m[1] -- see note above re: array syntax
return ( d_to_o_mappings[k] or k )
end
dns_to_onion = function (i)
if i == nil or i == "" or i == "*" then
return i
end
if (type(i) == "table") then
local j, k, result
result = {}
for j, k in ipairs(i) do
table.insert(result, dns_to_onion(k))
end
return result
end
local num, errs
%%BEGIN
i, num, errs = ngx.re.gsub(i, "\\b%DNS_DOMAIN_RE2%\\b", "%ONION_ADDRESS%", "io")
%%END
return i
end
-- a note for future maintainers; if we were being strictly orthogonal then
-- the replacement with ONION_ADDRESS in much of this Lua block would have to
-- be double-escaped for potential backslashes, because double-quotes;
-- however this is not needed because DNS forbids backslash; the only code
-- where this becomes evident/necessary is here, with "_RE2":
dnsre_to_onionre = function (i)
local num, errs
-- TODO: BRING THIS INTO LINE WITH dns_to_onion --
%%BEGIN
i, num, errs = ngx.re.gsub(i, "\\b%DNS_DOMAIN_RERE2%\\b", "%ONION_ADDRESS_RE2%", "io")
%%END
return i
end
}
# filter the response headers en-route back to the user
header_filter_by_lua_block {
local k, v
-- ==================================================================
%%IF ! %HARD_MODE%
-- ---- BEGIN CLASSIC MODE CODE ----
-- is this javascript/json? if so, extra processing:
-- 1) set a processing flag to pick up in body_filter_by_lua_block
-- 2) invalidate content-length, because we will change it
k = "Content-Type"
v = ngx.header[k]
if v == "application/javascript" or
v == "application/json" or
v == "application/x-javascript" or
v == "text/css" or
v == "text/javascript" then
ngx.ctx.needs_extra_processing = 1
ngx.header.content_length = nil
end
%%IF %EXTRA_PROCESSING_CSV%
-- run on `v` for further extra_processing_csv checks
%%CSV %EXTRA_PROCESSING_CSV%
if v == "%1%" then
local m, err = ngx.re.match(ngx.var.uri, "%2%", "io")
if m then
ngx.ctx.needs_extra_processing = 1
ngx.header.content_length = nil
end
end
%%ENDCSV
%%ELSE
-- no extra_processing_csv checks
%%ENDIF
-- ---- END CLASSIC MODE CODE ----
%%ENDIF
-- ==================================================================
local origin_rewrites = {
"Access-Control-Allow-Origin",
%%IF %SUPPRESS_HEADER_CSP%
-- CSP headers are suppressed via SUPPRESS_HEADER_CSP
%%ELSE
"Content-Security-Policy",
"Content-Security-Policy-Report-Only",
%%ENDIF
"Link",
"Location",
"Set-Cookie"
}
local i, k
for i, k in ipairs(origin_rewrites) do
local v = ngx.header[k]
if v then
ngx.header[k] = dns_to_onion(v)
end
end
}
# filter the response body en-route back to the user
body_filter_by_lua_block {
-- ==================================================================
%%IF ! %HARD_MODE%
-- ---- BEGIN CLASSIC MODE CODE ----
-- rather than blindly replacing "foo.com" with "foo.onion" everywhere,
-- instead we restrict such brute-force replacement to content that was
-- flagged in header_filter_by_lua_block
if ngx.ctx.needs_extra_processing == 1 then
-- the flag was set; this content deserves brute-force search & replace
local chunk = ngx.arg[1]
-- subs_filter picked up the "//"-anchored strings; now we sub the rest
chunk = dns_to_onion(chunk)
-- and we sub the basic "foo\.com" regular-expressions, too
chunk = dnsre_to_onionre(chunk)
-- more complex regular expressions are out of scope.
ngx.arg[1] = chunk
end
-- ---- END CLASSIC MODE CODE ----
%%ENDIF
-- ==================================================================
%%IF %DEBUG_TRAP%
-- debug traps
local i = ngx.arg[1]
local ct = ngx.header["Content-Type"]
local uri = ngx.var.uri
local iterator, err
%%CSV %DEBUG_TRAP%
iterator, err = ngx.re.gmatch(i, ".{0,32}(%1%).{0,32}")
if not iterator then
ngx.log(ngx.ERR, "gmatch error: ", err)
else
while true do
local m, err = iterator()
if err then
ngx.log(ngx.ERR, "iterator error: ", err)
break
end
if not m then
break
end
slog(string.format("TRAP <<%s>> CONTEXT <<%s>> TYPE <<%s>> URI %s", m[1], m[0], ct, uri))
end -- while true
end -- if iterator
%%ENDCSV
%%ELSE
-- no debug traps
%%ENDIF
}
%%IF %SUPPRESS_HEADER_CSP%
# csp suppression
proxy_hide_header "Content-Security-Policy";
proxy_hide_header "Content-Security-Policy-Report-Only";
%%ELSE
# csp not suppressed, will be rewritten instead, see below
%%ENDIF
%%IF %SUPPRESS_HEADER_HSTS%
# hsts suppression
proxy_hide_header "Strict-Transport-Security";
%%ELSE
# hsts not suppressed
%%ENDIF
%%IF %SUPPRESS_HEADER_HPKP%
# hpkp suppression
proxy_hide_header "Public-Key-Pins";
proxy_hide_header "Public-Key-Pins-Report-Only";
%%ELSE
# hpkp not suppressed
%%ENDIF
# global proxy settings
proxy_read_timeout %NGINX_TIMEOUT%;
proxy_connect_timeout %NGINX_TIMEOUT%;
# SSL config
ssl_certificate %SSL_DIR%/%CERT_PREFIX%.cert;
ssl_certificate_key %SSL_DIR%/%CERT_PREFIX%.pem;
ssl_buffer_size 4k;
#ssl_ciphers 'EECDH+CHACHA20:EECDH+AESGCM:EECDH+AES256'; ## LibreSSL, OpenSSL 1.1.0+
ssl_ciphers 'EECDH+AESGCM:EECDH+AES256'; ## OpenSSL 1.0.1% to 1.0.2%
ssl_ecdh_curve prime256v1;
#ssl_ecdh_curve secp384r1:prime256v1; ## NGINX nginx 1.11.0 and later
ssl_prefer_server_ciphers on;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# websockets: on the basis of http_upgrade, set connection_upgrade:
# empty -> empty
# default -> "upgrade"
map $http_upgrade $connection_upgrade {
default "upgrade";
"" "";
}
%%BEGIN
%%IF %FORCE_HTTPS%
# FORCE_HTTPS is in use; set up separate server for port 80 & force redirects
server {
%%IF %IS_SOFTMAP%
%%RANGE I 1 %SOFTMAP_TOR_WORKERS%
listen unix:%PROJECT_DIR%/%TOR_WORKER_PREFIX%-%I%.d/port-80.sock;
%%ENDRANGE
%%ELSE
listen unix:%PROJECT_DIR%/%ONION_ADDRESS%.d/port-80.sock;
%%ENDIF
# subdomain regexp captures trailing dot, use carefully; does not need "~*"
# NB: this regexp should be kept in-sync with the other FORCE_HTTPS copy
server_name
%ONION_ADDRESS%
~^(?<servernamesubdomain>([-0-9a-z]+\\.)+)%ONION_ADDRESS_RE2%$
;
%%IF %SUPPRESS_TOR2WEB%
# suppress tor2web traffic; "let them use clearnet"
if ( $http_x_tor2web ) {
return 403 "%BLOCK_ERR%";
}
%%ELSE
# tor2web not suppressed
%%ENDIF
# tell the client to try again as HTTPS without ever leaving the onion
# use 307 / temporary redirect because your URIs may change in future
# use $host (not $server) to copy-over subdomains, etc, transparently
# SEND BACK ORIGINAL PARAMS, FIX THEM ONLY UPON FORWARD TO THE PROXY.
return 307 https://$host$request_uri;
}
%%ELSE
# FORCE_HTTPS is not in use, cleartext data may traverse the internet
%%ENDIF
# for %ONION_ADDRESS% -> %DNS_DOMAIN%
server {
%%IF %IS_SOFTMAP%
%%RANGE I 1 %SOFTMAP_TOR_WORKERS%
%%IF not %FORCE_HTTPS%
# FORCE_HTTPS is not in use, cleartext data may traverse the internet
listen unix:%PROJECT_DIR%/%TOR_WORKER_PREFIX%-%I%.d/port-80.sock;
%%ENDIF
listen unix:%PROJECT_DIR%/%TOR_WORKER_PREFIX%-%I%.d/port-443.sock ssl;
%%ENDRANGE
%%ELSE
# hardmap
# unix sockets; use <ONION_ADDRESS>.d as a naming convention
%%IF not %FORCE_HTTPS%
# FORCE_HTTPS is not in use, cleartext data may traverse the internet
listen unix:%PROJECT_DIR%/%ONION_ADDRESS%.d/port-80.sock;
%%ENDIF
listen unix:%PROJECT_DIR%/%ONION_ADDRESS%.d/port-443.sock ssl;
%%ENDIF
# subdomain regexp captures trailing dot, use carefully; does not need "~*"
# NB: this regexp should be kept in-sync with the other FORCE_HTTPS copy
server_name
%ONION_ADDRESS%
~^(?<servernamesubdomain>([-0-9a-z]+\\.)+)%ONION_ADDRESS_RE2%$
;
%%INCLUDE templates.d/nginx-generated-blocks.conf
%%IF %COOKIE_LOCK%
# if we are visiting the magic path, open the cookie-lock
location "%COOKIE_LOCK%" {
add_header Set-Cookie "eotk_lock=%COOKIE_LOCK%;Domain=.%ONION_ADDRESS%;Path=/;Max-Age=604800";
return 200 "OK";
}
%%ELSE
# no cookie_lock cookie setting
%%ENDIF
%%IF %NGINX_HELLO_ONION%
# for test & to help SSL certificate acceptance
location ~* ^/hello[-_]onion/?$ {
return 200 "Hello, Onion User!";
}
%%ELSE
# no "hello-onion" endpoint
%%ENDIF
%%IF %HARDCODED_ENDPOINT_CSV%
# hardcoded_endpoints: 1=path_re,2=response
%%CSV %HARDCODED_ENDPOINT_CSV%
location "%1%" {
return 200 %2%;
}
%%ENDCSV
%%ELSE
# no hardcoded_endpoints
%%ENDIF
# for traffic
location / {
%%INCLUDE templates.d/nginx-generated-checks.conf
%%IF %COOKIE_LOCK%
# check for cookie-lock
if ( $cookie_eotk_lock != "%COOKIE_LOCK%" ) { %NGINX_ACTION_ABORT%; }
%%ELSE
# no cookie-lock checks
%%ENDIF
# deonionify the request_uri for forwarding (both path and args)
set_by_lua_block $request_uri2 {
local old = ngx.var.request_uri
-- onion_to_dns is potentially expensive at scale, so do a cheap test
local m, err = ngx.re.match(old, "\\b[a-z2-7]{16}(?:[a-z2-7]{40})?\\.onion\\b", "o")
if not m then -- nothing to attempt to rewrite, quick return
return old
end
return onion_to_dns(old)
}
# note use of both $scheme and the deonionified uri (both path and args)
set $new_url "$scheme://${servernamesubdomain}%DNS_DOMAIN%$request_uri2";
proxy_pass $new_url;
proxy_http_version 1.1;
# a note on proxy_set_header, add_header, similar methods, etc;
# if you override *any* header then you will lose the other
# headers inherited from the parent contexts:
# https://blog.g3rt.nl/nginx-add_header-pitfall.html
proxy_set_header X-From-Onion %X_FROM_ONION_VALUE%;
proxy_set_header Host "${servernamesubdomain}%DNS_DOMAIN%";
proxy_set_header Accept-Encoding "identity";
proxy_set_header Connection $connection_upgrade; # SSL
proxy_set_header Upgrade $http_upgrade; # SSL
proxy_ssl_server_name on; # SSL
# rewrite request referer
set_by_lua_block $referer2 { return onion_to_dns(ngx.var.http_referer) }
proxy_set_header Referer $referer2;
# rewrite request origin
set_by_lua_block $origin2 { return onion_to_dns(ngx.var.http_origin) }
proxy_set_header Origin $origin2;
# rewrite request cookies
set_by_lua_block $cookie2 { return onion_to_dns(ngx.var.http_cookie) }
proxy_set_header Cookie $cookie2;
%%IF %SUPPRESS_METHODS_EXCEPT_GET%
# suppress non-GET methods (e.g.: POST)
limit_except GET {
deny all;
}
%%ELSE
# non-GET methods (e.g.: POST) are not suppressed
%%ENDIF
}
}
%%END
# header purge
more_clear_headers "Age";
more_clear_headers "Server";
more_clear_headers "Via";
more_clear_headers "X-From-Nginx";
more_clear_headers "X-NA";
more_clear_headers "X-Powered-By";
more_clear_headers "X-Request-Id";
more_clear_headers "X-Runtime";
more_clear_headers "X-Varnish";
}