I have a bunch of php scripts in a specific folder on one of my domains which are constantly accessed (20+ hits a second) and would like to disable access logging for all of them (the folder). I am using CentOS 6 with Apache 2.4 and have WHM/Cpanel.
I found information on how to do this using environment variables and modifying the host file, but I am not sure how to customize this for my needs.
I want to disable logging for /home/username/public_html/folder1/folder2/ (everything in it).
Here is what I found online to do this (putting this in a vhost include file) :
<IfModule mod_userdir.c>
UserDir public_html
SetEnvIf Request_URI "/nolog" dontlog
CustomLog /var/log/apache2/useraccess_log combined env=!dontlog
</IfModule>
One thing I am confused about is I have a different log location setup. For instance, if I look up /var/cpanel/userdata/username/domain.com it shows this at the top :
customlog:
-
format: combined
target: /usr/local/apache/domlogs/domain.com
-
format: "\"%{%s}t %I .\\n%{%s}t %O .\""
target: /usr/local/apache/domlogs/domain.com-bytes_log
documentroot: /home/username/public_html
group: username
hascgi: 0
homedir: /home/username
Given the different log location how would I implement this? While I am at it I wouldn't mind disabling the logging for the bytes-log as well for this folder. This is too much logging constantly happening which would not be useful to me at all given how much often they are accessed.
'username' and 'domain.com' represent their actual values in the above.
By default cPanel/WHM stores the access logs for the cPanel accounts (domains/sites/etc) in /usr/local/apache/domlogs/. That means that all the requests for that site are logged in that file (including the requests from folder1, folder2 etc).
You could try something like this:
Create an .htaccess file in /home/username/public_html/folder1/folder2/ with the content from bellow:
<IfModule mod_userdir.c>
UserDir public_html
SetEnvIf Request_URI "/nolog" dontlog
CustomLog /usr/local/apache/domlogs/domain.com combined env=!dontlog
</IfModule>
See if that works (basically it should allow logging but exclude the requests from the files from folder1, folder2 etc).
If that doesn't work then you could edit /var/cpanel/userdata/username/domain.com and comment the bytes_log line and the access_log line. That should completely disable access logging of http requests for that domain. You might need to restart httpd and cpanel service for the changes to take effect.
Related
My local development web server has all my different project folders, for example:
https://localhost/project1
https://localhost/project2
Due to dynamic content, some of my projects require absolute links, such as /images/example.jpg - when they are uploaded to my web server, under their appropriate domain they work perfectly, for example domain.com/images/example.jpg
However on my local server they do not, because they point to localhost/images/example.jpg (obviously), however I need the root directory to be viewed as ./project1 so I need the link to be interpreted as localhost/project1/images/example.jpg
My current solution is I have this in my root .htaccess file:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)$ /project1/$1 [L,QSA]
However this only lets me rewrite the links for one dynamic project folder at a time, which is problematic if I want to jump between projects.
How can I do this from .htaccess in the project folder so I can develop on my local server with ease without having to switch directories in the root .htaccess file?
Edit: with the help from arkascha I want to further clarify my question:
With .htaccess I would like to check if a file/directory is existent in the root directory (as seen in my example), if is not, I would like it to look for the file in the directory of the referrer (the first directory after root).
Based on your comments to the question this probably is what you are looking for:
RewriteEngine on
RewriteCond %{HTTP_REFERER} ^https://[^/]+/([^/]+)/
RewriteRule ^/?images/ /%1%{REQUEST_URI} [END]
You can implement such rules in the http server's host configuration, or, if you have no access to that, you can use a distributed configuration file (".htaccess"), if you have enabled the consideration of such for that http host ...
Considering the clarification you made in your question after I offered my first answer, I would like to bring my first suggestions to notice again: using different host names. To me this sounds like the more promising approach to your situation.
You can use different hostnames locally without much effort. And if this only is about your local development environment anyway, then you also don't need to care about valid ssl certificates.
You just need to take care that a name resolution for such host name succeeds. All operating systems offer means for that, but the details obviously differ slightly. Unless you made really surprising changes to your local name resolution setup you should have a "hosts" file in your system where local host names can be registered in a static manner along with the address those names should get resolved to. That is effective, easy to setup and solves your issue.
Given that you can define a local host for each of your projects. Thus requesting these hosts just like your projects would get requested in production. This way your development setup stays much closer to the actual production setup you implement your projects for.
This would be an example for such a "hosts" file, here on taken from a typical Linux based system:
# Host addresses
127.0.0.1 localhost
127.0.1.1 bragi
::1 localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
You can simply add entries there using any plain text editor, for example you could append:
127.0.0.1 project1
127.0.0.1 project2
All that is left is to setup separate virtual hosts for those projects inside your http server:
<VirtualHost *:80>
ServerName project1
LogLevel notice
ErrorLog ${APACHE_LOG_DIR}/project1/error.log
CustomLog ${APACHE_LOG_DIR}/project1/access.log combined
DocumentRoot /var/www/hosts/project1
<Directory /var/www/hosts/project1>
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
<VirtualHost *:80>
ServerName project2
LogLevel notice
ErrorLog ${APACHE_LOG_DIR}/project2/error.log
CustomLog ${APACHE_LOG_DIR}/project2/access.log combined
DocumentRoot /var/www/hosts/project2
<Directory /var/www/hosts/project2>
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
That is all you need to request your local http server using different host names for different projects:
http://project1/foo
http://project2/bar
You could even use the https protocol locally using a snake oil certificate, you'd have to accept that certificate once for every project then in the browser used for testing.
The bottom line:
You use a host name per project, just as you do in production. This keeps your local development setup much closer to the actual production setup. You don't need any fancy rewriting rules.
I personally chose to include common, repeated configuration options for those virtual hosts in a shared configuration file I include in those host definitions above. But that is a question of personal choice, there are endless options, obviously. The documentation of the apache http server and all its glorious modules will answer all questions about that. That documentation is of excellent quality and comes with great examples, as typical for OpenSource projects.
Suppose we have the /home/example.org/public_html/ directory on the filesystem, which serves as the document root of my virtualhost.
The relevant httpd configuration for that vhost would look like this:
<VirtualHost *:80>
ServerName example.org:80
...
DocumentRoot /home/example.org/public_html
<Directory /home/example.org/public_html>
AllowOverride All
...
</Directory>
...
</VirtualHost>
In order to prevent the htaccess lookups on the filesystem without losing the htaccess functionality – at least at the DocumentRoot level- I transformed the configuration to the following:
<VirtualHost *:80>
ServerName example.org:80
...
DocumentRoot /home/example.org/public_html
<Directory /home/example.org/public_html>
AllowOverride None
Include /home/example.org/public_html/.htaccess
...
</Directory>
...
</VirtualHost>
Difference
AllowOverride None
Include /home/example.org/public_html/.htaccess
Let’s see what we have accomplished with this:
httpd does not waste any time looking for and parsing htaccess files
resulting in faster request processing
Questions:
Using Include directive, Apache load htaccess only on service start or for each request?
If point 1 it's true, how do refresh apache conf without httpd.exe -k restart?
Firstly, note that checking for .htaccess is commonly not all that big an issue, since the relevant bits of the disk are cached in memory. It becomes an issue where for example you have a very large number of directories under your web root directory or directories, and the hits are scattered amongst them so that the hit rate on cached disk blocks is low. You might be better dealing with that by disabling .htaccess selectively for directory trees where it creates a problem. Parsing the .htaccess directives creates a little CPU load of course, but CPU should generally not be your server's bottleneck.
Answering your question as posed though; Yes, you will need to run a command as root to load the new configuration. Rather than using restart though, use reload or (better) graceful.
httpd.exe -k graceful
You could (but probably shouldn't) write a cron job to periodically check whether this needs to be run. Without a lot of testing, I think something like this should work, run as a regular root cron job:
#!/bin/bash
[ /var/run/httpd/http.pid -nt /home/example.org/public_html/.htaccess ] \
&& httpd.exe -k graceful
This creates a bit of disk load itself of course. This load doesn't increase with traffic volume, but might be an issue if you have many such included files.
SECURITY WARNING: It sounds like you are setting up a situation where a non root user is likely to be able to get Apache to Include directives at will. This is much more powerful than what can be done with a .htaccess file, and amounts to a root exploit. E.g. it gives access to things like the User and LoadModule directives, which .htaccess directives can never do.
I recommend that you should put Included directives in a file inside your Apache configuration directory, and have it accessible only by root. There are other ways to make sure that only root can edit the .htaccess file, but getting these files out of the user-owned area makes it less likely you'll inadvertently open access again later.
While the .htaccess mechanism does incur extra disk load, it is the mechanism that's designed for use by non-root users. It would be nice to have a mechanism for untrusted users to modify configuration with a limit on how often the .htaccess file would be checked for, but if it exists, I don't know it.
Apache accesses and processes the htaccess files on each request. This is why one does not need to restart the server every time to check their current configurations.
You do need to restart the server/service for testing any changes made to apache.conf, httpd.conf or the vhost configurations.
Quoting from Apache's tutorial on htaccess file:
You should avoid using .htaccess files completely if you have access
to httpd main server config file. Using .htaccess files slows down
your Apache http server. Any directive that you can include in a
.htaccess file is better set in a Directory block, as it will have
the same effect with better performance.
Since you already are trying to Include the htaccess from inside a <Directory> module block, the performance would be better if you include everything from the file to this block itself instead. There is, although no difference; apart from having to maintain configurations in two places simultaneously.
The htaccess file will get processed just once, at the time of server start.
I have a question about the Apache's Directory directive, here is what they say in the docs (http://httpd.apache.org/docs/2.4/mod/core.html#directory):
Note that the default access for <Directory "/"> is to permit all access. This means that Apache httpd will serve any file mapped from an URL. It is recommended that you change this with a block such as
<Directory "/">
Require all denied
</Directory>
But how will Apache do what they say (serve any file mapped from an URL) if I have only DocumentRoot set up, e.g.:
DocumentRoot "/usr/local/apache/htdocs"
No Alias "/some/webspace/path" "/", UserDir or other URL mapping rules which map to the root / directory of the system?
In another section of the docs (Security Tips http://httpd.apache.org/docs/2.4/misc/security_tips.html#protectserverfiles), they make a half-full example of UserDir as I can guess:
One aspect of Apache which is occasionally misunderstood is the
feature of default access. That is, unless you take steps to change
it, if the server can find its way to a file through normal URL
mapping rules, it can serve it to clients.
For instance, consider the following example:
# cd /; ln -s / public_html
Accessing http://localhost/~root/
This would allow clients to walk through the entire filesystem. To work around this, add the following block to your server's configuration:
<Directory "/">
Require all denied
</Directory>
This will forbid default access to filesystem locations.
Is what they say about the Directory directive at http://httpd.apache.org/docs/2.4/mod/core.html#directory just a warning in the case you use modules like mod_userdir like they then show at http://httpd.apache.org/docs/2.4/misc/security_tips.html#protectserverfiles? Or is there something else, maybe a little detail about Directory not given in the doc?
Thanks for the attention!
In Apache, there are unlimited hypothetical plugins/directives that could change only how a URL is mapped to the filesystem. Obvious/mainstream ones are DocumentRoot, Alias, AliasMatch, RewriteRule, UserDir etc. But there's no telling what other ones might exist.
Apache simply separates the URI to filesystem mapping completely from whether the core is willing to actually serve from that filesystem location.
There are a few ways you can accidentally expose things, like with mod_rewrite, and the default configuration file protects you from this with the defaults on <Directory />. The manual is not good at always emphasizing the differences in the compiled-in defaults and the contents of the default conf. The latter can change when repackaged which is tricky.
I'm working on a web site where the client doesn't want ANY logging on the site for privacy reasons. The site will be hosted on the same Apache Web Server as a number of other websites which is why I can just turn logging off in Apache. Is there some way to disable logging for an individual site using htaccess rules or by adding something to the VirtualHost settings?
The options seem to be
Sending to /dev/null on *nix or C:/nul on Windows (see here)
Removing the base logging directives and duplicating them in each vhost (so there is no logging on for vhosts by default)
Seems like there should be some better way to do this, but that's what I've found.
Yes, just comment out (using a '#') the ErrorLog and CustomLog entries in the httpd conf for your virtual host.
http://www.mydigitallife.info/how-to-disable-and-turn-off-apache-httpd-access-and-error-log/
I achieve this by making the logging dependent on a non-existing environment variable. So in the VirtualHost you can have:
CustomLog /var/log/httpd/my_access_log combined env=DISABLED
and so long as there is no environment variable called DISABLED then you'll get no logs.
I actually arrived here looking for a neater solution but this works without having to change the global httpd.conf.
Edit: removed reference to .htaccess because CustomLog only applies in the global config or in the virtual host config as pointed out by #Basj
I have a .htaccess file & I currently I am working on localhost. For a 404 page error, I have the following code in the .htaccess file:
ErrorDocument 404 /my_local_domain/404.php
But when I upload this file to my website online, the functionality of the file breaks. It no longer shows the 404.php page. It works if I modify the code in the .htaccess file of my online website to the following:
ErrorDocument 404 /404.php
Now all through the changes that I do in the .htaccess file, I would have to remember to remove the domain name before I upload it to the website or I risk breaking the functionality. So with this in mind, here are my questions:
1. How do I solve the above problem without needing to edit the .htaccess file each time (by stripping it off the my_local_domain) I make a change & upload it online?
2. How do I setup 404 page redirection for all the nested folders? (I don't want to setup a .htaccess file for each of the folders. A single .htaccess file that resides in the root folder of the website & controls all the redirection for all the sub-folders would be awesome)
All help is appreciated.
Thank you.
I believe you have two different issues here.
First of all, you should not need to have different paths in development and live site. It appears that you've configured your local Apache to host only one site and each actual sites goes in a subdirectory. It's not a good idea: you'll soon be mixing cookies and sessions between all your dev sites. Have a look at the name based virtual hosts feature: you can configure as many independent sites as you need. You don't even have to buy real domains in you set them in the hosts file.
Secondly, under certain circumstances it can be useful to have different Apache directives. I've been using the following trick.
Pick a keyword for the dev server, e.g. DEV_BOX.
Pass that keyword to Apache in the -D parameter. If you run it as service, you can run regedit and find the HKLM\SYSTEM\CurrentControlSet\Services\Apache2.2\Parameters key. Append -D DEV_BOX to the ConfigArgs value. Restart Apache.
Now, you can use the <IfDefine> directive to set local directives:
-
#
# Common stuff
#
AddDefaultCharset UTF-8
#
# Local-only stuff
#
<IfDefine DEV_BOX>
Options +Indexes
</IfDefine>
#
# Live-only stuff
#
<IfDefine !DEV_BOX>
Options -Indexes
</IfDefine>
First of all I suggest you setup local domains for development. For example if you are developing a website which will go under www.example.com, you can setup a local.example.com in your HOSTS file. You'll do a VirtualHost setup in your apache and the .htaccess will then be the same.
Also, you can setup a build process (e.g via Ant) which will allow you to prepare and generate a zip file with the files which go on the live server. This build will feature the correct configuration files (db configs, mail servers, htaccess etc).