Redirect to https before basic Auth


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

Apache config for redirect from www to just domain


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

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

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

Drupal 7 Multiviews Error fix


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

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

Apache mod_write on IP addresses and Query string


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 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 ...
  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]
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


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