Project

General

Profile

The Proxy Interface

Module: mod_proxy

Description

Options

lighttpd mod_proxy is a reverse proxy. lighttpd mod_proxy does not currently support SSL/TLS connections to the backend server.

mod_proxy config options:

  • proxy.server: backend server definition(s) for hosts to which to send requests; options for each backend host. Every file-extension can have its own handler. Load-balancing is done by specifying multiple hosts for the same extension.
  • proxy.debug: debug level (value between 0 and 65535) Note: Use 'enable|disable' in v1.4.13.
  • proxy.balance: might be one of 'fair' (default), 'hash', 'round-robin' or 'sticky'.
    • 'fair' or 'least-connection' is the normal load-based, passive balancing.
    • 'round-robin' chooses another host for each request.
    • 'hash' is generating a hash over the request-uri and makes sure that the same request URI is sent to always the same host. That can increase the performance of the backend servers a lot due to higher cache-locality.
    • 'sticky' (since 1.4.44) sends requests from the same (client) IP to the same backend.
  • proxy.map-extensions | map multiple extensions to the same backend
  • proxy.forwarded: append "Forwarded" header (RFC7239) to proxied requests (since 1.4.46)
  • proxy.header: options to perform simple remapping of host and URL paths in proxied HTTP headers (since 1.4.46)
  • proxy.replace-http-host: enable/disable replacing Host header in request to backend with proxy.server label (default: disable) (since 1.4.44)

Structure of proxy.server section:

    ( <extension> => 
      ( [ <label> => ]
        ( "host" => <string> ,
          "port" => <integer> ),
        ( "host" => <string> ,
          "port" => <integer> )
      ),
      <extension> => ... 
    )
  • <extension>: is the file-extension or prefix (if started with "/"); can be empty ("") to match all requests
  • <label>: optional name that shows up in the generated statistics of mod_status, useful for indicating which backend handler processed this extension
  • "host": IP of the proxy server (since 1.4.46, DNS name is resolved to first IP at lighttpd startup)
    (since 1.4.36:) if host starts with a "/" lighttpd will try to connect to the unix domain socket
  • "port": tcp-port on the "host" used by the proxy server (default: 80)

e.g.:

    proxy.server = ( ".jsp" =>
                       ( ( 
                           "host" => "10.0.0.242",
                           "port" => 81
                         ) )
                     )

proxy.forwarded (since 1.4.46) is a list of parameters to include in "Forwarded". It is not enabled by default. To provide the same information as X-Forwarded-For and X-Forwarded-Proto, enable "for" and "proto". The "remote_user" is a lighttpd extension to the Forwarded header and, if enabled, adds the authenticated user set by mod_auth.

    proxy.forwarded = ( "for"          => 1,
                        "proto"        => 1,
                        #"host"        => 1,
                        #"by"          => 1,
                        #"remote_user" => 1
    )

proxy.header (since 1.4.46) is a list of options to perform simple prefix matching to remap host and URL paths in proxied HTTP headers (commit 036d3d3d)

    proxy.header = (
        #"map-host-request" => (
            #"-" => "...",#replace provided given Host request authority
            #"..." => "-",#preserve existing authority (no further matching)
            #"..." => "", #preserve existing authority (no further matching)
            #             #(equivalent to "xxx" => "xxx")
            #"xxx" => "yyy", #map one string ("xxx") to another ("yyy")
        #),
        #"map-host-response" => (
            #"-" => "...",#replace authority used in backend request
            #"..." => "-",#replace with original authority
            #"..." => "", #preserve existing authority (no further matching)
            #             #(equivalent to "xxx" => "xxx")
            #"xxx" => "yyy", #map one string ("xxx") to another ("yyy")
        #),
        #"map-urlpath" => (
            #"/xxx"  => "/yyy",#map one urlpath prefix to another
            #"/xxx/" => "/",   #map one urlpath prefix to another
            #"/xxx"  => "",    #map one urlpath prefix to another
            #"/key"  => "/value",
            # Note: request headers have matching "key" prefix replaced with
            # "value", and response headers have matching "value" prefix
            # replaced with "key", with a pre-test of the "value" from the
            # first-matched "key" in request headers (if there was a match)
        #),
        #"https-remap" => "enable",
            # For https requests from client, map https:// to http://
            # when map-host-request matches URI in request, and map http://
            # to https:// when map-host-response matches URI in response.
            # (mod_proxy currently sends all backend requests as http)
        #"upgrade" => "enable",
            # enable experimental support for Upgrade: websocket
        #"connect" => "enable",
            # permit HTTP CONNECT method to target backend (since 1.4.49)
    )

Example

Using lighttpd + mod_proxy in front of 8 Squids which handle the caching of dynamic content for you. All requests for the host www.example.org should be forwarded to the proxy. All proxies listen on port 80 for requests.

  $HTTP["host"] == "www.example.org" {
    proxy.balance = "hash" 
    proxy.server  = ( "" => ( ( "host" => "10.0.0.10" ),
                              ( "host" => "10.0.0.11" ),
                              ( "host" => "10.0.0.12" ),
                              ( "host" => "10.0.0.13" ),
                              ( "host" => "10.0.0.14" ),
                              ( "host" => "10.0.0.15" ),
                              ( "host" => "10.0.0.16" ),
                              ( "host" => "10.0.0.17" ) ) )
  }

If one of the hosts goes down the all requests for this one server are moved equally to the other servers. If you want to know more about the algorithm used here, "google" for 'Microsoft CARP'.

Troubleshooting

If you are getting:

2007-05-02 09:45:48: (mod_proxy.c.397) connect failed: 8 Network is unreachable 101 
2007-05-02 09:45:48: (mod_proxy.c.871) proxy-server disabled: blabla.com 80 8
2007-05-02 09:45:48: (mod_proxy.c.1229) no proxy-handler found for: /

Check if you have used an IP address for the proxy address. Hostnames are not allowed there before lighttpd 1.4.46. Since lighttpd 1.4.46, DNS name is resolved at lighttpd startup to first IP at returned from DNS for that host.

Example: websocket proxy to noVNC (since 1.4.46)

Follow instructions to download and install, or use available packages for your Linux/*BSD distribution.
https://github.com/novnc/noVNC
https://github.com/novnc/websockify

If noVNC files are in /usr/share/novnc, run novnc_server with: $ novnc_server --web /usr/share/novnc
novnc_server runs websockify on port 6080 by default and expects the VNC server to be on port 5900, unless configured otherwise. lighttpd mod_proxy can be configured in front of websockify to provide optional SSL, authentication, logging, etc:

server.modules += ( "mod_proxy" )
$HTTP["url"] =~ "^/websockify" {
    proxy.server = ( "" => ( ( "host" => "127.0.0.1", "port" => "6080" ) ) )
    proxy.header = ( "upgrade" => "enable" )
}

The above assumes an already running VNC server. Please take proper precautions to limit access to the VNC server, possibly including requiring proper authentication and limiting access to certain source IPs. See Docs_ModWStunnel for sample commands with x11vnc server and consider using mod_wstunnel for a slightly more direct way to access a VNC server through lighttpd.

Updated by gstrauss 21 days ago · 37 revisions