TracNav menu
-
Core Features
- Configuration File Syntax
- Configuration Options
- Change Root
- Performance
- PerformanceFastCGI
- SSL
- Traffic Shaping
- Using SMP
-
Modules
- mod_accesslog
- mod_access
- mod_alias
- mod_auth
- mod_cache
- mod_cgi
- mod_cml
- mod_compress
- mod_deflate
- mod_dirlisting
- mod_evasive
- mod_evhost
- mod_expire
- mod_extforward
- mod_fastcgi
- mod_flv_streaming
- mod_geoip
- mod_magnet
- mod_mem_cache
- mod_mysql_vhost
- mod_proxy
- mod_redirect
- mod_rewrite
- mod_rrdtool
- mod_scgi
- mod_secdownload
- mod_setenv
- mod_simple_vhost
- mod_ssi
- mod_status
- mod_trigger_b4_dl
- mod_userdir
- mod_useronline
- mod_usertrack
- mod_webdav
-
Modules (1.5 only)
- mod_proxy_core
- mod_sql_vhost_core
- mod_uploadprogress
- mod_deflate
-
Internals
- FastCGI state-engine
- Plugin interface
- HTTP state-engine
-
Additional
- User written Modules
Using Authentication
Module: mod_auth
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:
for digest auth:
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. You can force most to use MD5 with:
$htpasswd -m <pwfile> <username>
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 PATH="/bin:/usr/bin:/usr/sbin:$PATH"
# 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
# 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.) :
# if you add or change
$ lightdigest -u USERNAME -r REALM_NAME -f PASSWORD_FILE_PATH
# if you want to remove use
$ lightdigest -d -u USERNAME
ldap
the ldap backend is performing the following steps to authenticate a user
- Init the LDAP connection
- Set Protocol version to LDAPv3
- If StartTLS if configured -> Configure CA certificate if supplied
- If StartTLS if configured -> Activate TLS using StartTLS
- If Bind DN is included -> Simple bind with Bind-DN and Bind-Password
- If there is no Bind-DN -> Simple bind anonymously
- Try up to two times a SUBTREE search of the base-DN with the filter applied.
- Retrieve the DN of the user matching the filter.
- 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
## debugging
# 0 for off, 1 for 'auth-ok' messages, 2 for verbose debugging
auth.debug = 0
## type of backend
# plain, htpasswd, ldap or htdigest
auth.backend = "htpasswd"
# filename of the password storage for
# plain
auth.backend.plain.userfile = "lighttpd-plain.user"
## for htpasswd
auth.backend.htpasswd.userfile = "/full/path/to/lighttpd-htpasswd.user"
## for htdigest
auth.backend.htdigest.userfile = "lighttpd-htdigest.user"
## for ldap
# the $ in auth.backend.ldap.filter is replaced by the
# '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=$)"
# if enabled, startTLS needs a valid (base64-encoded) CA
# certificate unless the certificate has been stored
# in a c_hashed directory and referenced in ldap.conf
auth.backend.ldap.starttls = "enable"
auth.backend.ldap.ca-file = "/etc/CAcertificate.pem"
# 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"
# If you want to allow empty passwords
# "disable" for requiring passwords, "enable" for allowing empty passwords
auth.backend.ldap.allow-empty-pw = "disable"
## restrictions
# set restrictions:
#
# ( <left-part-of-the-url> =>
# ( "method" => "digest"/"basic",
# "realm" => <realm>,
# "require" => "user=<username>" )
# )
#
# <realm> is a string to display in the dialog
# presented to the user and is also used for the
# digest-algorithm and has to match the realm in the
# 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"
)
)
# 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

