Making mod_rewrite on Ubuntu Server actually work

Ubuntu LogoThroughout the updating to, there were a lot of new things to learn; I switched from CentOS to Ubuntu Server, my own hardware to Amazon’s EC2 service, and I moved the website to a much more sophisticated web platform. One of the coolest features about the presentation of the site was the ability to use mod_rewrite to change the URL.

The use of mod_rewrite allowed me to have URL’s change from to Not only is this a more user friendly method of displaying a URL, it is also more secure and more search engine friendly. I did encounter some challenges as I got mod_rewrite to work on Ubuntu Server and, after all kinds of Googl’ing, I never did find the answer until I figured it out on my own.

To enable mod_rewrite on Ubuntu Server 10.04 (and probably most if not all versions), run the following command:

sudo a2enmod rewrite

After you run that command, it may just work. However, it did not work for me. After I wrote my rewrite rules in my .htaccess file, I would get an “Access Forbidden” (403) error. Of course you have to have the following in your host configuration file in /etc/apache2/sites-enabled file:

AllowOverride All
Options +FollowSymLinks

The part of +FollowSymLinks just wasn’t working. In /var/log/apache2/error.log it was telling me that FollowSymLinks wasn’t enabled. The way to fix this problem (THIS IS WHAT YOU ARE LOOKING FOR) was to add that option directly to the .htaccess file. Here is my .htaccess file at the root of my website now:

Options +FollowSymlinks
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

Now mod_rewrite is working. If it still doesn’t work, make sure you restarted the Apache service:

service apache2 restart

How to encrypt a file in Linux

keyIf you have sensitive information that needs to be sent or kept private, encrypt it!

GPG is a *nix program used for encrypting and decrypting files. This tutorial shows GPG in the most basic form – step by step.

Follow these steps in command line to encrypt and decrypt files:

Create a file

touch gpg_test
echo "The quick brown fox jumped over the lazy dog" &gt; gpg_test

Now, open gpg_test and you will see the contents of it are exactly what you put into it.

Encrypt the file

gpg -c gpg_test
# Enter password, then enter it again

Notice now that you have the original file, and now there is another file called gpg_test.gpg. The original file is not encrypted, so why not shred it so that it is securely removed?

shred -uzvn 25 gpg_test

View the contents of gpg_test.gpg

cat gpg_test.gpg

The content of the file was encrypted and completely unreadable. But say you want to open the file in the future, or you want somebody else to open the file. Here’s how you do it:

gpg gpg_test.gpg
# Enter Password

Now the file has been restored as the original – leaving the encrypted version there as well in case you need to send it to somebody else.

Installing Dell V515w Printer on Arch Linux

Dell printers can be a challenge to install on some Linux distributions…

However, once you figure out the key files, it makes it a little bit easier to make things happen. The steps here are basically hacks that I went through until I could figure out what was going on. Here are some KEY bits of information to get things going:

Summary of Requirements

Install dpkg (Debian Package Manager)

To install dpkg, you need to get it from the AUR (Arch User Repository). The easiest way is to follow these steps:

echo "[archlinuxfr]" &gt;&gt; /etc/pacman.conf
 echo "Server =" &gt;&gt; /etc/pacman.conf
 pacman -Syu yaourt

At this point, yaourt should now be installed. Now to install dpkg (NEVER EVER RUN YAOURT AS ROOT!!!):

When you run the following command, select “dpkg” – at the time of this article, it was number 3 on the list:

yaourt dpkg

No need to modify the makepkg or anything – just let it do its thing.

Getting the .deb file from the Dell .sh installer

This part is a little tricky. Do these steps (as regular user – not root) and it “should” work:

  • sh
  • Open up your user’s home directory (use the GUI for this)
  • Go into the lua* directory that was created by the installer
  • As you press next in the wizard, you will notice some files that pop up in that directory. When they do, quickly copy the .deb files to your desktop or somewhere that you will remember
  • I know it’s tricky, but keep trying. It worked for me

Run the .deb file

dpkg -i --force-architecture dell-inkjet-09-driver-1.0-1.i386.deb

Check if “dlnet” exists in /usr/lib/cups/backend

ls /usr/lib/cups/backend/dlnet

If the dlnet file does exist, then you can now run system-config-printer and add your printer (use Dell Network Backend as the socket when the list comes up:

dlnet:// &lt;-- Change that with the IP of your printer

When it asks for a driver file, select the Dell_V310V510_Series.ppd file (if you can’t find it, run this command):

find / -name Dell_V310V510_Series.ppd

If the dlnet file is not in /usr/lib/cups/backend…

Then you will have to extract the .deb files and

bsdtar -xf *.i386.deb; tar -xzvf data.tar.gz; cd usr/local/dell/dell09/bin; cp dlnet /usr/lib/cups/backend/

Now proceed to the step above this one and configure your printer.

If something didn’t work for you, or if I missed something…

I wrote this article after spending about 20 hours trying to get this printer to work. Because of this, there are probably some things I forgot – but I believe the most important stuff is written here. If you notice anything off or that needs to be added, please just reply using the comments area below.

The very powerful sed command

Have you ever needed to replace a string in a file or multiple files? Why not try it without opening a file?

I do a lot of web design. Every so often, I will have a string or a variable in a web page which is in there many times. Even more often, the same string will be in multiple files – multiple times. This occurs most often in plain HTML code. However, there are often times where it happens in a regular text document or a configuration file. The best example of this is Conky which is a program that allows you to “code” a desktop widget. In my Conky script, I had the color red in the file many times – about 10 times. I’m sure I could probably use a variable and only have to change the color in one place, but I haven’t gotten to the point where I know how to make a variable in Conky. So, for instance, the following line might be in my Conky script 10 times:

${color F00}This is red text${color}

Going through each line to change the color to green (0F0) can be very redundant, and this is where sed comes to the rescue.

Follow these steps to get a good working example of sed:

  • Open up the Linux/Unix terminal of choice
  • enter these commands:
touch sed.txt
echo "a b c d e f g h i j k l m n o p q r s t u v w x y z" > sed.txt

Now that we have a file to work with, let’s replace the letters l, m, and n with your name:

sed -i 's/l m n/Kris/g' sed.txt

From what I understand, the -i makes sure the file is saved with the changes. The s searches for all of the strings that match “l m n” and replaces them with Kris. The g makes sure that it goes to the end of the current line – for each line.

Your name should now be in the file instead of the l, m, and n. Let’s check to make sure:

cat sed.txt

sed is very powerful and can do things beyond what I have shown here. To learn more about sed, take a look at its man page.
man sed

Move the Windows Paging file

If you need a performance boost on Windows (or in a Windows Virtual Machine), then moving your page file might be a big help. The page file is a type of “swap” file that Windows uses to store blocks of data – typically when the memory is fully used or unavailable. When you have the page file on the same disk partition as the Windows system files, performance is not going to be as good as it would be if it was on a separate disk or even partition.

To move the page file, follow these steps:

*Note for virtualization users: Do this for every virtual machine (However, you can create the new virtual disk once and copy it to every other virtual machine directory and then “use an existing hard drive for each virtual machine.”

Creating a partition

  • Create a new partition of about 2+ GigaBytes (either by shrinking your disk and adding a new partition, adding a physical disk, or creating a new disk if you’re in a virtual environment).
  • Once the partition is added, open up the Computer Management console and drill down to Disk Management.
  • From there, right-click on the new partition (in the grey area at the left side) and make sure the disk is “online”
  • Next, right-click the disk and create a new simple partition. Format it with NTFS and assign it a drive letter.

Using the partition as a Page File

  • Right-Click on Computer in the start menu
  • Select properties and then, in the menu at the left, select Advanced System Properties
  • In the Advanced tab under the Performance category, select the Settings button.
  • Change the radio button to “Adjust for Performance”
  • Go the the Advanced tab and click the Change button under Virtual Memory
  • Uncheck the “Automatically manage paging file size for all drives”
  • Select the C: drive
  • Select the “No Paging File” radio button and the press the Set button to apply the setting.
  • Next, select the new partition you created (probably the second drive in the list)
  • Click the Custom Size radio button
  • Enter 2000 for the Initial Size (MB), and enter 2000 (or whatever the maximum available size is) for the Maximum Size (MB) (This is a fixed size – you don’t want the page file size to be dynamic – use the full size of the partition)
  • Press the Set button again and press okay.
  • Press okay two more times and reboot the computer or virtual machine and you should notice a fairly decent performance boost.

Linux DNS Server Setup

What is the Domain Name System(DNS? The DNS is the glue that keeps the Internet together. DNS translates domain name( to an IP address and vice versa. It’s much easier for us to remember names than numbers.

DNS is defined in Request for Comments (RFCs) 1034 and 1035.

Basically, any major Linux distro can be used as a DNS, Web, E-mail, and FTP server, and Suse is not an exception. All in one box and one static IP address. That’s all you need! Of course, I am talking about an experimental machine. An educative aproach. If you are seriuos about the Internet, you are going to need minimun two DNS servers, an email server, a web server, an FTP server, a firewall machine may be using, a proxy server, etc.

The DNS server is very easy to install. All you need to install is the BIND package, modified the /etc/named.conf file, and create your own zones files.

If you are using any type of firewall, keep port 53 open for UDP and TCP. This is the port dedicated to DNS.

Edit /etc/named.conf and add your reference zone files. Right after the first reference zone file, in this case zone “”, add yours, in my case I added two zone references: and Pay close attention to the open and close braces, quotes, and semicolons.

zone "" in {
  type master;
  file "";

zone "" in {
  type master;
  file "";

zone "" in {
  type master;
  file "";

Zones files
Suse puts the named dir in /var/lib/named. Here is where your zones file will be located. This is the domain’s zone file:

unix:/home/ipv6 # more /var/lib/named/
; DNS record for the domain

$TTL 86400 ; max TTL


@ IN A
@ IN MX 10

Now, we need to test the zone files, so we type: rndc reload, next we run rcnamed start. You should get not erros. Next type rcnamed status, you should see the number of zones running, and the last line will say the server is up and running.

If you get an error, check braces, quotes, and semicolos in /etc/named.conf.

If you want to know more about CNAME, A, NS, etc. Read The DNS & Bind Book

Have you seen those sites that if you don’t put the www, you cannot get to it? Well, it’s all in the zone files. If you check the file, you see one reference with the www and one reference without it, these are called CNAME or alias. Bingo! By the same token, you create the same way an FTP server, so on and so forth. In the case of a Web server, you need to check your Apache conf files, and make sure that you create your virtual hosts reference as well. This is another topic. Finally, I run the last check using dig, your DNS friend, and this is what I get:

unix:/home/ipv6 # dig
; <<>> DiG 9.3.1 <<>>
;; global options: printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 55238
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 0
; IN A
;; Query time: 34 msec
;; WHEN: Thu Jan 13 03:27:51 2005
;; MSG SIZE rcvd: 64

DNS is an exciting topic, and these few lines don’t even put a dent to it. For example, you need to register your own domain name with a domain name service provider. i.e,, etc. By creating these zone files in your server, your DNS server is not going to work, I mean, it won’t resolve any domain name at all, may be locally.

How the DNS work? Here is a link that explain very well how it works: How DNS worksEach domain name must have two DNS servers. Some people named their and ns2,example,com, in my case I named mine unix is the name of the machine itself, or host name in the UNIX jargon. The first reference in the link above, is the root level. These are a series of machines, 13 total to be exact, distributed around the world. I think Japan has two, Europe has a couple more, the US has the most, etc.

What are the names of these machines? In your /var/lib/named there is a file called root.hint, this file contain the list of the these machines. Here is the file in my Linux box:

unix:/home/ipv6 # more /var/lib/named/root.hint
; This file holds the information on root name servers needed to
; initialize cache of Internet domain name servers
; (e.g. reference this file in the "cache . "
; configuration file of BIND domain name servers).
; This file is made available by InterNIC
; under anonymous FTP as
; file /domain/named.root
; on server FTP.INTERNIC.NET
; last update: Jan 29, 2004
; related version of root zone: 2004012900
; formerly NS.INTERNIC.NET
; formerly NS1.ISI.EDU
; formerly C.PSI.NET
; formerly TERP.UMD.EDU
; formerly NS.NASA.GOV
; formerly NS.ISC.ORG
; formerly NS.NIC.DDN.MIL
; formerly AOS.ARL.ARMY.MIL
; formerly NIC.NORDU.NET
; operated by VeriSign, Inc.
; operated by RIPE NCC
; operated by ICANN
; operated by WIDE
; End of File

The last machine listed in this root.hint file is locates in Paris, France. Just use to find the rest.

Keep in mind that we are “inserting” a machine to the biggest network of the world: The Internet. And this machine must be capable to let everybody know regardless where they are how to find, how to find this domain name and its contents. For a small local network, you don’t need a DNS server, you can use the first approach since the ARPANET’s days of resolving names to IP addresses: the hosts file located in /etc/hosts

Mod your Php installation to handle larger uploads

Though PHP presents a very versatile and user friendly interface for handling file uploads, the default installation is not geared for working with files in excess of 2 Mega Bytes. This article will help you configure your PHP engine for handling such large file transfers.

The php.ini File

All the configuration settings for your installation are contained in the php.ini file. Sometimes these setting might be overridden by directives in apache .htaccess files or even with in the scripts themselves. However you cannot over ride the settings that effect file uploads with .htaccess directives in this way. So let’s just concentrate on the ini file.

You can call the phpinfo() function to find the location of your php.ini file, it will also tell you the current values for the following settings that we need to modify

  • file_uploads
  • upload_max_filesize
  • max_input_time
  • memory_limit
  • max_execution_time
  • post_max_size

The first one is fairly obvious if you set this off, uploading is disabled for your installation. We will cover the rest of the configuration settings in detail below.

  • upload_max_filesize and post_max_size
  • memory_limit
  • max_execution_time and max_input_time

Files are usually POSTed to the webserver in a format known as ‘multipart/form-data’. The post_max_size sets the upper limit on the amount of data that a script can accept in this manner. Ideally this value should be larger than the value that you set for upload_max_filesize.

It’s important to realize that upload_max_filesize is the sum of the sizes of all the files that you are uploading. post_max_size is the upload_max_filesize plus the sum of the lengths of all the other fields in the form plus any mime headers that the encoder might include. Since these fields are typically small you can often approximate the upload max size to the post max size.

According to the PHP documentation you can set a MAX_UPLOAD_LIMIT in your HTML form to suggest a limit to the browser. Our understanding is that browsers totally ignore this directive and the only solution that can impose such a client side restriction is our own Rad Upload Applet

When the PHP engine is handling an incoming POST it needs to keep some of the incoming data in memory. This directive has any effect only if you have used the –enable-memory-limit option at configuration time. Setting too high a value can be very dangerous because if several uploads are being handled concurrently all available memory will be used up and other unrelated scripts that consume a lot of memory might effect the whole server as well.

These settings define the maximum life time of the script and the time that the script should spend in accepting input. If several mega bytes of data are being transfered max_input_time should be reasonably high. You can override the setting in the ini file for max_input_time by calling the set_time_limit() function in your scripts.

  • Additonal Comments
  • Apache Settings
  • Other Options

The apache webserver has a LimitRequestBody configuration directive that restricts the size of all POST data regardless of the web scripting language in use. Some RPM installations sets limit request body to 512Kb. You will need to change this to a larger value or remove the entry altogether.

If you expect to handle a large number of concurrent file transfers on your website consider using a perl or java server side component. PHP happens to be our favourite web programming language as well but perl and Java are just slightly ahead when it comes to file upload.

Most installations of perl as an apache module can accept in excess of 32 megabytes out of the box. Compare this against the 2MB default for PHP. The downside is that perl coding takes just a bit more effort than PHP but it’s worth it. You can try our sample scripts to get started.

How to configure the Apache web server to run SSL

Following is a step-by-step guide to creating a self-signed SSL certificate for apache2 on the Ubuntu Linux distribution. Procedures here are sufficiently different from my selfsign.html guide applying to other linux distributions that it warranted a separate document.

Note that this document can be used a couple different ways. If you follow all the steps you’ll have a self-signed SSL certificate and (hopefully) a working SSL site. If you’d rather generate a Certificate Authority (CA) which you can use to sign multiple certificates, then you should read this document, my general purpose selfsign.html document, and start with the section at the end of this document: Generating a CA under Ubuntu.

(1) Preliminaries and Packages.

If you have a registered DNS name, be sure that you properly set it up. On the Gnome console: System->Administration->Networking:General. Your host/domain name here should match the one you’ll be using in later steps.

Use apt-get (apt-get install apache2), Synaptic or some other tool to get and install apache2. You should also have openssl (most likely already installed).

su to the superuser and make a backup of the original apache configuration file. Call it whatever you want. My practice is to add “_original” to any default configuration file before I make changes and a “_YYYY_MMDD” timestamp to later versions I modify — whatever works for you. If this is the first time you’ve ever done this, you may want to take backups at incremental change points.

You should not make a backup of the file in the sites-enabled directory, since both the original and backup will be loaded when you restart apache (I discovered this behavior). Also note that a symlink exists from /etc/apache2/sites-enabled/000-default to /etc/apache2/sites-available/default. Instead, back it up in the sites-available directory or some other location.

 sudo su -
 cd /etc/apache2/sites-available
 cp /etc/apache2/sites-available/default default_original

(2) Run the SSL certificate generating script.

The /usr/sbin/apache2-ssl-certificate script lacks the “-days xxx” flag, and creates a certificate that only lasts a month by default. One visitor to this web page suggested that the script accepts standard arguments so you can pass additional flags to it. I’ve not verified this to be true yet, but I’m almost certain he is correct. For example, to generate a self-signed certificate that lasts one year:

/usr/sbin/apache2-ssl-certificate -days 365

An alternative is to modify the /usr/sbin/apache2-ssl-certificate script itself. If you open this script with an editor, you can see that it’s just a thin shell over native openssl commands. Make a back up this script. You’ll see a portion in it that looks like this:

 export RANDFILE=/dev/random
 openssl req $@ -config /usr/share/apache2/ssleay.cnf
 -new -x509 -nodes -out /etc/apache2/ssl/apache.pem
 -keyout /etc/apache2/ssl/apache.pem

Change it to this if want your self-signed cert. to last a full year:

 export RANDFILE=/dev/random
 openssl req $@ -config /usr/share/apache2/ssleay.cnf
 -new -x509 -days 365 -nodes -out /etc/apache2/ssl/apache.pem
 -keyout /etc/apache2/ssl/apache.pem

Then run the tweaked version, answering the questions as they come. When you’re more comfortable working with openssl, you can check out my other doc Creating a self-signed SSL certificate, run the commands natively or modify this script further to suit your tastes.


(3) Enable ssl.

a2enmod ssl

(4) Establish a necessary symlink.

The first command copies the default configuration file for port 80, to use it as a stub configuration file for 443. The second command establishes a symlink from the ‘available’ ssl file to the ‘enabled’ file. The symlinking methodology between the two directories (as well as mods-available and mods-enabled) is an arrangement briefly explained in /etc/apache2/README. The general idea is that enabled files exist as symlinks created to their available counterparts.

 cp /etc/apache2/sites-available/default /etc/apache2/sites-available/ssl
 ln -s /etc/apache2/sites-available/ssl /etc/apache2/sites-enabled/ssl

(5) Set up the document roots.

The default location for HMTL pages with an initial install of Ubuntu is /var/www and there exists no separate place for ssl files. I prefer to serve up basic HTML pages in /var/www/html and SSL pages in /var/www-ssl/html. Whatever works for you. But at this point I create the directories.

 cd /var/www
 mkdir html
 cd /var
 mkdir www-ssl
 cd www-ssl
 mkdir html

(6) Configure virtual hosts.

Here you need to tell the apache configuration file the IP of your box, DNS name (if any) and document roots you just created in the previous step.

To configure HTTP over port 80 (edit /etc/apache2/sites-available/default):

 NameVirtualHost *:80
 (Note: Look down just a bit and make a change to the virtual host settings.)
 <VirtualHost *:80>
 ServerName localhost
 DocumentRoot /var/www/html
(Note: Use your assigned IP or DNS name followed with “:80” if you have one for ServerName).

Similar procedure for HTTPS over port 443 (edit /etc/apache2/sites-available/ssl):

 NameVirtualHost *:443
 (Note: Look down just a bit and make a change to the virtual host settings.)
 <VirtualHost *:443>
 ServerName localhost
 DocumentRoot /var/www-ssl/html
(Note: Again, use your assigned IP or a DNS name followed with “:443” if you have one for ServerName.)

(7) Instruct apache2 to listen to 443.

Go to this file /etc/apache2/ports.conf and add the following to it:

Listen 443

(8) Turn on the SSL engine.

In the middle of /etc/apache2/sites-available/ssl file, after the commented area which says “# Possible values include: debug, info, notice, warn, error, crit…” add the following:

 SSLEngine On
 SSLCertificateFile /etc/apache2/ssl/apache.pem

(9) Make an /etc/hosts tweak (if need be) — and restart apache.

When starting and stopping Apache there may be a complaint such as “Could not determine the server’s fully qualified domain name, using for ServerName”. You may encounter this if you don’t have a DNS name for your server, and are just using a dynamic IP. If this applies to you, go into your /etc/hosts file and make the following changes. Basically, we’ll be adding “localhost.localdomain” to the IP and whatever system name you chose when you installed Ubuntu (assuming you’ve not changed it). The final line below should be there if you have a static IP, and corresponding DNS name registered to it. If this is the case, earlier steps that wanted ServerName should have a value which corresponds to the DNS name also indicated here. localhost localhost.localdomain {your system name} {your system name}
 {static IP if you you have one} {fully qualified DNS host name if you have one}

Restart apache.

 /etc/init.d/apache2 restart

Done — test it out.

Generating a CA under Ubuntu

Skip this section unless you want to roll your own Ubuntu Certificate Authority (CA) using the openssl commands natively. If this is the route you want to take, then you should get familiar with this document and my selfsign.html document.

The game plan in a nutshell:

Follow steps #1-4 on selfsign.html, then copy the resulting server.key and server.crt files into /etc/apache2/ssl. There may be an apache.pem file sitting there (if at some point in the past you used the “apache2-ssl-certificate” script supplied with Ubuntu to generate a certificate rather than openssl natively). You’ll note that this file may have a symlink aimed at it. Apache won’t need the apache.pem file or symlink any longer (if they exist).

You’ll then do all of the steps in this document, with the following exceptions: you’ll skip #2 (you don’t need to use the apache ssl generating script) and in step #8 you’ll not reference apache.pem (if it exists). Edit your /etc/apache2/sites-available/ssl file and remove any reference to “SSLCertificateFile etc/apache2/ssl/apache.pem”. Instead, add this:

 SSLEngine On
 SSLCertificateFile /etc/apache2/ssl/server.crt
 SSLCertificateKeyFile /etc/apache2/ssl/server.key

You’ll also need to run the /usr/sbin/a2enmod script if you haven’t already done so. Go you /usr/sbin/ and type “a2enmod ssl”. If you look at this script, it’s simply a general purpose utility to establish a symlink between a module in /etc/apache2/mods-available to /etc/apache2/mods-enabled (or give a message to the effect that a given module doesn’t exist or that it’s already symlinked for loading).

Restart apache and test it out.

Apache configuration for redirect using httpd.conf and .htaccess

File: /etc/httpd/conf/httpd.conf (older systems used apache.conf)

Default: This disables the processing of .htaccess files for the system.

 <Directory />
 AllowOverride None

or for a specified directory:

 <Directory /home/domain/public_html>
 AllowOverride None

Specify directory containing site or page to be redirected:

 <Directory /root-directory-of-web-site-to-be-redirected>
 AllowOverride All
 AllowOverride parameters: AuthConfig FileInfo Indexes Limits Options

File: .htaccess Create a file /home/domain/public_html/.htaccess in that directory of the domain to be forwarded that looks something like this:

Redirect entire domain:

 Redirect 301 /

Note: The use of the “/” at the end of the redirected domain. This is necessary so that will be redirected to


Redirect specified pages:

 Redirect 301 /old-page-1.html
 Redirect 301 /old-page-2.html

You may use the following directives:

 301: permanent
 302: temp
 303: seeother
 410: gone

For example:

 Redirect permanent /

If an incorrect directive is used in the httpd.conf or .htaccess file it will result in a server error. Check your log files: /var/log/httpd/error_log.