Use apache http server reverse-proxy to send a request expected not to return a response - apache

Need somebody to push me in the right direction.
We're using apache http server (http1) reverse-proxy to send a request to another http server (http2). The challenge is http2 is not expected to send an HTML page in the response back to http1.
The http2 log does show the request coming in. However, the http1 log results in HTTP 502 error:
Internal error (specific information not available): [client ] AH01102: error reading status line from remote server localhost:9001
[proxy:error] [client ] AH00898: Error reading from remote server returned by /app/myContext/LogMessage
Here's http2 log which returns HTTP status 200:
"GET /app/myContext/LogMessage HTTP/1.1" 200 -
Please note that those requests that result in an HTML page work fine.
What would you think should be an approach here? Maybe using reverse proxy is not a good choice for this type of request?
We have httpd.conf on http1 set up this way:
ProxyPass "/app/myContext/"
http://localhost:9001/app/myContext/"
ProxyPassReverse "/app/myContext/"
http://localhost:9001/app/myContext/"

Disable ErrorLog on http1 altogether:
ErrorLog /dev/null
Have you tried to have http1 ignore using mod_log_config? According to the example the format string might be:
CustomLog expr=%{REQUEST_STATUS} -eq 502 && %{REQUEST_URI} =~ /app\/myContext/ ...
Or the LogFormat string might work too:
LogFormat %!502...
(h/t to Avoid logging of certain missing files into the Apache2 error log)
Is your problem that http1 is emitting 502 to the requestor? In that case, maybe use an <If> and a custom ErrorDocument?
<If %{REQUEST_URI} =~ /app\/myContext/>ErrorDocument 502 'OK'</If>

Went with the following solution: In http2 re-route the LogMessage call to fetch a blank html page:
1. Create blankfile.html in the /htdocs directory.
2. In httpd.conf add this line:
RewriteRule ^.(app/myContext/LogMessage). /blankfile.html [L]
This works for us since the whole purpose of LogMessage is to log the request in http2 access_log.
Just'd like to thank you #cowbert for working so deligently with me on this!

Related

How do I add custom errors for client certificates in Apache?

How do I configure a custom error document for when a user fails to provide a client certificate or when the one they provide is invalid?
The browser displays ERR_BAD_SSL_CLIENT_AUTH_CERT and ERR_SSL_DECRYPT_ERROR_ALERT respectively when I encounter those errors. I'd like to provide the user with a custom error.
This is how I do it in NGINX.
location = /495.html {}
error_page 495 /495.html;
location = /496.html {}
error_page 496 /496.html;
When I add the following line to the apache config I receive the error "Unsupported HTTP response code 495".
ErrorDocument 495 /495.html
This is running httpd-2.4.6-45.el7.centos.4.x86_64
UPDATE:
I am able to provide a custom error document for the 496 error by changing SSLVerifyClient from require to optional and using a rewrite rule.
<Directory "/var/www/html">
SSLVerifyClient optional
RewriteEngine On
RewriteCond %{SSL:SSL_CLIENT_VERIFY} !=SUCCESS
RewriteRule . 496.html [L]
</Directory>
The 495 error still eludes me.
What version of Apache are you running?
https://unix.stackexchange.com/questions/290845/unsupported-http-response-code-429
Apache 2.2 does not support 495.
Apache 2.4 does support this according to https://httpd.apache.org/docs/2.4/custom-error.html
Customized error responses can be defined for any HTTP status code designated as an error condition - that is, any 4xx or 5xx status.

How to disable HTTP 1.0 protocol in Apache?

HTTP 1.0 has security weakness related to session hijacking.
I want to disable it on my web server.
You can check against the SERVER_PROTOCOL variable in a mod-rewrite clause. Be sure to put this rule as the first one.
RewriteEngine On
RewriteCond %{SERVER_PROTOCOL} ^HTTP/1\.0$
RewriteCond %{REQUEST_URI} !^/path/to/403/document.html$
RewriteRule ^ - [F]
The additional negative check for !^/path/to/403/document.html$ is so that the forbidden page can be shown to the users. It would otherwise lead to a recursion.
If you are on a name-based virtual host (and each virtual server does not have its own separate IP address), then it is technically impossible to connect to your virtual host using HTTP/1.0; Only the default server --the first virtual server defined-- will be accessible. This is because HTTP/1.0 does not support the HTTP "Host" request header, and the Host header is required on name-based virtual hosts in order to "pick" which virtual host the request is being addressed to. In most cases, the response to a true HTTP/1.0 request will be a 400-Bad Request.If you did manage to get that code working, but you later tried to use custom error documents (see Apache core ErrorDocument directive), then the result of blocking a request would be an 'infinite' loop: The server would try to respond with a 403-Forbidden response code, and to serve the custom 403 error document. But this would result in another 403 error because access to all resources --including the custom 403 page-- is denied. So the server would generate another 403 error and then try to respond to it, creating another 403, and another, and another... This would continue until either the client or the server gave up.
I'd suggest something like:
SetEnvIf Request_Protocol HTTP/1\.0$ Bad_Req
SetEnvIf Request_URI ^/path-to-your-custom-403-error-page\.html$
Allow_Bad_Req
#Order Deny,Allow
Deny from env=BadReq
Allow from env=Allow_Bad_Req
In mod_rewrite, something like:
RewriteCond %{THE_REQUEST} HTTP/1\.0$
RewriteCond %{REQUEST_URI} !^/path-to-your-custom-403-error-page\.html$
This will (note the FUTURE tense - as of October 2018) be possible with Apache 2.5, using the PolicyVersion directive in mod_policy. The PolicyVersion directive sets the lowest level of the HTTP protocol that is accepted by the server, virtual host, or directory structure - depending on where the directive is placed.
First enable the policy module:
a2enmod mod_policy
Then in the server config, vhost, or directory (will not work in .htaccess), add:
PolicyVersion enforce HTTP/1.1
Finally restart the server:
systemctl restart apache2

Why does Apache return 403

Why can't I see why Apache returns 403?!
If I look in the access log the only information I get is
193.162.142.166 - - [29/Jan/2014:18:34:26 +0100] "POST /api_test/callback.php HTTP/1.1" 403 2293
How can I get more information about why the request is forbidden/rejected?
The call is made from a payment gateway...
If the callback URL is a http request there are no problems and returns 200 OK
If the callback URL is a https my server returns 403.. I need to know why?
The server has SSL and openSSL installed and it works!
Have tried to do the https request from http://web-sniffer.net/ and then there are no problems..
I don't get it.. There must be something in the request headers from the payment gateway which results in 403
update
error log
[Wed Jan 29 20:45:55 2014] [error] No hostname was provided via SNI for a name based virtual host
solution
Ok it looks like the client doesn't support SNI
http://wiki.apache.org/httpd/NameBasedSSLVHostsWithSNI
Use the LogLevel directive to adjust how verbose the error logs are and increase until you can see what you want.
httpd 2.4 has better messages in a lot of respect and expensive list of LogLevel settings than 2.2. So if you're using 2.2 it may be a bit harder to figure this out.

How to enable ErrorDocument for 400 error?

I have installed apache2 on my ubuntu machine. As I need to work with subdomains I created a proper entry in sites-available which looks like this:
<VirtualHost *:80>
ServerName xxx.localhost
DocumentRoot /var/www/
</VirtualHost>
I also enabled mod_rewrite (and changed "AllowOverride All" in my sites-available/default file) but other than that nothing else was changed.
My .htaccess file does work, and I wanted to handle some error codes. Doing so with 404 worked pretty well, but for some reason other errors don't seem to work. I'm mostly interested in handling error 400:
ErrorDocument 400 /400.php
ErrorDocument 404 /404.php
Is there anything else I should look at? I couldn't seem to find any place where 404 are allowed while other error codes aren't.
If the php is returning the 400 error, then php should generate the error document.
Use something like:
if( $someError )
{
http_response_code(400);
include("{$_SERVER['DOCUMENT_ROOT']}/400.php");
exit();
}
From the Apache documentation:
Although most error messages can be overriden, there are certain circumstances where the internal messages are used regardless of the setting of ErrorDocument. In particular, if a malformed request is detected, normal request processing will be immediately halted and the internal error message returned. This is necessary to guard against security problems caused by bad requests.
Try adding it directly in the httpd.conf and restart Apache.

Disabling TRACE request method on Apache/2.0.52

By default, Apache 2.0.52 will respond to any HTTP TRACE request that it receives. This is a potential security problem because it can allow certain types of XSS attacks. For details, see http://www.apacheweek.com/issues/03-01-24#news
I am trying to disable TRACE requests by following the instructions shown in the page linked to above. I added the following lines of code to my http.conf file, and restarted apache:
RewriteEngine On
RewriteCond %{REQUEST_METHOD} ^TRACE
RewriteRule .* - [F]
However, when I send a TRACE request to my web server, it seems to ignore the rewrite rules and responds as if TRACE requests were still enabled.
For example:
[admin2#dedicated ~]$ telnet XXXX.com 80
Trying XXXX...
Connected to XXXX.com (XXXX).
Escape character is '^]'.
TRACE / HTTP/1.0
X-Test: foobar
HTTP/1.1 200 OK
Date: Sat, 11 Jul 2009 17:33:41 GMT
Server: Apache/2.0.52 (Red Hat)
Connection: close
Content-Type: message/http
TRACE / HTTP/1.0
X-Test: foobar
Connection closed by foreign host.
The server should respond with 403 Forbidden. Instead, it echoes back my request with a 200 OK.
As a test, I changed the RewriteCond to %{REQUEST_METHOD} ^GET
When I do this, Apache correctly responds to all GET requests with 403 Forbidden. But when I change GET back to TRACE, it still lets TRACE requests through.
How can I get Apache to stop responding to TRACE requests?
Some versions require:
TraceEnable Off
I figured out the correct way to do it.
I had tried placing the block of rewrite directives in three places: in the <Directory "/var/www/html"> part of the httpd.conf file, at the top of my httpd.conf file, and in the /var/www/html/.htaccess file. None of these three methods worked.
Finally, however, I tried putting the block of code in <VirtualHost *:80> part of my httpd.conf. For some reason, it works when it is placed. there.
As you've said, that works in your VirtualHost block. As you didn't show httpd.conf I can't say why your initial attempt didn't work - it's context-sensitive.
It failed in the because it's not really relevant there, that's generally for access control. If it didn't work in the .htaccess it's likely that apache wasn't looking for it (you can use AllowOverride to enable them).