apache

Hide .git repo with Apache

Snippet

Don't allow apache to serve anything from the .git repo that might be in the DocumentRoot

Add this to the .htaccess in the DocumentRoot after the RewriteEngine On line.

RedirectMatch 404 /\.git

Redirect to https before basic Auth

Snippet

Some directories need to redirect to https before you check auth, otherwise people are typing in their passwords in clear text before they are redirected. Which would SUUUUuuuUUUuck.

So, for Apache > 2.4, use configuration sections, and redirect before authenticating.

# Redirect to HTTPS
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
 
# Authenticate users only when using HTTPS
<If "%{HTTPS} == 'on'">
    AuthType Basic
    AuthName "Yep, you need to provide a password."
    AuthUserFile /etc/path/to/htpasswd.file
    # this is so the next 'Require' directive doesn't override any merged previously
    AuthMerging And
    Require valid-user
</If>

Apache config for redirect from www to just domain

Blog

You can use a VirtualHost directive to redirect from www.example.com to example.com at the Apache level

# redirect www to no-host
<VirtualHost *:80>
  ServerName www.example.io
  Redirect permanent / http://example.io
</VirtualHost>

# redirect SSL www to no-host
<VirtualHost *:443>
  ServerName www.example.io
  Redirect permanent / https://example.io
</VirtualHost>

That second one will likely fail unless you have the SNI (Server Name Indication) TLS extension on your server.

Then, include the rest of your Apache configuration as normal:

<VirtualHost *:80>
  ServerName example.io
  ServerAdmin hello@example.io
  DocumentRoot /var/www/example.io/html/
  ErrorDocument 404 /404.html
  ErrorDocument 403 /403.html
  ...
</VirtualHost>
...

Drupal 7 Multiviews Error fix

Blog

Installing Drupal 7 for a project, received a 500 Server configuration error.

Looking in the Apache error log, I saw the error:

[Wed Jan 12 19:40:24 2011] [alert] [client xxx.xxx.xxx.xxx] /var/www/httpdocs/.htaccess: Option Multiviews not allowed here

Turns out, in the apache2 config file, the following is not sufficient in the Directory section:

AllowOverride Options FileInfo AuthConfig Limit Indexes

In particular, the MultiViews option is needed:

AllowOverride Options=All,MultiViews FileInfo AuthConfig Limit Indexes

htpasswd setup notes

Snippet
Create htpasswd file to store passwords:
 
% cd sites/example.com/passwords
% htpasswd -c htpasswdfile username
 
alternately, add a user to an existing file
 
% htpasswd htpasswdfile username2
 
Update the apache configuration file, or adjust the .htaccess file if desired.
 
...
   <Directory /sites/example.com/hostname/website>
     Options FollowSymLinks MultiViews -Indexes
     order deny,allow
     AllowOverride All
     AuthType Basic
     AuthUserFile /sites/example.com/passwords/htpasswdfile
     AuthName "Please enter user name and password"
     Require valid-user
   </Directory>
...

Apache mod_write on IP addresses and Query string

Snippet

If a page has a query string argument that is well-defined such that it is unique to a particular page, you can trigger off that query string to redirect the page. You can also restrict access by IP address, or several IP addresses, or a range of IP addresses.

# if the string has id=6121 in the query and ...
  RewriteCond %{QUERY_STRING} id=6121
 
# ... doesn't have IP address 174.143.157.55 and ...
  RewriteCond %{REMOTE_ADDR} !^174\.143\.157\.55
 
# note that you need to escape the periods in the IP address
 
# ... doesn't have IP address 24.173.159.252 ...
  RewriteCond %{REMOTE_ADDR} !^24\.173\.159\.252
 
# conditions are automatically AND conditions
 
#  RewriteCond %{REMOTE_ADDR} !^24\.173\.159\.253
#  RewriteCond %{REMOTE_ADDR} !^99\.201\.42\.89
#  RewriteCond %{REMOTE_ADDR} !^24\.173\.159\.254
 
# .. then redirect all the URLs that match the original query string to the new page
  RewriteRule ^/(.*)$ http://club2009.upa.org/scores/women.html [R,L]
 
 
Notes: 
 
** 
 
You don't have to add ^(.*) in front of the query string, 
it'll match ALL URLs with the id=6121, so make sure that's 
the correct query string pattern.
 
** 
 
You can also chain conditions together by using [OR] at the 
end of the conditions (say, to restrict access to only 
specific IP addresses:
 
  ...
  RewriteCond %{REMOTE_ADDR} ^24\.173\.159\.253 [OR]
  RewriteCond %{REMOTE_ADDR} ^99\.201\.42\.89
  ...
 
** 
 
processing directives
 
  [R] means redirect
  [R=301] means permanent redirect
  [L] means the last conditionals, stop processing on this match
 
** 
 
Put the most restrictive conditional first.

Stats from apache log files

Snippet

Quick generation of numbers of total page hits on a server with apache log files.

#!/usr/bin/env tcsh
 
# not bash, actually, tcsh
 
foreach g (01 02 03 04 05 06 07 08 09 10 11 12)
foreach f (01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31)
echo -n "2008-" >> ~/scores-stats-2008.txt
echo -n $g >> ~/scores-stats-2008.txt
echo -n "-" >> ~/scores-stats-2008.txt
echo -n $f >> ~/scores-stats-2008.txt
echo -n "  " >> ~/scores-stats-2008.txt
grep /scores/ serverx.example.org-access_log.2008-$g-$f | wc -l >> ~/scores-stats-2008.txt
end
end