Mod auth » History » Revision 25
Revision 24 (Anonymous, 2008-02-20 14:32) → Revision 25/92 (Anonymous, 2008-02-27 23:02)
[[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 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 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 ============= :: ## 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", "htdigest"/"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 See Also ======== }}} * [wiki:HowToAuthenticationFromMultipleFiles Authenticate from Multiple Password Files]