|
CertificateAuthentication
IntroductionThis howto explains the set up for access control to php-syslog-ng using x.509 certificates. Almost any web browser is capable of doing client authentication in SSL protocol, and apache is easy to configure to allow that. This authentication module works as follows:
Needed php-syslog-ng versionThis was first introduced in version 2.9.8f. If you have a prior version, branch 2.9.8, you can apply the patch below: diff -Nur html/includes/common_funcs.php htmlnew/includes/common_funcs.php
--- html/includes/common_funcs.php 2008-08-08 05:38:01.000000000 +0200
+++ htmlnew/includes/common_funcs.php 2008-08-12 22:19:58.000000000 +0200
@@ -761,6 +761,22 @@
$error .= " Sorry, $username does not have access to this service.";
$_SESSION["error"] = "$error";
}
+ } elseif ($forms["authtype"] == "cert") {
+ // Using Cert basic authentication.Check certificate SerialNumber first, Subject DN if SerialNumber fails
+ $dbLink = db_connect_syslog(DBUSER, DBUSERPW);
+ if (verify_user($_SERVER['SSL_CLIENT_M_SERIAL'], $dbLink) || verify_user($_SERVER['SSL_CLIENT_S_DN'], $dbLink)) {
+ $sessionId = md5(mt_rand());
+ $_SESSION["pageId"] = "searchform";
+ $expTime = time()+SESSION_EXP_TIME;
+ $expTimeDB = date('Y-m-d H:i:s', $expTime);
+ // Update sessionId and exptime in database
+ $query = "UPDATE ".AUTHTABLENAME." SET sessionid='".$sessionId."',
+ exptime='".$expTimeDB."' WHERE username='".$username."'";
+ $result = perform_query($query, $dbLink);
+ } else {
+ $error .= " Sorry, $username does not have access to this service.";
+ $_SESSION["error"] = "$error";
+ }
} else {
// Not using LDAP or WebBasic, revert to local db authentication
if ($_POST["username"]) {
diff -Nur html/login.php htmlnew/login.php
--- html/login.php 2008-05-10 19:18:32.000000000 +0200
+++ htmlnew/login.php 2008-08-12 22:18:20.000000000 +0200
@@ -47,6 +47,33 @@
} else {
print "Error:$error";
}
+} elseif (defined('CERTAUTH_ENABLE') && (CERTAUTH_ENABLE == TRUE)) {
+ $_POST['username'] = $_SERVER['SSL_CLIENT_S_DN'];
+ $_POST['password'] = "nothing";
+ $_POST['authtype'] = "cert";
+
+ $error = login_check($_POST);
+ if (trim($error)=="") {
+ $_SESSION["member_id"] = login($_POST);
+ if ((stristr($_SESSION["member_id"], "Invalid") == TRUE) ||
+ (stristr($_SESSION["member_id"], "Sorry") == TRUE)) {
+ die($_SESSION["member_id"] ."<br><a href=" .INDEX_URL .">Return</a>");
+ }
+ // Cdukes: 3/20/08: Carry post variables through login
+ // Ref: http://code.google.com/p/php-syslog-ng/issues/detail?id=35
+ // Header("Location: " .INDEX_URL); // Redirect authenticated member
+ $destination = INDEX_URL;
+ // Remember search query across login
+ if (!empty($_POST['searchQuery']))
+ {
+ $destination .= '?' . ($_POST['searchQuery']);
+ }
+ Header("Location: " . $destination); // Redirect authenticated member
+ exit();
+ } else {
+ print "Error:$error";
+ }
+
} else {
?>
<html>ConfigurationYou need to configure apache and php-syslog-ng to get this working. Needed changes are explained below. Apache configurationFirst, you need to configure apache to accept certificates from only the CA or CAs you want user certificates to be issued by. You can even force the SSL connection with client certificates from these CAs only. Imagine you have your running php-syslog-ng in a url such as https://myvirtualhost/logs. In your virtualhost directory config, put this: SSLEngine On
# Next line is important for this to work
SSLOptions +StdEnvVars +OptRenegotiate
SSLCertificateFile /etc/apache2/ssl/server.pem
SSLCertificateKeyFile /etc/apache2/ssl/server.key
# Line below only needed if the CA signing apache server
# cert is not distributed with the browser software:
SSLCertificateChainFile /etc/apache2/ssl/serverca.pem
<Location /logs>
# CAs you want to use to issue certificates to users:
SSLCACertificateFile /etc/apache2/certs/validca.pem
# Here put 'require' to force client to provide certificate for SSL
# or 'optional' to allow but not forcing (in the later case, you would
# be able to access php-syslog-ng with fallback local user auth)
SSLVerifyClient require
</Location>Now, restart apache. It should ask you for a client certificate when accessing php-syslog-ng. php-syslog-ng database modificationCertificate DNs are often quite long, so it's advisable to extend the maximum length allowed for user names (not needed if you installed php-syslog-ng with version 2.9.8f or newer): alter table users modify username varchar(128) not null; alter table user_access modify username varchar(128) not null; Adding certificate-based users to php-syslog-ngYou have two ways to add them. Web GUIThis is the common way to add users, and works for usual internal php-syslog-ng authentication. You can use this method too for adding subject DNs from certificates as usernames. Please notice that a certificate serial number can also be used as username. The expected format is in hexadecimal form, without digit separator like ':' and all capital letters. Example: 6424DAC46826DC45. The only problem with this method is you have to enter a password, and thus this password could be used to authenticate using normal login instead of a certificate. You should also take into account that the regexp used for validating usernames won't work, so you should change this: "username" => "(^[A-Za-z_.@]{4,}\$)",for something like this to catch most variants: "username" => "(^[A-Za-z0-9_.@/ =-]{4,}\$)",Manual database insertionYou can insert subject DNs or certificate serial numbers manually into the database tables, just like this: insert into users values (username='/CN=some common name/GN=First Name/SN=Family Name/OU=IT department', pwhash='nothingthatworks'); php-syslog-ng configurationYou must enable support for certificate based authentication in config.php by setting CERTAUTH_ENABLE to TRUE. Add line below if you don't have it: define('CERTAUTH_ENABLE',TRUE);Certificate TIPS
openssl x509 -in certificatefile.pem -noout -text | grep Subject: openssl x509 -in certificatefile.pem -noout -text | grep -A 1 "Serial Number" openssl x509 -in certificatefile.der -inform DER -noout -text | grep Subject: |
I've implemented this into v2.9.8f, so if you have 2.9.8f or later, there is no need to patch, alter the db tables or add the config variable (you will need to turn it on in config.php though)
Hi Guys,
-Chris
Hi Guys,
mysql> describe users; +-----------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-----------+--------------+------+-----+---------+-------+ | username | varchar(128) | NO | PRI | NULL | | | pwhash | char(40) | YES | | NULL | | | sessionid | char(32) | YES | | NULL | | | exptime | datetime | YES | | NULL | | +-----------+--------------+------+-----+---------+-------+ 4 rows in set (0.00 sec)