There a few flags that I have been searching through the internet that I don't seem to understand.
When would you use the [E] flag?
For example.
RewriteRule \.jpg$ - [env=dontlog:1]
What does that do...?
And how does the NS (No subsequent requests) work? If I have many includes in my php file, do I need to put it the NS so that it doesnt stop it from working? whats use has it got?
When that rule is matched (\.jpg%), an environment variable dontlog is set with a value of 1.
Later, the most likely scenario for how it is used is that the Apache configuration defines a CustomLog directive which reads that environment variable and does not write a line to the log file when it is set. Therefore, requests for .jpg image files are not written to the Apache log.
For example:
# Log any request that doesn't have a dontlog variable set...
CustomLog logs/access_log common env=!dontlog
There is a little bit of information about environment variables in the mod_rewrite documentation
Directly from said documentation:
The following example sets an environment variable called 'image' to a value of '1' if the requested URI is an image file. Then, that environment variable is used to exclude those requests from the access log.
RewriteRule \.(png|gif|jpg) - [E=image:1]
CustomLog logs/access_log combined env=!image
To answer your question about why the rewrites aren't working, it is because your first rule rewrites the request from index.php to target.php, therefore the second rule will never fire because the requested file is no longer index.php.
The comment already gave you the answer to the environmental variable flag.
Related
Do you need to enclose your rewrite rules with the following?
<IfModule mod_rewrite.c>
# Rewrite rules here.
</IfModule>
Assuming mod_rewrite wasn't turned on, the rules won't be executed anyway, no?
If mod_rewrite wasn't turned on, the rules would generate an error upon starting.
Whenever there's reason NOT to be sure a module is loaded ("generic" .htaccess used on multiple servers for example), the IfModule tags are useful. If you're sure the module is loaded, there's no need for the tags.
From the Apache docs ifmodule: This directive should only be used if you need your configuration file to work whether or not certain modules are installed. It should not be used to enclose directives that you want to work all the time, because it can suppress useful error messages about missing modules.
I keep reading that, where possible, I should not be using mod_rewrite. As such, I am trying to do a http to https rewrite with RedirectMatch.
Question: How can I use RedirectMatch and use Apache server variables (such as %{HTTP_HOST}) in the URL parameter?
This code fails to return a response to the client (Chrome):
RedirectMatch ^(.*) https://%{HTTP_HOST}/$1
I recently asked a similar question to this, but it may have been too wordy and lacks direction for an answer: Redirecting http traffic to https in Apache without using mod_rewrite
If you're using 2.4.19 or later, the Redirect directive has a somewhat obscure feature: putting it inside a Location or LocationMatch will enable expression syntax.
So your example can be written as
<LocationMatch ^(?<PATH>.*)>
Redirect "https://%{HTTP_HOST}%{env:MATCH_PATH}"
</LocationMatch>
(Here, the ?<PATH> notation means that the match capture will be saved to an environment variable with the name MATCH_PATH. That's how we can use it later in the Redirect.)
It's even easier if you always redirect using the entire request path, because you can replace the capture group entirely with the REQUEST_URI variable:
<Location "/">
Redirect "https://%{HTTP_HOST}%{REQUEST_URI}"
</Location>
Now, is this easier to maintain/understand than just using mod_rewrite for this one case? Maybe not. But it's an option.
No, You can't use variables of that type with Redirect/RedirectMatch. If you need variables, such as %{HTTP_HOST}, use mod_rewrite.
Note: I commend you for not trying to use mod_rewrite right away, because most people will go for mod_rewrite even for the simplest of redirections, which is clearly overkill and most times it is just looking to complicate things unnecessarily.
Writing for users who might face the same in future.
Not sure how you are adding vhost entries.
I guess this vhost entries are added automatically with help of some programming script.
Do you use VhostDirective with ServerName?
<VirtualHost *:8080>
ServerName example.domain.com
</VirutalHost>
If so, then you can use the same domain value for populating RedirectMatch field.
If you are manually adding vhost entries just write that domain URL value explicitly instead of HTTP_HOST.
Or let me know if its a different scenario.
I have SVN configured thru Apache 2.4.18 on Linux 6.6. Next i have to disable cross frame scripting for my svn url. SVN url is like https://servername/svn/projectA. I have compiled mod_security2.so and copied to /modules directory and loaded then in virtualHost have the lines below.
LoadFile /usr/lib64/libxml2.so
LoadFile /usr/lib64/liblua-5.1.so
LoadModule security2_module modules/mod_security2.so
httpd-vhosts.conf
<VirtualHost *:80>
ServerAdmin email#domain.com
DocumentRoot "/var/local/apache/httpd2.4.18/htdocs"
ServerName servername.fqdn.com
# For http to https redirect
Redirect / https://servername
TraceEnable off
RewriteEngine on
RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK)
RewriteRule .* - [F]
SecRuleEngine On
#SecFilterEngine On
#SecFilterForceByteRange 32 126
#SecFilterScanPOST On
#SecFilter "<( |\n)*script"
SecRequestBodyAccess On
SecResponseBodyAccess On
ErrorLog "logs/error_log"
CustomLog "logs/access_log" common
</VirtualHost>
The rules that Apache not supported are
SecFilterEngine
SecFilterForceByteRange
SecFilterScanPOST
SecFilter
Blockquote
Instead of SecFilterEngine, its taking SecRuleEngine. But I do not know alternative rule for other rules. I am using modsecurity-2.9.0 source compiled. The error i see is below. [root#server extra]# /var/local/apache/httpd2.4.18/bin/apachectl configtest
AH00526: Syntax error on line 45 of /var/local/apache/httpd2.4.18/conf/extra/httpd-vhosts.conf:
Invalid command 'SecFilterForceByteRange', perhaps misspelled or defined by a module not included in the server configuration. Any one know the mod_security2 supported modules for SecFilterForceByteRange, SecFilterScanPOST and SecFilter. I also read documentation about mod_security but could not figure out and solve the issue. I followed the url below.
http://www.unixpearls.com/how-to-block-xss-vulnerability-cross-site-scripting-in-apache-2-2-x/
[EDIT]
Its solved by adding the header response.
All those unsupported commands are ModSecurity v1 commands and have been completely rewritten for ModSecurity2.
The rule you would want would be something like this:
SecRule ARGS "<( |\n)*script" "phase:2,id:1234,deny"
This basically scans any of your arguments (as parameters or the body) for items like this:
<script
or
< script
or
<
script
That's not a bad start to trying to protect for XSS but is a bit basic.
OWASP has a Core Rule Set of ModSecurity rules and their XSS rules are much more complex and can be seen here: https://github.com/SpiderLabs/owasp-modsecurity-crs/blob/master/base_rules/modsecurity_crs_41_xss_attacks.conf
XSS can be exploited in a number of ways, some of which will make it to your server (and this sort of thing might catch) and some which might not even make it to your server at all (and so which this can't protect against).
The best way to protect against XSS is to look at Content Security Policy, which allows you to explicitly say what javascript you want to allow on your site, and what not, and to explicitly deny in-line scripts if you want. This may require some clean up of your site to remove inline scripts and is not always the easiest to set up, particularly if loading third party assets and widgets on your site, but is the most robust protection.
The X-Frame-Options header is useful to stop your site being framed, and someone overlaying content to make you think you are clicking on the real site buttons and fields, but actually clicking their buttons. It's not really a form of XSS, since you are more putting scripting on an invisible window on top of your site rather than directly on your site, but can have similar effects. It's a good header to use.
I am using mod_rewrite in the httpd.conf file (not in a .htaccess file) and I was wondering if there was a variable I could use that represents the entire request; ie DOCUMENT_ROOT represents the "path/to/htdocs" and REQUEST_FILENAME represents the "/path/to/file.php". Is there a single Apache variable that represents both of these together, like "path/to/htdocs/path/to/file.php" ?
The reason I'm asking is that in my rewrite directives, this doesn't work:
RewriteCond %{REQUEST_FILENAME} -f
but this does:
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} -f
the weird thing is, all of the tutorials I've seen use the first format, but that didn't work for me and I came up with the second format on my own-- and I've never seen the second format being used in any tutorials. Does it have to do with the fact that I'm writing in httpd.conf instead of a .htaccess document?
When I output the %{REQUEST_FILENAME} variable, it does not include the document root.
%{DOCUMENT_ROOT} is not website.com, it's the local path on the filesystem that is associated with the site's DocumentRoot directive. For example: /var/www/localhost/htdocs
If you want website.com, then you either want %{SERVER_NAME} (defined by the UserCanonicalName directive) or %{HTTP_HOST} which is defined by the Host: request header.
Additionally, %{REQUEST_FILENAME} includes the document root, it's more or less the equivalent of: %{DOCUMENT_ROOT}%{REQUEST_URI}. So given the above example of the document root, and a request URI of /images/title.png, then the %{REQUEST_FILENAME} would be /var/www/localhost/htdocs/images/title.png
If what you're looking for is: website.com/path/to/file.php, then, no. There's not a single variable that puts this together for you. You either want:
%{HTTP_HOST}%{REQUEST_URI}
or
%{SERVERNAME}%{REQUEST_URI}
Does it have to do with the fact that I'm writing in httpd.conf instead of a .htaccess document?
Yes. From the Apache docs:
REQUEST_FILENAME
The full local filesystem path to the file or script matching the request, if this has already been determined by the server at the time REQUEST_FILENAME is referenced. Otherwise, such as when used in virtual host context, the same value as REQUEST_URI.
And REQUEST_URI is the "path component of the requested URI, such as /index.html".
the weird thing is, all of the tutorials I've seen use the first format
Because most of the tutorials are written with respect to a .htaccess (or <Directory>) context.
If used in per-server context (i.e., before the request is mapped to the filesystem) SCRIPT_FILENAME and REQUEST_FILENAME cannot contain the full local filesystem path since the path is unknown at this stage of processing. Both variables will initially contain the value of REQUEST_URI in that case. In order to obtain the full local filesystem path of the request in per-server context, use an URL-based look-ahead %{LA-U:REQUEST_FILENAME} to determine the final value of REQUEST_FILENAME.
I am trying to fix this whole day without success, so I hope someone might be able to help me. I have an app at http://localhost/, and it uses Pylons for the app I am hosting. In addition to that, I need to host a PHP/MySQL site, so I had to use Apache too.
My current setup is that I use haproxy with this config for the Apache backend:
backend apache
mode http
timeout connect 4000
timeout server 30000
timeout queue 60000
balance roundrobin
server app02-8002 localhost:8002 maxconn 1000
This is triggered by this:
acl image url_sub images
use_backend apache if image
So, when I open my IP/images, it will trigger that and open Apache then, with port 8002.
For Apache, I created virtual hosts, and this is the "image" one:
<VirtualHost *:8002>
ServerAdmin my#email.com
ServerName image
ServerAlias image
DocumentRoot /srv/www/image/public_html/
ErrorLog /srv/www/image/logs/error.log
CustomLog /srv/www/image/logs/access.log combined
</VirtualHost>
So, that all works nicely, when I type IP/images it open the /srv/www/image/public_html. But then the issues come. As I am using the image uploading script, it involves a lot of rewriting, so I had to enable that mod. This is the .htaccess which is located in the public_html/images folder (I somehow had to make this subfolder too, to "match" the URL with the actual location in the public_html.
SetEnv PHP_VER 5_3
RewriteEngine On
# You must define your installation directory and uncomment the line :
RewriteBase /images/
RewriteRule ^([a-zA-Z]+)\.(jpg|gif|png|wbmp)$ controller/Resizer.php?m=original&a=$1&e=$2 [L]
RewriteRule ^(icon|small|medium|square)\/([a-zA-Z]+)\.(jpg|gif|png|wbmp)$ controller/Resizer.php?m=$1&a=$2&e=$3 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule (.*) application.php?request=$1 [L,QSA]
So, basically, this is somethow not working. I suppose there is a conflict between this virtual host, subdirectory, rewriting or something, but I can't seem to isolate it.
It is a bit confusing that when I open the IP/images/xxxx.jpg it opens the image, which is located in the public_html/images/upload/original folder, so the rewrite is working. The the other rules seem not to be working. All of the thumbnails and smaller versions are not rendering properly (with the icon, small, medium, square), so that makes the site quite unsusable.
Here is the link of the development server: http://localhost/images/
Thanks in advance for your time and help!
The first thing you should do is determine whether mod_rewrite is in fact part of the problem by accessing one of the failing URLs directly via its rewritten form and verifying that you get the expected result.
Indeed, the problem might simply be that the PHP script for the smaller resolutions "doesn't work" while it does for the original size ones. The first of the following URLs nicely served me an image; the second one is supposed to give me a smaller version of the same image, but served me an HTTP 500:
http://106.186.21.176/images/controller/Resizer.php?m=original&a=q&e=png
http://106.186.21.176/images/controller/Resizer.php?m=small&a=q&e=png
I got the same result (HTTP 500) for any of the smaller-size format names mentioned in your post, which matches your problem description.
Once you've verified that the script works as expected, it's likely that the problem is with mod_rewrite. If so, enable rewrite logging: use the RewriteLog directive to activate it, and RewriteLogLevel to control its verbosity. Especially at the higher log levels, it can give you very detailed information about exactly what it's doing. This should make the problem readily apparent from the logs.
Also, if possible, try to avoid configuring mod_rewrite rules in .htaccess files -- move them into your main server config file instead. The reason is explained on Apache mod_rewrite Technical Details, section "API phases":
Unbelievably mod_rewrite provides URL manipulations in per-directory context, i.e., within .htaccess files, although these are reached a very long time after the URLs have been translated to filenames. It has to be this way because .htaccess files live in the filesystem, so processing has already reached this stage. In other words: According to the API phases at this time it is too late for any URL manipulations. To overcome this chicken and egg problem mod_rewrite uses a trick: When you manipulate a URL/filename in per-directory context mod_rewrite first rewrites the filename back to its corresponding URL (which is usually impossible, but see the RewriteBase directive below for the trick to achieve this) and then initiates a new internal sub-request with the new URL. This restarts processing of the API phases.
Again mod_rewrite tries hard to make this complicated step totally transparent to the user, but you should remember here: While URL manipulations in per-server context are really fast and efficient, per-directory rewrites are slow and inefficient due to this chicken and egg problem. But on the other hand this is the only way mod_rewrite can provide (locally restricted) URL manipulations to the average user.
In general, not using .htaccess at all has the added advantage that you can tell Apache to not even bother and disable the functionality all together, which save Apache from having to scan each directory level it serves from for the .htaccess files.