ΠΠ° Π΄Π° ΠΏΠΎΠ΄Π³ΠΎΡΠ²ΠΈΠΌ Π°Π²ΡΠΎΡΠΈΠ·Π°ΡΠΈΡ Ρ CAPTCHA, Π½ΠΈ ΡΡΡΠ±Π²Π° ΡΠ°ΠΌ ΠΈ Π½Π΅Π³ΠΎΠ²ΠΈΡΠ΅ ΠΏΠ»ΡΠ³ΠΈΠ½ΠΈ , , , , , , , . (ΠΠ°Π΄ΠΎΡ
Π»ΠΈΠ½ΠΊΠΎΠ²Π΅ ΠΊΡΠΌ ΠΌΠΎΠΈΡΠ΅ ΡΠΎΡΠΊΠΎΠ²Π΅, ΡΡΠΉ ΠΊΠ°ΡΠΎ Π½Π°ΠΏΡΠ°Π²ΠΈΡ
Π½ΡΠΊΠΎΠΈ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΡ, ΠΊΠΎΠΈΡΠΎ Π²ΡΠ΅ ΠΎΡΠ΅ Π½Π΅ ΡΡΠΏΡΡ
Π΄Π° Π²Π½Π΅Π΄ΡΡ Π² ΠΎΡΠΈΠ³ΠΈΠ½Π°Π»Π½ΠΈΡΠ΅ ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΠΈ. ΠΠΎΠΆΠ΅ ΡΡΡΠΎ Π΄Π° ΡΠ΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° .)
ΠΠ° Π½Π°ΡΠ°Π»ΠΎ, ΡΠ΅ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΠΈΠΌ
encrypted_session_key "abcdefghijklmnopqrstuvwxyz123456";Π‘Π»Π΅Π΄ ΡΠΎΠ²Π°, Π·Π° Π²ΡΠ΅ΠΊΠΈ ΡΠ»ΡΡΠ°ΠΉ, Π΄Π΅Π°ΠΊΡΠΈΠ²ΠΈΡΠ°ΠΌΠ΅ Π°Π²ΡΠΎΡΠΈΠ·Π°ΡΠΈΠΎΠ½Π½ΠΈΡ Π·Π°Π³Π»Π°Π²ΠΈΠ΅
more_clear_input_headers Authorization;Π‘Π΅Π³Π° Π·Π°ΡΠΈΡΠ°Π²Π°ΠΌΠ΅ Π²ΡΠΈΡΠΊΠΎ Ρ Π°Π²ΡΠΎΡΠΈΠ·Π°ΡΠΈΡ
auth_request /auth;
location =/auth {
internal;
subrequest_access_phase on; # ΡΠ°Π·ΡΠ΅ΡΠ°Π²Π°ΠΌΠ΅ Π°Π²ΡΠΎΡΠΈΠ·Π°ΡΠΈΠΎΠ½Π½Π°ΡΠ° ΡΠ°Π·Π° Π² ΠΏΠΎΠ΄Π·Π°ΠΏΡΠΎΡΠ°
auth_request off; # Π½Π΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ Π°Π²ΡΠΎΡΠΈΠ·Π°ΡΠΈΡ
set_decode_base64 $auth_decode $cookie_auth; # ΡΠ°ΡΠΊΠΎΠ΄ΠΈΡΡΠ΅ΠΌ Π°Π²ΡΠΎΡΠΈΠ·Π°ΡΠΈΠΎΠ½Π½Π°ΡΠ° ΠΊΡΠΊΠ°
set_decrypt_session $auth_decrypt $auth_decode; # ΡΠ°ΡΡΠΈΡΡΠΎΠ²ΡΠ²Π°ΠΌΠ΅ Π°Π²ΡΠΎΡΠΈΠ·Π°ΡΠΈΠΎΠ½Π½Π°ΡΠ° ΠΊΡΠΊΠ°
if ($auth_decrypt = "") { return 401 UNAUTHORIZED; } # Π°ΠΊΠΎ Π½Π΅ ΡΡΠΏΠ΅Ρ Π΄Π° ΡΠ°Π·ΡΠΈΡΡΠΎΠ²Π°ΠΌ, Π·Π½Π°ΡΠΈ ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»ΡΡ Π½Π΅ Π΅ Π°Π²ΡΠΎΡΠΈΠ·ΠΈΡΠ°Π½
more_set_input_headers "Authorization: Basic $auth_decrypt"; # ΠΏΠΎΠ΄ΠΌΠ΅Π½ΡΠΌΠ΅ Π°Π²ΡΠΎΡΠΈΠ·Π°ΡΠΈΡΡΠ° Π½Π° basic (Π·Π° Π΄Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ ΠΏΡΠΎΠΌΠ΅Π½Π»ΠΈΠ²Π°ΡΠ° $remote_user)
auth_basic_user_file /data/nginx/.htaccess; # Π·Π°Π΄Π°Π²Π°ΠΌΠ΅ ΡΠ°ΠΉΠ»Π° Π·Π° basic Π°Π²ΡΠΎΡΠΈΠ·Π°ΡΠΈΡ
auth_basic Auth; # Π²ΠΊΠ»ΡΡΠ²Π°ΠΌΠ΅ basic Π°Π²ΡΠΎΡΠΈΠ·Π°ΡΠΈΡ
echo -n OK; # ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»ΡΡ Π΅ Π°Π²ΡΠΎΡΠΈΠ·ΠΈΡΠ°Π½
}ΠΠ° Π°Π²ΡΠΎΡΠΈΠ·ΠΈΡΠ°Π½ΠΈ ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»ΠΈ ΠΏΠΎΠΊΠ°Π·Π²Π°ΠΌΠ΅ ΡΡΠ΄ΡΡΠΆΠ°Π½ΠΈΠ΅ ΠΎΡ ΡΡΡ Π½Π°ΡΠ° ΠΏΠ°ΠΏΠΊΠ°
location / {
alias html/$remote_user/;
}Π ΠΏΡΠΈ ΠΎΡΡΡΡΡΠ²ΠΈΠ΅ Π½Π° Π°Π²ΡΠΎΡΠΈΠ·Π°ΡΠΈΡ ΠΏΠΎΠΊΠ°Π·Π²Π°ΠΌΠ΅ Π°Π²ΡΠΎΡΠΈΠ·Π°ΡΠΈΠΎΠ½Π½Π°ΡΠ° ΡΠΎΡΠΌΠ° Ρ CAPTCHA
error_page 401 = @error401;
location @error401 {
set_escape_uri $request_uri_escape $request_uri; # ΠΊΠΎΠ΄ΠΈΡΠ°Π½Π΅ Π½Π° Π·Π°ΡΠ²ΠΊΠ°ΡΠ°
return 303 /login?request_uri=$request_uri_escape; # ΠΏΡΠ΅Π½Π°ΡΠΎΡΠ²Π°ΠΌΠ΅ ΠΊΡΠΌ ΡΠΎΡΠΌΡΠ»ΡΡΠ° Π·Π° Π°Π²ΡΠΎΡΠΈΠ·Π°ΡΠΈΡ Ρ ΠΊΠ°ΠΏΡΠ°, Π·Π°ΠΏΠ°Π·Π²Π°ΠΉΠΊΠΈ Π·Π°ΡΠ²ΠΊΠ°ΡΠ°
}
location =/login {
default_type "text/html; charset=utf-8"; # Π·Π°Π΄Π°Π²Π°Π½Π΅ Π½Π° ΡΠΈΠΏΠ°
if ($request_method = GET) { # Π°ΠΊΠΎ ΡΠ°ΠΌΠΎ ΠΏΠΎΠΊΠ°Π·Π²Π°ΠΌΠ΅ ΡΠΎΡΠΌΡΠ»ΡΡΠ° Π·Π° Π°Π²ΡΠΎΡΠΈΠ·Π°ΡΠΈΡ Ρ ΠΊΠ°ΠΏΡΠ°
template login.html.ct2; # Π·Π°Π΄Π°Π²Π°ΠΌΠ΅ ΡΠ°Π±Π»ΠΎΠ½Π°
ctpp2 on; # Π²ΠΊΠ»ΡΡΠ²Π°Π½Π΅ Π½Π° ΡΠ°Π±Π»ΠΎΠ½ΠΈΠ·Π°ΡΠΎΡΠ°
set_secure_random_alphanum $csrf_random 32; # Π·Π°Π΄Π°Π²Π°ΠΌΠ΅ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ»Π½ΠΎ csrf
encrypted_session_expires 300; # Π·Π°Π΄Π°Π²Π°ΠΌΠ΅ Π²ΡΠ΅ΠΌΠ΅ Π½Π° ΠΆΠΈΠ²ΠΎΡ Π½Π° csrf 5 ΠΌΠΈΠ½ΡΡΠΈ (5 * 60 = 300)
set_encrypt_session $csrf_encrypt $csrf_random; # ΠΊΡΠΈΠΏΡΠΈΡΠ°Π½Π΅ Π½Π° ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ»Π½ΠΎΡΠΎ csrf
set_encode_base64 $csrf_encode $csrf_encrypt; # ΠΊΠΎΠ΄ΠΈΡΠ°Π½Π΅ Π½Π° ΠΊΡΠΈΠΏΡΠΈΡΠ°Π½ΠΎΡΠΎ csrf
add_header Set-Cookie "CSRF=$csrf_encode; Max-Age=300"; # Π²ΠΊΠ»ΡΡΠ²Π°Π½Π΅ Π½Π° ΠΊΡΠΈΠΏΡΠΈΡΠ°Π½ΠΎΡΠΎ csrf Π² Π±ΠΈΡΠΊΠ²ΠΈΡΠΊΠ° Π·Π° 5 ΠΌΠΈΠ½ΡΡΠΈ (5 * 60 = 300)
return 200 "{"csrf":"$csrf_random"}"; # Π²ΡΡΡΠ°Π½Π΅ Π½Π° json Π·Π° ΡΠ°Π±Π»ΠΎΠ½ΠΈΠ·Π°ΡΠΎΡΠ°
} # ΠΈΠ½Π°ΡΠ΅ - ΠΎΠ±ΡΠ°Π±ΠΎΡΠ²Π°Π½Π΅ Π½Π° ΡΠΎΡΠΌΡΠ»ΡΡΠ° Π·Π° Π°Π²ΡΠΎΡΠΈΠ·Π°ΡΠΈΡ Ρ ΠΊΠ°ΠΏΡΠ°
set_form_input $csrf_form csrf; # ΠΏΠΎΠ»ΡΡΠ°Π²Π°Π½Π΅ Π½Π° csrf ΠΎΡ ΡΠΎΡΠΌΠ°ΡΠ°
set_unescape_uri $csrf_unescape $csrf_form; # Π΄Π΅ΠΊΠΎΠ΄ΠΈΡΠ°Π½Π΅ Π½Π° csrf ΠΎΡ ΡΠΎΡΠΌΠ°ΡΠ°
set_decode_base64 $csrf_decode $cookie_csrf; # Π΄Π΅ΠΊΠΎΠ΄ΠΈΡΠ°Π½Π΅ Π½Π° csrf ΠΎΡ Π±ΠΈΡΠΊΠ²ΠΈΡΠΊΠ°ΡΠ°
set_decrypt_session $csrf_decrypt $csrf_decode; # Π΄Π΅ΠΊΡΠΈΠΏΡΠΈΡΠ°Π½Π΅ Π½Π° csrf ΠΎΡ Π±ΠΈΡΠΊΠ²ΠΈΡΠΊΠ°ΡΠ°
if ($csrf_decrypt != $csrf_unescape) { return 303 $request_uri; } # Π°ΠΊΠΎ csrf ΠΎΡ ΡΠΎΡΠΌΠ°ΡΠ° Π½Π΅ ΡΡΠ²ΠΏΠ°Π΄Π° Ρ csrf ΠΎΡ Π±ΠΈΡΠΊΠ²ΠΈΡΠΊΠ°ΡΠ°, ΠΏΡΠ΅Π½Π°ΡΠΎΡΠ²Π°ΠΌΠ΅ ΠΎΡΠ½ΠΎΠ²ΠΎ ΠΊΡΠΌ ΠΏΠΎΠΊΠ°Π·Π²Π°Π½Π΅ΡΠΎ Π½Π° ΡΠΎΡΠΌΠ°ΡΠ°
set_form_input $captcha_form captcha; # ΠΏΠΎΠ»ΡΡΠ°Π²Π°Π½Π΅ Π½Π° ΠΊΠ°ΠΏΡΠ° ΠΎΡ ΡΠΎΡΠΌΠ°ΡΠ°
set_unescape_uri $captcha_unescape $captcha_form; # Π΄Π΅ΠΊΠΎΠ΄ΠΈΡΠ°Π½Π΅ Π½Π° ΠΊΠ°ΠΏΡΠ° ΠΎΡ ΡΠΎΡΠΌΠ°ΡΠ°
set_md5 $captcha_md5 "secret${captcha_unescape}${csrf_decrypt}"; # ΠΈΠ·ΡΠΈΡΠ»ΡΠ²Π°ΠΌΠ΅ md5
if ($captcha_md5 != $cookie_captcha) { return 303 $request_uri; } # Π°ΠΊΠΎ md5 Π½Π΅ ΡΡΠ²ΠΏΠ°Π΄Π° Ρ ΠΊΠ°ΠΏΡΠ°ΡΠ° ΠΎΡ Π±ΠΈΡΠΊΠ²ΠΈΡΠΊΠ°ΡΠ°, ΠΏΡΠ΅Π½Π°ΡΠΎΡΠ²Π°ΠΌΠ΅ ΠΎΡΠ½ΠΎΠ²ΠΎ ΠΊΡΠΌ ΠΏΠΎΠΊΠ°Π·Π²Π°Π½Π΅ΡΠΎ Π½Π° ΡΠΎΡΠΌΠ°ΡΠ°
set_form_input $username_form username; # ΠΏΠΎΠ»ΡΡΠ°Π²Π°Π½Π΅ Π½Π° ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»ΡΠΊΠΎ ΠΈΠΌΠ΅ ΠΎΡ ΡΠΎΡΠΌΠ°ΡΠ°
set_form_input $password_form password; # ΠΏΠΎΠ»ΡΡΠ°Π²Π°Π½Π΅ Π½Π° ΠΏΠ°ΡΠΎΠ»Π° ΠΎΡ ΡΠΎΡΠΌΠ°ΡΠ°
set_unescape_uri $username_unescape $username_form; # Π΄Π΅ΠΊΠΎΠ΄ΠΈΡΠ°Π½Π΅ Π½Π° ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»ΡΠΊΠΎΡΠΎ ΠΈΠΌΠ΅ ΠΎΡ ΡΠΎΡΠΌΠ°ΡΠ°
set_unescape_uri $password_unescape $password_form; # Π΄Π΅ΠΊΠΎΠ΄ΠΈΡΠ°Π½Π΅ Π½Π° ΠΏΠ°ΡΠΎΠ»Π°ΡΠ° ΠΎΡ ΡΠΎΡΠΌΠ°ΡΠ°
encrypted_session_expires 2592000; # Π·Π°Π΄Π°Π²Π°ΠΌΠ΅ Π²ΡΠ΅ΠΌΠ΅ Π½Π° ΠΆΠΈΠ²ΠΎΡ Π½Π° ΡΠ΅ΡΠΈΡΡΠ° 30 Π΄Π½ΠΈ (30 * 24 * 60 * 60 = 2592000)
set $username_password "$username_unescape:$password_unescape"; # Π·Π°Π΄Π°Π²Π°ΠΌΠ΅ Π±Π°Π·ΠΎΠ²Π° Π°Π²ΡΠΎΡΠΈΠ·Π°ΡΠΈΡ
set_encode_base64 $username_password_encode $username_password; # ΠΊΠΎΠ΄ΠΈΡΠ°Π½Π΅ Π½Π° Π±Π°Π·ΠΎΠ²Π°ΡΠ° Π°Π²ΡΠΎΡΠΈΠ·Π°ΡΠΈΡ
set_encrypt_session $auth_encrypt $username_password_encode; # ΠΊΡΠΈΠΏΡΠΈΡΠ°Π½Π΅ Π½Π° Π±Π°Π·ΠΎΠ²Π°ΡΠ° Π°Π²ΡΠΎΡΠΈΠ·Π°ΡΠΈΡ
set_encode_base64 $auth_encode $auth_encrypt; # ΠΊΠΎΠ΄ΠΈΡΠ°Π½Π΅ Π½Π° ΠΊΡΠΈΠΏΡΠΈΡΠ°Π½Π°ΡΠ° Π±Π°Π·ΠΎΠ²Π° Π°Π²ΡΠΎΡΠΈΠ·Π°ΡΠΈΡ
add_header Set-Cookie "Auth=$auth_encode; Max-Age=2592000"; # Π²ΠΊΠ»ΡΡΠ²Π°Π½Π΅ Π½Π° ΠΊΡΠΈΠΏΡΠΈΡΠ°Π½Π°ΡΠ° Π±Π°Π·ΠΎΠ²Π° Π°Π²ΡΠΎΡΠΈΠ·Π°ΡΠΈΡ Π² Π±ΠΈΡΠΊΠ²ΠΈΡΠΊΠ° Π·Π° 30 Π΄Π½ΠΈ (30 * 24 * 60 * 60 = 2592000)
set $arg_request_uri_or_slash $arg_request_uri; # ΠΊΠΎΠΏΠΈΡΠ°Π½Π΅ Π½Π° Π·Π°ΡΠ²ΠΊΠ°ΡΠ° ΠΎΡ Π°ΡΠ³ΡΠΌΠ΅Π½ΡΠ°
set_if_empty $arg_request_uri_or_slash "/"; # Π°ΠΊΠΎ Π°ΡΠ³ΡΠΌΠ΅Π½ΡΡΡ Π½Π΅ Π΅ Π·Π°Π΄Π°Π΄Π΅Π½, Π·Π°Π΄Π°Π²Π°ΠΌΠ΅ Π½Π°ΡΠ°Π»ΠΎΡΠΎ
set_unescape_uri $request_uri_unescape $arg_request_uri_or_slash; # Π΄Π΅ΠΊΠΎΠ΄ΠΈΡΠ°Π½Π΅ Π½Π° Π·Π°ΡΠ²ΠΊΠ°ΡΠ°
return 303 $request_uri_unescape; # ΠΏΡΠ΅Π½Π°ΡΠΎΡΠ²Π°ΠΌΠ΅ ΠΊΡΠΌ Π·Π°ΠΏΠ°Π·Π΅Π½Π°ΡΠ° Π·Π°ΡΠ²ΠΊΠ°
}login.html
<html>
<body>
<form method="post" action="">
<input type="hidden" name="csrf" value="<TMPL_var csrf>" />
ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»ΡΠΊΠΎ ΠΈΠΌΠ΅: <input type="text" name="username" placeholder="ΠΡΠ²Π΅Π΄Π΅ΡΠ΅ ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»ΡΠΊΠΎ ΠΈΠΌΠ΅..." /><br />
ΠΏΠ°ΡΠΎΠ»Π°: <input type="password" name="password" /><br />
ΠΊΠ°ΠΏΡΠ°: <img src="/captcha?csrf=<TMPL_var csrf>"/><input type="text" name="captcha" autocomplete="off" /><br />
<input type="submit" name="submit" value="ΠΈΠ·ΠΏΡΠ°ΡΠΈ" />
<input type="hidden" name="trp-form-language" value="bg"/></form>
</body>
</html>ΠΠ·ΡΠΎΡΠ½ΠΈΠΊ: habr.com
