Benutzer-Werkzeuge

Webseiten-Werkzeuge


lighttpd

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen RevisionVorhergehende Überarbeitung
Nächste Überarbeitung
Vorhergehende Überarbeitung
lighttpd [2015-06-02 14:49:57] – [nur GET und POST] manfredlighttpd [2017-01-06 14:48:23] (aktuell) – [MySQL-Auth mit LighttpD] manfred
Zeile 1: Zeile 1:
 +====== Lighttpd ======
 +
 +  * [[http://www.lighttpd.net|Lighttpd]]
 +    * [[https://redmine.lighttpd.net/projects/1/wiki/Docs_ModSetEnv]] - Wiki
 +
 +
 +===== Sicherheit =====
 +
 +  * [[https://www.perpetual-beta.org/weblog/security-headers.html]]
 +
 +
 +==== HTTP Strict Transport Security (HSTS) ====
 +
 +  * [[https://support.servertastic.com/http-strict-transport-security-lighttpd]]
 +
 +To enable HTTP Strict Transport Security in lighttpd use the following config:
 +  server.modules += ( "mod_setenv" )
 +  $HTTP["scheme"] == "https" {
 +          setenv.add-response-header  = ( "Strict-Transport-Security" => "max-age=31536000")
 +  }
 +
 +The max-age value is in seconds. Use 31536000 for 12 months or 63072000 for 24 months.
 +
 +Adding includeSubdomains means that subdomains of the main domain should also be accessed using SSL.
 +
 +
 +==== Content Security Policy (CSP) ====
 +
 +  * [[http://www.html5rocks.com/en/tutorials/security/content-security-policy/]]
 +
 +Dieses Beispiel führt ein Upgrade der ''HTTP''-Verbindungen auf ''HTTPS'' durch (HSTS und CSP: ''/etc/lighttpd/lighttpd.conf''):
 +  server.modules += ( "mod_setenv" )
 +  $HTTP["scheme"] == "https" {
 +          setenv.add-response-header  = ( "Strict-Transport-Security" => "max-age=31536000",
 +                                          "Content-Security-Policy" => "default-src https: data: 'unsafe-inline' 'unsafe-eval' always; upgrade-insecure-requests" )
 +  }
 +
 +==== nur LTS 1.2 ====
 +
 +  * [[http://www.lighttpd.net/documentation/ssl.html]]
 +  * [[https://www.dfn.de/fileadmin/3Beratung/Betriebstagungen/bt60/3_BetterCrypto.org-T-Dussa.pdf]]
 +
 +SSL-Cipher auflisten:
 +  > openssl ciphers -V
 +  > openssl ciphers | tr -s ':' '\n'
 +  > openssl ciphers -V 'EECDH+aRSA+AES256:!SSLv3'
 +  > openssl ciphers -V 'EECDH+aRSA+AES256:ECDHE-RSA-AES128-GCM-SHA256:!SSLv3'
 +  > openssl ciphers -V 'EECDH+aRSA+AES256:ECDHE-RSA-AES128-GCM-SHA256'
 +  > openssl ciphers -V 'TLSv1+HIGH:!LOW:!3DES:!MD5:!RC4:!DSS:!PSK:!EXP:!SRP:!aNULL:!eNULL:!SSLv2:@STRENGTH'
 +
 +  > vi /etc/lighttpd/conf-enabled/10-ssl.conf
 +  ...
 +  ##
 +  ## Documentation: /usr/share/doc/lighttpd-doc/ssl.txt
 +  ##
 +  #### SSL engine
 +  $SERVER["socket"] == "0.0.0.0:443" {
 +          ssl.engine                          = "enable"
 +          ssl.pemfile                         = "/etc/lighttpd/ssl/domain.de.pem"
 +          ssl.ca-file                         = "/etc/lighttpd/ssl/intermediate.domain.de.crt"
 +          ssl.use-sslv2                       = "disable"
 +          ssl.use-sslv3                       = "disable"
 +          ssl.honor-cipher-order              = "enable"
 +          ssl.use-compression                 = "disable"
 +          ssl.cipher-list                     = "EECDH+aRSA+AES256:ECDHE-RSA-AES128-GCM-SHA256:!SSLv3"
 +          ssl.disable-client-renegotiation    = "enable"
 +  
 +          $HTTP["useragent"] =~ ".*MSIE (9|10)\..*" {
 +                  server.max-keep-alive-requests = 0
 +          }
 +  }
 +  ...
 +
 +
 +===== Datenübertragung =====
 +
 +
 +==== nur GET und POST ====
 +
 +viele HTML-Aufruf-Methoden können gefährlich sein, deshalb lassen wir mit diesem Teil nur "GET", "POST" und "HEAD" zu:
 +  > vi /etc/lighttpd/lighttpd.conf
 +  ...
 +  $HTTP["request-method"] !~ "^(GET|POST|HEAD)$" {
 +          url.access-deny = ("")
 +  }
 +  ...
 +
 +Das kann mit diesem SED-Kommando ganz leicht eingestellt werden:
 +  > sed -i 's/\$HTTP\["request-method"\] .*/$HTTP["request-method"] !~ "^(GET|POST|HEAD)$" {/' /etc/lighttpd/lighttpd.conf
 + 
 +
 +===== Logging =====
 +
 +
 +==== Debug-Level ====
 +
 +[[http://redmine.lighttpd.net/projects/1/wiki/DebugVariables]]
 +
 +um Fehler zu finden ist es oft gut, ins Log zu sehen, damit im Log auch genug zu sehen ist, muss **''debug.log-request-header''** eingeschaltet werden:
 +  > vi /etc/lighttpd/lighttpd.conf
 +  ...
 +  debug.log-request-header   = "enable"
 +  
 +  server.errorlog-use-syslog = "enable"
 +  #server.errorlog            = "/var/log/lighttpd/error.log"
 +  
 +  accesslog.format           = "premiumsim.de %V %h %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\""
 +  accesslog.use-syslog       = "enable"
 +  #accesslog.filename         = "/var/log/lighttpd/access.log"
 +  ...
 +
 +
 +===== MySQL-Auth mit LighttpD =====
 +
 +Leider gibt es für LighttpD kein Modul um die Passwortabfrage auf eine DB zu realisieren, wie man es vom Apache kennt. Um eine derartige Funktionalität in LighttpD umzusetzten, muss man ein entsprechendes LUA-Skript einbinden.
 +
 +  * [[https://redmine.lighttpd.net/projects/lighttpd/wiki/AbsoLUAtion#Do-basic-HTTP-Auth-against-a-MySQL-DBTable]]
 +
 +__Die Dateien, die Passwörter enthalten, dürfen nicht für die Welt lesbar sein!__
 +  > chown 33:33 /etc/lighttpd/sha512crypt.php /etc/lighttpd/mysql_auth.lua
 +  > chmod 0640 /etc/lighttpd/sha512crypt.php /etc/lighttpd/mysql_auth.lua
 +
 +  * [[https://redmine.lighttpd.net/projects/1/wiki/docs_configuration]]
 +
 +hier muß die IP ("''192.168.2.99''") des Web-Servers eingetragen werden:
 +<file lighttpd /etc/lighttpd/conf-enabled/20-mysql_auth.conf>
 +#
 +$HTTP["host"] =~ "192.168.2.99" {
 +                magnet.attract-physical-path-to = ( "/etc/lighttpd/mysql_auth.lua" )
 +}
 +</file>
 +
 +<file lua /etc/lighttpd/mysql_auth.lua>
 +-- vim: set ts=4 sw=4 sts=4 noai noet:
 +--[[
 +
 +    MySQL-Auth - IQ
 +
 +lighttpd-mod-magnet
 +lua-socket
 +lua-sql-mysql
 +
 +*************************** 1. row ***************************
 +      id: 1
 +   login: Fritz
 +password: a8e13417253337017fb29cbe1a647bba2d7dca95b232f70f782bd64da49855606d122e5715d6a63754d88d1ea3fe561af26260fedd7b2425044c7e565fa1dfa0
 +]]
 +
 +--[[
 +https://redmine.lighttpd.net/projects/lighttpd/wiki/AbsoLUAtion#Do-basic-HTTP-Auth-against-a-MySQL-DBTable
 +
 +Known Problems:
 +
 +    This Script is blocking!!! Lighttpd will hang, if there are MySQL connection problems.
 +    Additionally, a whole new MySQL Connection is created with every request! So you shouldn't use this on High-Traffic Sites.
 +    Passwords are stored plain in MySQL - well, easy to fix. Look for MySQL's PASSWORD function....
 +]]
 +
 +-- nur "/geheim.php" soll passwortgeschützt sein
 +if ( string.format('%s', lighty.env["uri.path"]) == "/geheim.php" ) then
 +
 +-- Force https
 +if (lighty.env["uri.scheme"] == "http") then
 +    lighty.header["Location"] = "https://" .. lighty.env["uri.authority"] .. lighty.env["request.uri"]
 +    return 302
 +end
 +
 +--[[
 +    Config Variables
 +]]
 +local dbConf = {}
 +dbConf.database = 'authdb'
 +dbConf.username = 'dbuser'
 +dbConf.password = 'geheim'
 +dbConf.hostname = '192.168.2.10'
 +dbConf.port = "3306"
 +--[[
 +dbConf.users_table = "dealer_logins" 
 +dbConf.col_user = "login"
 +dbConf.col_pass = "password"
 +]]
 +
 +--[[
 +    Requires
 +]]
 +
 +-- Debian package: liblua5.1-socket2
 +
 +-- required for Base64 De-/encoding. See: http://w3.impa.br/~diego/software/luasocket/home.html
 +require("mime")
 +
 +-- Debian package: liblua5.1-sql-mysql-2
 +
 +-- Lua Mysql Driver
 +luasql = require("luasql.mysql")
 +
 +--[[
 +    Function to send HTTP-Auth request
 +]]
 +
 +function doAuth()
 +    lighty.header["WWW-Authenticate"] = string.format('Basic realm="%s"', lighty.env["uri.authority"])
 +    return 401
 +end
 +
 +--[[
 +    Function to check Auth Creds against MySQL Database
 +]]
 +local env = assert(luasql.mysql())
 +local con = assert(env:connect (
 +        dbConf.database
 +        ,dbConf.username
 +        ,dbConf.password
 +        ,dbConf.hostname
 +        ,dbConf.port
 +))
 +
 +function checkAuthMySQL(user,pass)
 +        local res = con:execute(string.format([[
 +                SELECT login, password
 +                FROM `dealer_logins`
 +                WHERE `login` = '%s'
 +                AND `password` = '%s'
 +                ]], user, pass)
 +        )
 +
 +        -- Die Tabelle wir in ein Array gespeichert
 +        local row = res:fetch ({}, "a")
 +
 +        -- print(type(row))
 +
 +
 +        -- close everything
 +        -- res:close()  -- already closed because all the result set was consumed
 +        con:close()
 +        -- env:close()
 +
 +
 +        if (not row) then
 +                return false
 +        else
 +                lighty.req_env['REMOTE_USER'] = user
 +                return true
 +        end
 +end
 +
 +
 +-- MAIN
 +
 +--[[
 +    Check for Authorization Header
 +    and force Basic Auth if not set.
 +]]
 +
 +if (not lighty.request.Authorization) then
 +    return doAuth()
 +end
 +
 +--[[
 +    Header found: check string for "Basic" and base64 encoded username & password
 +    - upb = User Password Base64 encoded
 +]]
 +_, _, upb = string.find(lighty.request.Authorization, "^Basic%s+(.+)$")
 +up = mime.unb64(upb) -- Base64 Decode
 +_, _, username, password = string.find(up, "^(.+):(.+)$") -- split by ":" to get username and password supplied
 +
 +
 +-- =============================================================================
 +-- In der DB steht das Passwort nicht im klartext drin, sondern verschlüsselt
 +-- deshalb muss auch der Passwort-Hash und nicht das Passwort verglichen werden.
 +--
 +-- hier wird aus dem Passwort der Passwort-Hash generiert
 +--
 +-- /var/www/webauftritt/libs/WebServices/Ovp/Authentication/Encrypt.php
 +
 +local start = ("/usr/bin/php /etc/lighttpd/sha512crypt.php " .. password)
 +datei = assert (io.popen (start))
 +pwhash = datei:read ("*l") -- read one line
 +
 +-- =============================================================================
 +
 +if (not checkAuthMySQL(username, pwhash)) then
 +        return doAuth()
 +end
 +
 +
 +end
 +
 +-- return nothing to proceed normal operation
 +return
 +</file>
 +
 +Leider gibt es nur für eine SHA256-Verschlüsselung eine native LUA-Umsetzung.
 +Für SHA512 müssen wir uns eines externen Programmes (in diesem Fall ein PHP-Skript) bedienen.
 +
 +Der **Salz-hash** aus der Live-Umgebung => '<decrypt>U2FsdGVkX19AL/PUlfXxQQgDKgzZzAgiqTCFVCoKZUc=</decrypt>';
 +<file php /etc/lighttpd/sha512crypt.php>
 +<?php
 +$salt = 'Salz-hash';
 +echo hash('sha512', $salt . $argv[1]);
 +?>
 +</file>