-
Notifications
You must be signed in to change notification settings - Fork 2
/
nginx.conf
111 lines (99 loc) · 3.21 KB
/
nginx.conf
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
worker_processes 4;
daemon off;
error_log stderr info;
events {
worker_connections 1024;
}
http {
include mime.types;
lua_code_cache on;
client_body_temp_path tmp/client_body;
fastcgi_temp_path tmp/fastcgi;
proxy_temp_path tmp/proxy;
scgi_temp_path tmp/scgi;
uwsgi_temp_path tmp/uwsgi;
limit_req_zone $binary_remote_addr zone=heavy:1m rate=2r/s;
lua_shared_dict challenges 2m;
lua_shared_dict sessions 2m;
server {
listen %PORT%;
location / {
default_type text/html;
content_by_lua '
local template = require "template"
template.print(
require "templates.index",
{ background = "white", foreground = "black" },
ngx.print
)
';
}
location /challenge {
limit_req zone=heavy nodelay;
default_type image/png;
expires 0;
add_header Pragma no-cache;
add_header Cache-Control 'no-cache, no-store, must-revalidate';
content_by_lua '
local pool = require "pool"
local image = require "image"
local hmac = require "crypto".hmac
local challenge = pool:fetch()
if challenge then
local time = os.time()
local hash = hmac.digest("sha1", challenge, time)
-- Create session
ngx.shared.sessions:set(hash, time, 180)
ngx.header["Set-Cookie"] = ("recattle=%s"):format(hash)
local args = ngx.req.get_uri_args(3)
for key, value in pairs(args) do
args[key] = value:gsub("[^%w%d%%#]", "")
end
-- Generate image
ngx.print(image.create(challenge, "png", args.background, args.foreground))
else
ngx.print(image.create("NO UPSTREAM!11", "png", "white", "red"))
end
';
}
location /frame {
default_type text/html;
content_by_lua '
local template = require "template"
local args = ngx.req.get_uri_args(5)
args.method = args.method or "get"
args.callback = (args.callback or "http://recattle.dannote.net/validate"):gsub("[^%w%d/:.#%%%-]", "")
args.background = (args.background or "white"):gsub("[^%w%d%%#]", "")
args.foreground = (args.foreground or "black"):gsub("[^%w%d%%#]", "")
template.print(require "templates.frame", args, ngx.print)
';
}
location /validate {
default_type text/plain;
lua_need_request_body on;
content_by_lua '
local hmac = require "crypto".hmac
local utf8 = require "utf8"
local sessions = ngx.shared.sessions
function invalid()
ngx.print("false")
ngx.exit(ngx.HTTP_OK)
end
local response = ngx.req.get_uri_args(2).response or ngx.req.get_post_args(2).response or invalid()
local hash = ngx.var.cookie_recattle or args.challenge or invalid()
local time = sessions:get(hash) or invalid()
if hmac.digest("sha1", utf8.upper(response), time) ~= hash then
invalid()
end
ngx.print("true")
sessions:delete(hash)
';
}
location /yandex {
internal;
proxy_set_header User-Agent recattle;
proxy_pass_request_headers off;
proxy_pass https://export.yandex.ru/last/last20x.xml;
}
}
}