freeradius client 和jradius安裝編譯


freeradius client

radtest只是用來調試的,radclient功能更強大。用法如下:

From the man page we can see that radclient gives us much more power as compared to radtest. The following command can be used as an equivalent to the radtest command used at the start of this chapter:

$> echo "User-Name=alice,User-Password=passme" | radclient 127.0.0.1 auth testing123

radclient的格式: Usage: radclient [options] server[:port] <command> [<secret>] 

<command>  類型:  One of auth, acct, status, coa, or disconnect.

 

如果不是調試模式的話,只會返回code碼。

The response from radclient returns a code number and does not clearly indicate a pass or fail for an Access-Request. This is where you need to know the RADIUS packet codes as discussed in Chapter 1.

Here is the response of an Access-Accept packet (Code 2 成功):

Received response ID 32, code 2, length = 40 Framed-IP-Address = 192.168.1.65
Reply-Message = "Hello, alice"

Here is the response of an Access-Reject packet:(code 3  鑒權失敗

Received response ID 59, code 3, length = 34
Reply-Message = "Hello, alice"

 

jradius安裝/編譯/使用

當然還是優先參考官方文檔:http://coova.github.io/JRadius/FreeRADIUS/

wget ftp://ftp.freeradius.org/pub/freeradius/freeradius-server-2.1.1.tar.bz2
bzcat freeradius-server-2.1.1.tar.bz2 | tar xf -
cd freeradius-server-2.1.1 echo rlm_jradius >> src/modules/stable

 ./configure
 make
 make install

就是在解壓后編譯前,在 src/modules/stable文件添加一行rlm_jradius ,然后再編譯就有freeradius對jradius的支持模塊了。

 修改freeradius的配置

etc/raddb/radiusd.conf  配置文件中添加下面的部分

modules {
   ...
   # configure the rlm_jradius module
   jradius {
      name      = "example"             # The "Requester" name (a single
                                        # JRadius server can have
                                        # multiple "applications")
      primary   = "localhost"           # Uses default port 1814
      secondary = "192.168.0.1"         # Fail-over server
      tertiary  = "192.168.0.1:8002"    # Fail-over server on port 8002
      timeout   = 1                     # Connect Timeout
      onfail    = NOOP                  # What to do if no JRadius
                                        # Server is found. Options are:
                                        # FAIL (default), OK, REJECT, NOOP
      keepalive = yes                   # Keep connections to JRadius pooled
      connections = 8                   # Number of pooled JRadius connections
  }
}

在sites-available/default配置文件中,各個模塊添加jradius關鍵字

authorize {
   ...
   jradius
}
 
post-auth {
   ...
   jradius
   Post-Auth-Type REJECT {             # Use this to also process failures -
       jradius                         # AccessReject replies 
   }                                   # from the post-auth handler.
}
  
preacct {
   ...
   jradius
}
  
accounting {
   ...
   jradius
} 

 以上步驟freeradius部分已經配置好了。之后編譯安裝jradius

編譯安裝jradius

 官方給的步驟

官方是先編譯后解壓,應該是先下載源碼解壓后在根目錄用maven編譯

mvn clean install

編譯成功后,在  jradius/server/scripts  下有start.sh文件但是無法啟動,找不到類,vim start.sh打開

(cd `dirname $0`; classpath=".:./lib"
for jar in ./lib/*.jar; do
  classpath="$classpath:$jar" 
done
CLASSPATH="$classpath" java net.jradius.StartSpring)

由於當前目錄沒有lib文件夾,找不到類,我直接修改腳本,

(cd `dirname $0`; classpath=".:./lib"
for jar in /data/jradius/server/target/lib/*.jar; do
  classpath="$classpath:$jar" 
done
CLASSPATH="$classpath" java net.jradius.StartSpring)

/data/jradius 是我的jradius安裝目錄,這樣還不行,報錯缺少配置文件,再把 jradius/server/config下的所以配置文件copy到start.sh的目錄下,再次./start.sh啟動就可以成功了。

接下來用java代碼測試,測試代碼可以參考:

public class JradiusTest {

    public static void main(String[] args) throws Exception {
        if(args.length!=4) {
            System.out.println("<host><secret><username><password>");
            System.exit(2);
        }
         InetAddress host = InetAddress.getByName(args[0]);
         boolean aa=new JradiusTest().isRadius(host, 1812, 1813, "pap",args[2] , args[3], args[1], "110.110.110.110", 3, 3000);
         System.out.println("鑒權結果:"+aa);
    }
    
    /**
     * 
     * @param host
     *            The address for the radius server test.
     * @param authport
     *            Radius authentication port
     * @param acctport
     *            Radius accounting port - required by jradius
     *            but not explicitly checked
     * @param authType
     *            authentication type - pap or chap
     * @param user
     *            user for Radius authentication
     * @param password
     *            password for Radius authentication
     * @param secret
     *            Radius shared secret
     * @param timeout
     *            Timeout in milliseconds
     * @param retry 
     *          Number of times to retry 
     *
     * @param nasid
     *            NAS Identifier to use
     *
     * @return True if server, false if not.
     */
    @SuppressWarnings("unused")
    private boolean isRadius(final InetAddress host, final int authport, final int acctport, final String authType,
            final String user, final String password, final String secret, final String nasid, final int retry, final int timeout) {

        boolean isRadiusServer = false;

        AttributeFactory.loadAttributeDictionary("net.jradius.dictionary.AttributeDictionaryImpl");
        try {
//            final RadiusClient rc = new RadiusClient(host, secret, authport, acctport, convertTimeoutToSeconds(timeout));
            final RadiusClient rc = new RadiusClient(host, secret, authport, acctport, timeout);

            final AttributeList attributes = new AttributeList();
            attributes.add(new Attr_UserName(user));
            attributes.add(new Attr_NASIdentifier(nasid));
            attributes.add(new Attr_UserPassword(password));

            final AccessRequest accessRequest = new AccessRequest(rc, attributes);
            final RadiusAuthenticator auth;
            if (authType.equalsIgnoreCase("chap")) {
                auth = new CHAPAuthenticator();
            } else if (authType.equalsIgnoreCase("pap")) {
                auth = new PAPAuthenticator();
            } else if (authType.equalsIgnoreCase("mschapv1")) {
                auth = new MSCHAPv1Authenticator();
            } else if (authType.equalsIgnoreCase("mschapv2")) {
                auth = new MSCHAPv2Authenticator();
            } else if (authType.equalsIgnoreCase("eapmd5")) {
                auth = new EAPMD5Authenticator();
            } else if (authType.equalsIgnoreCase("eapmschapv2")) {
                auth = new EAPMSCHAPv2Authenticator();
            } else {
//                LogUtils.warnf(this, "Unknown authenticator type '%s'", authType);
                return isRadiusServer;
            }

            RadiusPacket reply = rc.authenticate(accessRequest, auth, retry);
            isRadiusServer = reply instanceof AccessAccept;
//            LogUtils.debugf(this, "Discovered RADIUS service on %s", host.getCanonicalHostName());
        } catch (final Throwable e) {
//            LogUtils.debugf(this, e, "Error while attempting to discover RADIUS service on %s", host.getCanonicalHostName());
            isRadiusServer = false;
        }

        return isRadiusServer;
    }

}

更多jradius客戶端使用代碼參考

github的example

https://github.com/coova/jradius/blob/master/example/src/main/java/net/jradius/example/ExampleRadiusClient.java

 和programcreek的example

https://www.programcreek.com/java-api-examples/index.php?api=net.jradius.client.RadiusClient

 

other :

我用上面代碼去鑒權的時候,鑒權可以成功,但是jradius的服務端會報錯

net.jradius.server.KeepAliveListener.run(): shutting down tcp socket listener
java.nio.BufferUnderflowException
    at java.nio.Buffer.nextGetIndex(Buffer.java:498)
    at java.nio.HeapByteBuffer.getInt(HeapByteBuffer.java:355)
    at net.jradius.packet.Format.getUnsignedInt(Format.java:389)
    at net.jradius.freeradius.FreeRadiusListener.parseRequest(FreeRadiusListener.java:98)
    at net.jradius.server.ListenerRequest.getEventFromListener(ListenerRequest.java:78)
    at net.jradius.server.TCPListenerRequest.accept(TCPListenerRequest.java:72)
    at net.jradius.server.KeepAliveListener.run(KeepAliveListener.java:61)

而且freeradius的debug日志中看到,賬號密碼鑒權是成功的,但是rlm_jradius 發送數據的時候失敗了。

測試代碼中打印出reply.getCode() ,為2,說明鑒權是成功的,我不知道請求包缺少了必要的數據還是我配置文件沒有弄對,導致數據包在FreeRadiusListener.parseRequest解析時報錯。

研究后發現  上面的報錯是應為ByteBuffer的limit小於實際的數據長度導致的,我以為是jradius本身的一個小bug,就注釋掉FreeradiusListener.java 中96行的代碼,重新編譯運行,發現這個錯雖然沒了,但是又直接拋出了102行的異常。

這個異常沒有解決,沒想明白。

 

參考:http://blog.csdn.net/lzz957748332/article/category/6017279


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM