2016-07-22

freeradius2 採 pop3 中繼認證(支援 google apps, office365)

採用文章:

  1. 山姆的IT人生: Freeradius 整合Gmail POP3s 協定認證
  2. 新家: Freeradius2 POP3 over SSL 認證
環境:
  • CentOS 5.11
  • perl, freeradius2, freeradius2-utils, freeradius2-perl...(好像)
  • cpan→Mail::POP3Client, cpan→IO::Socket::SSL
  • 要用來認證的帳號,要記得去設定開啟 pop 

會異動的檔案:
  1. raddb/proxy.conf
    [到檔尾,放在 realm DEFAULT {} 之前,假設是gmail.com]
    realm gmail.com {
       type = radius #都用 freeradius 了,不用解釋 type ,但 radius 不是唯一
       authhost = LOCAL #主要看你 radius.conf 的設定
       accthost = LOCAL #主要看你 radius.conf 的設定
       #secret = xxx #因為要跑去用 pop3 認證,所以不會使用自我認定,所以不需要密碼
       nostrip #告知送出帳號時要帶 realm
    }
  2. raddb/modules/gpop3perl
    [gpop3perl 是用 modules/perl 複製出來的]
    [紅字可以自定,但要和 site-available/default, site-available/inner-tunnel 要對應]
    [藍字可以自定,但要和步驟 3 從 example.pl 複製過來的檔名對應]
    perl gpop3 {
       ....
       ....(前略)
       module = ${confdir}/gpop3.pl
       ....
       ....(後略)
    }
  3. raddb/gpop3.pl
    [gpop3.pl 是從 raddb/example.pl 複製出來的]
    [紅色是增加的]
    [橘色是刪除或註解起來]
    [藍色是增加的]
    ....
    ....(前略)
    use Data::Dumper;
    use Mail::POP3Client;
    use IO::Socket::SSL;
    ....
    ....(中略)
    ....
    sub authorize {
    ....
    ....#這一區不用動
    ....
    }
    sub authenticate {
    # For debugging purposes only
    # &log_request_attributes;
    # if ($RAD_REQUEST{'User-Name'} =~ /^baduser/i) {
    # # Reject user and tell him why
    # $RAD_REPLY{'Reply-Message'} = "Denied access by rlm_perl function";
    # return RLM_MODULE_REJECT;
    # } else {
    # # Accept user and set some attribute
    # $RAD_REPLY{'h323-credit-amount'} = "100";
    # return RLM_MODULE_OK;
    # }


            my $pop = Mail::POP3Client->new(
                    USER => $RAD_REQUEST{'Stripped-User-Name'},
                    PASSWORD => $RAD_REQUEST{'User-Password'},
                    HOST => "pop.gmail.com", #google apps pop3 server, office365 pop server is outlook.office365.com
                    USESSL => 1,
                    DEBUG => 1, # 可在 radius.log 看到詳細的認證記錄,不看改 0 就好
            );

            if($pop->Connect()){#連接成功
                    # login success
                    return RLM_MODULE_OK;
            }else{#連接失敗
                    # login fail
                    return RLM_MODULE_REJECT;    
            }

            $pop->Close;#認證結束,關閉連線

    }
    ....
    ....(後略)
  4. raddb/site-available/default, raddb/site-available/inner-tunnel
    [有的狀況 inner-tunnel 並不用設定,但我自己的狀況不設定會有異常]
    [紅色的要建立的,POP3s 要和步驟 5 raddb/users 的對應]
    [gpop3 要跟步驟 2, 3 對應]
    ....
    ....(前略)
    authorize {
    ....(小略)
    #perl
    gpop3
    ....(小略)
    }

    authenticate {
    ....(小略)
    #Auth-Type PERL {
    #   perl
    #}
    Auth-Type POP3s {
       gpop3
    }

    ....(小略)
    }
    ....
    ....(後略)
  5. raddb/users
    [至檔尾]
    [紅色的要建立的]
    ....(前略)
    DEFAULT Auth-Type = POP3s, Realm = gmail.com
    ....(後略)

4 則留言:

Unknown 提到...

請問一下
我現在做好了上述的步驟
可是在用 radtest測試時 radiusd -X 上顯示
****************************************************************************
Using the default of SSL_verify_mode of SSL_VERIFY_NONE for client
is deprecated! Please set SSL_verify_mode to SSL_VERIFY_PEER
together with SSL_ca_file|SSL_ca_path for verification.
If you really don't want to verify the certificate and keep the
connection open to Man-In-The-Middle attacks please set
SSL_verify_mode explicitly to SSL_VERIFY_NONE in your application.
****************************************************************************

(1) Discarding duplicate request from client localhost port 44998 - ID: 182 due to delayed response

這樣的紅字

死狐狸 提到...

你好

你有確認過你的 perl 有安裝或啟用 IO::Socket::SSL 嗎

你可以用下面的測試一下
perl -M'IO::Socket::SSL' -e 'print "$IO::Socket::SSL::VERSION\n"'

看看有沒有回應版本號,如果沒有,那就代表你沒安裝,你再使用 YUM 或其他安裝庫來安裝試試

Unknown 提到...

(radtest messages)
Sending Access-Request of id 98 to 127.0.0.1 port 1812
User-Name = "xxxxxxx@gmail.com"
User-Password = "yyyyyyy"
NAS-IP-Address = 192.168.1.4
NAS-Port = 0
Message-Authenticator = 0x00000000000000000000000000000000
rad_recv: Access-Reject packet from host 127.0.0.1 port 1812, id=98, length=20


(radiusd -X : debug messges)
Ready to process requests.
rad_recv: Access-Request packet from host 127.0.0.1 port 56020, id=98, length=89
User-Name = " xxxxxxx @gmail.com"
User-Password = "yyyyyyy"
NAS-IP-Address = 192.168.1.4
NAS-Port = 0
Message-Authenticator = 0x0c0e58626c706b1397ccad600ba58433
# Executing section authorize from file /etc/raddb/sites-enabled/default
+group authorize {
++[preprocess] = ok
++[chap] = noop
++[mschap] = noop
++[digest] = noop
[suffix] Looking up realm "gmail.com" for User-Name = " xxxxxxx @gmail.com"
[suffix] Found realm "gmail.com"
[suffix] Adding Realm = "gmail.com"
[suffix] Authentication realm is LOCAL.
++[suffix] = ok
[eap] No EAP-Message, not doing EAP
++[eap] = noop
Invalid operator for item Realm: reverting to '=='
[files] users: Matched entry DEFAULT at line 210
++[files] = ok
rlm_perl: Added pair User-Name = xxxxxxx @gmail.com
rlm_perl: Added pair User-Password =yyyyyyy
rlm_perl: Added pair Realm = gmail.com
rlm_perl: Added pair NAS-Port = 0
rlm_perl: Added pair NAS-IP-Address = 192.168.1.4
rlm_perl: Added pair Message-Authenticator = 0x0c0e58626c706b1397ccad600ba58433
rlm_perl: Added pair Realm = gmail.com
rlm_perl: Added pair Auth-Type = POP3s
++[gpop3] = ok
++[expiration] = noop
++[logintime] = noop
++[pap] = noop
+} # group authorize = ok
Found Auth-Type = POP3s
# Executing group from file /etc/raddb/sites-enabled/default
+group POP3s {
rlm_perl: Added pair User-Name = xxxxxxx@gmail.com
rlm_perl: Added pair User-Password = yyyyyyy
rlm_perl: Added pair Realm = gmail.com
rlm_perl: Added pair NAS-IP-Address = 192.168.1.4
rlm_perl: Added pair NAS-Port = 0
rlm_perl: Added pair Message-Authenticator = 0x0c0e58626c706b1397ccad600ba58433
rlm_perl: Added pair Auth-Type = POP3s
rlm_perl: Added pair Realm = gmail.com
++[gpop3] = reject
+} # group POP3s = reject
Failed to authenticate the user.
Using Post-Auth-Type REJECT
# Executing group from file /etc/raddb/sites-enabled/default
+group REJECT {
[attr_filter.access_reject] expand: %{User-Name} -> xxxxxxx @gmail.com
attr_filter: Matched entry DEFAULT at line 11
++[attr_filter.access_reject] = updated
+} # group REJECT = updated
Delaying reject of request 0 for 1 seconds
Going to the next request
Waking up in 0.9 seconds.
Sending delayed reject for request 0
Sending Access-Reject of id 98 to 127.0.0.1 port 56020
Waking up in 4.9 seconds.
Cleaning up request 0 ID 98 with timestamp +14
Ready to process requests.


可以幫忙確認認題嗎 ?
還是測試方法錯誤!!

死狐狸 提到...

@Oyster Lin
先請問一下您在做 radiusd -X 做 debug 測試時,在 gpop3.pl 的 DEBUG 有沒有設定為 1 ?

因為我看訊息並沒有注意到有從 pop.gmail.com 回覆回來的資訊…可能要請您確認一下。

另外,因為這 perl 程式是走 pop.gmail.com 去測試 gmail 的帳號資訊,但因為是使用 pop 協定,所以可能要確定幾件事:
1) radius 主機本身 firewall 或所在的網路環境有開放 pop protocol 或可以連外
2) 用來測試的 gmail 帳戶有啟用 pop 功能 (可以看這邊:https://support.google.com/mail/answer/7104828?hl=zh-Hant)
3) 可以在 USESSL => 1 之前多加指定 PORT => 995 試試

我不太確定 gmail 是不是預設是關閉 pop ,然後預設開啟 imap ,如果是預設開啟 imap ,其實也可以把 gpop3.pl 改寫成用 imap 認證 (可以參考:https://stackoverflow.com/questions/13921109/access-to-gmail-using-mailpop3client)

祝順利。