Manage virtual hosts ==================== LemonLDAP::NG configuration is build around Apache or Nginx virtual hosts. Each virtual host is a protected resource, with access rules, headers, POST data and options. Apache configuration -------------------- To protect a virtual host in Apache, the LemonLDAP::NG Handler must be activated (see :ref:`Apache global configuration`). Then you can take any virtual host, and simply add this line to protect it: .. code-block:: apache PerlHeaderParserHandler Lemonldap::NG::Handler::ApacheMP2 Hosted application ~~~~~~~~~~~~~~~~~~ Example of a protected virtual host for a local application: .. code-block:: apache ServerName localsite.example.com PerlHeaderParserHandler Lemonldap::NG::Handler::ApacheMP2 DocumentRoot /var/www/localsite ErrorLog /var/log/apache2/localsite_error.log CustomLog /var/log/apache2/localsite_access.log combined Reverse proxy ~~~~~~~~~~~~~ Example of a protected virtual host with LemonLDAP::NG as reverse proxy: .. code-block:: apache ServerName application.example.com PerlHeaderParserHandler Lemonldap::NG::Handler::ApacheMP2 # Reverse-Proxy ProxyPass / http://private-name/ # Change "Location" header in redirections ProxyPassReverse / http://private-name/ # Change domain cookies ProxyPassReverseCookieDomain private-name application.example.com ErrorLog /var/log/apache2/proxysite_error.log CustomLog /var/log/apache2/proxysite_access.log combined Same with remote server configured with the same host name: .. code-block:: apache ServerName application.example.com PerlHeaderParserHandler Lemonldap::NG::Handler::ApacheMP2 # Reverse-Proxy ProxyPass / http://APPLICATION_IP/ ProxyPreserveHost on ErrorLog /var/log/apache2/proxysite_error.log CustomLog /var/log/apache2/proxysite_access.log combined .. note:: The ``ProxyPreserveHost`` directive will forward the Host header to the protected application. To learn more about using Apache as reverse-proxy, see `Apache documentation `__. .. tip:: Some applications need the ``REMOTE_USER`` environment variable to get the connected user, which is not set in reverse-proxy mode. In this case, see :doc:`how convert header into environment variable`. Add a floating menu ~~~~~~~~~~~~~~~~~~~ A little floating menu can be added to application with this simple Apache configuration: .. code-block:: apache PerlModule Lemonldap::NG::Handler::ApacheMP2::Menu PerlOutputFilterHandler Lemonldap::NG::Handler::ApacheMP2::Menu->run Pages where this menu is displayed can be restricted, for example: .. code-block:: apache PerlOutputFilterHandler Lemonldap::NG::Handler::ApacheMP2::Menu->run .. attention:: You need to disable mod_deflate to use the floating menu Nginx configuration ------------------- To protect a virtual host in Nginx, the LemonLDAP::NG FastCGI server must be launched (see :doc:`LemonLDAP::NG FastCGI server`). Then you can take any virtual host and modify it: - Declare the /lmauth endpoint .. code-block:: nginx location = /lmauth { internal; include /etc/nginx/fastcgi_params; fastcgi_pass unix:/var/run/llng-fastcgi-server/llng-fastcgi.sock; # Drop post datas fastcgi_pass_request_body off; fastcgi_param CONTENT_LENGTH ""; # Keep original hostname fastcgi_param HOST $http_host; # Keep original request (LLNG server will receive /lmauth) fastcgi_param X_ORIGINAL_URI $request_uri; } - Protect the application (/ or /path/to/protect): .. code-block:: nginx location /path/to/protect { auth_request /lmauth; auth_request_set $lmremote_user $upstream_http_lm_remote_user; auth_request_set $lmlocation $upstream_http_location; auth_request_set $cookie_value $upstream_http_set_cookie; add_header Set-Cookie $cookie_value; error_page 401 $lmlocation; try_files $uri $uri/ =404; # ... } - Use LUA or set manually the headers: .. code-block:: nginx location /path/to/protect { # ... # IF LUA IS SUPPORTED #include /etc/lemonldap-ng/nginx-lua-headers.conf; # ELSE # Set manually your headers #auth_request_set $authuser $upstream_http_auth_user; #proxy_set_header Auth-User $authuser; # OR #fastcgi_param HTTP_AUTH_USER $authuser; # Then (if LUA not supported), change cookie header to hide LLNG cookie #auth_request_set $lmcookie $upstream_http_cookie; #proxy_set_header Cookie: $lmcookie; # OR in the corresponding block #fastcgi_param HTTP_COOKIE $lmcookie; # Set REMOTE_USER (for FastCGI apps only) #fastcgi_param REMOTE_USER $lmremote_user; } .. _hosted-application-1: Hosted application ~~~~~~~~~~~~~~~~~~ Example of a protected virtual host for a local application: .. code-block:: nginx # Log format include /path/to/lemonldap-ng/nginx-lmlog.conf; server { listen 80; server_name myserver; root /var/www/html; # Internal authentication request location = /lmauth { internal; include /etc/nginx/fastcgi_params; fastcgi_pass /path/to/llng-fastcgi-server.sock; # Drop post datas fastcgi_pass_request_body off; fastcgi_param CONTENT_LENGTH ""; # Keep original hostname fastcgi_param HOST $http_host; # Keep original request (LLNG server will receive /lmauth) fastcgi_param X_ORIGINAL_URI $request_uri; } # Client requests location ~ \.php$ { auth_request /lmauth; auth_request_set $lmremote_user $upstream_http_lm_remote_user; auth_request_set $lmlocation $upstream_http_location; error_page 401 $lmlocation; try_files $uri $uri/ =404; include fastcgi_params; try_files $fastcgi_script_name =404; fastcgi_pass /path/to/php-fpm/socket; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_intercept_errors on; fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_hide_header X-Powered-By; ################################## # PASSING HEADERS TO APPLICATION # ################################## # IF LUA IS SUPPORTED #include /path/to/nginx-lua-headers.conf # ELSE # Set manually your headers #auth_request_set $authuser $upstream_http_auth_user; #fastcgi_param HTTP_AUTH_USER $authuser; } location / { try_files $uri $uri/ =404; } } .. _reverse-proxy-1: Reverse proxy ~~~~~~~~~~~~~ \* Example of a protected reverse-proxy: .. code-block:: nginx # Log format include /path/to/lemonldap-ng/nginx-lmlog.conf; server { listen 80; server_name myserver; root /var/www/html; # Internal authentication request location = /lmauth { internal; include /etc/nginx/fastcgi_params; fastcgi_pass /path/to/llng-fastcgi-server.sock; # Drop post datas fastcgi_pass_request_body off; fastcgi_param CONTENT_LENGTH ""; # Keep original hostname fastcgi_param HOST $http_host; # Keep original request (LLNG server will receive /lmauth) fastcgi_param X_ORIGINAL_URI $request_uri; } # Client requests location / { auth_request /lmauth; auth_request_set $lmremote_user $upstream_http_lm_remote_user; auth_request_set $lmlocation $upstream_http_location; error_page 401 $lmlocation; proxy_pass http://remote.server/; include /etc/nginx/proxy_params; ################################## # PASSING HEADERS TO APPLICATION # ################################## # IF LUA IS SUPPORTED #include /path/to/nginx-lua-headers.conf # ELSE # Set manually your headers #auth_request_set $authuser $upstream_http_auth_user; #proxy_set_header HTTP_AUTH_USER $authuser; } } \* Example of a Nginx Virtual Host using uWSGI with many URIs protected by different types of handler : .. code-block:: nginx # Log format include /path/to/lemonldap-ng/nginx-lmlog.conf; server { listen 80; server_name myserver; root /var/www/html; # Internal MAIN handler authentication request location = /lmauth { internal; # uWSGI Configuration include /etc/nginx/uwsgi_params; uwsgi_pass 127.0.0.1:5000; uwsgi_pass_request_body off; uwsgi_param CONTENT_LENGTH ""; uwsgi_param HOST $http_host; uwsgi_param X_ORIGINAL_URI $request_uri; # Improve performances uwsgi_buffer_size 32k; uwsgi_buffers 32 32k; } # Internal AUTH_BASIC handler authentication request location = /lmauth-basic { internal; # uWSGI Configuration include /etc/nginx/uwsgi_params; uwsgi_pass 127.0.0.1:5000; uwsgi_pass_request_body off; uwsgi_param CONTENT_LENGTH ""; uwsgi_param HOST $http_host; uwsgi_param X_ORIGINAL_URI $request_uri; uwsgi_param VHOSTTYPE AuthBasic; # Improve performances uwsgi_buffer_size 32k; uwsgi_buffers 32 32k; } # Internal SERVICE_TOKEN handler authentication request location = /lmauth-service { internal; # uWSGI Configuration include /etc/nginx/uwsgi_params; uwsgi_pass 127.0.0.1:5000; uwsgi_pass_request_body off; uwsgi_param CONTENT_LENGTH ""; uwsgi_param HOST $http_host; uwsgi_param X_ORIGINAL_URI $request_uri; uwsgi_param VHOSTTYPE ServiceToken; # Improve performances uwsgi_buffer_size 32k; uwsgi_buffers 32 32k; } # Client requests location / { ################################## # CALLING AUTHENTICATION # ################################## auth_request /lmauth; auth_request_set $lmremote_user $upstream_http_lm_remote_user; auth_request_set $lmremote_custom $upstream_http_lm_remote_custom; auth_request_set $lmlocation $upstream_http_location; # Remove this for AuthBasic handler error_page 401 $lmlocation; ################################## # PASSING HEADERS TO APPLICATION # ################################## # IF LUA IS SUPPORTED include /etc/nginx/nginx-lua-headers.conf; } location /AuthBasic/ { ################################## # CALLING AUTHENTICATION # ################################## auth_request /lmauth-basic; auth_request_set $lmremote_user $upstream_http_lm_remote_user; auth_request_set $lmremote_custom $upstream_http_lm_remote_custom; auth_request_set $lmlocation $upstream_http_location; # Remove this for AuthBasic handler #error_page 401 $lmlocation; ################################## # PASSING HEADERS TO APPLICATION # ################################## # IF LUA IS SUPPORTED include /etc/nginx/nginx-lua-headers.conf; } location /web-service/ { ################################## # CALLING AUTHENTICATION # ################################## auth_request /lmauth-service; auth_request_set $lmremote_user $upstream_http_lm_remote_user; auth_request_set $lmlocation $upstream_http_location; # Remove this for AuthBasic handler error_page 401 $lmlocation; ################################## # PASSING HEADERS TO APPLICATION # ################################## # IF LUA IS SUPPORTED include /etc/nginx/nginx-lua-headers.conf; } } .. _configvhost-lemonldapng-configuration: LemonLDAP::NG configuration --------------------------- A virtual host protected by LemonLDAP::NG Handler must be registered in LemonLDAP::NG configuration. To do this, use the Manager, and go in ``Virtual Hosts`` branch. You can add, delete or modify a virtual host here. Enter the exact virtual host name (for example ``test.example.com``) or use a wildcard (for example ``*.example.com``). A virtual host contains: - Access rules: check user's right on URL patterns - HTTP headers: forge information sent to protected applications - POST data: use form replay - Options: redirection port and protocol Access rules and HTTP headers ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ See :doc:`Writing rules and headers` to learn how to configure access control and HTTP headers sent to application by LL::NG. .. attention:: With **Nginx**-based ReverseProxy, header directives can be appended by a LUA script. To send more than **TEN** headers to protected applications, you have to edit and modify : ``/etc/nginx/nginx-lua-headers.conf`` .. danger:: \* **Nginx** gets rid of any empty headers. There is no point of passing along empty values to another server; it would only serve to bloat the request. In other words, headers with **empty values are completely removed** from the passed request. \* **Nginx**, by default, will consider any header that **contains underscores as invalid**. It will remove these from the proxied request. If you wish to have Nginx interpret these as valid, you can set the ``underscores_in_headers`` directive to “on”, otherwise your headers will never make it to the backend server. POST data ~~~~~~~~~ See :doc:`Form replay` to learn how to configure form replay to POST data on protected applications. Options ~~~~~~~ Some options are available: - Port: used to build redirection URL *(when user is not logged, or for CDA requests)* - HTTPS: used to build redirection URL - Maintenance mode: reject all requests with a maintenance message - Aliases: list of aliases for this virtual host *(avoid to rewrite rules,...)* - Type: handler type (normal, :doc:`ServiceToken Handler`, :doc:`DevOps Handler`,...) - Authentication level required: this option avoids to reject user with a rule based on ``$_authenticationLevel``. When user hasn't got the required level, he is redirected to an upgrade page in the portal. This level is applied to ALL VirtualHost locations. - ServiceToken timeout: The Service Token is only available during 30 seconds by default. This TTL can be customized for each virtual host. .. danger:: A same virtual host can serve many locations. Each location can be protected by a different type of handler : :: server test1.example.com 80 location ^/AuthBasic => AuthBasic handler location ^/AuthCookie => Main handler Keep in mind that AuthBasic handler use "Login/Password" to authenticate users. If you set "Authentication level required" option to "5" by example, AuthBasic requests will be ALWAYS rejected because AuthBasic authentication level is lower than required level. .. attention:: A negative or null ServiceToken timeout value will be overloaded by ``handlerServiceTokenTTL`` (30 seconds by default). "Port" and "HTTPS" options are used to build redirection URL *(when user is not logged, or for CDA requests)*. By default, default values are used. These options are only here to override default values.