The economic situation is eating into your profits, and the Microsoft Office licenses look more expensive than before. Or maybe you are familiar with the way Microsoft Office has looked for over a decade: it had a file menu, edit menu, and format menu, and you balk at the thought of retraining your staff for Microsoft Office 2007’s bizarre ribbon. In either case, you don’t have to buy Microsoft Office thanks to OpenOffice.org: the best kept secret in office suites.
OpenOffice.org is a free office suite that includes a word processor, spreadsheet, slide presentation application, drawing program, and database. It’s compatible with practically all operating systems and runs well on old and new computers alike. Don’t worry about exchanging documents with Microsoft Office users because OpenOffice.org is compatible with many file formats including the new Microsoft Office 2007 formats.
Not too good to be true
Don’t let the light-weight price tag fool you to comparing OpenOffice.org with the light-weight Microsoft Works office suite. (Isn’t it a little strange that Microsoft’s Works and Office compete with each other?) OpenOffice.org has sophisticated features making it useful for personal and businesses use.
It’s good to be skeptical about free offers, but OpenOffice.org is the real thing. Its origins reach back over twenty years to StarWriter and StarOffice. Technology giant Sun Microsystems purchased StarOffice and in 2000 released most of StarOffice as the open source project called OpenOffice.org. Open source means the source code (or programming blueprints) are available to anyone who wants to learn or improve it. Open source fosters a rapid, cost-effective, community-lead approach to software development.
Often businesses need paid support and consulting, which are available for OpenOffice.org and its cousin StarOffice from Sun Microsystems and consultants worldwide. If you prefer internal support, you pocket the savings. Either way, enjoy the commoditization of the office suite and making the best choice for your own business.
Easier than you think
Having switched the office I worked at, I know first hand that regular people quickly learn OpenOffice.org. Originally chosen for its price, it was the standard office suite on all computers. Looking back, it would have been ideal to provide training, but the staff, clients, and newcomers learned it with fewer questions than I expected. Many people didn’t seem to notice it was not the Microsoft Office they used before.
Switching
The general process to switch is:
- Evaluate the product. If you have few documents with macros and few third-party integrations with third-party applications, OpenOffice.org is an easy win.
- Make the pitch. Getting support from management is essential.
- Roll it out to a select group of people.
- Highlight the positives: a familiar interface (certainly more familiar than Office 2007), unique features such as PDF export, and money diverted to higher priorities—raises for all (maybe not).
- Roll it out to everyone.
- Provide a variety of training and resources because each person learns differently. Some people prefer class room training, some books, etc. In each work area, appoint a leader to field basic questions to provide quick help and reduce overwhelming your mainline support on the day of the roll out.
Next I’ll cover some important areas to get you started in your evaluation.
Download and install

Different names
OpenOffice.org consists of multiple components like Microsoft Office.

If you’re looking for email like Outlook, consider Google Apps Messaging, Zimbra, and Scalable OpenGroupware.org.
Starting up
There’s a variety of ways to start OpenOffice.org. On Microsoft Windows, OpenOffice.org puts a shortcut on the desktop. Just double click it.

On Windows, you can start OpenOffice.org from its quickstarter next to the system clock. Right click on the quickstarter, and then left click on the component.

Like any Windows application, it can be started by clicking on the Start Menu, then clicking Programs, then clicking OpenOffice.org, and then clicking on the component.

Of course, you can start OpenOffice.org by opening any of the documents associated with it on your computer, in your email, or online.

First look inside
At a first glance, OpenOffice.org Writer version 3.1 looks more like Microsoft Word 2003 than Word 2007 looks like Word 2003. OpenOffice.org has the familiar menu bar and toolbars, and many commands are found in the same place as in Microsoft Office.

MS Office Word 2003

OpenOffice Writer 2003

Word 2007
Customizing OpenOffice.org
Make OpenOffice.org feel like home by customizing it. Here are a few suggestions.
Better safe than sorry: to enable document backups, click Tools – Options. Click Load/Save and then General. Check the box labeled Always create backup copy.

The word completion feature saves time by finishing long words. If you see OpenOffice.org has correctly guessed the word you are currently typing, press the Enter key to accept the word. If you prefer to disable this feature, click Tools – AutoCorrect. Click the last tab Word Completion. Then uncheck the box Enable Word Completion.
By default OpenOffice.org only prints the selected worksheet instead of the whole workbook. If you prefer the Excel default, do this: open Calc. Click Tools – Options. Then click OpenOffice.org Calc and Print. Finally uncheck the box Print only selected sheets.
Sharing documents
While OpenOffice.org does fairly well saving in Microsoft Office formats, it’s best to retain the default setting to save documents in OpenDocument formats.
If you need to retain a few machines on Microsoft Office, either make OpenOffice.org the primary office suite or install the OpenXML / ODF Translator, Sun ODF Plugin for Microsoft Office, or Microsoft Office 2007 SP2. Any of these will allow Microsoft Office to share ODF files with OpenOffice.org users.
Chances are those with which you do business outside your organization use Microsoft Office. When sending documents externally, train your staff to click File – Send – Email as PDF or Email as Microsoft Word. In the future ODF may be the ideal exchange medium, but today PDF and Microsoft Office formats are the de facto standards. (Freedom purists should remember the specifications of the binary Microsoft Office file formats are covered by the Microsoft Open Specification Promise).
Recommended extensions
OpenOffice.org is a breeze to enhance with many free extensions available at http://extensions.services.openoffice.org/. Here are a few favorites.
Check grammar
To underline potentially incorrect grammar with a blue squiggly line, install the popular LanguageTool extension. It does well at catching double words, homophones, and other common mistakes.
Reduce the size of presentations
Presentations can easily balloon to sizes larger than necessary. For example, you may insert a 3 megapixel image from a digital camera, but over two megapixels are wasted as a typical presentation display is only 0.8 megapixels. The extra size wastes disk space, clogs up email boxes, and takes extra time to download. Simply install Sun Presentation Minimizer to tame the size of these bloated files.
Import PDFs
Not only does OpenOffice.org out of the box export PDFs with advanced options, OpenOffice.org imports PDFs in an editable format with remarkable results. PDFs aren’t designed for editing, so don’t expect too much, but OpenOffice.org will save some people the cost of buying Adobe Acrobat.
Templates
Microsoft Office ships with many templates, and OpenOffice.org doesn’t. Don’t worry because installing templates is easy, and there are many nice templates available for free. Start with these: Sun Template Pack I, Sun Template Pack II, and Label Templates. Remember OpenOffice.org reads all Microsoft templates! Check back later on this web site for a more thorough guide to OpenOffice.org resources.
Fonts
The best fonts are those that everyone has to ensure the document looks the same on all machines. De facto standards are Times New Roman, Arial, and Courier New, and OpenOffice.org automatically substitutes these fonts if not available (for example, on Linux). OpenOffice.org comes with the DejaVu and Liberation families; the latter is very similar to Times New Roman, Arial, and Courier New.
If you run Windows XP, install the Microsoft Office 2007 fonts (such as Calibri) for better compatibility with Office 2007 documents.
For branding purposes, you may want to deploy a common font within your company. A personal favorite is Gentium Basic, and OpenOffice.org supports any TrueType font installed on your operating system. When exporting PDFs, OpenOffice.org automatically includes a subset of the font, so the document looks exactly the same on all machines.
Getting help
As you build expertise within your company to support routine issues or need assistance with one-time situations like initial deployment, check OpenOffice.org Support for free and paid resources including service plans, consultants, books, tutorials, and online forums. Check back later on this web site for a more thorough guide to OpenOffice.org resources.
Conclusion
With its mature feature set, strong support system, and economical price tag OpenOffice.org can add solid value to your business. When you are ready to put your cash to better use than paying The Other Guy, start planning your own OpenOffice.org migration.
About the author: Andrew Ziem has worked with OpenOffice.org since 2001 as an author, trainer, tester, and quasi-developer. He blogs about OpenOffice.org at http://www.oooninja.com.
Step 1: Installing the Hardened-PHP Project Signaturekey
You should first grab a copy of the Hardened-PHP Project's Release Signaturekey and import it into your GNU Privacy Guard keychain. (For further information on the usage of gnupg please consult it’s manpage)
#> gpg --import < hardened-php-signature-key.asc
gpg: /root/.gnupg/trustdb.gpg: trust-db erzeugt
gpg: key 0A864AA1: public key "Hardened-PHP Signature Key" imported
gpg: Anzahl insgesamt bearbeiteter Schlüssel: 1
gpg: importiert: 1
Step 2: Downloading and verifying the necessary files
It is now time to grab a copy of a fresh PHP tarball and the latest version of the Suhosin-Patch. Additionally you should get the digital signature (*.sig) files. You can grab all of this on our suhosin download page.
As a first precaution you can check the MD5 hashs of the downloaded files against those you find on the download page.
#> md5sum php-5.1.4.tar.bz2
66a806161d4a2d3b5153ebe4cd0f2e1c php-5.1.4.tar.bz2
#> md5sum suhosin-patch-5.1.4-0.9.0.patch.gz
ea9026495c4ce34a329fd0a87474f1ba suhosin-patch-5.1.4-0.9.0.patch.gz
When the MD5 hash values are valid you can check the digital signatures like this.
#> gpg php-5.1.4.tar.bz2.sig
gpg: Signature made Di 16 Mai 2006 23:39:04 CEST using DSA key ID 0A864AA1
gpg: Good signature from "Hardened-PHP Signature Key"
#> gpg suhosin-patch-5.1.4-0.9.0.patch.gz.sig
gpg: Signature made So 21 August 2006 20:02:53 CEST using DSA key ID 0A864AA1
gpg: Good signature from "Hardened-PHP Signature Key"
Step 3: Unpacking and Patching
You now have to unpack the PHP tarball, gunzip the patchfile and then apply the patch.
#> tar -xfj php-5.1.4.tar.bz2
#> gunzip suhosin-patch-5.1.4-0.9.0.patch.gz
#> cd php-5.1.4
#> patch -p 1 -i ../suhosin-patch-5.1.4-0.9.0.patch
If you prefer to have suhosin as builtin extension you can also download the suhosin extension source code and copy the src files into the ext/suhosin directory within your PHP source tree.
Installing on a Generic Linux/Unix
After having prepared the PHP source tree the next step is not much different from the usual installation of PHP. If you have copied the suhosin extension into the ext directory you also have to activate it.
#> [./buildconf - in case you want to compile suhosin statically]
#> ./configure --with-whatever-you-want [--enable-suhosin]
#> make
#> make test
#> make install
By executing make test you can verify, that PHP still works and does not break anything.
If you are upgrading from a previous installation of PHP you do not need to recompile all installed PHP modules and extensions unless you are upgrading to a PHP version that breaks binary compatibility. However recompiling the extensions after having installed PHP with the Suhosin-Patch can protect them from possible format string vulnerabilities, which was built into the header files.
After having recompiled and installed everything, have a look at the bundled php.ini files for examples how to use the new configuration directives. For a documentation of the new directives consult the Configuration section.
Binary extensions from for example Zend should continue flawlessly. If you encounter any problem contact us immediately.
Installing the Extension
Unlike the Hardening-Patch for PHP, nearly all of Suhosin´s features are within the extension. Therefore you might want to only install the extension and use a plain unpatched PHP. Depending on the system we might already offer binary packages. You can check our Suhosin Downloads page. In that case you only need to activate the extension inside your php.ini and maybe add Configuration directives if you are not satisfied by the default values.
Before you continue compiling the Suhosin-Extension you should verify the file integrity. Please check the preparation section of this guide. The next step is unpacking the extension tarball and performing the usual compilation steps for PHP extensions.
#> cd suhosin
#> phpize
#> ./configure
#> make
#> make install
This should install suhosin in the correct extension directory. The final step is adding a load directive to php.ini
extension=suhosin.so
and optionally add some Configuration directives in case you do not like the default values.
Special Instructions
Some distributions already come with Suhosin source or binary packages. Here is a small overview how to install Suhosin on this distributions.
Installing on Gentoo
Installing and using Suhosin on Gentoo is very easy. At the moment the Suhosin patches and extensions are only available in the external PHP Overlay, and not yet in the Portage tree, you can expect them to also be available in the main Portage tree during October 2006. Let’s install the PHP Overlay then:
#> emerge layman
#> layman -f
#> layman -a php-testing
Now let’s install PHP with the Suhosin patch and extension:
#> echo "dev-lang/php" >> /etc/portage/package.keywords
(unstable version needed)
#> USE="suhosin" emerge =php-4* for PHP4, or =php-5* for PHP5
(NOTE: you cannot also have the "hardenedphp" USE flag enabled at the same time!)
That’s it, your PHP on Gentoo is now running with the Suhosin patch enabled, and the Suhosin extension was automatically installed (from the dev-php{4,5}/suhosin package).
Installing on FreeBSD
The Suhosin-Patch and the Suhosin extension are both within the FreeBSD ports. Therefore installing it on FreeBSD is very simple. The Suhosin-Patch is an option which you can choose when you install the lang/php4 or lang/php5 port. To install the patch just do
#> cd /usr/ports/lang/php5
#> make
... now select the menu item that says: Enable Suhosin Protection
#> make install
To install the extension just do
#> cd /usr/ports/security/php-suhosin
#> make
#> make install
After these simple steps Suhosin-Patch is successfully installed on your system.
Upgrading
Upgrading to a new PHP or new Suhosin-Patch version is quite identical to the normal installation process. This is like upgrading a normal PHP. That means, if the binary compatibility was broken between PHP versions you have to recompile all installed PHP modules/extension. Upgrading the Suhosin-Extension on the other hand is as simple as recompiling it (or using a binary), replacing the file and restarting your webserver.
Log files are a useful tool for webmasters. It helps to know how people are finding your site, and what software they are using to view it, among other things. A strange decision by a small group of bloggers, though, has given unscrupulous marketers another window of opportunity to manipulate search engines to increase their traffic.
The decision made by these short-sighted bloggers was to display, on their site, a list of recent referrers to each page. I can't imagine any reason why a visitor might be in the least bit interested in seeing this, but nevertheless many sites now display referrers on every page.
As search engine spiders visit sites, they grab the contents of each page they visit. They use this snapshot in their index - meaning that although a page may change every minute or two, a search engine may be using a single copy of a page for several days, or even weeks.
So a referral URL that is on a page when the spiders come to visit can have quite a bit of value, if the search engine visiting uses link popularity in any way (Google uses link popularity, as do many others).
So marketers have started to use programs to visit pages using a fake referral header, to get their URLs listed on as many sites as possible, in the hopes that this will increase their traffic.
However, this renders log files almost completely useless. These fake visitors usually visit from search engines, having searched for a keyphrase relevant to their own site. They skew statistics relating to number of visitors received, the countries used to visit, the technology used to view the page, how users found the page, how long they spent on the site ... and so on.
A webmaster may find their search engine rankings dropping because of this, and they may find search engines have removed them completely. Many sites that use spam techniques are quickly identified and penalised, and penalties will often be applied to sites that link to them as well.
There are plenty of techniques available for blocking referrer spam, and everyone has their favourite. Personally, I use a combination of two techniques.
The first is fairly simple - my referrer log is not indexable. I don't display referrers on the pages of my site. My referral log is publicly available, but search engines are instructed to ignore it. This removes the main incentive for people to referrer-spam my site (the other reason for this type of spam - the hope that the site owner will themselves visit the spamming URL - is less common, because it has such a low response rate).
Second, I use an .htaccess file to block requests from whatever I've managed to identify as either a crawler designed to find URLs to spam or a spamming URL. This is a relatively simple blacklist, and though it cannot work as a long term solution to this problem, it keeps me happy for now.
To implement this technique on your own site, first make sure you are running Apache with mod_rewrite. If you are, create a file called ".htaccess" (just that, not .htaccess.txt or anything else) and paste the following into it:
Update: 14th September 2005
The list below has been expanded substantially over the last year, and now covers much more spam than before. As stated before, this is not a practical solution to the problem in the long term, as this list can only ever get longer and longer, and may become unmaintainable, or even (eventually) slow a site to a crawl as all the rules are processed. However, as of now, it is still a useful tool.
RewriteEngine on
# Block Referrer Spam
# Drugs / Herbal
RewriteCond %{HTTP_REFERER} (sleep-?deprivation) [NC,OR]
RewriteCond %{HTTP_REFERER} (sleep-?disorders) [NC,OR]
RewriteCond %{HTTP_REFERER} (insomnia) [NC,OR]
RewriteCond %{HTTP_REFERER} (phentermine) [NC,OR]
RewriteCond %{HTTP_REFERER} (phentemine) [NC,OR]
RewriteCond %{HTTP_REFERER} (vicodin) [NC,OR]
RewriteCond %{HTTP_REFERER} (hydrocodone) [NC,OR]
RewriteCond %{HTTP_REFERER} (levitra) [NC,OR]
RewriteCond %{HTTP_REFERER} (hgh-) [NC,OR]
RewriteCond %{HTTP_REFERER} (-hgh) [NC,OR]
RewriteCond %{HTTP_REFERER} (ultram-) [NC,OR]
RewriteCond %{HTTP_REFERER} (-ultram) [NC,OR]
RewriteCond %{HTTP_REFERER} (cialis) [NC,OR]
RewriteCond %{HTTP_REFERER} (soma-) [NC,OR]
RewriteCond %{HTTP_REFERER} (-soma) [NC,OR]
RewriteCond %{HTTP_REFERER} (diazepam) [NC,OR]
RewriteCond %{HTTP_REFERER} (gabapentin) [NC,OR]
RewriteCond %{HTTP_REFERER} (celebrex) [NC,OR]
RewriteCond %{HTTP_REFERER} (viagra) [NC,OR]
RewriteCond %{HTTP_REFERER} (fioricet) [NC,OR]
RewriteCond %{HTTP_REFERER} (ambien) [NC,OR]
RewriteCond %{HTTP_REFERER} (valium) [NC,OR]
RewriteCond %{HTTP_REFERER} (zoloft) [NC,OR]
RewriteCond %{HTTP_REFERER} (finasteride) [NC,OR]
RewriteCond %{HTTP_REFERER} (lamisil) [NC,OR]
RewriteCond %{HTTP_REFERER} (meridia) [NC,OR]
RewriteCond %{HTTP_REFERER} (allegra) [NC,OR]
RewriteCond %{HTTP_REFERER} (diflucan) [NC,OR]
RewriteCond %{HTTP_REFERER} (zovirax) [NC,OR]
RewriteCond %{HTTP_REFERER} (valtrex) [NC,OR]
RewriteCond %{HTTP_REFERER} (lipitor) [NC,OR]
RewriteCond %{HTTP_REFERER} (proscar) [NC,OR]
RewriteCond %{HTTP_REFERER} (acyclovir) [NC,OR]
RewriteCond %{HTTP_REFERER} (sildenafil) [NC,OR]
RewriteCond %{HTTP_REFERER} (tadalafil) [NC,OR]
RewriteCond %{HTTP_REFERER} (xenical) [NC,OR]
RewriteCond %{HTTP_REFERER} (melatonin) [NC,OR]
RewriteCond %{HTTP_REFERER} (xanax) [NC,OR]
RewriteCond %{HTTP_REFERER} (herbal) [NC,OR]
RewriteCond %{HTTP_REFERER} (drugs) [NC,OR]
RewriteCond %{HTTP_REFERER} (lortab) [NC,OR]
RewriteCond %{HTTP_REFERER} (adipex) [NC,OR]
RewriteCond %{HTTP_REFERER} (propecia) [NC,OR]
RewriteCond %{HTTP_REFERER} (carisoprodol) [NC,OR]
RewriteCond %{HTTP_REFERER} (tramadol) [NC]
RewriteRule .* - [F]
# Porn
RewriteCond %{HTTP_REFERER} (porno) [NC,OR]
RewriteCond %{HTTP_REFERER} (shemale) [NC,OR]
RewriteCond %{HTTP_REFERER} (gangbang) [NC,OR]
RewriteCond %{HTTP_REFERER} (-cock) [NC,OR]
RewriteCond %{HTTP_REFERER} (-anal) [NC,OR]
RewriteCond %{HTTP_REFERER} (-orgy) [NC,OR]
RewriteCond %{HTTP_REFERER} (cock-) [NC,OR]
RewriteCond %{HTTP_REFERER} (anal-) [NC,OR]
RewriteCond %{HTTP_REFERER} (orgy-) [NC,OR]
RewriteCond %{HTTP_REFERER} (singles-?christian) [NC,OR]
RewriteCond %{HTTP_REFERER} (dating-?christian) [NC,OR]
RewriteCond %{HTTP_REFERER} (cumeating) [NC,OR]
RewriteCond %{HTTP_REFERER} (cream-?pies) [NC,OR]
RewriteCond %{HTTP_REFERER} (cumsucking) [NC,OR]
RewriteCond %{HTTP_REFERER} (cumswapping) [NC,OR]
RewriteCond %{HTTP_REFERER} (cumfilled) [NC,OR]
RewriteCond %{HTTP_REFERER} (cumdripping) [NC,OR]
RewriteCond %{HTTP_REFERER} (krankenversicherung) [NC,OR]
RewriteCond %{HTTP_REFERER} (cumpussy) [NC,OR]
RewriteCond %{HTTP_REFERER} (suckingcum) [NC,OR]
RewriteCond %{HTTP_REFERER} (drippingcum) [NC,OR]
RewriteCond %{HTTP_REFERER} (pussycum) [NC,OR]
RewriteCond %{HTTP_REFERER} (swappingcum) [NC,OR]
RewriteCond %{HTTP_REFERER} (eatingcum) [NC,OR]
RewriteCond %{HTTP_REFERER} (cum-) [NC,OR]
RewriteCond %{HTTP_REFERER} (-cum) [NC,OR]
RewriteCond %{HTTP_REFERER} (sperm) [NC,OR]
RewriteCond %{HTTP_REFERER} (christian-?dating) [NC,OR]
RewriteCond %{HTTP_REFERER} (jewish-?singles) [NC,OR]
RewriteCond %{HTTP_REFERER} (sex-?meetings) [NC,OR]
RewriteCond %{HTTP_REFERER} (swinging) [NC,OR]
RewriteCond %{HTTP_REFERER} (swingers) [NC,OR]
RewriteCond %{HTTP_REFERER} (personals) [NC,OR]
RewriteCond %{HTTP_REFERER} (sleeping) [NC,OR]
RewriteCond %{HTTP_REFERER} (libido) [NC,OR]
RewriteCond %{HTTP_REFERER} (grannies) [NC,OR]
RewriteCond %{HTTP_REFERER} (mature) [NC,OR]
RewriteCond %{HTTP_REFERER} (enhancement) [NC,OR]
RewriteCond %{HTTP_REFERER} (sexual) [NC,OR]
RewriteCond %{HTTP_REFERER} (gay-?teen) [NC,OR]
RewriteCond %{HTTP_REFERER} (teen-?chat) [NC,OR]
RewriteCond %{HTTP_REFERER} (gay-?chat) [NC,OR]
RewriteCond %{HTTP_REFERER} (adult-?finder) [NC,OR]
RewriteCond %{HTTP_REFERER} (adult-?friend) [NC,OR]
RewriteCond %{HTTP_REFERER} (friend-?finder) [NC,OR]
RewriteCond %{HTTP_REFERER} (friend-?adult) [NC,OR]
RewriteCond %{HTTP_REFERER} (finder-?adult) [NC,OR]
RewriteCond %{HTTP_REFERER} (finder-?friend) [NC,OR]
RewriteCond %{HTTP_REFERER} (discrete-?encounters) [NC,OR]
RewriteCond %{HTTP_REFERER} (cheating-?wives) [NC,OR]
RewriteCond %{HTTP_REFERER} (housewives) [NC,OR]
RewriteCond %{HTTP_REFERER} (\-sex\.) [NC,OR]
RewriteCond %{HTTP_REFERER} (xxx) [NC,OR]
RewriteCond %{HTTP_REFERER} (snowballing) [NC]
RewriteRule .* - [F]
# Weight
RewriteCond %{HTTP_REFERER} (fat-) [NC,OR]
RewriteCond %{HTTP_REFERER} (-fat) [NC,OR]
RewriteCond %{HTTP_REFERER} (diet) [NC,OR]
RewriteCond %{HTTP_REFERER} (pills) [NC,OR]
RewriteCond %{HTTP_REFERER} (weight) [NC,OR]
RewriteCond %{HTTP_REFERER} (supplement) [NC]
RewriteRule .* - [F]
# Gambling
RewriteCond %{HTTP_REFERER} (texas-?hold-?em) [NC,OR]
RewriteCond %{HTTP_REFERER} (poker) [NC,OR]
RewriteCond %{HTTP_REFERER} (casino) [NC,OR]
RewriteCond %{HTTP_REFERER} (blackjack) [NC]
RewriteRule .* - [F]
# Loans / Finance
RewriteCond %{HTTP_REFERER} (mortgage) [NC,OR]
RewriteCond %{HTTP_REFERER} (refinancing) [NC,OR]
RewriteCond %{HTTP_REFERER} (cash-?advance) [NC,OR]
RewriteCond %{HTTP_REFERER} (cash-?money) [NC,OR]
RewriteCond %{HTTP_REFERER} (pay-?day) [NC]
RewriteRule .* - [F]
# User Agents
RewriteCond %{HTTP_USER_AGENT} (Program\ Shareware|Fetch\ API\ Request) [NC,OR]
RewriteCond %{HTTP_USER_AGENT} (Microsoft\ URL\ Control) [NC]
RewriteRule .* - [F]
# Misc / Specific Sites
RewriteCond %{HTTP_REFERER} (netwasgroup\.com) [NC,OR]
RewriteCond %{HTTP_REFERER} (nic4u\.com) [NC,OR]
RewriteCond %{HTTP_REFERER} (wear4u\.com) [NC,OR]
RewriteCond %{HTTP_REFERER} (foxmediasolutions\.com) [NC,OR]
RewriteCond %{HTTP_REFERER} (liveplanets\.com) [NC,OR]
RewriteCond %{HTTP_REFERER} (aeterna-tech\.com) [NC,OR]
RewriteCond %{HTTP_REFERER} (continentaltirebowl\.com) [NC,OR]
RewriteCond %{HTTP_REFERER} (chemsymphony\.com) [NC,OR]
RewriteCond %{HTTP_REFERER} (infolibria\.com) [NC,OR]
RewriteCond %{HTTP_REFERER} (globaleducationeurope\.net) [NC,OR]
RewriteCond %{HTTP_REFERER} (soma\.125mb\.com) [NC,OR]
RewriteCond %{HTTP_REFERER} (mitglied\.lycos\.de) [NC,OR]
RewriteCond %{HTTP_REFERER} (foxmediasolutions\.com) [NC,OR]
RewriteCond %{HTTP_REFERER} (jroundup\.com) [NC,OR]
RewriteCond %{HTTP_REFERER} (feathersandfurvanlines\.com) [NC,OR]
RewriteCond %{HTTP_REFERER} (conecrusher\.org) [NC,OR]
RewriteCond %{HTTP_REFERER} (sbj-broadcasting\.com) [NC,OR]
RewriteCond %{HTTP_REFERER} (edthompson\.com) [NC,OR]
RewriteCond %{HTTP_REFERER} (codychesnutt\.com) [NC,OR]
RewriteCond %{HTTP_REFERER} (artsmallforsenate\.com) [NC,OR]
RewriteCond %{HTTP_REFERER} (axionfootwear\.com) [NC,OR]
RewriteCond %{HTTP_REFERER} (protzonbeer\.com) [NC,OR]
RewriteCond %{HTTP_REFERER} (candiria\.com) [NC,OR]
RewriteCond %{HTTP_REFERER} (bigsitecity\.com) [NC,OR]
RewriteCond %{HTTP_REFERER} (coresat\.com) [NC,OR]
RewriteCond %{HTTP_REFERER} (istarthere\.com) [NC,OR]
RewriteCond %{HTTP_REFERER} (amateurvoetbal\.net) [NC,OR]
RewriteCond %{HTTP_REFERER} (alleghanyeda\.com) [NC,OR]
RewriteCond %{HTTP_REFERER} (xadulthosting\.com) [NC,OR]
RewriteCond %{HTTP_REFERER} (datashaping\.com) [NC,OR]
RewriteCond %{HTTP_REFERER} (zick\.biz) [NC,OR]
RewriteCond %{HTTP_REFERER} (newprinceton\.com) [NC,OR]
RewriteCond %{HTTP_REFERER} (dvdsqueeze\.com) [NC,OR]
RewriteCond %{HTTP_REFERER} (xopy\.com) [NC,OR]
RewriteCond %{HTTP_REFERER} (webdevboard\.com) [NC,OR]
RewriteCond %{HTTP_REFERER} (devaddict\.com) [NC,OR]
RewriteCond %{HTTP_REFERER} (eaton-inc\.com) [NC,OR]
RewriteCond %{HTTP_REFERER} (whiteguysgroup\.com) [NC,OR]
RewriteCond %{HTTP_REFERER} (guestbookz\.com) [NC,OR]
RewriteCond %{HTTP_REFERER} (webdevsquare\.com) [NC,OR]
RewriteCond %{HTTP_REFERER} (indfx\.net) [NC,OR]
RewriteCond %{HTTP_REFERER} (snap\.to) [NC,OR]
RewriteCond %{HTTP_REFERER} (2y\.net) [NC,OR]
RewriteCond %{HTTP_REFERER} (astromagia\.info) [NC,OR]
RewriteCond %{HTTP_REFERER} (free-?sms) [NC]
RewriteRule .* - [F]
The above will block just about all of the most common referral spam that I've seen so far. I'm adding to the list constantly (last addition: 14th September 2005) so do check back and see if there are updates if you're using it.
One potential problem with this technique, other than that it will, in time, become useless as too many URLs are added, is that there is always a possibility authentic visitors will be blocked. So, on this site, instead of the last line above, I've actually used something a little more user-friendly:
RewriteRule .* bad_referrer.php [L]
And there we have it. With minimum effort (for now), referral log spamming in my site has been almost entirely removed. Before adding this set of rules and scripts, I was seeing around 200 fake referrals per day in my log files. Now, I see about 3 or 4 a week. Hopefully, this will continue until I can devise a better way of protecting against this kind of problem - before blacklists become an impossibility to manage.
Introduction
URL rewriting can be one of the best and quickest ways to improve the usability and search friendliness of your site. It can also be the source of near-unending misery and suffering. Definitely worth playing carefully with it - lots of testing is recommended. With great power comes great responsibility, and all that.
There are several other guides on the web already, that may suit your needs better than this one.
Before reading on, you may find it helpful to have the mod_rewrite cheat sheet and/or the regular expressions cheat sheet handy. A basic grasp of the concept of regular expressions would also be very helpful.
What is "URL Rewriting"?
Most dynamic sites include variables in their URLs that tell the site what information to show the user. Typically, this gives URLs like the following, telling the relevant script on a site to load product number 7.
http://www.pets.com/show_a_product.php?product_id=7
The problems with this kind of URL structure are that the URL is not at all memorable. It's difficult to read out over the phone (you'd be surprised how many people pass URLs this way). Search engines and users alike get no useful information about the content of a page from that URL. You can't tell from that URL that that page allows you to buy a Norwegian Blue Parrot (lovely plumage). It's a fairly standard URL - the sort you'd get by default from most CMSes. Compare that to this URL:
http://www.pets.com/products/7/
Clearly a much cleaner and shorter URL. It's much easier to remember, and vastly easier to read out. That said, it doesn't exactly tell anyone what it refers to. But we can do more:
http://www.pets.com/parrots/norwegian-blue/
Now we're getting somewhere. You can tell from the URL, even when it's taken out of context, what you're likely to find on that page. Search engines can split that URL into words (hyphens in URLs are treated as spaces by search engines, whereas underscores are not), and they can use that information to better determine the content of the page. It's an easy URL to remember and to pass to another person.
Unfortunately, the last URL cannot be easily understood by a server without some work on our part. When a request is made for that URL, the server needs to work out how to process that URL so that it knows what to send back to the user. URL rewriting is the technique used to "translate" a URL like the last one into something the server can understand.
Platforms and Tools
Depending on the software your server is running, you may already have access to URL rewriting modules. If not, most hosts will enable or install the relevant modules for you if you ask them very nicely.
Apache is the easiest system to get URL rewriting running on. It usually comes with its own built-in URL rewriting module, mod_rewrite, enabled, and working with mod_rewrite is as simple as uploading correctly formatted and named text files.
IIS, Microsoft's server software, doesn't include URL rewriting capability as standard, but there are add-ons out there that can provide this functionality. ISAPI_Rewrite is the one I recommend working with, as I've so far found it to be the closest to mod_rewrite's functionality. Instructions for installing and configuring ISAPI_Rewrite can be found at the end of this article.
The code that follows is based on URL rewriting using mod_rewrite.
Basic URL Rewriting
To begin with, let's consider a simple example. We have a website, and we have a single PHP script that serves a single page. Its URL is:
http://www.pets.com/pet_care_info_07_07_2008.php
We want to clean up the URL, and our ideal URL would be:
http://www.pets.com/pet-care/
In order for this to work, we need to tell the server to internally redirect all requests for the URL "pet-care" to "pet_care_info_07_07_2008.php". We want this to happen internally, because we don't want the URL in the browser's address bar to change.
To accomplish this, we need to first create a text document called ".htaccess" to contain our rules. It must be named exactly that (not ".htaccess.txt" or "rules.htaccess"). This would be placed in the root directory of the server (the same folder as "pet_care_info_07_07_2008.php" in our example). There may already be an .htaccess file there, in which case we should edit that rather than overwrite it.
The .htaccess file is a configuration file for the server. If there are errors in the file, the server will display an error message (usually with an error code of "500"). If you are transferring the file to the server using FTP, you must make sure it is transferred using the ASCII mode, rather than BINARY. We use this file to perform 2 simple tasks in this instance - first, to tell Apache to turn on the rewrite engine, and second, to tell apache what rewriting rule we want it to use. We need to add the following to the file:
RewriteEngine On # Turn on the rewriting engine
RewriteRule ^pet-care/?$ pet_care_info_01_02_2003.php [NC,L] # Handle requests for "pet-care"
A couple of quick items to note - everything following a hash symbol in an .htaccess file is ignored as a comment, and I'd recommend you use comments liberally; and the "RewriteEngine" line should only be used once per .htaccess file (please note that I've not included this line from here onwards in code example).
The "RewriteRule" line is where the magic happens. The line can be broken down into 5 parts:
- RewriteRule - Tells Apache that this like refers to a single RewriteRule.
- ^/pet-care/?$ - The "pattern". The server will check the URL of every request to the site to see if this pattern matches. If it does, then Apache will swap the URL of the request for the "substitution" section that follows.
- pet_care_info_01_02_2003.php - The "substitution". If the pattern above matches the request, Apache uses this URL instead of the requested URL.
- [NC,L] - "Flags", that tell Apache how to apply the rule. In this case, we're using two flags. "NC", tells Apache that this rule should be case-insensitive, and "L" tells Apache not to process any more rules if this one is used.
- # Handle requests for "pet-care" - Comment explaining what the rule does (optional but recommended)
The rule above is a simple method for rewriting a single URL, and is the basis for almost all URL rewriting rules.
Patterns and Replacements
The rule above allows you to redirect requests for a single URL, but the real power of mod_rewrite comes when you start to identify and rewrite groups of URLs based on patterns they contain.
Let's say you want to change all of your site URLs as described in the first pair of examples above. Your existing URLs look like this:
http://www.pets.com/show_a_product.php?product_id=7
And you want to change them to look like this:
http://www.pets.com/products/7/
Rather than write a rule for every single product ID, you of course would rather write one rule to manage all product IDs. Effectively you want to change URLs of this format:
http://www.pets.com/show_a_product.php?product_id={a number}
And you want to change them to look like this:
http://www.pets.com/products/{a number}/
In order to do so, you will need to use "regular expressions". These are patterns, defined in a specific format that the server can understand and handle appropriately. A typical pattern to identify a number would look like this:
[0-9]+
The square brackets contain a range of characters, and "0-9" indicates all the digits. The plus symbol indicates that the pattern will idenfiy one or more of whatever precedes the plus - so this pattern effectively means "one or more digits" - exactly what we're looking to find in our URL.
The entire "pattern" part of the rule is treated as a regular expression by default - you don't need to turn this on or activate it at all.
RewriteRule ^products/([0-9]+)/?$ show_a_product.php?product_id=$1 [NC,L] # Handle product requests
The first thing I hope you'll notice is that we've wrapped our pattern in brackets. This allows us to "back-reference" (refer back to) that section of the URL in the following "substitution" section. The "$1" in the substitution tells Apache to put whatever matched the earlier bracketed pattern into the URL at this point. You can have lots of backreferences, and they are numbered in the order they appear.
And so, this RewriteRule will now mean that Apache redirects all requests for domain.com/products/{number}/ to show_a_product.php?product_id={same number}.
Regular Expressions
A complete guide to regular expressions is rather beyond the scope of this article. However, important points to remember are that the entire pattern is treated as a regular expression, so always be careful of characters that are "special" characters in regular expressions.
The most instance of this is when people use a period in their pattern. In a pattern, this actually means "any character" rather than a literal period, and so if you want to match a period (and only a period) you will need to "escape" the character - precede it with another special character, a backslash, that tells Apache to take the next character to be literal.
For example, this RewriteRule will not just match the URL "rss.xml" as intended - it will also match "rss1xml", "rss-xml" and so on.
RewriteRule ^rss.xml$ rss.php [NC,L] # Change feed URL
This does not usually present a serious problem, but escaping characters properly is a very good habit to get into early. Here's how it should look:
RewriteRule ^rss\.xml$ rss.php [NC,L] # Change feed URL
This only applies to the pattern, not to the substitution. Other characters that require escaping (referred to as "metacharacters") follow, with their meaning in brackets afterwards:
- . (any character)
- * (zero of more of the preceding)
- + (one or more of the preceding)
- {} (minimum to maximum quantifier)
- ? (ungreedy modifier)
- ! (at start of string means "negative pattern")
- ^ (start of string, or "negative" if at the start of a range)
- $ (end of string)
- [] (match any of contents)
- - (range if used between square brackets)
- () (group, backreferenced group)
- | (alternative, or)
- \ (the escape character itself)
Using regular expressions, it is possible to search for all sorts of patterns in URLs and rewrite them when they match. Time for another example - we wanted earlier to be able to indentify this URL and rewrite it:
http://www.pets.com/parrots/norwegian-blue/
And we want to be able to tell the server to interpret this as the following, but for all products:
http://www.pets.com/get_product_by_name.php?product_name=norwegian-blue
And we can do that relatively simply, with the following rule:
RewriteRule ^parrots/([A-Za-z0-9-]+)/?$ get_product_by_name.php?product_name=$1 [NC,L] # Process parrots
With this rule, any URL that starts with "parrots" followed by a slash (parrots/), then one or more (+) of any combination of letters, numbers and hyphens ([A-Za-z0-9-]) (note the hyphen at the end of the selection of characters within square brackets - it must be added there to be treated literally rather than as a range separator). We reference the product name in brackets with $1 in the substitution.
We can make it even more generic, if we want, so that it doesn't matter what directory a product appears to be in, it is still sent to the same script, like so:
RewriteRule ^[A-Za-z-]+/([A-Za-z0-9-]+)/?$ get_product_by_name.php?product_name=$1 [NC,L] # Process all products
As you can see, we've replaced "parrots" with a pattern that matches letter and hyphens. That rule will now match anything in the parrots directory or any other directory whose name is comprised of at least one or more letters and hyphens.
Flags
Flags are added to the end of a rewrite rule to tell Apache how to interpret and handle the rule. They can be used to tell apache to treat the rule as case-insensitive, to stop processing rules if the current one matches, or a variety of other options. They are comma-separated, and contained in square brackets. Here's a list of the flags, with their meanings (this information is included on the cheat sheet, so no need to try to learn them all).
- C (chained with next rule)
- CO=cookie (set specified cookie)
- E=var:value (set environment variable var to value)
- F (forbidden - sends a 403 header to the user)
- G (gone - no longer exists)
- H=handler (set handler)
- L (last - stop processing rules)
- N (next - continue processing rules)
- NC (case insensitive)
- NE (do not escape special URL characters in output)
- NS (ignore this rule if the request is a subrequest)
- P (proxy - i.e., apache should grab the remote content specified in the substitution section and return it)
- PT (pass through - use when processing URLs with additional handlers, e.g., mod_alias)
- R (temporary redirect to new URL)
- R=301 (permanent redirect to new URL)
- QSA (append query string from request to substituted URL)
- S=x (skip next x rules)
- T=mime-type (force specified mime type)
Moving Content
RewriteRule ^article/?$ http://www.new-domain.com/article/ [R,NC,L] # Temporary Move
Adding an "R" flag to the flags section changes how a RewriteRule works. Instead of rewriting the URL internally, Apache will send a message back to the browser (an HTTP header) to tell it that the document has moved temporarily to the URL given in the "substitution" section. Either an absolute or a relative URL can be given in the substitution section. The header sent back includea a code - 302 - that indicates the move is temporary.
RewriteRule ^article/?$ http://www.new-domain.com/article/ [R=301,NC,L] # Permanent Move
If the move is permanent, append "=301" to the "R" flag to have Apache tell the browser the move is considered permanent. Unlike the default "R", "R=301" will also tell the browser to display the new address in the address bar.
This is one of the most common methods of rewriting URLs of items that have moved to a new URL (for example, it is in use extensively on this site to forward users to new post URLs whenever they are changed).
Conditions
Rewrite rules can be preceded by one or more rewrite conditions, and these can be strung together. This can allow you to only apply certain rules to a subset of requests. Personally, I use this most often when applying rules to a subdomain or alternative domain as rewrite conditions can be run against a variety of criteria, not just the URL. Here's an example:
RewriteCond %{HTTP_HOST} ^addedbytes\.com [NC]
RewriteRule ^(.*)$ http://www.addedbytes.com/$1 [L,R=301]
The rewrite rule above redirects all requests, no matter what for, to the same URL at "www.addedbytes.com". Without the condition, this rule would create a loop, with every request matching that rule and being sent back to itself. The rule is intended to only redirect requests missing the "www" URL portion, though, and the condition preceding the rule ensures that this happens.
The condition operates in a similar way to the rule. It starts with "RewriteCond" to tell mod_rewrite this line refers to a condition. Following that is what should actually be tested, and then the pattern to test. Finally, the flags in square brackets, the same as with a RewriteRule.
The string to test (the second part of the condition) can be a variety of different things. You can test the domain being requested, as with the above example, or you could test the browser being used, the referring URL (commonly used to prevent hotlinking), the user's IP address, or a variety of other things (see the "server variables" section for an outline of how these work).
The pattern is almost exactly the same as that used in a RewriteRule, with a couple of small exceptions. The pattern may not be interpreted as a pattern if it starts with specific characters as described in the following "exceptions" section. This means that if you wish to use a regular expression pattern starting with <, >, or a hyphen, you should escape them with the backslash.
Rewrite conditions can, like rewrite rules, be followed by flags, and there are only two. "NC", as with rules, tells Apache to treat the condition as case-insensitive. The other available flag is "OR". If you only want to apply a rule if one of two conditions match, rather than repeat the rule, add the "OR" flag to the first condition, and if either match then the following rule will be applied. The default behaviour, if a rule is preceded by multiple conditions, is that it is only applied if all rules match.
Exceptions and Special Cases
Rewrite conditions can be tested in a few different ways - they do not need to be treated as regular expression patterns, although this is the most common way they are used. Here are the various ways rewrite conditons can be processed:
- <Pattern (is test string lower than pattern)
- >Pattern (is test string greater than pattern)
- =Pattern (is test string equal to pattern)
- -d (is test string a valid directory)
- -f (is test string a valid file)
- -s (is test string a valid file with size greater than zero)
- -l (is test string a symbolic link)
- -F (is test string a valid file, and accessible (via subrequest))
- -U (is test string a valid URL, and accessible (via subrequest))
Server Variables
Server variables are a selection of items you can test when writing rewrite conditions. This allows you to apply rules based on all sorts of request parameters, including browser identifiers, referring URL or a multitude of other strings. Variables are of the following format:
%{VARIABLE_NAME}
And "VARIABLE_NAME" can be replaced with any one of the following items:
- HTTP Headers
- HTTP_USER_AGENT
- HTTP_REFERER
- HTTP_COOKIE
- HTTP_FORWARDED
- HTTP_HOST
- HTTP_PROXY_CONNECTION
- HTTP_ACCEPT
- Connection Variables
- REMOTE_ADDR
- REMOTE_HOST
- REMOTE_USER
- REMOTE_IDENT
- REQUEST_METHOD
- SCRIPT_FILENAME
- PATH_INFO
- QUERY_STRING
- AUTH_TYPE
- Server Variables
- DOCUMENT_ROOT
- SERVER_ADMIN
- SERVER_NAME
- SERVER_ADDR
- SERVER_PORT
- SERVER_PROTOCOL
- SERVER_SOFTWARE
- Dates and Times
- TIME_YEAR
- TIME_MON
- TIME_DAY
- TIME_HOUR
- TIME_MIN
- TIME_SEC
- TIME_WDAY
- TIME
- Special Items
- API_VERSION
- THE_REQUEST
- REQUEST_URI
- REQUEST_FILENAME
- IS_SUBREQ
Working With Multiple Rules
The more complicated a site, the more complicated the set of rules governing it can be. This can be problematic when it comes to resolving conflicts between rules. You will find this issue rears its ugly head most often when you add a new rule to a file, and it doesn't work. What you may find, if the rule itself is not at fault, is that an earlier rule in the file is matching the URL and so the URL is not being tested against the new rule you've just added.
RewriteRule ^([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/?$ get_product_by_name.php?category_name=$1&product_name=$2 [NC,L] # Process product requests
RewriteRule ^([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/?$ get_blog_post_by_title.php?category_name=$1&post_title=$2 [NC,L] # Process blog posts
In the example above, the product pages of a site and the blog post pages have identical patterns. The second rule will never match a URL, because anything that would match that pattern will have already been matched by the first rule.
There are a few ways to work around this. Several CMSes (including wordpress) handle this by adding an extra portion to the URL to denote the type of request, like so:
RewriteRule ^products/([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/?$ get_product_by_name.php?category_name=$1&product_name=$2 [NC,L] # Process product requests
RewriteRule ^blog/([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/?$ get_blog_post_by_title.php?category_name=$1&post_title=$2 [NC,L] # Process blog posts
You could also write a single PHP script to process all requests, which checked to see if the second part of the URL matched a blog post or a product. I usually go for this option, as while it may increase the load on the server slightly, it gives much cleaner URLs.
RewriteRule ^([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/?$ get_product_or_blog_post.php?category_name=$1&item_name=$2 [NC,L] # Process product and blog requests
There are certain situations where you can work around this issue by writing more precise rules and ordering your rules intelligently. Imagine a blog where there were two archives - one by topic and one by year.
RewriteRule ^([A-Za-z0-9-]+)/?$ get_archives_by_topic.php?topic_name=$1 [NC,L] # Get archive by topic
RewriteRule ^([A-Za-z0-9-]+)/?$ get_archives_by_year.php?year=$1 [NC,L] # Get archive by year
The above rules will conflict. Of course, years are numeric and only 4 digits, so you can make that rule more precise, and by running it first the only type of conflict you cound encounter would be if you had a topic with a 4-digit number for a name.
RewriteRule ^([0-9]{4})/?$ get_archives_by_year.php?year=$1 [NC,L] # Get archive by year
RewriteRule ^([A-Za-z0-9-]+)/?$ get_archives_by_topic.php?topic_name=$1 [NC,L] # Get archive by topic
mod_rewrite
Apache's mod_rewrite comes as standard with most Apache hosting accounts, so if you're on shared hosting, you are unlikely to have to do anything. If you're managing your own box, then you most likely just have to turn on mod_rewrite. If you are using Apache1, you will need to edit your httpd.conf file and remove the leading '#' from the following lines:
#LoadModule rewrite_module modules/mod_rewrite.so
#AddModule mod_rewrite.c
If you are using Apache2 on a Debian-based distribution, you need to run the following command and then restart Apache:
sudo a2enmod rewrite
Other distubutions and platforms differ. If the above instructions are not suitable for your system, then Google is your friend. You may need to edit your apache2 configuration file and add "rewrite" to the "APACHE_MODULES" list, or edit httpd.conf, or even download and compile mod_rewrite yourself. For the majority, however, installation should be simple.
ISAPI_Rewrite
ISAPI_Rewrite is a URL rewriting plugin for IIS based on mod_rewrite and is not free. It performs most of the same functionality as mod_rewrite, and there is a good quality ISAPI_Rewrite forum where most common questions are answered. As ISAPI_Rewrite works with IIS, installation is relatively simple - there are installation instructions available.
ISAPI_Rewrite rules go into a file named httpd.ini. Errors will go into a file named httpd.parse.errors by default.
Leading Slashes
I have found myself tripped up numerous times by leading slashes in URL rewriting systems. Whether they should be used in the pattern or in the substitution section of a RewriteRule or used in a RewriteCond statement is a constant source of frustration to me. This may be in part because I work with different URL rewriting engines, but I would advise being careful of leading slashes - if a rule is not working, that's often a good place to start looking. I never include leading slashes in mod_rewrite rules and always include them in ISAPI_Rewrite.
Sample Rules
To redirect an old domain to a new domain:
RewriteCond %{HTTP_HOST} old_domain\.com [NC]
RewriteRule ^(.*)$ http://www.new_domain.com/$1 [L,R=301]
To redirect all requests missing "www" (yes www):
RewriteCond %{HTTP_HOST} ^domain\.com [NC]
RewriteRule ^(.*)$ http://www.domain.com/$1 [L,R=301]
To redirect all requests with "www" (no www):
RewriteCond %{HTTP_HOST} ^www\.domain\.com [NC]
RewriteRule ^(.*)$ http://domain.com/$1 [L,R=301]
Redirect old page to new page:
RewriteRule ^old-url\.htm$ http://www.domain.com/new-url.htm [NC,R=301,L]
Useful Links
Summary
Hopefully if you've made it this far you now have a clear understanding of what URL rewriting is and how to add it to your site. It is worth taking the time to become familiar with - it can benefit your SEO efforts immediately, and increase the usability of your site.
Thanks To www.addedbytes.com