Project

General

Profile

Actions

Docs ModAuth » History » Revision 21

« Previous | Revision 21/70 (diff) | Next »
joungkyun, 2007-10-12 12:01
add lightdigest code


TracNav(DocsToc) {{{
#!rst ====================
Using Authentication ====================

----------------
Module: mod_auth
----------------

.. meta::
:keywords: lighttpd, authentication

.. contents:: Table of Contents

Description ===========

Supported Methods
-----------------

lighttpd supports both authentication methods described by
RFC 2617:

basic
`````

The Basic method transfers the username and the password in
cleartext over the network (base64 encoded) and might result
in security problems if not used in conjunction with a crypted
channel between client and server.

digest
``````

The Digest method only transfers a hashed value over the
network which performs a lot of work to harden the
authentication process in insecure networks.

Backends
--------

Depending on the method lighttpd provides various way to store
the credentials used for the authentication.

for basic auth:

- plain_
- htpasswd_
- htdigest_
- ldap_

for digest auth:

- plain_
- htdigest_

plain
`````

A file which contains username and the cleartext password
seperated by a colon. Each entry is terminated by a single
newline.::

e.g.:
agent007:secret

htpasswd
````````

A file which contains username and the crypt()'ed password
seperated by a colon. Each entry is terminated by a single
newline. ::

e.g.:
agent007:XWY5JwrAVBXsQ

You can use htpasswd from the apache distribution to manage
those files. ::

$ htpasswd lighttpd.user.htpasswd agent007

Keep in mind that not all versions of htpasswd default to use
Apache's modified MD5 algorithm for passwords, which is
required by lighttpd.

htdigest
````````

A file which contains username, realm and the md5()'ed
password seperated by a colon. Each entry is terminated
by a single newline. ::

e.g.:
agent007:download area:8364d0044ef57b3defcfa141e8f77b65

You can use htdigest from the apache distribution to manage
those files. ::

$ htdigest lighttpd.user.htdigest 'download area' agent007

Using md5sum can also generate the password-hash: ::

#!/bin/sh
user=$1
realm=$2
pass=$3
hash=`echo -n "$user:$realm:$pass" | md5sum | cut -b -32`
echo "$user:$realm:$hash"

To use it (spaces between arguments!) :

$ htdigest.sh 'agent007' 'download area' 'secret'
agent007:download area:8364d0044ef57b3defcfa141e8f77b65

follow code is improved when you use for service: ::

#!/bin/sh
export PAHT="/bin:/usr/bin:/usr/sbin:$PATH"
  1. when input ctrl-c, remove lockfile and exit
    trap '[ $lockstart -eq 1 ] && unlock $pfile && exit 0 || exit 0' INT
pfile="/etc/lighttpd/conf.d/lighttpd.user" 
lockstart=0
remove=0
errmsg() {
echo "$1" > /dev/stderr
}
user_check() {
check_user=$1
grep "^${check_user}:" ${pfile} >& /dev/null
return $?
}
lock() {
lockfile="$1"
lockfile="${lockfile}.lock"
[ -f "${lockfile}" ] && {
errmsg "WARNING: lock file ${lockfile} is already exists"
errmsg " Wait minites for end of previous working ..."
}
while [ -f "${lockfile}" ]; do echo >& /dev/null ; done
touch ${lockfile}
lockstart=1
}
unlock() {
lockfile="$1"
lockfile="${lockfile}.lock"
[ -f "${lockfile}" ] && rm -f ${lockfile} && lockstart=0
}
usage() {
errmsg
errmsg "lightdigest: lighttpd htdigest password generation program"
errmsg "Scripted by JoungKyun.Kim <http://oops.org>"
errmsg
errmsg "Usage: $0 -[hd] -u user -p pass -r realm [-f password_file]"
errmsg "Options:"
errmsg " -h print this help messages"
errmsg " -u user username"
errmsg " -p pass password"
errmsg " -r realm realm name"
errmsg " -f filename password file [default: /etc/lighttpd/conf.d/lighttpd.user"
errmsg " -d remove user"
errmsg
[ $lockstart -eq 1 ] && rm -f ${pfile}.lock
exit 1
}
opts=$(getopt df:hp:r:u: $*)
[ $? != 0 ] && usage
set -- ${opts}
for i
do
case "$i" in
d) remove=1; shift;;
-f) pfile="$2"; shift; shift;;
-p) pass="$2"; shift; shift;;
-r) realm="$2"; shift; shift;;
-u) user="$2"; shift; shift;;
-
) shift; break;
esac
done
#echo $user
#echo $realm
#echo $pass
#echo $pfile
#echo $remove
[ -z "$user" ] && errmsg "ERROR: User is none!!" && usage
[ ${remove} -eq 0 -a -z "${realm}" ] && errmsg "ERROR: Realm is none!!" && usage
if [ -z "${pass}" -a ${remove} -eq 0 ]; then
echo -n "Input new password : "
read newpass
echo -n "Reinput password for confirm : "
read renewpass
if [ "${newpass}" != "${renewpass}" ]; then
errmsg "ERROR: Password is not match"
exit 1
fi
pass=${newpass}
fi
lock ${pfile}
if [ ${remove} -eq 0 ]; then
    # User Add Mode
hash=$(echo -n "${user}:${realm}:${pass}" | md5sum | cut -b -32)
user_check ${user}
already=$?
[ -f "${pfile}" ] && cp -af ${pfile} ${pfile}.bak
if [ ${already} -eq 0 ]; then # already exists
perl -pi -e "s/^${user}:.*$/${user}:${realm}:${hash}/g" ${pfile}
else # add new user
echo "${user}:${realm}:${hash}" >> ${pfile}
fi
else
  1. User Remove Mode
    tmp_htdigest="/tmp/lighttpd-htdiges.tmp.$$"
    cp -af ${pfile} ${pfile}.bak
    grep -v "^${user}:" ${pfile} > ${tmp_htdigest}
    mv -f ${tmp_htdigest} ${pfile}
    fi
unlock ${pfile}
exit 0

To use it (don't use realm value! getopt of some bash version has bug.) :

  1. if you add or change
$ lightdigest -u USERNAME -r REAML_NAME -f PASSWORD_FILE_PATH
  1. if you want to remove use
$ lightdigest -d -u USERNAME

ldap
````

the ldap backend is performing the following steps
to authenticate a user

1. Init the LDAP connection
2. Set Protocol version to LDAPv3
3. If StartTLS if configured -> Configure CA certificate if supplied
4. If StartTLS if configured -> Activate TLS using StartTLS
5. If Bind DN is included -> Simple bind with Bind-DN and Bind-Password
6. If there is no Bind-DN -> Simple bind anonymously
7. Try up to two times a SUBTREE search of the base-DN with the filter applied.
8. Retrieve the DN of the user matching the filter.
9. Finally, re-init the connection (following the steps above), this time using the DN found using the filter and the password supplied by the user.

if all 9 steps are performed without any error the user is
authenticated

Configuration =============

::

  1. debugging
  1. 0 for off, 1 for 'auth-ok' messages, 2 for verbose debugging
    auth.debug = 0
  1. type of backend
  1. plain, htpasswd, ldap or htdigest
    auth.backend = "htpasswd"
  1. filename of the password storage for
  2. plain
    auth.backend.plain.userfile = "lighttpd-plain.user"
  1. for htpasswd
    auth.backend.htpasswd.userfile = "/full/path/to/lighttpd-htpasswd.user"
  1. for htdigest
    auth.backend.htdigest.userfile = "lighttpd-htdigest.user"
  1. for ldap
  1. the $ in auth.backend.ldap.filter is replaced by the
  2. 'username' from the login dialog
    auth.backend.ldap.hostname = "localhost"
    auth.backend.ldap.base-dn = "dc=my-domain,dc=com"
    auth.backend.ldap.filter = "(uid=$)"
  3. if enabled, startTLS needs a valid (base64-encoded) CA
  4. certificate unless the certificate has been stored
  5. in a c_hashed directory and referenced in ldap.conf
    auth.backend.ldap.starttls = "enable"
    auth.backend.ldap.ca-file = "/etc/CAcertificate.pem"
  6. If you need to use a custom bind to access the server
    auth.backend.ldap.bind-dn = "uid=admin,dc=my-domain,dc=com"
    auth.backend.ldap.bind-pw = "mysecret"
  7. If you want to allow empty passwords
  8. 0 for requiring passwords, 1 for allowing empty passwords
    auth.backend.ldap.allow-empty-pw = 0
  1. restrictions
  1. set restrictions: #
  2. ( <left-part-of-the-url> =>
  3. ( "method" => "htdigest"/"basic",
  4. "realm" => <realm>,
  5. "require" => "user=<username>" )
  6. ) #
  7. <realm> is a string to display in the dialog
  8. presented to the user and is also used for the
  9. digest-algorithm and has to match the realm in the
  10. htdigest file (if used) #
auth.require = ( "/download/" => 
( # method must be either basic or digest
"method" => "digest",
"realm" => "download archiv",
"require" => "user=agent007|user=agent008"
),
"/server-info" =>
(
"method" => "digest",
"realm" => "download archiv",
"require" => "valid-user"
)
)
  1. Or, using regular expressions:
    $HTTP["url"] =~ "^/download|^/server-info" {
    auth.require = ( "" => (
    "method" => "digest",
    "realm" => "download archiv",
    "require" => "user=agent007|user=agent008"
    )
    )
    }

Limitations ============

- The implementation of digest method is currently not
completely compliant with the standard as it still allows
a replay attack.

- LDAP authentication only allows alphanumeric uid's that
do not contain punctuations. i.e.) john.doe will come
up as "ldap: invalid character (a-zA-Z0-9 allowed) in username: john.doe"

- There seems to be no reasonable logging of failed login attempts yet

See Also ========
}}}

  • [wiki:HowToAuthenticationFromMultipleFiles Authenticate from Multiple Password Files]

Updated by joungkyun about 13 years ago · 21 revisions