FOG/Apache PKI/Certificate Authentication
-
@ty900000 While you are right the http://ipxe.org/err/410de3 error is a bit strange but I’d still suspect this to be a certificate issue. FOG does a couple of things behind the scenes with the
-S
switch installed. But if you want to use your custom CA (which is perfectly fine by the way and I’d love that we’d already have the installer up to the point where we let people decide but you know too many other issues around) you can still do the iPXE compilation sort of “manually”.cd /path/to/fogproject-code/utils/FOGiPXE/ ./buildipxe.sh /path/to/your/own/CA/cert.pem
See if it runs through (take a few minutes) or if it stops with errors. If there are no errors you can just copy the new binaries over.
rsync -av /path/to/fogproject-code/packages/tftp/ /tftpboot/
Make sure you use the trailing slashes exactly as seen above!
-
Still no luck with the iPXE over HTTPS… That’s something I’ll look at later. I don’t want to get too off track and overwhelmed with taking on too many things at one time.
However, I did manage to get FOG to pass through the certificate and its information. FOG prompts for a certificate, pulls the (Microsoft) UPN, and creates the temporary user with the UPN.
I have been wracking my brain all day about ways to bind to LDAP and since I’m not an expert on LDAP; I don’t know if there is a way to check LDAP without a username and password. What brought this on is: I found out the LDAP plugin does not need a bind user and password to successfully log in, it can use the entered username and password. But if a bind user is defined, it will rebind with the username and password entered on the login page. Since the certificate does not have a password, it can’t technically bind to LDAP to search through group memberships? I’m not entirely sure how other companies search through LDAP for group membership with PKI authentication.
For now, since I have to define a bind user and password, I disabled the rebind. It does work, but it’s not perfect.
Once I select a viable certificate, I still get directed to the login page. I have to enter random gibberish in the username and password boxes so it will create the temporary user with the password that was entered. I have tried in vain to change the password passthrough and generate a random password. I have a function to generate an ‘n’ length string. But when I replace the $pass variable from what what originally defined to the returned variable from the password function, FOG will not log the user in. I tried several things to replace $pass. I set it manually to something like ‘testing’ and it still wouldn’t work and then I changed the actual variable call in line 133 to a string, still no luck. https://github.com/FOGProject/fogproject/blob/dev-branch/packages/web/lib/plugins/ldap/hooks/ldappluginhook.hook.php#L133
I can’t seem to figure out how to decouple it and change it…
Also, I’d like to figure out how to completely skip the login page if a valid certificate is presented. Since the LDAP plugin needs a password to create the temporary user, I was hoping to use the randomly generated password to bypass the login page password box.
I know it’s a lot in this post and I’m sure it’s not very clear. Let me know if I’m not being clear and I can attempt to explain better.
I appreciate the assistance! Thanks again for the help and guidance. I’d never be able to figure it out with the tips and pointers of where to start digging.
-
@ty900000 said:
Still no luck with the iPXE over HTTPS… That’s something I’ll look at later. I don’t want to get too off track and overwhelmed with taking on too many things at one time.
Good point! Take it one step at a time!
I’m not entirely sure how other companies search through LDAP for group membership with PKI authentication.
Usually this is done using what I’d call a service account. It’s setup in AD/LDAP and the username/password stored/hardcoded in the software that wants to query AD/LDAP.
Will answer more when I get more time.
-
@Sebastian-Roth If OP looked at the ldap plugin there is an account called a bind dn. That account is a basic level account that has read-only access to AD (LDAP). That bind account is used to search AD for a valid user, then it rebinds to AD as that user to test to see if the user’s password is valid. If its valid then using the user’s credentials it looks at the admin group and the mobile group to see if the user is a member of that group. I think that framework would be a good starting point for your pki plugin. At least someone can see how the program flow goes.
-
Right, I am currently using the bindDN user to search through LDAP and commented out the rebind since there is no user/password defined with PKI certificates. I was just wondering if there was another way to search LDAP without explicitly defining a user and password. I know anonymous LDAP browsing is a thing, but that’s a huge security risk and should never be enabled in production.
-
@ty900000 My experience is anonymous ldap browsing is disabled in AD. As you said its a big security hole if left on. If on it would give hackers a way to enumerate the number and names of user accounts.
-
@ty900000 As mentioned using a special service account to bind to LDAP/AD is good practice and I don’t advice you to allow anonymous LDAP searches!
Once I select a viable certificate, I still get directed to the login page.
For that you need to start looking at the core code. This is where it decides wheather the user is logged in and directed to the dashboard or not. The variable
$FOGUser
is being defined and initialized in class FOGBase. Now this again is being set as a global variable from the session. And the real magic then happens invalidatePw
function in class User.Sorry I can’t give a an easy solution to this just now. Don’t have enough time. But those pieces of code should give you all you need to figure it out - I hope.
-
@Sebastian-Roth said in FOG/Apache PKI/Certificate Authentication:
As mentioned using a special service account to bind to LDAP/AD is good practice and I don’t advice you to allow anonymous LDAP searches!
Right! Yeah, I would never enable anonymous LDAP searching. I’ll stick with the hardcoded bind user and set it up on a password change schedule.
For that you need to start looking at the core code.
Okay, cool. I’ve been tracking down the myriad bugs I have managed to introduce for today, so I can take a look at that code tonight and tomorrow.
Sorry I can’t give a an easy solution to this just now. Don’t have enough time.
No worries! I know you guys are busy with updating the core FOG functionality. I’ll keep at it and see what I can find.
-
@george1421 In my previous post I mentioned generating a random password for the login user, rather than manually typing in a password in the box at the login page. I can’t seem to figure that out. I know you said you were an originator of the LDAP plugin. Could you offer any tips on how I can change this? https://github.com/FOGProject/fogproject/blob/dev-branch/packages/web/lib/plugins/ldap/hooks/ldappluginhook.hook.php#L133
If I change the $pass variable, which is defined at line 104, in any way, the login fails. Thank you, sir!
-
@ty900000 This is the bit of code the developers added. But I wonder if you set $pass to a static text like “hello” and then when it writes that to that temp user it would write hello to that account. But I suspect there is a bit of caching of $pass going on at a session level.
-
@ty900000 Well on line 104 we are getting the text from the form. Its only used in 4 spots and one is used to check if we can bind to ad with the user id and password combo. I guess I don’t see a reason why you can’t just set it to a static (or random) value.
Without thinking about this at all, I wonder if you seeded the value on the login prompt, just type in a random password on the login form, because apache may be caching that value. During your testing will it accept any password you enter since you are not using that value for qualification of the account?
-
@george1421 said in FOG/Apache PKI/Certificate Authentication:
@ty900000 Well on line 104 we are getting the text from the form. Its only used in 4 spots and one is used to check if we can bind to ad with the user id and password combo. I guess I don’t see a reason why you can’t just set it to a static (or random) value.
Without thinking about this at all, I wonder if you seeded the value on the login prompt, just type in a random password on the login form, because apache may be caching that value. During your testing will it accept any password you enter since you are not using that value for qualification of the account?
Yes, I did try manually setting line 104 to something like “testing” and FOG would not let me log in no matter what I type in the password box, even if it was the local built-in fog user/password.
If I leave line 104 alone and type in random stuff in the password box on the login page, it will pass along whatever I type in the password box. But, that means the password of the temporary user could be something really simple like ‘a’
-
@ty900000 Well that’s where I wonder if you want to tweak the login form. I know this is hacking FOG a bit more than you wanted. But set the field on the login page to read only and then pipe in a random password. As I’m suspecting FOG or apache is caching what the user keys into the login page for subsequent logins during the session. Probably by setting a session level value with the user ID and password. But I’m only guessing here. But that would explain why setting something on the login page would be persistent and you keying in something in the plugin code is being rejected.
-
@george1421 said in FOG/Apache PKI/Certificate Authentication:
@ty900000 But set the field on the login page to read only and then pipe in a random password.
Okay, I will try that. Stupid question from me, where is the code that creates the page that does the username and password read?
Is it somewhere in here? https://github.com/FOGProject/fogproject/blob/dev-branch/packages/web/lib/pages/processlogin.class.php
Thanks again!!
-
@ty900000 Yes, on line 275ff.
-
@ty900000 For that answer I’ll have to see if I can reverse engineer it. I don’t think it was the class but just a php page. I can see the processlogin acting upon the form.
-
@ty900000 Yes from what Sebastian said is what I found. Its in
lib/pages/processlogin.class.php
relative to the fog root directory. I searched for “form-signin” that I found on the web page using the firefox developer tools. -
Okay, I managed to figure out how to generate a random string for the password in place of user input. (I could never decouple the password form and the LDAP plugin need for a password, so it just passes it through like it always has.) I also made the Username and Password not required, so they can be left blank. Now if I press the Login button, it just uses the LDAP query to authenticate certificate UPN user is in the specified admin group in AD.
I took a look at how to completely bypass the login page after selecting a certificate. I am a little stumped on how the Login button actually does the login. Is it this line that does the login? If so, how? https://github.com/FOGProject/fogproject/blob/dev-branch/packages/web/lib/pages/processlogin.class.php#L320
I’m not so good at working with HTML code, so I don’t really understand how things do the thing they are supposed to do, i.e. a button logging a user in.
Thanks for the assistance over the past week, everyone. I truly appreciate the help and guidance!
-
@ty900000 Well what makes it a bit confusing is there is a mixture of JS, HTML and PHP code intermixed. But me (ignorantly) reading it, I just looked at the HTML. The login button is an html “submit” button L366. It then submits the html form. The html form has a javascript action attached L329 to it. It calls a javascript procedure called formAction. I don’t see the procedure formAction in any of the code on that page, so that means the procedure is being brought in through an html include some place else. I’ll have to remote into the office to my fog server to find where that is. It will be in a .js file (probably).
Edit: well I was wrong (maybe), formAction is a variable that holds a pointer to the javascript functions that gets called. This level of indirection is a bit maddening.
Edit2: Ok I’m not as smart as I thought. I thought the action may have come in through the class style sheet for “form-signin” class, but no.
-
Not much luck today. I couldn’t really decipher what the login page is doing when the button is pressed. I was thinking that, after a certificate is selected, I could figure out how to change the login page to automatically “click” the button and that would automatically call the JavaScript code. But, I could never get that far.
That would also mean when a user clicked “Logout” and it redirected back to the login page, it would automatically log back in immediately. I was thinking of adding an actual logout page that was just a basic HTML page stating the user was logged out.
There are still a number of bugs, some of which I cannot for the life of me figure out what is wrong and Googling returns zero results. On a more positive note, I did manage to get LDAPS to work. I initially had problems with it binding the server for some reason - probably certificate stuff, I’m sure.
Don’t know if anyone can offer any more guidance on how to make the login page automatically “click” the login button?
Thanks again for the assistance everyone!