Zum Inhalt springen

10. FastCGI-Anwendungen

Einrichtung von FastCGI-Anwendungen, Parameter, Beispiele und Einschränkungen

HAProxy kann HTTP-Anfragen an FastCGI-Anwendungen mit der Rolle Responder senden. Diese Funktion wurde in HAProxy 2.1 eingeführt. Dazu müssen die Server für das FastCGI-Protokoll konfiguriert sein, mit dem Schlüsselwort “proto fcgi” in der Serverzeile. Außerdem muss eine FastCGI-Anwendung konfiguriert und von dem Backend verwendet werden, das diese Server verwaltet, mit dem Schlüsselwort “use-fcgi-app” im Proxy-Abschnitt. Es können mehrere FastCGI-Anwendungen definiert werden, aber ein Backend kann jeweils nur eine davon verwenden.

HAProxy implementiert alle Funktionen der FastCGI-Spezifikation für Responder-Anwendungen. Insbesondere können mehrere Anfragen über eine einzelne Verbindung gemultiplext werden.

10.1. Einrichtung

10.1.1. Abschnitt fcgi-app

fcgi-app <name>

fcgi-app <name>

Deklariert eine FastCGI-Anwendung namens <name>. Damit sie gültig ist, muss mindestens das Dokumentwurzelverzeichnis definiert sein.

acl <aclname> <criterion> [flags] [operator] <value> ...

acl <aclname> <criterion> [flags] [operator] <value> ...

Deklariert oder ergänzt eine Zugriffsliste.

Einzelheiten zur Verwendung von ACL finden Sie beim Schlüsselwort “acl” in Abschnitt 4.2 und in Abschnitt 7 . Für eine FastCGI-Anwendung definierte ACLs sind privat. Sie können weder von anderen Anwendungen noch von Proxys verwendet werden. Ebenso kann eine FastCGI-Anwendung keine ACLs verwenden, die in einem anderen Abschnitt definiert wurden. Vordefinierte ACLs stehen jedoch zur Verfügung.

docroot <path>

docroot <path>

Definiert das Dokumentwurzelverzeichnis auf dem entfernten Host. <path> wird verwendet, um den Standardwert der FastCGI-Parameter SCRIPT_FILENAME und PATH_TRANSLATED zu bilden. Diese Einstellung ist erforderlich.

index <script-name>

index <script-name>

Definiert den Skriptnamen, der an eine mit einem Schrägstrich ("/") endende URI angehängt wird, um den Standardwert des FastCGI-Parameters SCRIPT_NAME zu setzen. Diese Einstellung ist optional.

Beispiel:

index index.php

log-stderr global

log-stderr global
log-stderr <target> [len <length>] [format <format>]
    [sample <ranges>:<sample_size>] <facility> [<level> [<minlevel>]]

Aktiviert die Protokollierung von STDERR-Meldungen der FastCGI-Anwendung.

Einzelheiten finden Sie beim Schlüsselwort “log” in Abschnitt 4.2 . Diese Einstellung ist optional. Standardmäßig werden STDERR-Meldungen ignoriert.

pass-header <name> [ { if | unless } <condition> ]

pass-header <name> [ { if | unless } <condition> ]

Gibt den Namen eines Anfrageheaders an, der an die FastCGI-Anwendung übergeben werden soll. Optional kann eine ACL-basierte Bedingung folgen; in diesem Fall wird die Direktive nur ausgewertet, wenn die Bedingung wahr ist.

Die meisten Anfrageheader stehen der FastCGI-Anwendung bereits mit dem Präfix “HTTP_” zur Verfügung. Diese Direktive ist daher nur nötig, um bewusst ausgelassene Header zu übergeben. Derzeit werden die Header “Authorization”, “Proxy-Authorization” sowie Hop-by-Hop-Header ausgelassen.

Die Header “Content-type” und “Content-length” werden niemals an die FastCGI-Anwendung übergeben, da sie bereits in Parameter umgewandelt werden.

path-info <regex>

path-info <regex>

Definiert einen regulären Ausdruck, um den Skriptnamen und die Pfadinformation aus dem URL-dekodierten Pfad zu extrahieren. <regex> kann dazu zwei Erfassungsgruppen enthalten: die erste für den Skriptnamen, die zweite für die Pfadinformation. Die erste ist erforderlich, die zweite optional. So lässt sich der Skriptname aus dem Pfad extrahieren und die Pfadinformation ignorieren. Diese Einstellung ist optional. Ist sie nicht definiert, wird kein Mustervergleich auf dem Pfad ausgeführt, und die FastCGI-Parameter PATH_INFO und PATH_TRANSLATED werden nicht gefüllt.

Wenn dieser reguläre Ausdruck definiert ist, sind Zeilenumbruch- und Nullzeichen im URL-dekodierten Pfad aus Sicherheitsgründen verboten. Andernfalls würde der Mustervergleich aufgrund einer Einschränkung bei der Ausführung regulärer Ausdrücke in HAProxy immer fehlschlagen. Wird eines dieser beiden Zeichen im URL-dekodierten Pfad gefunden, wird deshalb ein Fehler an den Client zurückgegeben. Hier gilt das Prinzip der geringsten Überraschung.

Beispiel:

path-info ^(/.+\.php)(/.*)?$ # both script-name and path-info may be set
path-info ^(/.+\.php)        # the path-info is ignored

option get-values

option get-values
no option get-values

Aktiviert oder deaktiviert den Abruf von Variablen zur Verbindungsverwaltung.

HAProxy kann beim Verbindungsaufbau den Datensatz FCGI_GET_VALUES senden, um die Werte der folgenden Variablen abzurufen:

* FCGI_MAX_REQS     Die maximale Anzahl gleichzeitiger Anfragen, die diese
                    Anwendung akzeptiert.

* FCGI_MPXS_CONNS   "0", wenn diese Anwendung kein Verbindungsmultiplexing
                    unterstützt, andernfalls "1".

Einige FastCGI-Anwendungen unterstützen diese Funktion nicht. Andere schließen die Verbindung unmittelbar nach dem Senden ihrer Antwort. Daher ist diese Option standardmäßig deaktiviert.

Die maximale Anzahl gleichzeitiger Anfragen, die eine FastCGI-Anwendung akzeptiert, ist eine verbindungsbezogene Variable. Sie begrenzt nur die Anzahl der Datenströme pro Verbindung. Soll die Gesamtlast der Anwendung begrenzt werden, müssen die Serverparameter “maxconn” und “pool-max-conn” gesetzt werden. Unterstützt eine Anwendung kein Verbindungsmultiplexing, wird die maximale Anzahl gleichzeitiger Anfragen außerdem automatisch auf 1 gesetzt.

option keep-conn

option keep-conn
no option keep-conn

Weist die FastCGI-Anwendung an, die Verbindung nach dem Senden einer Antwort offen zu halten oder zu schließen.

Ist diese Option deaktiviert, schließt die FastCGI-Anwendung die Verbindung nach der Antwort auf diese Anfrage. Standardmäßig ist die Option aktiviert.

option max-reqs <reqs>

option max-reqs <reqs>

Definiert die maximale Anzahl gleichzeitiger Anfragen, die diese Anwendung akzeptiert.

Diese Option kann überschrieben werden, wenn die Variable FCGI_MAX_REQS beim Verbindungsaufbau abgerufen wird. Unterstützt die Anwendung kein Verbindungsmultiplexing, wird die Option zudem ignoriert. Der Standardwert ist 1.

option mpxs-conns

option mpxs-conns
no option mpxs-conns

Aktiviert oder deaktiviert die Unterstützung für Verbindungsmultiplexing.

Diese Option kann überschrieben werden, wenn die Variable FCGI_MPXS_CONNS beim Verbindungsaufbau abgerufen wird. Sie ist standardmäßig deaktiviert.

set-param <name> <fmt> [ { if | unless } <condition> ]

set-param <name> <fmt> [ { if | unless } <condition> ]

Setzt einen FastCGI-Parameter, der an diese Anwendung übergeben werden soll. Sein durch <fmt> definierter Wert muss den Regeln für benutzerdefinierte Protokollformate entsprechen; siehe Abschnitt 8.2.6 „Benutzerdefiniertes Protokollformat“. Optional kann eine ACL-basierte Bedingung folgen; in diesem Fall wird die Direktive nur ausgewertet, wenn die Bedingung wahr ist.

Mit dieser Direktive lassen sich die Werte der standardmäßigen FastCGI-Parameter überschreiben. Ergibt die Auswertung des Werts eine leere Zeichenfolge, wird die Regel ignoriert. Diese Direktiven werden in der Reihenfolge ihrer Deklaration ausgewertet.

Beispiel:

# PHP only, required if PHP was built with --enable-force-cgi-redirect
set-param REDIRECT_STATUS 200

set-param PHP_AUTH_DIGEST %[req.hdr(Authorization)]

10.1.2. Proxy-Abschnitt

use-fcgi-app <name> Definiert die vom Backend zu verwendende FastCGI-Anwendung.

Argumente:

<name>    ist der Name der zu verwendenden FastCGI-Anwendung.

Dieses Schlüsselwort steht nur für HTTP-Proxys mit Backend-Funktion und mindestens einem FastCGI-Server zur Verfügung. FastCGI-Server können zwar mit HTTP-Servern kombiniert werden, dies wird jedoch ohne triftigen Grund nicht empfohlen; Einzelheiten zu den Einschränkungen finden Sie in Abschnitt 10.3 . Pro Backend kann jeweils nur eine Anwendung definiert werden.

Sobald für ein Backend eine FastCGI-Anwendung referenziert wird, kann je nach Konfiguration bestimmte Verarbeitung stattfinden, auch wenn die Anfrage nicht an einen FastCGI-Server gesendet wird. Regeln zum Setzen von Parametern oder zum Übergeben von Headern an eine Anwendung werden ausgewertet.

10.1.3. Beispiel

frontend front-http
    mode http
    bind *:80

    use_backend back-dynamic if { path_reg ^/.+\.php(/.*)?$ }
    default_backend back-static

backend back-static
    mode http
    server www A.B.C.D:80

backend back-dynamic
    mode http
    use-fcgi-app php-fpm
    server php-fpm A.B.C.D:9000 proto fcgi

fcgi-app php-fpm
    log-stderr global
    option keep-conn

    docroot /var/www/my-app
    index index.php
    path-info ^(/.+\.php)(/.*)?$

10.2. Standardparameter

Eine FastCGI-Anwendung mit der Rolle Responder erfüllt denselben Zweck wie ein CGI/1.1-Programm. Laut CGI/1.1-Spezifikation (RFC3875) müssen mehrere Variablen an das Skript übergeben werden. HAProxy setzt daher diese sowie einige weitere Variablen, die FastCGI-Anwendungen üblicherweise verwenden. Alle diese Variablen können überschrieben werden, allerdings mit Vorsicht.

  +-------------------+--------------------------------------------------------------------------------+
  | AUTH_TYPE         | Identifiziert den gegebenenfalls von HAProxy zur Authentifizierung des         |
  |                   | Benutzers verwendeten Mechanismus. Konkret wird nur der                        |
  |                   | Authentifizierungsmechanismus BASIC unterstützt.                               |
  |                   |                                                                                |
  +-------------------+--------------------------------------------------------------------------------+
  | CONTENT_LENGTH    | Enthält die Größe des an die Anfrage angehängten Nachrichteninhalts. Es werden |
  |                   | daher nur Anfragen mit bekannter Größe als gültig betrachtet und an die        |
  |                   | Anwendung gesendet.                                                            |
  |                   |                                                                                |
  +-------------------+--------------------------------------------------------------------------------+
  | CONTENT_TYPE      | Enthält den Typ des an die Anfrage angehängten Nachrichteninhalts. Dieser      |
  |                   | Parameter kann ungesetzt sein.                                                 |
  |                   |                                                                                |
  +-------------------+--------------------------------------------------------------------------------+
  | DOCUMENT_ROOT     | Enthält das Dokumentwurzelverzeichnis auf dem entfernten Host, unter dem das   |
  |                   | Skript ausgeführt werden sollte, wie in der Anwendungskonfiguration definiert. |
  |                   |                                                                                |
  +-------------------+--------------------------------------------------------------------------------+
  | GATEWAY_INTERFACE | Enthält den CGI-Dialekt, den HAProxy zur Kommunikation mit der                 |
  |                   | FastCGI-Anwendung verwendet. Konkret wird er auf "CGI/1.1" gesetzt.            |
  |                   |                                                                                |
  +-------------------+--------------------------------------------------------------------------------+
  | PATH_INFO         | Enthält den Teil der URI-Pfadhierarchie, der auf den das Skript selbst         |
  |                   | identifizierenden Teil folgt. Damit dieser Parameter gesetzt wird, muss die    |
  |                   | Direktive "path-info" definiert sein.                                          |
  |                   |                                                                                |
  +-------------------+--------------------------------------------------------------------------------+
  | PATH_TRANSLATED   | Wenn PATH_INFO gesetzt ist, enthält dieser Parameter dessen übersetzte         |
  |                   | Fassung. Sie ist die Verkettung von DOCUMENT_ROOT und PATH_INFO. Ist PATH_INFO |
  |                   | nicht gesetzt, wird auch dieser Parameter nicht gesetzt.                       |
  |                   |                                                                                |
  +-------------------+--------------------------------------------------------------------------------+
  | QUERY_STRING      | Enthält die Abfragezeichenfolge der Anfrage. Dieser Parameter kann ungesetzt   |
  |                   | sein.                                                                          |
  |                   |                                                                                |
  +-------------------+--------------------------------------------------------------------------------+
  | REMOTE_ADDR       | Enthält die Netzwerkadresse des Clients, der die Anfrage sendet.               |
  |                   |                                                                                |
  +-------------------+--------------------------------------------------------------------------------+
  | REMOTE_USER       | Enthält die Zeichenfolge zur Benutzeridentifikation, die der Client im Rahmen  |
  |                   | der Benutzerauthentifizierung übermittelt hat.                                 |
  |                   |                                                                                |
  +-------------------+--------------------------------------------------------------------------------+
  | REQUEST_METHOD    | Enthält die Methode, die das Skript zur Verarbeitung der Anfrage verwenden     |
  |                   | sollte.                                                                        |
  |                   |                                                                                |
  +-------------------+--------------------------------------------------------------------------------+
  | REQUEST_URI       | Enthält die URI der Anfrage.                                                   |
  |                   |                                                                                |
  +-------------------+--------------------------------------------------------------------------------+
  | SCRIPT_FILENAME   | Enthält den absoluten Pfadnamen des Skripts. Er ist die Verkettung von         |
  |                   | DOCUMENT_ROOT und SCRIPT_NAME.                                                 |
  |                   |                                                                                |
  +-------------------+--------------------------------------------------------------------------------+
  | SCRIPT_NAME       | Enthält den Namen des Skripts. Ist die Direktive "path-info" definiert, ist    |
  |                   | dies der erste Teil der URI-Pfadhierarchie bis einschließlich des              |
  |                   | Skriptnamens. Andernfalls ist es der gesamte URI-Pfad.                         |
  |                   |                                                                                |
  +-------------------+--------------------------------------------------------------------------------+
  | SERVER_NAME       | Enthält den Namen des Serverhosts, an den die Client-Anfrage gerichtet ist.    |
  |                   | Dies ist der Wert des Headers "Host", sofern dieser definiert ist, andernfalls |
  |                   | die Zieladresse der Verbindung auf der Clientseite.                            |
  |                   |                                                                                |
  +-------------------+--------------------------------------------------------------------------------+
  | SERVER_PORT       | Enthält den TCP-Zielport der Verbindung auf der Clientseite, also den Port,    |
  |                   | mit dem sich der Client verbunden hat.                                         |
  |                   |                                                                                |
  +-------------------+--------------------------------------------------------------------------------+
  | SERVER_PROTOCOL   | Enthält das Protokoll der Anfrage.                                             |
  |                   |                                                                                |
  +-------------------+--------------------------------------------------------------------------------+
  | SERVER_SOFTWARE   | Enthält die Zeichenfolge "HAProxy", gefolgt von der aktuellen HAProxy-Version. |
  |                   |                                                                                |
  +-------------------+--------------------------------------------------------------------------------+
  | HTTPS             | Wird auf einen nicht leeren Wert ("on") gesetzt, wenn das Skript über das      |
  |                   | Protokoll HTTPS angefragt wurde.                                               |
  |                   |                                                                                |
  +-------------------+--------------------------------------------------------------------------------+

10.3. Einschränkungen

Die aktuelle Implementierung hat einige Einschränkungen. Die erste betrifft die Art, wie bestimmte Anfrageheader vor FastCGI-Anwendungen verborgen werden. Dies geschieht bei der Headeranalyse auf der Backend-Seite vor dem Verbindungsaufbau. Zu diesem Zeitpunkt weiß HAProxy, dass das Backend eine FastCGI-Anwendung verwendet, aber noch nicht, ob die Anfrage an einen FastCGI-Server weitergeleitet wird. Um die Anfrageheader zu verbergen, entfernt HAProxy sie einfach aus der HTX-Nachricht. Wird die Anfrage schließlich an einen HTTP-Server weitergeleitet, bekommt dieser diese Header daher niemals zu sehen. Aus diesem Grund wird nicht empfohlen, FastCGI-Server und HTTP-Server im selben Backend zu kombinieren.

Ebenso werden die Regeln “set-param” und “pass-header” während der Analyse der Anfrageheader ausgewertet. Die Auswertung findet daher immer statt, auch wenn die Anfrage schließlich an einen HTTP-Server weitergeleitet wird.

Wird eine Regel “set-param” angewendet, wird der HTX-Nachricht ein Pseudoheader hinzugefügt. Wie das Umschreiben von HTTP-Headern kann dies bei vollem Puffer fehlschlagen. Die Regeln “set-param” konkurrieren dabei mit den Regeln “http-request”.

Schließlich werden alle FastCGI-Parameter und HTTP-Header in einem einzigen Datensatz FCGI_PARAM gesendet. Dieser Datensatz muss in einem Durchgang kodiert werden; andernfalls wird ein Verarbeitungsfehler zurückgegeben. Der kodierte Datensatz FCGI_PARAM darf daher nicht größer als ein Puffer sein. Eine Reserve muss hierbei jedoch nicht eingehalten werden.