{"id":952,"date":"2016-10-11T09:20:46","date_gmt":"2016-10-11T07:20:46","guid":{"rendered":"http:\/\/www.netnea.com\/cms\/?page_id=952"},"modified":"2025-11-07T11:03:09","modified_gmt":"2025-11-07T10:03:09","slug":"apache-tutorial-9_setting-up-a-reverse-proxy","status":"publish","type":"page","link":"https:\/\/www.netnea.com\/cms\/apache-tutorial-9_setting-up-a-reverse-proxy\/","title":{"rendered":"Setting up a Reverse Proxy Server"},"content":{"rendered":"\n<h2 id=\"setting-up-a-reverse-proxy-server\">Setting up a reverse proxy server<\/h2>\n<h3 id=\"what-are-we-doing\">What are we doing?<\/h3>\n<p>We are configuring a reverse proxy protecting access to the application and shielding the application server from the internet. In doing so, we\u2019ll become familiar with several configuration methods and will be working with ModRewrite for the first time.<\/p>\n<h3 id=\"why-are-we-doing-this\">Why are we doing this?<\/h3>\n<p>A modern application architecture has multiple layers. Only the reverse proxy is exposed to the internet. It conducts a security check on the HTTP payload and forwards the requests found to be good to the application server in the second layer. This in turn is connected to a database server located in yet another layer. This is referred to as a three-tier model. In a staggered defense spanning three levels, the reverse proxy or to be technically correct, the gateway server, provides the first look into the encrypted requests. On the way back it is in turn the last instance in which the responses can be checked one last time.<\/p>\n<p>There are a number of ways for converting an Apache server into a reverse proxy. More importantly, there are multiple ways of communicating with the application server. In this tutorial we will be restricting ourselves to the normal HTTP-based <code>mod_proxy_http<\/code>. We will not be discussing other methods of communication such as FastCGI proxy or AJP here. There are also several ways of getting the proxy process going in Apache. We will start by looking at the normal setup using ProxyPass and will afterwards discuss other options using ModRewrite.<\/p>\n<h3 id=\"requirements\">Requirements<\/h3>\n<p>The following is a recommended set of requirements. You do not really need all of these, but if you follow them diligently, I am sure all the examples will work 1:1. If you take a short cut, it will probably need some tweaking with paths and predefined aliases.<\/p>\n<ul>\n<li>An Apache web server, ideally one created using the file structure shown in <a href=\"https:\/\/www.netnea.com\/cms\/apache-tutorial-1_compiling-apache\/\">Tutorial 1 (Compiling an Apache web server)<\/a>.<\/li>\n<li>Understanding of the minimal configuration from <a href=\"https:\/\/www.netnea.com\/cms\/apache-tutorial-2_minimal-apache-configuration\/\">Tutorial 2 (Configuring a minimal Apache server)<\/a>.<\/li>\n<li>An Apache web server with SSL\/TLS support as shown in <a href=\"https:\/\/www.netnea.com\/cms\/apache-tutorial-4_configuring-ssl-tls\/\">Tutorial 4 (Configuring an SSL server)<\/a>.<\/li>\n<li>An Apache web server with extended access log as shown in <a href=\"https:\/\/www.netnea.com\/cms\/apache-tutorial-5\/apache-tutorial-5_extending-access-log\/\">Tutorial 5 (Extending and analyzing the access log)<\/a>.<\/li>\n<li>An Apache web server with ModSecurity as shown in <a href=\"https:\/\/www.netnea.com\/cms\/apache-tutorial-6\/apache-tutorial-6_embedding-modsecurity\/\">Tutorial 6 (Embedding ModSecurity)<\/a>.<\/li>\n<li>An Apache web server with the Core Rule Set, as shown in <a href=\"https:\/\/www.netnea.com\/cms\/apache-tutorial-7_including-modsecurity-core-rules\/\">Tutorial 7 (Including the Core Rule Set)<\/a><\/li>\n<\/ul>\n<h3 id=\"step-1-preparing-the-backend\">Step 1: Preparing the backend<\/h3>\n<p>The purpose of a reverse proxy is to shield an application server from direct internet access. As somewhat of a prerequisite for this tutorial, we\u2019ll be needing a backend server like this. In principle, any HTTP application can be used for such an installation and we could very well use the application server from the third tutorial. However, it seems appropriate for me to demonstrate a very simple approach. We\u2019ll be using the tool <code>socat<\/code> short for SOcket CAt.<\/p>\n<div class=\"sourceCode\" id=\"cb1\"><pre class=\"sourceCode bash\"><code class=\"sourceCode bash\"><span id=\"cb1-1\"><a href=\"#cb1-1\" aria-hidden=\"true\"><\/a>$<span class=\"op\">&gt;<\/span> <span class=\"ex\">socat<\/span> -v -v TCP-LISTEN:8000,bind=127.0.0.1,crlf,reuseaddr,fork SYSTEM:<span class=\"st\">&quot;echo HTTP\/1.0 200;\\<\/span><\/span>\n<span id=\"cb1-2\"><a href=\"#cb1-2\" aria-hidden=\"true\"><\/a><span class=\"st\">echo Content-Type\\: text\/plain; echo; echo &#39;Server response, port 8000.&#39;&quot;<\/span><\/span><\/code><\/pre><\/div>\n<p>Using this complex command we instruct socat to bind a listener to local port 8000 and to use several echoes to return an HTTP response when a connection occurs. The additional parameters make sure that the listener stays permanently open and error output works.<\/p>\n<div class=\"sourceCode\" id=\"cb2\"><pre class=\"sourceCode bash\"><code class=\"sourceCode bash\"><span id=\"cb2-1\"><a href=\"#cb2-1\" aria-hidden=\"true\"><\/a>$<span class=\"op\">&gt;<\/span> <span class=\"ex\">curl<\/span> -v http:\/\/localhost:8000\/<\/span>\n<span id=\"cb2-2\"><a href=\"#cb2-2\" aria-hidden=\"true\"><\/a><span class=\"ex\">*<\/span> Hostname was NOT found in DNS cache<\/span>\n<span id=\"cb2-3\"><a href=\"#cb2-3\" aria-hidden=\"true\"><\/a><span class=\"ex\">*<\/span>  Trying 127.0.0.1...<\/span>\n<span id=\"cb2-4\"><a href=\"#cb2-4\" aria-hidden=\"true\"><\/a><span class=\"ex\">*<\/span> Connected to localhost (127.0.0.1) <span class=\"ex\">port<\/span> 8000 (#0)<\/span>\n<span id=\"cb2-5\"><a href=\"#cb2-5\" aria-hidden=\"true\"><\/a><span class=\"op\">&gt;<\/span> <span class=\"ex\">GET<\/span> \/ HTTP\/1.1<\/span>\n<span id=\"cb2-6\"><a href=\"#cb2-6\" aria-hidden=\"true\"><\/a><span class=\"op\">&gt;<\/span> <span class=\"ex\">User-Agent<\/span>: curl\/7.35.0<\/span>\n<span id=\"cb2-7\"><a href=\"#cb2-7\" aria-hidden=\"true\"><\/a><span class=\"op\">&gt;<\/span> <span class=\"ex\">Host<\/span>: localhost:8000<\/span>\n<span id=\"cb2-8\"><a href=\"#cb2-8\" aria-hidden=\"true\"><\/a><span class=\"op\">&gt;<\/span> <span class=\"ex\">Accept<\/span>: *\/*<\/span>\n<span id=\"cb2-9\"><a href=\"#cb2-9\" aria-hidden=\"true\"><\/a><span class=\"op\">&gt;<\/span> <\/span>\n<span id=\"cb2-10\"><a href=\"#cb2-10\" aria-hidden=\"true\"><\/a><span class=\"ex\">*<\/span> HTTP 1.0, assume close after body<\/span>\n<span id=\"cb2-11\"><a href=\"#cb2-11\" aria-hidden=\"true\"><\/a><span class=\"op\">&lt;<\/span> <span class=\"ex\">HTTP\/1.0<\/span> 200<\/span>\n<span id=\"cb2-12\"><a href=\"#cb2-12\" aria-hidden=\"true\"><\/a><span class=\"op\">&lt;<\/span> <span class=\"ex\">Content-Type<\/span>: text\/plain<\/span>\n<span id=\"cb2-13\"><a href=\"#cb2-13\" aria-hidden=\"true\"><\/a><span class=\"op\">&lt;<\/span> <\/span>\n<span id=\"cb2-14\"><a href=\"#cb2-14\" aria-hidden=\"true\"><\/a><span class=\"ex\">Server<\/span> response, port 8000<\/span>\n<span id=\"cb2-15\"><a href=\"#cb2-15\" aria-hidden=\"true\"><\/a><span class=\"ex\">*<\/span> Closing connection 0<\/span><\/code><\/pre><\/div>\n<p>We have set up a backend system with the simplest of means. So easy, that in the future we might come back to this method to verify that a proxy server is working before the real application server is running.<\/p>\n<h3 id=\"step-2-enabling-the-proxy-module\">Step 2: Enabling the proxy module<\/h3>\n<p>Several modules are required to use Apache as a proxy server. We compiled them in the first tutorial and can now simply link them.<\/p>\n<div class=\"sourceCode\" id=\"cb3\"><pre class=\"sourceCode bash\"><code class=\"sourceCode bash\"><span id=\"cb3-1\"><a href=\"#cb3-1\" aria-hidden=\"true\"><\/a><span class=\"ex\">LoadModule<\/span>              proxy_module            modules\/mod_proxy.so<\/span>\n<span id=\"cb3-2\"><a href=\"#cb3-2\" aria-hidden=\"true\"><\/a><span class=\"ex\">LoadModule<\/span>              proxy_http_module       modules\/mod_proxy_http.so<\/span><\/code><\/pre><\/div>\n<p>The proxying feature set is provided by a basic proxy module and a proxy HTTP module. Proxying actually means receiving a request and forwarding it to another server. In our case we will be defining the backend system from the beginning and then accept requests from different clients for this backend service. It\u2019s a different situation if you set up a proxy server that accepts requests from a group of clients and sends then onward to any server on the internet. This is referred to as a forward proxy. This is useful for when you don\u2019t want to directly expose clients on a corporate network to the internet since the proxy server appears as a client to the servers on the internet.<\/p>\n<p>This mode is also possible in Apache, even if for historical reasons. Alternative software packages offering these features have become well established, e.g.\u00a0squid. The case is relevant insofar as a faulty configuration may have fatal consequences, particularly if the forward proxy accepts requests from any client and sends them onward to the internet in anonymized form. This is referred to as an open proxy. It\u2019s essential to prevent this since we don\u2019t want to operate Apache in this mode. That requires a directive in the past used to reference the risky default <code>on<\/code> value, but is now correctly predefined as <code>off<\/code>:<\/p>\n<div class=\"sourceCode\" id=\"cb4\"><pre class=\"sourceCode bash\"><code class=\"sourceCode bash\"><span id=\"cb4-1\"><a href=\"#cb4-1\" aria-hidden=\"true\"><\/a><span class=\"ex\">ProxyRequests<\/span> Off<\/span><\/code><\/pre><\/div>\n<p>This directive actually means forwarding requests to servers on the internet, even if the name indicates a general setting. As mentioned before, the directive is correctly set for Apache 2.4 and it is only being mentioned here to guard against questions or incorrect settings in the future.<\/p>\n<h3 id=\"step-3-proxypass\">Step 3: ProxyPass<\/h3>\n<p>This brings us to the actual proxying settings: There are many ways for instructing Apache to forward a request to a backend application. We\u2019ll be looking at each option in turn. The most common way of proxying requests is based on the ProxyPass directive. It is used as follows:<\/p>\n<div class=\"sourceCode\" id=\"cb5\"><pre class=\"sourceCode bash\"><code class=\"sourceCode bash\"><span id=\"cb5-1\"><a href=\"#cb5-1\" aria-hidden=\"true\"><\/a><span class=\"ex\">ProxyPass<\/span>          \/service1    http:\/\/localhost:8000\/service1<\/span>\n<span id=\"cb5-2\"><a href=\"#cb5-2\" aria-hidden=\"true\"><\/a><span class=\"ex\">ProxyPassReverse<\/span>   \/service1    http:\/\/localhost:8000\/service1<\/span>\n<span id=\"cb5-3\"><a href=\"#cb5-3\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb5-4\"><a href=\"#cb5-4\" aria-hidden=\"true\"><\/a><span class=\"op\">&lt;<\/span><span class=\"ex\">Proxy<\/span> http:\/\/localhost:8000\/service1<span class=\"op\">&gt;<\/span><\/span>\n<span id=\"cb5-5\"><a href=\"#cb5-5\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb5-6\"><a href=\"#cb5-6\" aria-hidden=\"true\"><\/a>      <span class=\"ex\">Require<\/span> all granted<\/span>\n<span id=\"cb5-7\"><a href=\"#cb5-7\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb5-8\"><a href=\"#cb5-8\" aria-hidden=\"true\"><\/a>      <span class=\"ex\">Options<\/span> None<\/span>\n<span id=\"cb5-9\"><a href=\"#cb5-9\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb5-10\"><a href=\"#cb5-10\" aria-hidden=\"true\"><\/a><span class=\"op\">&lt;<\/span>\/<span class=\"ex\">Proxy<\/span><span class=\"op\">&gt;<\/span><\/span><\/code><\/pre><\/div>\n<p>The most important directive is ProxyPass. It defines a <code>\/service1<\/code> path and specifies how it is mapped to the backend: To the service defined above running on our own host, localhost, on port 8000. The path to the application server is again <code>\/service1<\/code>. We are proxying symmetrically, because the frontend path is identical to the backend path. This mapping is however not absolutely required. Technically, it would be entirely possible to proxy <code>service1<\/code> to <code>\/<\/code>, but this results to administrative difficulties and misunderstandings, if a path in the application log file no longer maps to the path on the reverse proxy and the requests can no longer be correlated easily.<\/p>\n<p>On the next line comes a related directive that despite having a similar name performs only a small auxiliary function. Redirect responses from the backend are fully qualified in http-compliant form. Such as <code>https:\/\/backend.example.com\/service1<\/code>, for example. The address is however not accessible by the client. For this reason, the reverse proxy has to rewrite the backend\u2019s location header, <code>backend.example.com<\/code>, replacing it with its own name and thus mapping it back to its own namespace. ProxyPassReverse, with such a great name, only has a simple search and replace feature touching the location headers. As already seen in the ProxyPass directive, proxying is again symmetric: the paths are rewritten 1:1. We are free to ignore this rule, but I urgently recommend keeping it, because misunderstandings and confusion lie beyond. In addition to accessing location headers, there is a series of further reverse directives for handling things like cookies. They can be useful from case to case.<\/p>\n<h3 id=\"step-4-proxy-stanza\">Step 4: Proxy stanza<\/h3>\n<p>Continuing on in the configuration: now comes the Proxy block where the connection to the backend is more precisely defined. Specifically, this is where requests are authenticated and authorized. Further below in the tutorial we will also be adding a load balancer to this block.<\/p>\n<p>The proxy block is similar to the location and the directory block we have previously become familiar with in our configuration. These are called containers. Containers specify to the web server how to structure the work. When a container appears in the configuration, it prepares a processing structure for it. In the case of <code>mod_proxy<\/code> the backend can also be accessed without a Proxy container. However, access protection is not taken into account and other directives no longer have any place where it can be inserted. Without the Proxy block the processing of complex servers remains a bit haphazard and it would do us well to configure this part as well. Using the ProxySet directive, we could intervene even more here and specify things like the connection behavior. Min, max and smax can be used to specify the number of threads assigned to the proxy connection pool. This can impact performance from case to case. The keep-alive behavior of the proxy connection can be influenced and a variety of different timeouts defined for it. Additional information is available in the Apache Project documentation.<\/p>\n<h3 id=\"step-5-defining-exceptions-when-proxying-and-making-other-settings\">Step 5: Defining exceptions when proxying and making other settings<\/h3>\n<p>The <code>ProxyPass<\/code> directive we are using has forwarded all requests for <code>\/service1<\/code> to the backend. However, in practice it is often the case that you don\u2019t want to forward everything. Let\u2019s suppose there\u2019s a path <code>\/service1\/admin<\/code> that we don\u2019t want to expose to the internet. This can also be prevented by the appropriate <code>ProxyPass<\/code> setting, where the exception is initiated by using an exclamation mark. What\u2019s important is to define the exception before configuring the actual proxy command:<\/p>\n<div class=\"sourceCode\" id=\"cb6\"><pre class=\"sourceCode bash\"><code class=\"sourceCode bash\"><span id=\"cb6-1\"><a href=\"#cb6-1\" aria-hidden=\"true\"><\/a><span class=\"ex\">ProxyPass<\/span>          \/service1\/admin !<\/span>\n<span id=\"cb6-2\"><a href=\"#cb6-2\" aria-hidden=\"true\"><\/a><span class=\"ex\">ProxyPass<\/span>          \/service1         http:\/\/localhost:8000\/service1<\/span>\n<span id=\"cb6-3\"><a href=\"#cb6-3\" aria-hidden=\"true\"><\/a><span class=\"ex\">ProxyPassReverse<\/span>   \/service1         http:\/\/localhost:8000\/service1<\/span><\/code><\/pre><\/div>\n<p>You often see configurations that forward the entire namespace below <code>\/<\/code> to the backend. Then a number of exceptions to the pattern above are often defined. I think this is the wrong approach and I prefer to forward only what is actually being processed. The advantage is obvious: scanners and automated attacks looking for their next victim from a pool of IP addresses on the internet make requests for a lot of non-existent paths on our server. We can now forward them to the backend and may overload the backend or even put it in danger. Or we can just drop these requests on the reverse proxy server. The latter is clearly preferable for security-related reasons.<\/p>\n<p>An essential directive which may optionally be part of the proxy concerns the timeout. We defined our own timeout value for our server. This timeout is also used by the server for the connection to the backend. But this is not always wise, because while we can expect from the client that it will quickly make its request and not take its sweet time, depending on the backend application, it can take a while until the response is processed. For a short, general timeout which is wise to have for the client for defensive reasons, the reverse proxy would interrupt access to the backend too quickly. For this reason, there is a ProxyTimeout directive which affects only the connection to the backend. By the way, time measurement is not the total processing time on the backend, but the duration of time between IP packets: When the backend sends part of the response the clock is reset.<\/p>\n<div class=\"sourceCode\" id=\"cb7\"><pre class=\"sourceCode bash\"><code class=\"sourceCode bash\"><span id=\"cb7-1\"><a href=\"#cb7-1\" aria-hidden=\"true\"><\/a><span class=\"ex\">ProxyTimeout<\/span>            60<\/span><\/code><\/pre><\/div>\n<p>Now comes time to fix the host header. Via the HTTP request host header the client specifies which of a server\u2019s VirtualHosts to use for the request. If there are multiple VirtualHosts being operated using the same IP address, this value is important. However, when forwarding the reverse proxy normally sets a new host header, specifically the one from the backend system. This is often undesired, because in many cases the backend system sets its links based on the host header. Fully qualified links for a backend application may be a bad practice, but we avoid conflicts if we make clear from the beginning that the host header should be preserved and forwarded as is by the backend.<\/p>\n<div class=\"sourceCode\" id=\"cb8\"><pre class=\"sourceCode bash\"><code class=\"sourceCode bash\"><span id=\"cb8-1\"><a href=\"#cb8-1\" aria-hidden=\"true\"><\/a><span class=\"ex\">ProxyPreserveHost<\/span>       On<\/span><\/code><\/pre><\/div>\n<p>Backend systems often pay less attention to security than a reverse proxy. Error messages are one place this is obvious. Detailed error messages are often desirable since they enable the developer or backend administrator to get at the root of the problem. But we don\u2019t want to distribute them over the internet, because without authentication on the reverse proxy an attacker could always be lurking behind the client. It\u2019s better to hide error messages from the backend application or to replace them with an error message from the reverse proxy. The <code>ProxyErrorOverride<\/code> directive intervenes in the HTTP response body and replaces it if a status code greater than or equal to 400 is present. Requests with normal statuses below 400 are not affected by this directive.<\/p>\n<div class=\"sourceCode\" id=\"cb9\"><pre class=\"sourceCode bash\"><code class=\"sourceCode bash\"><span id=\"cb9-1\"><a href=\"#cb9-1\" aria-hidden=\"true\"><\/a><span class=\"ex\">ProxyErrorOverride<\/span>      On<\/span><\/code><\/pre><\/div>\n<h3 id=\"step-6-modrewrite\">Step 6: ModRewrite<\/h3>\n<p>In addition to the <code>ProxyPass<\/code> directive, the Rewrite module can be used to enable reverse proxy features. Compared to ProxyPass, it enables more flexible configuration. We have not seen ModRewrite up to this point. Since this is a very important module, we should take a good look at it.<\/p>\n<p>ModRewrite defines its own rewrite engine used to manipulate, or change, HTTP requests; This rewrite engine can run in the server or VirtualHost context. Strictly speaking, we are using two separate rewrite engines. The rewrite engine in the VirtualHost context can also be configured from the Proxy container that we learned about above. If we define a rewrite engine in the server context, then it could be shortcut if there is an engine in the VirtualHost context. In this case we have to manually ensure that the rewrite rules are being inherited. We are therefore setting up a rewrite engine in the server context, configuring an example rule and initiating the inheritance.<\/p>\n<div class=\"sourceCode\" id=\"cb10\"><pre class=\"sourceCode bash\"><code class=\"sourceCode bash\"><span id=\"cb10-1\"><a href=\"#cb10-1\" aria-hidden=\"true\"><\/a><span class=\"ex\">LoadModule<\/span>              rewrite_module          modules\/mod_rewrite.so<\/span>\n<span id=\"cb10-2\"><a href=\"#cb10-2\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb10-3\"><a href=\"#cb10-3\" aria-hidden=\"true\"><\/a><span class=\"ex\">...<\/span><\/span>\n<span id=\"cb10-4\"><a href=\"#cb10-4\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb10-5\"><a href=\"#cb10-5\" aria-hidden=\"true\"><\/a><span class=\"ex\">RewriteEngine<\/span>           On<\/span>\n<span id=\"cb10-6\"><a href=\"#cb10-6\" aria-hidden=\"true\"><\/a><span class=\"ex\">RewriteOptions<\/span>          InheritDownBefore<\/span>\n<span id=\"cb10-7\"><a href=\"#cb10-7\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb10-8\"><a href=\"#cb10-8\" aria-hidden=\"true\"><\/a><span class=\"ex\">RewriteRule<\/span>             ^\/$     %<span class=\"dt\">{REQUEST_SCHEME}<\/span>:\/\/%<span class=\"dt\">{HTTP_HOST}<\/span>\/index.html  [redirect,last]<\/span><\/code><\/pre><\/div>\n<p>We initialize the engine on the server level. We then instruct the engine to pass on our rules to other rewrite engines. Specifically, so that our rules are performed before the rules further down. Then comes the actual rule. We tell the server to instruct the client to send a new request to <code>\/index.html<\/code> for a request without a path or a request for \u201c\/\u201d respectively. This is a redirect. What\u2019s important is for the redirect to indicate the schema of the request, http or https as well as the host name. Relatives paths won\u2019t work. But because we are outside the VirtualHost, we don\u2019t see the type. And we don\u2019t want to hard code the host name, but prefer to take the host names from client requests. Both of these values are available as variables as you can see in the example above.<\/p>\n<p>Then appearing within square brackets come the flags influencing the behavior of the rewrite rule. As previously mentioned, we want a redirect and tell the engine that this is the last rule to process (<code>last<\/code>).<\/p>\n<p>Let\u2019s have a look at a request like this and the redirect returned:<\/p>\n<div class=\"sourceCode\" id=\"cb11\"><pre class=\"sourceCode bash\"><code class=\"sourceCode bash\"><span id=\"cb11-1\"><a href=\"#cb11-1\" aria-hidden=\"true\"><\/a>$<span class=\"op\">&gt;<\/span> <span class=\"ex\">curl<\/span> -v http:\/\/localhost\/<\/span>\n<span id=\"cb11-2\"><a href=\"#cb11-2\" aria-hidden=\"true\"><\/a><span class=\"ex\">*<\/span> Hostname was NOT found in DNS cache<\/span>\n<span id=\"cb11-3\"><a href=\"#cb11-3\" aria-hidden=\"true\"><\/a><span class=\"ex\">*<\/span>  Trying 127.0.0.1...<\/span>\n<span id=\"cb11-4\"><a href=\"#cb11-4\" aria-hidden=\"true\"><\/a><span class=\"ex\">*<\/span> Connected to localhost (127.0.0.1) <span class=\"ex\">port<\/span> 80 (#0)<\/span>\n<span id=\"cb11-5\"><a href=\"#cb11-5\" aria-hidden=\"true\"><\/a><span class=\"op\">&gt;<\/span> <span class=\"ex\">GET<\/span> \/ HTTP\/1.1<\/span>\n<span id=\"cb11-6\"><a href=\"#cb11-6\" aria-hidden=\"true\"><\/a><span class=\"op\">&gt;<\/span> <span class=\"ex\">User-Agent<\/span>: curl\/7.35.0<\/span>\n<span id=\"cb11-7\"><a href=\"#cb11-7\" aria-hidden=\"true\"><\/a><span class=\"op\">&gt;<\/span> <span class=\"ex\">Host<\/span>: localhost<\/span>\n<span id=\"cb11-8\"><a href=\"#cb11-8\" aria-hidden=\"true\"><\/a><span class=\"op\">&gt;<\/span> <span class=\"ex\">Accept<\/span>: *\/*<\/span>\n<span id=\"cb11-9\"><a href=\"#cb11-9\" aria-hidden=\"true\"><\/a><span class=\"op\">&gt;<\/span> <\/span>\n<span id=\"cb11-10\"><a href=\"#cb11-10\" aria-hidden=\"true\"><\/a><span class=\"op\">&lt;<\/span> <span class=\"ex\">HTTP\/1.1<\/span> 302 Found<\/span>\n<span id=\"cb11-11\"><a href=\"#cb11-11\" aria-hidden=\"true\"><\/a><span class=\"op\">&lt;<\/span> <span class=\"ex\">Date<\/span>: Thu, 10 Dec 2015 05:24:42 GMT<\/span>\n<span id=\"cb11-12\"><a href=\"#cb11-12\" aria-hidden=\"true\"><\/a><span class=\"ex\">*<\/span> Server Apache is not blacklisted<\/span>\n<span id=\"cb11-13\"><a href=\"#cb11-13\" aria-hidden=\"true\"><\/a><span class=\"op\">&lt;<\/span> <span class=\"ex\">Server<\/span>: Apache<\/span>\n<span id=\"cb11-14\"><a href=\"#cb11-14\" aria-hidden=\"true\"><\/a><span class=\"op\">&lt;<\/span> <span class=\"ex\">Location<\/span>: http:\/\/localhost\/index.html<\/span>\n<span id=\"cb11-15\"><a href=\"#cb11-15\" aria-hidden=\"true\"><\/a><span class=\"op\">&lt;<\/span> <span class=\"ex\">Content-Length<\/span>: 211<\/span>\n<span id=\"cb11-16\"><a href=\"#cb11-16\" aria-hidden=\"true\"><\/a><span class=\"op\">&lt;<\/span> <span class=\"ex\">Content-Type<\/span>: text\/html<span class=\"kw\">;<\/span> <span class=\"va\">charset=<\/span>iso-8859-1<\/span>\n<span id=\"cb11-17\"><a href=\"#cb11-17\" aria-hidden=\"true\"><\/a><span class=\"op\">&lt;<\/span> <\/span>\n<span id=\"cb11-18\"><a href=\"#cb11-18\" aria-hidden=\"true\"><\/a><span class=\"op\">&lt;<\/span>!<span class=\"ex\">DOCTYPE<\/span> HTML PUBLIC <span class=\"st\">&quot;-\/\/IETF\/\/DTD HTML 2.0\/\/EN&quot;<\/span><span class=\"op\">&gt;<\/span><\/span>\n<span id=\"cb11-19\"><a href=\"#cb11-19\" aria-hidden=\"true\"><\/a><span class=\"op\">&lt;<\/span><span class=\"ex\">html<\/span><span class=\"op\">&gt;&lt;<\/span>head<span class=\"op\">&gt;<\/span><\/span>\n<span id=\"cb11-20\"><a href=\"#cb11-20\" aria-hidden=\"true\"><\/a><span class=\"op\">&lt;<\/span><span class=\"ex\">title<\/span><span class=\"op\">&gt;<\/span>302 Found<span class=\"op\">&lt;<\/span>\/title<span class=\"op\">&gt;<\/span><\/span>\n<span id=\"cb11-21\"><a href=\"#cb11-21\" aria-hidden=\"true\"><\/a><span class=\"op\">&lt;<\/span>\/<span class=\"ex\">head<\/span><span class=\"op\">&gt;&lt;<\/span>body<span class=\"op\">&gt;<\/span><\/span>\n<span id=\"cb11-22\"><a href=\"#cb11-22\" aria-hidden=\"true\"><\/a><span class=\"op\">&lt;<\/span><span class=\"ex\">h1<\/span><span class=\"op\">&gt;<\/span>Found<span class=\"op\">&lt;<\/span>\/h1<span class=\"op\">&gt;<\/span><\/span>\n<span id=\"cb11-23\"><a href=\"#cb11-23\" aria-hidden=\"true\"><\/a><span class=\"op\">&lt;<\/span><span class=\"ex\">p<\/span><span class=\"op\">&gt;<\/span>The document has moved <span class=\"op\">&lt;<\/span>a href=<span class=\"st\">&quot;http:\/\/localhost\/index.html&quot;<\/span><span class=\"op\">&gt;<\/span>here<span class=\"op\">&lt;<\/span>\/a<span class=\"op\">&gt;<\/span>.<span class=\"op\">&lt;<\/span>\/p<span class=\"op\">&gt;<\/span><\/span>\n<span id=\"cb11-24\"><a href=\"#cb11-24\" aria-hidden=\"true\"><\/a><span class=\"op\">&lt;<\/span>\/<span class=\"ex\">body<\/span><span class=\"op\">&gt;&lt;<\/span>\/html<span class=\"op\">&gt;<\/span><\/span>\n<span id=\"cb11-25\"><a href=\"#cb11-25\" aria-hidden=\"true\"><\/a><span class=\"ex\">*<\/span> Connection #0 to host localhost left intact<\/span><\/code><\/pre><\/div>\n<p>The server now responds with HTTP status code <code>302 Found<\/code>, corresponding to the typical redirect status code. Alternatively, 301, 303, 307 or very rarely 308 also appear. The differences are subtle, but influence the behavior of the browser. What\u2019s important then is the location header. It tells the client to make a new request, specifically for the fully qualified URL with a schema specified here. This is required for the location header. Only returning the path here, assuming that the client would then correctly conclude that it\u2019s the same server name, would be incorrect and prohibited according to the specification (even if it works with most browsers).<\/p>\n<p>In the body part of the response the redirect is included as a link in HTML text. This is provided for users to click manually, if the browser does not initiate the redirect. However, this is very unlikely and is probably only included for historical reasons.<\/p>\n<p>You could now ask yourself why we are opening a rewrite engine in the server context and not dealing with everything on the VirtualHost level. In the example I chose you see that this would result in redundancy, because the redirect from \u201c\/\u201d to \u201cindex.html\u201d should take place on port 80 and also on encrypted port 443. This is the rule of thumb: It\u2019s best for us to define and inherit everything being used on all VirtualHosts in the server context. We also deal with individual rules for a single VirtualHost on this level. Typically, the following rule is used to redirect all requests from port 80 to port 443, where encryption is enabled:<\/p>\n<div class=\"sourceCode\" id=\"cb12\"><pre class=\"sourceCode bash\"><code class=\"sourceCode bash\"><span id=\"cb12-1\"><a href=\"#cb12-1\" aria-hidden=\"true\"><\/a><span class=\"op\">&lt;<\/span><span class=\"ex\">VirtualHost<\/span> 127.0.0.1:<span class=\"op\">80&gt;<\/span><\/span>\n<span id=\"cb12-2\"><a href=\"#cb12-2\" aria-hidden=\"true\"><\/a>      <\/span>\n<span id=\"cb12-3\"><a href=\"#cb12-3\" aria-hidden=\"true\"><\/a>      <span class=\"ex\">RewriteEngine<\/span>   On<\/span>\n<span id=\"cb12-4\"><a href=\"#cb12-4\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb12-5\"><a href=\"#cb12-5\" aria-hidden=\"true\"><\/a>      <span class=\"ex\">RewriteRule<\/span>     ^\/(.*)$   <span class=\"ex\">https<\/span>:\/\/%<span class=\"dt\">{HTTP_HOST}<\/span>\/<span class=\"va\">$1<\/span>  [redirect,last]<\/span>\n<span id=\"cb12-6\"><a href=\"#cb12-6\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb12-7\"><a href=\"#cb12-7\" aria-hidden=\"true\"><\/a>      <span class=\"ex\">...<\/span><\/span>\n<span id=\"cb12-8\"><a href=\"#cb12-8\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb12-9\"><a href=\"#cb12-9\" aria-hidden=\"true\"><\/a><span class=\"op\">&lt;<\/span>\/<span class=\"ex\">VirtualHost<\/span><span class=\"op\">&gt;<\/span><\/span><\/code><\/pre><\/div>\n<p>The schema we want is now clear. But to the left of it comes a new item. We don\u2019t suppress the path as quickly as above. We instead put it in parenthesis and use <code>$1<\/code> to reference the content of the parenthesis again in the redirect. This means that we are forwarding the request on port 80 using the same URL on port 443.<\/p>\n<p>ModRewrite has been introduced. For further examples refer to the documentation or the sections of this tutorial below where it will become familiar with yet more recipes.<\/p>\n<h3 id=\"step-7-modrewrite-proxy\">Step 7: ModRewrite [proxy]<\/h3>\n<p>Let\u2019s use ModRewrite to configure a reverse proxy. We do this as follows:<\/p>\n<div class=\"sourceCode\" id=\"cb13\"><pre class=\"sourceCode bash\"><code class=\"sourceCode bash\"><span id=\"cb13-1\"><a href=\"#cb13-1\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb13-2\"><a href=\"#cb13-2\" aria-hidden=\"true\"><\/a><span class=\"op\">&lt;<\/span><span class=\"ex\">VirtualHost<\/span> 127.0.0.1:<span class=\"op\">443&gt;<\/span><\/span>\n<span id=\"cb13-3\"><a href=\"#cb13-3\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb13-4\"><a href=\"#cb13-4\" aria-hidden=\"true\"><\/a>    <span class=\"ex\">...<\/span><\/span>\n<span id=\"cb13-5\"><a href=\"#cb13-5\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb13-6\"><a href=\"#cb13-6\" aria-hidden=\"true\"><\/a>    <span class=\"ex\">RewriteEngine<\/span>     On<\/span>\n<span id=\"cb13-7\"><a href=\"#cb13-7\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb13-8\"><a href=\"#cb13-8\" aria-hidden=\"true\"><\/a>    <span class=\"ex\">RewriteRule<\/span>       ^\/service1\/(.*)   <span class=\"ex\">http<\/span>:\/\/localhost:8000\/service1\/<span class=\"va\">$1<\/span> [proxy,last]<\/span>\n<span id=\"cb13-9\"><a href=\"#cb13-9\" aria-hidden=\"true\"><\/a>    <span class=\"ex\">ProxyPassReverse<\/span>  \/                 http:\/\/localhost:8000\/<\/span>\n<span id=\"cb13-10\"><a href=\"#cb13-10\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb13-11\"><a href=\"#cb13-11\" aria-hidden=\"true\"><\/a>    <span class=\"op\">&lt;<\/span><span class=\"ex\">Proxy<\/span> http:\/\/localhost:8000\/service1<span class=\"op\">&gt;<\/span><\/span>\n<span id=\"cb13-12\"><a href=\"#cb13-12\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb13-13\"><a href=\"#cb13-13\" aria-hidden=\"true\"><\/a>        <span class=\"ex\">Require<\/span> all granted<\/span>\n<span id=\"cb13-14\"><a href=\"#cb13-14\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb13-15\"><a href=\"#cb13-15\" aria-hidden=\"true\"><\/a>        <span class=\"ex\">Options<\/span> None<\/span>\n<span id=\"cb13-16\"><a href=\"#cb13-16\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb13-17\"><a href=\"#cb13-17\" aria-hidden=\"true\"><\/a>        <span class=\"ex\">ProxySet<\/span> enablereuse=on<\/span>\n<span id=\"cb13-18\"><a href=\"#cb13-18\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb13-19\"><a href=\"#cb13-19\" aria-hidden=\"true\"><\/a>    <span class=\"op\">&lt;<\/span>\/<span class=\"ex\">Proxy<\/span><span class=\"op\">&gt;<\/span><\/span>\n<span id=\"cb13-20\"><a href=\"#cb13-20\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb13-21\"><a href=\"#cb13-21\" aria-hidden=\"true\"><\/a><span class=\"op\">&lt;<\/span>\/<span class=\"ex\">VirtualHost<\/span><span class=\"op\">&gt;<\/span><\/span><\/code><\/pre><\/div>\n<p>The instruction follows a pattern similar to the variation using ProxyPass. Here however, the last part of the path has to be explicitly intercepted by using a bracket and again indicated by \u201c$1\u201d as we saw above. Instead of the suggested redirect flag the keyword proxy is used here. ProxyPassReverse and the proxy container remain almost identical to the setup using ProxyPass. There is an additional instruction however: ProxySet. It is vital for performance reasons and a somewhat odd behavior of the Apache webserver: When we define proxying via ProxyPass, Apache will implictly set up a resource pool for the backend connection. This resource pool allows for HTTP keep-alive on the backend connection. With the RewriteRule proxy construct, this resource pool is not created automatically. In fact, it is only prepared when we issue a ProxySet statement. The exact nature of the statement does not matter. In fact, enablereuse=on is the default value, but it does not come into play until the resource pool is set up and that only happens with the ProxySet. So we use enablereuse=on as a dummy and activate HTTP keep-alive that way.<\/p>\n<p>So much for the configuration using a rewrite rule. There is no real advantage over ProxyPass syntax in this example. Referencing parts of paths by using <code>$1<\/code>, <code>$2<\/code>, etc. does provide a bit of flexibility, though. But if we are working with rewrite rules anyway, then by rewrite rule proxying we ensure that RewriteRule and ProxyPass don\u2019t come into conflict by touching the same request and impacting one another.<\/p>\n<p>However, it may now be that we want to use a single reverse proxy to combine multiple backends or to distribute the load over multiple servers. This calls for our own load balancer. We\u2019ll be looking at it in the next section.<\/p>\n<h3 id=\"step-8-balancer-proxy\">Step 8: Balancer [proxy]<\/h3>\n<p>We first have to load the Apache load balancer module:<\/p>\n<div class=\"sourceCode\" id=\"cb14\"><pre class=\"sourceCode bash\"><code class=\"sourceCode bash\"><span id=\"cb14-1\"><a href=\"#cb14-1\" aria-hidden=\"true\"><\/a><span class=\"ex\">LoadModule<\/span>        proxy_balancer_module           modules\/mod_proxy_balancer.so<\/span>\n<span id=\"cb14-2\"><a href=\"#cb14-2\" aria-hidden=\"true\"><\/a><span class=\"ex\">LoadModule<\/span>        lbmethod_byrequests_module      modules\/mod_lbmethod_byrequests.so<\/span>\n<span id=\"cb14-3\"><a href=\"#cb14-3\" aria-hidden=\"true\"><\/a><span class=\"ex\">LoadModule<\/span>        slotmem_shm_module              modules\/mod_slotmem_shm.so<\/span><\/code><\/pre><\/div>\n<p>Besides the load balancer module itself we also need a module that can help us distribute the requests to the different backends. We\u2019ll take the easiest route and load the lbmethod_byrequests module. It\u2019s the oldest module from a series of four modules and distributes requests evenly across backends by counting them sequentially. Once to the left and once to the right for two backends.<\/p>\n<p>Here is a list of all four available algorithms:<\/p>\n<ul>\n<li>mod_lbmethod_byrequests (counts requests)<\/li>\n<li>mod_lbmethod_bytraffic (totals sizes of requests and responses)<\/li>\n<li>mod_lbmethod_bybusyness (Load balancing based on active threads in an connection established with the backend. The backend with the lowest number of threads is given the next request)<\/li>\n<li>mod_lbmethod_heartbeat (the backend can even communicate via a heartbeat on th network and use it to inform the reverse proxy whether it has any free capacity).<\/li>\n<\/ul>\n<p>The different modules are well documented online so this brief description will have to suffice for now.<\/p>\n<p>Finally, we still need a module to help us manage shared segments of memory. These features are required by the proxy balancer module and provided by <code>mod_slotmem_shm.so<\/code>.<\/p>\n<p>We are now ready to configure the load balancer. We can set it up via the RewriteRule. This modification also affects the proxy stanza, where the balancer just defined must be referenced and resolved:<\/p>\n<div class=\"sourceCode\" id=\"cb15\"><pre class=\"sourceCode bash\"><code class=\"sourceCode bash\"><span id=\"cb15-1\"><a href=\"#cb15-1\" aria-hidden=\"true\"><\/a>    <span class=\"ex\">RewriteRule<\/span>         ^\/service1\/(.*)       <span class=\"ex\">balancer<\/span>:\/\/backend\/service1\/<span class=\"va\">$1<\/span>   [proxy,last]<\/span>\n<span id=\"cb15-2\"><a href=\"#cb15-2\" aria-hidden=\"true\"><\/a>    <span class=\"ex\">ProxyPassReverse<\/span>    \/                     balancer:\/\/backend\/<\/span>\n<span id=\"cb15-3\"><a href=\"#cb15-3\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb15-4\"><a href=\"#cb15-4\" aria-hidden=\"true\"><\/a>    <span class=\"op\">&lt;<\/span><span class=\"ex\">Proxy<\/span> balancer:\/\/backend<span class=\"op\">&gt;<\/span><\/span>\n<span id=\"cb15-5\"><a href=\"#cb15-5\" aria-hidden=\"true\"><\/a>        <span class=\"ex\">BalancerMember<\/span> http:\/\/localhost:8000 route=backend-port-8000<\/span>\n<span id=\"cb15-6\"><a href=\"#cb15-6\" aria-hidden=\"true\"><\/a>        <span class=\"ex\">BalancerMember<\/span> http:\/\/localhost:8001 route=backend-port-8001<\/span>\n<span id=\"cb15-7\"><a href=\"#cb15-7\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb15-8\"><a href=\"#cb15-8\" aria-hidden=\"true\"><\/a>        <span class=\"ex\">Require<\/span> all granted<\/span>\n<span id=\"cb15-9\"><a href=\"#cb15-9\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb15-10\"><a href=\"#cb15-10\" aria-hidden=\"true\"><\/a>        <span class=\"ex\">Options<\/span> None<\/span>\n<span id=\"cb15-11\"><a href=\"#cb15-11\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb15-12\"><a href=\"#cb15-12\" aria-hidden=\"true\"><\/a>        <span class=\"ex\">ProxySet<\/span> enablereuse=on<\/span>\n<span id=\"cb15-13\"><a href=\"#cb15-13\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb15-14\"><a href=\"#cb15-14\" aria-hidden=\"true\"><\/a>    <span class=\"op\">&lt;<\/span>\/<span class=\"ex\">Proxy<\/span><span class=\"op\">&gt;<\/span><\/span><\/code><\/pre><\/div>\n<p>We are also defining two backends, one on the previously configured port 8000 and a second on port 8001. I recommend using <code>socat<\/code> to quickly set up this service on a second port and then to try it out. I have defined a number of different responses so we will be able to see from the HTTP response which backend has processed the request. This then looks like this:<\/p>\n<div class=\"sourceCode\" id=\"cb16\"><pre class=\"sourceCode bash\"><code class=\"sourceCode bash\"><span id=\"cb16-1\"><a href=\"#cb16-1\" aria-hidden=\"true\"><\/a>$<span class=\"op\">&gt;<\/span> <span class=\"ex\">curl<\/span> -v -k https:\/\/localhost\/service1\/index.html https:\/\/localhost\/service1\/index.html<\/span>\n<span id=\"cb16-2\"><a href=\"#cb16-2\" aria-hidden=\"true\"><\/a><span class=\"ex\">*<\/span> Rebuilt URL to: https:\/\/localhost:40443\/<\/span>\n<span id=\"cb16-3\"><a href=\"#cb16-3\" aria-hidden=\"true\"><\/a><span class=\"ex\">*<\/span>   Trying 127.0.0.1...<\/span>\n<span id=\"cb16-4\"><a href=\"#cb16-4\" aria-hidden=\"true\"><\/a><span class=\"ex\">*<\/span> Connected to localhost (127.0.0.1) <span class=\"ex\">port<\/span> 40443 (#0)<\/span>\n<span id=\"cb16-5\"><a href=\"#cb16-5\" aria-hidden=\"true\"><\/a><span class=\"ex\">*<\/span> found 173 certificates in \/etc\/ssl\/certs\/ca-certificates.crt<\/span>\n<span id=\"cb16-6\"><a href=\"#cb16-6\" aria-hidden=\"true\"><\/a><span class=\"ex\">*<\/span> found 697 certificates in \/etc\/ssl\/certs<\/span>\n<span id=\"cb16-7\"><a href=\"#cb16-7\" aria-hidden=\"true\"><\/a><span class=\"ex\">*<\/span> ALPN, offering http\/1.1<\/span>\n<span id=\"cb16-8\"><a href=\"#cb16-8\" aria-hidden=\"true\"><\/a><span class=\"ex\">*<\/span> SSL connection using TLS1.2 \/ ECDHE_RSA_AES_256_GCM_SHA384<\/span>\n<span id=\"cb16-9\"><a href=\"#cb16-9\" aria-hidden=\"true\"><\/a><span class=\"ex\">*<\/span>        server certificate verification SKIPPED<\/span>\n<span id=\"cb16-10\"><a href=\"#cb16-10\" aria-hidden=\"true\"><\/a><span class=\"ex\">*<\/span>        server certificate status verification SKIPPED<\/span>\n<span id=\"cb16-11\"><a href=\"#cb16-11\" aria-hidden=\"true\"><\/a><span class=\"ex\">*<\/span>        common name: ubuntu (does not match <span class=\"st\">&#39;localhost&#39;<\/span>)<\/span>\n<span id=\"cb16-12\"><a href=\"#cb16-12\" aria-hidden=\"true\"><\/a><span class=\"ex\">*<\/span>        server certificate expiration date OK<\/span>\n<span id=\"cb16-13\"><a href=\"#cb16-13\" aria-hidden=\"true\"><\/a><span class=\"ex\">*<\/span>        server certificate activation date OK<\/span>\n<span id=\"cb16-14\"><a href=\"#cb16-14\" aria-hidden=\"true\"><\/a><span class=\"ex\">*<\/span>        certificate public key: RSA<\/span>\n<span id=\"cb16-15\"><a href=\"#cb16-15\" aria-hidden=\"true\"><\/a><span class=\"ex\">*<\/span>        certificate version: #3<\/span>\n<span id=\"cb16-16\"><a href=\"#cb16-16\" aria-hidden=\"true\"><\/a><span class=\"ex\">*<\/span>        subject: CN=ubuntu<\/span>\n<span id=\"cb16-17\"><a href=\"#cb16-17\" aria-hidden=\"true\"><\/a><span class=\"ex\">*<\/span>        start date: Mon, 27 Feb 2017 20:46:21 GMT<\/span>\n<span id=\"cb16-18\"><a href=\"#cb16-18\" aria-hidden=\"true\"><\/a><span class=\"ex\">*<\/span>        expire date: Thu, 25 Feb 2027 20:46:21 GMT<\/span>\n<span id=\"cb16-19\"><a href=\"#cb16-19\" aria-hidden=\"true\"><\/a><span class=\"ex\">*<\/span>        issuer: CN=ubuntu<\/span>\n<span id=\"cb16-20\"><a href=\"#cb16-20\" aria-hidden=\"true\"><\/a><span class=\"ex\">*<\/span>        compression: NULL<\/span>\n<span id=\"cb16-21\"><a href=\"#cb16-21\" aria-hidden=\"true\"><\/a><span class=\"ex\">*<\/span> ALPN, server accepted to use http\/1.1<\/span>\n<span id=\"cb16-22\"><a href=\"#cb16-22\" aria-hidden=\"true\"><\/a><span class=\"op\">&gt;<\/span> <span class=\"ex\">GET<\/span> \/service1\/index.html HTTP\/1.1<\/span>\n<span id=\"cb16-23\"><a href=\"#cb16-23\" aria-hidden=\"true\"><\/a><span class=\"op\">&gt;<\/span> <span class=\"ex\">User-Agent<\/span>: curl\/7.35.0<\/span>\n<span id=\"cb16-24\"><a href=\"#cb16-24\" aria-hidden=\"true\"><\/a><span class=\"op\">&gt;<\/span> <span class=\"ex\">Host<\/span>: localhost<\/span>\n<span id=\"cb16-25\"><a href=\"#cb16-25\" aria-hidden=\"true\"><\/a><span class=\"op\">&gt;<\/span> <span class=\"ex\">Accept<\/span>: *\/*<\/span>\n<span id=\"cb16-26\"><a href=\"#cb16-26\" aria-hidden=\"true\"><\/a><span class=\"op\">&gt;<\/span> <\/span>\n<span id=\"cb16-27\"><a href=\"#cb16-27\" aria-hidden=\"true\"><\/a><span class=\"op\">&lt;<\/span> <span class=\"ex\">HTTP\/1.1<\/span> 200 <\/span>\n<span id=\"cb16-28\"><a href=\"#cb16-28\" aria-hidden=\"true\"><\/a><span class=\"op\">&lt;<\/span> <span class=\"ex\">Date<\/span>: Thu, 10 Dec 2015 05:42:14 GMT<\/span>\n<span id=\"cb16-29\"><a href=\"#cb16-29\" aria-hidden=\"true\"><\/a><span class=\"ex\">*<\/span> Server Apache is not blacklisted<\/span>\n<span id=\"cb16-30\"><a href=\"#cb16-30\" aria-hidden=\"true\"><\/a><span class=\"op\">&lt;<\/span> <span class=\"ex\">Server<\/span>: Apache<\/span>\n<span id=\"cb16-31\"><a href=\"#cb16-31\" aria-hidden=\"true\"><\/a><span class=\"op\">&lt;<\/span> <span class=\"ex\">Content-Type<\/span>: text\/plain<\/span>\n<span id=\"cb16-32\"><a href=\"#cb16-32\" aria-hidden=\"true\"><\/a><span class=\"op\">&lt;<\/span> <span class=\"ex\">Content-Length<\/span>: 28<\/span>\n<span id=\"cb16-33\"><a href=\"#cb16-33\" aria-hidden=\"true\"><\/a><span class=\"op\">&lt;<\/span> <\/span>\n<span id=\"cb16-34\"><a href=\"#cb16-34\" aria-hidden=\"true\"><\/a><span class=\"ex\">Server<\/span> response, port 8000<\/span>\n<span id=\"cb16-35\"><a href=\"#cb16-35\" aria-hidden=\"true\"><\/a><span class=\"ex\">*<\/span> Connection #0 to host localhost left intact<\/span>\n<span id=\"cb16-36\"><a href=\"#cb16-36\" aria-hidden=\"true\"><\/a><span class=\"ex\">*<\/span> Found bundle for host localhost: 0x24e3660<\/span>\n<span id=\"cb16-37\"><a href=\"#cb16-37\" aria-hidden=\"true\"><\/a><span class=\"ex\">*<\/span> Re-using existing connection! (#0) <span class=\"ex\">with<\/span> host localhost<\/span>\n<span id=\"cb16-38\"><a href=\"#cb16-38\" aria-hidden=\"true\"><\/a><span class=\"ex\">*<\/span> Connected to localhost (127.0.0.1) <span class=\"ex\">port<\/span> 443 (#0)<\/span>\n<span id=\"cb16-39\"><a href=\"#cb16-39\" aria-hidden=\"true\"><\/a><span class=\"op\">&gt;<\/span> <span class=\"ex\">GET<\/span> \/service1\/index.html HTTP\/1.1<\/span>\n<span id=\"cb16-40\"><a href=\"#cb16-40\" aria-hidden=\"true\"><\/a><span class=\"op\">&gt;<\/span> <span class=\"ex\">User-Agent<\/span>: curl\/7.35.0<\/span>\n<span id=\"cb16-41\"><a href=\"#cb16-41\" aria-hidden=\"true\"><\/a><span class=\"op\">&gt;<\/span> <span class=\"ex\">Host<\/span>: localhost<\/span>\n<span id=\"cb16-42\"><a href=\"#cb16-42\" aria-hidden=\"true\"><\/a><span class=\"op\">&gt;<\/span> <span class=\"ex\">Accept<\/span>: *\/*<\/span>\n<span id=\"cb16-43\"><a href=\"#cb16-43\" aria-hidden=\"true\"><\/a><span class=\"op\">&gt;<\/span> <\/span>\n<span id=\"cb16-44\"><a href=\"#cb16-44\" aria-hidden=\"true\"><\/a><span class=\"op\">&lt;<\/span> <span class=\"ex\">HTTP\/1.1<\/span> 200 <\/span>\n<span id=\"cb16-45\"><a href=\"#cb16-45\" aria-hidden=\"true\"><\/a><span class=\"op\">&lt;<\/span> <span class=\"ex\">Date<\/span>: Thu, 10 Dec 2015 05:42:14 GMT<\/span>\n<span id=\"cb16-46\"><a href=\"#cb16-46\" aria-hidden=\"true\"><\/a><span class=\"ex\">*<\/span> Server Apache is not blacklisted<\/span>\n<span id=\"cb16-47\"><a href=\"#cb16-47\" aria-hidden=\"true\"><\/a><span class=\"op\">&lt;<\/span> <span class=\"ex\">Server<\/span>: Apache<\/span>\n<span id=\"cb16-48\"><a href=\"#cb16-48\" aria-hidden=\"true\"><\/a><span class=\"op\">&lt;<\/span> <span class=\"ex\">Content-Type<\/span>: text\/plain<\/span>\n<span id=\"cb16-49\"><a href=\"#cb16-49\" aria-hidden=\"true\"><\/a><span class=\"op\">&lt;<\/span> <span class=\"ex\">Content-Length<\/span>: 28<\/span>\n<span id=\"cb16-50\"><a href=\"#cb16-50\" aria-hidden=\"true\"><\/a><span class=\"op\">&lt;<\/span> <\/span>\n<span id=\"cb16-51\"><a href=\"#cb16-51\" aria-hidden=\"true\"><\/a><span class=\"ex\">Server<\/span> response, port 8001<\/span>\n<span id=\"cb16-52\"><a href=\"#cb16-52\" aria-hidden=\"true\"><\/a><span class=\"ex\">*<\/span> Connection #0 to host localhost left intact<\/span><\/code><\/pre><\/div>\n<p>In this somewhat unusual curl call two identical request are being initiated via a single curl command. What\u2019s also interesting is the fact that with this method curl can use HTTP keep-alive. The first request lands on the first backend, and the second one on the second backend. Let\u2019s have a look at the entries for this in the reverse proxy\u2019s access log:<\/p>\n<div class=\"sourceCode\" id=\"cb17\"><pre class=\"sourceCode bash\"><code class=\"sourceCode bash\"><span id=\"cb17-1\"><a href=\"#cb17-1\" aria-hidden=\"true\"><\/a><span class=\"ex\">127.0.0.1<\/span> - - [2015-12-10 06:42:14.390998] <span class=\"st\">&quot;GET \/service1\/index.html HTTP\/1.1&quot;<\/span> 200 28 <span class=\"st\">&quot;-&quot;<\/span> <span class=\"st\">&quot;curl\/7.35.0&quot;<\/span><span class=\"kw\">\\<\/span><\/span>\n<span id=\"cb17-2\"><a href=\"#cb17-2\" aria-hidden=\"true\"><\/a><span class=\"ex\">localhost<\/span> 127.0.0.1 443 proxy-server backend-port-8000 + <span class=\"st\">&quot;-&quot;<\/span> VmkQtn8AAQEAAH@M3zAAAAAN TLSv1.2 <span class=\"kw\">\\<\/span><\/span>\n<span id=\"cb17-3\"><a href=\"#cb17-3\" aria-hidden=\"true\"><\/a><span class=\"ex\">ECDHE-RSA-AES256-GCM-SHA384<\/span> 538 1402 -% 7856 1216 3708 381 0 0<\/span>\n<span id=\"cb17-4\"><a href=\"#cb17-4\" aria-hidden=\"true\"><\/a><span class=\"ex\">127.0.0.1<\/span> - - [2015-12-10 06:42:14.398995] <span class=\"st\">&quot;GET \/service1\/index.html HTTP\/1.1&quot;<\/span> 200 28 <span class=\"st\">&quot;-&quot;<\/span> <span class=\"st\">&quot;curl\/7.35.0&quot;<\/span><span class=\"kw\">\\<\/span><\/span>\n<span id=\"cb17-5\"><a href=\"#cb17-5\" aria-hidden=\"true\"><\/a><span class=\"ex\">localhost<\/span> 127.0.0.1 443 proxy-server backend-port-8001 + <span class=\"st\">&quot;-&quot;<\/span> VmkQtn8AAQEAAH@M3zEAAAAN TLSv1.2 <span class=\"kw\">\\<\/span><\/span>\n<span id=\"cb17-6\"><a href=\"#cb17-6\" aria-hidden=\"true\"><\/a><span class=\"ex\">ECDHE-RSA-AES256-GCM-SHA384<\/span> 121 202 -% 7035 1121 3752 354 0 0<\/span><\/code><\/pre><\/div>\n<p>Besides the keep-alive header, the request handler is also of interest. The request was thus processed by the <code>proxy server handler<\/code>. We also see entries for the route, specifically the values defined as <code>backend-port-8000<\/code> and <code>backend-port-8001<\/code>. This makes it possible to determine from the server\u2019s access log the exact route a request took.<\/p>\n<p>In a subsequent tutorial we will be seeing that the proxy balancer can also be used in other situations. For the moment we will however be content with what is happening and will now be turning to RewriteMaps. A RewriteMap is an auxiliary structure which again increases the power of ModRewrite. Combined with the proxy server, flexibility rises substantially.<\/p>\n<h3 id=\"step-9-rewritemap-proxy\">Step 9: RewriteMap [proxy]<\/h3>\n<p>RewriteMaps come in a number of different variations. They works by assigning a value to a key parameter at every request. A hash table is a simple example. But it is then also possible to configure external scripts as a programmable RewriteMap. The following types of maps are possible:<\/p>\n<ul>\n<li>txt : A key value pair in a text file is searched for here.<\/li>\n<li>rnd : Several values can be specified for each key here. They are then selected at random.<\/li>\n<li>dbm : This variation works like the txt variation, but provides a big speed advantage as a binary hash table is used.<\/li>\n<li>int : This abbreviation stands for internal function and refers to a function from the following list: <code>toupper<\/code>, <code>tolower<\/code>, <code>escape<\/code> and <code>unescape<\/code>.<\/li>\n<li>prg : An external script is invoked in this variation. The script is started along with the server and each time the RewriteMap is accessed receives new input via STDIN.<\/li>\n<li>dbd und fastdbd : The response value is searched for in a database request.<\/li>\n<\/ul>\n<p>This list makes clear that RewriteMaps are extremely flexible and can be used in a variety of situations. Determining the backend for proxying is only one of many possible applications. In our example we want to ensure that the request from a specific client always goes to the same backend. There are a number of different ways of doing this, specifically, by setting a cookie. But we don\u2019t want to intervene in the requests. We could divide by network ranges. But how to prevent a large number of clients from a specific network range from all being taken to the same backend? Some kind of distribution has to take place. To do so, we combine ModSecurity with using ModRewrite and a RewriteMap. Let\u2019s have a look at it step by step.<\/p>\n<p>First, we calculate a hash value from the client\u2019s IP address. This means that we are converting the IP address into a seemingly random hexadecimal string using ModSecurity:<\/p>\n<div class=\"sourceCode\" id=\"cb18\"><pre class=\"sourceCode bash\"><code class=\"sourceCode bash\"><span id=\"cb18-1\"><a href=\"#cb18-1\" aria-hidden=\"true\"><\/a><span class=\"ex\">SecRule<\/span> REMOTE_ADDR   <span class=\"st\">&quot;^(.)&quot;<\/span> <span class=\"kw\">\\<\/span><\/span>\n<span id=\"cb18-2\"><a href=\"#cb18-2\" aria-hidden=\"true\"><\/a>   <span class=\"st\">&quot;phase:1,id:50001,capture,nolog,t:sha1,t:hexEncode,setenv:IPHashChar=%{TX.1}&quot;<\/span><\/span><\/code><\/pre><\/div>\n<p>We have used hexEncode to convert the binary hash value we generated using sha1 into readable characters. We then apply the regular expression to this value. \u201c^(.)\u201d means that we want to find a match on the first character. Of the ModSecurity flags that follow <code>capture<\/code> is of interest. It indicates that we want to capture the value in the parenthesis in the previous regex condition. We then put it into the IPHashChar environment variable.<\/p>\n<p>If there is any uncertainty as to whether this will really work, then the content of the variable <code>IPHashChar<\/code> can be printed and checked using <code>%{IPHashChar}e<\/code> in the server\u2019s access log. This brings us to RewriteMap and the request itself:<\/p>\n<div class=\"sourceCode\" id=\"cb19\"><pre class=\"sourceCode bash\"><code class=\"sourceCode bash\"><span id=\"cb19-1\"><a href=\"#cb19-1\" aria-hidden=\"true\"><\/a><span class=\"ex\">RewriteMap<\/span> hashchar2backend <span class=\"st\">&quot;txt:\/apache\/conf\/hashchar2backend.txt&quot;<\/span><\/span>\n<span id=\"cb19-2\"><a href=\"#cb19-2\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb19-3\"><a href=\"#cb19-3\" aria-hidden=\"true\"><\/a><span class=\"ex\">RewriteCond<\/span>     <span class=\"st\">&quot;%{ENV:IPHashChar}&quot;<\/span>     ^(.)<\/span>\n<span id=\"cb19-4\"><a href=\"#cb19-4\" aria-hidden=\"true\"><\/a><span class=\"ex\">RewriteRule<\/span>     ^\/service1\/(.*) <span class=\"kw\">\\<\/span><\/span>\n<span id=\"cb19-5\"><a href=\"#cb19-5\" aria-hidden=\"true\"><\/a>                     <span class=\"ex\">http<\/span>:\/\/<span class=\"va\">${hashchar2backend:<\/span><span class=\"er\">%1|<\/span><span class=\"va\">localhost:8000}<\/span>\/service1\/<span class=\"va\">$1<\/span> [proxy,last]<\/span>\n<span id=\"cb19-6\"><a href=\"#cb19-6\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb19-7\"><a href=\"#cb19-7\" aria-hidden=\"true\"><\/a><span class=\"op\">&lt;<\/span><span class=\"ex\">Proxy<\/span> http:\/\/localhost:8000\/service1<span class=\"op\">&gt;<\/span><\/span>\n<span id=\"cb19-8\"><a href=\"#cb19-8\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb19-9\"><a href=\"#cb19-9\" aria-hidden=\"true\"><\/a>    <span class=\"ex\">Require<\/span> all granted<\/span>\n<span id=\"cb19-10\"><a href=\"#cb19-10\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb19-11\"><a href=\"#cb19-11\" aria-hidden=\"true\"><\/a>    <span class=\"ex\">Options<\/span> None<\/span>\n<span id=\"cb19-12\"><a href=\"#cb19-12\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb19-13\"><a href=\"#cb19-13\" aria-hidden=\"true\"><\/a>    <span class=\"ex\">ProxySet<\/span> enablereuse=on<\/span>\n<span id=\"cb19-14\"><a href=\"#cb19-14\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb19-15\"><a href=\"#cb19-15\" aria-hidden=\"true\"><\/a><span class=\"op\">&lt;<\/span>\/<span class=\"ex\">Proxy<\/span><span class=\"op\">&gt;<\/span><\/span>\n<span id=\"cb19-16\"><a href=\"#cb19-16\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb19-17\"><a href=\"#cb19-17\" aria-hidden=\"true\"><\/a><span class=\"op\">&lt;<\/span><span class=\"ex\">Proxy<\/span> http:\/\/localhost:8001\/service1<span class=\"op\">&gt;<\/span><\/span>\n<span id=\"cb19-18\"><a href=\"#cb19-18\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb19-19\"><a href=\"#cb19-19\" aria-hidden=\"true\"><\/a>    <span class=\"ex\">Require<\/span> all granted<\/span>\n<span id=\"cb19-20\"><a href=\"#cb19-20\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb19-21\"><a href=\"#cb19-21\" aria-hidden=\"true\"><\/a>    <span class=\"ex\">Options<\/span> None<\/span>\n<span id=\"cb19-22\"><a href=\"#cb19-22\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb19-23\"><a href=\"#cb19-23\" aria-hidden=\"true\"><\/a>    <span class=\"ex\">ProxySet<\/span> enablereuse=on<\/span>\n<span id=\"cb19-24\"><a href=\"#cb19-24\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb19-25\"><a href=\"#cb19-25\" aria-hidden=\"true\"><\/a><span class=\"op\">&lt;<\/span>\/<span class=\"ex\">Proxy<\/span><span class=\"op\">&gt;<\/span><\/span><\/code><\/pre><\/div>\n<p>We introduce the map by using the RewriteMap command. We assign it a name, define its type and the path to the file. RewriteMap is invoked in a RewriteRule. Before we really access the map, we enable a rewrite condition. This is done using the RewriteCond directive. There we reference the IPHashChar environment variable and determine the first byte of the variable. We know that only a single byte is included in the variation, but this won\u2019t put a stop to our plans. On the next line then the typical start of the Proxy directive. But instead of now specifying the backend, we reference RewriteMap by the name previously assigned. After the colon comes the parameter for the request. Interestingly, we use <code>%1<\/code> to communicate with the rewrite conditions captured in parenthesis. The RewriteRule variable is not affected by this and continues to be referenced via <code>$1<\/code>. After the <code>%1<\/code> comes the default value separated by a pipe character. Should anything go wrong when accessing the map, then communication with localhost takes place over port 8000.<\/p>\n<p>All we need now is the RewriteMap. In the code sample we specified a text file. Better performance is provided by a hash file, but this is not the focus at present. Here\u2019s the <code>\/apache\/conf\/hashchar2backend.txt<\/code> map file:<\/p>\n<div class=\"sourceCode\" id=\"cb20\"><pre class=\"sourceCode bash\"><code class=\"sourceCode bash\"><span id=\"cb20-1\"><a href=\"#cb20-1\" aria-hidden=\"true\"><\/a><span class=\"co\">##<\/span><\/span>\n<span id=\"cb20-2\"><a href=\"#cb20-2\" aria-hidden=\"true\"><\/a><span class=\"co\">## RewriteMap linking hex characters with one of two backends<\/span><\/span>\n<span id=\"cb20-3\"><a href=\"#cb20-3\" aria-hidden=\"true\"><\/a><span class=\"co\">##<\/span><\/span>\n<span id=\"cb20-4\"><a href=\"#cb20-4\" aria-hidden=\"true\"><\/a><span class=\"ex\">1<\/span>   localhost:8000<\/span>\n<span id=\"cb20-5\"><a href=\"#cb20-5\" aria-hidden=\"true\"><\/a><span class=\"ex\">2<\/span>   localhost:8000<\/span>\n<span id=\"cb20-6\"><a href=\"#cb20-6\" aria-hidden=\"true\"><\/a><span class=\"ex\">3<\/span>   localhost:8000<\/span>\n<span id=\"cb20-7\"><a href=\"#cb20-7\" aria-hidden=\"true\"><\/a><span class=\"ex\">4<\/span>   localhost:8000<\/span>\n<span id=\"cb20-8\"><a href=\"#cb20-8\" aria-hidden=\"true\"><\/a><span class=\"ex\">5<\/span>   localhost:8000<\/span>\n<span id=\"cb20-9\"><a href=\"#cb20-9\" aria-hidden=\"true\"><\/a><span class=\"ex\">6<\/span>   localhost:8000<\/span>\n<span id=\"cb20-10\"><a href=\"#cb20-10\" aria-hidden=\"true\"><\/a><span class=\"ex\">7<\/span>   localhost:8000<\/span>\n<span id=\"cb20-11\"><a href=\"#cb20-11\" aria-hidden=\"true\"><\/a><span class=\"ex\">8<\/span>   localhost:8000<\/span>\n<span id=\"cb20-12\"><a href=\"#cb20-12\" aria-hidden=\"true\"><\/a><span class=\"ex\">9<\/span>   localhost:8001<\/span>\n<span id=\"cb20-13\"><a href=\"#cb20-13\" aria-hidden=\"true\"><\/a><span class=\"ex\">0<\/span>   localhost:8001<\/span>\n<span id=\"cb20-14\"><a href=\"#cb20-14\" aria-hidden=\"true\"><\/a><span class=\"ex\">a<\/span>   localhost:8001<\/span>\n<span id=\"cb20-15\"><a href=\"#cb20-15\" aria-hidden=\"true\"><\/a><span class=\"ex\">b<\/span>   localhost:8001<\/span>\n<span id=\"cb20-16\"><a href=\"#cb20-16\" aria-hidden=\"true\"><\/a><span class=\"ex\">c<\/span>   localhost:8001<\/span>\n<span id=\"cb20-17\"><a href=\"#cb20-17\" aria-hidden=\"true\"><\/a><span class=\"ex\">d<\/span>   localhost:8001<\/span>\n<span id=\"cb20-18\"><a href=\"#cb20-18\" aria-hidden=\"true\"><\/a><span class=\"ex\">e<\/span>   localhost:8001<\/span>\n<span id=\"cb20-19\"><a href=\"#cb20-19\" aria-hidden=\"true\"><\/a><span class=\"ex\">f<\/span>   localhost:8001<\/span><\/code><\/pre><\/div>\n<p>We are differentiating between two backends and can perform the distribution any way we want. All in all, this is more indicative of a complex recipe that we put together forming a hash for each IP address and using the first character in order to determine one of two backends in the hash tables we just saw. If the client IP address remains constant (which does not always have to be the case in practice) the result of this lookup will always be the same. This means that the client will always end up on the same backend. This is called IP stickiness. However, since this entail a hash operation and not a simple IP address lookup, two clients with a similar IP address will be given a completely different hash and will not necessarily end up on the same backend. This gives us a somewhat flat distribution of the requests yet we can still be sure that specific clients will always end up on the same backend until the IP address changes.<\/p>\n<h3 id=\"step-10-forwarding-information-to-backend-systems\">Step 10: Forwarding information to backend systems<\/h3>\n<p>The reverse proxy server shields the application server from direct client access. However, this also means that the application server is no longer able to see certain types of information about the client and its connection to the reverse proxy. To compensate for this loss, the Proxy module sets three HTTP request header lines that describe the reverse proxy:<\/p>\n<ul>\n<li>X-Forwarded-For : The IP address of the client<\/li>\n<li>X-Forwarded-Host : The original HTTP host header in the client request<\/li>\n<li>X-Forwarded-Server : The name of the reverse proxy server<\/li>\n<\/ul>\n<p>If multiple reverse proxies are staggered behind one another then the additional IP addresses and server names are comma separated. In addition to this information about the connection, it is also a good idea to pass along yet more information. This would of course include the unique ID, uniquely identifying the request. A well-configured backend server will create a key value similar to our reverse proxy in the log file. Being able to easily correlate the different log file entries simplifies debugging in the future.<\/p>\n<p>A reverse proxy is frequently used to perform authentication. Although we haven\u2019t set that up yet, it is still wise to add this value to an expanding basic configuration. If authentication is not defined, this value simply remains empty. And finally, we want to tell the backend system about the type of encryption the client and reverse proxy agreed upon. The entire block looks like this:<\/p>\n<div class=\"sourceCode\" id=\"cb21\"><pre class=\"sourceCode bash\"><code class=\"sourceCode bash\"><span id=\"cb21-1\"><a href=\"#cb21-1\" aria-hidden=\"true\"><\/a><span class=\"ex\">RequestHeader<\/span> set <span class=\"st\">&quot;X-RP-UNIQUE-ID&quot;<\/span>     <span class=\"st\">&quot;%{UNIQUE_ID}e&quot;<\/span><\/span>\n<span id=\"cb21-2\"><a href=\"#cb21-2\" aria-hidden=\"true\"><\/a><span class=\"ex\">RequestHeader<\/span> set <span class=\"st\">&quot;X-RP-REMOTE-USER&quot;<\/span>   <span class=\"st\">&quot;%{REMOTE_USER}e&quot;<\/span><\/span>\n<span id=\"cb21-3\"><a href=\"#cb21-3\" aria-hidden=\"true\"><\/a><span class=\"ex\">RequestHeader<\/span> set <span class=\"st\">&quot;X-RP-SSL-PROTOCOL&quot;<\/span>  <span class=\"st\">&quot;%{SSL_PROTOCOL}s&quot;<\/span><\/span>\n<span id=\"cb21-4\"><a href=\"#cb21-4\" aria-hidden=\"true\"><\/a><span class=\"ex\">RequestHeader<\/span> set <span class=\"st\">&quot;X-RP-SSL-CIPHER&quot;<\/span>    <span class=\"st\">&quot;%{SSL_CIPHER}s&quot;<\/span><\/span><\/code><\/pre><\/div>\n<p>Let\u2019s see how this affects the request between the reverse proxy and the backend:<\/p>\n<div class=\"sourceCode\" id=\"cb22\"><pre class=\"sourceCode bash\"><code class=\"sourceCode bash\"><span id=\"cb22-1\"><a href=\"#cb22-1\" aria-hidden=\"true\"><\/a><span class=\"ex\">GET<\/span> \/service1\/index.html HTTP\/1.1<\/span>\n<span id=\"cb22-2\"><a href=\"#cb22-2\" aria-hidden=\"true\"><\/a><span class=\"ex\">Host<\/span>: localhost<\/span>\n<span id=\"cb22-3\"><a href=\"#cb22-3\" aria-hidden=\"true\"><\/a><span class=\"ex\">User-Agent<\/span>: curl\/7.35.0<\/span>\n<span id=\"cb22-4\"><a href=\"#cb22-4\" aria-hidden=\"true\"><\/a><span class=\"ex\">Accept<\/span>: *\/*<\/span>\n<span id=\"cb22-5\"><a href=\"#cb22-5\" aria-hidden=\"true\"><\/a><span class=\"ex\">X-RP-UNIQUE-ID<\/span>: VmpSwH8AAQEAAG@hXBcAAAAC<\/span>\n<span id=\"cb22-6\"><a href=\"#cb22-6\" aria-hidden=\"true\"><\/a><span class=\"ex\">X-RP-REMOTE-USER<\/span>: (null)<\/span>\n<span id=\"cb22-7\"><a href=\"#cb22-7\" aria-hidden=\"true\"><\/a><span class=\"ex\">X-RP-SSL-PROTOCOL<\/span>: TLSv1.2<\/span>\n<span id=\"cb22-8\"><a href=\"#cb22-8\" aria-hidden=\"true\"><\/a><span class=\"ex\">X-RP-SSL-CIPHER<\/span>: ECDHE-RSA-AES256-GCM-SHA384<\/span>\n<span id=\"cb22-9\"><a href=\"#cb22-9\" aria-hidden=\"true\"><\/a><span class=\"ex\">X-Forwarded-For<\/span>: 127.0.0.1<\/span>\n<span id=\"cb22-10\"><a href=\"#cb22-10\" aria-hidden=\"true\"><\/a><span class=\"ex\">X-Forwarded-Host<\/span>: localhost<\/span>\n<span id=\"cb22-11\"><a href=\"#cb22-11\" aria-hidden=\"true\"><\/a><span class=\"ex\">X-Forwarded-Server<\/span>: localhost<\/span>\n<span id=\"cb22-12\"><a href=\"#cb22-12\" aria-hidden=\"true\"><\/a><span class=\"ex\">Connection<\/span>: close<\/span><\/code><\/pre><\/div>\n<p>The different extended header lines are listed sequentially and are filled in with values where present.<\/p>\n<h3 id=\"step-11-goodie-configuration-of-the-complete-reverse-proxy-server\">Step 11 (Goodie): Configuration of the complete reverse proxy server<\/h3>\n<p>This small extension brings us to the end of this tutorial and also to the end of the basic block of different tutorials. Over several tutorials we have seen how to set up an Apache web server for a lab, from compiling it to the basic configuration, and ModSecurity tuning to reverse proxies, gaining deep insight into the how of the server and its most important modules work.<\/p>\n<p>Now, here\u2019s the complete configuration for the reverse proxy server that we worked out in the last tutorials.<\/p>\n<div class=\"sourceCode\" id=\"cb23\"><pre class=\"sourceCode bash\"><code class=\"sourceCode bash\"><span id=\"cb23-1\"><a href=\"#cb23-1\" aria-hidden=\"true\"><\/a><span class=\"ex\">ServerName<\/span>        localhost<\/span>\n<span id=\"cb23-2\"><a href=\"#cb23-2\" aria-hidden=\"true\"><\/a><span class=\"ex\">ServerAdmin<\/span>       root@localhost<\/span>\n<span id=\"cb23-3\"><a href=\"#cb23-3\" aria-hidden=\"true\"><\/a><span class=\"ex\">ServerRoot<\/span>        \/apache<\/span>\n<span id=\"cb23-4\"><a href=\"#cb23-4\" aria-hidden=\"true\"><\/a><span class=\"ex\">User<\/span>              www-data<\/span>\n<span id=\"cb23-5\"><a href=\"#cb23-5\" aria-hidden=\"true\"><\/a><span class=\"ex\">Group<\/span>             www-data<\/span>\n<span id=\"cb23-6\"><a href=\"#cb23-6\" aria-hidden=\"true\"><\/a><span class=\"ex\">PidFile<\/span>           logs\/httpd.pid<\/span>\n<span id=\"cb23-7\"><a href=\"#cb23-7\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-8\"><a href=\"#cb23-8\" aria-hidden=\"true\"><\/a><span class=\"ex\">ServerTokens<\/span>      Prod<\/span>\n<span id=\"cb23-9\"><a href=\"#cb23-9\" aria-hidden=\"true\"><\/a><span class=\"ex\">UseCanonicalName<\/span>  On<\/span>\n<span id=\"cb23-10\"><a href=\"#cb23-10\" aria-hidden=\"true\"><\/a><span class=\"ex\">TraceEnable<\/span>       Off<\/span>\n<span id=\"cb23-11\"><a href=\"#cb23-11\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-12\"><a href=\"#cb23-12\" aria-hidden=\"true\"><\/a><span class=\"ex\">Timeout<\/span>           10<\/span>\n<span id=\"cb23-13\"><a href=\"#cb23-13\" aria-hidden=\"true\"><\/a><span class=\"ex\">MaxRequestWorkers<\/span> 100<\/span>\n<span id=\"cb23-14\"><a href=\"#cb23-14\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-15\"><a href=\"#cb23-15\" aria-hidden=\"true\"><\/a><span class=\"ex\">Listen<\/span>            127.0.0.1:80<\/span>\n<span id=\"cb23-16\"><a href=\"#cb23-16\" aria-hidden=\"true\"><\/a><span class=\"ex\">Listen<\/span>            127.0.0.1:443<\/span>\n<span id=\"cb23-17\"><a href=\"#cb23-17\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-18\"><a href=\"#cb23-18\" aria-hidden=\"true\"><\/a><span class=\"ex\">LoadModule<\/span>        mpm_event_module        modules\/mod_mpm_event.so<\/span>\n<span id=\"cb23-19\"><a href=\"#cb23-19\" aria-hidden=\"true\"><\/a><span class=\"ex\">LoadModule<\/span>        unixd_module            modules\/mod_unixd.so<\/span>\n<span id=\"cb23-20\"><a href=\"#cb23-20\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-21\"><a href=\"#cb23-21\" aria-hidden=\"true\"><\/a><span class=\"ex\">LoadModule<\/span>        log_config_module       modules\/mod_log_config.so<\/span>\n<span id=\"cb23-22\"><a href=\"#cb23-22\" aria-hidden=\"true\"><\/a><span class=\"ex\">LoadModule<\/span>        logio_module            modules\/mod_logio.so<\/span>\n<span id=\"cb23-23\"><a href=\"#cb23-23\" aria-hidden=\"true\"><\/a><span class=\"ex\">LoadModule<\/span>        rewrite_module          modules\/mod_rewrite.so<\/span>\n<span id=\"cb23-24\"><a href=\"#cb23-24\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-25\"><a href=\"#cb23-25\" aria-hidden=\"true\"><\/a><span class=\"ex\">LoadModule<\/span>        authn_core_module       modules\/mod_authn_core.so<\/span>\n<span id=\"cb23-26\"><a href=\"#cb23-26\" aria-hidden=\"true\"><\/a><span class=\"ex\">LoadModule<\/span>        authz_core_module       modules\/mod_authz_core.so<\/span>\n<span id=\"cb23-27\"><a href=\"#cb23-27\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-28\"><a href=\"#cb23-28\" aria-hidden=\"true\"><\/a><span class=\"ex\">LoadModule<\/span>        ssl_module              modules\/mod_ssl.so<\/span>\n<span id=\"cb23-29\"><a href=\"#cb23-29\" aria-hidden=\"true\"><\/a><span class=\"ex\">LoadModule<\/span>        headers_module          modules\/mod_headers.so<\/span>\n<span id=\"cb23-30\"><a href=\"#cb23-30\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-31\"><a href=\"#cb23-31\" aria-hidden=\"true\"><\/a><span class=\"ex\">LoadModule<\/span>        unique_id_module        modules\/mod_unique_id.so<\/span>\n<span id=\"cb23-32\"><a href=\"#cb23-32\" aria-hidden=\"true\"><\/a><span class=\"ex\">LoadModule<\/span>        security2_module        modules\/mod_security2.so<\/span>\n<span id=\"cb23-33\"><a href=\"#cb23-33\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-34\"><a href=\"#cb23-34\" aria-hidden=\"true\"><\/a><span class=\"ex\">LoadModule<\/span>        proxy_module            modules\/mod_proxy.so<\/span>\n<span id=\"cb23-35\"><a href=\"#cb23-35\" aria-hidden=\"true\"><\/a><span class=\"ex\">LoadModule<\/span>        proxy_http_module       modules\/mod_proxy_http.so<\/span>\n<span id=\"cb23-36\"><a href=\"#cb23-36\" aria-hidden=\"true\"><\/a><span class=\"ex\">LoadModule<\/span>        proxy_balancer_module   modules\/mod_proxy_balancer.so<\/span>\n<span id=\"cb23-37\"><a href=\"#cb23-37\" aria-hidden=\"true\"><\/a><span class=\"ex\">LoadModule<\/span>        lbmethod_byrequests_module modules\/mod_lbmethod_byrequests.so<\/span>\n<span id=\"cb23-38\"><a href=\"#cb23-38\" aria-hidden=\"true\"><\/a><span class=\"ex\">LoadModule<\/span>        slotmem_shm_module      modules\/mod_slotmem_shm.so<\/span>\n<span id=\"cb23-39\"><a href=\"#cb23-39\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-40\"><a href=\"#cb23-40\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-41\"><a href=\"#cb23-41\" aria-hidden=\"true\"><\/a><span class=\"ex\">ErrorLogFormat<\/span>          <span class=\"st\">&quot;[%{cu}t] [%-m:%-l] %-a %-L %M&quot;<\/span><\/span>\n<span id=\"cb23-42\"><a href=\"#cb23-42\" aria-hidden=\"true\"><\/a><span class=\"ex\">LogFormat<\/span> <span class=\"st\">&quot;%h %{GEOIP_COUNTRY_CODE}e %u [%{%Y-%m-%d %H:%M:%S}t.%{usec_frac}t] <\/span><span class=\"dt\">\\&quot;<\/span><span class=\"st\">%r<\/span><span class=\"dt\">\\&quot;<\/span><span class=\"st\"> %&gt;s %b \\<\/span><\/span>\n<span id=\"cb23-43\"><a href=\"#cb23-43\" aria-hidden=\"true\"><\/a><span class=\"dt\">\\&quot;<\/span><span class=\"st\">%{Referer}i<\/span><span class=\"dt\">\\&quot;<\/span><span class=\"st\"> <\/span><span class=\"dt\">\\&quot;<\/span><span class=\"st\">%{User-Agent}i<\/span><span class=\"dt\">\\&quot;<\/span><span class=\"st\"> <\/span><span class=\"dt\">\\&quot;<\/span><span class=\"st\">%{Content-Type}i<\/span><span class=\"dt\">\\&quot;<\/span><span class=\"st\"> %{remote}p %v %A %p %R \\<\/span><\/span>\n<span id=\"cb23-44\"><a href=\"#cb23-44\" aria-hidden=\"true\"><\/a><span class=\"st\">%{BALANCER_WORKER_ROUTE}e %X <\/span><span class=\"dt\">\\&quot;<\/span><span class=\"st\">%{cookie}n<\/span><span class=\"dt\">\\&quot;<\/span><span class=\"st\"> %{UNIQUE_ID}e %{SSL_PROTOCOL}x %{SSL_CIPHER}x \\<\/span><\/span>\n<span id=\"cb23-45\"><a href=\"#cb23-45\" aria-hidden=\"true\"><\/a><span class=\"st\">%I %O %{ratio}n%% %D %{ModSecTimeIn}e %{ApplicationTime}e %{ModSecTimeOut}e \\<\/span><\/span>\n<span id=\"cb23-46\"><a href=\"#cb23-46\" aria-hidden=\"true\"><\/a><span class=\"st\">%{ModSecAnomalyScoreInPLs}e %{ModSecAnomalyScoreOutPLs}e \\<\/span><\/span>\n<span id=\"cb23-47\"><a href=\"#cb23-47\" aria-hidden=\"true\"><\/a><span class=\"st\">%{ModSecAnomalyScoreIn}e %{ModSecAnomalyScoreOut}e&quot;<\/span> extended<\/span>\n<span id=\"cb23-48\"><a href=\"#cb23-48\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-49\"><a href=\"#cb23-49\" aria-hidden=\"true\"><\/a><span class=\"ex\">LogFormat<\/span> <span class=\"st\">&quot;[%{%Y-%m-%d %H:%M:%S}t.%{usec_frac}t] %{UNIQUE_ID}e %D \\<\/span><\/span>\n<span id=\"cb23-50\"><a href=\"#cb23-50\" aria-hidden=\"true\"><\/a><span class=\"st\">PerfModSecInbound: %{TX.perf_modsecinbound}M \\<\/span><\/span>\n<span id=\"cb23-51\"><a href=\"#cb23-51\" aria-hidden=\"true\"><\/a><span class=\"st\">PerfAppl: %{TX.perf_application}M \\<\/span><\/span>\n<span id=\"cb23-52\"><a href=\"#cb23-52\" aria-hidden=\"true\"><\/a><span class=\"st\">PerfModSecOutbound: %{TX.perf_modsecoutbound}M \\<\/span><\/span>\n<span id=\"cb23-53\"><a href=\"#cb23-53\" aria-hidden=\"true\"><\/a><span class=\"st\">TS-Phase1: %{TX.ModSecTimestamp1start}M-%{TX.ModSecTimestamp1end}M \\<\/span><\/span>\n<span id=\"cb23-54\"><a href=\"#cb23-54\" aria-hidden=\"true\"><\/a><span class=\"st\">TS-Phase2: %{TX.ModSecTimestamp2start}M-%{TX.ModSecTimestamp2end}M \\<\/span><\/span>\n<span id=\"cb23-55\"><a href=\"#cb23-55\" aria-hidden=\"true\"><\/a><span class=\"st\">TS-Phase3: %{TX.ModSecTimestamp3start}M-%{TX.ModSecTimestamp3end}M \\<\/span><\/span>\n<span id=\"cb23-56\"><a href=\"#cb23-56\" aria-hidden=\"true\"><\/a><span class=\"st\">TS-Phase4: %{TX.ModSecTimestamp4start}M-%{TX.ModSecTimestamp4end}M \\<\/span><\/span>\n<span id=\"cb23-57\"><a href=\"#cb23-57\" aria-hidden=\"true\"><\/a><span class=\"st\">TS-Phase5: %{TX.ModSecTimestamp5start}M-%{TX.ModSecTimestamp5end}M \\<\/span><\/span>\n<span id=\"cb23-58\"><a href=\"#cb23-58\" aria-hidden=\"true\"><\/a><span class=\"st\">Perf-Phase1: %{PERF_PHASE1}M \\<\/span><\/span>\n<span id=\"cb23-59\"><a href=\"#cb23-59\" aria-hidden=\"true\"><\/a><span class=\"st\">Perf-Phase2: %{PERF_PHASE2}M \\<\/span><\/span>\n<span id=\"cb23-60\"><a href=\"#cb23-60\" aria-hidden=\"true\"><\/a><span class=\"st\">Perf-Phase3: %{PERF_PHASE3}M \\<\/span><\/span>\n<span id=\"cb23-61\"><a href=\"#cb23-61\" aria-hidden=\"true\"><\/a><span class=\"st\">Perf-Phase4: %{PERF_PHASE4}M \\<\/span><\/span>\n<span id=\"cb23-62\"><a href=\"#cb23-62\" aria-hidden=\"true\"><\/a><span class=\"st\">Perf-Phase5: %{PERF_PHASE5}M \\<\/span><\/span>\n<span id=\"cb23-63\"><a href=\"#cb23-63\" aria-hidden=\"true\"><\/a><span class=\"st\">Perf-ReadingStorage: %{PERF_SREAD}M \\<\/span><\/span>\n<span id=\"cb23-64\"><a href=\"#cb23-64\" aria-hidden=\"true\"><\/a><span class=\"st\">Perf-WritingStorage: %{PERF_SWRITE}M \\<\/span><\/span>\n<span id=\"cb23-65\"><a href=\"#cb23-65\" aria-hidden=\"true\"><\/a><span class=\"st\">Perf-GarbageCollection: %{PERF_GC}M \\<\/span><\/span>\n<span id=\"cb23-66\"><a href=\"#cb23-66\" aria-hidden=\"true\"><\/a><span class=\"st\">Perf-ModSecLogging: %{PERF_LOGGING}M \\<\/span><\/span>\n<span id=\"cb23-67\"><a href=\"#cb23-67\" aria-hidden=\"true\"><\/a><span class=\"st\">Perf-ModSecCombined: %{PERF_COMBINED}M&quot;<\/span> perflog<\/span>\n<span id=\"cb23-68\"><a href=\"#cb23-68\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-69\"><a href=\"#cb23-69\" aria-hidden=\"true\"><\/a><span class=\"ex\">LogLevel<\/span>                      debug<\/span>\n<span id=\"cb23-70\"><a href=\"#cb23-70\" aria-hidden=\"true\"><\/a><span class=\"ex\">ErrorLog<\/span>                      logs\/error.log<\/span>\n<span id=\"cb23-71\"><a href=\"#cb23-71\" aria-hidden=\"true\"><\/a><span class=\"ex\">CustomLog<\/span>                     logs\/access.log extended<\/span>\n<span id=\"cb23-72\"><a href=\"#cb23-72\" aria-hidden=\"true\"><\/a><span class=\"ex\">CustomLog<\/span>                     logs\/modsec-perf.log perflog env=write_perflog<\/span>\n<span id=\"cb23-73\"><a href=\"#cb23-73\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-74\"><a href=\"#cb23-74\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-75\"><a href=\"#cb23-75\" aria-hidden=\"true\"><\/a><span class=\"co\"># == ModSec Base Configuration<\/span><\/span>\n<span id=\"cb23-76\"><a href=\"#cb23-76\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-77\"><a href=\"#cb23-77\" aria-hidden=\"true\"><\/a><span class=\"ex\">SecRuleEngine<\/span>                 On<\/span>\n<span id=\"cb23-78\"><a href=\"#cb23-78\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-79\"><a href=\"#cb23-79\" aria-hidden=\"true\"><\/a><span class=\"ex\">SecRequestBodyAccess<\/span>          On<\/span>\n<span id=\"cb23-80\"><a href=\"#cb23-80\" aria-hidden=\"true\"><\/a><span class=\"ex\">SecRequestBodyLimit<\/span>           10000000<\/span>\n<span id=\"cb23-81\"><a href=\"#cb23-81\" aria-hidden=\"true\"><\/a><span class=\"ex\">SecRequestBodyNoFilesLimit<\/span>    64000<\/span>\n<span id=\"cb23-82\"><a href=\"#cb23-82\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-83\"><a href=\"#cb23-83\" aria-hidden=\"true\"><\/a><span class=\"ex\">SecResponseBodyAccess<\/span>         On<\/span>\n<span id=\"cb23-84\"><a href=\"#cb23-84\" aria-hidden=\"true\"><\/a><span class=\"ex\">SecResponseBodyLimit<\/span>          10000000<\/span>\n<span id=\"cb23-85\"><a href=\"#cb23-85\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-86\"><a href=\"#cb23-86\" aria-hidden=\"true\"><\/a><span class=\"ex\">SecPcreMatchLimit<\/span>             100000<\/span>\n<span id=\"cb23-87\"><a href=\"#cb23-87\" aria-hidden=\"true\"><\/a><span class=\"ex\">SecPcreMatchLimitRecursion<\/span>    100000<\/span>\n<span id=\"cb23-88\"><a href=\"#cb23-88\" aria-hidden=\"true\"><\/a> <span class=\"ex\">SecRequestBodyJsonDepthLimit<\/span> 16<\/span>\n<span id=\"cb23-89\"><a href=\"#cb23-89\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-90\"><a href=\"#cb23-90\" aria-hidden=\"true\"><\/a><span class=\"ex\">SecTmpDir<\/span>                     \/tmp\/<\/span>\n<span id=\"cb23-91\"><a href=\"#cb23-91\" aria-hidden=\"true\"><\/a><span class=\"ex\">SecUploadDir<\/span>                  \/tmp\/<\/span>\n<span id=\"cb23-92\"><a href=\"#cb23-92\" aria-hidden=\"true\"><\/a><span class=\"ex\">SecDataDir<\/span>                    \/tmp\/<\/span>\n<span id=\"cb23-93\"><a href=\"#cb23-93\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-94\"><a href=\"#cb23-94\" aria-hidden=\"true\"><\/a><span class=\"ex\">SecDebugLog<\/span>                   \/apache\/logs\/modsec_debug.log<\/span>\n<span id=\"cb23-95\"><a href=\"#cb23-95\" aria-hidden=\"true\"><\/a><span class=\"ex\">SecDebugLogLevel<\/span>              0<\/span>\n<span id=\"cb23-96\"><a href=\"#cb23-96\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-97\"><a href=\"#cb23-97\" aria-hidden=\"true\"><\/a><span class=\"ex\">SecAuditEngine<\/span>                RelevantOnly<\/span>\n<span id=\"cb23-98\"><a href=\"#cb23-98\" aria-hidden=\"true\"><\/a><span class=\"ex\">SecAuditLogRelevantStatus<\/span>     <span class=\"st\">&quot;^(?:5|4(?!04))&quot;<\/span><\/span>\n<span id=\"cb23-99\"><a href=\"#cb23-99\" aria-hidden=\"true\"><\/a><span class=\"ex\">SecAuditLogParts<\/span>              ABEFHIJKZ<\/span>\n<span id=\"cb23-100\"><a href=\"#cb23-100\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-101\"><a href=\"#cb23-101\" aria-hidden=\"true\"><\/a><span class=\"ex\">SecAuditLogType<\/span>               Concurrent<\/span>\n<span id=\"cb23-102\"><a href=\"#cb23-102\" aria-hidden=\"true\"><\/a><span class=\"ex\">SecAuditLog<\/span>                   \/apache\/logs\/modsec_audit.log<\/span>\n<span id=\"cb23-103\"><a href=\"#cb23-103\" aria-hidden=\"true\"><\/a><span class=\"ex\">SecAuditLogStorageDir<\/span>         \/apache\/logs\/audit\/<\/span>\n<span id=\"cb23-104\"><a href=\"#cb23-104\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-105\"><a href=\"#cb23-105\" aria-hidden=\"true\"><\/a><span class=\"ex\">SecDefaultAction<\/span>              <span class=\"st\">&quot;phase:2,pass,log,tag:&#39;Local Lab Service&#39;&quot;<\/span><\/span>\n<span id=\"cb23-106\"><a href=\"#cb23-106\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-107\"><a href=\"#cb23-107\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-108\"><a href=\"#cb23-108\" aria-hidden=\"true\"><\/a><span class=\"co\"># == ModSec Rule ID Namespace Definition<\/span><\/span>\n<span id=\"cb23-109\"><a href=\"#cb23-109\" aria-hidden=\"true\"><\/a><span class=\"co\"># Service-specific before Core Rule Set: 10000 -  49999<\/span><\/span>\n<span id=\"cb23-110\"><a href=\"#cb23-110\" aria-hidden=\"true\"><\/a><span class=\"co\"># Service-specific after Core Rule Set:  50000 -  79999<\/span><\/span>\n<span id=\"cb23-111\"><a href=\"#cb23-111\" aria-hidden=\"true\"><\/a><span class=\"co\"># Locally shared rules:                  80000 -  99999<\/span><\/span>\n<span id=\"cb23-112\"><a href=\"#cb23-112\" aria-hidden=\"true\"><\/a><span class=\"co\">#  - Performance:                        90000 -  90199<\/span><\/span>\n<span id=\"cb23-113\"><a href=\"#cb23-113\" aria-hidden=\"true\"><\/a><span class=\"co\"># Recommended ModSec Rules (few):       200000 - 200010<\/span><\/span>\n<span id=\"cb23-114\"><a href=\"#cb23-114\" aria-hidden=\"true\"><\/a><span class=\"co\"># OWASP Core Rule Set:                  900000 - 999999<\/span><\/span>\n<span id=\"cb23-115\"><a href=\"#cb23-115\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-116\"><a href=\"#cb23-116\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-117\"><a href=\"#cb23-117\" aria-hidden=\"true\"><\/a><span class=\"co\"># === ModSec timestamps at the start of each phase (ids: 90000 - 90009)<\/span><\/span>\n<span id=\"cb23-118\"><a href=\"#cb23-118\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-119\"><a href=\"#cb23-119\" aria-hidden=\"true\"><\/a><span class=\"ex\">SecAction<\/span> <span class=\"st\">&quot;id:90000,phase:1,nolog,pass,setvar:TX.ModSecTimestamp1start=%{DURATION}&quot;<\/span><\/span>\n<span id=\"cb23-120\"><a href=\"#cb23-120\" aria-hidden=\"true\"><\/a><span class=\"ex\">SecAction<\/span> <span class=\"st\">&quot;id:90001,phase:2,nolog,pass,setvar:TX.ModSecTimestamp2start=%{DURATION}&quot;<\/span><\/span>\n<span id=\"cb23-121\"><a href=\"#cb23-121\" aria-hidden=\"true\"><\/a><span class=\"ex\">SecAction<\/span> <span class=\"st\">&quot;id:90002,phase:3,nolog,pass,setvar:TX.ModSecTimestamp3start=%{DURATION}&quot;<\/span><\/span>\n<span id=\"cb23-122\"><a href=\"#cb23-122\" aria-hidden=\"true\"><\/a><span class=\"ex\">SecAction<\/span> <span class=\"st\">&quot;id:90003,phase:4,nolog,pass,setvar:TX.ModSecTimestamp4start=%{DURATION}&quot;<\/span><\/span>\n<span id=\"cb23-123\"><a href=\"#cb23-123\" aria-hidden=\"true\"><\/a><span class=\"ex\">SecAction<\/span> <span class=\"st\">&quot;id:90004,phase:5,nolog,pass,setvar:TX.ModSecTimestamp5start=%{DURATION}&quot;<\/span><\/span>\n<span id=\"cb23-124\"><a href=\"#cb23-124\" aria-hidden=\"true\"><\/a>                      <\/span>\n<span id=\"cb23-125\"><a href=\"#cb23-125\" aria-hidden=\"true\"><\/a><span class=\"co\"># SecRule REQUEST_FILENAME &quot;@beginsWith \/&quot; \\<\/span><\/span>\n<span id=\"cb23-126\"><a href=\"#cb23-126\" aria-hidden=\"true\"><\/a><span class=\"co\">#    &quot;id:90005,phase:5,t:none,nolog,noauditlog,pass,setenv:write_perflog&quot;<\/span><\/span>\n<span id=\"cb23-127\"><a href=\"#cb23-127\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-128\"><a href=\"#cb23-128\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-129\"><a href=\"#cb23-129\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-130\"><a href=\"#cb23-130\" aria-hidden=\"true\"><\/a><span class=\"co\"># === ModSec Recommended Rules (in modsec src package) (ids: 200000-200010)<\/span><\/span>\n<span id=\"cb23-131\"><a href=\"#cb23-131\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-132\"><a href=\"#cb23-132\" aria-hidden=\"true\"><\/a><span class=\"ex\">SecRule<\/span> REQUEST_HEADERS:Content-Type <span class=\"st\">&quot;(?:application(?:\/soap\\+|\/)|text\/)xml&quot;<\/span> <span class=\"kw\">\\<\/span><\/span>\n<span id=\"cb23-133\"><a href=\"#cb23-133\" aria-hidden=\"true\"><\/a>  <span class=\"st\">&quot;id:200000,phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=XML&quot;<\/span><\/span>\n<span id=\"cb23-134\"><a href=\"#cb23-134\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-135\"><a href=\"#cb23-135\" aria-hidden=\"true\"><\/a><span class=\"ex\">SecRule<\/span> REQUEST_HEADERS:Content-Type <span class=\"st\">&quot;application\/json&quot;<\/span> <span class=\"kw\">\\<\/span><\/span>\n<span id=\"cb23-136\"><a href=\"#cb23-136\" aria-hidden=\"true\"><\/a>  <span class=\"st\">&quot;id:200001,phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=JSON&quot;<\/span><\/span>\n<span id=\"cb23-137\"><a href=\"#cb23-137\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-138\"><a href=\"#cb23-138\" aria-hidden=\"true\"><\/a><span class=\"ex\">SecRule<\/span> REQBODY_ERROR <span class=\"st\">&quot;!@eq 0&quot;<\/span> <span class=\"kw\">\\<\/span><\/span>\n<span id=\"cb23-139\"><a href=\"#cb23-139\" aria-hidden=\"true\"><\/a>  <span class=\"st\">&quot;id:200002,phase:2,t:none,deny,status:400,log,msg:&#39;Failed to parse request body.&#39;,\\<\/span><\/span>\n<span id=\"cb23-140\"><a href=\"#cb23-140\" aria-hidden=\"true\"><\/a><span class=\"st\">logdata:&#39;%{reqbody_error_msg}&#39;,severity:2&quot;<\/span><\/span>\n<span id=\"cb23-141\"><a href=\"#cb23-141\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-142\"><a href=\"#cb23-142\" aria-hidden=\"true\"><\/a><span class=\"ex\">SecRule<\/span> MULTIPART_STRICT_ERROR <span class=\"st\">&quot;!@eq 0&quot;<\/span> <span class=\"kw\">\\<\/span><\/span>\n<span id=\"cb23-143\"><a href=\"#cb23-143\" aria-hidden=\"true\"><\/a><span class=\"st\">&quot;id:200003,phase:2,t:none,log,deny,status:403, \\<\/span><\/span>\n<span id=\"cb23-144\"><a href=\"#cb23-144\" aria-hidden=\"true\"><\/a><span class=\"st\">msg:&#39;Multipart request body failed strict validation: \\<\/span><\/span>\n<span id=\"cb23-145\"><a href=\"#cb23-145\" aria-hidden=\"true\"><\/a><span class=\"st\">PE %{REQBODY_PROCESSOR_ERROR}, \\<\/span><\/span>\n<span id=\"cb23-146\"><a href=\"#cb23-146\" aria-hidden=\"true\"><\/a><span class=\"st\">BQ %{MULTIPART_BOUNDARY_QUOTED}, \\<\/span><\/span>\n<span id=\"cb23-147\"><a href=\"#cb23-147\" aria-hidden=\"true\"><\/a><span class=\"st\">BW %{MULTIPART_BOUNDARY_WHITESPACE}, \\<\/span><\/span>\n<span id=\"cb23-148\"><a href=\"#cb23-148\" aria-hidden=\"true\"><\/a><span class=\"st\">DB %{MULTIPART_DATA_BEFORE}, \\<\/span><\/span>\n<span id=\"cb23-149\"><a href=\"#cb23-149\" aria-hidden=\"true\"><\/a><span class=\"st\">DA %{MULTIPART_DATA_AFTER}, \\<\/span><\/span>\n<span id=\"cb23-150\"><a href=\"#cb23-150\" aria-hidden=\"true\"><\/a><span class=\"st\">HF %{MULTIPART_HEADER_FOLDING}, \\<\/span><\/span>\n<span id=\"cb23-151\"><a href=\"#cb23-151\" aria-hidden=\"true\"><\/a><span class=\"st\">LF %{MULTIPART_LF_LINE}, \\<\/span><\/span>\n<span id=\"cb23-152\"><a href=\"#cb23-152\" aria-hidden=\"true\"><\/a><span class=\"st\">SM %{MULTIPART_MISSING_SEMICOLON}, \\<\/span><\/span>\n<span id=\"cb23-153\"><a href=\"#cb23-153\" aria-hidden=\"true\"><\/a><span class=\"st\">IQ %{MULTIPART_INVALID_QUOTING}, \\<\/span><\/span>\n<span id=\"cb23-154\"><a href=\"#cb23-154\" aria-hidden=\"true\"><\/a><span class=\"st\">IP %{MULTIPART_INVALID_PART}, \\<\/span><\/span>\n<span id=\"cb23-155\"><a href=\"#cb23-155\" aria-hidden=\"true\"><\/a><span class=\"st\">IH %{MULTIPART_INVALID_HEADER_FOLDING}, \\<\/span><\/span>\n<span id=\"cb23-156\"><a href=\"#cb23-156\" aria-hidden=\"true\"><\/a><span class=\"st\">FL %{MULTIPART_FILE_LIMIT_EXCEEDED}&#39;&quot;<\/span><\/span>\n<span id=\"cb23-157\"><a href=\"#cb23-157\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-158\"><a href=\"#cb23-158\" aria-hidden=\"true\"><\/a><span class=\"ex\">SecRule<\/span> TX:\/^MSC_\/ <span class=\"st\">&quot;!@streq 0&quot;<\/span> <span class=\"kw\">\\<\/span><\/span>\n<span id=\"cb23-159\"><a href=\"#cb23-159\" aria-hidden=\"true\"><\/a>  <span class=\"st\">&quot;id:200005,phase:2,t:none,deny,status:500,\\<\/span><\/span>\n<span id=\"cb23-160\"><a href=\"#cb23-160\" aria-hidden=\"true\"><\/a><span class=\"st\">  msg:&#39;ModSecurity internal error flagged: %{MATCHED_VAR_NAME}&#39;&quot;<\/span><\/span>\n<span id=\"cb23-161\"><a href=\"#cb23-161\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-162\"><a href=\"#cb23-162\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-163\"><a href=\"#cb23-163\" aria-hidden=\"true\"><\/a><span class=\"co\"># === ModSec Core Rule Set Base Configuration (ids: 900000-900999)<\/span><\/span>\n<span id=\"cb23-164\"><a href=\"#cb23-164\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-165\"><a href=\"#cb23-165\" aria-hidden=\"true\"><\/a><span class=\"ex\">Include<\/span>    \/apache\/conf\/crs\/crs-setup.conf<\/span>\n<span id=\"cb23-166\"><a href=\"#cb23-166\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-167\"><a href=\"#cb23-167\" aria-hidden=\"true\"><\/a><span class=\"ex\">SecAction<\/span> <span class=\"st\">&quot;id:900110,phase:1,pass,nolog,\\<\/span><\/span>\n<span id=\"cb23-168\"><a href=\"#cb23-168\" aria-hidden=\"true\"><\/a><span class=\"st\">  setvar:tx.inbound_anomaly_score_threshold=5,\\<\/span><\/span>\n<span id=\"cb23-169\"><a href=\"#cb23-169\" aria-hidden=\"true\"><\/a><span class=\"st\">  setvar:tx.outbound_anomaly_score_threshold=4&quot;<\/span><\/span>\n<span id=\"cb23-170\"><a href=\"#cb23-170\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-171\"><a href=\"#cb23-171\" aria-hidden=\"true\"><\/a><span class=\"ex\">SecAction<\/span> <span class=\"st\">&quot;id:900000,phase:1,pass,nolog,\\<\/span><\/span>\n<span id=\"cb23-172\"><a href=\"#cb23-172\" aria-hidden=\"true\"><\/a><span class=\"st\">  setvar:tx.paranoia_level=1&quot;<\/span><\/span>\n<span id=\"cb23-173\"><a href=\"#cb23-173\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-174\"><a href=\"#cb23-174\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-175\"><a href=\"#cb23-175\" aria-hidden=\"true\"><\/a><span class=\"co\"># === ModSec Core Rule Set: Runtime Exclusion Rules (ids: 10000-49999)<\/span><\/span>\n<span id=\"cb23-176\"><a href=\"#cb23-176\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-177\"><a href=\"#cb23-177\" aria-hidden=\"true\"><\/a><span class=\"co\"># ...<\/span><\/span>\n<span id=\"cb23-178\"><a href=\"#cb23-178\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-179\"><a href=\"#cb23-179\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-180\"><a href=\"#cb23-180\" aria-hidden=\"true\"><\/a><span class=\"co\"># === ModSecurity Core Rule Set Inclusion<\/span><\/span>\n<span id=\"cb23-181\"><a href=\"#cb23-181\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-182\"><a href=\"#cb23-182\" aria-hidden=\"true\"><\/a><span class=\"ex\">Include<\/span>    \/apache\/conf\/crs\/rules\/*.conf<\/span>\n<span id=\"cb23-183\"><a href=\"#cb23-183\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-184\"><a href=\"#cb23-184\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-185\"><a href=\"#cb23-185\" aria-hidden=\"true\"><\/a><span class=\"co\"># === ModSec Core Rule Set: Startup Time Rules Exclusions<\/span><\/span>\n<span id=\"cb23-186\"><a href=\"#cb23-186\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-187\"><a href=\"#cb23-187\" aria-hidden=\"true\"><\/a><span class=\"co\"># ...<\/span><\/span>\n<span id=\"cb23-188\"><a href=\"#cb23-188\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-189\"><a href=\"#cb23-189\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-190\"><a href=\"#cb23-190\" aria-hidden=\"true\"><\/a><span class=\"co\"># === ModSec timestamps at the end of each phase (ids: 90010 - 90019)<\/span><\/span>\n<span id=\"cb23-191\"><a href=\"#cb23-191\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-192\"><a href=\"#cb23-192\" aria-hidden=\"true\"><\/a><span class=\"ex\">SecAction<\/span> <span class=\"st\">&quot;id:90010,phase:1,pass,nolog,setvar:TX.ModSecTimestamp1end=%{DURATION}&quot;<\/span><\/span>\n<span id=\"cb23-193\"><a href=\"#cb23-193\" aria-hidden=\"true\"><\/a><span class=\"ex\">SecAction<\/span> <span class=\"st\">&quot;id:90011,phase:2,pass,nolog,setvar:TX.ModSecTimestamp2end=%{DURATION}&quot;<\/span><\/span>\n<span id=\"cb23-194\"><a href=\"#cb23-194\" aria-hidden=\"true\"><\/a><span class=\"ex\">SecAction<\/span> <span class=\"st\">&quot;id:90012,phase:3,pass,nolog,setvar:TX.ModSecTimestamp3end=%{DURATION}&quot;<\/span><\/span>\n<span id=\"cb23-195\"><a href=\"#cb23-195\" aria-hidden=\"true\"><\/a><span class=\"ex\">SecAction<\/span> <span class=\"st\">&quot;id:90013,phase:4,pass,nolog,setvar:TX.ModSecTimestamp4end=%{DURATION}&quot;<\/span><\/span>\n<span id=\"cb23-196\"><a href=\"#cb23-196\" aria-hidden=\"true\"><\/a><span class=\"ex\">SecAction<\/span> <span class=\"st\">&quot;id:90014,phase:5,pass,nolog,setvar:TX.ModSecTimestamp5end=%{DURATION}&quot;<\/span><\/span>\n<span id=\"cb23-197\"><a href=\"#cb23-197\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-198\"><a href=\"#cb23-198\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-199\"><a href=\"#cb23-199\" aria-hidden=\"true\"><\/a><span class=\"co\"># === ModSec performance calculations and variable export (ids: 90100 - 90199)<\/span><\/span>\n<span id=\"cb23-200\"><a href=\"#cb23-200\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-201\"><a href=\"#cb23-201\" aria-hidden=\"true\"><\/a><span class=\"ex\">SecAction<\/span> <span class=\"st\">&quot;id:90100,phase:5,pass,nolog,\\<\/span><\/span>\n<span id=\"cb23-202\"><a href=\"#cb23-202\" aria-hidden=\"true\"><\/a><span class=\"st\">  setvar:TX.perf_modsecinbound=%{PERF_PHASE1},\\<\/span><\/span>\n<span id=\"cb23-203\"><a href=\"#cb23-203\" aria-hidden=\"true\"><\/a><span class=\"st\">  setvar:TX.perf_modsecinbound=+%{PERF_PHASE2},\\<\/span><\/span>\n<span id=\"cb23-204\"><a href=\"#cb23-204\" aria-hidden=\"true\"><\/a><span class=\"st\">  setvar:TX.perf_application=%{TX.ModSecTimestamp3start},\\<\/span><\/span>\n<span id=\"cb23-205\"><a href=\"#cb23-205\" aria-hidden=\"true\"><\/a><span class=\"st\">  setvar:TX.perf_application=-%{TX.ModSecTimestamp2end},\\<\/span><\/span>\n<span id=\"cb23-206\"><a href=\"#cb23-206\" aria-hidden=\"true\"><\/a><span class=\"st\">  setvar:TX.perf_modsecoutbound=%{PERF_PHASE3},\\<\/span><\/span>\n<span id=\"cb23-207\"><a href=\"#cb23-207\" aria-hidden=\"true\"><\/a><span class=\"st\">  setvar:TX.perf_modsecoutbound=+%{PERF_PHASE4},\\<\/span><\/span>\n<span id=\"cb23-208\"><a href=\"#cb23-208\" aria-hidden=\"true\"><\/a><span class=\"st\">  setenv:ModSecTimeIn=%{TX.perf_modsecinbound},\\<\/span><\/span>\n<span id=\"cb23-209\"><a href=\"#cb23-209\" aria-hidden=\"true\"><\/a><span class=\"st\">  setenv:ApplicationTime=%{TX.perf_application},\\<\/span><\/span>\n<span id=\"cb23-210\"><a href=\"#cb23-210\" aria-hidden=\"true\"><\/a><span class=\"st\">  setenv:ModSecTimeOut=%{TX.perf_modsecoutbound},\\<\/span><\/span>\n<span id=\"cb23-211\"><a href=\"#cb23-211\" aria-hidden=\"true\"><\/a><span class=\"st\">  setenv:ModSecAnomalyScoreInPLs=%{tx.anomaly_score_pl1}-%{tx.anomaly_score_pl2}-%{tx.anomaly_score_pl3}-%{tx.anomaly_score_pl4},\\<\/span><\/span>\n<span id=\"cb23-212\"><a href=\"#cb23-212\" aria-hidden=\"true\"><\/a><span class=\"st\">  setenv:ModSecAnomalyScoreOutPLs=%{tx.outbound_anomaly_score_pl1}-%{tx.outbound_anomaly_score_pl2}-%{tx.outbound_anomaly_score_pl3}-%{tx.outbound_anomaly_score_pl4},\\<\/span><\/span>\n<span id=\"cb23-213\"><a href=\"#cb23-213\" aria-hidden=\"true\"><\/a><span class=\"st\">  setenv:ModSecAnomalyScoreIn=%{TX.anomaly_score},\\<\/span><\/span>\n<span id=\"cb23-214\"><a href=\"#cb23-214\" aria-hidden=\"true\"><\/a><span class=\"st\">  setenv:ModSecAnomalyScoreOut=%{TX.outbound_anomaly_score}&quot;<\/span><\/span>\n<span id=\"cb23-215\"><a href=\"#cb23-215\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-216\"><a href=\"#cb23-216\" aria-hidden=\"true\"><\/a><span class=\"co\"># === ModSec finished<\/span><\/span>\n<span id=\"cb23-217\"><a href=\"#cb23-217\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-218\"><a href=\"#cb23-218\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-219\"><a href=\"#cb23-219\" aria-hidden=\"true\"><\/a><span class=\"ex\">RewriteEngine<\/span>           On<\/span>\n<span id=\"cb23-220\"><a href=\"#cb23-220\" aria-hidden=\"true\"><\/a><span class=\"ex\">RewriteOptions<\/span>          InheritDownBefore<\/span>\n<span id=\"cb23-221\"><a href=\"#cb23-221\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-222\"><a href=\"#cb23-222\" aria-hidden=\"true\"><\/a><span class=\"ex\">RewriteRule<\/span>             ^\/$  %<span class=\"dt\">{REQUEST_SCHEME}<\/span>:\/\/%<span class=\"dt\">{HTTP_HOST}<\/span>\/index.html  [redirect,last]<\/span>\n<span id=\"cb23-223\"><a href=\"#cb23-223\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-224\"><a href=\"#cb23-224\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-225\"><a href=\"#cb23-225\" aria-hidden=\"true\"><\/a><span class=\"ex\">SSLCertificateKeyFile<\/span>   \/etc\/ssl\/private\/ssl-cert-snakeoil.key<\/span>\n<span id=\"cb23-226\"><a href=\"#cb23-226\" aria-hidden=\"true\"><\/a><span class=\"ex\">SSLCertificateFile<\/span>      \/etc\/ssl\/certs\/ssl-cert-snakeoil.pem<\/span>\n<span id=\"cb23-227\"><a href=\"#cb23-227\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-228\"><a href=\"#cb23-228\" aria-hidden=\"true\"><\/a><span class=\"ex\">SSLProtocol<\/span>             All -SSLv2 -SSLv3 -TLSv1 -TLSv1.1<\/span>\n<span id=\"cb23-229\"><a href=\"#cb23-229\" aria-hidden=\"true\"><\/a><span class=\"ex\">SSLCipherSuite<\/span>          <span class=\"st\">&#39;kEECDH+ECDSA kEECDH kEDH HIGH +SHA !aNULL !eNULL !LOW !MEDIUM !MD5 !EXP !DSS \\<\/span><\/span>\n<span id=\"cb23-230\"><a href=\"#cb23-230\" aria-hidden=\"true\"><\/a><span class=\"st\">!PSK !SRP !kECDH !CAMELLIA !RC4&#39;<\/span><\/span>\n<span id=\"cb23-231\"><a href=\"#cb23-231\" aria-hidden=\"true\"><\/a><span class=\"ex\">SSLHonorCipherOrder<\/span>     On<\/span>\n<span id=\"cb23-232\"><a href=\"#cb23-232\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-233\"><a href=\"#cb23-233\" aria-hidden=\"true\"><\/a><span class=\"ex\">SSLRandomSeed<\/span>           startup file:\/dev\/urandom 2048<\/span>\n<span id=\"cb23-234\"><a href=\"#cb23-234\" aria-hidden=\"true\"><\/a><span class=\"ex\">SSLRandomSeed<\/span>           connect builtin<\/span>\n<span id=\"cb23-235\"><a href=\"#cb23-235\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-236\"><a href=\"#cb23-236\" aria-hidden=\"true\"><\/a><span class=\"ex\">DocumentRoot<\/span>            \/apache\/htdocs<\/span>\n<span id=\"cb23-237\"><a href=\"#cb23-237\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-238\"><a href=\"#cb23-238\" aria-hidden=\"true\"><\/a><span class=\"op\">&lt;<\/span><span class=\"ex\">Directory<\/span> \/<span class=\"op\">&gt;<\/span><\/span>\n<span id=\"cb23-239\"><a href=\"#cb23-239\" aria-hidden=\"true\"><\/a>      <\/span>\n<span id=\"cb23-240\"><a href=\"#cb23-240\" aria-hidden=\"true\"><\/a>      <span class=\"ex\">Require<\/span> all denied<\/span>\n<span id=\"cb23-241\"><a href=\"#cb23-241\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-242\"><a href=\"#cb23-242\" aria-hidden=\"true\"><\/a>      <span class=\"ex\">Options<\/span> SymLinksIfOwnerMatch<\/span>\n<span id=\"cb23-243\"><a href=\"#cb23-243\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-244\"><a href=\"#cb23-244\" aria-hidden=\"true\"><\/a><span class=\"op\">&lt;<\/span>\/<span class=\"ex\">Directory<\/span><span class=\"op\">&gt;<\/span><\/span>\n<span id=\"cb23-245\"><a href=\"#cb23-245\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-246\"><a href=\"#cb23-246\" aria-hidden=\"true\"><\/a><span class=\"op\">&lt;<\/span><span class=\"ex\">VirtualHost<\/span> 127.0.0.1:<span class=\"op\">80&gt;<\/span><\/span>\n<span id=\"cb23-247\"><a href=\"#cb23-247\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-248\"><a href=\"#cb23-248\" aria-hidden=\"true\"><\/a>    <span class=\"ex\">RewriteEngine<\/span>     On<\/span>\n<span id=\"cb23-249\"><a href=\"#cb23-249\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-250\"><a href=\"#cb23-250\" aria-hidden=\"true\"><\/a>    <span class=\"ex\">RewriteRule<\/span>       ^\/(.*)$  <span class=\"ex\">https<\/span>:\/\/%<span class=\"dt\">{HTTP_HOST}<\/span>\/<span class=\"va\">$1<\/span>  [redirect,last]<\/span>\n<span id=\"cb23-251\"><a href=\"#cb23-251\" aria-hidden=\"true\"><\/a>    <\/span>\n<span id=\"cb23-252\"><a href=\"#cb23-252\" aria-hidden=\"true\"><\/a>    <span class=\"op\">&lt;<\/span><span class=\"ex\">Directory<\/span> \/apache\/htdocs<span class=\"op\">&gt;<\/span><\/span>\n<span id=\"cb23-253\"><a href=\"#cb23-253\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-254\"><a href=\"#cb23-254\" aria-hidden=\"true\"><\/a>        <span class=\"ex\">Require<\/span> all granted<\/span>\n<span id=\"cb23-255\"><a href=\"#cb23-255\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-256\"><a href=\"#cb23-256\" aria-hidden=\"true\"><\/a>        <span class=\"ex\">Options<\/span> None<\/span>\n<span id=\"cb23-257\"><a href=\"#cb23-257\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-258\"><a href=\"#cb23-258\" aria-hidden=\"true\"><\/a>    <span class=\"op\">&lt;<\/span>\/<span class=\"ex\">Directory<\/span><span class=\"op\">&gt;<\/span><\/span>\n<span id=\"cb23-259\"><a href=\"#cb23-259\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-260\"><a href=\"#cb23-260\" aria-hidden=\"true\"><\/a><span class=\"op\">&lt;<\/span>\/<span class=\"ex\">VirtualHost<\/span><span class=\"op\">&gt;<\/span><\/span>\n<span id=\"cb23-261\"><a href=\"#cb23-261\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-262\"><a href=\"#cb23-262\" aria-hidden=\"true\"><\/a><span class=\"op\">&lt;<\/span><span class=\"ex\">VirtualHost<\/span> 127.0.0.1:<span class=\"op\">443&gt;<\/span><\/span>\n<span id=\"cb23-263\"><a href=\"#cb23-263\" aria-hidden=\"true\"><\/a>    <\/span>\n<span id=\"cb23-264\"><a href=\"#cb23-264\" aria-hidden=\"true\"><\/a>    <span class=\"ex\">SSLEngine<\/span> On<\/span>\n<span id=\"cb23-265\"><a href=\"#cb23-265\" aria-hidden=\"true\"><\/a>    <span class=\"ex\">Header<\/span> always set Strict-Transport-Security <span class=\"st\">&quot;max-age=31536000; includeSubDomains&quot;<\/span> env=HTTPS<\/span>\n<span id=\"cb23-266\"><a href=\"#cb23-266\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-267\"><a href=\"#cb23-267\" aria-hidden=\"true\"><\/a>    <span class=\"ex\">ProxyTimeout<\/span>              60<\/span>\n<span id=\"cb23-268\"><a href=\"#cb23-268\" aria-hidden=\"true\"><\/a>    <span class=\"ex\">ProxyErrorOverride<\/span>        On<\/span>\n<span id=\"cb23-269\"><a href=\"#cb23-269\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-270\"><a href=\"#cb23-270\" aria-hidden=\"true\"><\/a>    <span class=\"ex\">RewriteEngine<\/span>             On<\/span>\n<span id=\"cb23-271\"><a href=\"#cb23-271\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-272\"><a href=\"#cb23-272\" aria-hidden=\"true\"><\/a>    <span class=\"ex\">RewriteRule<\/span>               ^\/service1\/(.*)   <span class=\"ex\">http<\/span>:\/\/localhost:8000\/service1\/<span class=\"va\">$1<\/span> [proxy,last]<\/span>\n<span id=\"cb23-273\"><a href=\"#cb23-273\" aria-hidden=\"true\"><\/a>    <span class=\"ex\">ProxyPassReverse<\/span>          \/                 http:\/\/localhost:8000\/<\/span>\n<span id=\"cb23-274\"><a href=\"#cb23-274\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-275\"><a href=\"#cb23-275\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-276\"><a href=\"#cb23-276\" aria-hidden=\"true\"><\/a>    <span class=\"op\">&lt;<\/span><span class=\"ex\">Proxy<\/span> http:\/\/localhost:8000\/service1<span class=\"op\">&gt;<\/span><\/span>\n<span id=\"cb23-277\"><a href=\"#cb23-277\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-278\"><a href=\"#cb23-278\" aria-hidden=\"true\"><\/a>        <span class=\"ex\">Require<\/span> all granted<\/span>\n<span id=\"cb23-279\"><a href=\"#cb23-279\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-280\"><a href=\"#cb23-280\" aria-hidden=\"true\"><\/a>        <span class=\"ex\">Options<\/span> None<\/span>\n<span id=\"cb23-281\"><a href=\"#cb23-281\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-282\"><a href=\"#cb23-282\" aria-hidden=\"true\"><\/a>        <span class=\"ex\">ProxySet<\/span> enablereuse=on<\/span>\n<span id=\"cb23-283\"><a href=\"#cb23-283\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-284\"><a href=\"#cb23-284\" aria-hidden=\"true\"><\/a>    <span class=\"op\">&lt;<\/span>\/<span class=\"ex\">Proxy<\/span><span class=\"op\">&gt;<\/span><\/span>\n<span id=\"cb23-285\"><a href=\"#cb23-285\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-286\"><a href=\"#cb23-286\" aria-hidden=\"true\"><\/a>    <span class=\"op\">&lt;<\/span><span class=\"ex\">Directory<\/span> \/apache\/htdocs<span class=\"op\">&gt;<\/span><\/span>\n<span id=\"cb23-287\"><a href=\"#cb23-287\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-288\"><a href=\"#cb23-288\" aria-hidden=\"true\"><\/a>        <span class=\"ex\">Require<\/span> all granted<\/span>\n<span id=\"cb23-289\"><a href=\"#cb23-289\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-290\"><a href=\"#cb23-290\" aria-hidden=\"true\"><\/a>        <span class=\"ex\">Options<\/span> None<\/span>\n<span id=\"cb23-291\"><a href=\"#cb23-291\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-292\"><a href=\"#cb23-292\" aria-hidden=\"true\"><\/a>        <span class=\"ex\">ProxySet<\/span> enablereuse=on<\/span>\n<span id=\"cb23-293\"><a href=\"#cb23-293\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-294\"><a href=\"#cb23-294\" aria-hidden=\"true\"><\/a>    <span class=\"op\">&lt;<\/span>\/<span class=\"ex\">Directory<\/span><span class=\"op\">&gt;<\/span><\/span>\n<span id=\"cb23-295\"><a href=\"#cb23-295\" aria-hidden=\"true\"><\/a><\/span>\n<span id=\"cb23-296\"><a href=\"#cb23-296\" aria-hidden=\"true\"><\/a><span class=\"op\">&lt;<\/span>\/<span class=\"ex\">VirtualHost<\/span><span class=\"op\">&gt;<\/span><\/span><\/code><\/pre><\/div>\n<h3 id=\"references\">References<\/h3>\n<ul>\n<li>Apache mod_proxy <a href=\"https:\/\/httpd.apache.org\/docs\/2.4\/mod\/mod_proxy.html\">https:\/\/httpd.apache.org\/docs\/2.4\/mod\/mod_proxy.html<\/a><\/li>\n<li>Apache mod_rewrite <a href=\"https:\/\/httpd.apache.org\/docs\/2.4\/mod\/mod_rewrite.html\">https:\/\/httpd.apache.org\/docs\/2.4\/mod\/mod_rewrite.html<\/a><\/li>\n<\/ul>\n<h3 id=\"license-copying-further-use\">License \/ Copying \/ Further use<\/h3>\n<p><a rel=\"license\" href=\"http:\/\/creativecommons.org\/licenses\/by-nc-sa\/4.0\/\"><img decoding=\"async\" alt=\"Creative Commons License\" style=\"border-width:0\" src=\"https:\/\/i.creativecommons.org\/l\/by-nc-sa\/4.0\/80x15.png\" \/><\/a><br \/>This work is licensed under a <a rel=\"license\" href=\"http:\/\/creativecommons.org\/licenses\/by-nc-sa\/4.0\/\">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License<\/a>.<\/p>\n<h5 id=\"changelog\">Changelog<\/h5>\n<ul>\n<li>2023-03-10: Added SecRequestBodyJsonDepthLimit directive<\/li>\n<li>2020-07-22: Fixed error in description of X-Forwarded-For<\/li>\n<li>2019-11-05: Typo with path in RewriteRule<\/li>\n<li>2019-11-04: Added env=HTTPS condition to STS header config<\/li>\n<li>2019-11-01: Consistent naming of CRS in config comments<\/li>\n<li>2019-10-31: Disabling TLSv1 and TLSv1.1<\/li>\n<li>2019-07-04: Add ProxySet<\/li>\n<li>2018-04-13: Remove duplicate Headers module from config; update title format (markdown); rewordings (Simon Studer)<\/li>\n<li>2017-12-17: Added STS header, renumbered 200004-&gt;200005<\/li>\n<li>2017-03-05: MaxClients -&gt; MaxRequestWorkers; changed order of ModSec data folders<\/li>\n<li>2017-03-04: Updated stdout of curl calls<\/li>\n<li>2017-02-25: Getting rid of AllowOverride completely<\/li>\n<li>2017-02-18: Bugfix in config roundup near the end (removed a doubled passage)<\/li>\n<li>2016-12-28: Typo<\/li>\n<li>2016-11-15: Review, update ModSecurity config to CRS3<\/li>\n<li>2016-10-10: Fixing small issues<\/li>\n<li>2016-07-15: Apache 2.4.20 -&gt; 2.4.23<\/li>\n<li>2016-04-18: Fixing small issues<\/li>\n<li>2016-03-10: Translated to English<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Setting up a reverse proxy server What are we doing? We are configuring a reverse proxy protecting access to the application and shielding the application server from the internet. In doing so, we\u2019ll become familiar with several configuration methods and will be working with ModRewrite for the first time. Why are we doing this? A [&hellip;]<\/p>\n","protected":false},"author":3,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-952","page","type-page","status-publish","czr-hentry"],"_links":{"self":[{"href":"https:\/\/www.netnea.com\/cms\/wp-json\/wp\/v2\/pages\/952","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.netnea.com\/cms\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.netnea.com\/cms\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.netnea.com\/cms\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/www.netnea.com\/cms\/wp-json\/wp\/v2\/comments?post=952"}],"version-history":[{"count":2,"href":"https:\/\/www.netnea.com\/cms\/wp-json\/wp\/v2\/pages\/952\/revisions"}],"predecessor-version":[{"id":2062,"href":"https:\/\/www.netnea.com\/cms\/wp-json\/wp\/v2\/pages\/952\/revisions\/2062"}],"wp:attachment":[{"href":"https:\/\/www.netnea.com\/cms\/wp-json\/wp\/v2\/media?parent=952"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}