Okay, I’ll try and make this as clear as I can, but please feel free to ask for any clarification, and I’ll try and see what I can do.
My Server Info
- OS version: CentOS 7 (minimal install iso)
- Apache version: 2.4.6 (installed by Fog’s bin/installfog.sh ?)
- Fog version: trunk via Wiki (https://wiki.fogproject.org/wiki/index.php/Upgrade_to_trunk)
- Revision: 7609
- Hardware: VMware / vSphere
Prerequisites
The material in this documentation assumes:
- Fog has already been installed and the web interface is fully accessible.
- The Fog server has sshd access and sftpd is working.
- You know how to extract files.
- You know how to transfer files.
- Maybe a few other things I’ve missed listing.
The Procedure
So, the ultimate goal was to authenticate only IT Techs, and via AD, so we could have yet another system with single sign-on. Research indicated that LDAP authentication should be fairly quick and easy with Apache.
Truth be told, I had to hunt down and find the exact version of some required files. I finally found them at rpmfind.net (ftp://rpmfind.net/linux/RPM/centos/7.2.1511/x86_64/Packages/mod_ldap-2.4.6-40.el7.centos.x86_64.html) and attempted to install the RPM with yum localinstall mod_ldap-2.*.rpm
. However, whenever I tried this, the OS told me what version the file is, and what version the file needs to actually be.
They looked the same to my eyes, so, I downloaded the rpm on my Windows unit and opened it with 7-zip. I extracted the files and then transferred them to the Fog server, to /etc/httpd/modules/. Now, I don’t know if the next part was required, but it’s a habit. I updated permissions and access to the files once they were extracted and moved to their proper location:
chmod 755 /etc/httpd/modules/mod_ldap.so /etc/httpd/modules/mod_authnz_ldap.so
chown root:root /etc/httpd/modules/mod_ldap.so /etc/httpd/modules/mod_authnz_ldap.so
chcon -t httpd_modules_t etc/httpd/modules/mod_ldap.so /etc/httpd/modules/mod_authnz_ldap.so
chcon -t httpd_modules_t /etc/httpd/modules/mod_ldap.so /etc/httpd/modules/mod_authnz_ldap.so
In the end, my httpd.conf file looks as follows, using Christoph’s brain dump (http://www.held-im-ruhestand.de/software/apache-ldap-active-directory-authentication.html) as a guide. Loading the modules takes place first, in the LoadModules section.
nano /etc/httpd/conf/httpd.conf
..
...
LoadModule ldap_module /etc/httpd/modules/mod_ldap.so
LoadModule authnz_ldap_module /etc/httpd/modules/mod_authnz_ldap.so
...
..
The following takes place after DocumentRoot “/var/www/html”. Potentially sensitive material has been redacted and/or modified.
..
...
<Directory "/var/www/html/fog/management">
# These options were here; I'm not messing with them.
Options FollowSymLinks
AllowOverride None
Allow from all
# Engage the initial connection with an account that can read the domain trees.
AuthLDAPBindDN "ldapuser"
AuthLDAPBindPassword yoursecretpasswordhere
# Path to the AD/LDAP server. Includes the path as to where the above user can
# search for usernames
AuthLDAPURL "ldap://192.168.1.250/OU=People,DC=gtcc,DC=ad?sAMAccountName?sub?(objectClass=*)"
# Standard authentication configurations.
AuthType Basic
AuthName "ITS FOG Server"
AuthBasicProvider ldap
AuthLDAPBindAuthoritative off
AuthUserFile /dev/null
# Users in the following groups are the *only* users allowed into the site.
Require ldap-group CN=ITS Department,OU=ITS,OU=Groups,DC=gtcc,DC=ad
</Directory>
...
..
I found that next, I needed to run the following command to install some ldap tools that doesn’t come with a minimal installation of CentOS 7.
yum install apr-util-ldap -y
Then, restarted the httpd service:
systemctl restart httpd
With LDAP sign-in working, I was still getting the Login page (and rightly so). Editing the processlogin.class.php file will fix that right up. The code that follows attempts to perform the following:
- Rename what I came to believe to be the logout form.
- Make a connection to the Fog database and check for the username of the user that just successfully authenticated via Apache’s LDAP authentication process. The process I took here might should be updated to best practices standards. I’m not that great of a programmer, so I don’t know those standards.
- If no user is found in Fog’s user table, then add them; they’re authenticated via LDAP anyway.
- Adds username and generic password to the form input fields values.
- Hides the form input fields.
- Hides the Login button, placing a Please Wait… notice in its place.
- Javascript immediately submits the form.
nano /var/www/html/fog/lib/fog/processlogin.class.php
Line ~145:
..
...
# This was being double printed in the source code, and forcing a loop of redirection in the code below.
# Renaming the id to avoid that. It's probably for logout, anyways.
echo '<form method="post" action="" id="login-form0">';
...
..
Line ~153: after $this->getLanguages();, and replacing printf for mainLoginForm
..
...
# Make the username from Apache quicker to type.
$ap_user = $_SERVER['PHP_AUTH_USER'];
# Adding this password variable in, from the MariaDB result I got from manually querying
# the 'users' table. It should be the equivilent to "FogREMOTEUSER" and will be everyone's
# password with Fog, because they've already signed in with their AD credentials.
# However, I just realized this.... what if they need 'Quick Image'? Hmm... I guess I'll
# just tell them "FogREMOTEUSER", huh?
$ap_pass = '$2y$11$PIB.FzVsBSccSnoOVvyPcuPwJsHBYZRQO/RUFx.WinrCk0tQvb3IC';
# Connecting to the database the only way I know how. Maybe even re-inventing the wheel. Anyways,
# one does not simply walk into a database.
$DBServer = 'localhost';
$DBUser = 'root';
$DBPass = '';
$DBName = 'fog';
$conn = new mysqli($DBServer, $DBUser, $DBPass, $DBName);
# Create the sql statement that will check for the user's existence in the database realm.
$sqlChkExist = "SELECT * FROM users WHERE uName = '" . $ap_user . "'";
# Execute the query
$rs=$conn->query($sqlChkExist);
# How many rows where returned?
$rowCount = $rs->num_rows;
# If there were 0 rows, then we need to add this user to the database, then.
if ($rowCount == 0) {
# Hey! Listen! ^_^
# Looks like this user doesn't exist in this database. Let's add them.
# Build the statement that will add the user.
$sqlInsUsr = "INSERT INTO users (uName, uPass, uCreateBy, uType) VALUES ('" . $ap_user . "', '" . $ap_pass . "', 'autoGen', 0)";
# Join me, and together we can rule the images, as SA and Tech.
$rs=$conn->query($sqlInsUsr);
}
printf('</form><form method="post" action="" id="login-form"><input type="hidden" class="input" name="uname" id="username" value="' . $ap_user . '"/><input type="hidden" class="input" name="upass" id="password" value="FogREMOTEUSER"/><label for="login-form-submit"> </label><input type="submit" value="%s" id="login-form-submit" style="display:none;"/>Please wait....</form><div id="login-form-info"><p>%s: <b><i class="icon fa fa-circle-o-notch fa-spin fa-fw"></i></b></p><p>%s: <b><i class="icon fa fa-circle-o-notch fa-spin fa-fw"></i></b></p></div><script>document.getElementById("login-form").submit();</script>',self::$foglang['Login'],self::$foglang['FOGSites'],self::$foglang['LatestVer']);
# Troll the respawn, Jeremy.
...
..
I then realized that clicking the Logout button sends the user to the Login page, which then signs them back in. Since our Techs use their own computers, and the credentials go away upon closing the browser, I decide to remove the option to login. Simply comment out line ~52 of page.class.php
nano /var/www/html/fog/lib/fog/page.class.php
..
...
'about'=>array(self::$foglang['FOG Configuration'],'fa fa-wrench fa-2x'),
# 'logout'=>array(self::$foglang['Logout'],'fa fa-sign-out fa-2x'),
);
...
..
And according to my notes, that took me about… Eeyup, ~15 hours to figure out. Shows how bad I am at researching and debugging, I guess. But it works for us and what we’re trying to do! Again, please feel free to contact me about anything here; also, don’t be afraid to point out any typos. ^_^
Thanks!