[Swan] IKEv2 PAM auth failure - how it's done properly?

Mirsad Goran Todorovac mirsad.todorovac at alu.unizg.hr
Sat Jan 22 13:50:22 EET 2022


Dear Paul,

I have succeeded making it work, with some tweaking to pam_url source.

Apropos /etc/pam.d/pluto, it appears to be a part of the Debian 
libreswan package, so I mailed the maintainer.

Thank you for your thoughts and prayers.

This was an exciting challenge, with ups and downs ;-)

Kind regards,
Mirsad

On 1/22/2022 9:47 AM, Mirsad Goran Todorovac wrote:
>
> P.P.S.
>
> I apologize, the link in the previous email executed the PHP script 
> instead of displaying the source. Here is the fixed link:
>
> https://domac.alu.hr/mtodorov/myauth.php.txt
>
> But IMHO the script works as intended: it returns 200 OK if the user 
> is existing in the account.txt file.
> The problem seems to be in the /etc/pam.d/test that I can't seem to 
> get right.
>
> Mirsad
>
> On 1/22/2022 9:39 AM, Mirsad Goran Todorovac wrote:
>>
>> Hello Paul,
>>
>> I have unsuccessfully tried libpam-pkcs11 but it seems to require a 
>> card slot and it didn't work with NSS.
>>
>> I have succeeded to enable pam_url with SSL on my local web server to 
>> call my CGI-BIN script.
>>
>> However, I couldn't make it to work with PAM.
>>
>> However, there seems to be a problem with the default 
>> /etc/pam.d/pluto with libreswan-4.6. It is including system-auth, but 
>> system-auth does not exist in my Debian server's /etc/pam.d . It 
>> seems to be sort of a RedHat thing.
>>
>> The file is:
>>
>> % cat /etc/pam.d/pluto
>> #%PAM-1.0
>> # Regular System auth
>> auth include system-auth
>> #
>> # Google Authenticator with Regular System auth in combined prompt mode
>> # (OTP is added to the password at the password prompt without separator)
>> # auth required pam_google_authenticator.so forward_pass
>> # auth include system-auth use_first_pass
>> #
>> # Common
>> account required pam_nologin.so
>> auth    sufficient pam_pkcs11.so
>> account include system-auth
>> password include system-auth
>> session optional pam_keyinit.so debug force revoke
>> session include system-auth
>> session required pam_loginuid.so
>>
>> The /etc/pam.d/test for pam_url also calls system-auth:
>>
>> # cat /etc/pam.d/test
>> #%PAM-1.0
>> auth       required     pam_env.so
>> auth       sufficient   /lib64/security/pam_url.so debug 
>> config=/etc/pam_url.conf
>> auth       requisite    pam_succeed_if.so uid >= 500 quiet
>> auth       required     pam_deny.so
>>
>> account    include      system-auth
>> password   include      system-auth
>> session    optional     pam_keyinit.so revoke
>> session    required     pam_limits.so
>>
>> It seems to be made for local users.
>>
>> I am going to paste a working system-auth from the web, but it is 
>> rather cumbersome :-P
>>
>> I feel really confused, as I see none of functions in 
>> pam_authenticate return "yes" or "no". Maybe I was wrong to take it 
>> literally.
>>
>> I have succeeded to make the script be called from pamtester and to 
>> return "200 OK" in case the username is in the permitted access file, 
>> and "400 Bad Request" if it is not.
>>
>> However, pamtester treats both of these cases as "Authentication 
>> failure":
>>
>> root at domac:/home/admin/mtodorov/build/pam_url# pamtester -v test 
>> user1 authenticate
>> pamtester: invoking pam_start(test, user1, ...)
>> pamtester: performing operation - authenticate
>> 161.53.235.3 - - [22/Jan/2022:09:35:45 +0100] "POST 
>> /cgi-bin/myauth.php HTTP/2.0" 200 134 "-" "pam_url/0.3.3"
>> pamtester: Authentication failure
>> root at domac:/home/admin/mtodorov/build/pam_url# pamtester -v test 
>> notexisting authenticate
>> pamtester: invoking pam_start(test, notexisting, ...)
>> pamtester: performing operation - authenticate
>> 161.53.235.3 - - [22/Jan/2022:09:35:58 +0100] "POST 
>> /cgi-bin/myauth.php HTTP/2.0" 400 125 "-" "pam_url/0.3.3"
>> pamtester: Authentication failure
>> root at domac:/home/admin/mtodorov/build/pam_url#
>>
>> I feel like I'm out of options.
>>
>> pam_url/pam_url.c has this:
>>
>>         if( CURLE_OK != curl_easy_perform(eh) )
>>                 goto curl_error;
>>
>>         // No errors
>>         free(post);
>>         curl_easy_cleanup(eh);
>>         curl_global_cleanup();
>>         return PAM_SUCCESS;
>>
>> so the "200 OK" should be sufficient to authorize, but something 
>> spurious seems to be happening.
>>
>> I hope I can be given an idea, as I feel I ran out of options.
>>
>> Kind regards,
>> Mirsad
>>
>> On 1/21/2022 5:03 PM, Paul Wouters wrote:
>>> to use pam, you create or modify /etc/pam.d/pluto
>>>
>>> For example, you could change this file to use pam_url as the pam 
>>> module and then run your own REST http server that will receive the 
>>> authorization name and you can write you own code to respond with 
>>> either “yes” or “no”.
>>>
>>> This part is not libreswan specific, and you can test your pam 
>>> module using pam_tester and specifying the “pluto” method that will 
>>> then use /etc/pam.d/pluto to perform the check to your backend. Once 
>>> pam_tester works, libreswan should work too.
>>>
>>> Paul
>>>
>>> Sent using a virtual keyboard on a phone
>>>
>>>> On Jan 21, 2022, at 10:44, Mirsad Goran Todorovac 
>>>> <mirsad.todorovac at alu.unizg.hr> wrote:
>>>>
>>>> 
>>>>
>>>> Hello Paul, Manfred,
>>>>
>>>> SO far I have located the lines in the source, but I am unable to 
>>>> decypher what these meant to do:
>>>>
>>>> pluto/pam-conv.c:
>>>> 143                 what = "pam_start";
>>>> 144                 retval = pam_start("pluto", arg->name, &conv, 
>>>> &pamh);
>>>> 145                 if (retval != PAM_SUCCESS)
>>>> 146                         break;
>>>> 147                 dbg_pam_step(arg, what);
>>>> 148
>>>> 149                 /* Send the remote host address to PAM */
>>>> 150                 what = "pam_set_item";
>>>> 151                 address_buf rhb;
>>>> 152                 retval = pam_set_item(pamh, PAM_RHOST, 
>>>> str_address(&arg->rhost, &rhb));
>>>> 153                 if (retval != PAM_SUCCESS)
>>>> 154                         break;
>>>> 155                 dbg_pam_step(arg, what);
>>>> 156
>>>> 157                 /* Two factor authentication - Check that the 
>>>> user is valid,
>>>> 158                  * and then check if they are permitted access
>>>> 159                  */
>>>> 160                 what = "pam_authenticate";
>>>> 161                 retval = pam_authenticate(pamh, PAM_SILENT); /* 
>>>> is user really user? */
>>>> 162                 if (retval != PAM_SUCCESS)
>>>> 163                         break;
>>>> 164                 dbg_pam_step(arg, what);
>>>> 165
>>>> 166                 what = "pam_acct_mgmt";
>>>> 167                 retval = pam_acct_mgmt(pamh, 0); /* permitted 
>>>> access? */
>>>> 168                 if (retval != PAM_SUCCESS)
>>>> 169                         break;
>>>> 170                 dbg_pam_step(arg, what);
>>>> 171
>>>> 172                 /* success! */
>>>> 173                 pam_end(pamh, PAM_SUCCESS);
>>>> 174                 return true;
>>>>
>>>> From this it appears that the username should be on the PAM side, 
>>>> and not in the ipsec.secret (5) file.
>>>> But I don't know which file yet. I think that I am rather certain 
>>>> that it shouldn't mess with /etc/passwd, for it doesn't allow 
>>>> spaces in usernames, does it?
>>>>
>>>> Mirsad
>>>>
>>>> On 21.1.2022. 16:00, Mirsad Goran Todorovac wrote:
>>>>>
>>>>> On 21.1.2022. 15:08, Paul Wouters wrote:
>>>>>
>>>>>> Hello,
>>>>>>>> I have installed the IKEv2 VPN connection at my colleague's laptop and he disappointingly noticed that there is no password authentication in addition to certificate.
>>>>>>>> This is also akward because we would have to change all certificates if i.e. one laptop configured for the Faculty VPN was lost or stolen. :-(
>>>>>>> I don't think this is right. The certificate system (in general, not libreswan's specifically) is explicitly designed so that you don't have to do that.
>>>>>>> Ref CRL (Certificate Revocation List).
>>>>>> Exactly. You only need to revoke the laptop certificate. The CA certificate is on the laptop too but not the CA certificate’s private key, only the public key.
>>>>>>
>>>>>> An additional password adds little security assuming there is already a login password, an automatic screen lock after a few minutes and whole disk encryption with a password.
>>>>>>
>>>>>> The libreswan pam option for IKEv2 is only meant for the server to check authorization of the client ID (usually a cert), not authentication. This is so you can temporary lock out a user without (irrevocably) revoking their certificate. This is often used when a customer hasn’t paid their bill for instance, or could be used if a laptop is missing but most likely will be found again.
>>>>>
>>>>> 1. I agree this opportunity to temporary disable the login with a 
>>>>> certificate would be practical. I have generated the certificates 
>>>>> as proposed on the link: 
>>>>> https://libreswan.org/wiki/VPN_server_for_remote_clients_using_IKEv2#Example_certificate_generation_with_certutil
>>>>>
>>>>> export PARM='--keyUsage digitalSignature,keyEncipherment 
>>>>> --extKeyUsage serverAuth,clientAuth'
>>>>> certutil -S -c "GRF-UNIZG CA" -n "laptop-marko.grf.hr" -s 
>>>>> "O=GRF-UNIZG,CN=laptop-marko.grf.hr"  -k rsa -g 4096 -v 12 -d 
>>>>> sql:${HOME}/tmpdb -t ",," ${PARM} -8 "laptop-marko.grf.hr"
>>>>> pk12util -o laptop-marko.grf.hr.p12 -n "laptop-marko.grf.hr" -d 
>>>>> sql:${HOME}/tmpdb/
>>>>>
>>>>> I have imported the cert into Windows 10 certificate manager in 
>>>>> the "Local Machine" keystore.
>>>>>
>>>>> I can't seem to understand how to revoke such a local certificate. 
>>>>> It is not generated by Letsencrypt or Sectigo, so where does ipsec 
>>>>> check for revocation lists?
>>>>>
>>>>> However, once it is revoked, the damage is done. I can't make it 
>>>>> alive again, can I? So, there is a justified question:
>>>>>
>>>>> 2. Can I get a pointer to the username/password file for the 
>>>>> certificates? I don't know if it should be in 
>>>>> /etc/ipsec.d/hostname.secrets, and what is the syntax considering 
>>>>> that the username contains spaces when expanded by certificate 
>>>>> check facility of I think pluto.
>>>>>
>>>>> As the username is as it appears in the pluto log, what is the 
>>>>> location and syntax of the password file? And who would provide 
>>>>> password? Windows 10 client or else?
>>>>>
>>>>> Jan 20 09:45:03.533787: | PAM: #1: PAM-process completed for user 
>>>>> 'CN=pc-mtodorov.alu.hr, O=ALU-UNIZG' with result FAILURE
>>>>>
>>>>> This would be a great feature to have.
>>>>> However, the manual ipsec.conf (5) only says this:
>>>>>
>>>>>     pam-authorize
>>>>>
>>>>>     IKEv1 supports PAM authorization via XAUTH using xauthby=pam.
>>>>>     IKEv2 does not support receiving a plaintext username and
>>>>>     password. Libreswan does not yet support EAP authentication
>>>>>     methods for IKE. The pam-authorize=yes option performs an
>>>>>     authorization call via PAM, but only includes the remote ID
>>>>>     (not username or password). This allows for backends to
>>>>>     disallow an ID based on non-password situations, such as "user
>>>>>     disabled" or "user over quota". See also xauthby=pam
>>>>>
>>>>> It is not clear to me which file should provide remote ID list 
>>>>> with permissions? And the syntax.
>>>>>
>>>>> My current /etc/pam.d/pluto looks like this:
>>>>>
>>>>> root at domac:~# cat /etc/pam.d/pluto
>>>>> #%PAM-1.0
>>>>> auth       required     pam_unix.so
>>>>> auth       required     pam_nologin.so
>>>>> account    required     pam_unix.so
>>>>> password   required     pam_unix.so
>>>>> session    required     pam_unix.so
>>>>> session    required     pam_loginuid.so
>>>>> root at domac:~#
>>>>>
>>>>> The 4.6 distribution original did not work for me either: it said 
>>>>> simply this:
>>>>>
>>>>> Jan 20 09:07:48.551340: "MYCONN-ikev2-cp"[4] 193.198.186.218 #2: 
>>>>> IKEv2 FAILED during pam_authenticate with 'Permission denied' for
>>>>> state #2, MYCONN-ikev2-cp[4] user=CN=pc-mtodorov.alu.hr, O=ALU-UNIZG.
>>>>> Jan 20 09:07:48.551600: | PAM: #2: PAM-process completed for user 
>>>>> 'CN=pc-mtodorov.alu.hr, O=ALU-UNIZG' with result FAILURE
>>>>> Jan 20 09:07:48.552834: | processing signal PLUTO_SIGCHLD
>>>>> Jan 20 09:07:48.552890: | waitpid returned pid 2652 (exited with 
>>>>> status 1)
>>>>> Jan 20 09:07:48.552903: | suspend: restoring MD at 0x55f56d8e5aa8 
>>>>> from state #2 (server_fork_sigchld_handler() +224 programs/pluto/ser
>>>>> ver_fork.c)
>>>>> Jan 20 09:07:48.552928: | #2 waited 0.010288 for 'pamauth' fork()
>>>>> Jan 20 09:07:48.552941: "MYCONN-ikev2-cp"[4] 193.198.186.218 #2: 
>>>>> PAM: authentication of user 'CN=pc-mtodorov.alu.hr, O=ALU-UNIZG' 
>>>>> FAILED after 0.01074 seconds
>>>>>
>>>>> I would love this feature to work on my VPN server. Libreswan team 
>>>>> is very motivational for experimenting. As I said before, I felt 
>>>>> moved by the all-inclusive code of conduct for the project :-)
>>>>>
>>>>>> The next version of libreswan will add EAPTLS authentication, so windows won’t require administrative rights to add the IKEv2 connection. Once that it is, perhaps another EAP method - mschapv2 - will be added that does add a user / password method that can be used without certificates.
>>>>> This sounds great. Looking forward to testing it :-)
>>>>> Kind regards,
>>>>> Mirsad
>>>>> -- 
>>>>> Mirsad Todorovac
>>>>> CARNet system engineer
>>>>> Faculty of Graphic Arts | Academy of Fine Arts
>>>>> University of Zagreb
>>>>> Republic of Croatia, the European Union
>>>>> --
>>>>> CARNet sistem inženjer
>>>>> Grafički fakultet | Akademija likovnih umjetnosti
>>>>> Sveučilište u Zagrebu
>>>>>
>>>>> _______________________________________________
>>>>> Swan mailing list
>>>>> Swan at lists.libreswan.org
>>>>> https://lists.libreswan.org/mailman/listinfo/swan
>>>> -- 
>>>> Mirsad Todorovac
>>>> CARNet system engineer
>>>> Faculty of Graphic Arts | Academy of Fine Arts
>>>> University of Zagreb
>>>> Republic of Croatia, the European Union
>>>> --
>>>> CARNet sistem inženjer
>>>> Grafički fakultet | Akademija likovnih umjetnosti
>>>> Sveučilište u Zagrebu
>>>> _______________________________________________
>>>> Swan mailing list
>>>> Swan at lists.libreswan.org
>>>> https://lists.libreswan.org/mailman/listinfo/swan
>> --
>> Mirsad Goran Todorovac
>> CARNet sistem inženjer
>> Grafički fakultet | Akademija likovnih umjetnosti
>> Sveučilište u Zagrebu
>> -- 
>> CARNet system engineer
>> Faculty of Graphic Arts | Academy of Fine Arts
>> University of Zagreb, Republic of Croatia
>> tel. +385 (0)1 3711 451
>> mob. +385 91 57 88 355
>>
>> _______________________________________________
>> Swan mailing list
>> Swan at lists.libreswan.org
>> https://lists.libreswan.org/mailman/listinfo/swan
> --
> Mirsad Goran Todorovac
> CARNet sistem inženjer
> Grafički fakultet | Akademija likovnih umjetnosti
> Sveučilište u Zagrebu
> -- 
> CARNet system engineer
> Faculty of Graphic Arts | Academy of Fine Arts
> University of Zagreb, Republic of Croatia
> tel. +385 (0)1 3711 451
> mob. +385 91 57 88 355
>
> _______________________________________________
> Swan mailing list
> Swan at lists.libreswan.org
> https://lists.libreswan.org/mailman/listinfo/swan

--
Mirsad Goran Todorovac
CARNet sistem inženjer
Grafički fakultet | Akademija likovnih umjetnosti
Sveučilište u Zagrebu
-- 
CARNet system engineer
Faculty of Graphic Arts | Academy of Fine Arts
University of Zagreb, Republic of Croatia
tel. +385 (0)1 3711 451
mob. +385 91 57 88 355
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.libreswan.org/pipermail/swan/attachments/20220122/7489fbe3/attachment-0001.htm>


More information about the Swan mailing list