Не совсем стандартный подход к организации доступа к WiFi сети (Cisco WLC -> FreeRadius -> PHP -> страничка в сети )

    Хочу поделиться решением одной нетривиальной задачи. Было необходимо организовать удобный доступ к беспроводной сети в офисе организации. Сеть предоставляет доступ только к public internet, с корпоративной сетью ничто не связывает — полностью изолированная система. Единственный общий компонент — пользователи. Для упрощения процесса решено аутентификацию делать на уровне Layer 3 — то есть сеть открытая, после подключения надо вводить пароль для доступа к интернету (Cisco WLC Web Auth).
    В принципе все просто, заводятся учетные записи на каждого пользователя, и все готово. Но, ввиду дефицита хелпдеск персонала, заниматься созданием логинов и, тем более, выдачей паролей персоналу было некому. Была поставлена задача использовать один из существующих источников аутентификации, что в стандартной ситуации сделать достаточно просто: например для MS Active Directory можно использовать NPS в качестве радиус сервера, на LDAP же можно подключаться напрямую).
    В нашем случае было и то, и другое (AD для сети и LDAP для доступа к корпоративному интранету ), но из WiFi сегмента туда не было вообще никакого доступа. Максимум что нам смогли дать, это тестовые AD акаунт и акаунт для интранета. Сели, подумали… и вот что придумали


    У FreeRadius есть возможность запрашивать аутентификацию у внешнего скрипта, например PHP. Делается это вот так:
    authorize{
        update control { 
            Auth-Type := `/usr/bin/php -f /etc/raddb/yourscript.php '%{User-Name}' '%{User-Password}'`
        }
    


    В этом случае, PHP должен только проверить логин&пароль и ответить либо Accept либо Reject.

    Используя это мы с успехом проблему решили. Диаграмма того, что получилось:


    PHP скрипт логинится на интранет страничку с переданными ему '%{User-Name}' '%{User-Password}'` через curl, проверяет удалось ли это, и делает echo «Accept» если удалось.

    Вот код скрипта (вход в интранет с использованием IBM Tivoli Access Manager WebSEAL)
            $authSuccessful = False;
            $user = $argv[1];
            $password = $argv[2];
            $url = 'https://intranet.of.the.company.accessible.from.internet/pkmslogin.form';
            $fields_string= "username=".$user."&password=".$password."&login-form-type=pwd&submit=Login";
            //open connection
            $ch = curl_init();
            //set the url, number of POST vars, POST data
            curl_setopt($ch,CURLOPT_URL, $url);
            curl_setopt($ch,CURLOPT_POSTFIELDS, $fields_string);
            curl_setopt($ch,CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)");
            curl_setopt($ch,CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_COOKIESESSION, TRUE);
            curl_setopt($ch,CURLOPT_COOKIEJAR, "cookie.txt");
            curl_setopt($ch,CURLOPT_COOKIEFILE, "cookie.txt");
            curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
            curl_setopt($ch, CURLOPT_POSTREDIR, 0);
            curl_setopt($ch,CURLOPT_RETURNTRANSFER, true);
            //execute post
            $result = curl_exec($ch);
            curl_close($ch);
            if (strpos($result,'Your login was successful') !== false)
                    $authSuccessful = True;
    
            if ($authSuccessful == True)
                    echo "Accept\n";
            else
                    echo "Reject\n";
    


    Работало все на славу, все были довольны..., кроме тех, кто не помнил свой интранет пароль (по какой-то причине пароли на интранет отличались от AD паролей). IT начальство, вместо того чтобы намекнуть юзерам что пароли надо помнить все а не только основной (в данном случае основным паролем оказался AD), попросило нас решить проблему техническими методами.
    По счастливой случайности, у конторы был Citrix XenApp сервер с Web Interface доступным из интернета и MS AD в качестве источника аутентификации. Чем и воспользовались:
    Код скрипта (логин на Citrix Web Interface v 5.4)
            $authSuccessful = False;
            $user = $argv[1];
            $password = $argv[2];
            //WebInterface 5.4.x
            $url = 'https://the.web.interface.of.citrix.xenapp/Citrix/XenApp/auth/login.aspx';
            $fields_string= "user=".$user."&password=".$password."&LoginType=Explicit";
            //open connection
            $ch = curl_init();
            //set the url, number of POST vars, POST data
            curl_setopt($ch,CURLOPT_URL, $url);
            curl_setopt($ch,CURLOPT_POSTFIELDS, $fields_string);
            curl_setopt($ch,CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)");
            curl_setopt($ch,CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_COOKIESESSION, TRUE);
            curl_setopt($ch,CURLOPT_COOKIEJAR, "cookie.txt");
            curl_setopt($ch,CURLOPT_COOKIEFILE, "cookie.txt");
            curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
            curl_setopt($ch, CURLOPT_POSTREDIR, 0);
            curl_setopt($ch,CURLOPT_RETURNTRANSFER, true);
            //execute post
            $result = curl_exec($ch);
            //close connection
            curl_close($ch);
            if (strpos($result,'default.aspx') !== false) {
                    $authSuccessful = True;
            }
    
            if ($authSuccessful == True)
                    echo "Accept\n";
            else
                    echo "Reject\n";
    


    Решили пойти еще дальше, и объединили оба скрипта в один — теперь сначала проверяется интранет логин, затем MS AD через Citrix WI
    Код финального скрипта
            $authSuccessful = False;
            $user = $argv[1];
            $password = $argv[2];
            $url = 'https://intranet.of.the.company.accessible.from.internet/pkmslogin.form';
            $fields_string= "username=".$user."&password=".$password."&login-form-type=pwd&submit=Login";
            //open connection
            $ch = curl_init();
            //set the url, number of POST vars, POST data
            curl_setopt($ch,CURLOPT_URL, $url);
            curl_setopt($ch,CURLOPT_POSTFIELDS, $fields_string);
            curl_setopt($ch,CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)");
            curl_setopt($ch,CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_COOKIESESSION, TRUE);
            curl_setopt($ch,CURLOPT_COOKIEJAR, "cookie.txt");
            curl_setopt($ch,CURLOPT_COOKIEFILE, "cookie.txt");
            curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
            curl_setopt($ch, CURLOPT_POSTREDIR, 0);
            curl_setopt($ch,CURLOPT_RETURNTRANSFER, true);
            //execute post
            $result = curl_exec($ch);
            curl_close($ch);
            if (strpos($result,'Your login was successful') !== false)
                    $authSuccessful = True;
            if ($authSuccessful == False) {
      //WebInterface 5.4.x
            $url = 'https://the.web.interface.of.citrix.xenapp/Citrix/XenApp/auth/login.aspx';
            $fields_string= "user=".$user."&password=".$password."&LoginType=Explicit";
            //open connection
            $ch = curl_init();
            //set the url, number of POST vars, POST data
            curl_setopt($ch,CURLOPT_URL, $url);
            curl_setopt($ch,CURLOPT_POSTFIELDS, $fields_string);
            curl_setopt($ch,CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)");
            curl_setopt($ch,CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_COOKIESESSION, TRUE);
            curl_setopt($ch,CURLOPT_COOKIEJAR, "cookie.txt");
            curl_setopt($ch,CURLOPT_COOKIEFILE, "cookie.txt");
            curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
            curl_setopt($ch, CURLOPT_POSTREDIR, 0);
            curl_setopt($ch,CURLOPT_RETURNTRANSFER, true);
            //execute post
            $result = curl_exec($ch);
            //close connection
            curl_close($ch);
            if (strpos($result,'default.aspx') !== false) {
                    $authSuccessful = True;
            }
    }
            if ($authSuccessful == True)
                    echo "Accept\n";
            else
                    echo "Reject\n";
    

    Similar posts

    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 2

      0
      зачем Вы каждый раз делаете curl_init(); с последующей установкой настроек? (по поводу настроек есть curl_setopt_array. Хотя эту часть можно было вообще бы вынести в отдельную функцию, а для http запроса есть http_build_query… в общем причесать бы код чуток не помешало
        0
        зачем Вы каждый раз делаете curl_init();

        потому что изначально был один только curl_init, и только потом понадобилось два… финальный код это просто копипейст того что было

        в общем причесать бы код чуток не помешало

        если причесанный код сделает скрипт быстрее, то да, а так, на причесывание времени нет…
        я понимаю, глаз режет, но если работает и новый человек сможет прочитать, то предпочту оставить как есть

      Only users with full accounts can post comments. Log in, please.