Make FreeRADIUS talk to FreeIPA / RHEL IDM

This was a challenge. So it turns out FreeIPA talks ldap out of the box. I wanted to authenticate against FreeIPA using FreeRADIUS. I am thankful to Arran Cudbard-Bell which helped me figure out some of these things in the (very active) FreeRADIUS mailing list.

This will not be a nice step by step post, just some hints to ‘get you there’.

First, you need a working FreeIPA server which responds to your LDAP queries. This can be tested:

ldapsearch -x -v -W -D 'cn=Directory Manager'  uid=testuser

on the box itself. You will probably get some results back. Note the base dn’s. This is going to be important. When configuring FreeRADIUS, I first used the base DN dc=companyname,dc=local. This resulted in FreeIPA giving back two results, the first not having a userPassword attribute. I then started using cn=users,cn=accounts,dc=companyname,dc=local which helped. This will come back later.

Okay, so you have verified you have a working LDAP server. Now let’s install freeradius.

yum install freeradius-ldap freeradius-utils

Of course make sure your ntp/chrony/time is ok.

freeradius-utils gives you radtest which will allow you to test radius login later:

radtest testuser testpassword machine 1812 secret123

Now FreeRADIUS has to be configured. I write this guide after the fact so I hope I include everything. Here it goes. Base dir for the folling stuff is /etc/raddb.

Edit sites-enabled/default, uncomment the ldap stuff. Check if listen stuff is OK.

Edit mods-enabled/ldap. Add your server host name, do not change the port, edit the identity, password and base DN. My config:

ldap {
  #
  #  Note that this needs to match the name in the LDAP
  #  server certificate, if you're using ldaps.
  #
  #  The ldap client libraries can do fail-over from one
  #  server to another.  Enable this by specifying
  #  multiple host names, separated by commas.
  #
  # e.g. server = "ldap1.example.org,ldap2.example.org"
  #
  #  Otherwise, it will use just one server.
  server = "auth1.company.local"

  #  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=Directory Manager"
  password = secret

  #  Unless overridden in another section, the dn from which all
  #  searches will start from.
# base_dn = "dc=example,dc=org"
  #base_dn = "dc=company,dc=domain"
  base_dn = "cn=users,cn=accounts,dc=company,dc=domain"

  #
  #  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:
  #     
  #
  #  Where:
  #   :  Is the destination RADIUS attribute
  #       with any valid list and request qualifiers.
  #   :     Is any assignment attribute (=, :=, +=, -=).
  #   :  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: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'

}

I did not change the rest I think. Then finally there is clients.conf:

At the bottom I added/changed two entries:


# AUTH
client localhost {
  ipaddr = 10.0.64.213
  proto = *
  #netmask = 32
  secret = secret123
  require_message_authenticator = no
  shortname = auth2
  nas_type   = other
  limit {
    max_connections = 16
    lifetime = 0
    idle_timeout = 30
  }
}

# WIKI
client localhost {
  ipaddr = 10.0.64.225
  proto = *
  netmask = 32
  secret = secret456
  require_message_authenticator = no
  shortname = orion
  nas_type   = other
  limit {
    max_connections = 16
    lifetime = 0
    idle_timeout = 30
  }
}

Now start the things (systemctl enable , start) and test with the previously given radtest command. Be happy if it works ;).