实现Radius+LDAP认证测试平台

时间:2022-03-10 14:27:12
1.       RADIUS 概述 (Introduction)

  RADIUS:Remote Authentication Dial In User Service ,远程用户拨号认证系统

  由 RFC2865 , RFC2866 定义,是目前应用最广泛的 AAA 协议。

   RADIUS 协议最初是由 Livingston 公司提出的,原先的目的是为拨号用户进行认证和计费。后来经过多次改进,形成了一项通用的认证计费协议。

  创立于 1966 年 Merit Network, Inc. 是密执安大学的一家非营利公司,其业务是运行维护该校的网络互联 MichNet 。 1987 年, Merit 在美国 NSF(国家科学基金会)的招标中胜出,赢得了 NSFnet (即 Internet 前身)的运营合同。因为 NSFnet 是基于 IP 的网络,而 MichNet 却基于专有网络协议, Merit 面对着如何将 MichNet 的专有网络协议演变为 IP 协议,同时也要把 MichNet 上的大量拨号业务以及其相关专有协议移植到 IP 网络上来。

   1991 年, Merit 决定招标拨号服务器供应商,几个月后,一家叫Livingston 的公司提出了建议,冠名为 RADIUS ,并为此获得了合同。

   1992 年秋天, IETF 的 NASREQ 工作组成立 , 随之提交了 RADIUS 作为草案。很快, RADIUS 成为事实上的网络接入标准,几乎所有的网络接入服务器厂商均实现了该协议。

   1997 年, RADIUS RFC2039 发表,随后是 RFC2138 ,最新的RADIUS RFC2865 发表于 2000 年 6 月。

   RADIUS 是一种 C/S 结构的协议,它的客户端最初就是 NAS ( Net Access Server )服务器,现在任何运行 RADIUS 客户端软件的计算机都可以成为 RADIUS 的客户端。 RADIUS 协议认证机制灵活,可以采用 PAP 、 CHAP 或者 Unix 登录认证等多种方式。 RADIUS 是一种可扩展的协议,它进行的全部工作都是基于 Attribute-Length-Value 的向量进行的。 RADIUS 也支持厂商扩充厂家专有属性。

   RADIUS 的基本工作原理。用户接入 NAS , NAS 向 RADIUS 服务器使用 Access-Require 数据包提交用户信息,包括用户名、密码等相关信息,其中用户密码是经过 MD5 加密的,双方使用共享密钥,这个密钥不经过网络传播; RADIUS 服务器对用户名和密码的合法性进行检验,必要时可以提出一个Challenge ,要求进一步对用户认证,也可以对 NAS 进行类似的认证;如果合法,给 NAS 返回 Access-Accept 数据包,允许用户进行下一步工作,否则返回 Access-Reject 数据包,拒绝用户访问;如果允许访问, NAS 向RADIUS 服务器提出计费请求 Account- Require , RADIUS 服务器响应Account-Accept ,对用户的计费开始,同时用户可以进行自己的相关操作。

   RADIUS 还支持代理和漫游功能。简单地说,代理就是一台服务器,可以作为其他 RADIUS 服务器的代理,负责转发 RADIUS 认证和计费数据包。所谓漫游功能,就是代理的一个具体实现,这样可以让用户通过本来和其无关的RADIUS 服务器进行认证,用户到非归属运营商所在地也可以得到服务,也可以实现虚拟运营。

   RADIUS 服务器和 NAS 服务器通过 UDP 协议进行通信, RADIUS 服务器的 1812 端口负责认证, 1813 端口负责计费工作。采用 UDP 的基本考虑是因为 NAS 和 RADIUS 服务器大多在同一个局域网中,使用 UDP 更加快捷方便。

   RADIUS 协议还规定了重传机制。如果 NAS 向某个 RADIUS 服务器提交请求没有收到返回信息,那么可以要求备份 RADIUS 服务器重传。由于有多个备份 RADIUS 服务器,因此 NAS 进行重传的时候,可以采用轮询的方法。如果备份 RADIUS 服务器的密钥和以前 RADIUS 服务器的密钥不同,则需要重新进行认证。  由于 RADIUS 协议简单明确,可扩充,因此得到了广泛应用,包括普通电话上网、 ADSL 上网、小区宽带上网、 IP 电话、 VPDN (Virtual Private Dialup Networks ,基于拨号用户的虚拟专用拨号网业务)、移动电话预付费等业务。最近 IEEE提出了 802.1x 标准,这是一种基于端口的标准,用于对无线网络的接入认证,在认证时也采用 RADIUS 协议。

2.       Radius 802.1X 无线认证模型

802.1x 简要概述 
这是一项通过验证来保护网络的端口访问协议。此类型的验证方法在无线环境中因该媒体的性质而特别有用。如果无线用户通过 802.1x 网络访问验证,接入点上会打开一个用于通信的虚拟端口。如果验证不成功,则不会提供虚拟端口,并将阻断通信。

802.1x 验证分为 3 个基本部分:

1.     请求者 - 在无线工作站上运行的软件客户端

2.     验证者 - 无线接入点

3.     认证服务器 - 一个认证数据库,通常是一个 Radius 服务器(例如 Cisco ACS* 、 Funk Steel-Belted RADIUS* 或 Microsoft* IAS* )

 

表 1 认证架构图

实现Radius+LDAP认证测试平台

表二 Radius 支持的无线认证类型

802.1x EAP 类型

功能/ 优点

MD5
---
信息摘要 5

TLS
---
传输层安全

TTLS
---
隧道传输层安全

PEAP
---
受保护的传输层安全

FAST
---
通过安全隧道灵活验证

LEAP
---
轻型可扩展认证协议

需要客户端证书


(PAC)

需要服务器证书


(PAC)

WEP 密钥管理

Rouge AP 检测

提供商

MS

MS

Funk

MS

Cisco

Cisco

验证属性

单向

相互

相互

相互

相互

相互

部署难易程度

容易

难(因为客户端证书配置的缘故)

一般

一般

一般

一般

无线安全

很高

在使用强密码时,高。

 

3.       Radius+LDAP 的安装与配置 3.1. 安装 LDAP

我使用的是 OpenLDAP-2.4.9, 解压后

[root@localhost ubuntu ] ./configure

      一般情况下,系统会提示你没有安装 berkeleyDB ,但就算你安装了,你一样会发现还是找不到( configure: error: BDB/HDB: BerkeleyDB not available ),使用如下方法解决

CPPFLAGS="-I/usr/local/BerkeleyDB.4.3/include"
export CPPFLAGS
LDFLAGS="-L/usr/local/BerkeleyDB.4.3/lib"
export LDFLAGS
LD_LIBRARY_PATH="/usr/local/BerkeleyDB.4.3/lib"
export LD_LIBRARY_PATH

[root@localhost ubuntu ] make

[root@localhost ubuntu ] make install

[root@localhost ubuntu ] make tes t ( 最好要做的,可以测试是否可以启动 ldap 服务,如提示无法启动,表明 389 端口被占用,重启机器就好了 )

启动服务:

[root@localhost ubuntu ] ./slapd –d 1 这里我推荐使用 log=1 的模式,log level=256 时很多输出就看不到了

3.2. 安装 Radius Server

     我使用的是 freeradius-server-2.0.4

     先安装 openssl

  #tar zxvf openssl-f-0.9.7-stable-SNAP-20040225.tar.gz
       #cd openssl-0.9.7-stable-SNAP-20040225
       #./config shared --prefix=/usr/local/openssl
       #make
       #make install

安装 FreeRadius
       #cd radiusd
    #./configure --prefix=/usr/local/newradius --with-openssl-includes=/usr/local/openssl/include \
             --with-openssl-libraries=/usr/local/openssl/lib 
      #make
      #make install

这里之所以要安装 openssl ,我们的目的是去产生证书,在raddb/certs 下,使用 make client.pem 之类的命令,如果需要修改证书配置,可以编辑 .cnf 文件, commonname=ly@example.com , 这样产生的证书就是 ly@example.com.pem

BTW:

der 和 cer 是一样的 , 都是一个证书 ,cer 是 windows 上用的 ,   
  pem 是一个证书请求 , 是的文本文件   
  p12 是一个个人证书 , 里面的包含私钥

  3.3 配置 LDAP

Edit slapd.conf 如下

#

# See slapd.conf(5) for details on configuration options.

# This file should NOT be world readable.

# 添加 schema 顺序最好不要变

include       /usr/local/etc/openldap/schema/core.schema

include       /usr/local/etc/openldap/schema/corba.schema

include       /usr/local/etc/openldap/schema/cosine.schema

include       /usr/local/etc/openldap/schema/inetorgperson.schema

include       /usr/local/etc/openldap/schema/misc.schema

include       /usr/local/etc/openldap/schema/openldap.schema

include       /usr/local/etc/openldap/schema/nis.schema

include         /usr/local/etc/openldap/schema/radius.schema

# Define global ACLs to disable default read access.

 

# Do not enable referrals until AFTER you have a working directory

# service AND an understanding of referrals.

#referral    ldap://root.openldap.org

 

pidfile        /usr/local/var/run/slapd.pid

argsfile  /usr/local/var/run/slapd.args

 

# Load dynamic backend modules:

# modulepath  %MODULEDIR%

# moduleload  back_bdb.la

# moduleload  back_hdb.la

# moduleload  back_ldap.la

 

# Sample security restrictions

# Require integrity protection (prevent hijacking)

# Require 112-bit (3DES or better) encryption for updates

# Require 63-bit encryption for simple bind

# security ssf=1 update_ssf=112 simple_bind=64

 

# Sample access control policy:

# Root DSE: allow anyone to read it

# Subschema (sub)entry DSE: allow anyone to read it

# Other DSEs:

#      Allow self write access

#      Allow authenticated users read access

#      Allow anonymous users to authenticate

# Directives needed to implement policy:

# access to dn.base="" by * read

# access to dn.base="cn=Subschema" by * read

# access to *

# by self write

# by users read

# by anonymous auth

  

# if no access controls are present, the default policy

# allows anyone and everyone to read anything but restricts

# updates to rootdn.  (e.g., "access to * by * read")

#

# rootdn can always read and write EVERYTHING!

 

#######################################################################

# BDB database definitions

#######################################################################

 

database    bdb

#你的 ldap 的根节点,在添加搜索时都会用到

suffix          "dc=teddy,dc=net"

rootdn          "cn=master,dc=teddy,dc=net"

# Cleartext passwords, especially for the rootdn, should

# be avoid.  See slappasswd(8) and slapd.conf(5) for details.

# Use of strong authentication encouraged.

#连接密码

rootpw      secret

# The database directory MUST exist prior to running slapd AND

# should only be accessible by the slapd and slap tools.

# Mode 700 recommended.

directory    /usr/local/var/openldap-data

# Indices to maintain

index    objectClass  eq

 

下面我们将开始往 LDAP 上添加结点

生成一个 test1.ldif

dn: cn=master,dc=teddy,dc=net

objectClass: organizationalRole

cn=master

生成一个 test2.ldif 

dn: uid=radiususer,cn=master,dc=teddy,dc=net

uid:radiususer

cn:radiususer

objectClass:top

#objectClass: dcObject

objectClass: account

objectClass:posixAccount

userPassword:test

uidNumber:10072

gidNumber:10002

homeDirectory:/home/radiususer

loginShell:/bin/shell

cn:master

 

执行命令:

Ldapadd –x –D “cn=master,dc=teddy,dc=net” –w –f test1(2).ldif

此时要确保 ldap 的服务是启动状态的

这时你会得到要求输入密码的要求 , 输入 rootdn 的密码,添加成功

使用

Ldapsearch –x –b ‘dc=terry,dc=net’ 去验证

3.4 配置 FreeRadius

 

3.4.1 编辑 eap.conf

        tls {

            #证书部分要看实际情况,测试时可使用刚才生成的证书

            #

            #  These is used to simplify later configurations.

            #

            certdir = ${confdir}/certs

            cadir = ${confdir}/certs

 

            private_key_password = whatever

            private_key_file = ${certdir}/server.pem

 

            #  If Private key & Certificate are located in

            #  the same file, then private_key_file &

            #  certificate_file must contain the same file

            #  name.

            #

            #  If CA_file (below) is not used, then the

             #  certificate_file below MUST include not

            #  only the server certificate, but ALSO all

            #  of the CA certificates used to sign the

            #  server certificate.

            certificate_file = ${certdir}/server.pem

 

            #  Trusted Root CA list

            #

            #  ALL of the CA's in this list will be trusted

            #  to issue client certificates for authentication.

            #

            #  In general, you should use self-signed

            #  certificates for 802.1x (EAP) authentication.

            #  In that case, this CA file should contain

            #  *one* CA certificate.

            #

            #  This parameter is used only for EAP-TLS,

            #  when you issue client certificates.  If you do

            #  not use client certificates, and you do not want

            #  to permit EAP-TLS authentication, then delete

            #  this configuration item.

            CA_file = ${cadir}/ca.pem

 

            #

            #  For DH cipher suites to work, you have to

            #  run OpenSSL to create the DH file first:

            #

            #      openssl dhparam -out certs/dh 1024

            #

            dh_file = ${certdir}/dh

            random_file = ${certdir}/random

 

            #

            #  This can never exceed the size of a RADIUS

            #  packet (4096 bytes), and is preferably half

            #  that, to accomodate other attributes in

            #  RADIUS packet.  On most APs the MAX packet

            #  length is configured between 1500 - 1600

            #  In these cases, fragment size should be

            #  1024 or less.

            #

        #   fragment_size = 1024

 

            #  include_length is a flag which is

            #  by default set to yes If set to

            #  yes, Total Length of the message is

            #  included in EVERY packet we send.

            #  If set to no, Total Length of the

            #  message is included ONLY in the

            #  First packet of a fragment series.

            #

        #   include_length = yes

 

            #  Check the Certificate Revocation List

            #

            #  1) Copy CA certificates and CRLs to same directory.

            #  2) Execute 'c_rehash <CA certs&CRLs Directory>'.

            #    'c_rehash' is OpenSSL's command.

            #  3) uncomment the line below.

            #  5) Restart radiusd

        #   check_crl = yes

        #   CA_path = /path/to/directory/with/ca_certs/and/crls/

 

               #

               #  If check_cert_issuer is set, the value will

               #  be checked against the DN of the issuer in

               #  the client certificate.  If the values do not

               #  match, the cerficate verification will fail,

               #  rejecting the user.

               #

        #       check_cert_issuer = "/C=GB/ST=Berkshire/L=Newbury/O=My Company Ltd"

 

               #

               #  If check_cert_cn is set, the value will

               #  be xlat'ed and checked against the CN

               #  in the client certificate.  If the values

               #  do not match, the certificate verification

               #  will fail rejecting the user.

               #

               #  This check is done only if the previous

               #  "check_cert_issuer" is not set, or if

               #  the check succeeds.

               #

        #   check_cert_cn = %{User-Name}

        #

            # Set this option to specify the allowed

            # TLS cipher suites.  The format is listed

            # in "man 1 ciphers".

            cipher_list = "DEFAULT"

 

            #

 

            #  This configuration entry should be deleted

            #  once the server is running in a normal

            #  configuration.  It is here ONLY to make

            #  initial deployments easier.

            #

            make_cert_command = "${certdir}/bootstrap"

        }

 

  

        ttls {

            default_eap_type = md5

 

       

            copy_request_to_tunnel = no

 

       

            # allowed values: {no, yes}

             use_tunneled_reply = no

 

       

            virtual_server = "inner-tunnel"

        }

 

        ##################################################

        #

  

        peap {

            #  The tunneled EAP session needs a default

            #  EAP type which is separate from the one for

            #  the non-tunneled EAP module.  Inside of the

            #  PEAP tunnel, we recommend using MS-CHAPv2,

            #  as that is the default type supported by

            #  Windows clients.

            default_eap_type = mschapv2

 

            #  the PEAP module also has these configuration

            #  items, which are the same as for TTLS.

            copy_request_to_tunnel = no

            use_tunneled_reply = no

 

            #  When the tunneled session is proxied, the

            #  home server may not understand EAP-MSCHAP-V2.

            #  Set this entry to "no" to proxy the tunneled

            #  EAP-MSCHAP-V2 as normal MSCHAPv2.

        #   proxy_tunneled_request_as_eap = yes

 

            #

            #  The inner tunneled request can be sent

            #  through a virtual server constructed

            #  specifically for this purpose.

            #

            #  If this entry is commented out, the inner

            #  tunneled request will be sent through

            #  the virtual server that processed the

            #  outer requests.

            #

            virtual_server = "inner-tunnel"

        }

 

  

        mschapv2 {

        }

   }

 

3.4.2 编辑 radiusd.conf

这里我只说 ldap 的配置

ldap {

        #

        #  Note that this needs to match the name in the LDAP

        #  server certificate, if you're using ldaps.

        #LDAP 服务器的地址

        server = "127.0.0.1"

       # login LDAP 时所使用的 account

        identity="cn=master,dc=teddy,dc=net

# 密码 "      

        password = "secret"       

  

        basedn = "dc=teddy,dc=net"    

        filter = "(uid=%{Stripped-User-Name:-%{User-Name}})"

        #属性

access_attr="uid"

        password_attribute=userPassword

        #  How many connections to keep open to the LDAP server.

        #  This saves time over opening a new LDAP socket for

        #  every authentication request.

        ldap_connections_number = 5

 

        # seconds to wait for LDAP query to finish. default: 20

        timeout = 4

 

        #  seconds LDAP server has to process the query (server-side

        #  time limit). default: 20

        #

        #  LDAP_OPT_TIMELIMIT is set to this value.

        timelimit = 3

 

        #

        #  seconds to wait for response of the server. (network

        #   failures) default: 10

        #

        #  LDAP_OPT_NETWORK_TIMEOUT is set to this value.

        net_timeout = 1

 

        #

        #  This subsection configures the tls related items

        #  that control how FreeRADIUS connects to an LDAP

        #  server.  It contains all of the "tls_*" configuration

        #  entries used in older versions of FreeRADIUS.  Those

        #  configuration entries can still be used, but we recommend

        #  using these.

        #

        tls {

            # Set this to 'yes' to use TLS encrypted connections

            # to the LDAP database by using the StartTLS extended

            # operation.

            #           

            # The StartTLS operation is supposed to be

            # used with normal ldap connections instead of

            # using ldaps (port 689) connections

           

            start_tls = no

 

            # cacertfile   = /path/to/cacert.pem

            # cacertdir        = /path/to/ca/dir/

            # certfile      = /path/to/radius.crt

            # keyfile      = /path/to/radius.key

            # randfile         = /path/to/rnd

 

            #  Certificate Verification requirements.  Can be:

            #    "never" (don't even bother trying)

            #    "allow" (try, but don't fail if the cerificate

            #        can't be verified)

            #    "demand" (fail if the certificate doesn't verify.)

            #

            #   The default is "allow"

            # require_cert   = "demand"

        }

 

        # default_profile = "cn=radprofile,ou=dialup,o=My Org,c=UA"

        # profile_attribute = "radiusProfileDn"

        # access_attr = "dialupAccess"

 

        # Mapping of RADIUS dictionary attributes to LDAP

        # directory attributes.

        dictionary_mapping = ${confdir}/ldap.attrmap

 

        #  Set password_attribute = nspmPassword to get the

        #  user's password from a Novell eDirectory

        #  backend. This will work ONLY IF FreeRADIUS has been

        #  built with the --with-edir configure option.

        #

        #  See also the following links:

        #

        #  http://www.novell.com/coolsolutions/appnote/16745.html

        #  https://secure-support.novell.com/KanisaPlatform/Publishing/558/3009668_f.SAL_Public.html

        #

        #  Novell may require TLS encrypted sessions before returning

        #  the user's password.

        #

        # password_attribute = userPassword

 

        #  Un-comment the following to disable Novell

        #  eDirectory account policy check and intruder

        #  detection. This will work *only if* FreeRADIUS is

        #  configured to build with --with-edir option.

        #

        edir_account_policy_check = no

 

        #

        #  Group membership checking.  Disabled by default.

        #

        # groupname_attribute = cn

        # groupmembership_filter = "(|(&(objectClass=GroupOfNames)(member=%{Ldap-UserDn}))(&(objectClass=GroupOfUniqueNames)(uniquemember=%{Ldap-UserDn})))"

        # groupmembership_attribute = radiusGroupName

 

        # compare_check_items = yes

        # do_xlat = yes

        # access_attr_used_for_allow = yes

 

        #

        #  By default, if the packet contains a User-Password,

        #  and no other module is configured to handle the

        #  authentication, the LDAP module sets itself to do

        #  LDAP bind for authentication.

        #

        #  THIS WILL ONLY WORK FOR PAP AUTHENTICATION.

        #

        #  THIS WILL NOT WORK FOR CHAP, MS-CHAP, or 802.1x (EAP).

        #

        #  You can disable this behavior by setting the following

        #  configuration entry to "no".

        #

        #  allowed values: {no, yes}

        # set_auth_type = yes

 

        #  ldap_debug: debug flag for LDAP SDK

        #  (see OpenLDAP documentation).  Set this to enable

        #  huge amounts of LDAP debugging on the screen.

        #  You should only use this if you are an LDAP expert.

        #

        #   default: 0x0000 (no debugging messages)

        #   Example:(LDAP_DEBUG_FILTER+LDAP_DEBUG_CONNS)

        ldap_debug = 0x0028

   }

3.4.3 编辑 client.conf

增加

   Client ‘IP address’{

   Secret=test

   Shortname=test802.1

}

Ok, 重新启动 radius

#radius –X –f

4.       测试

   [ root@ubuntu:~ ] # radtest radiususer test (ldap user)10.190.41.78 0 test(radius password)

        User-Name = "radiususer"

        User-Password = "test"

        NAS-IP-Address = 127.0.1.1

        NAS-Port = 0

成功你会看到

http://blog.csdn.net/yoki2009/archive/2009/05/27/4221430.aspx