ΠΠ° Π΄Π° ΠΏΠΎΠ΄Π³ΠΎΡΠ²ΠΈΠΌ ΡΠ΄ΠΎΡΡΠΎΠ²Π΅ΡΡΠ²Π°Π½Π΅ Ρ 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"; # ΠΏΠΎΠ΄ΠΌΠ΅Π½ΡΠΌΠ΅ Π°Π²ΡΠΎΡΠΈΠ·Π°ΡΠΈΡΡΠ° Ρ ΠΎΡΠ½ΠΎΠ²Π½Π° (Π·Π° Π΄Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ ΠΏΡΠΎΠΌΠ΅Π½Π»ΠΈΠ²Π°ΡΠ° $remote_user)
auth_basic_user_file /data/nginx/.htaccess; # Π·Π°Π΄Π°Π²Π°ΠΌΠ΅ ΡΠ°ΠΉΠ»Π° Π·Π° ΠΎΡΠ½ΠΎΠ²Π½Π° Π°Π²ΡΠΎΡΠΈΠ·Π°ΡΠΈΡ
auth_basic Auth; # Π°ΠΊΡΠΈΠ²ΠΈΡΠ°ΠΌΠ΅ ΠΎΡΠ½ΠΎΠ²Π½Π°ΡΠ° Π°Π²ΡΠΎΡΠΈΠ·Π°ΡΠΈΡ
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
