Kurs: IT-Security
3.x Sicherheit von serverseitigem Skripting

Das Common Gateway Interface - CGI (Sequenzdoku 5.2)
3.1
  • Server Side Includes konfigurieren
    Erlaube im Verzeichnis /kurs1/sub1/ die Ausführung von Server Side Includes in *.shtml Dateien (./sub1/welcome.shtml)
  • Scripte in Perl, Shell, (Ruby, Python, Lisp, usw) konfigurieren
    Teste die Ausführung von CGIs mit den vorhandenen Perl- und Shell-Scripten
    • Kopiere zunächst die Scripte aus dem Userordner /home/skurs/public_html/cgi-bin/ in den Systemordner /srv/www/cgi-bin/
    • Das (in den System cgi-bin-Ordner) kopierte Perl-Script, sollte dort auch ohne Konfigurationsänderungen ausführbar sein
      - /cgi-bin/envirmnt1.pl (im Verzeichnis /srv/www/cgi-bin/)
    • Das User-Perl-Script sollt nun auch im User-Ordner (nach einer Scripting Konfiguration) eine ähnliche Ausgabe erzeugen
      - /~skurs/cgi-bin/envirmnt1.pl (im Verzeichnis /home/skurs/public_html/cgi-bin/)
    • Passe dazu folgende Direktiven aus dem HowTo "Dynamic Content with CGI" (https://httpd.apache.org/docs/2.4/howto/cgi.html) an
      ScriptAlias ... ... # wie Alias und ein SetHandler (spart eine Zeile)
      AddHandler ... ...  # Scriptzuordnung über Namenserweiterung[en] 
      SetHandler ...      # Scriptzuordnung für einen kompl. Ordner
      
      Options ... # Scripting Ein/Aus
    • Welche Einstellung legen fest wo oder mit welcher Extension Scriptdateien ausgeführt werden?
      Welche Überraschungen bietet der Apache bei Scripten in Userordnern (/~*) ?
      siehe: https://httpd.apache.org/docs/2.4/suexec.html

  • Übermittlung von Formulardaten (über das Common Gateway Interface)
    Sende über folgende HTML-Formulare (mit Get und Post) Daten zum CGI/Perl-Script ./cgi-bin/getpost.pl
    clientseitiger HTML-Quelltext:
    
    <form method="get" action="../cgi-bin/getpost.pl"> <input type="text" name="login" size="27"> <input type="submit" value="ab damit"> </form>
    Dieses (Perl-Script) sendet eine einfache Antwortseite zurück?
    serverseitiger Perl-Quelltext:
    
    #!/usr/bin/perl print "Content-type: text/html\n\n"; #-----POST?----- read(STDIN, $ENV{"QUERY_STRING"}, $ENV{"CONTENT_LENGTH"}); print "<h1>".$ENV{"QUERY_STRING"}."</h1>";
    • Wie gelangen (bei GET/POST) die Formulardaten zum Server?
    • Was wird von den Perl-Scripten noch vor dem HTML-Kode (im Header) erzeugt?

  • PHP-Scripte konfigurieren
    Teste die aktuelle (mod_php7?) PHP-Konfiguration über die Dateien im ./php/ Ordner.
    Optional: befindet sich im Paket php-doc eine PHP Doku (/usr/share/doc/packages/php-doc/)
    Optimiere die Sicherheitseinstellungen des Interpreters:
    - Per Default sollte der Interpreter in der php.ini Datei abgeschaltet und ein system() Aufruf verboten sein
    - Nur für den Kunden skurs wird der Interpreter über php_admin_* eingeschaltet
    Man kann die Konfiguration auch mittels Apache-Direktiven in der httpd.conf oder den .htaccess-Dateien ändern. Für .htaccess benötigt man aber "AllowOverride Options"- oder "AllowOverride All"-Privilegien.

    Die verfügbaren php_* Direktiven zeigt der Befehl "apachectl -L".
    Mit "php_value" können Vorgaben der php.ini dynamisch geändert werden
    Syntax: php_value Name Wert 
    Php_value kann aber nur für Direktiven mit den Typen PHP_INI_ALL und PHP_INI_PERDIR (siehe: http://de2.php.net/manual/de/ini.list.php) verwendet werden. Um einen vorher gesetzten Wert zu löschen, verwenden Sie none als Wert.

    Hinweis: Verwenden Sie php_value nicht, um boolesche Werte zu setzen.
    Hierfür steht php_flag zur Verfügung. Es setzt boolesche Konfigurationsdirektiven und kann ebenfalls nur für Direktiven vom Type PHP_INI_ALL und PHP_INI_PERDIR verwendet werden
    Syntax: php_flag Name on|off bzw. 1/0 

    Sollen Vorgaben nicht über .htaccess-Dateien oder mit ini_set() veränderbar sein, können Werte mit php_admin_value (logischerweise nur in der httpd.conf) gesetzt werden. Auch hier können zuvor gesetzte Werte mit none gelöscht werden.
    Syntax: php_admin_value Name Wert 
    bzw. für boolesche Konfigurationsdirektiven
    Syntax: php_admin_flag Name on|off bzw. 1/0 

    Optional:
    - Als mod_php Alternative (für MPM-worker/event) steht noch mod_fcgid (wie folgt) ...
    1. apache2-event gegen apache2-prefork tauschen
       zypper in apache2-event ; zypper rm apache2-prefork
    2. PAKET -> apache2-mod_fcgid und php7-fastcgi installieren 
       zypper in apache2-mod_fcgid php7-fastcgi
    3. Das Modul fcgid laden
       a2enmod fcgid
    4. Anpassung der /etc/apache2/conf.d/mod_fcgid.conf
       <FilesMatch "\.php$">
         AddHandler fcgid-script .php
         Options +ExecCGI
         FcgidWrapper /srv/www/cgi-bin/php .php
       </FilesMatch>
    und die Variante mod_fastcgi zur Verfügung.
    Hierbei reicht der Apache über einen TCP-Port oder einen Unix Socket die Anfrage an ein (anderes) PHP-FPM-System weiter.
  • Java-Server-Pages konfigurieren
    Dazu sollten folgende Tomcat-Pakete installiert sein:
    - tomcat - Apache Servlet/JSP Engine, RI for Servlet 3.0/JSP 2.2 API
    - tomcat-webapps - mit Beispielseiten in /srv/tomcat/webapps/examples/
  • Den Tomcat starten:
    - Ein "ss -ta" (ehemals netstat -tln) zeigt, ob die benötigten Portsadressen "frei" sind
    systemctl restart tomcat.service (opt. systemctl enable tomcat.service) 
    Testadressen: http://localhost:8080/, http://localhost:8080/examples/
  • Nun soll der Apache als "reverser Proxy" die Beispielseiten des Tomcat (auf Port 80) ausliefern.
    Die Konfiguration ist vergleichbar mit einem reversen http-Proxy, aber der Apache verwendet zum Tomcat das ajp:// Protokoll.
    Apache-Manual-Infos: https://httpd.apache.org/docs/2.4/mod/mod_proxy_ajp.html
    #Simple Reverse Proxy
    ProxyPass /app ajp://backend.example.com:8009/app 
    Lade dazu die notwendigen Module (proxy, proxy_ajp) und leite die Zugriffe von /examples auf den Tomcat um
  • Optional kann auch für WebSocket-Anwendungen (/examples/websocket/drawboard.xhtml und dem snake) eine "ws://" Weiterleitung konfiguriert werden. Dabei müssen die ProxyPass-Direktiven für "ws:" vor den "http:" bzw. "ajp:" Angaben stehen.
    Apache-Manual-Infos: https://httpd.apache.org/docs/2.4/mod/mod_proxy_wstunnel.html
    #Simple Reverse Proxy
    ProxyPass "/Path2drawboard" "ws://backend.example.com:8080/Path2drawboard"
    ProxyPass "/Path2snake"     "ws://backend.example.com:8080/Path2snake"
    #Nun noch "einer" der bisherigen Weiterleitungen (http ODER ajp)
    ProxyPass /app http://backend.example.com:8080/app
    ProxyPass /app ajp://backend.example.com:8009/app
    
    Lade dazu benötigten Module (proxy_http und proxy_wstunnel)
  • Optional kann der Apache als "Lastverteiler" die Zugriffe auf mehrerer Tomcat-Server verteilen.
    Apache-Manual-Infos: https://httpd.apache.org/docs/2.4/mod/mod_proxy_ajp.html
    #Balancer Reverse Proxy
    <Proxy "balancer://cluster">
        BalancerMember "ajp://app1.example.com:8009" loadfactor=1
        BalancerMember "ajp://app2.example.com:8009" loadfactor=2
        ProxySet lbmethod=bytraffic
    </Proxy>
    ProxyPass "/app" "balancer://cluster/app"
    
    Lade dazu benötigten Module (proxy_balancer, lbmethod_bytraffic und slotmem_shm)

Sicherheit von virtuellen Hosts (Sequenzdoku 6.1)
3.2
  • Richte nun für die Kunden 1 bis 4 namens-basierte virtuelle-Hosts (www.kunde1.de) ein und ordne diesen unter /srv/www/* Homeordner zu
    <VirtualHost *:80>
     DocumentRoot /srv/www/htdocs 
     ServerName www.provider.de
    </VirtualHost>
    - Trage dabei (als Ersatz für einen DNS-Eintrag) den FQDN in der /etc/hosts ein
    - Optional kann eine (Script-)Vorlage unter ftp://server/kurs/vhost-muster/ verwendet werden

Meinolf Mühlenjost 2022