抱歉,我只能使用 freeradius 来访问 LDAP

抱歉,我只能使用 freeradius 来访问 LDAP

好吧,我对 FreeRadus 有点困惑。

我想我已经找到问题所在了,但我不知道为什么,如果我尝试通过 wifi 进行身份验证,它似乎没有获取到密码,下面就是它的调试

Ready to process requests
(0) Received Access-Request Id 149 from 192.168.200.238:49881 to 192.168.20.2:1812 length 227
(0)   User-Name = "testing"
(0)   NAS-IP-Address = 192.168.200.238
(0)   NAS-Identifier = "d221f94b63df"
(0)   Called-Station-Id = "D2-21-F9-4B-63-DF:test no join"
(0)   NAS-Port-Type = Wireless-802.11
(0)   Service-Type = Framed-User
(0)   Calling-Station-Id = "D2-5A-22-F3-F6-A1"
(0)   Connect-Info = "CONNECT 0Mbps 802.11a"
(0)   Acct-Session-Id = "08DE2818B2804F38"
(0)   Acct-Multi-Session-Id = "47EF77EBC7B5BF7A"
(0)   WLAN-Pairwise-Cipher = 1027076
(0)   WLAN-Group-Cipher = 1027076
(0)   WLAN-AKM-Suite = 1027073
(0)   Framed-MTU = 1400
(0)   EAP-Message = 0x02bd000c0174657374696e67
(0)   Message-Authenticator = 0xcef6985af177d3099edb44dbcfaba6e7
(0) # Executing section authorize from file /etc/freeradius/3.0/sites-enabled/my_server
(0)   authorize {
rlm_ldap (ldap): Reserved connection (0)
(0) ldap: EXPAND (cn=%{%{Stripped-User-Name}:-%{User-Name}})
(0) ldap:    --> (cn=testing)
(0) ldap: Performing search in "ou=users,dc=ldap,DC=alexosaurous,DC=co,DC=nz" with filter "(cn=testing)", scope "sub"
(0) ldap: Waiting for search result...
(0) ldap: User object found at DN "cn=testing,ou=users,dc=ldap,dc=alexosaurous,dc=co,dc=nz"
(0) ldap: Processing user attributes
(0) ldap: WARNING: No "known good" password added. Ensure the admin user has permission to read the password attribute
(0) ldap: WARNING: PAP authentication will *NOT* work with Active Directory (if that is what you were trying to configure)
rlm_ldap (ldap): Released connection (0)
(0)     [ldap] = ok
(0)     if ((ok || updated) && User-Password) {
(0)     if ((ok || updated) && User-Password)  -> FALSE
(0)   } # authorize = ok
(0) ERROR: No Auth-Type found: rejecting the user via Post-Auth-Type = Reject
(0) Failed to authenticate the user
(0) Using Post-Auth-Type Reject
(0) Post-Auth-Type sub-section not found.  Ignoring.
(0) Delaying response for 1.000000 seconds
Waking up in 0.3 seconds.
Waking up in 0.6 seconds.
(0) Sending delayed response
(0) Sent Access-Reject Id 149 from 192.168.20.2:1812 to 192.168.200.238:49881 length 20
Waking up in 3.9 seconds.
(0) Cleaning up request packet ID 149 with timestamp +10 due to cleanup_delay was reached

正如你所看到的,除非我遗漏了某些东西,否则其中没有密码,但当我进行 radtest 时,我通过这种方式在调试日志下方得到了 accept-accept

radtest testing test localhost 2 testing123                                                                           root@docker-host
Sent Access-Request Id 76 from 0.0.0.0:39308 to 127.0.0.1:1812 length 77
    User-Name = "testing"
    User-Password = "test"
    NAS-IP-Address = 127.0.1.1
    NAS-Port = 2
    Message-Authenticator = 0x00
    Cleartext-Password = "test"
Received Access-Accept Id 76 from 127.0.0.1:1812 to 127.0.0.1:39308 length 20


Ready to process requests
q(1) Received Access-Request Id 163 from 127.0.0.1:53905 to 127.0.0.1:1812 length 77
(1)   User-Name = "testing"
(1)   User-Password = "test"
(1)   NAS-IP-Address = 127.0.1.1
(1)   NAS-Port = 2
(1)   Message-Authenticator = 0xfade5a334cefa11b8d1c07ea3ca02fae
(1) # Executing section authorize from file /etc/freeradius/3.0/sites-enabled/my_server
(1)   authorize {
rlm_ldap (ldap): Reserved connection (1)
(1) ldap: EXPAND (cn=%{%{Stripped-User-Name}:-%{User-Name}})
(1) ldap:    --> (cn=testing)
(1) ldap: Performing search in "ou=users,dc=ldap,DC=alexosaurous,DC=co,DC=nz" with filter "(cn=testing)", scope "sub"
(1) ldap: Waiting for search result...
(1) ldap: User object found at DN "cn=testing,ou=users,dc=ldap,dc=alexosaurous,dc=co,dc=nz"
(1) ldap: Processing user attributes
(1) ldap: WARNING: No "known good" password added. Ensure the admin user has permission to read the password attribute
(1) ldap: WARNING: PAP authentication will *NOT* work with Active Directory (if that is what you were trying to configure)
rlm_ldap (ldap): Released connection (1)
rlm_ldap (ldap): Closing connection (2) - Too many unused connections.
rlm_ldap (ldap): You probably need to lower "min"
rlm_ldap (ldap): Closing expired connection (4) - Hit idle_timeout limit
rlm_ldap (ldap): You probably need to lower "min"
rlm_ldap (ldap): Closing expired connection (3) - Hit idle_timeout limit
(1)     [ldap] = ok
(1)     if ((ok || updated) && User-Password) {
(1)     if ((ok || updated) && User-Password)  -> TRUE
(1)     if ((ok || updated) && User-Password)  {
(1)       update {
(1)         control:Auth-Type := LDAP
(1)       } # update = noop
(1)     } # if ((ok || updated) && User-Password)  = noop
(1)   } # authorize = ok
(1) Found Auth-Type = LDAP
(1) # Executing group from file /etc/freeradius/3.0/sites-enabled/my_server
(1)   Auth-Type LDAP {
rlm_ldap (ldap): Reserved connection (0)
(1) ldap: Login attempt by "testing"
(1) ldap: Using user DN from request "cn=testing,ou=users,dc=ldap,dc=alexosaurous,dc=co,dc=nz"
(1) ldap: Waiting for bind result...
(1) ldap: Bind successful
(1) ldap: Bind as user "cn=testing,ou=users,dc=ldap,dc=alexosaurous,dc=co,dc=nz" was successful
rlm_ldap (ldap): Released connection (0)
(1)     [ldap] = ok
(1)   } # Auth-Type LDAP = ok
(1) Sent Access-Accept Id 163 from 127.0.0.1:1812 to 127.0.0.1:53905 length 20
(1) Finished request
Waking up in 4.9 seconds.
(1) Cleaning up request packet ID 163 with timestamp +67 due to cleanup_delay was reached
Ready to process requests
(2) Received Access-Request Id 210 from 127.0.0.1:49536 to 127.0.0.1:1812 length 77
Dropping packet without response because of error: Received packet from 127.0.0.1 with invalid Message-Authenticator!  (Shared secret is incorrect.)
Waking up in 0.3 seconds.
(2) Cleaning up request packet ID 210 with timestamp +109 due to done
Ready to process requests

在该请求中,它似乎获得了密码并将其放入 LDAP,然后验证了用户名和密码

我很困惑为什么手机通过 wifi 不发送密码

配置如下

已启用站点

server my_server {
listen {
        type = auth
        ipaddr = *
        port = 1812
}
authorize {
        ldap
        if ((ok || updated) && User-Password) {
        update {
        control:Auth-Type := ldap
          }
        }
        
}
authenticate {
        Auth-Type LDAP {
                ldap
        }
}
}

LDAP 配置

# -*- text -*-
#
#  $Id: 1f0ee0383834684c7314a89be40003933023c401 $

#
#  Lightweight Directory Access Protocol (LDAP)
#
ldap {
    #  Note that this needs to match the name(s) in the LDAP server
    #  certificate, if you're using ldaps.  See OpenLDAP documentation
    #  for the behavioral semantics of specifying more than one host.
    server = "auth.domain"

    #  Port to connect on, defaults to 389. Setting this to 636 will enable
    #  LDAPS if start_tls (see below) is not able to be used.
    port = "389"

    #  Administrator account for searching and possibly modifying.
    identity = "cn=myserviceaccount,dc=domain"
    password = ""

    #  Unless overridden in another section, the dn from which all
    #  searches will start from.
    base_dn = "dc=ldap,dc=alexosaurous,dc=co,dc=nz"

    #
    #  Generic valuepair attribute
    #

    #  If set, this will attribute will be retrieved in addition to any
    #  mapped attributes.
    #
    #  Values should be in the format:
    #   <radius attr> <op> <value>
    #
    #  Where:
    #   <radius attr>:  Is the attribute you wish to create
    #           with any valid list and request qualifiers.
    #   <op>:       Is any assignment attribute (=, :=, +=, -=).
    #   <value>:    Is the value to parse into the new valuepair.
    #           If the attribute name is wrapped in double
    #           quotes it will be xlat expanded.
#   valuepair_attribute = "radiusAttribute"

    #
    #  Mapping of LDAP directory attributes to RADIUS dictionary attributes.
    #

    #  WARNING: Although this format is almost identical to the unlang
    #  update section format, it does *NOT* mean that you can use other
    #  unlang constructs in module configuration files.
    #
    #  Configuration items are in the format:
    #   <radius attr> <op> <ldap attr>
    #
    #  Where:
    #   <radius attr>:  Is the destination RADIUS attribute
    #           with any valid list and request qualifiers.
    #   <op>:       Is any assignment attribute (=, :=, +=, -=).
    #   <ldap attr>:    Is the attribute associated with user or
    #           profile objects in the LDAP directory.
    #           If the attribute name is wrapped in double
    #           quotes it will be xlat expanded.
    #
    #  Request and list qualifiers may also be placed after the 'update'
    #  section name to set defaults destination requests/lists
    #  for unqualified RADIUS attributes.
    #
    #  Note: LDAP attribute names should be single quoted unless you want
    #  the name value to be derived from an xlat expansion, or an
    #  attribute ref.
    update {
        control:Password-With-Header    += 'userPassword'
#       control:NT-Password     := 'ntPassword'
#       reply:Reply-Message     := 'radiusReplyMessage'
#       reply:Tunnel-Type       := 'radiusTunnelType'
#       reply:Tunnel-Medium-Type    := 'radiusTunnelMediumType'
#       reply:Tunnel-Private-Group-ID   := 'radiusTunnelPrivategroupId'

        #  These are provided for backwards compatibility.
        #  Where only a list is specified as the RADIUS attribute,
        #  the value of the LDAP attribute is parsed as a valuepair
        #  in the same format as the 'valuepair_attribute' (above).
#       control:            += 'radiusCheckAttributes'
#       reply:              += 'radiusReplyAttributes'
    }

    #  Set to yes if you have eDirectory and want to use the universal
    #  password mechanism.
#   edir = no

    #  Set to yes if you want to bind as the user after retrieving the
    #  Cleartext-Password. This will consume the login grace, and
    #  verify user authorization.
#   edir_autz = no

    #  Note: set_auth_type was removed in v3.x.x
    #  Equivalent functionality can be achieved by adding the following
    #  stanza to the authorize {} section of your virtual server.
    #
    #    ldap
    #    if ((ok || updated) && User-Password) {
    #        update {
    #            control:Auth-Type := ldap
    #        }
    #    }

    #
    #  User object identification.
    #
    user {
        #  Where to start searching in the tree for users
        base_dn = "ou=users,dc=ldap,DC=alexosaurous,DC=co,DC=nz"

        #  Filter for user objects, should be specific enough
        #  to identify a single user object.
        filter = "(cn=%{%{Stripped-User-Name}:-%{User-Name}})"

        #  Search scope, may be 'base', 'one', sub' or 'children'
#       scope = 'sub'

        #  If this is undefined, anyone is authorised.
        #  If it is defined, the contents of this attribute
        #  determine whether or not the user is authorised
#       access_attribute = "dialupAccess"

        #  Control whether the presence of "access_attribute"
        #  allows access, or denys access.
        #
        #  If "yes", and the access_attribute is present, or
        #  "no" and the access_attribute is absent then access
        #  will be allowed.
        #
        #  If "yes", and the access_attribute is absent, or
        #  "no" and the access_attribute is present, then
        #  access will not be allowed.
        #
        #  If the value of the access_attribute is "false", it
        #  will negate the result.
        #
        #  e.g.
        #    access_positive = yes
        #    access_attribute = userAccessAllowed
        #
        #    userAccessAllowed = false
        #
        #  Will result in the user being locked out.
#       access_positive = yes
    }

    #
    #  User membership checking.
    #
    group {
        #  Where to start searching in the tree for groups
        base_dn = "ou=Groups,dc=ldap,DC=alexosaurous,DC=co,DC=nz"

        #  Filter for group objects, should match all available
        #  group objects a user might be a member of.
        filter = "(objectClass=posixGroup)"

        # Search scope, may be 'base', 'one', sub' or 'children'
#       scope = 'sub'

        #  Attribute that uniquely identifies a group.
        #  Is used when converting group DNs to group
        #  names.
        name_attribute = cn

        #  Filter to find group objects a user is a member of.
        #  That is, group objects with attributes that
        #  identify members (the inverse of membership_attribute).
        membership_filter = "(|(member=%{control:Ldap-UserDn})(memberUid=%{%{Stripped-User-Name}:-%{User-Name}}))"

        #  The attribute in user objects which contain the names
        #  or DNs of groups a user is a member of.
        #
        #  Unless a conversion between group name and group DN is
        #  needed, there's no requirement for the group objects
        #  referenced to actually exist.
#       membership_attribute = "memberOf"

        #  If cacheable_name or cacheable_dn are enabled,
        #  all group information for the user will be
        #  retrieved from the directory and written to LDAP-Group
        #  attributes appropriate for the instance of rlm_ldap.
        #
        #  For group comparisons these attributes will be checked
        #  instead of querying the LDAP directory directly.
        #
        #  This feature is intended to be used with rlm_cache.
        #
        #  If you wish to use this feature, you should enable
        #  the type that matches the format of your check items
        #  i.e. if your groups are specified as DNs then enable
        #  cacheable_dn else enable cacheable_name.
#       cacheable_name = "no"
#       cacheable_dn = "no"

        #  Override the normal cache attribute (<inst>-LDAP-Group)
        #  and create a custom attribute.  This can help if multiple
        #  module instances are used in fail-over.
#       cache_attribute = "LDAP-Cached-Membership"
    }

    #
    #  User profiles. RADIUS profile objects contain sets of attributes
    #  to insert into the request. These attributes are mapped using
    #  the same mapping scheme applied to user objects.
    #
    profile {
        #  Filter for RADIUS profile objects
#       filter = "(objectclass=radiusprofile)"

        #  The default profile applied to all users.
#       default = "cn=radprofile,dc=example,dc=org"

        #  The list of profiles which are applied (after the default)
        #  to all users.
        #  The "User-Profile" attribute in the control list
        #  will override this setting at run-time.
#       attribute = "radiusProfileDn"
    }

    #
    #  Bulk load clients from the directory
    #
    client {
        #   Where to start searching in the tree for clients
        base_dn = "ou=Clients,dc=example,dc=com"

        #
        #  Filter to match client objects
        #
        filter = '(objectClass=frClient)'

        # Search scope, may be 'base', 'one', 'sub' or 'children'
#       scope = 'sub'

        #
        #  Client attribute mappings are in the format:
        #      <client attribute> = <ldap attribute>
        #
        #  Arbitrary attributes (accessible by %{client:<attr>}) are not yet supported.
        #
        #  The following attributes are required:
        #    * identifier - IPv4 address, or IPv4 address with prefix, or hostname.
        #    * secret - RADIUS shared secret.
        #
        #  The following attributes are optional:
        #    * shortname - Friendly name associated with the client
        #    * nas_type - NAS Type
        #    * virtual_server - Virtual server to associate the client with
        #    * require_message_authenticator - Whether we require the Message-Authenticator
        #      attribute to be present in requests from the client.
        #
        #  Schemas are available in doc/schemas/ldap for openldap and eDirectory
        #
        attribute {
            identifier          = 'radiusClientIdentifier'
            secret              = 'radiusClientSecret'
#           shortname           = 'radiusClientShortname'
#           nas_type            = 'radiusClientType'
#           virtual_server          = 'radiusClientVirtualServer'
#           require_message_authenticator   = 'radiusClientRequireMa'
        }
    }

    #  Load clients on startup
#   read_clients = no

    #
    #  Modify user object on receiving Accounting-Request
    #

    #  Useful for recording things like the last time the user logged
    #  in, or the Acct-Session-ID for CoA/DM.
    #
    #  LDAP modification items are in the format:
    #   <ldap attr> <op> <value>
    #
    #  Where:
    #   <ldap attr>:    The LDAP attribute to add modify or delete.
    #   <op>:       One of the assignment operators:
    #           (:=, +=, -=, ++).
    #           Note: '=' is *not* supported.
    #   <value>:    The value to add modify or delete.
    #
    #  WARNING: If using the ':=' operator with a multi-valued LDAP
    #  attribute, all instances of the attribute will be removed and
    #  replaced with a single attribute.
    accounting {
        reference = "%{tolower:type.%{Acct-Status-Type}}"

        type {
            start {
                update {
                    description := "Online at %S"
                }
            }

            interim-update {
                update {
                    description := "Last seen at %S"
                }
            }

            stop {
                update {
                    description := "Offline at %S"
                }
            }
        }
    }

    #
    #  Post-Auth can modify LDAP objects too
    #
    post-auth {
        update {
            description := "Authenticated at %S"
        }
    }

    #
    #  LDAP connection-specific options.
    #
    #  These options set timeouts, keep-alives, etc. for the connections.
    #
    options {
        #  Control under which situations aliases are followed.
        #  May be one of 'never', 'searching', 'finding' or 'always'
        #  default: libldap's default which is usually 'never'.
        #
        #  LDAP_OPT_DEREF is set to this value.
#       dereference = 'always'

        #
        #  The following two configuration items control whether the
        #  server follows references returned by LDAP directory.
        #  They are  mostly for Active Directory compatibility.
        #  If you set these to "no", then searches will likely return
        #  "operations error", instead of a useful result.
        #
        chase_referrals = yes
        rebind = yes

        #  Seconds to wait for LDAP query to finish. default: 20
        timeout = 10

        #  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

        #  LDAP_OPT_X_KEEPALIVE_IDLE
        idle = 60

        #  LDAP_OPT_X_KEEPALIVE_PROBES
        probes = 3

        #  LDAP_OPT_X_KEEPALIVE_INTERVAL
        interval = 3

        #  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
    }

    #
    #  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 636) connections
        start_tls = no

#       ca_file = ${certdir}/cacert.pem

#       ca_path = ${certdir}
#       certificate_file = /path/to/radius.crt
#       private_key_file = /path/to/radius.key
#       random_file = ${certdir}/random

        #  Certificate Verification requirements.  Can be:
        #    "never" (don't even bother trying)
        #    "allow" (try, but don't fail if the certificate
        #       can't be verified)
        #    "demand" (fail if the certificate doesn't verify.)
        #
        #  The default is "allow"
#       require_cert    = "demand"
    }


    #  As of version 3.0, the "pool" section has replaced the
    #  following configuration items:
    #
    #  ldap_connections_number

    #  The connection pool is new for 3.0, and will be used in many
    #  modules, for all kinds of connection-related activity.
    #
    #  When the server is not threaded, the connection pool
    #  limits are ignored, and only one connection is used.
    pool {
        #  Number of connections to start
        start = 5

        #  Minimum number of connections to keep open
        min = 4

        #  Maximum number of connections
        #
        #  If these connections are all in use and a new one
        #  is requested, the request will NOT get a connection.
        #
        #  Setting 'max' to LESS than the number of threads means
        #  that some threads may starve, and you will see errors
        #  like "No connections available and at max connection limit"
        #
        #  Setting 'max' to MORE than the number of threads means
        #  that there are more connections than necessary.
        max = ${thread[pool].max_servers}

        #  Spare connections to be left idle
        #
        #  NOTE: Idle connections WILL be closed if "idle_timeout"
        #  is set.
        spare = 3

        #  Number of uses before the connection is closed
        #
        #  0 means "infinite"
        uses = 0

        #  The lifetime (in seconds) of the connection
        lifetime = 0

        #  Idle timeout (in seconds).  A connection which is
        #  unused for this length of time will be closed.
        idle_timeout = 60

        #  NOTE: All configuration settings are enforced.  If a
        #  connection is closed because of "idle_timeout",
        #  "uses", or "lifetime", then the total number of
        #  connections MAY fall below "min".  When that
        #  happens, it will open a new connection.  It will
        #  also log a WARNING message.
        #
        #  The solution is to either lower the "min" connections,
        #  or increase lifetime/idle_timeout.
    }
}

附注:我的用户过滤器有点不同,因为我使用了 authentik LDAP outpost,并且按照 https://goauthentik.io/docs/providers/ldap

用户名映射到 cn

顺便说一句,谢谢你花时间阅读这一切

相关内容