MSCHAPV2 for PP2P VPN

Leo Giusti ttdhead at gmail.com
Wed Jan 10 03:01:01 UTC 2024


Hi,

I am trying to get MSCHAPV2 working for a VPN. I am running FreeRADIUS
3.2.1 on Debian.

I am able to authenticate against my domain with ntlm_auth with a username
and password.

My /etc/freeradius/3.0/mods-available/mschap is:
# -*- text -*-
#
#  $Id: 1748d5747f5b2fda08a017ad3095d9b96b0c2ee0 $

#
#  Microsoft CHAP authentication
#
#  This module supports MS-CHAP and MS-CHAPv2 authentication.
#  It also enforces the SMB-Account-Ctrl attribute.
#
mschap {
        #
        #  If you are using /etc/smbpasswd, see the 'passwd'
        #  module for an example of how to use /etc/smbpasswd
        #

        #
        #  If use_mppe is not set to no mschap, will
        #  add MS-CHAP-MPPE-Keys for MS-CHAPv1 and
        #  MS-MPPE-Recv-Key/MS-MPPE-Send-Key for MS-CHAPv2
        #
#       use_mppe = no

        #
        #  If MPPE is enabled, require_encryption makes
        #  encryption moderate
        #
#       require_encryption = yes

        #
        #  require_strong always requires 128 bit key
        #  encryption
        #
#       require_strong = yes

        #
        #  This module can perform authentication itself, OR
        #  use a Windows Domain Controller.  This configuration
        #  directive tells the module to call the ntlm_auth
        #  program, which will do the authentication, and return
        #  the NT-Key.  Note that you MUST have "winbindd" and
        #  "nmbd" running on the local machine for ntlm_auth
        #  to work.  See the ntlm_auth program documentation
        #  for details.
        #
        #  If ntlm_auth is configured below, then the mschap
        #  module will call ntlm_auth for every MS-CHAP
        #  authentication request.  If there is a cleartext
        #  or NT hashed password available, you can set
        #  "MS-CHAP-Use-NTLM-Auth := No" in the control items,
        #  and the mschap module will do the authentication itself,
        #  without calling ntlm_auth.
        #
        #  Be VERY careful when editing the following line!
        #
        #  You can also try setting the user name as:
        #
        #       ... --username=%{mschap:User-Name} ...
        #
        #  In that case, the mschap module will look at the User-Name
        #  attribute, and do prefix/suffix checks in order to obtain
        #  the "best" user name for the request.
        #
        #  For Samba 4, you should also set the "ntlm auth" parameter
        #  in the Samba configuration:
        #
        #       ntlm auth = yes
        #
        #  or
        #
        #       ntlm auth = mschapv2-and-ntlmv2-only
        #
        #  This will let Samba 4 accept the MS-CHAP authentication
        #  method that is needed by FreeRADIUS.
        #
        #  Depending on the Samba version, you may also need to add:
        #
        #       --allow-mschapv2
        #
        #  to the command-line parameters.
        #
        ntlm_auth = "/usr/bin/ntlm_auth --request-nt-key --allow-mschapv2
--username=%{%{Stripped-User-Name}:-%{%{User-Name}:-None}}
--challenge=%{%{mschap:Challenge}:-00}
--nt-response=%{%{mschap:NT-Response}:-00}"

        #
        #  The default is to wait 10 seconds for ntlm_auth to
        #  complete.  This is a long time, and if it's taking that
        #  long then you likely have other problems in your domain.

        #  The length of time can be decreased with the following
        #  option, which can save clients waiting if your ntlm_auth
        #  usually finishes quicker. Range 1 to 10 seconds.
        #
#       ntlm_auth_timeout = 10

        #
        #  An alternative to using ntlm_auth is to connect to the
        #  winbind daemon directly for authentication. This option
        #  is likely to be faster and may be useful on busy systems,
        #  but is less well tested.
        #
        #  Using this option requires libwbclient from Samba 4.2.1
        #  or later to be installed. Make sure that ntlm_auth above is
        #  commented out.
        #
#       winbind_username = "%{mschap:User-Name}"
#       winbind_domain = "%{mschap:NT-Domain}"

        #
        #  When using single sign-on with a winbind connection and the
        #  client uses a different casing for the username than the
        #  casing is according to the backend, reauth may fail because
        #  of some Windows internals. This switch tries to find the
        #  user in the correct casing in the backend, and retry
        #  authentication with that username.
        #
#       winbind_retry_with_normalised_username = no

        #
        #  Information for the winbind connection pool.  The configuration
        #  items below are the same for all modules which use the new
        #  connection pool.
        #
        pool {
                #
                #  Connections to create during module instantiation.
                #  If the server cannot create specified number of
                #  connections during instantiation it will exit.
                #  Set to 0 to allow the server to start without the
                #  winbind daemon being available.
                #
                start = ${thread[pool].start_servers}

                #
                #  Minimum number of connections to keep open
                #
                min = ${thread[pool].min_spare_servers}

                #
                #  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.  This should be less than or equal to "max"
above.
                #
                spare = ${thread[pool].max_spare_servers}

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

                #
                #  The number of seconds to wait after the server tries
                #  to open a connection, and fails.  During this time,
                #  no new connections will be opened.
                #
                retry_delay = 30

                #
                #  The lifetime (in seconds) of the connection
                #
                #  NOTE: A setting of 0 means infinite (no limit).
                #
                lifetime = 86400

                #
                #  The pool is checked for free connections every
                #  "cleanup_interval".  If there are free connections,
                #  then one of them is closed.
                #
                cleanup_interval = 300

                #
                #  The idle timeout (in seconds).  A connection which is
                #  unused for this length of time will be closed.
                #
                #  NOTE: A setting of 0 means infinite (no timeout).
                #
                idle_timeout = 600

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

        passchange {
                #
                #  This support MS-CHAPv2 (not v1) password change
                #  requests.  See doc/mschap.rst for more IMPORTANT
                #  information.
                #
                #  Samba/ntlm_auth - if you are using ntlm_auth to
                #  validate passwords, you will need to use ntlm_auth
                #  to change passwords.  Uncomment the three lines
                #  below, and change the path to ntlm_auth.
                #
#               ntlm_auth = "/usr/bin/ntlm_auth
--helper-protocol=ntlm-change-password-1"
#               ntlm_auth_username = "username: %{mschap:User-Name}"
#               ntlm_auth_domain = "nt-domain: %{mschap:NT-Domain}"

                #
                #  To implement a local password change, you need to
                #  supply a string which is then expanded, so that the
                #  password can be placed somewhere.  e.g. passed to a
                #  script (exec), or written to SQL (UPDATE/INSERT).
                #  We give both examples here, but only one will be
                #  used.
                #
#               local_cpw = "%{exec:/path/to/script %{mschap:User-Name}
%{MS-CHAP-New-Cleartext-Password}}"
                #
#               local_cpw = "%{sql:UPDATE radcheck set
value='%{MS-CHAP-New-NT-Password}' where username='%{SQL-User-Name}' and
attribute='NT-Password'}"
        }

        #
        #  For Apple Server, when running on the same machine as
        #  Open Directory.  It has no effect on other systems.
        #
#       use_open_directory = yes

        #
        #  On failure, set (or not) the MS-CHAP error code saying
        #  "retries allowed".
        #
#       allow_retry = yes

        #
        #  An optional retry message.
        #
#       retry_msg = "Re-enter (or reset) the password"
        #with_ntdomain_hack = yes
}

The output from freeradius -X is:
(0) Received Access-Request Id 12 from 192.168.1.1:44212 to
192.168.1.124:1812 length 164
(0)   Service-Type = Framed-User
(0)   Framed-Protocol = PPP
(0)   User-Name = "joshua.sharpe at home.win"
(0)   MS-CHAP-Challenge = 0xb35e16425214f586285afcac0f038db9
(0)   MS-CHAP2-Response =
0x6100a8393fbaf6d17963e99be8d8b1bb0a280000000000000000c3b892042ad109ffc85d84f05a3322050c6f048fee25f823
(0)   Calling-Station-Id = "192.168.1.10"
(0)   NAS-IP-Address = 192.168.1.1
(0)   NAS-Port = 0
(0) # Executing section authorize from file
/etc/freeradius/3.0/sites-enabled/default
(0)   authorize {
(0)     policy filter_username {
(0)       if (&User-Name) {
(0)       if (&User-Name)  -> TRUE
(0)       if (&User-Name)  {
(0)         if (&User-Name =~ / /) {
(0)         if (&User-Name =~ / /)  -> FALSE
(0)         if (&User-Name =~ /@[^@]*@/ ) {
(0)         if (&User-Name =~ /@[^@]*@/ )  -> FALSE
(0)         if (&User-Name =~ /\.\./ ) {
(0)         if (&User-Name =~ /\.\./ )  -> FALSE
(0)         if ((&User-Name =~ /@/) && (&User-Name !~ /@(.+)\.(.+)$/))  {
(0)         if ((&User-Name =~ /@/) && (&User-Name !~ /@(.+)\.(.+)$/))   ->
FALSE
(0)         if (&User-Name =~ /\.$/)  {
(0)         if (&User-Name =~ /\.$/)   -> FALSE
(0)         if (&User-Name =~ /@\./)  {
(0)         if (&User-Name =~ /@\./)   -> FALSE
(0)       } # if (&User-Name)  = notfound
(0)     } # policy filter_username = notfound
(0)     [preprocess] = ok
(0)     [chap] = noop
(0) mschap: Found MS-CHAP attributes.  Setting 'Auth-Type  = mschap'
(0)     [mschap] = ok
(0)     [digest] = noop
(0) suffix: Checking for suffix after "@"
(0) suffix: Looking up realm "home.win" for User-Name =
"joshua.sharpe at home.win"
(0) suffix: No such realm "home.win"
(0)     [suffix] = noop
(0) eap: No EAP-Message, not doing EAP
(0)     [eap] = noop
(0)     [files] = noop
(0)     [expiration] = noop
(0)     [logintime] = noop
Not doing PAP as Auth-Type is already set.
(0)     [pap] = noop
(0)   } # authorize = ok
(0) Found Auth-Type = mschap
(0) # Executing group from file /etc/freeradius/3.0/sites-enabled/default
(0)   authenticate {
(0) mschap: Creating challenge hash with username: joshua.sharpe at home.win
(0) mschap: Client is using MS-CHAPv2
(0) mschap: Executing: /usr/bin/ntlm_auth --request-nt-key --allow-mschapv2
--username=%{%{Stripped-User-Name}:-%{%{User-Name}:-None}}
--challenge=%{%{mschap:Challenge}:-00}
--nt-response=%{%{mschap:NT-Response}:-00}:
(0) mschap: EXPAND
--username=%{%{Stripped-User-Name}:-%{%{User-Name}:-None}}
(0) mschap:    --> --username=joshua.sharpe at home.win
(0) mschap: Creating challenge hash with username: joshua.sharpe at home.win
(0) mschap: EXPAND --challenge=%{%{mschap:Challenge}:-00}
(0) mschap:    --> --challenge=9c377afcf9835f65
(0) mschap: EXPAND --nt-response=%{%{mschap:NT-Response}:-00}
(0) mschap:    -->
--nt-response=c3b892042ad109ffc85d84f05a3322050c6f048fee25f823
(0) mschap: ERROR: Program returned code (1) and output 'The attempted
logon is invalid. This is either due to a bad username or authentication
information. (0xc000006d)'
(0) mschap: External script failed
(0) mschap: ERROR: External script says: The attempted logon is invalid.
This is either due to a bad username or authentication information.
(0xc000006d)
(0) mschap: ERROR: MS-CHAP2-Response is incorrect
(0)     [mschap] = reject
(0)   } # authenticate = reject
(0) Failed to authenticate the user
(0) Using Post-Auth-Type Reject
(0) # Executing group from file /etc/freeradius/3.0/sites-enabled/default
(0)   Post-Auth-Type REJECT {
(0) attr_filter.access_reject: EXPAND %{User-Name}
(0) attr_filter.access_reject:    --> joshua.sharpe at home.win
(0) attr_filter.access_reject: Matched entry DEFAULT at line 11
(0)     [attr_filter.access_reject] = updated
(0)     [eap] = noop
(0)     policy remove_reply_message_if_eap {
(0)       if (&reply:EAP-Message && &reply:Reply-Message) {
(0)       if (&reply:EAP-Message && &reply:Reply-Message)  -> FALSE
(0)       else {
(0)         [noop] = noop
(0)       } # else = noop
(0)     } # policy remove_reply_message_if_eap = noop
(0)   } # Post-Auth-Type REJECT = updated
(0) Delaying response for 1.000000 seconds
Waking up in 0.2 seconds.
Waking up in 0.7 seconds.
(0) Sending delayed response
(0) Sent Access-Reject Id 12 from 192.168.1.124:1812 to 192.168.1.1:44212
length 103
(0)   MS-CHAP-Error = "aE=691 R=1 C=f845a8b4f969a07f79282666cf728100 V=3
M=Authentication rejected"
Waking up in 3.9 seconds.
(0) Cleaning up request packet ID 12 with timestamp +30 due to
cleanup_delay was reached

Can I please get advice?


-- 
==============================================================
This Message is intended for the Addressee named and may contain Privileged
Information or Confidential Information or both. If you are not the
intended Recipient please delete it and notify the Sender. Sender is:
TTDHEAD at gmail.com
==============================================================


More information about the Freeradius-Users mailing list