Resipi Nginx: Keizinan LDAP dengan Captcha

Untuk menyediakan kebenaran dengan captcha, kami perlukan nginx dan pemalamnya sesi disulitkan, borang-input, ctpp2, echo, ldap, tajuk-lebih lagi, auth_request, set-misc. (Saya menyediakan pautan ke garpu saya, kerana saya membuat beberapa perubahan yang masih belum dimasukkan ke dalam repositori asal. Anda juga boleh menggunakan siap sedia.)

Sebagai permulaan, mari kita tetapkan

encrypted_session_key "abcdefghijklmnopqrstuvwxyz123456";

Seterusnya, untuk berjaga-jaga, lumpuhkan pengepala kebenaran

more_clear_input_headers Authorization;

Kini kami melindungi segala-galanya dengan kebenaran

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_ldap_realm Auth; # Π²ΠΊΠ»ΡŽΡ‡Π°Π΅ΠΌ ldap Π°Π²Ρ‚ΠΎΡ€ΠΈΠ·Π°Ρ†ΠΈΡŽ
    auth_basic_ldap_url ldap://ldap.server.com; # Π·Π°Π΄Π°Ρ‘ΠΌ адрСс
    auth_basic_ldap_bind_dn dn.server.com; # Π·Π°Π΄Π°Ρ‘ΠΌ постфикс
    echo -n OK; # ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ Π°Π²Ρ‚ΠΎΡ€ΠΈΠ·ΠΎΠ²Π°Π½
}

Untuk pengguna yang diberi kuasa kami menunjukkan kandungan daripada folder mereka

location / {
    alias html/$remote_user/;
}

Dan jika tiada kebenaran, kami menunjukkan borang kebenaran dengan 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"; # Π·Π°Π΄Π°Ρ‘ΠΌ basic Π°Π²Ρ‚ΠΎΡ€ΠΈΠ·Π°Ρ†ΠΈΡŽ
    set_encode_base64 $username_password_encode $username_password; # ΠΊΠΎΠ΄ΠΈΡ€ΡƒΠ΅ΠΌ basic Π°Π²Ρ‚ΠΎΡ€ΠΈΠ·Π°Ρ†ΠΈΡŽ
    set_encrypt_session $auth_encrypt $username_password_encode; # Π·Π°ΡˆΠΈΡ„Ρ€ΠΎΠ²Ρ‹Π²Π°Π΅ΠΌ basic Π°Π²Ρ‚ΠΎΡ€ΠΈΠ·Π°Ρ†ΠΈΡŽ
    set_encode_base64 $auth_encode $auth_encrypt; # ΠΊΠΎΠ΄ΠΈΡ€ΡƒΠ΅ΠΌ Π·Π°ΡˆΠΈΡ„Ρ€ΠΎΠ²Π°Π½Π½ΡƒΡŽ basic Π°Π²Ρ‚ΠΎΡ€ΠΈΠ·Π°Ρ†ΠΈΡŽ
    add_header Set-Cookie "Auth=$auth_encode; Max-Age=2592000"; # ΠΏΠΎΠΌΠ΅Ρ‰Π°Π΅ΠΌ Π·Π°ΡˆΠΈΡ„Ρ€ΠΎΠ²Π°Π½Π½ΡƒΡŽ basic Π°Π²Ρ‚ΠΎΡ€ΠΈΠ·Π°Ρ†ΠΈΡŽ Π² Π°Π²Ρ‚ΠΎΡ€ΠΈΠ·Π°Ρ†ΠΈΠΎΠ½Π½ΡƒΡŽ ΠΊΡƒΠΊΡƒ Π½Π° 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; # пСрСнаправляСм Π½Π° сохранённый запрос
}

log masuk.html

<html>
    <body>
        <form method="post">
            <input type="hidden" name="csrf" value="<TMPL_var csrf>" />
            username: <input type="text" name="username" placeholder="Enter User Name..." /><br />
            password: <input type="password" name="password" /><br />
            captcha: <img src="/captcha?csrf=<TMPL_var csrf>"/><input type="text" name="captcha" autocomplete="off" /><br />
            <input type="submit" name="submit" value="submit" />
        </form>
    </body>
</html>

Sumber: www.habr.com

Tambah komen