PPPower Server: Difference between revisions

From Alteeve Wiki
Jump to navigation Jump to search
 
(34 intermediate revisions by the same user not shown)
Line 9: Line 9:
Yum repo install.
Yum repo install.
<source lang="bash">yum -y install yum-protectbase
<source lang="bash">yum -y install yum-protectbase
rpm --import http://apt.sw.be/RPM-GPG-KEY.dag.txt # import keys
rpm -Uvh https://alteeve.ca/an-repo/el6/RPMS/noarch/alteeve-repo-0.1-3.noarch.rpm
rpm -Uvh http://pkgs.repoforge.org/rpmforge-release/rpmforge-release-0.5.2-2.el6.rf.x86_64.rpm
yum clean expire-cache
# install EPEL
yum -y update
rpm -Uvh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
</source>
</source>


Line 38: Line 37:
</source>
</source>


<source lang="bash">
=== Protecting against malicious users with Denyhosts. ===
cp /etc/yum.repos.d/epel.repo /etc/yum.repos.d/epel.repo.orig
vim /etc/yum.repos.d/epel.repo
# add protect=0 to each paragraph
diff -U 0 /etc/yum.repos.d/epel.repo.orig /etc/yum.repos.d/epel.repo
</source>
<source lang="bash">
--- /etc/yum.repos.d/epel.repo.orig 2012-05-07 01:08:58.279379860 -0400
+++ /etc/yum.repos.d/epel.repo 2012-05-07 01:09:18.144157701 -0400
@@ -8,0 +9 @@
+protect=0
@@ -17,0 +19 @@
+protect=0
@@ -26,0 +29 @@
+protect=0
</source>


=== Protecting against malicious users with Denyhosts. ===
Denyhosts is a daemon that watches for too many failed logins via ssh. It uses TCP-wrappers to deny the user access to ssh (or any service) on the server after X failed logins. It has the option to download a list of known malicious IPs and add them to /hosts.deny, making possible to block attackers before they attack the server.
Denyhosts is a daemon that watches for too many failed logins via ssh. It uses TCP-wrappers to deny the user access to ssh (or any service) on the server after X failed logins. It has the option to download a list of known malicious IPs and add them to /hosts.deny, making possible to block attackers before they attack the server.


Line 121: Line 104:


=== Additional software to install ===
=== Additional software to install ===
To view neatly-summarized daily logs, and system resource usage.
To view neatly-summarized daily logs, and system resource usage.
<source lang="bash">yum -y install logwatch htop</source>
<source lang="bash">yum -y install logwatch htop</source>
Line 126: Line 110:
Packages for web server and wiki install.
Packages for web server and wiki install.
<source lang="bash">
<source lang="bash">
yum install httpd httpd-tools postgresql-server postgresql-plperl postgresql-contrib postgresql mysql-server telnet mod_ssl mysql-server php-mysql gcc jwhois bind \
yum install httpd httpd-tools postgresql94-server postgresql94-plperl postgresql94-contrib postgresql94 mysql-server telnet mod_ssl mysql-server php-mysql gcc jwhois bind \
             acpid bind-utils syslinux screen man bzip2 zip unzip php-pgsql php yum-utils
             acpid bind-utils syslinux screen man bzip2 zip unzip php-pgsql php yum-utils policycoreutils-python rsync
chkconfig acpid on
chkconfig acpid on
</source>
</source>
Line 393: Line 377:
SSL provides for secure client to server communications.
SSL provides for secure client to server communications.


=== Creating The Signed Certificate ===
=== Per-Domain SSL Cert ===
 
This covers setting up an SSL certificate for one domain only.
 
==== Per-Domain SS - Creating The Signed Certificate ====


This section assumes you are using a 3rd party signing authority. Specifically, I use http://www.trustico.ca/ (resellers of http://RapidSSL.com and others). This is also for a domain-specific certificate. Wildcard certificates will differ.
This section assumes you are using a 3rd party signing authority. Specifically, I use http://www.trustico.ca/ (resellers of http://RapidSSL.com and others). This is also for a domain-specific certificate. Wildcard certificates will differ.
Line 400: Line 388:


<source lang="bash">
<source lang="bash">
cd /etc/pki/CA/private/
openssl genrsa -des3 -out /etc/pki/CA/private/alteeve.ca.key 2048
openssl genrsa -des3 -out /etc/pki/CA/private/alteeve.ca.key 2048
</source>
</source>
Line 490: Line 479:
</source>
</source>


=== Change ssl.conf ===
=== Wildcard SSL Certificate ===
 
These certs work for any <span class="code">*.example.com</span> domain.
 
==== Wildcard SSL - Creating The Signed Certificate ====
 
This section assumes you are using a 3rd party signing authority. Specifically, I use http://www.trustico.ca/ (resellers of http://RapidSSL.com and others). This is also for a domain-specific certificate. Wildcard certificates will differ.
 
Unlike the per-domain SSL certificate, this one will ''not'' require a pass-phrase to decrypt.


If you forget to update <span class="code">/etc/httpd/conf.d/ssl.conf</span>, you will get an error like this;
First, create 2048bit private key.


<source lang="bash">
<source lang="bash">
apachectl -t
cd /etc/pki/CA/private/
openssl genrsa -out /etc/pki/CA/private/wildcard_alteeve.ca.key 2048
</source>
</source>
<source lang="text">
<source lang="text">
[Mon Feb 25 19:50:32 2013] [warn] _default_ VirtualHost overlap on port 443, the first has precedence
Generating RSA private key, 2048 bit long modulus
Syntax OK
..<snip>..+++
..<snip>..+++
e is 65537 (0x10001)
</source>
</source>


To avoid this, edit <span class="code">/etc/httpd/conf.d/ssl.conf</span> and change <span class="code"><VirtualHost _default_:443></span> to <span class="code"><VirtualHost _default_:80></span>.
Verify it was created:


=== Creating An SSL Virtual Host ===
<syntaxhighlight lang="bash">
ls -lah /etc/pki/CA/private/wildcard_alteeve.ca.key
</syntaxhighlight>
<syntaxhighlight lang="text">
-rw-r--r-- 1 root root 1.7K Feb 26 15:40 /etc/pki/CA/private/wildcard_alteeve.ca.key
</syntaxhighlight>


Create a new virtual host container for the new SSL protected virtual host. We will leave the normal unencrypted virtual-host alone for now. Once we're done, we'll use it to capture and redirect <span class="code">http://</span> requests to their <span class="code">https://</span> equivalents. I make my virtual host directories writeable by my normal user account. Feel free to adapt this to your preferences.
Now create a [[CSR]] (Certificate signing request) which we will send to the signing authority. Do not enter anything in the <span class="code">extra</span> section below.


Setup the directories and then create a trivial <span class="code">index.html</span> file.
{{note|1=The <span class="code">Common Name</span> must be the short, fully qualified domain name with a leading <span class="code">*.</span> to make it a wildcard. In this example, I want to create a certificate domains under <span class="code">alteeve.ca</span>, so I will enter <span class="code">*.alteeve.ca</span>.}}


<source lang="bash">
<source lang="bash">
mkdir ssl_alteeve.ca/{cgi-bin,html,logs,temp} -p
openssl req -new -key /etc/pki/CA/private/wildcard_alteeve.ca.key -out wildcard_alteeve.ca.csr
chown apache:digimer ssl_alteeve.ca -R
chmod g+w ssl_alteeve.ca -R
vim /var/www/ssl_alteeve.ca/html/index.html
</source>
</source>
<source lang="apache">
<source lang="text">
<head>
You are about to be asked to enter information that will be incorporated
        <title>AN!Wiki - SSL Test Server</title>
into your certificate request.
</head>
What you are about to enter is what is called a Distinguished Name or a DN.
<body>
There are quite a few fields but you can leave some blank
        <h1>SSL Test</h1>
For some fields there will be a default value,
</body>
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CA
State or Province Name (full name) []:Ontario
Locality Name (eg, city) [Default City]:Toronto
Organization Name (eg, company) [Default Company Ltd]:Alteeve's Niche! Inc.
Organizational Unit Name (eg, section) []:IT
Common Name (eg, your name or your server's hostname) []:*.alteeve.ca
Email Address []:admin@alteeve.ca
 
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
</source>
</source>


Now setup the Apache2 config. I like to use the <span class="code">ssl_</span> prefix for encrypted domains.
Check that it was generated.
 
<syntaxhighlight lang="bash">
ls -lah /etc/pki/CA/private/wildcard_alteeve.ca.csr
</syntaxhighlight>
<syntaxhighlight lang="text">
-rw-r--r-- 1 root root 1.1K Feb 26 16:19 /etc/pki/CA/private/wildcard_alteeve.ca.csr
</syntaxhighlight>


{{note|1=This example is for a MediaWiki virtual host with short URLs configured. You will want to adapt the values to suit your needs.}}
Test that the CSR file is ok.


<source lang="bash">
<source lang="bash">
vim /etc/httpd/conf.d/ssl_alteeve.ca.conf
openssl req -noout -text -in /etc/pki/CA/private/wildcard_alteeve.ca.csr
</source>
<source lang="text">
Certificate Request:
    Data:
        Version: 0 (0x0)
        Subject: C=CA, ST=Ontario, L=Toronto, O=Alteeve's Niche! Inc., OU=IT, CN=*.alteeve.ca/emailAddress=admin@alteeve.ca
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    ...
                Exponent: 65537 (0x10001)
        Attributes:
            a0:00
    Signature Algorithm: sha1WithRSAEncryption
        ...
</source>
</source>
<source lang="apache">
<VirtualHost *:443>
        ServerAdmin digimer@alteeve.ca


        ServerName alteeve.ca
Copy the exact contents of the <span class="code">wildcard_alteeve.ca.csr</span> file and provide it to your signing authority as per their instructions. Once you complete their CSR form, they should email you a signed certificate and an intermediary certificate. At this point, the CSR file is no longer needed.


        DirectoryIndex index.php index.html
Save the signed certificate:


        # We can haz security?
<source lang="bash">
        SSLEngine on
vim /etc/pki/CA/wildcard_ssl_alteeve.ca.crt  
        SSLProtocol all
</source>
        SSLCACertificateFile /etc/pki/CA/RapidSSL_CA_bundle.pem
<source lang="text">
        SSLCertificateFile /etc/pki/CA/ssl_alteeve.ca.crt
-----BEGIN CERTIFICATE-----
        SSLCertificateKeyFile /etc/pki/CA/private/alteeve.ca.key
...
-----END CERTIFICATE-----
</source>


        DocumentRoot /var/www/ssl_alteeve.ca/html/
Save the intermediary certificate. Change the certificate name to that of your provider. If they provide you with this file, simply save it in the <span class="code">/etc/pki/CA/</span> directory.
        Alias /w /var/www/ssl_alteeve.ca/html/index.php
        <Directory /var/www/ssl_alteeve.ca/html>
                Options +Includes Indexes FollowSymLinks MultiViews
                AllowOverride All
                Order allow,deny
                allow from all
        </Directory>


        ScriptAlias /cgi-bin/ /var/www/ssl_alteeve.ca/cgi-bin/
<source lang="bash">
        <Directory "/var/www/ssl_alteeve.ca/cgi-bin">
vim /etc/pki/CA/RapidSSL_CA_bundle.pem
                AllowOverride None
</source>
                Options ExecCGI -MultiViews +SymLinksIfOwnerMatch
<source lang="text">
                Order allow,deny
-----BEGIN CERTIFICATE-----
                Allow from all
...
        </Directory>
-----END CERTIFICATE-----
 
-----BEGIN CERTIFICATE-----
        ErrorLog /var/www/ssl_alteeve.ca/logs/error.log
...
        TransferLog /var/www/ssl_alteeve.ca/logs/transfer.log
-----END CERTIFICATE-----
 
        # Possible values include: debug, info, notice, warn, error, crit,
        # alert, emerg.
        LogLevel debug
 
        CustomLog /var/www/ssl_alteeve.ca/logs/access.log combined
        ServerSignature On
</VirtualHost>
</source>
</source>


==== Bad Identity Error ====
==== Copying Wildcard to a new Server ====


If you get an error about the server not providing identity information, you may have be loading images, CSS, javascript or similar using a URL from a remote domain with no SSL or badly configured SSL.
When you are setting up a new server to use an existing wildcard cert, you simply need to copy over four files:


For example, on Firefox 4, you may see:
<syntaxhighlight lang="bash">
rsync -av root@alteeve.ca:/etc/pki/CA/wildcard_ssl_alteeve.ca.crt /etc/pki/CA/
rsync -av root@alteeve.ca:/etc/pki/CA/private/wildcard_alteeve.ca* /etc/pki/CA/private/
rsync -av root@alteeve.ca:/etc/pki/CA/RapidSSL_CA_bundle.pem /etc/pki/CA/
</syntaxhighlight>


<source lang="text">
Once copied, setup the SSL virtual host the same as always.
This web site does not supply identity information.


Your connection to this site is only partially encrypted, and does not prevent eavesdropping.
=== Change ssl.conf ===
                                                                        [ More Information ]
</source>


In my case, this turned out to be a problem where mediawiki was loading a Creative Commons logo from their server using <span class="code">http://</span> link to the icon. Once this was changed to <span class="code">https://</span> (in <span class="code">LocalSettings.php</span>), the error went away.
If you forget to update <span class="code">/etc/httpd/conf.d/ssl.conf</span>, you will get an error like this;
 
=== Testing and Using the New Configuration ===
 
Test your new Apache configuration.


<source lang="bash">
<source lang="bash">
Line 599: Line 618:
</source>
</source>
<source lang="text">
<source lang="text">
[Mon Feb 25 19:50:32 2013] [warn] _default_ VirtualHost overlap on port 443, the first has precedence
Syntax OK
Syntax OK
</source>
</source>


Now restart Apache. Note that you will be asked to enter the pass-phrase you used when you created your private key.
To avoid this, edit <span class="code">/etc/httpd/conf.d/ssl.conf</span> and change <span class="code"><VirtualHost _default_:443></span> to <span class="code"><VirtualHost _default_:80></span>.
 
=== Creating An SSL Virtual Host ===
 
Create a new virtual host container for the new SSL protected virtual host. We will leave the normal unencrypted virtual-host alone for now. Once we're done, we'll use it to capture and redirect <span class="code">http://</span> requests to their <span class="code">https://</span> equivalents. I make my virtual host directories writeable by my normal user account. Feel free to adapt this to your preferences.
 
Setup the directories and then create a trivial <span class="code">index.html</span> file.


<source lang="bash">
<source lang="bash">
/etc/init.d/httpd restart
mkdir ssl_alteeve.ca/{cgi-bin,html,logs,temp} -p
chown apache:digimer ssl_alteeve.ca -R
chmod g+w ssl_alteeve.ca -R
vim /var/www/ssl_alteeve.ca/html/index.html
</source>
</source>
<source lang="text">
<source lang="apache">
Stopping httpd:                                            [  OK  ]
Starting httpd: Apache/2.2.15 mod_ssl/2.2.15 (Pass Phrase Dialog)
Some of your private key files are encrypted for security reasons.
In order to read them you have to provide the pass phrases.
 
Server alteeve.ca:443 (RSA)
Enter pass phrase:
 
OK: Pass Phrase Dialog successful.
                                                          [  OK  ]
</source>
 
{{warning|1=From now on, you will need to enter the pass-phrase to start Apache. Consider this when restarting your server and when deciding if you want the Apache server to start with your server. As my server is in a VM and it's underlying disk is also encrypted, I will enable it at boot time. I'll need to be watching the boot process anyway. This may not apply to you.}}
 
Now make sure that you can still connect to your server on [[TCP]] port 80 (normal http port). The contents after the <span class="code">GET</span> request will obviously vary depending on your configuration:
 
<source lang="bash">
telnet localhost 80
</source>
<source lang="text">
Trying ::1...
Connected to localhost.
Escape character is '^]'.
GET
<head>
<head>
<title>Asakusa.alteeve.ca</title>
        <title>AN!Wiki - SSL Test Server</title>
</head>
</head>
<body>
<body>
Default - Requested domain not found
        <h1>SSL Test</h1>
</body>
</body>
Connection closed by foreign host.
</source>
</source>


Now to check that the SSL port is listening properly. We can't use <span class="code">[[telnet]]</span> because of the SSL encryption. Instead we will use <span class="code">openssl</span>.
Now setup the Apache2 config. I like to use the <span class="code">ssl_</span> prefix for encrypted domains.
 
{{note|1=This example is for a MediaWiki virtual host with short URLs configured. You will want to adapt the values to suit your needs.}}


<source lang="bash">
<source lang="bash">
openssl s_client -connect localhost:443 -state -debug
vim /etc/httpd/conf.d/ssl_alteeve.ca.conf
</source>
</source>
<source lang="text">
<source lang="apache">
CONNECTED(00000003)
<VirtualHost *:443>
SSL_connect:before/connect initialization
        ServerAdmin digimer@alteeve.ca
write to 0x196a050 [0x1a0b3a0] (113 bytes => 113 (0x71))
 
0000 - 16 03 01 00 6c 01 00 00-68 03 01 4d f8 f4 a4 f9  ....l...h..M....
        ServerName alteeve.ca
0010 - 07 b3 11 f8 3d ff 5d 80-ed 69 87 52 e2 60 80 57  ....=.]..i.R.`.W
 
0020 - 59 c7 83 4c ea 5b e5 37-06 e0 13 00 00 3a 00 39  Y..L.[.7.....:.9
        DirectoryIndex index.php index.html
0030 - 00 38 00 88 00 87 00 35-00 84 00 16 00 13 00 0a  .8.....5........
 
0040 - 00 33 00 32 00 9a 00 99-00 45 00 44 00 2f 00 96  .3.2.....E.D./..
        # We can haz security?
0050 - 00 41 00 05 00 04 00 15-00 12 00 09 00 14 00 11  .A..............
        SSLEngine on
0060 - 00 08 00 06 00 03 00 ff-02 01 00 00 04 00 23      ..............#
        SSLProtocol all
0071 - <SPACES/NULS>
        SSLCACertificateFile /etc/pki/CA/RapidSSL_CA_bundle.pem
SSL_connect:SSLv2/v3 write client hello A
        SSLCertificateFile /etc/pki/CA/wildcard_ssl_alteeve.ca.crt
read from 0x196a050 [0x1a10900] (7 bytes => 7 (0x7))
        SSLCertificateKeyFile /etc/pki/CA/private/wildcard_alteeve.ca.key
0000 - 16 03 01 00 35 02                                ....5.
 
0007 - <SPACES/NULS>
        DocumentRoot /var/www/ssl_alteeve.ca/html/
read from 0x196a050 [0x1a1090a] (51 bytes => 51 (0x33))
        Alias /w /var/www/ssl_alteeve.ca/html/index.php
0000 - 00 31 03 01 4d f8 f4 a4-7d 35 00 74 24 43 bc c9  .1..M...}5.t$C..
        <Directory /var/www/ssl_alteeve.ca/html>
 
                Options +Includes Indexes FollowSymLinks MultiViews
                AllowOverride All
                Order allow,deny
                allow from all
        </Directory>
 
        ScriptAlias /cgi-bin/ /var/www/ssl_alteeve.ca/cgi-bin/
        <Directory "/var/www/ssl_alteeve.ca/cgi-bin">
                AllowOverride None
                Options ExecCGI -MultiViews +SymLinksIfOwnerMatch
                Order allow,deny
                Allow from all
        </Directory>
 
        ErrorLog /var/www/ssl_alteeve.ca/logs/error.log
        TransferLog /var/www/ssl_alteeve.ca/logs/transfer.log
 
        # Possible values include: debug, info, notice, warn, error, crit,
        # alert, emerg.
        LogLevel debug
 
        CustomLog /var/www/ssl_alteeve.ca/logs/access.log combined
        ServerSignature On
</VirtualHost>
</source>
 
==== Bad Identity Error ====
 
If you get an error about the server not providing identity information, you may have be
read from 0x196a050 [0x1a10903] (5 bytes => 5 (0x5))
read from 0x196a050 [0x1a10903] (5 bytes => 5 (0x5))
0000 - 17 03 01 00 60                                   ....`
0000 - 16 03 01 00 04                                   .....
read from 0x196a050 [0x1a10908] (96 bytes => 96 (0x60))
read from 0x196a050 [0x1a10908] (4 bytes => 4 (0x4))
0000 - 46 4c 99 93 29 c9 ed 66-81 43 89 39 26 2b d1 b0   FL..)..f.C.9&+..
0000 - 0e                                                .
0010 - 19 73 eb 51 18 45 54 49-74 43 e0 92 1b f8 af f0   .s.Q.ETItC......
0004 - <SPACES/NULS>
0020 - 0d e1 08 79 96 38 e1 5e-29 9d 66 9c 30 04 8e c4  ...y.8.^).f.0...
SSL_connect:SSLv3 read server done A
0030 - 10 83 49 7e 09 d7 8a ff-4b 11 f9 13 3e ac 77 73   ..I~....K...>.ws
write to 0x196a050 [0x1a1add0] (139 bytes => 139 (0x8B))
0040 - e8 94 e3 f3 74 db 4e 5f-67 13 1d c4 3a 06 98 b3   ....t.N_g...:...
0000 - 16 03 01 00 86 10 00 00-82 00 80 7f 9d d2 3b 68  ..............;h
0050 - da 20 41 3c ca 9a fb 3f-f3 d7 64 a1 e9 f4 0a 98   . A<...?..d.....
0010 - 49 c9 dd ed 4f 35 a0 70-3a 28 0f ce c1 5a 81 ce  I...O5.p:(...Z..
<head>
0020 - cd 46 c5 e5 a4 44 25 04-4e b4 48 d8 3b a6 d4 44   .F...D%.N.H.;..D
<title>AN!Wiki - SSL Test Server</title>
0030 - 4e 9a dc 20 fa 52 9f eb-52 3b 3c 3e 34 dc ed 34  N.. .R..R;<>4..4
</head>
0040 - e5 b7 10 f9 6d 3a c0 84-64 bf b8 91 54 6c 37 1b  ....m:..d...Tl7.
<body>
0050 - eb 75 7a 95 aa e8 83 6f-e0 16 f2 af 77 0f 7a 0c   .uz....o....w.z.
<h1>SSL Test</h1>
0060 - a8 82 27 a4 a5 f2 f0 1b-d2 6e 46 c4 ef 10 7c 39   ..'......nF...|9
</body>
0070 - 6c 87 74 ec 68 7e d5 9a-10 ab 10 03 75 a2 fb 4b  l.t.h~......u..K
0080 - 8c 49 4c da 64 49 bd 27-ba 51 a4                  .IL.dI.'.Q.
SSL_connect:SSLv3 write client key exchange A
write to 0x196a050 [0x1a1add0] (6 bytes => 6 (0x6))
0000 - 14 03 01 00 01 01                                ......
SSL_connect:SSLv3 write change cipher spec A
write to 0x196a050 [0x1a1add0] (53 bytes => 53 (0x35))
0000 - 16 03 01 00 30 b4 8a 74-4d a4 bf b1 54 04 8a 25   ....0..tM...T..%
0010 - 24 f8 81 f1 64 9f 1f 6d-fb bd a7 4c 57 6a a5 63  $...d..m...LWj.c
0020 - fb 3a dd 8e e3 f9 38 f6-22 fd 7e 42 81 2e a2 41   .:....8.".~B...A
0030 - 1f 74 d1 27 02                                    .t.'.
SSL_connect:SSLv3 write finished A
SSL_connect:SSLv3 flush data
read from 0x196a050 [0x1a10903] (5 bytes => 5 (0x5))
read from 0x196a050 [0x1a10903] (5 bytes => 5 (0x5))
0000 - 15 03 01                                         ...
0000 - 16 03 01 00 ca                                    .....
0005 - <SPACES/NULS>
read from 0x196a050 [0x1a10908] (202 bytes => 202 (0xCA))
read from 0x196a050 [0x1a10908] (32 bytes => 32 (0x20))
0000 - 04 00 00 c6 00 00 00 00-00 c0 6c f3 41 26 c8 6b  ..........l.A&.k
0000 - 2e bb a7 d6 dc ce 6c 34-dc 2e 43 c7 89 02 a9 5c   ......l4..C....\
0010 - 1e 9c 2e 78 af 75 b2 46-34 f4 30 c3 bd e4 ee 2f  ...x.u.F4.0..../
0010 - 3b 3e d0 43 1c ec fa c7-89 48 fd 76 58 82 ef 45   ;>.C.....H.vX..E
0020 - f6 28 37 f6 7c 55 3b c7-08 ad 1e 48 f1 83 9f 9a  .(7.|U;....H....
SSL3 alert read:warning:close notify
0030 - d4 ef 9b 7d 5a 9c f7 5b-92 e9 2f ca c3 e5 44 c7  ...}Z..[../...D.
closed
0040 - 7a c1 ed db 98 1a 18 bd-25 30 3c 50 ad 96 23 22  z.......%0<P..#"
write to 0x196a050 [0x1a14e53] (37 bytes => 37 (0x25))
0050 - 7e a1 b7 eb 1d b5 cc 69-2a 43 63 13 4f 21 90 32  ~......i*Cc.O!.2
0000 - 15 03 01 00 20 d8 6f 46-24 e9 fa 0c c9 9f aa 2d   .... .oF$......-
0060 - 87 94 0b 6a 66 da 99 fa-45 79 cc 53 29 35 59 0d  ...jf...Ey.S)5Y.
0010 - db 69 2a d8 fb 61 66 b0-23 23 f9 a4 ac 49 b7 e6   .i*..af.##...I..
0070 - 02 93 c6 c6 af f3 52 79-b5 36 c0 a6 4d 22 9f af  ......Ry.6..M"..
0020 - 31 73 56 05 ed                                    1sV..
0080 - 4a f2 86 b4 50 68 83 b1-ab a6 a6 ac 6e 4e 18 3d   J...Ph......nN.=
SSL3 alert write:warning:close notify
0090 - 80 a7 b4 85 77 06 69 60-fa b2 22 9a 79 14 c6 3e  ....w.i`..".y..>
</source>
00a0 - 3e 68 33 4e 1e a9 40 09-47 d0 02 97 8b ba 39 db  >h3N..@.G.....9.
 
00b0 - 2f b1 1c 2e 66 49 d3 bc-99 cc 56 4f 1d f4 c6 7b  /...fI....VO...{
Perfect!
00c0 - 58 3e 28 df b1 ce 2b 45-36 ca                    X>(...+E6.
 
SSL_connect:SSLv3 read server session ticket A
=== Open Port 443 On The Firewall ===
read from 0x196a050 [0x1a10903] (5 bytes => 5 (0x5))
 
0000 - 14 03 01 00 01                                    .....
At this point, if you try to connect to the SSL virtual host remotely, you will fail because port 443 is not yet open.
read from 0x196a050 [0x1a10908] (1 bytes => 1 (0x1))
 
0000 - 01                                                .
Use your favourite program to open inbound TCP port 443. I like to directly edit the firewall's config.
read from 0x196a050 [0x1a10903] (5 bytes => 5 (0x5))
 
0000 - 16 03 01 00 30                                    ....0
<source lang="bash">
read from 0x196a050 [0x1a10908] (48 bytes => 48 (0x30))
vim /etc/sysconfig/iptables
0000 - c0 79 35 bf c6 1e 7e d4-04 cf 68 c7 9d f5 9f 42   .y5...~...h....B
</source>
0010 - 03 91 5f 72 ae 5b ec a8-aa e7 af e8 f3 39 1b cd   .._r.[.......9..
<source lang="text">
0020 - 13 05 56 f2 1b 28 c9 42-4b 67 88 48 20 c2 a5 06  ..V..(.BKg.H ...
# Firewall configuration written by system-config-firewall
SSL_connect:SSLv3 read finished A
# Manual customization of this file is not recommended.
---
*filter
Certificate chain
:INPUT ACCEPT [0:0]
0 s:/serialNumber=0TS5WzauQRJ7sc2b-hTGwK1yxSfEDphF/C=CA/O=alteeve.ca/OU=GT13908817/OU=See www.rapidssl.com/resources/cps (c)11/OU=Domain Control Validated - FreeSSL/CN=alteeve.ca
:FORWARD ACCEPT [0:0]
  i:/C=US/O=GeoTrust, Inc./CN=RapidSSL CA
:OUTPUT ACCEPT [0:0]
1 s:/C=US/O=GeoTrust, Inc./CN=RapidSSL CA
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
  i:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
-A INPUT -p icmp -j ACCEPT
2 s:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
-A INPUT -i lo -j ACCEPT
  i:/C=US/O=Equifax/OU=Equifax Secure Certificate Authority
-A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
---
-A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
Server certificate
-A INPUT -m state --state NEW -m tcp -p tcp --dport 443 -j ACCEPT
-----BEGIN CERTIFICATE-----
-A INPUT -j REJECT --reject-with icmp-host-prohibited
MIIEvjCCA6agAwIBAgIDAhUkMA0GCSqGSIb3DQEBBQUAMDwxCzAJBgNVBAYTAlVT
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
MRcwFQYDVQQKEw5HZW9UcnVzdCwgSW5jLjEUMBIGA1UEAxMLUmFwaWRTU0wgQ0Ew
COMMIT
HhcNMTEwNjE0MTIxOTAxWhcNMTEwNzE2MTU1NjE0WjCB2TEpMCcGA1UEBRMgMFRT
</source>
NVd6YXVRUko3c2MyYi1oVEd3SzF5eFNmRURwaEYxCzAJBgNVBAYTAkNBMRQwEgYD
<source lang="bash">
VQQKEwthbHRlZXZlLmNvbTETMBEGA1UECxMKR1QxMzkwODgxNzExMC8GA1UECxMo
/etc/init.d/iptables restart
U2VlIHd3dy5yYXBpZHNzbC5jb20vcmVzb3VyY2VzL2NwcyAoYykxMTErMCkGA1UE
</source>
CxMiRG9tYWluIENvbnRyb2wgVmFsaWRhdGVkIC0gRnJlZVNTTDEUMBIGA1UEAxML
<source lang="text">
YWx0ZWV2ZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDHtXUD
iptables: Flushing firewall rules:                         [  OK  ]
x6m1IbJ6m3CN8kRd4Bj0BVLGk9MXpTrHRgNo0QFTG+i400xWRrLKYzSILE97I0kH
iptables: Setting chains to policy ACCEPT: filter          [  OK  ]
7443XIqs14ib7aEBkLwy2EYwbYIzWeq1OCyKFuFj57o52Cr6imslRQvJTbjSvqk6
iptables: Unloading modules:                               [  OK  ]
4/9hYPmkmU4/wiULIQfGGx5jcS49MUKYAfSIuIAmt79bALFXhrTYcObs6pjhF0Wn
iptables: Applying firewall rules:                         [  OK  ]
/4Pgdm+KULsdy8WP9AGETlnDTShzcDnI2oVDuQeuVyYEJLLW1HwDr09yAI8g7SZ3
</source>
s79OAWKLYhsQFmWS9bta3INc8lbzYDQs72L07s8mbZtKXnQFdPsjhgdvz7BIbbot
 
iV0P4MABHJGvAF/zAgMBAAGjggEpMIIBJTAfBgNVHSMEGDAWgBRraT1qGEJK3Y8C
=== Browse to the New Virtual Host ===
ZTn9NSSGeJEWMDAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEG
 
CCsGAQUFBwMCMBYGA1UdEQQPMA2CC2FsdGVldmUuY29tMEMGA1UdHwQ8MDowOKA2
You should now be able to access the new SSL virtual host! Simply browse to <span class="code">https://alteeve.ca</span> (replace with your domain).
oDSGMmh0dHA6Ly9yYXBpZHNzbC1jcmwuZ2VvdHJ1c3QuY29tL2NybHMvcmFwaWRz
 
c2wuY3JsMB0GA1UdDgQWBBShK06vVQh7NL50/FdB3ryP2UodyTAMBgNVHRMBAf8E
[[Image:SSL_Test_Page_01.png|thumb|center|741px|Test SSL virtual host in Firefox 4.]]
AjAAMEkGCCsGAQUFBwEBBD0wOzA5BggrBgEFBQcwAoYtaHR0cDovL3JhcGlkc3Ns
 
LWFpYS5nZW90cnVzdC5jb20vcmFwaWRzc2wuY3J0MA0GCSqGSIb3DQEBBQUAA4IB
Note the '<span class="code">alteeve.ca</span>' to the left of the address bar showing that the site is encrypted and verified!
AQBmi2+o1dKEx4kx+6W64RFeL2dv3w08CxpLrNk47ikKTdkGmCwlClm7OQOwzTsG
 
kz5ZkM8GF3R3u82RNNBvuY9TV+0UML3pbASEtvAWnSmbsUf4hGRfAzbq4dYTl1tQ
== Common apachectl -t Configuration Problems ==
ubJZzPjvIwGZkW5e6NB3VDhJGFjnDlQ1wDe1nnmy1MbZ/ycx1L8ErtMKkEu8NLxT
 
+LznTCK3s7yM10FE/OBQLpqsulzuiAP8DlMyqt2kJO6mfD3cnXqCC5+4keChEnej
=== httpd: apr_sockaddr_info_get() failed for <domain> ===
lffQxJ7x19mZaIDor61o9RpfZgZ4yVb4NjcW+n0n3x2i2HyMW1Dbxv4G/5aG9R/k
 
Nc7PQ2ZT2qFQtcBz7B70yCAT
Make sure that the hostname for the server resolves to an IP address. This is done by ensuring that the name returned by <span class="code">hostname</span> has a [[DNS]] entry or has an entry in the <span class="code">/etc/hosts</span> file.
-----END CERTIFICATE-----
 
subject=/serialNumber=0TS5WzauQRJ7sc2b-hTGwK1yxSfEDphF/C=CA/O=alteeve.ca/OU=GT13908817/OU=See www.rapidssl.com/resources/cps (c)11/OU=Domain Control Validated - FreeSSL/CN=alteeve.ca
=== [warn] NameVirtualHost *:80 has no VirtualHosts ===
issuer=/C=US/O=GeoTrust, Inc./CN=RapidSSL CA
 
---
This will be shown when no virtual host containers have been configured ye.
No client certificate CA names sent
 
---
= PostgreSQL =
SSL handshake has read 3984 bytes and written 311 bytes
 
---
We need to initialize the postgres core databases before we can start it for the first time.
New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA
 
Server public key is 2048 bit
<source lang="bash">
Secure Renegotiation IS supported
/etc/init.d/postgresql initdb
Compression: zlib compression
</source>
Expansion: zlib compression
<source lang="text">
SSL-Session:
Initializing database:                                    [  OK  ]
    Protocol  : TLSv1
</source>
    Cipher    : DHE-RSA-AES256-SHA
    Session-ID: 2880725EB8BDD73F469C17BCA54DF373DFE8EDE3D52A1C8F5E0A5919694FB111
    Session-ID-ctx:  
    Master-Key: F329DEA0DF39FF181ACFBCA69BEC417D7CAA4399D73229A1D912CC8236A858FD099B834F5B32C9BF979C4B5948196FC9
    Key-Arg  : None
    Krb5 Principal: None
    PSK identity: None
    PSK identity hint: None
    TLS session ticket:
    0000 - 6c f3 41 26 c8 6b 1e 9c-2e 78 af 75 b2 46 34 f4  l.A&.k...x.u.F4.
    0010 - 30 c3 bd e4 ee 2f f6 28-37 f6 7c 55 3b c7 08 ad  0..../.(7.|U;...
    0020 - 1e 48 f1 83 9f 9a d4 ef-9b 7d 5a 9c f7 5b 92 e9  .H.......}Z..[..
    0030 - 2f ca c3 e5 44 c7 7a c1-ed db 98 1a 18 bd 25 30  /...D.z.......%0
    0040 - 3c 50 ad 96 23 22 7e a1-b7 eb 1d b5 cc 69 2a 43  <P..#"~......i*C
    0050 - 63 13 4f 21 90 32 87 94-0b 6a 66 da 99 fa 45 79  c.O!.2...jf...Ey
    0060 - cc 53 29 35 59 0d 02 93-c6 c6 af f3 52 79 b5 36  .S)5Y.......Ry.6
    0070 - c0 a6 4d 22 9f af 4a f2-86 b4 50 68 83 b1 ab a6  ..M"..J...Ph....
    0080 - a6 ac 6e 4e 18 3d 80 a7-b4 85 77 06 69 60 fa b2  ..nN.=....w.i`..
    0090 - 22 9a 79 14 c6 3e 3e 68-33 4e 1e a9 40 09 47 d0  ".y..>>h3N..@.G.
    00a0 - 02 97 8b ba 39 db 2f b1-1c 2e 66 49 d3 bc 99 cc  ....9./...fI....
    00b0 - 56 4f 1d f4 c6 7b 58 3e-28 df b1 ce 2b 45 36 ca  VO...{X>(...+E6.


From now on, we can start PostgreSQL normally.
    Compression: 1 (zlib compression)
 
    Start Time: 1308161188
<source lang="bash">
    Timeout  : 300 (sec)
/etc/init.d/postgresql restart
    Verify return code: 0 (ok)
</source>
---
<source lang="text">
GET
Stopping postgresql service:                              [ OK  ]
write to 0x196a050 [0x1a14e56] (74 bytes => 74 (0x4A))
Starting postgresql service:                              [  OK  ]
0000 - 17 03 01 00 20 8a 4c 57-8c b9 d5 d4 c6 1b 56 ce  .... .LW......V.
</source>
0010 - 93 b5 78 6b 5f 0e c5 a2-39 2a f9 7a 20 7d 68 85  ..xk_...9*.z }h.
 
0020 - af 52 e3 5f fc 17 03 01-00 20 c6 c4 19 74 61 64  .R._..... ...tad
Create the admin user called <span class="code">alteeve</span> which will own the databases we will create and use.
0030 - 42 59 e0 52 3f 42 44 53-8b c9 40 69 1c 3d 9b 7f  BY.R?BDS..@i.=..
 
0040 - aa e8 8f a4 5c de c9 d4-0a a4                    ....\.....
<source lang="bash">
read from 0x196a050 [0x1a10903] (5 bytes => 5 (0x5))
su - postgres
0000 - 17 03 01 00 60                                    ....`
createuser -S -d -R alteeve
read from 0x196a050 [0x1a10908] (96 bytes => 96 (0x60))
psql template1
0000 - 46 4c 99 93 29 c9 ed 66-81 43 89 39 26 2b d1 b0  FL..)..f.C.9&+..
0010 - 19 73 eb 51 18 45 54 49-74 43 e0 92 1b f8 af f0  .s.Q.ETItC......
0020 - 0d e1 08 79 96 38 e1 5e-29 9d 66 9c 30 04 8e c4  ...y.8.^).f.0...
0030 - 10 83 49 7e 09 d7 8a ff-4b 11 f9 13 3e ac 77 73  ..I~....K...>.ws
0040 - e8 94 e3 f3 74 db 4e 5f-67 13 1d c4 3a 06 98 b3  ....t.N_g...:...
0050 - da 20 41 3c ca 9a fb 3f-f3 d7 64 a1 e9 f4 0a 98  . A<...?..d.....
<head>
<title>AN!Wiki - SSL Test Server</title>
</head>
<body>
<h1>SSL Test</h1>
</body>
read from 0x196a050 [0x1a10903] (5 bytes => 5 (0x5))
0000 - 15 03 01                                          ...
0005 - <SPACES/NULS>
read from 0x196a050 [0x1a10908] (32 bytes => 32 (0x20))
0000 - 2e bb a7 d6 dc ce 6c 34-dc 2e 43 c7 89 02 a9 5c  ......l4..C....\
0010 - 3b 3e d0 43 1c ec fa c7-89 48 fd 76 58 82 ef 45  ;>.C.....H.vX..E
SSL3 alert read:warning:close notify
closed
write to 0x196a050 [0x1a14e53] (37 bytes => 37 (0x25))
0000 - 15 03 01 00 20 d8 6f 46-24 e9 fa 0c c9 9f aa 2d  .... .oF$......-
0010 - db 69 2a d8 fb 61 66 b0-23 23 f9 a4 ac 49 b7 e6  .i*..af.##...I..
0020 - 31 73 56 05 ed                                    1sV..
SSL3 alert write:warning:close notify
</source>
</source>


At the shell, run the following:
Perfect!


<source lang="sql">
=== Open Port 443 On The Firewall ===
ALTER USER alteeve WITH PASSWORD 'secret';
</source>
<source lang="text">
ALTER ROLE
</source>
<source lang="sql">
\q
</source>


Tell PostgreSQL to require a password for all local and incoming connections. Also enable access to the database from the local network.
At this point, if you try to connect to the SSL virtual host remotely, you will fail because port 443 is not yet open.


<source lang="bash">
Use your favourite program to open inbound TCP port 443. I like to directly edit the firewall's config.
vim /var/lib/pgsql/data/pg_hba.conf
</source>
<source lang="diff">
# TYPE  DATABASE    USER        CIDR-ADDRESS          METHOD
host    all        all        10.222.0.0/16        md5
 
# "local" is for Unix domain socket connections only
local  all        all                              md5
# IPv4 local connections:
host    all        all        127.0.0.1/32          md5
# IPv6 local connections:
host    all        all        ::1/128              md5
</source>
 
Reload PostgreSQL's configuration.


<source lang="bash">
<source lang="bash">
/etc/init.d/postgresql reload
vim /etc/sysconfig/iptables
</source>
 
Now create a Database that is owned by the <span class="code">alteeve</span> user, then connect to it to make sure we're asked for a password.
 
<source lang="bash">
su postgres -c "createdb an_wiki -O alteeve"
psql an_wiki -U alteeve
</source>
</source>
<source lang="text">
<source lang="text">
Password for user alteeve:  
# Firewall configuration written by system-config-firewall
psql (8.4.13)
# Manual customization of this file is not recommended.
Type "help" for help.
*filter
 
:INPUT ACCEPT [0:0]
an_wiki=>
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 443 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT
</source>
</source>
Now load a database from a backup file.
<source lang="bash">
<source lang="bash">
psql an_wiki -U alteeve -f /var/www/ssl_alteeve.ca/temp/an_wiki_3.out
/etc/init.d/iptables restart
</source>
</source>
<source lang="text">
<source lang="text">
Password for user alteeve:  
iptables: Flushing firewall rules:                         [  OK  ]
SET
iptables: Setting chains to policy ACCEPT: filter          [  OK  ]
SET
iptables: Unloading modules:                              [  OK  ]
SET
iptables: Applying firewall rules:                        [  OK  ]
SET
</source>
SET
 
CREATE SCHEMA
=== Browse to the New Virtual Host ===
ALTER SCHEMA
 
CREATE LANGUAGE
You should now be able to access the new SSL virtual host! Simply browse to <span class="code">https://alteeve.ca</span> (replace with your domain).
psql:/var/www/ssl_alteeve.ca/temp/an_wiki_3.out:27: ERROR:  must be member of role "postgres"
 
SET
[[Image:SSL_Test_Page_01.png|thumb|center|741px|Test SSL virtual host in Firefox 4.]]
CREATE FUNCTION
ALTER FUNCTION
CREATE FUNCTION
ALTER FUNCTION
CREATE FUNCTION
ALTER FUNCTION
CREATE FUNCTION
ALTER FUNCTION
SET
SET
CREATE TABLE
ALTER TABLE
CREATE SEQUENCE
ALTER TABLE
setval
--------
      1
(1 row)


CREATE TABLE
Note the '<span class="code">alteeve.ca</span>' to the left of the address bar showing that the site is encrypted and verified!
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE SEQUENCE
ALTER TABLE
setval
--------
      8
(1 row)


CREATE TABLE
== Common apachectl -t Configuration Problems ==
ALTER TABLE
 
CREATE TABLE
=== httpd: apr_sockaddr_info_get() failed for <domain> ===
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE SEQUENCE
ALTER TABLE
setval
--------
  2500
(1 row)


CREATE TABLE
Make sure that the hostname for the server resolves to an IP address. This is done by ensuring that the name returned by <span class="code">hostname</span> has a [[DNS]] entry or has an entry in the <span class="code">/etc/hosts</span> file.
ALTER TABLE
CREATE SEQUENCE
ALTER TABLE
setval
--------
  4416
(1 row)


CREATE TABLE
=== [warn] NameVirtualHost *:80 has no VirtualHosts ===
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE SEQUENCE
ALTER TABLE
setval
--------
  3465
(1 row)


CREATE TABLE
This will be shown when no virtual host containers have been configured ye.
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE SEQUENCE
ALTER TABLE
setval
--------
    34
(1 row)


CREATE TABLE
= PostgreSQL =
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE SEQUENCE
ALTER TABLE
setval
--------
    957
(1 row)


CREATE TABLE
We need to initialize the postgres core databases before we can start it for the first time.
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE SEQUENCE
ALTER TABLE
setval
--------
      1
(1 row)


CREATE TABLE
<source lang="bash">
ALTER TABLE
/etc/init.d/postgresql-9.4 initdb
CREATE SEQUENCE
</source>
ALTER TABLE
<source lang="text">
  setval
Initializing database:                                    [ OK  ]
--------
</source>
  3274
 
(1 row)
From now on, we can start PostgreSQL normally.


CREATE TABLE
<source lang="bash">
ALTER TABLE
/etc/init.d/postgresql-9.4 restart
CREATE TABLE
</source>
ALTER TABLE
<source lang="text">
CREATE TABLE
Stopping postgresql-9.4 service:                          [  OK ]
ALTER TABLE
Starting postgresql-9.4 service:                          [  OK  ]
CREATE TABLE
</source>
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE SEQUENCE
ALTER TABLE
  setval
--------
  3547
(1 row)


CREATE TABLE
Create the admin user called <span class="code">alteeve</span> which will own the databases we will create and use.
ALTER TABLE
 
CREATE TABLE
<source lang="bash">
ALTER TABLE
su - postgres
CREATE SEQUENCE
createuser -S -d -R alteeve
ALTER TABLE
psql template1
setval
</source>
--------
 
  3513
At the shell, run the following:
(1 row)


CREATE TABLE
{{note|1=If your password has a single-quote in it, escape it with <span class="code">''</span> (ie: <span class="code">ALTER USER alteeve WITH PASSWORD 'someone''s secret password';</span>).}}
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE SEQUENCE
ALTER TABLE
setval
--------
      1
(1 row)


CREATE TABLE
<source lang="sql">
ALTER TABLE
ALTER USER alteeve WITH PASSWORD 'secret';
CREATE TABLE
</source>
ALTER TABLE
<source lang="text">
CREATE TABLE
ALTER ROLE
ALTER TABLE
</source>
CREATE TABLE
<source lang="sql">
ALTER TABLE
\q
CREATE TABLE
</source>
ALTER TABLE
 
CREATE TABLE
Tell PostgreSQL to require a password for all local and incoming connections. Also enable access to the database from the local network.
ALTER TABLE
 
CREATE TABLE
<source lang="bash">
ALTER TABLE
vim /var/lib/pgsql/9.4/data/pg_hba.conf
CREATE TABLE
</source>
ALTER TABLE
<source lang="diff">
ALTER TABLE
# TYPE  DATABASE    USER        CIDR-ADDRESS          METHOD
ALTER TABLE
host    all        all        10.222.0.0/16        md5
ALTER TABLE
 
ALTER TABLE
# "local" is for Unix domain socket connections only
ALTER TABLE
local  all        all                              md5
ALTER TABLE
# IPv4 local connections:
ALTER TABLE
host    all        all        127.0.0.1/32          md5
ALTER TABLE
# IPv6 local connections:
ALTER TABLE
host    all        all        ::1/128              md5
ALTER TABLE
</source>
ALTER TABLE
 
ALTER TABLE
Reload PostgreSQL's configuration.
ALTER TABLE
 
ALTER TABLE
<source lang="bash">
ALTER TABLE
/etc/init.d/postgresql-9.4 reload
ALTER TABLE
</source>
ALTER TABLE
 
ALTER TABLE
Now create a Database that is owned by the <span class="code">alteeve</span> user, then connect to it to make sure we're asked for a password.
ALTER TABLE
 
ALTER TABLE
<source lang="bash">
ALTER TABLE
su postgres -c "createdb an_wiki -O alteeve"
ALTER TABLE
psql an_wiki -U alteeve
ALTER TABLE
</source>
ALTER TABLE
<source lang="text">
ALTER TABLE
Password for user alteeve:
CREATE INDEX
psql (9.4.1)
CREATE INDEX
Type "help" for help.
CREATE INDEX
 
CREATE INDEX
an_wiki=>
CREATE INDEX
</source>
CREATE INDEX
 
CREATE INDEX
Now load a database from a backup file.
CREATE INDEX
 
CREATE INDEX
<source lang="bash">
CREATE INDEX
psql an_wiki -U alteeve -f /var/www/ssl_alteeve.ca/temp/an_wiki_3.out
CREATE INDEX
</source>
CREATE INDEX
<source lang="text">
CREATE INDEX
Password for user alteeve:
CREATE INDEX
</source>
CREATE INDEX
<source lang="text">
CREATE INDEX
SET
CREATE INDEX
SET
CREATE INDEX
SET
CREATE INDEX
SET
CREATE INDEX
SET
CREATE INDEX
SET
CREATE INDEX
CREATE SCHEMA
CREATE INDEX
ALTER SCHEMA
CREATE INDEX
psql:/root/an_wiki_2.out:25: ERROR:  language "plpgsql" already exists
CREATE INDEX
ALTER LANGUAGE
CREATE INDEX
SET
CREATE INDEX
CREATE TYPE
CREATE INDEX
ALTER TYPE
CREATE INDEX
CREATE FUNCTION
CREATE INDEX
ALTER FUNCTION
CREATE INDEX
CREATE FUNCTION
CREATE INDEX
ALTER FUNCTION
CREATE INDEX
CREATE FUNCTION
CREATE INDEX
ALTER FUNCTION
CREATE INDEX
CREATE FUNCTION
CREATE INDEX
ALTER FUNCTION
CREATE INDEX
SET
CREATE INDEX
SET
CREATE INDEX
CREATE TABLE
CREATE INDEX
ALTER TABLE
CREATE INDEX
CREATE SEQUENCE
CREATE INDEX
ALTER TABLE
CREATE INDEX
setval
CREATE INDEX
--------
CREATE INDEX
    39
CREATE INDEX
(1 row)
CREATE INDEX
 
CREATE INDEX
CREATE TABLE
CREATE INDEX
ALTER TABLE
CREATE INDEX
CREATE TABLE
CREATE INDEX
ALTER TABLE
CREATE INDEX
CREATE TABLE
CREATE INDEX
ALTER TABLE
CREATE INDEX
CREATE TABLE
CREATE INDEX
ALTER TABLE
CREATE INDEX
CREATE TABLE
CREATE INDEX
ALTER TABLE
CREATE INDEX
CREATE SEQUENCE
CREATE INDEX
ALTER TABLE
CREATE INDEX
setval
CREATE INDEX
--------
CREATE INDEX
    28
CREATE INDEX
(1 row)
CREATE INDEX
 
CREATE INDEX
CREATE TABLE
CREATE INDEX
ALTER TABLE
CREATE INDEX
CREATE TABLE
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE TRIGGER
CREATE TRIGGER
CREATE TRIGGER
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
ALTER TABLE
CREATE SEQUENCE
ALTER TABLE
ALTER TABLE
setval
--------
  2507
(1 row)
CREATE TABLE
ALTER TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
ALTER TABLE
CREATE SEQUENCE
ALTER TABLE
ALTER TABLE
setval
--------
  14274
(1 row)
CREATE TABLE
ALTER TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
ALTER TABLE
CREATE SEQUENCE
ALTER TABLE
ALTER TABLE
setval
--------
  6586
(1 row)
CREATE TABLE
ALTER TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
ALTER TABLE
CREATE SEQUENCE
ALTER TABLE
ALTER TABLE
setval
--------
    50
(1 row)
CREATE TABLE
ALTER TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
ALTER TABLE
CREATE SEQUENCE
ALTER TABLE
ALTER TABLE
setval
--------
  1563
(1 row)
CREATE TABLE
ALTER TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
ALTER TABLE
CREATE SEQUENCE
ALTER TABLE
ALTER TABLE
REVOKE
setval
REVOKE
--------
GRANT
      1
GRANT
(1 row)
</source>


Voila!
CREATE TABLE
ALTER TABLE
CREATE SEQUENCE
ALTER TABLE
setval
--------
  6335
(1 row)


== Media Wiki Problem ==
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE SEQUENCE
ALTER TABLE
setval
--------
  6741
(1 row)


If you moved a MediaWiki DB and it generated an error like this in the log file:
CREATE TABLE
 
ALTER TABLE
<source lang="text">
CREATE TABLE
[Wed Jun 15 21:37:20 2011] [error] [client 206.108.5.162] PHP Warning: pg_query(): Query failed: ERROR:  relation "objectcache" does not exist\nLINE 1: ...ECT /* SqlBagOStuff::get  */  value,exptime  FROM objectcach...\n
ALTER TABLE
                                                            ^ in /var/www/ssl_alteeve.ca/html/includes/db/DatabasePostgres.php on line 584
CREATE SEQUENCE
[Wed Jun 15 21:37:20 2011] [error] [client 206.108.5.162] PHP Warning:  pg_query(): Query failed: ERROR:  relation "l10n_cache" does not exist\nLINE 1: ... LCStore_DB::get 206.108.5.162 */  lc_value  FROM l10n_cache...\n
ALTER TABLE
                                                            ^ in /var/www/ssl_alteeve.ca/html/includes/db/DatabasePostgres.php on line 584
  setval
</source>
--------
  6663
(1 row)


The fix is to run:
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE SEQUENCE
ALTER TABLE
setval
--------
      1
(1 row)


<source lang="sql">
CREATE TABLE
ALTER DATABASE an_wiki SET search_path=mediawiki;
ALTER TABLE
</source>
CREATE TABLE
 
ALTER TABLE
Of course, replace <span class="code">an_wiki</span> with the name of your wiki database.
CREATE TABLE
ALTER TABLE
CREATE SEQUENCE
ALTER TABLE
setval
--------
    20
(1 row)


= MySQL =
CREATE TABLE
 
ALTER TABLE
Start MySQL for the first time:
CREATE TABLE
 
ALTER TABLE
<source lang="bash">
CREATE TABLE
/etc/init.d/mysqld start
ALTER TABLE
</source>
CREATE TABLE
<source lang="text">
ALTER TABLE
Initializing MySQL database:  Installing MySQL system tables...
CREATE TABLE
OK
ALTER TABLE
Filling help tables...
CREATE TABLE
OK
ALTER TABLE
 
CREATE TABLE
To start mysqld at boot time you have to copy
ALTER TABLE
support-files/mysql.server to the right place for your system
COPY 137
 
COPY 2
PLEASE REMEMBER TO SET A PASSWORD FOR THE MySQL root USER !
COPY 9
To do so, start the server, then issue the following commands:
COPY 0
 
COPY 0
/usr/bin/mysqladmin -u root password 'new-password'
COPY 2372
/usr/bin/mysqladmin -u root -h asakusa.alteeve.ca password 'new-password'
COPY 28
 
COPY 0
Alternatively you can run:
COPY 742
/usr/bin/mysql_secure_installation
COPY 872
 
COPY 92
which will also give you the option of removing the test
COPY 21
databases and anonymous user created by default.  This is
COPY 0
strongly recommended for production servers.
COPY 0
 
COPY 6626
See the manual for more instructions.
COPY 0
 
COPY 2
You can start the MySQL daemon with:
COPY 6586
cd /usr ; /usr/bin/mysqld_safe &
COPY 0
 
COPY 2
You can test the MySQL daemon with mysql-test-run.pl
COPY 16
cd /usr/mysql-test ; perl mysql-test-run.pl
COPY 44
 
COPY 28
Please report any problems with the /usr/bin/mysqlbug script!
COPY 51
 
COPY 104959
                                                          [  OK  ]
COPY 254
Starting mysqld:                                          [  OK  ]
COPY 1497
</source>
COPY 0
 
COPY 0
Secure the server.
COPY 6335
 
COPY 3901
<source lang="bash">
COPY 0
mysql_secure_installation
COPY 0
</source>
COPY 0
<source lang="text">
COPY 0
NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MySQL
COPY 0
      SERVERS IN PRODUCTION USE!  PLEASE READ EACH STEP CAREFULLY!
COPY 385
 
COPY 124
 
COPY 6525
In order to log into MySQL to secure it, we'll need the current
COPY 1
password for the root user.  If you've just installed MySQL, and
COPY 0
you haven't set the root password yet, the password will be blank,
COPY 1276
so you should just press enter here.
COPY 0
 
COPY 0
Enter current password for root (enter for none):
COPY 1
OK, successfully used password, moving on...
COPY 7
 
COPY 0
Setting the root password ensures that nobody can log into the MySQL
COPY 2
root user without the proper authorisation.
COPY 0
 
COPY 29
Set root password? [Y/n] y
COPY 0
New password:
COPY 12
Re-enter new password:
ALTER TABLE
Password updated successfully!
ALTER TABLE
Reloading privilege tables..
ALTER TABLE
... Success!
ALTER TABLE
 
ALTER TABLE
 
ALTER TABLE
By default, a MySQL installation has an anonymous user, allowing anyone
ALTER TABLE
to log into MySQL without having to have a user account created for
ALTER TABLE
them.  This is intended only for testing, and to make the installation
ALTER TABLE
go a bit smoother.  You should remove them before moving into a
ALTER TABLE
production environment.
ALTER TABLE
 
ALTER TABLE
Remove anonymous users? [Y/n] y
ALTER TABLE
... Success!
ALTER TABLE
 
ALTER TABLE
Normally, root should only be allowed to connect from 'localhost'.  This
ALTER TABLE
ensures that someone cannot guess at the root password from the network.
ALTER TABLE
 
ALTER TABLE
Disallow root login remotely? [Y/n] 
ALTER TABLE
... Success!
ALTER TABLE
 
ALTER TABLE
By default, MySQL comes with a database named 'test' that anyone can
ALTER TABLE
access.  This is also intended only for testing, and should be removed
ALTER TABLE
before moving into a production environment.
ALTER TABLE
 
ALTER TABLE
Remove test database and access to it? [Y/n]
ALTER TABLE
- Dropping test database...
ALTER TABLE
... Success!
CREATE INDEX
- Removing privileges on test database...
CREATE INDEX
... Success!
CREATE INDEX
 
CREATE INDEX
Reloading the privilege tables will ensure that all changes made so far
CREATE INDEX
will take effect immediately.
CREATE INDEX
 
CREATE INDEX
Reload privilege tables now? [Y/n]
CREATE INDEX
... Success!
CREATE INDEX
 
CREATE INDEX
Cleaning up...
CREATE INDEX
 
CREATE INDEX
 
CREATE INDEX
 
CREATE INDEX
All done!  If you've completed all of the above steps, your MySQL
CREATE INDEX
installation should now be secure.
CREATE INDEX
 
CREATE INDEX
Thanks for using MySQL!
CREATE INDEX
</source>
CREATE INDEX
 
CREATE INDEX
= BIND =
CREATE INDEX
 
CREATE INDEX
{{note|1=This is not meant to cover creating the actual zone files for DNS. It's goal is to setup BIND on your [[EL6]] server only.}}
CREATE INDEX
 
CREATE INDEX
This is the BIND named server that handles DNS resolution. It will be setup in two parts; The global options and then the zones file.
CREATE INDEX
 
CREATE INDEX
== Install bind ==
CREATE INDEX
 
CREATE INDEX
<source lang="bash">
CREATE INDEX
yum install bind bind-libs bind-utils
CREATE INDEX
</source>
CREATE INDEX
 
CREATE INDEX
== Global Configuration ==
CREATE INDEX
 
CREATE INDEX
Edit the main configuration file, making a backup first.
CREATE INDEX
 
CREATE INDEX
<source lang="bash">
CREATE INDEX
cp /etc/named.conf /etc/named.conf.orig
CREATE INDEX
vim /etc/named.conf
CREATE INDEX
</source>
CREATE INDEX
 
CREATE INDEX
Enable queries on any interface and answer queries for any domain, not just ours. Edit or add the following;
CREATE INDEX
 
CREATE INDEX
<source lang="dot">
CREATE INDEX
        listen-on port 53      { any; };
CREATE INDEX
        allow-query            { any; };
CREATE INDEX
        allow-query-cache      { any; };
CREATE INDEX
</source>
CREATE INDEX
 
CREATE INDEX
For now, we're going to disable DNSSEC. Make the following changes;
CREATE INDEX
 
CREATE INDEX
<source lang="dot">
CREATE INDEX
        dnssec-enable          no;
CREATE INDEX
        dnssec-validation      no;
CREATE INDEX
</source>
CREATE INDEX
 
CREATE INDEX
Now tell bind where to look for a domain name's IP when we don't know. Add;
CREATE INDEX
 
CREATE INDEX
<source lang="dot">
CREATE INDEX
        forwarders {
CREATE INDEX
                // These are Google's open DNS servers
CREATE INDEX
                8.8.8.8;
CREATE INDEX
                8.8.4.4;
CREATE INDEX
        };
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE TRIGGER
CREATE TRIGGER
CREATE TRIGGER
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
psql:/root/an_wiki_2.out:145782: WARNING:  no privileges could be revoked for "public"
REVOKE
psql:/root/an_wiki_2.out:145783: WARNING:  no privileges could be revoked for "public"
REVOKE
psql:/root/an_wiki_2.out:145784: WARNING:  no privileges were granted for "public"
GRANT
psql:/root/an_wiki_2.out:145785: WARNING:  no privileges were granted for "public"
GRANT
</source>
</source>


This server will have a slave, and we want to notify that slave when a record changes. Add;
Voila!


<source lang="dot">
== Media Wiki Problem ==
        notify                  yes;
</source>


Done. I like to clean up the file to put the variables in line with one another. With this in mind, let's look at the changes as a unified <span class="code">diff</span>;
If you moved a MediaWiki DB and it generated an error like this in the log file:
 
<source lang="text">
[Wed Jun 15 21:37:20 2011] [error] [client 206.108.5.162] PHP Warning:  pg_query(): Query failed: ERROR:  relation "objectcache" does not exist\nLINE 1: ...ECT /* SqlBagOStuff::get  */  value,exptime  FROM objectcach...\n
                                                            ^ in /var/www/ssl_alteeve.ca/html/includes/db/DatabasePostgres.php on line 584
[Wed Jun 15 21:37:20 2011] [error] [client 206.108.5.162] PHP Warning:  pg_query(): Query failed: ERROR:  relation "l10n_cache" does not exist\nLINE 1: ... LCStore_DB::get 206.108.5.162 */  lc_value  FROM l10n_cache...\n
                                                            ^ in /var/www/ssl_alteeve.ca/html/includes/db/DatabasePostgres.php on line 584
</source>
 
The fix is to run:
 
<source lang="sql">
ALTER DATABASE an_wiki SET search_path=mediawiki;
</source>
 
Of course, replace <span class="code">an_wiki</span> with the name of your wiki database.
 
= MySQL =
 
Start MySQL for the first time:


<source lang="bash">
<source lang="bash">
diff -u /etc/named.conf.orig /etc/named.conf
/etc/init.d/mysqld start
</source>
<source lang="diff">
--- /etc/named.conf.orig 2012-02-05 00:54:48.434068501 -0500
+++ /etc/named.conf 2012-02-05 13:45:16.484083319 -0500
@@ -8,18 +8,26 @@
//
options {
- listen-on port 53 { 127.0.0.1; };
- listen-on-v6 port 53 { ::1; };
- directory "/var/named";
- dump-file "/var/named/data/cache_dump.db";
-        statistics-file "/var/named/data/named_stats.txt";
-        memstatistics-file "/var/named/data/named_mem_stats.txt";
- allow-query    { localhost; };
- recursion yes;
-
- dnssec-enable yes;
- dnssec-validation yes;
- dnssec-lookaside auto;
+ listen-on port 53 { any; };
+ listen-on-v6 port 53 { ::1; };
+ directory "/var/named";
+ dump-file "/var/named/data/cache_dump.db";
+        statistics-file "/var/named/data/named_stats.txt";
+        memstatistics-file "/var/named/data/named_mem_stats.txt";
+ allow-query { any; };
+ allow-query-cache { any; };
+ recursion yes;
+ notify yes;
+
+ dnssec-enable no;
+ dnssec-validation no;
+ dnssec-lookaside auto;
+
+ forwarders {
+ // These are Google's open DNS servers
+ 8.8.8.8;
+ 8.8.4.4;
+ };
/* Path to ISC DLV key */
bindkeys-file "/etc/named.iscdlv.key";
</source>
</source>
<source lang="text">
Initializing MySQL database:  Installing MySQL system tables...
OK
Filling help tables...
OK
To start mysqld at boot time you have to copy
support-files/mysql.server to the right place for your system


== Setting Up rndc ==
PLEASE REMEMBER TO SET A PASSWORD FOR THE MySQL root USER !
To do so, start the server, then issue the following commands:


This ensures that we're transferring zone data between the real master and slave servers.
/usr/bin/mysqladmin -u root password 'new-password'
/usr/bin/mysqladmin -u root -h asakusa.alteeve.ca password 'new-password'
 
Alternatively you can run:
/usr/bin/mysql_secure_installation


{{note|1=This will take a long time to finish. Please be patient!}}
which will also give you the option of removing the test
databases and anonymous user created by default.  This is
strongly recommended for production servers.


<source lang="bash">
See the manual for more instructions.
rndc-confgen -a
</source>


Eventually, this will be returned;
You can start the MySQL daemon with:
cd /usr ; /usr/bin/mysqld_safe &


<source lang="text">
You can test the MySQL daemon with mysql-test-run.pl
wrote key file "/etc/rndc.key"
cd /usr/mysql-test ; perl mysql-test-run.pl
</source>


Now make sure everything is owned by <span class="name">named:named</span>.
Please report any problems with the /usr/bin/mysqlbug script!


<source lang="text">
                                                          [  OK  ]
chown named:named /etc/rndc.key
Starting mysqld:                                           [  OK  ]
chown -R named:named /etc/named
</source>
</source>


Now copy the <span class="code">rndc.key</span> to the other node:
Secure the server.


<source lang="bash">
<source lang="bash">
rsync -av /etc/rndc.key root@ns2.alteeve.ca:/etc/
mysql_secure_installation
</source>
</source>
<source lang="text">
<source lang="text">
root@ns2.alteeve.ca's password:  
NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MySQL
sending incremental file list
      SERVERS IN PRODUCTION USE!  PLEASE READ EACH STEP CAREFULLY!


sent 49 bytes  received 15 bytes  11.64 bytes/sec
total size is 77  speedup is 1.20
</source>


Done.
In order to log into MySQL to secure it, we'll need the current
password for the root user.  If you've just installed MySQL, and
you haven't set the root password yet, the password will be blank,
so you should just press enter here.


== Adding Zones ==
Enter current password for root (enter for none):
OK, successfully used password, moving on...


This is where we tell BIND which zones we have SOA for. This includes the pointers to the actual files on disk with each domain's information.
Setting the root password ensures that nobody can log into the MySQL
root user without the proper authorisation.


Backup then edit the zones file.
Set root password? [Y/n] y
New password:
Re-enter new password:
Password updated successfully!
Reloading privilege tables..
... Success!


<source lang="bash">
cp /etc/named.rfc1912.zones /etc/named.rfc1912.zones.orig
vim /etc/named.rfc1912.zones
</source>


'''On the master server''':
By default, a MySQL installation has an anonymous user, allowing anyone
to log into MySQL without having to have a user account created for
them.  This is intended only for testing, and to make the installation
go a bit smoother.  You should remove them before moving into a
production environment.


In here is where we add the entries for the domains we have [[SOA]] for at the end of the file. These will differ for every install, so only two examples will be shown.
Remove anonymous users? [Y/n] y
... Success!


<source lang="dot">
Normally, root should only be allowed to connect from 'localhost'.  This
// Our zones which this server is SOA for.
ensures that someone cannot guess at the root password from the network.


zone "digimer.ca" in {
Disallow root login remotely? [Y/n] 
type master;
... Success!
file "/etc/named/db.digimer.ca";
allow-transfer {
65.39.153.67;
10.255.5.4;
10.222.1.4;
};
};
</source>


'''On the slave server''':
By default, MySQL comes with a database named 'test' that anyone can
access.  This is also intended only for testing, and should be removed
before moving into a production environment.


<source lang="dot">
Remove test database and access to it? [Y/n]
// Our zones which this server is SOA for.
- Dropping test database...
... Success!
- Removing privileges on test database...
... Success!


zone "digimer.ca" in {
Reloading the privilege tables will ensure that all changes made so far
type slave;
will take effect immediately.
file "/etc/named/bak.digimer.ca";
masters {
65.39.153.66;
10.255.5.3;
10.222.1.3;
};
};
</source>


Reload privilege tables now? [Y/n]
... Success!
Cleaning up...


This tutorial does not aim to cover actual zone files, but here is one for reference:


<source lang="bash">
cat /etc/named/db.digimer.ca
</source>
<source lang="text">
$ORIGIN .
$TTL 600 ; Time To Live.
digimer.ca IN SOA ns1.alteeve.ca. admin.alteeve.ca. (
2013022106 ; Serial Number (yyyymmdd##)
300 ; refresh (in seconds)
180 ; retry (in seconds)
300 ; expire (in seconds)
300 ; minimum (in seconds)
)
NS ns1.alteeve.ca.
NS ns2.alteeve.ca.
A 65.39.153.65
MX 10 mail.digimer.ca.
$ORIGIN digimer.ca.
localhost A 127.0.0.1
mail A 64.34.141.3
www CNAME digimer.ca.
</source>


Start the <span class="code">named</span> daemon on the master node;
All done!  If you've completed all of the above steps, your MySQL
installation should now be secure.


<source lang="bash">
Thanks for using MySQL!
/etc/init.d/named start
</source>
<source lang="text">
Starting named:                                            [  OK  ]
</source>
</source>


In [[syslog]], you should see something like this;
= BIND =
 
{{note|1=This is not meant to cover creating the actual zone files for DNS. It's goal is to setup BIND on your [[EL6]] server only.}}


<source lang="text">
This is the BIND named server that handles DNS resolution. It will be setup in two parts; The global options and then the zones file.
Feb 23 18:21:46 vm03-dns01 named[2126]: starting BIND 9.8.2rc1-RedHat-9.8.2-0.10.rc1.el6_3.6 -u named
 
Feb 23 18:21:46 vm03-dns01 named[2126]: built with '--build=x86_64-redhat-linux-gnu' '--host=x86_64-redhat-linux-gnu' '--target=x86_64-redhat-linux-gnu' '--program-prefix=' '--prefix=/usr' '--exec-prefix=/usr' '--bindir=/usr/bin' '--sbindir=/usr/sbin' '--sysconfdir=/etc' '--datadir=/usr/share' '--includedir=/usr/include' '--libdir=/usr/lib64' '--libexecdir=/usr/libexec' '--sharedstatedir=/var/lib' '--mandir=/usr/share/man' '--infodir=/usr/share/info' '--with-libtool' '--localstatedir=/var' '--enable-threads' '--enable-ipv6' '--with-pic' '--disable-static' '--disable-openssl-version-check' '--with-dlz-ldap=yes' '--with-dlz-postgres=yes' '--with-dlz-mysql=yes' '--with-dlz-filesystem=yes' '--with-gssapi=yes' '--disable-isc-spnego' '--with-docbook-xsl=/usr/share/sgml/docbook/xsl-stylesheets' '--enable-fixed-rrset' 'build_alias=x86_64-redhat-linux-gnu' 'host_alias=x86_64-redhat-linux-gnu' 'target_alias=x86_64-redhat-linux-gnu' 'CFLAGS= -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic' 'CPPFLAGS= -DDIG_SIGCHASE'
== Install bind ==
Feb 23 18:21:46 vm03-dns01 named[2126]: ----------------------------------------------------
 
Feb 23 18:21:46 vm03-dns01 named[2126]: BIND 9 is maintained by Internet Systems Consortium,
<source lang="bash">
Feb 23 18:21:46 vm03-dns01 named[2126]: Inc. (ISC), a non-profit 501(c)(3) public-benefit
yum install bind bind-libs bind-utils
Feb 23 18:21:46 vm03-dns01 named[2126]: corporation. Support and training for BIND 9 are
</source>
Feb 23 18:21:46 vm03-dns01 named[2126]: available at https://www.isc.org/support
 
Feb 23 18:21:46 vm03-dns01 named[2126]: ----------------------------------------------------
== Global Configuration ==
Feb 23 18:21:46 vm03-dns01 named[2126]: adjusted limit on open files from 4096 to 1048576
 
Feb 23 18:21:46 vm03-dns01 named[2126]: found 2 CPUs, using 2 worker threads
Edit the main configuration file, making a backup first.
Feb 23 18:21:46 vm03-dns01 named[2126]: using up to 4096 sockets
 
Feb 23 18:21:46 vm03-dns01 named[2126]: loading configuration from '/etc/named.conf'
<source lang="bash">
Feb 23 18:21:46 vm03-dns01 named[2126]: reading built-in trusted keys from file '/etc/named.iscdlv.key'
cp /etc/named.conf /etc/named.conf.orig
Feb 23 18:21:46 vm03-dns01 named[2126]: using default UDP/IPv4 port range: [1024, 65535]
vim /etc/named.conf
Feb 23 18:21:46 vm03-dns01 named[2126]: using default UDP/IPv6 port range: [1024, 65535]
</source>
Feb 23 18:21:46 vm03-dns01 named[2126]: listening on IPv4 interface lo, 127.0.0.1#53
 
Feb 23 18:21:46 vm03-dns01 named[2126]: listening on IPv4 interface eth0, 65.39.153.66#53
Enable queries on any interface and answer queries for any domain, not just ours. Edit or add the following;
Feb 23 18:21:46 vm03-dns01 named[2126]: listening on IPv4 interface eth0:0, 10.255.5.3#53
 
Feb 23 18:21:46 vm03-dns01 named[2126]: listening on IPv4 interface eth0:1, 10.222.1.3#53
<source lang="dot">
Feb 23 18:21:46 vm03-dns01 named[2126]: listening on IPv6 interface lo, ::1#53
        listen-on port 53      { any; };
Feb 23 18:21:46 vm03-dns01 named[2126]: generating session key for dynamic DNS
        allow-query            { any; };
Feb 23 18:21:46 vm03-dns01 named[2126]: sizing zone task pool based on 7 zones
        allow-query-cache      { any; };
Feb 23 18:21:46 vm03-dns01 named[2126]: using built-in DLV key for view _default
Feb 23 18:21:46 vm03-dns01 named[2126]: set up managed keys zone for view _default, file '/var/named/dynamic/managed-keys.bind'
Feb 23 18:21:46 vm03-dns01 named[2126]: Warning: 'empty-zones-enable/disable-empty-zone' not set: disabling RFC 1918 empty zones
Feb 23 18:21:46 vm03-dns01 named[2126]: automatic empty zone: 127.IN-ADDR.ARPA
Feb 23 18:21:46 vm03-dns01 named[2126]: automatic empty zone: 254.169.IN-ADDR.ARPA
Feb 23 18:21:46 vm03-dns01 named[2126]: automatic empty zone: 2.0.192.IN-ADDR.ARPA
Feb 23 18:21:46 vm03-dns01 named[2126]: automatic empty zone: 100.51.198.IN-ADDR.ARPA
Feb 23 18:21:46 vm03-dns01 named[2126]: automatic empty zone: 113.0.203.IN-ADDR.ARPA
Feb 23 18:21:46 vm03-dns01 named[2126]: automatic empty zone: 255.255.255.255.IN-ADDR.ARPA
Feb 23 18:21:46 vm03-dns01 named[2126]: automatic empty zone: 0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.IP6.ARPA
Feb 23 18:21:46 vm03-dns01 named[2126]: automatic empty zone: D.F.IP6.ARPA
Feb 23 18:21:46 vm03-dns01 named[2126]: automatic empty zone: 8.E.F.IP6.ARPA
Feb 23 18:21:46 vm03-dns01 named[2126]: automatic empty zone: 9.E.F.IP6.ARPA
Feb 23 18:21:46 vm03-dns01 named[2126]: automatic empty zone: A.E.F.IP6.ARPA
Feb 23 18:21:46 vm03-dns01 named[2126]: automatic empty zone: B.E.F.IP6.ARPA
Feb 23 18:21:46 vm03-dns01 named[2126]: automatic empty zone: 8.B.D.0.1.0.0.2.IP6.ARPA
Feb 23 18:21:46 vm03-dns01 named[2126]: command channel listening on 127.0.0.1#953
Feb 23 18:21:46 vm03-dns01 named[2126]: command channel listening on ::1#953
Feb 23 18:21:46 vm03-dns01 named[2126]: zone 0.in-addr.arpa/IN: loaded serial 0
Feb 23 18:21:46 vm03-dns01 named[2126]: zone 1.0.0.127.in-addr.arpa/IN: loaded serial 0
Feb 23 18:21:46 vm03-dns01 named[2126]: zone 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa/IN: loaded serial 0
Feb 23 18:21:46 vm03-dns01 named[2126]: zone digimer.ca/IN: loaded serial 2013022106
Feb 23 18:21:46 vm03-dns01 named[2126]: zone localhost.localdomain/IN: loaded serial 0
Feb 23 18:21:46 vm03-dns01 named[2126]: zone localhost/IN: loaded serial 0
Feb 23 18:21:46 vm03-dns01 named[2126]: managed-keys-zone ./IN: loaded serial 3
Feb 23 18:21:46 vm03-dns01 named[2126]: zone digimer.ca/IN: sending notifies (serial 2013022106)
Feb 23 18:21:46 vm03-dns01 named[2126]: running
</source>
</source>


You can test that it's working by querying one of your zones.
For now, we're going to disable DNSSEC. Make the following changes;


<source lang="bash">
<source lang="dot">
dig digimer.ca @localhost
        dnssec-enable          no;
        dnssec-validation      no;
</source>
</source>
<source lang="text">
; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.10.rc1.el6_3.6 <<>> digimer.ca @localhost
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 18362
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 1


;; QUESTION SECTION:
Now tell bind where to look for a domain name's IP when we don't know. Add;
;digimer.ca. IN A


;; ANSWER SECTION:
<source lang="dot">
digimer.ca. 600 IN A 65.39.153.65
        forwarders {
                // These are Google's open DNS servers
                8.8.8.8;
                8.8.4.4;
        };
</source>


;; AUTHORITY SECTION:
This server will have a slave, and we want to notify that slave when a record changes. Add;
digimer.ca. 600 IN NS ns1.alteeve.ca.
digimer.ca. 600 IN NS ns2.alteeve.ca.


;; ADDITIONAL SECTION:
<source lang="dot">
ns2.alteeve.ca. 268 IN A 78.46.37.135
        notify                  yes;
 
;; Query time: 0 msec
;; SERVER: ::1#53(::1)
;; WHEN: Sat Feb 23 18:27:04 2013
;; MSG SIZE  rcvd: 104
</source>
</source>


Now start <span class="code">named</span> on the slave. First though, check <span class="code">/etc/named/</span> to see that there are no files there yet.
Done. I like to clean up the file to put the variables in line with one another. With this in mind, let's look at the changes as a unified <span class="code">diff</span>;


<source lang="bash">
<source lang="bash">
ls -lah /etc/named/
diff -u /etc/named.conf.orig /etc/named.conf
</source>
</source>
<source lang="text">
<source lang="diff">
total 8.0K
--- /etc/named.conf.orig 2012-02-05 00:54:48.434068501 -0500
drwxr-x---  2 named named 4.0K Dec  6 15:49 .
+++ /etc/named.conf 2012-02-05 13:45:16.484083319 -0500
drwxr-xr-x. 66 root  root  4.0K Feb 23 18:13 ..
@@ -8,18 +8,26 @@
</source>
  //
 
Now start <span class="code">named</span>;
options {
 
- listen-on port 53 { 127.0.0.1; };
<source lang="bash">
- listen-on-v6 port 53 { ::1; };
/etc/init.d/named start
- directory "/var/named";
</source>
- dump-file "/var/named/data/cache_dump.db";
<source lang="text">
-       statistics-file "/var/named/data/named_stats.txt";
Starting named:                                            [ OK  ]
-       memstatistics-file "/var/named/data/named_mem_stats.txt";
</source>
- allow-query    { localhost; };
 
- recursion yes;
In syslog on the slave, you will see something like;
-
 
- dnssec-enable yes;
<source lang="text">
- dnssec-validation yes;
Feb 23 18:29:28 vm04-dns02 named[2072]: starting BIND 9.8.2rc1-RedHat-9.8.2-0.10.rc1.el6_3.6 -u named
- dnssec-lookaside auto;
Feb 23 18:29:28 vm04-dns02 named[2072]: built with '--build=x86_64-redhat-linux-gnu' '--host=x86_64-redhat-linux-gnu' '--target=x86_64-redhat-linux-gnu' '--program-prefix=' '--prefix=/usr' '--exec-prefix=/usr' '--bindir=/usr/bin' '--sbindir=/usr/sbin' '--sysconfdir=/etc' '--datadir=/usr/share' '--includedir=/usr/include' '--libdir=/usr/lib64' '--libexecdir=/usr/libexec' '--sharedstatedir=/var/lib' '--mandir=/usr/share/man' '--infodir=/usr/share/info' '--with-libtool' '--localstatedir=/var' '--enable-threads' '--enable-ipv6' '--with-pic' '--disable-static' '--disable-openssl-version-check' '--with-dlz-ldap=yes' '--with-dlz-postgres=yes' '--with-dlz-mysql=yes' '--with-dlz-filesystem=yes' '--with-gssapi=yes' '--disable-isc-spnego' '--with-docbook-xsl=/usr/share/sgml/docbook/xsl-stylesheets' '--enable-fixed-rrset' 'build_alias=x86_64-redhat-linux-gnu' 'host_alias=x86_64-redhat-linux-gnu' 'target_alias=x86_64-redhat-linux-gnu' 'CFLAGS= -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic' 'CPPFLAGS= -DDIG_SIGCHASE'
+ listen-on port 53 { any; };
Feb 23 18:29:28 vm04-dns02 named[2072]: ----------------------------------------------------
+ listen-on-v6 port 53 { ::1; };
Feb 23 18:29:28 vm04-dns02 named[2072]: BIND 9 is maintained by Internet Systems Consortium,
+ directory "/var/named";
Feb 23 18:29:28 vm04-dns02 named[2072]: Inc. (ISC), a non-profit 501(c)(3) public-benefit
+ dump-file "/var/named/data/cache_dump.db";
Feb 23 18:29:28 vm04-dns02 named[2072]: corporation.  Support and training for BIND 9 are
+        statistics-file "/var/named/data/named_stats.txt";
Feb 23 18:29:28 vm04-dns02 named[2072]: available at https://www.isc.org/support
+        memstatistics-file "/var/named/data/named_mem_stats.txt";
Feb 23 18:29:28 vm04-dns02 named[2072]: ----------------------------------------------------
+ allow-query { any; };
Feb 23 18:29:28 vm04-dns02 named[2072]: adjusted limit on open files from 4096 to 1048576
+ allow-query-cache { any; };
Feb 23 18:29:28 vm04-dns02 named[2072]: found 2 CPUs, using 2 worker threads
+ recursion yes;
Feb 23 18:29:28 vm04-dns02 named[2072]: using up to 4096 sockets
+ notify yes;
Feb 23 18:29:28 vm04-dns02 named[2072]: loading configuration from '/etc/named.conf'
+
Feb 23 18:29:28 vm04-dns02 named[2072]: reading built-in trusted keys from file '/etc/named.iscdlv.key'
+ dnssec-enable no;
Feb 23 18:29:28 vm04-dns02 named[2072]: using default UDP/IPv4 port range: [1024, 65535]
+ dnssec-validation no;
Feb 23 18:29:28 vm04-dns02 named[2072]: using default UDP/IPv6 port range: [1024, 65535]
+ dnssec-lookaside auto;
Feb 23 18:29:28 vm04-dns02 named[2072]: listening on IPv4 interface lo, 127.0.0.1#53
+
Feb 23 18:29:28 vm04-dns02 named[2072]: listening on IPv4 interface eth0, 65.39.153.67#53
+ forwarders {
Feb 23 18:29:28 vm04-dns02 named[2072]: listening on IPv4 interface eth0:0, 10.255.5.4#53
+ // These are Google's open DNS servers
Feb 23 18:29:28 vm04-dns02 named[2072]: listening on IPv4 interface eth0:1, 10.222.1.4#53
+ 8.8.8.8;
Feb 23 18:29:28 vm04-dns02 named[2072]: listening on IPv6 interface lo, ::1#53
+ 8.8.4.4;
Feb 23 18:29:28 vm04-dns02 named[2072]: generating session key for dynamic DNS
+ };
Feb 23 18:29:28 vm04-dns02 named[2072]: sizing zone task pool based on 7 zones
Feb 23 18:29:28 vm04-dns02 named[2072]: using built-in DLV key for view _default
/* Path to ISC DLV key */
Feb 23 18:29:28 vm04-dns02 named[2072]: set up managed keys zone for view _default, file '/var/named/dynamic/managed-keys.bind'
bindkeys-file "/etc/named.iscdlv.key";
Feb 23 18:29:28 vm04-dns02 named[2072]: Warning: 'empty-zones-enable/disable-empty-zone' not set: disabling RFC 1918 empty zones
Feb 23 18:29:28 vm04-dns02 named[2072]: automatic empty zone: 127.IN-ADDR.ARPA
Feb 23 18:29:28 vm04-dns02 named[2072]: automatic empty zone: 254.169.IN-ADDR.ARPA
Feb 23 18:29:28 vm04-dns02 named[2072]: automatic empty zone: 2.0.192.IN-ADDR.ARPA
Feb 23 18:29:28 vm04-dns02 named[2072]: automatic empty zone: 100.51.198.IN-ADDR.ARPA
Feb 23 18:29:28 vm04-dns02 named[2072]: automatic empty zone: 113.0.203.IN-ADDR.ARPA
Feb 23 18:29:28 vm04-dns02 named[2072]: automatic empty zone: 255.255.255.255.IN-ADDR.ARPA
Feb 23 18:29:28 vm04-dns02 named[2072]: automatic empty zone: 0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.IP6.ARPA
Feb 23 18:29:28 vm04-dns02 named[2072]: automatic empty zone: D.F.IP6.ARPA
Feb 23 18:29:28 vm04-dns02 named[2072]: automatic empty zone: 8.E.F.IP6.ARPA
Feb 23 18:29:28 vm04-dns02 named[2072]: automatic empty zone: 9.E.F.IP6.ARPA
Feb 23 18:29:28 vm04-dns02 named[2072]: automatic empty zone: A.E.F.IP6.ARPA
Feb 23 18:29:28 vm04-dns02 named[2072]: automatic empty zone: B.E.F.IP6.ARPA
Feb 23 18:29:28 vm04-dns02 named[2072]: automatic empty zone: 8.B.D.0.1.0.0.2.IP6.ARPA
Feb 23 18:29:28 vm04-dns02 named[2072]: command channel listening on 127.0.0.1#953
Feb 23 18:29:28 vm04-dns02 named[2072]: command channel listening on ::1#953
Feb 23 18:29:28 vm04-dns02 named[2072]: zone 0.in-addr.arpa/IN: loaded serial 0
Feb 23 18:29:28 vm04-dns02 named[2072]: zone 1.0.0.127.in-addr.arpa/IN: loaded serial 0
Feb 23 18:29:28 vm04-dns02 named[2072]: zone 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa/IN: loaded serial 0
Feb 23 18:29:28 vm04-dns02 named[2072]: zone localhost.localdomain/IN: loaded serial 0
Feb 23 18:29:28 vm04-dns02 named[2072]: zone localhost/IN: loaded serial 0
Feb 23 18:29:28 vm04-dns02 named[2072]: managed-keys-zone ./IN: loaded serial 0
Feb 23 18:29:28 vm04-dns02 named[2072]: running
Feb 23 18:29:28 vm04-dns02 named[2072]: zone digimer.ca/IN: Transfer started.
Feb 23 18:29:28 vm04-dns02 named[2072]: transfer of 'digimer.ca/IN' from 65.39.153.66#53: connected using 65.39.153.67#47099
Feb 23 18:29:28 vm04-dns02 named[2072]: zone digimer.ca/IN: transferred serial 2013022106
Feb 23 18:29:28 vm04-dns02 named[2072]: transfer of 'digimer.ca/IN' from 65.39.153.66#53: Transfer completed: 1 messages, 9 records, 247 bytes, 0.001 secs (247000 bytes/sec)
</source>
</source>


If you look in syslog on the master, you will see that the <span class="code">digimer.ca</span> domain was transferred;
== Setting Up rndc ==
 
This ensures that we're transferring zone data between the real master and slave servers.
 
{{note|1=This will take a long time to finish. Please be patient!}}
 
<source lang="bash">
rndc-confgen -a
</source>
 
Eventually, this will be returned;


<source lang="text">
<source lang="text">
Feb 23 18:29:28 vm03-dns01 named[2126]: client 65.39.153.67#47099: transfer of 'digimer.ca/IN': AXFR started
wrote key file "/etc/rndc.key"
Feb 23 18:29:28 vm03-dns01 named[2126]: client 65.39.153.67#47099: transfer of 'digimer.ca/IN': AXFR ended
</source>
</source>


Indeed, you will now see that the <span class="code">/etc/named/bak.digimer.ca</span> file was created.
Now make sure everything is owned by <span class="name">named:named</span>.


<source lang="bash">
ls -lah /etc/named/
</source>
<source lang="text">
<source lang="text">
total 12K
chown named:named /etc/rndc.key
drwxr-x---  2 named named 4.0K Feb 23 18:29 .
chown -R named:named /etc/named
drwxr-xr-x. 66 root  root  4.0K Feb 23 18:13 ..
-rw-r--r--  1 named named 438 Feb 23 18:29 bak.digimer.ca
</source>
</source>


We can confirm that it's working by querying the slave;
Now copy the <span class="code">rndc.key</span> to the other node:


<source lang="bash">
<source lang="bash">
dig digimer.ca @localhost
rsync -av /etc/rndc.key root@ns2.alteeve.ca:/etc/
</source>
</source>
<source lang="text">
<source lang="text">
; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.10.rc1.el6_3.6 <<>> digimer.ca @localhost
root@ns2.alteeve.ca's password:  
;; global options: +cmd
sending incremental file list
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 15602
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 0


;; QUESTION SECTION:
sent 49 bytes  received 15 bytes  11.64 bytes/sec
;digimer.ca. IN A
total size is 77  speedup is 1.20
 
;; ANSWER SECTION:
digimer.ca. 600 IN A 65.39.153.65
 
;; AUTHORITY SECTION:
digimer.ca. 600 IN NS ns1.alteeve.ca.
digimer.ca. 600 IN NS ns2.alteeve.ca.
 
;; Query time: 0 msec
;; SERVER: ::1#53(::1)
;; WHEN: Sat Feb 23 18:32:52 2013
;; MSG SIZE  rcvd: 88
</source>
</source>


Excellent! Now you can add more DNS servers to the master server.
Done.


== Adding a Firewall Entry ==
== Adding Zones ==


Assuming you have a firewall running, be sure to add an entry for [[TCP]] port 53.
This is where we tell BIND which zones we have SOA for. This includes the pointers to the actual files on disk with each domain's information.


== (Re)Start BIND ==
Backup then edit the zones file.
 
Once all the configuration files and domain zone files are in place, (re)start the <span class="code">named</span> service.


<source lang="bash">
<source lang="bash">
/etc/init.d/named restart
cp /etc/named.rfc1912.zones /etc/named.rfc1912.zones.orig
</source>
vim /etc/named.rfc1912.zones
<source lang="text">
Stopping named: .                                         [  OK  ]
Starting named:                                            [  OK  ]
</source>
</source>


== Testing Name resolution ==
'''On the master server''':


To properly test name resolution, you will want to resolve a domain we are [[SOA]] for and another domain which we are not. We will repeat this twice, once on the server and once from a remote machine to ensure that it is answering remote queries. Note that in the examples below, my DNS server's IP address is <span class="code">78.46.37.135</span>.
In here is where we add the entries for the domains we have [[SOA]] for at the end of the file. These will differ for every install, so only two examples will be shown.


On the server;
<source lang="dot">
// Our zones which this server is SOA for.


Query <span class="code">alteeve.ca</span>, which we're SOA for.
zone "digimer.ca" in {
type master;
file "/etc/named/db.digimer.ca";
allow-transfer {
65.39.153.67;
10.255.5.4;
10.222.1.4;
};
};
</source>


<source lang="bash">
'''On the slave server''':
dig alteeve.ca @localhost
 
<source lang="dot">
// Our zones which this server is SOA for.
 
zone "digimer.ca" in {
type slave;
file "/etc/named/bak.digimer.ca";
masters {
65.39.153.66;
10.255.5.3;
10.222.1.3;
};
};
</source>
</source>
<source lang="text">
; <<>> DiG 9.7.3-P3-RedHat-9.7.3-8.P3.el6_2.2 <<>> alteeve.ca @localhost
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 1418
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 2


;; QUESTION SECTION:
;alteeve.ca. IN A


;; ANSWER SECTION:
This tutorial does not aim to cover actual zone files, but here is one for reference:
alteeve.ca. 600 IN A 192.139.81.121


;; AUTHORITY SECTION:
<source lang="bash">
alteeve.ca. 600 IN NS ns1.alteeve.ca.
cat /etc/named/db.digimer.ca  
alteeve.ca. 600 IN NS ns2.alteeve.ca.
</source>
 
<source lang="text">
;; ADDITIONAL SECTION:
$ORIGIN .
ns1.alteeve.ca. 600 IN A 192.139.81.117
$TTL 600 ; Time To Live.
ns2.alteeve.ca. 600 IN A 192.139.81.119
digimer.ca IN SOA ns1.alteeve.ca. admin.alteeve.ca. (
 
2013022106 ; Serial Number (yyyymmdd##)
;; Query time: 0 msec
300 ; refresh (in seconds)
;; SERVER: ::1#53(::1)
180 ; retry (in seconds)
;; WHEN: Sun Feb  5 13:57:11 2012
300 ; expire (in seconds)
;; MSG SIZE  rcvd: 113
300 ; minimum (in seconds)
)
NS ns1.alteeve.ca.
NS ns2.alteeve.ca.
A 65.39.153.65
MX 10 mail.digimer.ca.
$ORIGIN digimer.ca.
localhost A 127.0.0.1
mail A 64.34.141.3
www CNAME digimer.ca.
</source>
</source>


Now query <span class="code">google.ca</span> which we obviously are not SOA for.
Start the <span class="code">named</span> daemon on the master node;


<source lang="bash">
<source lang="bash">
dig google.ca @localhost
/etc/init.d/named start
</source>
</source>
<source lang="text">
<source lang="text">
; <<>> DiG 9.7.3-P3-RedHat-9.7.3-8.P3.el6_2.2 <<>> google.ca @localhost
Starting named:                                           [  OK  ]
;; global options: +cmd
</source>
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 56760
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 13, ADDITIONAL: 0


;; QUESTION SECTION:
In [[syslog]], you should see something like this;
;google.ca. IN A


;; ANSWER SECTION:
<source lang="text">
google.ca. 300 IN A 74.125.232.56
Feb 23 18:21:46 vm03-dns01 named[2126]: starting BIND 9.8.2rc1-RedHat-9.8.2-0.10.rc1.el6_3.6 -u named
 
Feb 23 18:21:46 vm03-dns01 named[2126]: built with '--build=x86_64-redhat-linux-gnu' '--host=x86_64-redhat-linux-gnu' '--target=x86_64-redhat-linux-gnu' '--program-prefix=' '--prefix=/usr' '--exec-prefix=/usr' '--bindir=/usr/bin' '--sbindir=/usr/sbin' '--sysconfdir=/etc' '--datadir=/usr/share' '--includedir=/usr/include' '--libdir=/usr/lib64' '--libexecdir=/usr/libexec' '--sharedstatedir=/var/lib' '--mandir=/usr/share/man' '--infodir=/usr/share/info' '--with-libtool' '--localstatedir=/var' '--enable-threads' '--enable-ipv6' '--with-pic' '--disable-static' '--disable-openssl-version-check' '--with-dlz-ldap=yes' '--with-dlz-postgres=yes' '--with-dlz-mysql=yes' '--with-dlz-filesystem=yes' '--with-gssapi=yes' '--disable-isc-spnego' '--with-docbook-xsl=/usr/share/sgml/docbook/xsl-stylesheets' '--enable-fixed-rrset' 'build_alias=x86_64-redhat-linux-gnu' 'host_alias=x86_64-redhat-linux-gnu' 'target_alias=x86_64-redhat-linux-gnu' 'CFLAGS= -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic' 'CPPFLAGS= -DDIG_SIGCHASE'
;; AUTHORITY SECTION:
Feb 23 18:21:46 vm03-dns01 named[2126]: ----------------------------------------------------
. 2967 IN NS f.root-servers.net.
Feb 23 18:21:46 vm03-dns01 named[2126]: BIND 9 is maintained by Internet Systems Consortium,
. 2967 IN NS c.root-servers.net.
Feb 23 18:21:46 vm03-dns01 named[2126]: Inc. (ISC), a non-profit 501(c)(3) public-benefit
. 2967 IN NS b.root-servers.net.
Feb 23 18:21:46 vm03-dns01 named[2126]: corporation.  Support and training for BIND 9 are
. 2967 IN NS a.root-servers.net.
Feb 23 18:21:46 vm03-dns01 named[2126]: available at https://www.isc.org/support
. 2967 IN NS k.root-servers.net.
Feb 23 18:21:46 vm03-dns01 named[2126]: ----------------------------------------------------
. 2967 IN NS i.root-servers.net.
Feb 23 18:21:46 vm03-dns01 named[2126]: adjusted limit on open files from 4096 to 1048576
. 2967 IN NS e.root-servers.net.
Feb 23 18:21:46 vm03-dns01 named[2126]: found 2 CPUs, using 2 worker threads
. 2967 IN NS h.root-servers.net.
Feb 23 18:21:46 vm03-dns01 named[2126]: using up to 4096 sockets
. 2967 IN NS l.root-servers.net.
Feb 23 18:21:46 vm03-dns01 named[2126]: loading configuration from '/etc/named.conf'
. 2967 IN NS d.root-servers.net.
Feb 23 18:21:46 vm03-dns01 named[2126]: reading built-in trusted keys from file '/etc/named.iscdlv.key'
. 2967 IN NS j.root-servers.net.
Feb 23 18:21:46 vm03-dns01 named[2126]: using default UDP/IPv4 port range: [1024, 65535]
. 2967 IN NS g.root-servers.net.
Feb 23 18:21:46 vm03-dns01 named[2126]: using default UDP/IPv6 port range: [1024, 65535]
. 2967 IN NS m.root-servers.net.
Feb 23 18:21:46 vm03-dns01 named[2126]: listening on IPv4 interface lo, 127.0.0.1#53
Feb 23 18:21:46 vm03-dns01 named[2126]: listening on IPv4 interface eth0, 65.39.153.66#53
Feb 23 18:21:46 vm03-dns01 named[2126]: listening on IPv4 interface eth0:0, 10.255.5.3#53
Feb 23 18:21:46 vm03-dns01 named[2126]: listening on IPv4 interface eth0:1, 10.222.1.3#53
Feb 23 18:21:46 vm03-dns01 named[2126]: listening on IPv6 interface lo, ::1#53
Feb 23 18:21:46 vm03-dns01 named[2126]: generating session key for dynamic DNS
Feb 23 18:21:46 vm03-dns01 named[2126]: sizing zone task pool based on 7 zones
Feb 23 18:21:46 vm03-dns01 named[2126]: using built-in DLV key for view _default
Feb 23 18:21:46 vm03-dns01 named[2126]: set up managed keys zone for view _default, file '/var/named/dynamic/managed-keys.bind'
Feb 23 18:21:46 vm03-dns01 named[2126]: Warning: 'empty-zones-enable/disable-empty-zone' not set: disabling RFC 1918 empty zones
Feb 23 18:21:46 vm03-dns01 named[2126]: automatic empty zone: 127.IN-ADDR.ARPA
Feb 23 18:21:46 vm03-dns01 named[2126]: automatic empty zone: 254.169.IN-ADDR.ARPA
Feb 23 18:21:46 vm03-dns01 named[2126]: automatic empty zone: 2.0.192.IN-ADDR.ARPA
Feb 23 18:21:46 vm03-dns01 named[2126]: automatic empty zone: 100.51.198.IN-ADDR.ARPA
Feb 23 18:21:46 vm03-dns01 named[2126]: automatic empty zone: 113.0.203.IN-ADDR.ARPA
Feb 23 18:21:46 vm03-dns01 named[2126]: automatic empty zone: 255.255.255.255.IN-ADDR.ARPA
Feb 23 18:21:46 vm03-dns01 named[2126]: automatic empty zone: 0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.IP6.ARPA
Feb 23 18:21:46 vm03-dns01 named[2126]: automatic empty zone: D.F.IP6.ARPA
Feb 23 18:21:46 vm03-dns01 named[2126]: automatic empty zone: 8.E.F.IP6.ARPA
Feb 23 18:21:46 vm03-dns01 named[2126]: automatic empty zone: 9.E.F.IP6.ARPA
Feb 23 18:21:46 vm03-dns01 named[2126]: automatic empty zone: A.E.F.IP6.ARPA
Feb 23 18:21:46 vm03-dns01 named[2126]: automatic empty zone: B.E.F.IP6.ARPA
Feb 23 18:21:46 vm03-dns01 named[2126]: automatic empty zone: 8.B.D.0.1.0.0.2.IP6.ARPA
Feb 23 18:21:46 vm03-dns01 named[2126]: command channel listening on 127.0.0.1#953
Feb 23 18:21:46 vm03-dns01 named[2126]: command channel listening on ::1#953
Feb 23 18:21:46 vm03-dns01 named[2126]: zone 0.in-addr.arpa/IN: loaded serial 0
Feb 23 18:21:46 vm03-dns01 named[2126]: zone 1.0.0.127.in-addr.arpa/IN: loaded serial 0
Feb 23 18:21:46 vm03-dns01 named[2126]: zone 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa/IN: loaded serial 0
Feb 23 18:21:46 vm03-dns01 named[2126]: zone digimer.ca/IN: loaded serial 2013022106
Feb 23 18:21:46 vm03-dns01 named[2126]: zone localhost.localdomain/IN: loaded serial 0
Feb 23 18:21:46 vm03-dns01 named[2126]: zone localhost/IN: loaded serial 0
Feb 23 18:21:46 vm03-dns01 named[2126]: managed-keys-zone ./IN: loaded serial 3
Feb 23 18:21:46 vm03-dns01 named[2126]: zone digimer.ca/IN: sending notifies (serial 2013022106)
Feb 23 18:21:46 vm03-dns01 named[2126]: running
</source>


;; Query time: 12 msec
You can test that it's working by querying one of your zones.
;; SERVER: ::1#53(::1)
;; WHEN: Sun Feb  5 14:02:03 2012
;; MSG SIZE  rcvd: 254
</source>
 
Now from a remote machine, repeat the same queries to ensure that our DNS server will respond to external queries.
 
On the server;
 
Query <span class="code">alteeve.ca</span>, which we're SOA for.


<source lang="bash">
<source lang="bash">
dig alteeve.ca @78.46.37.135
dig digimer.ca @localhost
</source>
</source>
<source lang="text">
<source lang="text">
; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.2.rc1.fc16 <<>> alteeve.ca @78.46.37.135
; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.10.rc1.el6_3.6 <<>> digimer.ca @localhost
;; global options: +cmd
;; global options: +cmd
;; Got answer:
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 46628
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 18362
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 2
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 1


;; QUESTION SECTION:
;; QUESTION SECTION:
;alteeve.ca. IN A
;digimer.ca. IN A


;; ANSWER SECTION:
;; ANSWER SECTION:
alteeve.ca. 600 IN A 192.139.81.121
digimer.ca. 600 IN A 65.39.153.65


;; AUTHORITY SECTION:
;; AUTHORITY SECTION:
alteeve.ca. 600 IN NS ns2.alteeve.ca.
digimer.ca. 600 IN NS ns1.alteeve.ca.
alteeve.ca. 600 IN NS ns1.alteeve.ca.
digimer.ca. 600 IN NS ns2.alteeve.ca.


;; ADDITIONAL SECTION:
;; ADDITIONAL SECTION:
ns1.alteeve.ca. 600 IN A 192.139.81.117
ns2.alteeve.ca. 268 IN A 78.46.37.135
ns2.alteeve.ca. 600 IN A 192.139.81.119


;; Query time: 138 msec
;; Query time: 0 msec
;; SERVER: 78.46.37.135#53(78.46.37.135)
;; SERVER: ::1#53(::1)
;; WHEN: Sun Feb 5 14:04:09 2012
;; WHEN: Sat Feb 23 18:27:04 2013
;; MSG SIZE  rcvd: 113
;; MSG SIZE  rcvd: 104
</source>
</source>


Now query <span class="code">google.ca</span> which we obviously are not SOA for.
Now start <span class="code">named</span> on the slave. First though, check <span class="code">/etc/named/</span> to see that there are no files there yet.


<source lang="bash">
<source lang="bash">
dig google.ca @78.46.37.135
ls -lah /etc/named/
</source>
</source>
<source lang="text">
<source lang="text">
; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.2.rc1.fc16 <<>> google.ca @78.46.37.135
total 8.0K
;; global options: +cmd
drwxr-x---   2 named named 4.0K Dec  6 15:49 .
;; Got answer:
drwxr-xr-x. 66 root  root  4.0K Feb 23 18:13 ..
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 18204
</source>
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 13, ADDITIONAL: 0
 
Now start <span class="code">named</span>;


;; QUESTION SECTION:
<source lang="bash">
;google.ca. IN A
/etc/init.d/named start
</source>
<source lang="text">
Starting named:                                           [  OK  ]
</source>


;; ANSWER SECTION:
In syslog on the slave, you will see something like;
google.ca. 138 IN A 74.125.232.56


;; AUTHORITY SECTION:
<source lang="text">
. 2805 IN NS h.root-servers.net.
Feb 23 18:29:28 vm04-dns02 named[2072]: starting BIND 9.8.2rc1-RedHat-9.8.2-0.10.rc1.el6_3.6 -u named
. 2805 IN NS c.root-servers.net.
Feb 23 18:29:28 vm04-dns02 named[2072]: built with '--build=x86_64-redhat-linux-gnu' '--host=x86_64-redhat-linux-gnu' '--target=x86_64-redhat-linux-gnu' '--program-prefix=' '--prefix=/usr' '--exec-prefix=/usr' '--bindir=/usr/bin' '--sbindir=/usr/sbin' '--sysconfdir=/etc' '--datadir=/usr/share' '--includedir=/usr/include' '--libdir=/usr/lib64' '--libexecdir=/usr/libexec' '--sharedstatedir=/var/lib' '--mandir=/usr/share/man' '--infodir=/usr/share/info' '--with-libtool' '--localstatedir=/var' '--enable-threads' '--enable-ipv6' '--with-pic' '--disable-static' '--disable-openssl-version-check' '--with-dlz-ldap=yes' '--with-dlz-postgres=yes' '--with-dlz-mysql=yes' '--with-dlz-filesystem=yes' '--with-gssapi=yes' '--disable-isc-spnego' '--with-docbook-xsl=/usr/share/sgml/docbook/xsl-stylesheets' '--enable-fixed-rrset' 'build_alias=x86_64-redhat-linux-gnu' 'host_alias=x86_64-redhat-linux-gnu' 'target_alias=x86_64-redhat-linux-gnu' 'CFLAGS= -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic' 'CPPFLAGS= -DDIG_SIGCHASE'
. 2805 IN NS j.root-servers.net.
Feb 23 18:29:28 vm04-dns02 named[2072]: ----------------------------------------------------
. 2805 IN NS i.root-servers.net.
Feb 23 18:29:28 vm04-dns02 named[2072]: BIND 9 is maintained by Internet Systems Consortium,
. 2805 IN NS b.root-servers.net.
Feb 23 18:29:28 vm04-dns02 named[2072]: Inc. (ISC), a non-profit 501(c)(3) public-benefit
. 2805 IN NS m.root-servers.net.
Feb 23 18:29:28 vm04-dns02 named[2072]: corporation. Support and training for BIND 9 are
. 2805 IN NS g.root-servers.net.
Feb 23 18:29:28 vm04-dns02 named[2072]: available at https://www.isc.org/support
. 2805 IN NS d.root-servers.net.
Feb 23 18:29:28 vm04-dns02 named[2072]: ----------------------------------------------------
. 2805 IN NS a.root-servers.net.
Feb 23 18:29:28 vm04-dns02 named[2072]: adjusted limit on open files from 4096 to 1048576
. 2805 IN NS l.root-servers.net.
Feb 23 18:29:28 vm04-dns02 named[2072]: found 2 CPUs, using 2 worker threads
. 2805 IN NS f.root-servers.net.
Feb 23 18:29:28 vm04-dns02 named[2072]: using up to 4096 sockets
. 2805 IN NS k.root-servers.net.
Feb 23 18:29:28 vm04-dns02 named[2072]: loading configuration from '/etc/named.conf'
. 2805 IN NS e.root-servers.net.
Feb 23 18:29:28 vm04-dns02 named[2072]: reading built-in trusted keys from file '/etc/named.iscdlv.key'
 
Feb 23 18:29:28 vm04-dns02 named[2072]: using default UDP/IPv4 port range: [1024, 65535]
;; Query time: 140 msec
Feb 23 18:29:28 vm04-dns02 named[2072]: using default UDP/IPv6 port range: [1024, 65535]
;; SERVER: 78.46.37.135#53(78.46.37.135)
Feb 23 18:29:28 vm04-dns02 named[2072]: listening on IPv4 interface lo, 127.0.0.1#53
;; WHEN: Sun Feb 5 14:04:31 2012
Feb 23 18:29:28 vm04-dns02 named[2072]: listening on IPv4 interface eth0, 65.39.153.67#53
;; MSG SIZE  rcvd: 254
Feb 23 18:29:28 vm04-dns02 named[2072]: listening on IPv4 interface eth0:0, 10.255.5.4#53
</source>
Feb 23 18:29:28 vm04-dns02 named[2072]: listening on IPv4 interface eth0:1, 10.222.1.4#53
 
Feb 23 18:29:28 vm04-dns02 named[2072]: listening on IPv6 interface lo, ::1#53
Done!
Feb 23 18:29:28 vm04-dns02 named[2072]: generating session key for dynamic DNS
 
Feb 23 18:29:28 vm04-dns02 named[2072]: sizing zone task pool based on 7 zones
= Email =
Feb 23 18:29:28 vm04-dns02 named[2072]: using built-in DLV key for view _default
 
Feb 23 18:29:28 vm04-dns02 named[2072]: set up managed keys zone for view _default, file '/var/named/dynamic/managed-keys.bind'
This is a pretty heavily customized postfix install using a custom schema. It was originally based on [http://www.howtoforge.com/virtual_users_and_domains_with_postfix_debian_etch this Debian Etch] tutorial, but adapted for PostgreSQL. Much time has passed and the operating system is now significantly changed, but it's lineage is thus. A more recent, but still Debian-focused version of the tutorial [http://workaround.org/ispmail/squeeze/big-picture is here]. I also used [http://en.gentoo-wiki.com/wiki/Mail_server_using_Postfix_and_Dovecot this tutorial] to help sort out the PostgreSQL stuff.
Feb 23 18:29:28 vm04-dns02 named[2072]: Warning: 'empty-zones-enable/disable-empty-zone' not set: disabling RFC 1918 empty zones
Feb 23 18:29:28 vm04-dns02 named[2072]: automatic empty zone: 127.IN-ADDR.ARPA
Feb 23 18:29:28 vm04-dns02 named[2072]: automatic empty zone: 254.169.IN-ADDR.ARPA
Feb 23 18:29:28 vm04-dns02 named[2072]: automatic empty zone: 2.0.192.IN-ADDR.ARPA
Feb 23 18:29:28 vm04-dns02 named[2072]: automatic empty zone: 100.51.198.IN-ADDR.ARPA
Feb 23 18:29:28 vm04-dns02 named[2072]: automatic empty zone: 113.0.203.IN-ADDR.ARPA
Feb 23 18:29:28 vm04-dns02 named[2072]: automatic empty zone: 255.255.255.255.IN-ADDR.ARPA
Feb 23 18:29:28 vm04-dns02 named[2072]: automatic empty zone: 0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.IP6.ARPA
Feb 23 18:29:28 vm04-dns02 named[2072]: automatic empty zone: D.F.IP6.ARPA
Feb 23 18:29:28 vm04-dns02 named[2072]: automatic empty zone: 8.E.F.IP6.ARPA
Feb 23 18:29:28 vm04-dns02 named[2072]: automatic empty zone: 9.E.F.IP6.ARPA
Feb 23 18:29:28 vm04-dns02 named[2072]: automatic empty zone: A.E.F.IP6.ARPA
Feb 23 18:29:28 vm04-dns02 named[2072]: automatic empty zone: B.E.F.IP6.ARPA
Feb 23 18:29:28 vm04-dns02 named[2072]: automatic empty zone: 8.B.D.0.1.0.0.2.IP6.ARPA
Feb 23 18:29:28 vm04-dns02 named[2072]: command channel listening on 127.0.0.1#953
Feb 23 18:29:28 vm04-dns02 named[2072]: command channel listening on ::1#953
Feb 23 18:29:28 vm04-dns02 named[2072]: zone 0.in-addr.arpa/IN: loaded serial 0
Feb 23 18:29:28 vm04-dns02 named[2072]: zone 1.0.0.127.in-addr.arpa/IN: loaded serial 0
Feb 23 18:29:28 vm04-dns02 named[2072]: zone 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa/IN: loaded serial 0
Feb 23 18:29:28 vm04-dns02 named[2072]: zone localhost.localdomain/IN: loaded serial 0
Feb 23 18:29:28 vm04-dns02 named[2072]: zone localhost/IN: loaded serial 0
Feb 23 18:29:28 vm04-dns02 named[2072]: managed-keys-zone ./IN: loaded serial 0
Feb 23 18:29:28 vm04-dns02 named[2072]: running
Feb 23 18:29:28 vm04-dns02 named[2072]: zone digimer.ca/IN: Transfer started.
Feb 23 18:29:28 vm04-dns02 named[2072]: transfer of 'digimer.ca/IN' from 65.39.153.66#53: connected using 65.39.153.67#47099
Feb 23 18:29:28 vm04-dns02 named[2072]: zone digimer.ca/IN: transferred serial 2013022106
Feb 23 18:29:28 vm04-dns02 named[2072]: transfer of 'digimer.ca/IN' from 65.39.153.66#53: Transfer completed: 1 messages, 9 records, 247 bytes, 0.001 secs (247000 bytes/sec)
</source>


This will use a few applications;
If you look in syslog on the master, you will see that the <span class="code">digimer.ca</span> domain was transferred;
* Postfix - The program that receives email.
* PostgreSQL - The database used to validate the existence of email accounts and validates incoming user credentials.
* Dovecot - Takes email coming from postfix, via amavis, and records them to disk. It also answers requests from users wanting to check their email.
* Amavis - Filters incoming email for spam (via spamassassin) and virsus (via clamav)


We will also be using graylisting, which is a spam fighting tactic where the first email from a given user to one of our users is bounced for a few minutes. Proper mail servers will acknowledge the bound, wait the time and resend. Spam mailers though are usually fire-and-forget and will not resend, thus effectively blocking the spam message. This is a very effective method of blocking spam with minimal chance of losing real mail from real users. Any subsequent message from the user would be allowed through with no delay, provided the user had in fact resent the first message as requested.
<source lang="text">
Feb 23 18:29:28 vm03-dns01 named[2126]: client 65.39.153.67#47099: transfer of 'digimer.ca/IN': AXFR started
Feb 23 18:29:28 vm03-dns01 named[2126]: client 65.39.153.67#47099: transfer of 'digimer.ca/IN': AXFR ended
</source>


== Install ==
Indeed, you will now see that the <span class="code">/etc/named/bak.digimer.ca</span> file was created.
 
To install the applications;


<source lang="bash">
<source lang="bash">
yum install postfix postfix-perl-scripts dovecot dovecot-pgsql spamassassin postgresql-server postgresql-plperl mutt
ls -lah /etc/named/
</source>
<source lang="text">
total 12K
drwxr-x---   2 named named 4.0K Feb 23 18:29 .
drwxr-xr-x. 66 root  root  4.0K Feb 23 18:13 ..
-rw-r--r--  1 named named  438 Feb 23 18:29 bak.digimer.ca
</source>
</source>


== Configuring Postfix ==
We can confirm that it's working by querying the slave;


Installation requires several steps. The AN!Console database must be loaded. Various applications need to be installed. Postfix, Dovecot and helper applications need to be configured and so on.
<source lang="bash">
dig digimer.ca @localhost
</source>
<source lang="text">
; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.10.rc1.el6_3.6 <<>> digimer.ca @localhost
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 15602
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 0


This tutorial uses the following values that you may need to adjust;
;; QUESTION SECTION:
* Database name; <span class="code">an_tools</span>
;digimer.ca. IN A
* Database user; <span class="code">alteeve</span>
* Database password; <span class="code">secret</span>
* Database host; <span class="code">127.0.0.1</span>


{{note|1=Do not use the database host "<span class="code">localhost</span>" unless you are certain you can connect to the DB using a standard [[unix]] socket.}}
;; ANSWER SECTION:
digimer.ca. 600 IN A 65.39.153.65


=== Building Support for PostgreSQL ===
;; AUTHORITY SECTION:
digimer.ca. 600 IN NS ns1.alteeve.ca.
digimer.ca. 600 IN NS ns2.alteeve.ca.
 
;; Query time: 0 msec
;; SERVER: ::1#53(::1)
;; WHEN: Sat Feb 23 18:32:52 2013
;; MSG SIZE  rcvd: 88
</source>
 
Excellent! Now you can add more DNS servers to the master server.


{{warning|1=We need to build our own RPM in order to support postgresql. This means we will have to disable <span class="code">postfix</span> from future updates, placing the onus on us to make sure critical updates are applied. This will require downloading the latest source RPMs, re-enabling postgres and recompile/reinstall.}}
== Adding a Firewall Entry ==


Add the source [[RPM]] repository by adding the following;
Assuming you have a firewall running, be sure to add an entry for [[TCP]] port 53.


<source lang="bash">
== (Re)Start BIND ==
vim /etc/yum.repos.d/CentOS-Base.repo
</source>
<source lang="bash">
# Source RPM repository
[base-source]
name=CentOS-$releasever - Base - Source
#mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=os
baseurl=http://vault.centos.org/6.3/os/Source/
gpgcheck=1
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6
</source>


Now download the source RPM for postfix.
Once all the configuration files and domain zone files are in place, (re)start the <span class="code">named</span> service.


<source lang="bash">
<source lang="bash">
yumdownloader --source postfix
/etc/init.d/named restart
</source>
</source>
<source lang="text">
<source lang="text">
Loaded plugins: fastestmirror
Stopping named: .                                         [ OK ]
Loading mirror speeds from cached hostfile
Starting named:                                           [  OK  ]
* base: centos.vieth-server.de
</source>
  * extras: centos.vieth-server.de
 
  * updates: centos.vieth-server.de
== Testing Name resolution ==
base                              | 3.7 kB    00:00
 
base-source                       | 1.9 kB    00:00
To properly test name resolution, you will want to resolve a domain we are [[SOA]] for and another domain which we are not. We will repeat this twice, once on the server and once from a remote machine to ensure that it is answering remote queries. Note that in the examples below, my DNS server's IP address is <span class="code">78.46.37.135</span>.
extras                            | 3.5 kB    00:00
 
updates                            | 3.5 kB    00:00
On the server;
No source RPM found for 2:postfix-2.6.6-2.2.el6_1.x86_64
./postfix-2.6.6-2.el6.src.rpm already exists and appears to be complete
nikko:/etc/postfix# rm postfix-2.6.6-2.el6.src.rpm
rm: remove regular file `postfix-2.6.6-2.el6.src.rpm'? y
nikko:/etc/postfix# yumdownloader --source postfix
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
* base: centos.vieth-server.de
* extras: centos.vieth-server.de
* updates: centos.vieth-server.de
No source RPM found for 2:postfix-2.6.6-2.2.el6_1.x86_64
postfix-2.6.6-2.el6.src.rpm        | 3.3 MB    00:00
</source>


Now that we have the postfix source RPM, we will install it.
Query <span class="code">alteeve.ca</span>, which we're SOA for.


<source lang="bash">
<source lang="bash">
rpm -Uvh postfix-2.6.6-2.el6.src.rpm
dig alteeve.ca @localhost
</source>
</source>
<source lang="text">
<source lang="text">
  1:postfix                warning: user mockbuild does not exist - using root
; <<>> DiG 9.7.3-P3-RedHat-9.7.3-8.P3.el6_2.2 <<>> alteeve.ca @localhost
warning: group mockbuild does not exist - using root
;; global options: +cmd
warning: user mockbuild does not exist - using root
;; Got answer:
warning: group mockbuild does not exist - using root
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 1418
warning: user mockbuild does not exist - using root
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 2
warning: group mockbuild does not exist - using root
warning: user mockbuild does not exist - using root
warning: group mockbuild does not exist - using root
warning: user mockbuild does not exist - using root
warning: group mockbuild does not exist - using root
warning: user mockbuild does not exist - using root
warning: group mockbuild does not exist - using root
warning: user mockbuild does not exist - using root
warning: group mockbuild does not exist - using root
warning: user mockbuild does not exist - using root
warning: group mockbuild does not exist - using root
########################################### [100%]
warning: user mockbuild does not exist - using root
warning: group mockbuild does not exist - using root
warning: user mockbuild does not exist - using root
warning: group mockbuild does not exist - using root
warning: user mockbuild does not exist - using root
warning: group mockbuild does not exist - using root
warning: user mockbuild does not exist - using root
warning: group mockbuild does not exist - using root
</source>


Now edit the <span class="code">.spec</span> file to enable postgres support.
;; QUESTION SECTION:
;alteeve.ca. IN A


<source lang="bash">
;; ANSWER SECTION:
cp ~/rpmbuild/SPECS/postfix.spec ~/rpmbuild/SPECS/postfix.spec.orig
alteeve.ca. 600 IN A 192.139.81.121
vim ~/rpmbuild/SPECS/postfix.spec
</source>


Make the following changes.
;; AUTHORITY SECTION:
alteeve.ca. 600 IN NS ns1.alteeve.ca.
alteeve.ca. 600 IN NS ns2.alteeve.ca.


* Enable PostgreSQL support
;; ADDITIONAL SECTION:
<source lang="text">
ns1.alteeve.ca. 600 IN A 192.139.81.117
%{?!PGSQL: %define PGSQL 1}
ns2.alteeve.ca. 600 IN A 192.139.81.119
</source>


Increment the release version by one.
;; Query time: 0 msec
<source lang="text">
;; SERVER: ::1#53(::1)
Release: 3%{?dist}
;; WHEN: Sun Feb  5 13:57:11 2012
;; MSG SIZE  rcvd: 113
</source>
</source>


We can see the changes here:
Now query <span class="code">google.ca</span> which we obviously are not SOA for.


<source lang="bash">
<source lang="bash">
diff -u ~/rpmbuild/SPECS/postfix.spec.orig ~/rpmbuild/SPECS/postfix.spec
dig google.ca @localhost
</source>
</source>
<source lang="diff">
<source lang="text">
--- /root/rpmbuild/SPECS/postfix.spec.orig      2012-02-11 16:54:54.495330859 -0500
; <<>> DiG 9.7.3-P3-RedHat-9.7.3-8.P3.el6_2.2 <<>> google.ca @localhost
+++ /root/rpmbuild/SPECS/postfix.spec  2012-02-11 16:53:39.873331101 -0500
;; global options: +cmd
@@ -1,5 +1,5 @@
;; Got answer:
%{?!MYSQL: %define MYSQL 1}
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 56760
-%{?!PGSQL: %define PGSQL 0}
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 13, ADDITIONAL: 0
+%{?!PGSQL: %define PGSQL 1}
 
%define LDAP 2
;; QUESTION SECTION:
%define PCRE 1
;google.ca. IN A
%define SASL 2
 
@@ -35,7 +35,7 @@
;; ANSWER SECTION:
Name: postfix
google.ca. 300 IN A 74.125.232.56
Summary: Postfix Mail Transport Agent
 
Version: 2.6.6
;; AUTHORITY SECTION:
-Release: 2%{?dist}
. 2967 IN NS f.root-servers.net.
+Release: 3%{?dist}
. 2967 IN NS c.root-servers.net.
  Epoch: 2
. 2967 IN NS b.root-servers.net.
Group: System Environment/Daemons
. 2967 IN NS a.root-servers.net.
  URL: http://www.postfix.org
. 2967 IN NS k.root-servers.net.
. 2967 IN NS i.root-servers.net.
. 2967 IN NS e.root-servers.net.
. 2967 IN NS h.root-servers.net.
. 2967 IN NS l.root-servers.net.
. 2967 IN NS d.root-servers.net.
. 2967 IN NS j.root-servers.net.
. 2967 IN NS g.root-servers.net.
. 2967 IN NS m.root-servers.net.
 
;; Query time: 12 msec
;; SERVER: ::1#53(::1)
;; WHEN: Sun Feb 5 14:02:03 2012
;; MSG SIZE rcvd: 254
</source>
</source>


Now rebuild the RPM, which means we need to install the build tools.
Now from a remote machine, repeat the same queries to ensure that our DNS server will respond to external queries.
 
On the server;
 
Query <span class="code">alteeve.ca</span>, which we're SOA for.


<source lang="bash">
<source lang="bash">
yum groupinstall development
dig alteeve.ca @78.46.37.135
yum install db4-devel openldap-devel cyrus-sasl-devel pcre-devel mysql-devel postgresql-devel openssl-devel
rpmbuild -bb ~/rpmbuild/SPECS/postfix.spec
</source>
</source>
<source lang="text">
<source lang="text">
(compile output)
; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.2.rc1.fc16 <<>> alteeve.ca @78.46.37.135
Processing files: postfix-debuginfo-2.6.6-3.el6.x86_64
;; global options: +cmd
Checking for unpackaged file(s): /usr/lib/rpm/check-files /root/rpmbuild/BUILDROOT/postfix-2.6.6-3.el6.x86_64
;; Got answer:
Wrote: /root/rpmbuild/RPMS/x86_64/postfix-2.6.6-3.el6.x86_64.rpm
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 46628
Wrote: /root/rpmbuild/RPMS/x86_64/postfix-perl-scripts-2.6.6-3.el6.x86_64.rpm
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 2
Wrote: /root/rpmbuild/RPMS/x86_64/postfix-debuginfo-2.6.6-3.el6.x86_64.rpm
Executing(%clean): /bin/sh -e /var/tmp/rpm-tmp.rymr5C
+ umask 022
+ cd /root/rpmbuild/BUILD
+ cd postfix-2.6.6
+ rm -rf /root/rpmbuild/BUILDROOT/postfix-2.6.6-3.el6.x86_64
+ exit 0
</source>


Install the updated postfix.
;; QUESTION SECTION:
;alteeve.ca. IN A


<source lang="bash">
;; ANSWER SECTION:
rpm -Uvh ~/rpmbuild/RPMS/x86_64/postfix-2.6.6-3.el6.x86_64.rpm ~/rpmbuild/RPMS/x86_64/postfix-perl-scripts-2.6.6-3.el6.x86_64.rpm
alteeve.ca. 600 IN A 192.139.81.121
</source>
<source lang="text">
Preparing...                ########################################### [100%]
  1:postfix                ########################################### [ 50%]
  2:postfix-perl-scripts  ########################################### [100%]
</source>


Now exclude <span class="code">postfix</span> from future updates.
;; AUTHORITY SECTION:
alteeve.ca. 600 IN NS ns2.alteeve.ca.
alteeve.ca. 600 IN NS ns1.alteeve.ca.


<source lang="bash">
;; ADDITIONAL SECTION:
cp /etc/yum.conf /etc/yum.conf.orig
ns1.alteeve.ca. 600 IN A 192.139.81.117
vim /etc/yum.conf
ns2.alteeve.ca. 600 IN A 192.139.81.119
diff -u /etc/yum.conf.orig /etc/yum.conf
 
</source>
;; Query time: 138 msec
<source lang="text">
;; SERVER: 78.46.37.135#53(78.46.37.135)
--- /etc/yum.conf.orig  2012-02-11 16:59:53.720079168 -0500
;; WHEN: Sun Feb 5 14:04:09 2012
+++ /etc/yum.conf      2012-02-11 17:00:47.013331283 -0500
;; MSG SIZE rcvd: 113
@@ -10,6 +10,7 @@
installonly_limit=5
bugtracker_url=http://bugs.centos.org/set_project.php?project_id=16&ref=http://bugs.centos.org/bug_report_page.php?category=yum
  distroverpkg=centos-release
+exclude=postfix*
   
#  This is the default, if you make this bigger yum won't see if the metadata
# is newer on the remote and so you'll "gain" the bandwidth of not having to
</source>
</source>


=== Basic Postfix Configuration ===
Now query <span class="code">google.ca</span> which we obviously are not SOA for.
 
Since we'll be using virtual domains, users, aliases and mailboxes, we'll need to start by commenting out some of the default options in Postfix. By default, Postfix is set up for small numbers of local users, and it only allows connections from the localhost. Our configuration will be more scalable, allowing many domains and users to be stored in the Postgres database.


Comment out the following:
<source lang="bash">vim /etc/postfix/main.cf</source>
<source lang="bash">
<source lang="bash">
# inet_interfaces = localhost
dig google.ca @78.46.37.135
# mydestination = $myhostname, localhost.$mydomain, localhost
# alias_maps = hash:/etc/aliases 
# alias_database = hash:/etc/aliases
</source>
</source>
<source lang="text">
; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.2.rc1.fc16 <<>> google.ca @78.46.37.135
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 18204
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 13, ADDITIONAL: 0


And uncomment/add these:
;; QUESTION SECTION:
<source lang="bash">vim /etc/postfix/main.cf</source>
;google.ca. IN A
<source lang="bash">
inet_interfaces = all  # allows us to connect and test from another machine
mynetworks = 192.168.1.0/32, 127.0.0.0/8  # use the IP or subnet of your test machine here
message_size_limit = 36700160 # increase max message size to 35MB to allow for ~25MB attachments
</source>


=== Setup Virtual Domain Lookup ===
;; ANSWER SECTION:
google.ca. 138 IN A 74.125.232.56


This tells postfix how to find which domains we have.
;; AUTHORITY SECTION:
. 2805 IN NS h.root-servers.net.
. 2805 IN NS c.root-servers.net.
. 2805 IN NS j.root-servers.net.
. 2805 IN NS i.root-servers.net.
. 2805 IN NS b.root-servers.net.
. 2805 IN NS m.root-servers.net.
. 2805 IN NS g.root-servers.net.
. 2805 IN NS d.root-servers.net.
. 2805 IN NS a.root-servers.net.
. 2805 IN NS l.root-servers.net.
. 2805 IN NS f.root-servers.net.
. 2805 IN NS k.root-servers.net.
. 2805 IN NS e.root-servers.net.


<source lang="bash">
;; Query time: 140 msec
vim /etc/postfix/pgsql-virtual-mailbox-domains.cf
;; SERVER: 78.46.37.135#53(78.46.37.135)
</source>
;; WHEN: Sun Feb  5 14:04:31 2012
<source lang="text">
;; MSG SIZE  rcvd: 254
user = alteeve
password = secret
hosts = 127.0.0.1
dbname = an_tools
query = SELECT 1 FROM domains WHERE dom_name='%s'
</source>
</source>


Now tell Postfix to use this new file by appending the following to the main postfix configuration file.
Done!
 
= Email =
 
This is a pretty heavily customized postfix install using a custom schema. It was originally based on [http://www.howtoforge.com/virtual_users_and_domains_with_postfix_debian_etch this Debian Etch] tutorial, but adapted for PostgreSQL. Much time has passed and the operating system is now significantly changed, but it's lineage is thus. A more recent, but still Debian-focused version of the tutorial [http://workaround.org/ispmail/squeeze/big-picture is here]. I also used [http://en.gentoo-wiki.com/wiki/Mail_server_using_Postfix_and_Dovecot this tutorial] to help sort out the PostgreSQL stuff.


<source lang="bash">
This will use a few applications;
vim /etc/postfix/main.cf
* Postfix - The program that receives email.
</source>
* PostgreSQL - The database used to validate the existence of email accounts and validates incoming user credentials.
<source lang="bash">
* Dovecot - Takes email coming from postfix, via amavis, and records them to disk. It also answers requests from users wanting to check their email.
# Tell postfix to validate domains using our postgresql databae via the
* Amavis - Filters incoming email for spam (via spamassassin) and virsus (via clamav)
# pgsql-virtual-mailbox-domains.cf
virtual_mailbox_domains=pgsql:/etc/postfix/pgsql-virtual-mailbox-domains.cf
</source>


Now reload postfix;
We will also be using graylisting, which is a spam fighting tactic where the first email from a given user to one of our users is bounced for a few minutes. Proper mail servers will acknowledge the bound, wait the time and resend. Spam mailers though are usually fire-and-forget and will not resend, thus effectively blocking the spam message. This is a very effective method of blocking spam with minimal chance of losing real mail from real users. Any subsequent message from the user would be allowed through with no delay, provided the user had in fact resent the first message as requested.


<source lang="bash">
== Install ==
/etc/init.d/postfix reload
</source>
<source lang="text">
Reloading postfix:                                        [  OK  ]
</source>


Now we can test that domains resolve. In my case, I will test the look-up for <span class="code">alteeve.ca</span>.
To install the applications;


<source lang="bash">
<source lang="bash">
postmap -q alteeve.ca pgsql:/etc/postfix/pgsql-virtual-mailbox-domains.cf
yum install postfix postfix-perl-scripts dovecot dovecot-pgsql spamassassin postgresql-server postgresql-plperl mutt
</source>
<source lang="text">
1
</source>
</source>


Now make sure it returns nothing when query a bad domain.
== Configuring Postfix ==
 
Installation requires several steps. The AN!Console database must be loaded. Various applications need to be installed. Postfix, Dovecot and helper applications need to be configured and so on.
 
This tutorial uses the following values that you may need to adjust;
* Database name; <span class="code">an_tools</span>
* Database user; <span class="code">alteeve</span>
* Database password; <span class="code">secret</span>
* Database host; <span class="code">127.0.0.1</span>
 
{{note|1=Do not use the database host "<span class="code">localhost</span>" unless you are certain you can connect to the DB using a standard [[unix]] socket.}}
 
=== Building Support for PostgreSQL ===
 
{{warning|1=We need to build our own RPM in order to support postgresql. This means we will have to disable <span class="code">postfix</span> from future updates, placing the onus on us to make sure critical updates are applied. This will require downloading the latest source RPMs, re-enabling postgres and recompile/reinstall.}}
 
Add the source [[RPM]] repository by adding the following;


<source lang="bash">
<source lang="bash">
postmap -q example.com pgsql:/etc/postfix/pgsql-virtual-mailbox-domains.cf
vim /etc/yum.repos.d/CentOS-Base.repo
</source>
</source>
<source lang="text">
<source lang="bash">
<nothing returned>
# Source RPM repository
[base-source]
name=CentOS-$releasever - Base - Source
#mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=os
baseurl=http://vault.centos.org/6.3/os/Source/
gpgcheck=1
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6
</source>
</source>


=== Setup Mailbox Mapping ===
Now download the source RPM for postfix.
 
This section will tell postfix which users for a given domain are valid.


<source lang="bash">
<source lang="bash">
vim /etc/postfix/pgsql-virtual-mailbox-maps.cf
yumdownloader --source postfix
</source>
</source>
<source lang="text">
<source lang="text">
user = alteeve
Loaded plugins: fastestmirror
password = secret
Loading mirror speeds from cached hostfile
hosts = 127.0.0.1
* base: centos.vieth-server.de
dbname = an_tools
* extras: centos.vieth-server.de
query = SELECT 1 FROM email_file WHERE email='%s'
* updates: centos.vieth-server.de
base                              | 3.7 kB    00:00
base-source                        | 1.9 kB    00:00
extras                            | 3.5 kB    00:00
updates                            | 3.5 kB    00:00
No source RPM found for 2:postfix-2.6.6-2.2.el6_1.x86_64
./postfix-2.6.6-2.el6.src.rpm already exists and appears to be complete
nikko:/etc/postfix# rm postfix-2.6.6-2.el6.src.rpm
rm: remove regular file `postfix-2.6.6-2.el6.src.rpm'? y
nikko:/etc/postfix# yumdownloader --source postfix
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
* base: centos.vieth-server.de
* extras: centos.vieth-server.de
* updates: centos.vieth-server.de
No source RPM found for 2:postfix-2.6.6-2.2.el6_1.x86_64
postfix-2.6.6-2.el6.src.rpm        | 3.3 MB    00:00
</source>
</source>


Tell postfix to use this new file when looking up users.
Now that we have the postfix source RPM, we will install it.


<source lang="bash">
<source lang="bash">
vim /etc/postfix/main.cf
rpm -Uvh postfix-2.6.6-2.el6.src.rpm
</source>
</source>
And add:
<source lang="text">
<source lang="text">
# Tell postfix which table to look in when validating a local user via their
  1:postfix               warning: user mockbuild does not exist - using root
# email address.
warning: group mockbuild does not exist - using root
virtual_mailbox_maps=pgsql:/etc/postfix/pgsql-virtual-mailbox-maps.cf
warning: user mockbuild does not exist - using root
warning: group mockbuild does not exist - using root
warning: user mockbuild does not exist - using root
warning: group mockbuild does not exist - using root
warning: user mockbuild does not exist - using root
warning: group mockbuild does not exist - using root
warning: user mockbuild does not exist - using root
warning: group mockbuild does not exist - using root
warning: user mockbuild does not exist - using root
warning: group mockbuild does not exist - using root
warning: user mockbuild does not exist - using root
warning: group mockbuild does not exist - using root
warning: user mockbuild does not exist - using root
warning: group mockbuild does not exist - using root
########################################### [100%]
warning: user mockbuild does not exist - using root
warning: group mockbuild does not exist - using root
warning: user mockbuild does not exist - using root
warning: group mockbuild does not exist - using root
warning: user mockbuild does not exist - using root
warning: group mockbuild does not exist - using root
warning: user mockbuild does not exist - using root
warning: group mockbuild does not exist - using root
</source>
</source>


Reload <span class="code">postfix<span>.
Now edit the <span class="code">.spec</span> file to enable postgres support.


<source lang="bash">
<source lang="bash">
/etc/init.d/postfix reload
cp ~/rpmbuild/SPECS/postfix.spec ~/rpmbuild/SPECS/postfix.spec.orig
vim ~/rpmbuild/SPECS/postfix.spec
</source>
</source>
Make the following changes.
* Enable PostgreSQL support
<source lang="text">
<source lang="text">
Reloading postfix:                                         [  OK  ]
%{?!PGSQL: %define PGSQL 1}
</source>
</source>


Now do a test of a valid user, which should return <span class="code">1</span>, and an invalid user, which should return nothing.
Increment the release version by one.
 
<source lang="bash">
postmap -q digimer@alteeve.ca pgsql:/etc/postfix/pgsql-virtual-mailbox-maps.cf
</source>
<source lang="text">
<source lang="text">
1
Release: 3%{?dist}
</source>
</source>
We can see the changes here:
<source lang="bash">
<source lang="bash">
postmap -q nobody@alteeve.ca pgsql:/etc/postfix/pgsql-virtual-mailbox-maps.cf
diff -u ~/rpmbuild/SPECS/postfix.spec.orig ~/rpmbuild/SPECS/postfix.spec
</source>
</source>
<source lang="text">
<source lang="diff">
<nothing returned>
--- /root/rpmbuild/SPECS/postfix.spec.orig      2012-02-11 16:54:54.495330859 -0500
+++ /root/rpmbuild/SPECS/postfix.spec  2012-02-11 16:53:39.873331101 -0500
@@ -1,5 +1,5 @@
%{?!MYSQL: %define MYSQL 1}
-%{?!PGSQL: %define PGSQL 0}
+%{?!PGSQL: %define PGSQL 1}
%define LDAP 2
%define PCRE 1
%define SASL 2
@@ -35,7 +35,7 @@
Name: postfix
Summary: Postfix Mail Transport Agent
Version: 2.6.6
-Release: 2%{?dist}
+Release: 3%{?dist}
Epoch: 2
Group: System Environment/Daemons
URL: http://www.postfix.org
</source>
</source>


=== Setup Email Forwards ===
Now rebuild the RPM, which means we need to install the build tools.
 
This will allow for email addresses to be forwarded to other email addresses.


<source lang="bash">
<source lang="bash">
vim /etc/postfix/pgsql-virtual-alias-maps.cf
yum groupinstall development
yum install db4-devel openldap-devel cyrus-sasl-devel pcre-devel mysql-devel postgresql-devel openssl-devel
rpmbuild -bb ~/rpmbuild/SPECS/postfix.spec
</source>
</source>
<source lang="text">
<source lang="text">
user = alteeve
(compile output)
password = secret
Processing files: postfix-debuginfo-2.6.6-3.el6.x86_64
hosts = 127.0.0.1
Checking for unpackaged file(s): /usr/lib/rpm/check-files /root/rpmbuild/BUILDROOT/postfix-2.6.6-3.el6.x86_64
dbname = an_tools
Wrote: /root/rpmbuild/RPMS/x86_64/postfix-2.6.6-3.el6.x86_64.rpm
query = SELECT fwd_destination FROM forwards WHERE fwd_source='%s'
Wrote: /root/rpmbuild/RPMS/x86_64/postfix-perl-scripts-2.6.6-3.el6.x86_64.rpm
Wrote: /root/rpmbuild/RPMS/x86_64/postfix-debuginfo-2.6.6-3.el6.x86_64.rpm
Executing(%clean): /bin/sh -e /var/tmp/rpm-tmp.rymr5C
+ umask 022
+ cd /root/rpmbuild/BUILD
+ cd postfix-2.6.6
+ rm -rf /root/rpmbuild/BUILDROOT/postfix-2.6.6-3.el6.x86_64
+ exit 0
</source>
</source>


Now tell postfix where to look.
Install the updated postfix.


<source lang="bash">
<source lang="bash">
vim /etc/postfix/main.cf
rpm -Uvh ~/rpmbuild/RPMS/x86_64/postfix-2.6.6-3.el6.x86_64.rpm ~/rpmbuild/RPMS/x86_64/postfix-perl-scripts-2.6.6-3.el6.x86_64.rpm
</source>
</source>
Add;
<source lang="text">
<source lang="text">
# This tells postfix where to forward incoming email to, where appropriate.
Preparing...                ########################################### [100%]
virtual_alias_maps=pgsql:/etc/postfix/pgsql-virtual-alias-maps.cf
  1:postfix               ########################################### [ 50%]
  2:postfix-perl-scripts  ########################################### [100%]
</source>
</source>


Reload;
Now exclude <span class="code">postfix</span> from future updates.


<source lang="bash">
<source lang="bash">
/etc/init.d/postfix reload
cp /etc/yum.conf /etc/yum.conf.orig
vim /etc/yum.conf
diff -u /etc/yum.conf.orig /etc/yum.conf
</source>
</source>
<source lang="text">
<source lang="text">
Reloading postfix:                                        [ OK ]
--- /etc/yum.conf.orig  2012-02-11 16:59:53.720079168 -0500
</source>
+++ /etc/yum.conf      2012-02-11 17:00:47.013331283 -0500
@@ -10,6 +10,7 @@
installonly_limit=5
bugtracker_url=http://bugs.centos.org/set_project.php?project_id=16&ref=http://bugs.centos.org/bug_report_page.php?category=yum
distroverpkg=centos-release
+exclude=postfix*
# This is the default, if you make this bigger yum won't see if the metadata
  # is newer on the remote and so you'll "gain" the bandwidth of not having to
</source>


I've setup a forward where <span class="code">digimer@alteeve.ca</span> forwards to <span class="code">digimer@alteeve.ca</span>, so we will use that for the next test.
=== Basic Postfix Configuration ===
 
Since we'll be using virtual domains, users, aliases and mailboxes, we'll need to start by commenting out some of the default options in Postfix. By default, Postfix is set up for small numbers of local users, and it only allows connections from the localhost. Our configuration will be more scalable, allowing many domains and users to be stored in the Postgres database.


Comment out the following:
<source lang="bash">vim /etc/postfix/main.cf</source>
<source lang="bash">
<source lang="bash">
postmap -q digimer@alteeve.ca pgsql:/etc/postfix/pgsql-virtual-alias-maps.cf
# inet_interfaces = localhost
# mydestination = $myhostname, localhost.$mydomain, localhost
# alias_maps = hash:/etc/aliases 
# alias_database = hash:/etc/aliases
</source>
</source>
<source lang="text">
 
digimer@alteeve.ca
And uncomment/add these:
<source lang="bash">vim /etc/postfix/main.cf</source>
<source lang="bash">
inet_interfaces = all  # allows us to connect and test from another machine
mynetworks = 192.168.1.0/32, 127.0.0.0/8  # use the IP or subnet of your test machine here
message_size_limit = 36700160 # increase max message size to 35MB to allow for ~25MB attachments
</source>
</source>


An email address with no forward should return nothing.
=== Setup Virtual Domain Lookup ===
 
This tells postfix how to find which domains we have.


<source lang="bash">
<source lang="bash">
postmap -q digimer@alteeve.ca pgsql:/etc/postfix/pgsql-virtual-alias-maps.cf
vim /etc/postfix/pgsql-virtual-mailbox-domains.cf
</source>
</source>
<source lang="text">
<source lang="text">
<nothing returned>
user = alteeve
</source>
password = secret
 
hosts = 127.0.0.1
Excellent.
dbname = an_tools
query = SELECT 1 FROM domains WHERE dom_name='%s'
</source>


=== Setup Postfix Mail Delivery via Dovecot ===
Now tell Postfix to use this new file by appending the following to the main postfix configuration file.


Define a mail transport method in the main Postfix config.
<source lang="bash">vim /etc/postfix/main.cf</source>
<source lang="bash">
<source lang="bash">
# this option is ignored, but may be useful for reference
vim /etc/postfix/main.cf
virtual_mailbox_base=/email
 
# deliver mail via dovecot
virtual_transport = dovecot
 
# prevent postfix from sending multiple recipients per delivery request,
# since dovecot only supports one recipient for each delivery
dovecot_destination_recipient_limit = 1
</source>
</source>
Tell Postfix what virtual_transport "dovecot" means, and how to use it.
<source lang="bash">vim /etc/postfix/master.cf</source>
Append this for RHEL/CentOS 6 machines. For other distros, make sure that /usr/libexec/dovecot/deliver exists and change the path if necessary.
<source lang="bash">
<source lang="bash">
dovecot  unix  -       n      n      -       -       pipe
# Tell postfix to validate domains using our postgresql databae via the
  flags=DRhu user=vmail:vmail argv=/usr/libexec/dovecot/deliver -f ${sender} -d ${recipient}
# pgsql-virtual-mailbox-domains.cf
virtual_mailbox_domains=pgsql:/etc/postfix/pgsql-virtual-mailbox-domains.cf
</source>
</source>


=== Setup Postfix SMTP Authentication using Dovecot ===
Now reload postfix;


Dovecot provides an SMTP authentication mechanism to Postfix called SASL. Enabling this will require users to authenticate against the server before sending mail.
<source lang="bash">vim /etc/postfix/main.cf</source>
Append the following to enable smtp authentication:
<source lang="bash">
<source lang="bash">
smtpd_sasl_auth_enable = yes
/etc/init.d/postfix reload
smtpd_sasl_type = dovecot
</source>
smtpd_sasl_path = private/auth
<source lang="text">
broken_sasl_auth_clients = yes
Reloading postfix:                                        [  OK  ]
 
# allow authenticated users to send mail through Postfix SMTP
# more info at /usr/share/doc/postfix-2.6.6/README_FILES/SMTPD_ACCESS_README
smtpd_recipient_restrictions =
        permit_mynetworks
        permit_sasl_authenticated
        reject_unauth_destination
 
# general smtpd settings
# - reject clients that speak too early
# - reject mail from a null address to many recipients (usually spam)
smtpd_data_restrictions =
        reject_unauth_pipelining
        reject_multi_recipient_bounce
        permit
</source>
</source>


== Configuring Dovecot ==
Now we can test that domains resolve. In my case, I will test the look-up for <span class="code">alteeve.ca</span>.
 
Dovecot handles writing incoming mail to the disk and moving/deleting mail as the user wishes. We're going to create a user and group called <span class="code">vmail</span> which will be used to manage the email stored on disk.


<source lang="bash">
<source lang="bash">
useradd -m vmail
postmap -q alteeve.ca pgsql:/etc/postfix/pgsql-virtual-mailbox-domains.cf
mkdir /email
</source>
chown -R vmail:vmail /email
<source lang="text">
1
</source>
</source>


Dovecot is configured in <span class="code">/etc/dovecot</span> and the main configuration file is <span class="code">dovecot.conf</span>.
Now make sure it returns nothing when query a bad domain.


<source lang="bash">
<source lang="bash">
cp /etc/dovecot/dovecot.conf /etc/dovecot/dovecot.conf.orig
postmap -q example.com pgsql:/etc/postfix/pgsql-virtual-mailbox-domains.cf
vim /etc/dovecot/dovecot.conf
</source>
<source lang="text">
<nothing returned>
</source>
</source>


Dovecot uses <span class="code">.d</span> style configuration files.
=== Setup Mailbox Mapping ===


* Authentication
This section will tell postfix which users for a given domain are valid.


<source lang="bash">
<source lang="bash">
cp /etc/dovecot/conf.d/10-auth.conf /etc/dovecot/conf.d/10-auth.conf.orig
vim /etc/postfix/pgsql-virtual-mailbox-maps.cf
vim /etc/dovecot/conf.d/10-auth.conf
</source>
<source lang="text">
user = alteeve
password = secret
hosts = 127.0.0.1
dbname = an_tools
query = SELECT 1 FROM email_file WHERE email='%s'
</source>
</source>


Tell dovecot to accept plain-text passwords (needed for some old email clients, you may not need to enable this).
Tell postfix to use this new file when looking up users.


<source lang="text">
<source lang="bash">
disable_plaintext_auth = no
vim /etc/postfix/main.cf
</source>
</source>


Tell it not to use the database, and not local users for mail delivery.
And add:


<source lang="text">
<source lang="text">
#!include auth-system.conf.ext
# Tell postfix which table to look in when validating a local user via their
!include auth-sql.conf.ext
# email address.
virtual_mailbox_maps=pgsql:/etc/postfix/pgsql-virtual-mailbox-maps.cf
</source>
</source>


* Mail store
Reload <span class="code">postfix<span>.
 
Tell dovecot where to store the email. The <span class="code">%d</span> tells dovecot to substitute the user's domain name and <span class="code">%n</span> is substituted by the user's email name. For example, <span class="code">digimer@alteeve.ca</span> becomes <span class="code">/email/alteeve.ca/mkelly</span>.


<source lang="bash">
<source lang="bash">
cp /etc/dovecot/conf.d/10-mail.conf /etc/dovecot/conf.d/10-mail.conf.orig
/etc/init.d/postfix reload
vim /etc/dovecot/conf.d/10-mail.conf
</source>
</source>
<source lang="text">
<source lang="text">
mail_location = mbox:/email/%d/%n
Reloading postfix:                                         [  OK  ]
</source>
</source>


=== Dovecot Authentication and SQL Settings ===
Now do a test of a valid user, which should return <span class="code">1</span>, and an invalid user, which should return nothing.
 
We need to tell dovecot where to look for passwords when authenticating a user. Where to look is controlled in the
<span class="code">auth-sql.conf.ext</span> file and is broken down into user and password lookups. We will want to first tell Dovecot which user to use when accessing the mail store on disk.


<source lang="bash">
<source lang="bash">
cp /etc/dovecot/conf.d/auth-sql.conf.ext /etc/dovecot/conf.d/auth-sql.conf.ext.orig
postmap -q digimer@alteeve.ca pgsql:/etc/postfix/pgsql-virtual-mailbox-maps.cf
vim /etc/dovecot/conf.d/auth-sql.conf.ext
</source>
<source lang="text">
1
</source>
<source lang="bash">
postmap -q nobody@alteeve.ca pgsql:/etc/postfix/pgsql-virtual-mailbox-maps.cf
</source>
</source>
<source lang="text">
<source lang="text">
userdb {
<nothing returned>
  driver = static
  args = uid=vmail gid=vmail home=/email/%d/%n allow_all_users=yes
}
</source>
</source>


* Now configure the SQL server access details.
=== Setup Email Forwards ===


{{note|1=Make sure that PostgreSQL has sufficient <span class="code">max_connections</span> set in <span class="code">/var/lib/pgsql/data/postgresql.conf</span> to handle enough connections for the expected number of email connections, plus other connections from other applications.}}
This will allow for email addresses to be forwarded to other email addresses.


<source lang="bash">
<source lang="bash">
cp /usr/share/doc/dovecot-2.0.9/example-config/dovecot-sql.conf.ext /etc/dovecot/dovecot-sql.conf.ext
vim /etc/postfix/pgsql-virtual-alias-maps.cf
chown root:root /etc/dovecot/dovecot-sql.conf.ext
chmod 600 /etc/dovecot/dovecot-sql.conf.ext
vim /etc/dovecot/dovecot-sql.conf.ext
</source>
</source>
Tell dovecot to use PostgreSQL.
<source lang="text">
<source lang="text">
driver = pgsql
user = alteeve
password = secret
hosts = 127.0.0.1
dbname = an_tools
query = SELECT fwd_destination FROM forwards WHERE fwd_source='%s'
</source>
</source>


Configure the connection string.
Now tell postfix where to look.


{{note|1=If your database uses a password with a space character in it, quote the password. Ie: <span class="code">password='super secret'</span>.}}
<source lang="bash">
 
vim /etc/postfix/main.cf
<source lang="text">
connect = host=127.0.0.1 dbname=an_tools user=alteeve password=secret
</source>
</source>


Tell dovecot to accept plain-text passwords (this is needed for some stupid MS clients, this will probably change soon).
Add;


<source lang="text">
<source lang="text">
default_pass_scheme = PLAIN
# This tells postfix where to forward incoming email to, where appropriate.
virtual_alias_maps=pgsql:/etc/postfix/pgsql-virtual-alias-maps.cf
</source>
</source>


Tell dovecot how to pull use the user's password.
Reload;


<source lang="bash">
/etc/init.d/postfix reload
</source>
<source lang="text">
<source lang="text">
password_query = SELECT email, password FROM email_password WHERE email='%u'
Reloading postfix:                                        [  OK  ]
</source>
</source>


The last thing to setup is the user query. The query needs to return the [[UID]] and [[GID]] of the <span class="code">vmail</span> user we setup earlier. To get it, you can use the <span class="code">id</span> command.
I've setup a forward where <span class="code">digimer@alteeve.ca</span> forwards to <span class="code">digimer@alteeve.ca</span>, so we will use that for the next test.


<source lang="bash">
<source lang="bash">
id vmail
postmap -q digimer@alteeve.ca pgsql:/etc/postfix/pgsql-virtual-alias-maps.cf
</source>
</source>
<source lang="text">
<source lang="text">
uid=503(vmail) gid=503(vmail) groups=503(vmail)
digimer@alteeve.ca
</source>
</source>


The numbers we want are <span class="code">503</span> and <span class="code">503</span> for the UID and GID, respectively. Knowing this, we can set the userdb SQL string.
An email address with no forward should return nothing.


<source lang="bash">
postmap -q digimer@alteeve.ca pgsql:/etc/postfix/pgsql-virtual-alias-maps.cf
</source>
<source lang="text">
<source lang="text">
user_query = SELECT '/email/'||file AS email_dir, '503' AS uid, '503' AS gid FROM email_file WHERE email='%u'
<nothing returned>
</source>
</source>


=== Configure Listener Sockets ===
Excellent.
 
=== Setup Postfix Mail Delivery via Dovecot ===


Setup the authentication socket to allow the vmail user. This will allow Dovecot to access the user authentication socket.
Define a mail transport method in the main Postfix config.
<source lang="bash">vim /etc/dovecot/conf.d/10-master.conf</source>
<source lang="bash">vim /etc/postfix/main.cf</source>
<source lang="bash">
<source lang="bash">
  unix_listener auth-userdb {
# this option is ignored, but may be useful for reference
    mode = 0600
virtual_mailbox_base=/email
    user = vmail
 
    group = vmail
# deliver mail via dovecot
  }
virtual_transport = dovecot
 
# prevent postfix from sending multiple recipients per delivery request,
# since dovecot only supports one recipient for each delivery
dovecot_destination_recipient_limit = 1
</source>
</source>


Configure Dovecot to authenticate Postfix SMTP requests.
Tell Postfix what virtual_transport "dovecot" means, and how to use it.
<source lang="bash">vim /etc/dovecot/conf.d/10-master.conf</source>
<source lang="bash">vim /etc/postfix/master.cf</source>
Append this for RHEL/CentOS 6 machines. For other distros, make sure that /usr/libexec/dovecot/deliver exists and change the path if necessary.
<source lang="bash">
<source lang="bash">
  unix_listener smtp-auth {
dovecot  unix  -      n      n      -      -       pipe
    mode = 0600
  flags=DRhu user=vmail:vmail argv=/usr/libexec/dovecot/deliver -f ${sender} -d ${recipient}
    user = postfix
    group = postfix
    path = /var/spool/postfix/private/auth
  }
</source>
</source>


=== Enable Logging ===
=== Setup Postfix SMTP Authentication using Dovecot ===


This is very useful for debugging an initial setup. It will place details about login attempts in /var/log/maillog.
Dovecot provides an SMTP authentication mechanism to Postfix called SASL. Enabling this will require users to authenticate against the server before sending mail.


<source lang="bash">vim /etc/dovecot/conf.d/10-logging.conf</source>
<source lang="bash">vim /etc/postfix/main.cf</source>
Append the following to enable smtp authentication:
<source lang="bash">
<source lang="bash">
log_path = syslog
smtpd_sasl_auth_enable = yes
auth_verbose = yes
smtpd_sasl_type = dovecot
auth_debug = yes
smtpd_sasl_path = private/auth
mail_debug = yes
broken_sasl_auth_clients = yes
 
# allow authenticated users to send mail through Postfix SMTP
# more info at /usr/share/doc/postfix-2.6.6/README_FILES/SMTPD_ACCESS_README
smtpd_recipient_restrictions =
        permit_mynetworks
        permit_sasl_authenticated
        reject_unauth_destination
 
# general smtpd settings
# - reject clients that speak too early
# - reject mail from a null address to many recipients (usually spam)
smtpd_data_restrictions =
        reject_unauth_pipelining
        reject_multi_recipient_bounce
        permit
</source>
</source>


At this point, it's a good idea to restart the Postfix and Dovecot services, and test out the basic configuration.
== Configuring Dovecot ==
 
Dovecot handles writing incoming mail to the disk and moving/deleting mail as the user wishes. We're going to create a user and group called <span class="code">vmail</span> which will be used to manage the email stored on disk.
 
<source lang="bash">
<source lang="bash">
service postfix restart
useradd -m vmail
service dovecot restart
mkdir /email
chown -R vmail:vmail /email
</source>
</source>


Watch the maillog while attempting to authenticate with an email client like Thunderbird.
Dovecot is configured in <span class="code">/etc/dovecot</span> and the main configuration file is <span class="code">dovecot.conf</span>.
 
<source lang="bash">
<source lang="bash">
tail -f /var/log/maillog
cp /etc/dovecot/dovecot.conf /etc/dovecot/dovecot.conf.orig
vim /etc/dovecot/dovecot.conf
</source>
</source>


If basic authentication is working, we can go ahead and add another layer of complexity on top of it: SSL.
Dovecot uses <span class="code">.d</span> style configuration files.


== SSL/TLS ==
* Authentication


Add TLS support to Postfix, to encrypt SMTP authentication traffic.
<source lang="bash">
<source lang="bash">vim /etc/postfix/main.cf</source>
cp /etc/dovecot/conf.d/10-auth.conf /etc/dovecot/conf.d/10-auth.conf.orig
<source lang="bash">
vim /etc/dovecot/conf.d/10-auth.conf
smtpd_use_tls = yes
smtpd_tls_auth_only = yes
smtpd_tls_cert_file = /etc/pki/CA/ssl_mail.alteeve.ca.crt
smtpd_tls_key_file = /etc/pki/CA/private/mail.alteeve.ca.key
smtpd_tls_loglevel = 1
</source>
</source>


Add TLS support to Dovecot, to encrypt IMAP authentication traffic.
Tell dovecot to accept plain-text passwords (needed for some old email clients, you may not need to enable this).
<source lang="bash">vim /etc/dovecot/conf.d/10-ssl.conf </source>
<source lang="bash">
ssl = yes


# PEM encoded X.509 SSL/TLS certificate and private key.
<source lang="text">
ssl_cert = /etc/pki/CA/ssl_mail.alteeve.ca.crt
disable_plaintext_auth = no
ssl_key = /etc/pki/CA/private/mail.alteeve.ca.key
</source>


# PEM encoded trusted certificate authority. Otherwise your CA will be untrusted.
Tell it not to use the database, and not local users for mail delivery.
# This is the intermediary certificate.
ssl_ca = /etc/pki/CA/RapidSSL_CA_bundle_alteeve.ca.pem
</source>


Dovecot prefers the following permissions for SSL certs, so set them accordingly.
<source lang="text">
<source lang="bash">
#!include auth-system.conf.ext
chmod 0444 /etc/pki/CA/ssl_mail.alteeve.ca.crt
!include auth-sql.conf.ext
chmod 0400 /etc/pki/CA/private/mail.alteeve.ca.key
chmod 0400 /etc/pki/CA/RapidSSL_CA_bundle_alteeve.ca.pem
</source>
</source>


Restart Postfix and Dovecot, then change your Thunderbird server options to 'STARTTLS'. If you're still able to connect to the mail server and send mail, proceed to the next section.
* Mail store


== User Password Encryption ==
Tell dovecot where to store the email. The <span class="code">%d</span> tells dovecot to substitute the user's domain name and <span class="code">%n</span> is substituted by the user's email name. For example, <span class="code">digimer@alteeve.ca</span> becomes <span class="code">/email/alteeve.ca/mkelly</span>.


In addition to SSL/TSL, which only encrypts the transport of user credentials, we're also  going to encrypt the passwords themselves. This will avoid storing any plaintext passwords in the Postgres database.
<source lang="bash">
 
cp /etc/dovecot/conf.d/10-mail.conf /etc/dovecot/conf.d/10-mail.conf.orig
<source lang="bash">vim /etc/dovecot/conf.d/10-auth.conf</source>
vim /etc/dovecot/conf.d/10-mail.conf
Remove the "plain" authentication, and replace with cram-md5.
</source>
<source lang="bash">
<source lang="text">
disable_plaintext_auth = yes
mail_location = mbox:/email/%d/%n
auth_mechanisms = cram-md5
</source>
</source>


Any user credentials that were previously stored in plaintext will no longer work. To encrypt your password in a way that Dovecot recognizes, use the following command:
=== Dovecot Authentication and SQL Settings ===
<source lang="bash">doveadm -v pw -s CRAM-MD5 -p mypassword</source>
It will return a hash like this.
<source lang="bash">
{CRAM-MD5}de5924752ad74e36bc271a8dc7fad4b2d341f21f05382f20dedf1fdfbd5a1717</source>


Take the entire hash, including the '{CRAM-MD5}' portion, and use it to replace the password entry in the database for that user. This will allow Dovecot to authenticate the user using the CRAM-MD5 auth mechanism.
We need to tell dovecot where to look for passwords when authenticating a user. Where to look is controlled in the  
 
<span class="code">auth-sql.conf.ext</span> file and is broken down into user and password lookups. We will want to first tell Dovecot which user to use when accessing the mail store on disk.
To automate this process for all users in the database, you can look at the number of userid's there are and loop through them, encrypting and replacing each password.


<source lang="bash">
<source lang="bash">
#!/bin/bash
cp /etc/dovecot/conf.d/auth-sql.conf.ext /etc/dovecot/conf.d/auth-sql.conf.ext.orig
#
vim /etc/dovecot/conf.d/auth-sql.conf.ext
# a script to encrypt the users.usr_password values of the an_tools database
</source>
<source lang="text">
userdb {
  driver = static
  args = uid=vmail gid=vmail home=/email/%d/%n allow_all_users=yes
}
</source>


export PGUSER="alteeve"
* Now configure the SQL server access details.
export PGPASSWORD='secret'


for usrid in {1..219}; do
{{note|1=Make sure that PostgreSQL has sufficient <span class="code">max_connections</span> set in <span class="code">/var/lib/pgsql/data/postgresql.conf</span> to handle enough connections for the expected number of email connections, plus other connections from other applications.}}


    # grab the user's password, removing whitespace
<source lang="bash">
    usrpass=$(psql -d an_tools -c "SELECT users.usr_password FROM users WHERE users.usr_id=$usrid;"\
cp /usr/share/doc/dovecot-2.0.9/example-config/dovecot-sql.conf.ext /etc/dovecot/dovecot-sql.conf.ext
| sed -n 3p | sed -e 's/^[ ]*//')
chown root:root /etc/dovecot/dovecot-sql.conf.ext
chmod 600 /etc/dovecot/dovecot-sql.conf.ext
vim /etc/dovecot/dovecot-sql.conf.ext
</source>


    if [[ "$usrpass" == *CRAM* ]]; then
Tell dovecot to use PostgreSQL.
        echo "Password for user #$usrid is already encrypted; skipping."
    else
        # encrypt and surround in single quotes for psql
        encrypted=\'$(doveadm -v pw -s CRAM-MD5 -p "$usrpass")\'
        echo "old password: [$usrpass] ; encrypted: $encrypted"


        # set password to encrypted value
<source lang="text">
        psql -d an_tools -c "UPDATE users SET usr_password=$encrypted WHERE usr_id=$usrid;"
driver = pgsql
    fi
done
 
unset PGUSER
unset PGPASSWORD
</source>
</source>


== Postgrey Greylisting ==
Configure the connection string.


Enabling postgrey for anti-spam greylisting.
{{note|1=If your database uses a password with a space character in it, quote the password. Ie: <span class="code">password='super secret'</span>.}}


First install the RPMForge repos. (See [http://dak1n1.com/blog/3-getting-more-from-yum-with-rpmforge-and-epel-repos Dakini's blog] for details.)
<source lang="text">
connect = host=127.0.0.1 dbname=an_tools user=alteeve password=secret
</source>


<source lang="bash">yum -y install postgrey</source>
Tell dovecot to accept plain-text passwords (this is needed for some stupid MS clients, this will probably change soon).


Create the config file with the following options. This will delay mail from untrusted sources by 6 minutes. A legitimate mailserver will resend the request after that time, and be allowed through. But spam is generally sent out only once, so those messages will drop.
<source lang="text">
<source lang="bash">vim /etc/sysconfig/postgrey</source>
default_pass_scheme = PLAIN
<source lang="bash">OPTIONS="--unix=/var/spool/postfix/postgrey/socket --delay=360"</source>
</source>


Ensure that Postgrey starts on boot.
Tell dovecot how to pull use the user's password.
<source lang="bash">chkconfig --levels 345 postgrey on</source>


<source lang="bash">/etc/postfix/main.cf</source>
<source lang="text">
password_query = SELECT email, password FROM email_password WHERE email='%u'
</source>


Configure Postfix to check SMTP requests through Postgrey. Postgrey will decide if the mail should be blocked or accepted.
The last thing to setup is the user query. The query needs to return the [[UID]] and [[GID]] of the <span class="code">vmail</span> user we setup earlier. To get it, you can use the <span class="code">id</span> command.
<source lang="bash">
smtpd_recipient_restrictions =
        permit_mynetworks
        permit_sasl_authenticated
        reject_unauth_destination
        check_policy_service unix:postgrey/socket</source>


Restart Postfix and Postgrey to take affect.
<source lang="bash">
<source lang="bash">
service postgrey start
id vmail
service postfix restart
</source>
<source lang="text">
uid=503(vmail) gid=503(vmail) groups=503(vmail)
</source>
</source>


== RoundCube Web Mail ==
The numbers we want are <span class="code">503</span> and <span class="code">503</span> for the UID and GID, respectively. Knowing this, we can set the userdb SQL string.


Install the packages (these require the [[EPEL]] repo);
<source lang="text">
user_query = SELECT '/email/'||file AS email_dir, '503' AS uid, '503' AS gid FROM email_file WHERE email='%u'
</source>


<source lang="bash">
=== Configure Listener Sockets ===
yum install roundcubemail php-pear-MDB2-Driver-pgsql
</source>


You need to set the timezone in the <span class="code">/etc/php.ini</span> file.
Setup the authentication socket to allow the vmail user. This will allow Dovecot to access the user authentication socket.  


<source lang="bash">
<source lang="bash">
cp /etc/php.ini /etc/php.ini.orig
vim /etc/dovecot/conf.d/10-master.conf
vim /etc/php.ini
</source>
<source lang="bash">
  unix_listener auth-userdb {
    mode = 0600
    user = vmail
    group = vmail
  }
</source>
</source>


Set <span class="code">date.timezone</span> value. If you aren't sure of the format or name of your timezone, run <span class="code">tzselect</span> and follow the prompts. We want <span class="code">America/Toronto</span>.
Configure Dovecot to authenticate Postfix SMTP requests.


<source lang="bash">
<source lang="bash">
diff -u /etc/php.ini.orig /etc/php.ini
vim /etc/dovecot/conf.d/10-master.conf
</source>
</source>
<source lang="diff">
<source lang="bash">
--- /etc/php.ini.orig 2012-08-18 22:27:05.244670258 -0400
  unix_listener smtp-auth {
+++ /etc/php.ini 2012-08-18 21:49:37.926938864 -0400
    mode = 0600
@@ -943,7 +943,7 @@
    user = postfix
[Date]
    group = postfix
; Defines the default timezone used by the date functions
    path = /var/spool/postfix/private/auth
; http://www.php.net/manual/en/datetime.configuration.php#ini.date.timezone
  }
-;date.timezone =  
+date.timezone = America/Toronto
; http://www.php.net/manual/en/datetime.configuration.php#ini.date.default-latitude
;date.default_latitude = 31.7667
</source>
</source>


Create the database for roundcube
Tell Dovecot to increase the number of allowed connections and child processes to handle heavier loads.


<source lang="bash">
<source lang="bash">
su - postgres
vim /etc/dovecot/conf.d/10-master.conf
createdb -O alteeve -E UNICODE roundcubemail
psql -U alteeve -D roundcubemail
\i /usr/share/doc/roundcubemail-0.5.4/SQL/postgres.initial.sql
</source>
</source>
Edit main configuration file
<source lang="bash">
<source lang="bash">
vim /etc/roundcubemail/main.inc.php
default_process_limit = 200
default_client_limit = 2000
</source>
</source>
=== Enable Logging ===
This is very useful for debugging an initial setup. It will place details about login attempts in /var/log/maillog.
<source lang="bash">vim /etc/dovecot/conf.d/10-logging.conf</source>
<source lang="bash">
<source lang="bash">
$rcmail_config['default_host'] = 'localhost';
log_path = syslog
$rcmail_config['smtp_server'] = 'tls://mail.alteeve.ca';
auth_verbose = yes
$rcmail_config['smtp_user'] = '%u';
auth_debug = yes
$rcmail_config['smtp_pass'] = '%p';
mail_debug = yes
$rcmail_config['smtp_auth_type'] = 'CRAM-MD5';
$rcmail_config['force_https'] = true;
$rcmail_config['use_https'] = true;
$rcmail_config['login_autocomplete'] = 1;
</source>
</source>


Now setup roundcube for connecting to our DB;
At this point, it's a good idea to restart the Postfix and Dovecot services, and test out the basic configuration.
<source lang="bash">
service postfix restart
service dovecot restart
</source>


Watch the maillog while attempting to authenticate with an email client like Thunderbird.
<source lang="bash">
<source lang="bash">
cp /etc/roundcubemail/db.inc.php /etc/roundcubemail/db.inc.php.orig
tail -f /var/log/maillog
vim /etc/roundcubemail/db.inc.php
</source>
</source>


Now set the connection string. Note to switch the DB driver to <span class="code">pgsql</span>.
If basic authentication is working, we can go ahead and add another layer of complexity on top of it: SSL.
 
== SSL/TLS ==


Add TLS support to Postfix, to encrypt SMTP authentication traffic.
<source lang="bash">vim /etc/postfix/main.cf</source>
<source lang="bash">
<source lang="bash">
diff -u /etc/roundcubemail/db.inc.php.orig /etc/roundcubemail/db.inc.php
smtpd_use_tls = yes
</source>
smtpd_tls_auth_only = yes
<source lang="diff">
smtpd_tls_cert_file = /etc/pki/CA/ssl_mail.alteeve.ca.crt
--- /etc/roundcubemail/db.inc.php.orig 2012-05-06 13:53:52.000000000 -0400
smtpd_tls_key_file = /etc/pki/CA/private/mail.alteeve.ca.key
+++ /etc/roundcubemail/db.inc.php 2012-05-06 15:45:30.000000000 -0400
smtpd_tls_loglevel = 1
@@ -18,7 +18,7 @@
// format is db_provider://user:password@host/database
// For examples see http://pear.php.net/manual/en/package.database.mdb2.intro-dsn.php
-$rcmail_config['db_dsnw'] = 'mysql://roundcube:pass@localhost/roundcubemail';
+$rcmail_config['db_dsnw'] = 'pgsql://alteeve:secret@localhost/roundcubemail';
// postgres example: 'pgsql://roundcube:pass@localhost/roundcubemail';
// Warning: for SQLite use absolute path in DSN:
</source>
</source>


Now setup roundcube to communicate with the mail server.
Add TLS support to Dovecot, to encrypt IMAP authentication traffic.
<source lang="bash">vim /etc/dovecot/conf.d/10-ssl.conf </source>
<source lang="bash">
ssl = yes
 
# PEM encoded X.509 SSL/TLS certificate and private key.
ssl_cert = </etc/pki/CA/ssl_mail.alteeve.ca.crt
ssl_key = </etc/pki/CA/private/mail.alteeve.ca.key
 
# PEM encoded trusted certificate authority. Otherwise your CA will be untrusted.
# This is the intermediary certificate.
ssl_ca = </etc/pki/CA/RapidSSL_CA_bundle_alteeve.ca.pem
</source>


Dovecot prefers the following permissions for SSL certs, so set them accordingly.
<source lang="bash">
<source lang="bash">
cp /etc/roundcubemail/main.inc.php /etc/roundcubemail/main.inc.php.orig
chmod 0444 /etc/pki/CA/ssl_mail.alteeve.ca.crt
vim /etc/roundcubemail/main.inc.php
chmod 0400 /etc/pki/CA/private/mail.alteeve.ca.key
chmod 0400 /etc/pki/CA/RapidSSL_CA_bundle_alteeve.ca.pem
</source>
</source>


There are several variables to set. Our server will talk to <span class="code">localhost</span> using <span class="code">[[tls]]</span> on port <span class="code">587</span> using <span class="code">[[CRAM_MD5]]</span> encryption. We use, and require, <span class="code">[[https]]</span> connections. There are a couple special values for querying the user's name and password from the database. Finally, we want to enable the user's browser's auto-complete functions and set the name shown to the users. Once all set, the <span class="code">diff</span> should be similar to the one below.
Restart Postfix and Dovecot, then change your Thunderbird server options to 'STARTTLS'. If you're still able to connect to the mail server and send mail, proceed to the next section.


<source lang="bash">
== User Password Encryption ==
diff -u /etc/roundcubemail/main.inc.php.orig /etc/roundcubemail/main.inc.php
 
</source>
In addition to SSL/TSL, which only encrypts the transport of user credentials, we're also  going to encrypt the passwords themselves. This will avoid storing any plaintext passwords in the Postgres database.
<source lang="diff">
 
--- /etc/roundcubemail/main.inc.php.orig 2012-05-06 13:53:59.000000000 -0400
<source lang="bash">vim /etc/dovecot/conf.d/10-auth.conf</source>
+++ /etc/roundcubemail/main.inc.php 2012-07-06 14:59:07.000000000 -0400
Remove the "plain" authentication, and replace with cram-md5.
@@ -65,7 +65,7 @@
<source lang="bash">
// %n - http hostname ($_SERVER['SERVER_NAME'])
disable_plaintext_auth = yes
// %d - domain (http hostname without the first part)
auth_mechanisms = cram-md5
// For example %n = mail.domain.tld, %d = domain.tld
</source>
-$rcmail_config['default_host'] = '';
 
+$rcmail_config['default_host'] = 'localhost';
Any user credentials that were previously stored in plaintext will no longer work. To encrypt your password in a way that Dovecot recognizes, use the following command:
<source lang="bash">doveadm -v pw -s CRAM-MD5 -p mypassword</source>
// TCP port used for IMAP connections
It will return a hash like this.
$rcmail_config['default_port'] = 143;
<source lang="bash">
@@ -121,22 +121,22 @@
{CRAM-MD5}de5924752ad74e36bc271a8dc7fad4b2d341f21f05382f20dedf1fdfbd5a1717</source>
// %d - domain (http hostname without the first part)
 
// %z - IMAP domain (IMAP hostname without the first part)
Take the entire hash, including the '{CRAM-MD5}' portion, and use it to replace the password entry in the database for that user. This will allow Dovecot to authenticate the user using the CRAM-MD5 auth mechanism.
// For example %n = mail.domain.tld, %d = domain.tld
 
-$rcmail_config['smtp_server'] = '';
To automate this process for all users in the database, you can look at the number of userid's there are and loop through them, encrypting and replacing each password.
+$rcmail_config['smtp_server'] = 'tls://mail.alteeve.ca';
 
<source lang="bash">
// SMTP port (default is 25; 465 for SSL)
#!/bin/bash
-$rcmail_config['smtp_port'] = 25;
#
+$rcmail_config['smtp_port'] = 587;
# a script to encrypt the users.usr_password values of the an_tools database
 
// SMTP username (if required) if you use %u as the username Roundcube
export PGUSER="alteeve"
// will use the current username for login
export PGPASSWORD='secret'
-$rcmail_config['smtp_user'] = '';
 
+$rcmail_config['smtp_user'] = '%u';
for usrid in {1..219}; do
 
// SMTP password (if required) if you use %p as the password Roundcube
    # grab the user's password, removing whitespace
// will use the current user's password for login
    usrpass=$(psql -d an_tools -c "SELECT users.usr_password FROM users WHERE users.usr_id=$usrid;"\
-$rcmail_config['smtp_pass'] = '';
| sed -n 3p | sed -e 's/^[ ]*//')
+$rcmail_config['smtp_pass'] = '%p';
 
    if [[ "$usrpass" == *CRAM* ]]; then
// SMTP AUTH type (DIGEST-MD5, CRAM-MD5, LOGIN, PLAIN or empty to use
        echo "Password for user #$usrid is already encrypted; skipping."
// best server supported one)
    else
-$rcmail_config['smtp_auth_type'] = '';
        # encrypt and surround in single quotes for psql
+$rcmail_config['smtp_auth_type'] = 'CRAM-MD5';
        encrypted=\'$(doveadm -v pw -s CRAM-MD5 -p "$usrpass")\'
        echo "old password: [$usrpass] ; encrypted: $encrypted"
// Optional SMTP authentication identifier to be used as authorization proxy
 
$rcmail_config['smtp_auth_cid'] = null;
        # set password to encrypted value
@@ -179,16 +179,16 @@
        psql -d an_tools -c "UPDATE users SET usr_password=$encrypted WHERE usr_id=$usrid;"
// enforce connections over https
    fi
// with this option enabled, all non-secure connections will be redirected.
done
// set the port for the ssl connection as value of this option if it differs from the default 443
 
-$rcmail_config['force_https'] = false;
unset PGUSER
+$rcmail_config['force_https'] = true;
unset PGPASSWORD
   
</source>
  // tell PHP that it should work as under secure connection
 
// even if it doesn't recognize it as secure ($_SERVER['HTTPS'] is not set)
== Postgrey Greylisting ==
// e.g. when you're running Roundcube behind a https proxy
 
-$rcmail_config['use_https'] = false;
Enabling postgrey for anti-spam greylisting.
+$rcmail_config['use_https'] = true;
 
First install the RPMForge repos. (See [http://dak1n1.com/blog/3-getting-more-from-yum-with-rpmforge-and-epel-repos Dakini's blog] for details.)
 
<source lang="bash">yum -y install postgrey</source>
 
Create the config file with the following options. This will delay mail from untrusted sources by 6 minutes. A legitimate mailserver will resend the request after that time, and be allowed through. But spam is generally sent out only once, so those messages will drop.
<source lang="bash">vim /etc/sysconfig/postgrey</source>
<source lang="bash">OPTIONS="--unix=/var/spool/postfix/postgrey/socket --delay=360"</source>
 
Ensure that Postgrey starts on boot.
<source lang="bash">chkconfig --levels 345 postgrey on</source>
 
<source lang="bash">/etc/postfix/main.cf</source>
 
Configure Postfix to check SMTP requests through Postgrey. Postgrey will decide if the mail should be blocked or accepted.
<source lang="bash">
smtpd_recipient_restrictions =
        permit_mynetworks
        permit_sasl_authenticated
        reject_unauth_destination
        check_policy_service unix:postgrey/socket</source>
 
Restart Postfix and Postgrey to take affect.
<source lang="bash">
service postgrey start
service postfix restart
</source>
 
== RoundCube Web Mail ==
 
Install the packages (these require the [[EPEL]] repo);
 
<source lang="bash">
yum install roundcubemail php-pear-MDB2-Driver-pgsql
</source>
 
You need to set the timezone in the <span class="code">/etc/php.ini</span> file.
 
<source lang="bash">
cp /etc/php.ini /etc/php.ini.orig
vim /etc/php.ini
</source>
 
Set <span class="code">date.timezone</span> value. If you aren't sure of the format or name of your timezone, run <span class="code">tzselect</span> and follow the prompts. We want <span class="code">America/Toronto</span>.
 
<source lang="bash">
diff -u /etc/php.ini.orig /etc/php.ini
</source>
<source lang="diff">
--- /etc/php.ini.orig 2012-08-18 22:27:05.244670258 -0400
+++ /etc/php.ini 2012-08-18 21:49:37.926938864 -0400
@@ -943,7 +943,7 @@
[Date]
  ; Defines the default timezone used by the date functions
  ; http://www.php.net/manual/en/datetime.configuration.php#ini.date.timezone
-;date.timezone =  
+date.timezone = America/Toronto
   
   
  // Allow browser-autocompletion on login form.
; http://www.php.net/manual/en/datetime.configuration.php#ini.date.default-latitude
  // 0 - disabled, 1 - username and host only, 2 - username, host, password
;date.default_latitude = 31.7667
</source>
 
Create the database for roundcube
 
<source lang="bash">
su - postgres
createdb -O alteeve -E UNICODE roundcubemail
psql -U alteeve -D roundcubemail
\i /usr/share/doc/roundcubemail-0.5.4/SQL/postgres.initial.sql
</source>
 
Edit main configuration file
 
<source lang="bash">
vim /etc/roundcubemail/main.inc.php
</source>
<source lang="bash">
$rcmail_config['default_host'] = 'localhost';
$rcmail_config['smtp_server'] = 'tls://mail.alteeve.ca';
$rcmail_config['smtp_user'] = '%u';
$rcmail_config['smtp_pass'] = '%p';
$rcmail_config['smtp_auth_type'] = 'CRAM-MD5';
$rcmail_config['force_https'] = true;
$rcmail_config['use_https'] = true;
$rcmail_config['login_autocomplete'] = 1;
</source>
 
Now setup roundcube for connecting to our DB;
 
<source lang="bash">
cp /etc/roundcubemail/db.inc.php /etc/roundcubemail/db.inc.php.orig
vim /etc/roundcubemail/db.inc.php
</source>
 
Now set the connection string. Note to switch the DB driver to <span class="code">pgsql</span>.
 
<source lang="bash">
diff -u /etc/roundcubemail/db.inc.php.orig /etc/roundcubemail/db.inc.php
</source>
<source lang="diff">
--- /etc/roundcubemail/db.inc.php.orig 2012-05-06 13:53:52.000000000 -0400
+++ /etc/roundcubemail/db.inc.php 2012-05-06 15:45:30.000000000 -0400
@@ -18,7 +18,7 @@
// format is db_provider://user:password@host/database
// For examples see http://pear.php.net/manual/en/package.database.mdb2.intro-dsn.php
-$rcmail_config['db_dsnw'] = 'mysql://roundcube:pass@localhost/roundcubemail';
+$rcmail_config['db_dsnw'] = 'pgsql://alteeve:secret@localhost/roundcubemail';
// postgres example: 'pgsql://roundcube:pass@localhost/roundcubemail';
// Warning: for SQLite use absolute path in DSN:
</source>
 
Now setup roundcube to communicate with the mail server.
 
<source lang="bash">
cp /etc/roundcubemail/main.inc.php /etc/roundcubemail/main.inc.php.orig
vim /etc/roundcubemail/main.inc.php
</source>
 
There are several variables to set. Our server will talk to <span class="code">localhost</span> using <span class="code">[[tls]]</span> on port <span class="code">587</span> using <span class="code">[[CRAM_MD5]]</span> encryption. We use, and require, <span class="code">[[https]]</span> connections. There are a couple special values for querying the user's name and password from the database. Finally, we want to enable the user's browser's auto-complete functions and set the name shown to the users. Once all set, the <span class="code">diff</span> should be similar to the one below.
 
<source lang="bash">
diff -u /etc/roundcubemail/main.inc.php.orig /etc/roundcubemail/main.inc.php
</source>
<source lang="diff">
--- /etc/roundcubemail/main.inc.php.orig 2012-05-06 13:53:59.000000000 -0400
+++ /etc/roundcubemail/main.inc.php 2012-07-06 14:59:07.000000000 -0400
@@ -65,7 +65,7 @@
// %n - http hostname ($_SERVER['SERVER_NAME'])
// %d - domain (http hostname without the first part)
// For example %n = mail.domain.tld, %d = domain.tld
-$rcmail_config['default_host'] = '';
+$rcmail_config['default_host'] = 'localhost';
// TCP port used for IMAP connections
$rcmail_config['default_port'] = 143;
@@ -121,22 +121,22 @@
// %d - domain (http hostname without the first part)
// %z - IMAP domain (IMAP hostname without the first part)
// For example %n = mail.domain.tld, %d = domain.tld
-$rcmail_config['smtp_server'] = '';
+$rcmail_config['smtp_server'] = 'tls://mail.alteeve.ca';
// SMTP port (default is 25; 465 for SSL)
-$rcmail_config['smtp_port'] = 25;
+$rcmail_config['smtp_port'] = 587;
// SMTP username (if required) if you use %u as the username Roundcube
// will use the current username for login
-$rcmail_config['smtp_user'] = '';
+$rcmail_config['smtp_user'] = '%u';
// SMTP password (if required) if you use %p as the password Roundcube
// will use the current user's password for login
-$rcmail_config['smtp_pass'] = '';
+$rcmail_config['smtp_pass'] = '%p';
// SMTP AUTH type (DIGEST-MD5, CRAM-MD5, LOGIN, PLAIN or empty to use
// best server supported one)
-$rcmail_config['smtp_auth_type'] = '';
+$rcmail_config['smtp_auth_type'] = 'CRAM-MD5';
// Optional SMTP authentication identifier to be used as authorization proxy
$rcmail_config['smtp_auth_cid'] = null;
@@ -179,16 +179,16 @@
// enforce connections over https
// with this option enabled, all non-secure connections will be redirected.
// set the port for the ssl connection as value of this option if it differs from the default 443
-$rcmail_config['force_https'] = false;
+$rcmail_config['force_https'] = true;
// tell PHP that it should work as under secure connection
// even if it doesn't recognize it as secure ($_SERVER['HTTPS'] is not set)
// e.g. when you're running Roundcube behind a https proxy
-$rcmail_config['use_https'] = false;
+$rcmail_config['use_https'] = true;
  // Allow browser-autocompletion on login form.
  // 0 - disabled, 1 - username and host only, 2 - username, host, password
-$rcmail_config['login_autocomplete'] = 0;
-$rcmail_config['login_autocomplete'] = 0;
+$rcmail_config['login_autocomplete'] = 1;
+$rcmail_config['login_autocomplete'] = 1;
   
   
  // If users authentication is not case sensitive this must be enabled.
  // If users authentication is not case sensitive this must be enabled.
  // You can also use it to force conversion of logins to lower case.
  // You can also use it to force conversion of logins to lower case.
@@ -261,7 +261,7 @@
@@ -261,7 +261,7 @@
  $rcmail_config['useragent'] = 'Roundcube Webmail/'.RCMAIL_VERSION;
  $rcmail_config['useragent'] = 'Roundcube Webmail/'.RCMAIL_VERSION;
   
   
  // use this name to compose page titles
  // use this name to compose page titles
-$rcmail_config['product_name'] = 'Roundcube Webmail';
-$rcmail_config['product_name'] = 'Roundcube Webmail';
+$rcmail_config['product_name'] = 'AN!Mail';
+$rcmail_config['product_name'] = 'AN!Mail';
   
   
  // try to load host-specific configuration
  // try to load host-specific configuration
  // see http://trac.roundcube.net/wiki/Howto_Config for more details
  // see http://trac.roundcube.net/wiki/Howto_Config for more details
</source>
</source>
 
That should be it.
 
==== Error No. [500] ====
 
After a recent OS update, 6.3 to 6.4, I started to get:
 
<source lang="text">
Error No. [500]
</source>
 
When trying to log into Round Cube. When I <span class="code">tail</span>'ed <span class="code">/var/www/ssl_alteeve.ca/logs/error.log</span>, there were two errors;
 
<source lang="text">
[Tue Sep 03 10:39:05 2013] [error] [client 108.168.16.38] PHP Warning:  Error writing to log file /var/log/roundcubemail/errors; Please check permissions in /usr/share/roundcubemail/program/include/main.inc on line 1965, referer: https://alteeve.ca/m/
[Tue Sep 03 10:39:05 2013] [error] [client 108.168.16.38] PHP Notice:  Could not perform encryption; make sure Mcrypt is installed or lib/des.inc is available in /usr/share/roundcubemail/program/include/main.inc on line 2120, referer: https://alteeve.ca/m/
</source>
 
Fixing the first was easy. The owner on <span class="code">/var/log/roundcubemail/errors</span> was <span class="code">root:apache</span> and the mode was <span class="code">644</span>, so a quick;
 
<source lang="bash">
chmod 664 /var/log/roundcubemail/errors
</source>
 
Resolved that issue. Then I <span class="code">tail</span>'ed the roundcube log and still saw the "Mcrypt" error. I found [https://www.centos.org/modules/newbb/viewtopic.php?topic_id=42045&forum=56 this post] which had the fix. The trick was to alter <span class="code">/etc/php.d/mcrypt.ini.orig</span>.
 
<source lang="bash">
cp /etc/php.d/mcrypt.ini /etc/php.d/mcrypt.ini.orig
vim /etc/php.d/mcrypt.ini
</source>
 
Change <span class="code">module.so</span> to <span class="code">mcrypt.so</span>, save and <span class="code">reload</span> apache.
 
<source lang="bash">
diff -u /etc/php.d/mcrypt.ini.orig /etc/php.d/mcrypt.ini
</source>
<source lang="diff">
--- /etc/php.d/mcrypt.ini.orig 2013-09-03 11:10:26.375001302 -0400
+++ /etc/php.d/mcrypt.ini 2013-09-03 10:46:52.340999323 -0400
@@ -1,2 +1,3 @@
; Enable mcrypt extension module
-extension=module.so
+;extension=module.so
+extension=mcrypt.so
</source>
 
Reload <span class="code">httpd</span>;
 
<source lang="bash">
/etc/init.d/httpd reload
</source>
<source lang="text">
Reloading httpd:
</source>
 
RoundCube should now work again.
 
==== Adding a password-reset link to the login page ====
 
Edit the login page template to insert the AN!Console password recovery link.
 
<source lang="bash">
vim /usr/share/roundcubemail/skins/default/templates/login.html</source>
 
(The part we're adding is the '<a href=""></a>'. Other parts of the template file are included here as a reference.)
<source lang="html4strict">
<div id="login-form">
<div class="boxtitle"><roundcube:label name="welcome" /></div>
<div class="boxcontent">
 
<form name="form" action="./" method="post">
<roundcube:object name="loginform" form="form" />
 
<p style="text-align:center;"><input type="submit" class="button mainaction" value="<roundcube:label name='login' />" /></p>
 
</form>
<a href="../../cgi-bin/t/password.cgi">Forgot your password?</a>
</div>
</div>
</source>
 
= Bugzilla =
 
This tutorial covers installing bugzilla 4.4 on [https://alteeve.ca/b/ AN!]'s bugzilla server.
 
== Installing Bugzilla ==
 
* Installed on a fresh minimal CentOS / RHEL 6.4 install.
* Installed at: <span class="code">/var/www/ssl_bugs.alteeve.ca/html/</span> on a dedicated server.
* Databases hosted on an external server running PostgreSQL.
 
Setup your webserver as above. Be sure to use SSL certificates! In this case, we will host our bugzilla at [https://bugs.alteeve.ca https://bugs.alteeve.ca].
 
Create the working directory, go to that directory, download the 4.4 install, extract it and switch into the created <span class="code">bugzilla-4.4</span> directory.
 
<source lang="bash">
mkdir -p /var/www/{bugs.alteeve.ca,ssl_bugs.alteeve.ca}/{html,logs,cgi-bin,temp}
cd /var/www/ssl_bugs.alteeve.ca/temp/
wget -c http://ftp.mozilla.org/pub/mozilla.org/webtools/bugzilla-4.4.tar.gz
tar -xvzf bugzilla-4.4.tar.gz
cd bugzilla-4.4
</source>
 
Install dependent RPMs;
 
<source lang="bash">
yum groupinstall development
yum install perl-ExtUtils-MakeMaker perl-GD perl-GDTextUtil perl-MIME-tools perl-XML-Twig perl-DBD-Pg openssl-devel mod_perl-devel \
            mod_perl patchutils perl-Authen-SASL perl-BSD-Resource perl-CPAN perl-Class-Singleton perl-Convert-ASN1 perl-DateTime \
            perl-Digest-HMAC perl-Digest-SHA1 vim rsync wget acpid gpm mlocate syslinux perl-GSSAPI perl-LDAP perl-List-MoreUtils \
            perl-Params-Validate perl-SOAP-Lite perl-Test-Simple perl-Text-Iconv perl-XML-Filter-BufferText perl-XML-NamespaceSupport \
            perl-XML-SAX-Writer httpd cvs postgresql
</source>
 
Remove RPMs with perl modules that are too old.
 
<source lang="bash">
yum remove perl-TimeDate perl-List-MoreUtils
</source>
 
Install from CPAN remaining needed perl modules.
 
<source lang="bash">
# Don't ask us questions
export PERL_MM_USE_DEFAULT=1
 
# Optional modules
perl -MCPAN -e 'install("YAML")'
perl -MCPAN -e 'install Chart::Lines'
perl -MCPAN -e 'install Template::Plugin::GD::Image'
perl -MCPAN -e 'install GD::Graph'
perl -MCPAN -e 'install MIME::Parser'
perl -MCPAN -e 'install PatchReader'
perl -MCPAN -e 'install Net::SMTP::SSL'
perl -MCPAN -e 'install Authen::Radius'
perl -MCPAN -e 'install SOAP::Lite'
perl -MCPAN -e 'install JSON::RPC'
perl -MCPAN -e 'install JSON::XS'
perl -MCPAN -e 'install Test::Taint'
perl -MCPAN -e 'install HTML::Scrubber'
perl -MCPAN -e 'install Encode::Detect'
perl -MCPAN -e 'install Email::Reply'
perl -MCPAN -e 'install HTML::FormatText::WithLinks'
perl -MCPAN -e 'install TheSchwartz'
perl -MCPAN -e 'install Daemon::Generic'
perl -MCPAN -e 'install Apache2::SizeLimit'
perl -MCPAN -e 'install File::MimeInfo::Magic'
 
# Required modules
perl -MCPAN -e 'install DateTime'
perl -MCPAN -e 'install Email::Send'
perl -MCPAN -e 'install Math::Random::ISAAC'
</source>
 
If the above completed successfully, you should be able to run bugzilla's <span class="code">checksetup.pl</span> script and have no missing modules, save for the DB drivers we're not going to use.
 
<source lang="bash">
./checksetup.pl --check-modules
</source>
<source lang="text">
* This is Bugzilla 4.4 on perl 5.10.1
* Running on Linux 2.6.32-358.18.1.el6.x86_64 #1 SMP Wed Aug 28 17:19:38 UTC 2013
 
Checking perl modules...
Checking for              CGI.pm (v3.51)    ok: found v3.63
Checking for          Digest-SHA (any)      ok: found v5.47
Checking for            TimeDate (v2.23)    ok: found v2.24
Checking for            DateTime (v0.28)    ok: found v1.03
Checking for    DateTime-TimeZone (v0.71)    ok: found v1.60
Checking for                  DBI (v1.54)    ok: found v1.609
Checking for    Template-Toolkit (v2.22)    ok: found v2.25
Checking for          Email-Send (v2.04)    ok: found v2.199
Checking for          Email-MIME (v1.904)    ok: found v1.924
Checking for                  URI (v1.37)    ok: found v1.60
Checking for      List-MoreUtils (v0.32)    ok: found v0.33
Checking for    Math-Random-ISAAC (v1.0.1)    ok: found v1.004
 
Checking available perl DBD modules...
Checking for              DBD-Pg (v2.7.0)    ok: found v2.15.1
Checking for            DBD-mysql (v4.001)    not found
Checking for          DBD-SQLite (v1.29)    not found
Checking for          DBD-Oracle (v1.19)    not found
 
The following Perl modules are optional:
Checking for                  GD (v1.20)    ok: found v2.44
Checking for                Chart (v2.1)      ok: found v2.4.6
Checking for          Template-GD (any)      ok: found v1.56
Checking for          GDTextUtil (any)      ok: found v0.86
Checking for              GDGraph (any)      ok: found v1.48
Checking for          MIME-tools (v5.406)    ok: found v5.504
Checking for          libwww-perl (any)      ok: found v6.05
Checking for            XML-Twig (any)      ok: found v3.34
Checking for          PatchReader (v0.9.6)    ok: found v0.9.6
Checking for            perl-ldap (any)      ok: found v0.40
Checking for          Authen-SASL (any)      ok: found v2.13
Checking for        Net-SMTP-SSL (v1.01)    ok: found v1.01
Checking for          RadiusPerl (any)      ok: found v0.23
Checking for            SOAP-Lite (v0.712)    ok: found v1.06
Checking for            JSON-RPC (any)      ok: found v1.03
Checking for              JSON-XS (v2.0)      ok: found v2.34
Checking for          Test-Taint (any)      ok: found v1.06
Checking for          HTML-Parser (v3.40)    ok: found v3.64
Checking for        HTML-Scrubber (any)      ok: found v0.09
Checking for              Encode (v2.21)    ok: found v2.35
Checking for        Encode-Detect (any)      ok: found v1.01
Checking for          Email-Reply (any)      ok: found v1.203
Checking for HTML-FormatText-WithLinks (v0.13)    ok: found v0.14
Checking for          TheSchwartz (any)      ok: found v1.10
Use of uninitialized value $ENV{"FLOCK_FORKING_USE"} in string eq at /usr/local/share/perl5/File/Flock/Forking.pm line 13, <DATA> line 522.
Checking for      Daemon-Generic (any)      ok: found v0.83
Checking for            mod_perl (v1.999022) ok: found v2.000004
Checking for    Apache-SizeLimit (v0.96)    ok: found v0.96
Checking for        File-MimeInfo (any)      ok: found v0.18
Checking for          IO-stringy (any)      ok: found v2.110
Checking for          mod_headers (any)      ok
Checking for          mod_expires (any)      ok
Checking for              mod_env (any)      ok
</source>
 
Excellent!
 
Now re-run <span class="code">checksetup.pl</span> by itself;
 
<source lang="bash">
./checksetup.pl
</source>
<source lang="text">
* This is Bugzilla 4.4 on perl 5.10.1
* Running on Linux 2.6.32-358.18.1.el6.x86_64 #1 SMP Wed Aug 28 17:19:38 UTC 2013
 
Checking perl modules...
Checking for              CGI.pm (v3.51)    ok: found v3.63
Checking for          Digest-SHA (any)      ok: found v5.47
Checking for            TimeDate (v2.23)    ok: found v2.24
Checking for            DateTime (v0.28)    ok: found v1.03
Checking for    DateTime-TimeZone (v0.71)    ok: found v1.60
Checking for                  DBI (v1.54)    ok: found v1.609
Checking for    Template-Toolkit (v2.22)    ok: found v2.25
Checking for          Email-Send (v2.04)    ok: found v2.199
Checking for          Email-MIME (v1.904)    ok: found v1.924
Checking for                  URI (v1.37)    ok: found v1.60
Checking for      List-MoreUtils (v0.32)    ok: found v0.33
Checking for    Math-Random-ISAAC (v1.0.1)    ok: found v1.004
 
Checking available perl DBD modules...
Checking for              DBD-Pg (v2.7.0)    ok: found v2.15.1
Checking for            DBD-mysql (v4.001)    not found
Checking for          DBD-SQLite (v1.29)    not found
Checking for          DBD-Oracle (v1.19)    not found
 
The following Perl modules are optional:
Checking for                  GD (v1.20)    ok: found v2.44
Checking for                Chart (v2.1)      ok: found v2.4.6
Checking for          Template-GD (any)      ok: found v1.56
Checking for          GDTextUtil (any)      ok: found v0.86
Checking for              GDGraph (any)      ok: found v1.48
Checking for          MIME-tools (v5.406)    ok: found v5.504
Checking for          libwww-perl (any)      ok: found v6.05
Checking for            XML-Twig (any)      ok: found v3.34
Checking for          PatchReader (v0.9.6)    ok: found v0.9.6
Checking for            perl-ldap (any)      ok: found v0.40
Checking for          Authen-SASL (any)      ok: found v2.13
Checking for        Net-SMTP-SSL (v1.01)    ok: found v1.01
Checking for          RadiusPerl (any)      ok: found v0.23
Checking for            SOAP-Lite (v0.712)    ok: found v1.06
Checking for            JSON-RPC (any)      ok: found v1.03
Checking for              JSON-XS (v2.0)      ok: found v2.34
Checking for          Test-Taint (any)      ok: found v1.06
Checking for          HTML-Parser (v3.40)    ok: found v3.64
Checking for        HTML-Scrubber (any)      ok: found v0.09
Checking for              Encode (v2.21)    ok: found v2.35
Checking for        Encode-Detect (any)      ok: found v1.01
Checking for          Email-Reply (any)      ok: found v1.203
Checking for HTML-FormatText-WithLinks (v0.13)    ok: found v0.14
Checking for          TheSchwartz (any)      ok: found v1.10
Use of uninitialized value $ENV{"FLOCK_FORKING_USE"} in string eq at /usr/local/share/perl5/File/Flock/Forking.pm line 13, <DATA> line 522.
Checking for      Daemon-Generic (any)      ok: found v0.83
Checking for            mod_perl (v1.999022) ok: found v2.000004
Checking for    Apache-SizeLimit (v0.96)    ok: found v0.96
Checking for        File-MimeInfo (any)      ok: found v0.18
Checking for          IO-stringy (any)      ok: found v2.110
Checking for          mod_headers (any)      ok
Checking for          mod_expires (any)      ok
Checking for              mod_env (any)      ok
Reading ./localconfig...
 
This version of Bugzilla contains some variables that you may want to
change and adapt to your local settings. The following variables are
new to ./localconfig since you last ran checksetup.pl:
 
create_htaccess, webservergroup, use_suexec, db_driver, db_host,
db_name, db_user, db_pass, db_port, db_sock, db_check, index_html,
cvsbin, interdiffbin, diffpath, site_wide_secret
 
Please edit the file ./localconfig and then re-run checksetup.pl
to complete your installation.
</source>
 
This will generate a file called <span class="code">localconfig</span> with initial values. Make a backup of this and then edit it.
 
<source lang="bash">
cp localconfig localconfig.orig
vim localconfig
</source>
 
Change the values as needed. Below is the <span class="code">diff</span> of the configuration use by AN!.
 
<source lang="bash">
diff -u localconfig.orig localconfig
</source>
<source lang="diff">
--- localconfig.orig 2013-09-03 18:21:10.265003147 -0400
+++ localconfig 2013-09-03 18:38:00.231000167 -0400
@@ -47,30 +47,30 @@
# can be obtained by listing Bugzilla/DB directory - every module corresponds
# to one supported database and the name of the module (before ".pm")
# corresponds to a valid value for this variable.
-$db_driver = 'mysql';
+$db_driver = 'Pg';
# The DNS name or IP address of the host that the database server runs on.
-$db_host = 'localhost';
+$db_host = 'vm09-db01.alteeve.ca';
# The name of the database. For Oracle, this is the database's SID. For
# SQLite, this is a name (or path) for the DB file.
-$db_name = 'bugs';
+$db_name = 'an_bugs';
# Who we connect to the database as.
-$db_user = 'bugs';
+$db_user = 'alteeve';
# Enter your database password here. It's normally advisable to specify
# a password for your bugzilla database user.
# If you use apostrophe (') or a backslash (\) in your password, you'll
# need to escape it by preceding it with a '\' character. (\') or (\)
# (It is far simpler to just not use those characters.)
-$db_pass = '';
+$db_pass = 'secret';
# Sometimes the database server is running on a non-standard port. If that's
# the case for your database server, set this to the port number that your
# database server is running on. Setting this to 0 means "use the default
# port for my database server."
-$db_port = 0;
+$db_port = 5432;
# MySQL Only: Enter a path to the unix socket for MySQL. If this is
# blank, then MySQL's compiled-in default will be used. You probably
</source>
 
Create the <span class="code">an_bugs</span> database.
 
<source lang="bash">
createdb an_bugs -h vm09-db01.alteeve.ca -U alteeve
</source>
<source lang="text">
Password:
</source>
 
Rerun <span class="code">checksetup.pl</span> again to verify your new configuration is sensible.
 
<source lang="bash">
./checksetup.pl
</source>
<source lang="text">
* This is Bugzilla 4.4 on perl 5.10.1
* Running on Linux 2.6.32-358.18.1.el6.x86_64 #1 SMP Wed Aug 28 17:19:38 UTC 2013
 
Checking perl modules...
Checking for              CGI.pm (v3.51)    ok: found v3.63
Checking for          Digest-SHA (any)      ok: found v5.47
Checking for            TimeDate (v2.23)    ok: found v2.24
Checking for            DateTime (v0.28)    ok: found v1.03
Checking for    DateTime-TimeZone (v0.71)    ok: found v1.60
Checking for                  DBI (v1.54)    ok: found v1.609
Checking for    Template-Toolkit (v2.22)    ok: found v2.25
Checking for          Email-Send (v2.04)    ok: found v2.199
Checking for          Email-MIME (v1.904)    ok: found v1.924
Checking for                  URI (v1.37)    ok: found v1.60
Checking for      List-MoreUtils (v0.32)    ok: found v0.33
Checking for    Math-Random-ISAAC (v1.0.1)    ok: found v1.004
 
Checking available perl DBD modules...
Checking for              DBD-Pg (v2.7.0)    ok: found v2.15.1
Checking for            DBD-mysql (v4.001)    not found
Checking for          DBD-SQLite (v1.29)    not found
Checking for          DBD-Oracle (v1.19)    not found
 
The following Perl modules are optional:
Checking for                  GD (v1.20)    ok: found v2.44
Checking for                Chart (v2.1)      ok: found v2.4.6
Checking for          Template-GD (any)      ok: found v1.56
Checking for          GDTextUtil (any)      ok: found v0.86
Checking for              GDGraph (any)      ok: found v1.48
Checking for          MIME-tools (v5.406)    ok: found v5.504
Checking for          libwww-perl (any)      ok: found v6.05
Checking for            XML-Twig (any)      ok: found v3.34
Checking for          PatchReader (v0.9.6)    ok: found v0.9.6
Checking for            perl-ldap (any)      ok: found v0.40
Checking for          Authen-SASL (any)      ok: found v2.13
Checking for        Net-SMTP-SSL (v1.01)    ok: found v1.01
Checking for          RadiusPerl (any)      ok: found v0.23
Checking for            SOAP-Lite (v0.712)    ok: found v1.06
Checking for            JSON-RPC (any)      ok: found v1.03
Checking for              JSON-XS (v2.0)      ok: found v2.34
Checking for          Test-Taint (any)      ok: found v1.06
Checking for          HTML-Parser (v3.40)    ok: found v3.64
Checking for        HTML-Scrubber (any)      ok: found v0.09
Checking for              Encode (v2.21)    ok: found v2.35
Checking for        Encode-Detect (any)      ok: found v1.01
Checking for          Email-Reply (any)      ok: found v1.203
Checking for HTML-FormatText-WithLinks (v0.13)    ok: found v0.14
Checking for          TheSchwartz (any)      ok: found v1.10
Use of uninitialized value $ENV{"FLOCK_FORKING_USE"} in string eq at /usr/local/share/perl5/File/Flock/Forking.pm line 13, <DATA> line 522.
Checking for      Daemon-Generic (any)      ok: found v0.83
Checking for            mod_perl (v1.999022) ok: found v2.000004
Checking for    Apache-SizeLimit (v0.96)    ok: found v0.96
Checking for        File-MimeInfo (any)      ok: found v0.18
Checking for          IO-stringy (any)      ok: found v2.110
Checking for          mod_headers (any)      ok
Checking for          mod_expires (any)      ok
Checking for              mod_env (any)      ok
Reading ./localconfig...
Checking for              DBD-Pg (v2.7.0)    ok: found v2.15.1
Checking for          PostgreSQL (v8.03.0000) ok: found v08.04.1300
 
Adding new table bz_schema...
Initializing bz_schema...
Creating tables...
Creating function array_accum...
Removing index 'bugs_fulltext_comments_idx' from the bugs_fulltext table...
Removing index 'bugs_fulltext_comments_noprivate_idx' from the bugs_fulltext table...
Adding new index 'profiles_login_name_lower_idx' to the profiles table ...
Adding new index 'fielddefs_name_lower_idx' to the fielddefs table ...
Adding new index 'keyworddefs_name_lower_idx' to the keyworddefs table ...
Adding new index 'products_name_lower_idx' to the products table ...
Setting up choices for standard drop-down fields:
  bug_status priority rep_platform resolution op_sys bug_severity
Creating ./data directory...
Creating ./data/attachments directory...
Creating ./data/db directory...
Creating ./data/extensions directory...
Creating ./data/mining directory...
Creating ./data/webdot directory...
Creating ./graphs directory...
Creating ./skins/custom directory...
Creating ./data/extensions/additional...
Creating ./data/mailer.testfile...
Creating ./Bugzilla/.htaccess...
Creating ./data/.htaccess...
Creating ./data/attachments/.htaccess...
Creating ./data/webdot/.htaccess...
Creating ./graphs/.htaccess...
Creating ./lib/.htaccess...
Creating ./template/.htaccess...
Creating contrib/.htaccess...
Creating t/.htaccess...
Creating xt/.htaccess...
Precompiling templates...done.
Fixing file permissions...
Initializing "Dependency Tree Changes" email_setting ...
Initializing "Product/Component Changes" email_setting ...
Marking closed bug statuses as such...
Creating default classification 'Unclassified'...
Setting up foreign keys...
Setting up the default status workflow...
Creating default groups...
Setting up user preferences...
 
Looks like we don't have an administrator set up yet. Either this is
your first time using Bugzilla, or your administrator's privileges
might have accidentally been deleted.
 
</source>
<source lang="text">
Enter the e-mail address of the administrator: admin@alteeve.ca
</source>
<source lang="text">
Enter the real name of the administrator: Alteeve Admin
</source>
<source lang="text">
Enter a password for the administrator account:
Please retype the password to verify:
</source>
<source lang="text">
admin@alteeve.ca is now set up as an administrator.
Creating initial dummy product 'TestProduct'...
 
Now that you have installed Bugzilla, you should visit the 'Parameters'
page (linked in the footer of the Administrator account) to ensure it
is set up as you wish - this includes setting the 'urlbase' option to
the correct URL.
checksetup.pl complete.
</source>
 
== Configure Apache for Bugzilla ==
 
Now move the files into the web root, switch to the web root document
 
<source lang="bash">
rsync -av /var/www/ssl_bugs.alteeve.ca/temp/bugzilla-4.4/* /var/www/ssl_bugs.alteeve.ca/html/
chown -R apache:apache /var/www/ssl_bugs.alteeve.ca
cd /var/www/ssl_bugs.alteeve.ca/html
</source>
 
Next, setup the apache configuration files. We'll need two;
* <span class="code">bugs.alteeve.ca.conf</span>; rewrite all non-SSL requests to their SSL version.
* <span class="code">ssl_bugs.alteeve.ca.conf</span>; The actual configuration file.
 
The configuration to rewrite any incoming <span class="code">http://</span> requests to <span class="code">https://</span> requests.
 
<syntaxhighlight lang="bash">
vim /etc/httpd/conf.d/bugs.alteeve.ca.conf
</syntaxhighlight>
<syntaxhighlight lang="text">
<VirtualHost *:80>
ServerAdmin admin@alteeve.ca
 
ServerName bugs.alteeve.ca
 
RedirectMatch permanent (.*) https://bugs.alteeve.ca$1
 
ErrorLog /var/www/bugs.alteeve.ca/logs/error.log
 
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel debug
 
CustomLog /var/www/bugs.alteeve.ca/logs/access.log combined
ServerSignature On
</VirtualHost>
</syntaxhighlight>
 
Now write the actual [[SSL]]-enabled configuration for bugzilla.
 
<syntaxhighlight lang="bash">
vim /etc/httpd/conf.d/ssl_bugs.alteeve.ca.conf
</syntaxhighlight>
<syntaxhighlight lang="text">
<VirtualHost *:443>
ServerAdmin admin@alteeve.ca
 
ServerName bugs.alteeve.ca
 
#DirectoryIndex index.cgi
# We can haz security?
SSLEngine on
SSLProtocol all
SSLCACertificateFile /etc/pki/CA/RapidSSL_CA_bundle.pem
SSLCertificateFile /etc/pki/CA/ssl_bugs.alteeve.ca.crt
SSLCertificateKeyFile /etc/pki/CA/private/bugs.alteeve.ca.key
   
DocumentRoot /var/www/ssl_bugs.alteeve.ca/html/
Alias /w /var/www/ssl_bugs.alteeve.ca/html/index.php
<Directory /var/www/ssl_bugs.alteeve.ca/html>
AddHandler cgi-script .cgi
Options +ExecCGI
DirectoryIndex index.cgi index.html
AllowOverride Limit FileInfo Indexes Options
#Options +Includes Indexes FollowSymLinks MultiViews
#AllowOverride All
#Order allow,deny
#allow from all
</Directory>
 
ErrorLog /var/www/ssl_bugs.alteeve.ca/logs/error.log
TransferLog /var/www/ssl_bugs.alteeve.ca/logs/transfer.log
 
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel info
 
CustomLog /var/www/ssl_bugs.alteeve.ca/logs/access.log combined
ServerSignature On
</VirtualHost>
</syntaxhighlight>
 
Verify the syntax;
 
<syntaxhighlight lang="bash">
apachectl -t
</syntaxhighlight>
<syntaxhighlight lang="text">
Syntax OK
</syntaxhighlight>
<syntaxhighlight lang="bash">
apachectl -S
</syntaxhighlight>
<syntaxhighlight lang="text">
VirtualHost configuration:
wildcard NameVirtualHosts and _default_ servers:
*:443                  bugs.alteeve.ca (/etc/httpd/conf.d/ssl_bugs.alteeve.ca.conf:1)
*:80                  is a NameVirtualHost
        default server unknown.alteeve.ca (/etc/httpd/conf.d/00_default.conf:1)
        port 80 namevhost unknown.alteeve.ca (/etc/httpd/conf.d/00_default.conf:1)
        port 80 namevhost bugs.alteeve.ca (/etc/httpd/conf.d/bugs.alteeve.ca.conf:1)
        port 80 namevhost bugs.alteeve.ca (/etc/httpd/conf.d/ssl.conf:74)
Syntax OK
</syntaxhighlight>
 
Run a final check of the bugzilla configuration;
 
<syntaxhighlight lang="bash">
cd /var/www/ssl_bugs.alteeve.ca/html
./checksetup.pl
</syntaxhighlight>
<syntaxhighlight lang="text">
* This is Bugzilla 4.4 on perl 5.10.1
* Running on Linux 2.6.32-358.18.1.el6.x86_64 #1 SMP Wed Aug 28 17:19:38 UTC 2013
 
Checking perl modules...
Checking for              CGI.pm (v3.51)    ok: found v3.63
Checking for          Digest-SHA (any)      ok: found v5.47
Checking for            TimeDate (v2.23)    ok: found v2.24
Checking for            DateTime (v0.28)    ok: found v1.03
Checking for    DateTime-TimeZone (v0.71)    ok: found v1.60
Checking for                  DBI (v1.54)    ok: found v1.609
Checking for    Template-Toolkit (v2.22)    ok: found v2.25
Checking for          Email-Send (v2.04)    ok: found v2.199
Checking for          Email-MIME (v1.904)    ok: found v1.924
Checking for                  URI (v1.37)    ok: found v1.60
Checking for      List-MoreUtils (v0.32)    ok: found v0.33
Checking for    Math-Random-ISAAC (v1.0.1)    ok: found v1.004
 
Checking available perl DBD modules...
Checking for              DBD-Pg (v2.7.0)    ok: found v2.15.1
Checking for            DBD-mysql (v4.001)    not found
Checking for          DBD-SQLite (v1.29)    not found
Checking for          DBD-Oracle (v1.19)    not found
 
The following Perl modules are optional:
Checking for                  GD (v1.20)    ok: found v2.44
Checking for                Chart (v2.1)      ok: found v2.4.6
Checking for          Template-GD (any)      ok: found v1.56
Checking for          GDTextUtil (any)      ok: found v0.86
Checking for              GDGraph (any)      ok: found v1.48
Checking for          MIME-tools (v5.406)    ok: found v5.504
Checking for          libwww-perl (any)      ok: found v6.05
Checking for            XML-Twig (any)      ok: found v3.34
Checking for          PatchReader (v0.9.6)    ok: found v0.9.6
Checking for            perl-ldap (any)      ok: found v0.40
Checking for          Authen-SASL (any)      ok: found v2.13
Checking for        Net-SMTP-SSL (v1.01)    ok: found v1.01
Checking for          RadiusPerl (any)      ok: found v0.23
Checking for            SOAP-Lite (v0.712)    ok: found v1.06
Checking for            JSON-RPC (any)      ok: found v1.03
Checking for              JSON-XS (v2.0)      ok: found v2.34
Checking for          Test-Taint (any)      ok: found v1.06
Checking for          HTML-Parser (v3.40)    ok: found v3.64
Checking for        HTML-Scrubber (any)      ok: found v0.09
Checking for              Encode (v2.21)    ok: found v2.35
Checking for        Encode-Detect (any)      ok: found v1.01
Checking for          Email-Reply (any)      ok: found v1.203
Checking for HTML-FormatText-WithLinks (v0.13)    ok: found v0.14
Checking for          TheSchwartz (any)      ok: found v1.10
Use of uninitialized value $ENV{"FLOCK_FORKING_USE"} in string eq at /usr/local/share/perl5/File/Flock/Forking.pm line 13, <DATA> line 522.
Checking for      Daemon-Generic (any)      ok: found v0.83
Checking for            mod_perl (v1.999022) ok: found v2.000004
Checking for    Apache-SizeLimit (v0.96)    ok: found v0.96
Checking for        File-MimeInfo (any)      ok: found v0.18
Checking for          IO-stringy (any)      ok: found v2.110
Checking for          mod_headers (any)      ok
Checking for          mod_expires (any)      ok
Checking for              mod_env (any)      ok
Reading ./localconfig...
Checking for              DBD-Pg (v2.7.0)    ok: found v2.15.1
Checking for          PostgreSQL (v8.03.0000) ok: found v08.04.1300
 
Removing existing compiled templates...
Precompiling templates...done.
Fixing file permissions...
 
Now that you have installed Bugzilla, you should visit the 'Parameters'
page (linked in the footer of the Administrator account) to ensure it
is set up as you wish - this includes setting the 'urlbase' option to
the correct URL.
checksetup.pl complete.
</syntaxhighlight>
 
Start up the server!
 
<syntaxhighlight lang="bash">
/etc/init.d/httpd start
</syntaxhighlight>
<syntaxhighlight lang="text">
Starting httpd: Apache/2.2.15 mod_ssl/2.2.15 (Pass Phrase Dialog)
Some of your private key files are encrypted for security reasons.
In order to read them you have to provide the pass phrases.
 
Server bugs.alteeve.ca:443 (RSA)
Enter pass phrase:
 
OK: Pass Phrase Dialog successful.
                                                          [  OK  ]
</syntaxhighlight>
 
If everything is working, you should be able to browse to your bugzilla install!
 
== Configure Bugzilla Itself ==
 
Log in as the adminitrator (user name is the email address you entered earlier with <span class="code">./checksetup.pl</span>) and go to <span class="code">https://<domain>/editparams.cgi</span>.
 
* General
 
{|class="wikitable"
!Variab!!Value
|-
|<span class="code">urlbase</span>||<span class="code">https://bugs.alteeve.ca</span>
|-
|<span class="code">ssl_redirect</span>||Click to check <span class="code">On</span>
|-
|<span class="code">sslbase</span>||<span class="code">https://bugs.alteeve.ca</span>
|}
 
* Email
 
{|class="wikitable"
!Variab!!Value
|-
|<span class="code">mail_delivery_method</span>||<span class="code">SMTP</span>
|-
|<span class="code">mailfrom</span>||<span class="code">bugs@alteeve.ca</span>
|-
|<span class="code">use_mailer_queue</span>||Click to check <span class="code">On</span>
|-
|<span class="code">smtpserver</span>||<span class="code">mail.alteeve.ca</span>
|-
|<span class="code">smtp_username</span>||<span class="code">bugs@alteeve.ca</span>
|-
|<span class="code">smtp_password</span>||<span class="code">secret</span>
|-
|<span class="code">smtp_ssl</span>||Click to check <span class="code">On</span>
|-
|<span class="code">globalwatchers</span>||<span class="code">admin@alteeve.ca</span>
|}
 
= Mailman =
 
Mailing list software!
 
== Install Mailman ==
 
We need mailman 3 in order to get encrypted passwords. So we'll not be using <span class="code">mailman</span> as shipped with [[RHEL6]].
 
=== Install Prerequisite RPMs ===
 
<syntaxhighlight lang="bash">
yum -y install postfix mailx httpd gcc mod_ssl
chkconfig postfix on
chkconfig httpd on
</syntaxhighlight>
 
=== Install Python 2.7 ===
 
From [https://www.digitalocean.com/community/articles/how-to-set-up-python-2-7-6-and-3-3-3-on-centos-6-4 here].
 
<syntaxhighlight lang="bash">
wget -qO- http://people.redhat.com/bkabrda/scl_python27.repo >> /etc/yum.repos.d/scl.repo
yum update
yum -y install python27
scl enable python27 bash
python -V
</syntaxhighlight>
 
You should get:
 
<syntaxhighlight lang="text">
Python 2.7.5
</syntaxhighlight>
 
=== Configure Local Postfix ===
 
<syntaxhighlight lang="bash">
vim /etc/postfix/main.cf
</syntaxhighlight>
 
Add:
 
<syntaxhighlight lang="text">
queue_directory = /var/spool/postfix
command_directory = /usr/sbin
daemon_directory = /usr/libexec/postfix
data_directory = /var/lib/postfix
mail_owner = postfix
mydomain = lists.alteeve.ca
inet_interfaces = all
inet_protocols = all
mydestination = lists.alteeve.ca
unknown_local_recipient_reject_code = 550
mynetworks_style = subnet
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
debug_peer_level = 2
debugger_command =
PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin
ddd $daemon_directory/$process_name $process_id & sleep 5
sendmail_path = /usr/sbin/sendmail.postfix
newaliases_path = /usr/bin/newaliases.postfix
mailq_path = /usr/bin/mailq.postfix
setgid_group = postdrop
html_directory = no
manpage_directory = /usr/share/man
sample_directory = /usr/share/doc/postfix-2.6.6/samples
readme_directory = /usr/share/doc/postfix-2.6.6/README_FILES
</syntaxhighlight>
 
(Re)start postfix:
 
<syntaxhighlight lang="bash">
/etc/init.d/postfix restart
</syntaxhighlight>
 
Test local mail delivery:
 
<syntaxhighlight lang="bash">
echo hi | mailx -s test admin@alteeve.ca
</syntaxhighlight>
 
If you got an email, local mail delivery is working.
 
=== Configure Apache for Mailman ===
 
Follow the [[#Apache|Apache]] install above. Come back here
 
We will configure <span class="code"><nowiki>http://lists.alteeve.ca</nowiki></span> to redirect all calls to <span class="code"><nowiki>https://lists.alteeve.ca</nowiki></span>.
 
Specific configs:
 
Base apache:
 
<syntaxhighlight lang="bash">
diff -U0 /etc/httpd/conf/httpd.conf.orig /etc/httpd/conf/httpd.conf
</syntaxhighlight>
<syntaxhighlight lang="diff">
--- /etc/httpd/conf/httpd.conf.orig 2013-02-25 18:26:51.000000000 -0500
+++ /etc/httpd/conf/httpd.conf 2014-04-03 21:00:51.952003006 -0400
@@ -103,6 +103,6 @@
-StartServers      8
-MinSpareServers    5
-MaxSpareServers  20
-ServerLimit      256
-MaxClients      256
-MaxRequestsPerChild  4000
+StartServers      16
+MinSpareServers  10
+MaxSpareServers  40
+ServerLimit      512
+MaxClients      512
+MaxRequestsPerChild  8000
@@ -119,5 +119,5 @@
-StartServers        4
-MaxClients        300
-MinSpareThreads    25
-MaxSpareThreads    75
-ThreadsPerChild    25
+StartServers        8
+MaxClients        600
+MinSpareThreads    50
+MaxSpareThreads    150
+ThreadsPerChild    50
@@ -262 +262 @@
-ServerAdmin root@localhost
+ServerAdmin admin@alteeve.ca
@@ -276 +276 @@
-#ServerName www.example.com:80
+ServerName lists.alteeve.ca:80
@@ -292 +292 @@
-DocumentRoot "/var/www/html"
+DocumentRoot "/var/www/default/html"
@@ -317 +317 @@
-<Directory "/var/www/html">
+<Directory "/var/www/default/html">
@@ -551 +551 @@
-Alias /icons/ "/var/www/icons/"
+Alias /icons/ "/var/www/default/icons/"
@@ -553 +553 @@
-<Directory "/var/www/icons">
+<Directory "/var/www/default/icons">
@@ -576 +576 @@
-ScriptAlias /cgi-bin/ "/var/www/cgi-bin/"
+ScriptAlias /cgi-bin/ "/var/www/default/cgi-bin/"
@@ -579 +579 @@
-# "/var/www/cgi-bin" should be changed to whatever your ScriptAliased
+# "/var/www/default/cgi-bin" should be changed to whatever your ScriptAliased
@@ -582 +582 @@
-<Directory "/var/www/cgi-bin">
+<Directory "/var/www/default/cgi-bin">
@@ -851 +851 @@
-# /var/www/error/include/ files and
+# /var/www/default/error/include/ files and
@@ -855 +855 @@
-Alias /error/ "/var/www/error/"
+Alias /error/ "/var/www/default/error/"
@@ -859 +859 @@
-    <Directory "/var/www/error">
+    <Directory "/var/www/default/error">
@@ -990 +990 @@
-#NameVirtualHost *:80
+NameVirtualHost *:80
</syntaxhighlight>
 
SSL setup:
 
<syntaxhighlight lang="bash">
diff -U0 /etc/httpd/conf.d/ssl.conf.orig /etc/httpd/conf.d/ssl.conf
</syntaxhighlight>
<syntaxhighlight lang="diff">
--- /etc/httpd/conf.d/ssl.conf.orig 2014-04-03 21:37:26.431005814 -0400
+++ /etc/httpd/conf.d/ssl.conf 2014-04-03 21:10:16.558004490 -0400
@@ -74 +74 @@
-<VirtualHost _default_:443>
+<VirtualHost _default_:80>
</syntaxhighlight>
 
Configure the http redirect to https:
 
<syntaxhighlight lang="bash">
vim /etc/httpd/conf.d/lists.alteeve.ca.conf
</syntaxhighlight>
<syntaxhighlight lang="apache">
<VirtualHost *:80>
ServerAdmin admin@alteeve.ca
 
ServerName lists.alteeve.ca
 
RedirectMatch permanent (.*) https://lists.alteeve.ca$1
 
ErrorLog /var/www/lists.alteeve.ca/logs/error.log
LogLevel debug
 
CustomLog /var/www/lists.alteeve.ca/logs/access.log combined
ServerSignature On
</VirtualHost>
</syntaxhighlight>
 
Setup the main https page:
 
<syntaxhighlight lang="bash">
vim /etc/httpd/conf.d/ssl_lists.alteeve.ca.conf
</syntaxhighlight>
<syntaxhighlight lang="apache">
<VirtualHost *:443>
        ServerAdmin admin@alteeve.ca
        ServerName lists.alteeve.ca
        DirectoryIndex index.php index.html
        # We can haz security?
        SSLEngine on
        SSLProtocol all
        SSLCACertificateFile /etc/pki/CA/RapidSSL_CA_bundle.pem
        SSLCertificateFile /etc/pki/CA/wildcard_ssl_alteeve.ca.crt
        SSLCertificateKeyFile /etc/pki/CA/private/wildcard_alteeve.ca.key
        DocumentRoot /var/www/ssl_lists.alteeve.ca/html/
        Alias /w /var/www/ssl_lists.alteeve.ca/html/index.php
        <Directory /var/www/ssl_lists.alteeve.ca/html>
                Options +Includes Indexes FollowSymLinks MultiViews
                AllowOverride All
                Order allow,deny
                allow from all
        </Directory>
        ScriptAlias /cgi-bin/ /var/www/ssl_lists.alteeve.ca/cgi-bin/
        <Directory "/var/www/ssl_lists.alteeve.ca/cgi-bin">
                AllowOverride None
                Options ExecCGI -MultiViews +SymLinksIfOwnerMatch
                Order allow,deny
                Allow from all
        </Directory>
        ErrorLog /var/www/ssl_lists.alteeve.ca/logs/error.log
        TransferLog /var/www/ssl_lists.alteeve.ca/logs/transfer.log
        # Possible values include: debug, info, notice, warn, error, crit,
        # alert, emerg.
        LogLevel debug
        CustomLog /var/www/ssl_lists.alteeve.ca/logs/access.log combined
        ServerSignature On
</VirtualHost>
</syntaxhighlight>
 
[[#Copying_Wildcard_to_a_new_Server|Copy the wildcard]] SSL certs into place.
 
Create a redirect page:
 
<syntaxhighlight lang="bash">
mkdir -p /var/www/ssl_lists.alteeve.ca/{cgi-bin,html,logs}
touch /var/www/ssl_lists.alteeve.ca/html/index.html
chown -R apache:apache /var/www
vim /var/www/ssl_lists.alteeve.ca/html/index.html
</syntaxhighlight>
<syntaxhighlight lang="html4strict">
<head>
        <title>Alteeve's Niche! - Mailing Lists</title>
</head>
<body>
        <meta http-equiv="refresh" content="0; url=mailman/listinfo/" />
</body>
</syntaxhighlight>
 
Connect to [http://lists.alteeve.ca http://lists.alteeve.ca] and it should automatically redirect to: <span class="code">http://lists.alteeve.ca/mailman/listinfo/</span>.
 
=== Add an MX Record to Bind For lists.alteeve.ca ===
 
Add an entry in bind so that there is an MX record for <span class="code">lists.alteeve.ca</span>:
 
<syntaxhighlight lang="bash">
/etc/named/db.alteeve.ca
</syntaxhighlight>
 
Add:
 
<syntaxhighlight lang="text">
lists.alteeve.ca. MX 10 lists.alteeve.ca.
</syntaxhighlight>
 
Save and reload <span class="code">named</span>.
 
<syntaxhighlight lang="bash">
/etc/init.d/named reload
</syntaxhighlight>
 
=== Install Mailman v3 from Source ===
 
At this time, the only v3 install is beta.
 
<syntaxhighlight lang="bash">
mkdir ~/temp
cd ~/temp/
wget https://launchpad.net/mailman/3.0/3.0.0b3/+download/mailman-3.0.0b3.tar.gz
tar -xvzf mailman-3.0.0b3.tar.gz
cd mailman-3.0.0b3
python setup.py build
python setup.py install
</syntaxhighlight>
 
And here, the best laid plans fell to pieces... Back to mailman 2.
 
<span class="code"></span>
<syntaxhighlight lang="bash">
</syntaxhighlight>
<syntaxhighlight lang="text">
</syntaxhighlight>
 
== Configure Mailmain ==
 
Create the initial <span class="code">mailman</span> list.
 
<syntaxhighlight lang="bash">
/usr/lib/mailman/bin/newlist anvil-users
</syntaxhighlight>
<syntaxhighlight lang="text">
Enter the email of the person running the list: admin@alteeve.ca
Initial anvil-users password:
</syntaxhighlight>
<syntaxhighlight lang="text">
To finish creating your mailing list, you must edit your /etc/aliases (or
equivalent) file by adding the following lines, and possibly running the
`newaliases' program:
 
## anvil-users mailing list
anvil-users:              "|/usr/lib/mailman/mail/mailman post anvil-users"
anvil-users-admin:        "|/usr/lib/mailman/mail/mailman admin anvil-users"
anvil-users-bounces:      "|/usr/lib/mailman/mail/mailman bounces anvil-users"
anvil-users-confirm:      "|/usr/lib/mailman/mail/mailman confirm anvil-users"
anvil-users-join:        "|/usr/lib/mailman/mail/mailman join anvil-users"
anvil-users-leave:        "|/usr/lib/mailman/mail/mailman leave anvil-users"
anvil-users-owner:        "|/usr/lib/mailman/mail/mailman owner anvil-users"
anvil-users-request:      "|/usr/lib/mailman/mail/mailman request anvil-users"
anvil-users-subscribe:    "|/usr/lib/mailman/mail/mailman subscribe anvil-users"
anvil-users-unsubscribe:  "|/usr/lib/mailman/mail/mailman unsubscribe anvil-users"
 
Hit enter to notify anvil-users owner...
</syntaxhighlight>
 
Edit the alias file:
 
<syntaxhighlight lang="bash">
vim /etc/aliases
</syntaxhighlight>
 
Append:
 
<syntaxhighlight lang="text">
## anvil-users mailing list
anvil-users:              "|/usr/lib/mailman/mail/mailman post anvil-users"
anvil-users-admin:        "|/usr/lib/mailman/mail/mailman admin anvil-users"
anvil-users-bounces:      "|/usr/lib/mailman/mail/mailman bounces anvil-users"
anvil-users-confirm:      "|/usr/lib/mailman/mail/mailman confirm anvil-users"
anvil-users-join:        "|/usr/lib/mailman/mail/mailman join anvil-users"
anvil-users-leave:        "|/usr/lib/mailman/mail/mailman leave anvil-users"
anvil-users-owner:        "|/usr/lib/mailman/mail/mailman owner anvil-users"
anvil-users-request:      "|/usr/lib/mailman/mail/mailman request anvil-users"
anvil-users-subscribe:    "|/usr/lib/mailman/mail/mailman subscribe anvil-users"
anvil-users-unsubscribe:  "|/usr/lib/mailman/mail/mailman unsubscribe anvil-users"
</syntaxhighlight>
 
And load:
 
<syntaxhighlight lang="bash">
newaliases
</syntaxhighlight>
 
=== WebUI Config ===
 
# https://lists.alteeve.ca/mailman/admin/anvil-users/general
## Hide the sender of a message, replacing it with the list address (Removes From, Sender and Reply-To fields) -> Yes.
 
<span class="code"></span>
<syntaxhighlight lang="bash">
</syntaxhighlight>
<syntaxhighlight lang="text">
</syntaxhighlight>
 
== Deleting Mail from the Archive ==
 
Go to the list directory:
 
<syntaxhighlight lang="bash">
cd /var/lib/mailman/archives/private
</syntaxhighlight>
 
Edit the <span class="code">.mbox</span> file for the list.
 
<syntaxhighlight lang="bash">
vim anvil-users.mbox/anvil-users.mbox
</syntaxhighlight>
 
Find the message you want to delete and then delete everything from <span class="code">From <sender email>  <date> <time> <year></span> until the same line from the next message (or end of the file if it's the last message in the list).
 
Example:


That should be it.
<syntaxhighlight lang="email">
From lists@alteeve.ca  Thu Apr  3 23:35:27 2014
Return-Path: <lists@alteeve.ca>
X-Original-To: anvil-users@lists.alteeve.ca
Delivered-To: anvil-users@lists.alteeve.ca
Received: from vm08-mail01.alteeve.ca (unknown [65.39.153.71])
        by vm17-lists.alteeve.ca (Postfix) with ESMTP id DD83313FB13
        for <anvil-users@lists.alteeve.ca>;
        Thu,  3 Apr 2014 23:35:27 -0400 (EDT)
Received: from lemass.alteeve.ca (dhcp-108-168-20-202.cable.user.start.ca
        [108.168.20.202])
        by vm08-mail01.alteeve.ca (Postfix) with ESMTPSA id 80EC720171
        for <anvil-users@lists.alteeve.ca>;
        Thu,  3 Apr 2014 23:00:07 -0400 (EDT)
Message-ID: <533E2037.1020302@alteeve.ca>
Date: Thu, 03 Apr 2014 23:00:07 -0400
From: Digimer <lists@alteeve.ca>
User-Agent: Mozilla/5.0 (X11; Linux x86_64;
        rv:24.0) Gecko/20100101 Thunderbird/24.4.0
MIME-Version: 1.0
To: anvil-users@lists.alteeve.ca
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit
Subject: [Anvil-users] Test
X-BeenThere: anvil-users@lists.alteeve.ca
X-Mailman-Version: 2.1.12
Precedence: list
List-Id: <anvil-users.lists.alteeve.ca>
List-Unsubscribe: <https://lists.alteeve.ca/mailman/options/anvil-users>,
        <mailto:anvil-users-request@lists.alteeve.ca?subject=unsubscribe>
List-Archive: <http://lists.alteeve.ca/pipermail/anvil-users/>
List-Post: <mailto:anvil-users@lists.alteeve.ca>
List-Help: <mailto:anvil-users-request@lists.alteeve.ca?subject=help>
List-Subscribe: <https://lists.alteeve.ca/mailman/listinfo/anvil-users>,
        <mailto:anvil-users-request@lists.alteeve.ca?subject=subscribe>
X-List-Received-Date: Fri, 04 Apr 2014 03:35:27 -0000


==== Adding a password-reset link to the login page ====
Please ignore.


Edit the login page template to insert the AN!Console password recovery link.
--
Digimer
Papers and Projects: https://alteeve.ca/w/
What if the cure for cancer is trapped in the mind of a person without
access to education?
</syntaxhighlight>


<source lang="bash">
Once deleted, move the list directory out of the way and then regenerate the list archives.
vim /usr/share/roundcubemail/skins/default/templates/login.html</source>


(The part we're adding is the '<a href=""></a>'. Other parts of the template file are included here as a reference.)
<syntaxhighlight lang="bash">
<source lang="bash">
mv /var/lib/mailman/archives/private/anvil-users /var/lib/mailman/archives/private/anvil-users.1
<div id="login-form">
/usr/lib/mailman/bin/arch anvil-users
<div class="boxtitle"><roundcube:label name="welcome" /></div>
</syntaxhighlight>
<div class="boxcontent">
<syntaxhighlight lang="text">
#00000 <CA+scbRK1dZAY6Jv5UqBM7-cG_L385QCtFY5UFx3RWRABN7sG1g@mail.gmail.com>
figuring article archives
2014-April
#00001 <CA+scbRJ96jXnx=0iFk220FsoEFghNoR2gwLg-DmTQ3rL2qDw+w@mail.gmail.com>
figuring article archives
2014-April
#00002 <533E2CF6.7080909@alteeve.ca>
figuring article archives
2014-April
Updating index files for archive [2014-April]
  Date
  Subject
  Author
  Thread
Computing threaded index
Updating HTML for article 0
Updating HTML for article 1
Updating HTML for article 2
Pickling archive state into /var/lib/mailman/archives/private/anvil-users/pipermail.pck
</syntaxhighlight>


<form name="form" action="./" method="post">
Reload the archive page and verify that the email is gone.
<roundcube:object name="loginform" form="form" />


<p style="text-align:center;"><input type="submit" class="button mainaction" value="<roundcube:label name='login' />" /></p>
If so, delete the backup directory.


</form>
<syntaxhighlight lang="bash">
<a href="../../cgi-bin/t/password.cgi">Forgot your password?</a>
rm -rf /var/lib/mailman/archives/private/anvil-users.1
</div>
</syntaxhighlight>
</div>
</source>


= Thanks =
= Thanks =


* To [http://planet-geek.com Dave Shevett] (aka: eidolon) and [http://codex.grimoire.ca/ Owen Jacobson] for answering my n00b SSL questions.
* To [http://planet-geek.com Dave Shevett] (aka: eidolon) and [http://codex.grimoire.ca/ Owen Jacobson] for answering my n00b SSL questions.
<span class="code"></span>
<source lang="bash">
</source>
<source lang="text">
</source>


{{footer}}
{{footer}}

Latest revision as of 22:51, 23 July 2015

 AN!Wiki :: How To :: PPPower Server

With tongue firmly in cheek, this is a tutorial on building an EL6 server for hosting website and email using PostgreSQL, Postfix and Postgrey for mail and Apache for web. There are many canned and arguably superior was of accomplishing the same, but this is what I user for this server.

Post OS Install

First, some post-install preparation. We'll need to set up some basic security, a program to report server statistics, and some 3rd-party yum repositories for additional software.

Yum repo install.

yum -y install yum-protectbase
rpm -Uvh https://alteeve.ca/an-repo/el6/RPMS/noarch/alteeve-repo-0.1-3.noarch.rpm
yum clean expire-cache
yum -y update

The yum-protectbase plugin will ensure that the 3rd-party repos play nicely and never overwrite the Base repos. To use this plugin with a specific repo, add protect=0 or protect=1 to the repo's config file.

cp /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.orig
vim /etc/yum.repos.d/CentOS-Base.repo
# add protect=1 to each paragraph
diff -U 0 /etc/yum.repos.d/CentOS-Base.repo.orig /etc/yum.repos.d/CentOS-Base.repo
--- /etc/yum.repos.d/CentOS-Base.repo.orig	2012-05-07 01:07:47.688145406 -0400
+++ /etc/yum.repos.d/CentOS-Base.repo	2012-05-07 01:08:15.915322496 -0400
@@ -18,0 +19 @@
+protect=1
@@ -26,0 +28 @@
+protect=1
@@ -34,0 +37 @@
+protect=1
@@ -43,0 +47 @@
+protect=1
@@ -52,0 +57 @@
+protect=1

Protecting against malicious users with Denyhosts.

Denyhosts is a daemon that watches for too many failed logins via ssh. It uses TCP-wrappers to deny the user access to ssh (or any service) on the server after X failed logins. It has the option to download a list of known malicious IPs and add them to /hosts.deny, making possible to block attackers before they attack the server.

Install denyhosts

yum -y install denyhosts

Edit the config to your preferences.

cp /etc/denyhosts.conf /etc/denyhosts.conf.orig
vim /etc/denyhosts.conf
BLOCK_SERVICE = ALL
SYNC_SERVER = http://xmlrpc.denyhosts.net:9911
SYNC_DOWNLOAD = yes
diff -U 0 /etc/denyhosts.conf.orig /etc/denyhosts.conf
--- /etc/denyhosts.conf.orig	2012-05-13 02:33:05.584566483 -0400
+++ /etc/denyhosts.conf	2012-05-13 02:34:19.386558503 -0400
@@ -96 +96 @@
-#BLOCK_SERVICE = ALL
+BLOCK_SERVICE = ALL
@@ -98 +98 @@
-BLOCK_SERVICE  = sshd
+#BLOCK_SERVICE  = sshd
@@ -547 +547 @@
-#SYNC_SERVER = http://xmlrpc.denyhosts.net:9911
+SYNC_SERVER = http://xmlrpc.denyhosts.net:9911
@@ -582 +582 @@
-#SYNC_DOWNLOAD = yes
+SYNC_DOWNLOAD = yes

White-list any trusted machines, including localhost.

cp /etc/hosts.allow /etc/hosts.allow.orig
vim /etc/hosts.allow
127.0.0.1
206.108.5.162
diff -U 0 /etc/hosts.allow.orig /etc/hosts.allow
--- /etc/hosts.allow.orig	2012-05-13 02:36:02.613767847 -0400
+++ /etc/hosts.allow	2012-05-13 02:40:37.473523845 -0400
@@ -10,0 +11,2 @@
+127.0.0.1
+206.108.5.162

Start the service.

chkconfig denyhosts on
/etc/init.d/denyhosts start
Starting denyhosts:                                        [  OK  ]

Additional software to install

To view neatly-summarized daily logs, and system resource usage.

yum -y install logwatch htop

Packages for web server and wiki install.

yum install httpd httpd-tools postgresql94-server postgresql94-plperl postgresql94-contrib postgresql94 mysql-server telnet mod_ssl mysql-server php-mysql gcc jwhois bind \
            acpid bind-utils syslinux screen man bzip2 zip unzip php-pgsql php yum-utils policycoreutils-python rsync
chkconfig acpid on

Packages that are currently needed for personal stuff.

yum install perl-XML-Simple perl-MIME-Lite perl-DBD-MySQL perl-DBD-Pg perl-Digest-Perl-MD5 mod_auth_pgsql perl-Digest-SHA perl-CGI perl-Time-HiRes

Apache

Apache is configured first with a global configuration, which also defines the "default" website which is shown when the server is called by it's IP address (or by a domain that is not configured). Then with per-domain configurations known as "virtual host containers".

First, the global configuration and default domain. We will put our default website in /var/www/default/. So the first step is to create the needed directories.

mkdir -p /var/www/default/{html,cgi-bin,logs}
chown -R apache:apache /var/www

Now to edit the configuration file.

cp /etc/httpd/conf/httpd.conf /etc/httpd/conf/httpd.conf.orig
vim /etc/httpd/conf/httpd.conf
Note: This needs to be explained.

Make the following changes.

diff -U 0 /etc/httpd/conf/httpd.conf.orig /etc/httpd/conf/httpd.conf
--- /etc/httpd/conf/httpd.conf.orig	2012-05-13 19:32:07.718570148 -0400
+++ /etc/httpd/conf/httpd.conf	2012-05-13 21:48:18.439736244 -0400
@@ -103,6 +103,6 @@
-StartServers       8
-MinSpareServers    5
-MaxSpareServers   20
-ServerLimit      256
-MaxClients       256
-MaxRequestsPerChild  4000
+StartServers      16
+MinSpareServers   10
+MaxSpareServers   40
+ServerLimit      512
+MaxClients       512
+MaxRequestsPerChild  8000
@@ -119,5 +119,5 @@
-StartServers         4
-MaxClients         300
-MinSpareThreads     25
-MaxSpareThreads     75 
-ThreadsPerChild     25
+StartServers         8
+MaxClients         600
+MinSpareThreads     50
+MaxSpareThreads    150 
+ThreadsPerChild     50
@@ -262 +262 @@
-ServerAdmin root@localhost
+ServerAdmin admin@alteeve.ca
@@ -276,0 +277 @@
+ServerName omiya.alteeve.ca:80
@@ -292 +293 @@
-DocumentRoot "/var/www/html"
+DocumentRoot "/var/www/default/html"
@@ -317 +318 @@
-<Directory "/var/www/html">
+<Directory "/var/www/default/html">
@@ -551 +552 @@
-Alias /icons/ "/var/www/icons/"
+Alias /icons/ "/var/www/default/icons/"
@@ -553 +554 @@
-<Directory "/var/www/icons">
+<Directory "/var/www/default/icons">
@@ -576 +577 @@
-ScriptAlias /cgi-bin/ "/var/www/cgi-bin/"
+ScriptAlias /cgi-bin/ "/var/www/default/cgi-bin/"
@@ -582 +583 @@
-<Directory "/var/www/cgi-bin">
+<Directory "/var/www/default/cgi-bin">
@@ -855 +856 @@
-Alias /error/ "/var/www/error/"
+Alias /error/ "/var/www/default/error/"
@@ -859 +860 @@
-    <Directory "/var/www/error">
+    <Directory "/var/www/default/error">
@@ -990 +991 @@
-#NameVirtualHost *:80
+NameVirtualHost *:80
@@ -1004,5 +1005,5 @@
-#    ServerAdmin webmaster@dummy-host.example.com
-#    DocumentRoot /www/docs/dummy-host.example.com
-#    ServerName dummy-host.example.com
-#    ErrorLog logs/dummy-host.example.com-error_log
-#    CustomLog logs/dummy-host.example.com-access_log common
+#    ServerAdmin admin@alteeve.ca
+#    DocumentRoot /var/www/default/html
+#    ServerName unknown.alteeve.ca
+#    ErrorLog /var/www/default/logs/error.log
+#    CustomLog /var/www/default/logs/access.log common
@@ -1009,0 +1011 @@
+

After all changes, use this to make sure there are no syntax errors.

apachectl -t
[Sun May 13 21:48:11 2012] [warn] NameVirtualHost *:80 has no VirtualHosts
Syntax OK

Note that the [Sun May 13 21:48:11 2012] [warn] NameVirtualHost *:80 has no VirtualHosts is expected at this stage as we've not yet configured any virtual hosts.

All virtual host configuration files need to be created in the /etc/httpd/conf.d directory and the file must have the .conf suffix in order to be read by apache. These files will be read in order, so if you want to ensure that one file is read before another, as we will do shortly, you can prefix the configuration file with an integer to ensure read order.

I like to redirect all unknown server requests to http://unknown.alteeve.ca. For this, I will create an initial configuration file called 00_default.conf.

vim /etc/httpd/conf.d/00_default.conf
<VirtualHost *:80>
        ServerAdmin admin@alteeve.ca
        DocumentRoot /var/www/default/html
        ServerName unknown.alteeve.ca
        ErrorLog /var/www/default/logs/error.log
        CustomLog /var/www/default/logs/access.log common
</VirtualHost>

Now we will do two kinds of checks; One for syntax and one to check the configuration of virtual host containers.

apachectl -t
Syntax OK

We no longer see the warning from before as we now have our first virtual host configured.

apachectl -S
VirtualHost configuration:
wildcard NameVirtualHosts and _default_ servers:
_default_:443          omiya.alteeve.ca (/etc/httpd/conf.d/ssl.conf:74)
*:80                   is a NameVirtualHost
         default server unknown.alteeve.ca (/etc/httpd/conf.d/00_default.conf:1)
         port 80 namevhost unknown.alteeve.ca (/etc/httpd/conf.d/00_default.conf:1)
Syntax OK

We can now start the web server for the first time.

/etc/init.d/httpd start
Starting httpd:                                            [  OK  ]

Perfect! Time to configure some real domains.

Common Virtual Host Configurations

All domains on this server will be housed under either:

  • /var/www/domain.tld/{cgi-bin,html,logs,temp}

Or, for SSL encrypted domains;

  • /var/www/ssl_domain.tld/{cgi-bin,html,logs,temp}

The four directories found under the domain are used for hosting executable scripts (cgi-bin), standard HTML websites or websites with in-line code like PHP (html), log files (logs) and an optional temporary directory used for staging files (temp).

Standard Virtual Hosts

This section covers the configuration on standard virtual host containers (using TCP port 80).

In this example, we will setup the domain http://mizu-bu.org.

First, create the directories for the domain's files.

mkdir -p /var/www/mizu-bu.org/{cgi-bin,html,logs,temp}

Now create the virtual host container's configuration file. Note that in this example, it is a MediaWiki website, so we will tell apache to look for index.php files by default.

vim /etc/httpd/conf.d/mizu-bu.org.conf
<VirtualHost *:80>
	ServerAdmin digimer@alteeve.ca

	ServerName mizu-bu.org
        ServerAlias www.mizu-bu.org

	DirectoryIndex index.html
    	
	DocumentRoot /var/www/mizu-bu.org/html/
	<Directory /var/www/mizu-bu.org/html>
		Options +Includes Indexes FollowSymLinks MultiViews
		AllowOverride Options
		Order allow,deny
		allow from all
	</Directory>

	ScriptAlias /cgi-bin/ /var/www/mizu-bu.org/cgi-bin/
	<Directory "/var/www/mizu-bu.org/cgi-bin">
		AllowOverride None
		Options ExecCGI -MultiViews +SymLinksIfOwnerMatch
		Order allow,deny
		Allow from all
	</Directory>

	ErrorLog /var/www/mizu-bu.org/logs/error.log

	# Possible values include: debug, info, notice, warn, error, crit,
	# alert, emerg.
	LogLevel debug

	CustomLog /var/www/mizu-bu.org/logs/access.log combined
	ServerSignature On
</VirtualHost>

As before, test the syntax and virtual host configurations.

apachectl -S
VirtualHost configuration:
wildcard NameVirtualHosts and _default_ servers:
_default_:443          omiya.alteeve.ca (/etc/httpd/conf.d/ssl.conf:74)
*:80                   is a NameVirtualHost
         default server unknown.alteeve.ca (/etc/httpd/conf.d/00_default.conf:1)
         port 80 namevhost unknown.alteeve.ca (/etc/httpd/conf.d/00_default.conf:1)
         port 80 namevhost mizu-bu.org (/etc/httpd/conf.d/mizu-bu.org.conf:1)
Syntax OK


SSL Virtual Hosts

SSL provides for secure client to server communications.

Per-Domain SSL Cert

This covers setting up an SSL certificate for one domain only.

Per-Domain SS - Creating The Signed Certificate

This section assumes you are using a 3rd party signing authority. Specifically, I use http://www.trustico.ca/ (resellers of http://RapidSSL.com and others). This is also for a domain-specific certificate. Wildcard certificates will differ.

First, create 2048bit private key. Note that this will require a pass-phrase, which you will need to enter whenever the Apache daemon httpd daemon starts. If you do not want this, remove the -des3 switch.

cd /etc/pki/CA/private/
openssl genrsa -des3 -out /etc/pki/CA/private/alteeve.ca.key 2048
Generating RSA private key, 2048 bit long modulus
..................................+++
.............................................................+++
e is 65537 (0x10001)
Enter pass phrase for /etc/pki/CA/private/alteeve.ca.key:
Verifying - Enter pass phrase for /etc/pki/CA/private/alteeve.ca.key:

Now create a CSR (Certificate signing request) which we will send to the signing authority. Do not enter anything in the extra section below.

Note: The Common Name must be the fully qualified domain name. In this example, I want to create a certificate for the domain https://alteeve.ca, so I will enter alteeve.ca. If you prefer to use a www. prefix, include it. I will rewrite requests using the www. prefix to not use it.
openssl req -new -key /etc/pki/CA/private/alteeve.ca.key -out alteeve.ca.csr
Enter pass phrase for /etc/pki/CA/private/alteeve.ca.key:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CA
State or Province Name (full name) []:Ontario
Locality Name (eg, city) [Default City]:Oakville
Organization Name (eg, company) [Default Company Ltd]:Alteeve's Niche
Organizational Unit Name (eg, section) []:IT
Common Name (eg, your name or your server's hostname) []:alteeve.ca
Email Address []:admin@alteeve.ca     

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

Test that the CSR file is ok.

openssl req -noout -text -in /etc/pki/CA/alteeve.ca.csr
Certificate Request:
    Data:
        Version: 0 (0x0)
        Subject: C=CA, ST=Ontario, L=Oakville, O=Alteeve's Niche, OU=IT, CN=alteeve.ca/emailAddress=admin@alteeve.ca
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    ...
                Exponent: 65537 (0x10001)
        Attributes:
            a0:00
    Signature Algorithm: sha1WithRSAEncryption
        ...

Copy the exact contents of the alteeve.ca.csr file and provide it to your signing authority as per their instructions. Once you complete their CSR form, they should email you a signed certificate and an intermediary certificate. At this point, the CSR file is no longer needed.

Save the signed certificate:

vim /etc/pki/CA/ssl_alteeve.ca.crt
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----

Save the intermediary certificate. Change the certificate name to that of your provider. If they provide you with this file, simply save it in the /etc/pki/CA/ directory.

vim /etc/pki/CA/RapidSSL_CA_bundle.pem
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----

Wildcard SSL Certificate

These certs work for any *.example.com domain.

Wildcard SSL - Creating The Signed Certificate

This section assumes you are using a 3rd party signing authority. Specifically, I use http://www.trustico.ca/ (resellers of http://RapidSSL.com and others). This is also for a domain-specific certificate. Wildcard certificates will differ.

Unlike the per-domain SSL certificate, this one will not require a pass-phrase to decrypt.

First, create 2048bit private key.

cd /etc/pki/CA/private/
openssl genrsa -out /etc/pki/CA/private/wildcard_alteeve.ca.key 2048
Generating RSA private key, 2048 bit long modulus
..<snip>..+++
..<snip>..+++
e is 65537 (0x10001)

Verify it was created:

ls -lah /etc/pki/CA/private/wildcard_alteeve.ca.key
-rw-r--r-- 1 root root 1.7K Feb 26 15:40 /etc/pki/CA/private/wildcard_alteeve.ca.key

Now create a CSR (Certificate signing request) which we will send to the signing authority. Do not enter anything in the extra section below.

Note: The Common Name must be the short, fully qualified domain name with a leading *. to make it a wildcard. In this example, I want to create a certificate domains under alteeve.ca, so I will enter *.alteeve.ca.
openssl req -new -key /etc/pki/CA/private/wildcard_alteeve.ca.key -out wildcard_alteeve.ca.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CA
State or Province Name (full name) []:Ontario
Locality Name (eg, city) [Default City]:Toronto
Organization Name (eg, company) [Default Company Ltd]:Alteeve's Niche! Inc.
Organizational Unit Name (eg, section) []:IT
Common Name (eg, your name or your server's hostname) []:*.alteeve.ca
Email Address []:admin@alteeve.ca

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

Check that it was generated.

ls -lah /etc/pki/CA/private/wildcard_alteeve.ca.csr
-rw-r--r-- 1 root root 1.1K Feb 26 16:19 /etc/pki/CA/private/wildcard_alteeve.ca.csr

Test that the CSR file is ok.

openssl req -noout -text -in /etc/pki/CA/private/wildcard_alteeve.ca.csr
Certificate Request:
    Data:
        Version: 0 (0x0)
        Subject: C=CA, ST=Ontario, L=Toronto, O=Alteeve's Niche! Inc., OU=IT, CN=*.alteeve.ca/emailAddress=admin@alteeve.ca
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    ...
                Exponent: 65537 (0x10001)
        Attributes:
            a0:00
    Signature Algorithm: sha1WithRSAEncryption
         ...

Copy the exact contents of the wildcard_alteeve.ca.csr file and provide it to your signing authority as per their instructions. Once you complete their CSR form, they should email you a signed certificate and an intermediary certificate. At this point, the CSR file is no longer needed.

Save the signed certificate:

vim /etc/pki/CA/wildcard_ssl_alteeve.ca.crt
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----

Save the intermediary certificate. Change the certificate name to that of your provider. If they provide you with this file, simply save it in the /etc/pki/CA/ directory.

vim /etc/pki/CA/RapidSSL_CA_bundle.pem
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----

Copying Wildcard to a new Server

When you are setting up a new server to use an existing wildcard cert, you simply need to copy over four files:

rsync -av root@alteeve.ca:/etc/pki/CA/wildcard_ssl_alteeve.ca.crt /etc/pki/CA/
rsync -av root@alteeve.ca:/etc/pki/CA/private/wildcard_alteeve.ca* /etc/pki/CA/private/
rsync -av root@alteeve.ca:/etc/pki/CA/RapidSSL_CA_bundle.pem /etc/pki/CA/

Once copied, setup the SSL virtual host the same as always.

Change ssl.conf

If you forget to update /etc/httpd/conf.d/ssl.conf, you will get an error like this;

apachectl -t
[Mon Feb 25 19:50:32 2013] [warn] _default_ VirtualHost overlap on port 443, the first has precedence
Syntax OK

To avoid this, edit /etc/httpd/conf.d/ssl.conf and change <VirtualHost _default_:443> to <VirtualHost _default_:80>.

Creating An SSL Virtual Host

Create a new virtual host container for the new SSL protected virtual host. We will leave the normal unencrypted virtual-host alone for now. Once we're done, we'll use it to capture and redirect http:// requests to their https:// equivalents. I make my virtual host directories writeable by my normal user account. Feel free to adapt this to your preferences.

Setup the directories and then create a trivial index.html file.

mkdir ssl_alteeve.ca/{cgi-bin,html,logs,temp} -p
chown apache:digimer ssl_alteeve.ca -R
chmod g+w ssl_alteeve.ca -R
vim /var/www/ssl_alteeve.ca/html/index.html
<head>
        <title>AN!Wiki - SSL Test Server</title>
</head>
<body>
        <h1>SSL Test</h1>
</body>

Now setup the Apache2 config. I like to use the ssl_ prefix for encrypted domains.

Note: This example is for a MediaWiki virtual host with short URLs configured. You will want to adapt the values to suit your needs.
vim /etc/httpd/conf.d/ssl_alteeve.ca.conf
<VirtualHost *:443>
        ServerAdmin digimer@alteeve.ca

        ServerName alteeve.ca

        DirectoryIndex index.php index.html

        # We can haz security?
        SSLEngine on
        SSLProtocol all
        SSLCACertificateFile /etc/pki/CA/RapidSSL_CA_bundle.pem
        SSLCertificateFile /etc/pki/CA/wildcard_ssl_alteeve.ca.crt
        SSLCertificateKeyFile /etc/pki/CA/private/wildcard_alteeve.ca.key

        DocumentRoot /var/www/ssl_alteeve.ca/html/
        Alias /w /var/www/ssl_alteeve.ca/html/index.php
        <Directory /var/www/ssl_alteeve.ca/html>
                Options +Includes Indexes FollowSymLinks MultiViews
                AllowOverride All
                Order allow,deny
                allow from all
        </Directory>

        ScriptAlias /cgi-bin/ /var/www/ssl_alteeve.ca/cgi-bin/
        <Directory "/var/www/ssl_alteeve.ca/cgi-bin">
                AllowOverride None
                Options ExecCGI -MultiViews +SymLinksIfOwnerMatch
                Order allow,deny
                Allow from all
        </Directory>

        ErrorLog /var/www/ssl_alteeve.ca/logs/error.log
        TransferLog /var/www/ssl_alteeve.ca/logs/transfer.log

        # Possible values include: debug, info, notice, warn, error, crit,
        # alert, emerg.
        LogLevel debug

        CustomLog /var/www/ssl_alteeve.ca/logs/access.log combined
        ServerSignature On
</VirtualHost>

Bad Identity Error

If you get an error about the server not providing identity information, you may have be loading images, CSS, javascript or similar using a URL from a remote domain with no SSL or badly configured SSL.

For example, on Firefox 4, you may see:

This web site does not supply identity information.

Your connection to this site is only partially encrypted, and does not prevent eavesdropping.
                                                                        [ More Information ]

In my case, this turned out to be a problem where mediawiki was loading a Creative Commons logo from their server using http:// link to the icon. Once this was changed to https:// (in LocalSettings.php), the error went away.

Testing and Using the New Configuration

Test your new Apache configuration.

apachectl -t
Syntax OK

Now restart Apache. Note that you will be asked to enter the pass-phrase you used when you created your private key.

/etc/init.d/httpd restart
Stopping httpd:                                            [  OK  ]
Starting httpd: Apache/2.2.15 mod_ssl/2.2.15 (Pass Phrase Dialog)
Some of your private key files are encrypted for security reasons.
In order to read them you have to provide the pass phrases.

Server alteeve.ca:443 (RSA)
Enter pass phrase:

OK: Pass Phrase Dialog successful.
                                                           [  OK  ]
Warning: From now on, you will need to enter the pass-phrase to start Apache. Consider this when restarting your server and when deciding if you want the Apache server to start with your server. As my server is in a VM and it's underlying disk is also encrypted, I will enable it at boot time. I'll need to be watching the boot process anyway. This may not apply to you.

Now make sure that you can still connect to your server on TCP port 80 (normal http port). The contents after the GET request will obviously vary depending on your configuration:

telnet localhost 80
Trying ::1...
Connected to localhost.
Escape character is '^]'.
GET
<head>
	<title>Asakusa.alteeve.ca</title>
</head>
<body>
	Default - Requested domain not found
</body>
Connection closed by foreign host.

Now to check that the SSL port is listening properly. We can't use telnet because of the SSL encryption. Instead we will use openssl.

openssl s_client -connect localhost:443 -state -debug
CONNECTED(00000003)
SSL_connect:before/connect initialization
write to 0x196a050 [0x1a0b3a0] (113 bytes => 113 (0x71))
0000 - 16 03 01 00 6c 01 00 00-68 03 01 4d f8 f4 a4 f9   ....l...h..M....
0010 - 07 b3 11 f8 3d ff 5d 80-ed 69 87 52 e2 60 80 57   ....=.]..i.R.`.W
0020 - 59 c7 83 4c ea 5b e5 37-06 e0 13 00 00 3a 00 39   Y..L.[.7.....:.9
0030 - 00 38 00 88 00 87 00 35-00 84 00 16 00 13 00 0a   .8.....5........
0040 - 00 33 00 32 00 9a 00 99-00 45 00 44 00 2f 00 96   .3.2.....E.D./..
0050 - 00 41 00 05 00 04 00 15-00 12 00 09 00 14 00 11   .A..............
0060 - 00 08 00 06 00 03 00 ff-02 01 00 00 04 00 23      ..............#
0071 - <SPACES/NULS>
SSL_connect:SSLv2/v3 write client hello A
read from 0x196a050 [0x1a10900] (7 bytes => 7 (0x7))
0000 - 16 03 01 00 35 02                                 ....5.
0007 - <SPACES/NULS>
read from 0x196a050 [0x1a1090a] (51 bytes => 51 (0x33))
0000 - 00 31 03 01 4d f8 f4 a4-7d 35 00 74 24 43 bc c9   .1..M...}5.t$C..
0010 - 84 5d fe e3 90 1a e8 14-39 a1 b1 7e e8 19 c7 9f   .]......9..~....
0020 - 45 20 d1 cb 00 00 39 01-00 09 ff 01 00 01 00 00   E ....9.........
0030 - 23                                                #
0033 - <SPACES/NULS>
SSL_connect:SSLv3 read server hello A
read from 0x196a050 [0x1a10903] (5 bytes => 5 (0x5))
0000 - 16 03 01 0c 2c                                    ....,
read from 0x196a050 [0x1a10908] (3116 bytes => 3116 (0xC2C))
0000 - 0b 00 0c 28 00 0c 25 00-04 c2 30 82 04 be 30 82   ...(..%...0...0.
0010 - 03 a6 a0 03 02 01 02 02-03 02 15 24 30 0d 06 09   ...........$0...
0020 - 2a 86 48 86 f7 0d 01 01-05 05 00 30 3c 31 0b 30   *.H........0<1.0
0030 - 09 06 03 55 04 06 13 02-55 53 31 17 30 15 06 03   ...U....US1.0...
0040 - 55 04 0a 13 0e 47 65 6f-54 72 75 73 74 2c 20 49   U....GeoTrust, I
0050 - 6e 63 2e 31 14 30 12 06-03 55 04 03 13 0b 52 61   nc.1.0...U....Ra
0060 - 70 69 64 53 53 4c 20 43-41 30 1e 17 0d 31 31 30   pidSSL CA0...110
0070 - 36 31 34 31 32 31 39 30-31 5a 17 0d 31 31 30 37   614121901Z..1107
0080 - 31 36 31 35 35 36 31 34-5a 30 81 d9 31 29 30 27   16155614Z0..1)0'
0090 - 06 03 55 04 05 13 20 30-54 53 35 57 7a 61 75 51   ..U... 0TS5WzauQ
00a0 - 52 4a 37 73 63 32 62 2d-68 54 47 77 4b 31 79 78   RJ7sc2b-hTGwK1yx
00b0 - 53 66 45 44 70 68 46 31-0b 30 09 06 03 55 04 06   SfEDphF1.0...U..
00c0 - 13 02 43 41 31 14 30 12-06 03 55 04 0a 13 0b 61   ..CA1.0...U....a
00d0 - 6c 74 65 65 76 65 2e 63-6f 6d 31 13 30 11 06 03   lteeve.com1.0...
00e0 - 55 04 0b 13 0a 47 54 31-33 39 30 38 38 31 37 31   U....GT139088171
00f0 - 31 30 2f 06 03 55 04 0b-13 28 53 65 65 20 77 77   10/..U...(See ww
0100 - 77 2e 72 61 70 69 64 73-73 6c 2e 63 6f 6d 2f 72   w.rapidssl.com/r
0110 - 65 73 6f 75 72 63 65 73-2f 63 70 73 20 28 63 29   esources/cps (c)
0120 - 31 31 31 2b 30 29 06 03-55 04 0b 13 22 44 6f 6d   111+0)..U..."Dom
0130 - 61 69 6e 20 43 6f 6e 74-72 6f 6c 20 56 61 6c 69   ain Control Vali
0140 - 64 61 74 65 64 20 2d 20-46 72 65 65 53 53 4c 31   dated - FreeSSL1
0150 - 14 30 12 06 03 55 04 03-13 0b 61 6c 74 65 65 76   .0...U....alteev
0160 - 65 2e 63 6f 6d 30 82 01-22 30 0d 06 09 2a 86 48   e.com0.."0...*.H
0170 - 86 f7 0d 01 01 01 05 00-03 82 01 0f 00 30 82 01   .............0..
0180 - 0a 02 82 01 01 00 c7 b5-75 03 c7 a9 b5 21 b2 7a   ........u....!.z
0190 - 9b 70 8d f2 44 5d e0 18-f4 05 52 c6 93 d3 17 a5   .p..D]....R.....
01a0 - 3a c7 46 03 68 d1 01 53-1b e8 b8 d3 4c 56 46 b2   :.F.h..S....LVF.
01b0 - ca 63 34 88 2c 4f 7b 23-49 07 ef 8e 37 5c 8a ac   .c4.,O{#I...7\..
01c0 - d7 88 9b ed a1 01 90 bc-32 d8 46 30 6d 82 33 59   ........2.F0m.3Y
01d0 - ea b5 38 2c 8a 16 e1 63-e7 ba 39 d8 2a fa 8a 6b   ..8,...c..9.*..k
01e0 - 25 45 0b c9 4d b8 d2 be-a9 3a e3 ff 61 60 f9 a4   %E..M....:..a`..
01f0 - 99 4e 3f c2 25 0b 21 07-c6 1b 1e 63 71 2e 3d 31   .N?.%.!....cq.=1
0200 - 42 98 01 f4 88 b8 80 26-b7 bf 5b 00 b1 57 86 b4   B......&..[..W..
0210 - d8 70 e6 ec ea 98 e1 17-45 a7 ff 83 e0 76 6f 8a   .p......E....vo.
0220 - 50 bb 1d cb c5 8f f4 01-84 4e 59 c3 4d 28 73 70   P........NY.M(sp
0230 - 39 c8 da 85 43 b9 07 ae-57 26 04 24 b2 d6 d4 7c   9...C...W&.$...|
0240 - 03 af 4f 72 00 8f 20 ed-26 77 b3 bf 4e 01 62 8b   ..Or.. .&w..N.b.
0250 - 62 1b 10 16 65 92 f5 bb-5a dc 83 5c f2 56 f3 60   b...e...Z..\.V.`
0260 - 34 2c ef 62 f4 ee cf 26-6d 9b 4a 5e 74 05 74 fb   4,.b...&m.J^t.t.
0270 - 23 86 07 6f cf b0 48 6d-ba 2d 89 5d 0f e0 c0 01   #..o..Hm.-.]....
0280 - 1c 91 af 00 5f f3 02 03-01 00 01 a3 82 01 29 30   ...._.........)0
0290 - 82 01 25 30 1f 06 03 55-1d 23 04 18 30 16 80 14   ..%0...U.#..0...
02a0 - 6b 69 3d 6a 18 42 4a dd-8f 02 65 39 fd 35 24 86   ki=j.BJ...e9.5$.
02b0 - 78 91 16 30 30 0e 06 03-55 1d 0f 01 01 ff 04 04   x..00...U.......
02c0 - 03 02 05 a0 30 1d 06 03-55 1d 25 04 16 30 14 06   ....0...U.%..0..
02d0 - 08 2b 06 01 05 05 07 03-01 06 08 2b 06 01 05 05   .+.........+....
02e0 - 07 03 02 30 16 06 03 55-1d 11 04 0f 30 0d 82 0b   ...0...U....0...
02f0 - 61 6c 74 65 65 76 65 2e-63 6f 6d 30 43 06 03 55   alteeve.ca.0C..U
0300 - 1d 1f 04 3c 30 3a 30 38-a0 36 a0 34 86 32 68 74   ...<0:08.6.4.2ht
0310 - 74 70 3a 2f 2f 72 61 70-69 64 73 73 6c 2d 63 72   tp://rapidssl-cr
0320 - 6c 2e 67 65 6f 74 72 75-73 74 2e 63 6f 6d 2f 63   l.geotrust.com/c
0330 - 72 6c 73 2f 72 61 70 69-64 73 73 6c 2e 63 72 6c   rls/rapidssl.crl
0340 - 30 1d 06 03 55 1d 0e 04-16 04 14 a1 2b 4e af 55   0...U.......+N.U
0350 - 08 7b 34 be 74 fc 57 41-de bc 8f d9 4a 1d c9 30   .{4.t.WA....J..0
0360 - 0c 06 03 55 1d 13 01 01-ff 04 02 30 00 30 49 06   ...U.......0.0I.
0370 - 08 2b 06 01 05 05 07 01-01 04 3d 30 3b 30 39 06   .+........=0;09.
0380 - 08 2b 06 01 05 05 07 30-02 86 2d 68 74 74 70 3a   .+.....0..-http:
0390 - 2f 2f 72 61 70 69 64 73-73 6c 2d 61 69 61 2e 67   //rapidssl-aia.g
03a0 - 65 6f 74 72 75 73 74 2e-63 6f 6d 2f 72 61 70 69   eotrust.com/rapi
03b0 - 64 73 73 6c 2e 63 72 74-30 0d 06 09 2a 86 48 86   dssl.crt0...*.H.
03c0 - f7 0d 01 01 05 05 00 03-82 01 01 00 66 8b 6f a8   ............f.o.
03d0 - d5 d2 84 c7 89 31 fb a5-ba e1 11 5e 2f 67 6f df   .....1.....^/go.
03e0 - 0d 3c 0b 1a 4b ac d9 38-ee 29 0a 4d d9 06 98 2c   .<..K..8.).M...,
03f0 - 25 0a 59 bb 39 03 b0 cd-3b 06 93 3e 59 90 cf 06   %.Y.9...;..>Y...
0400 - 17 74 77 bb cd 91 34 d0-6f b9 8f 53 57 ed 14 30   .tw...4.o..SW..0
0410 - bd e9 6c 04 84 b6 f0 16-9d 29 9b b1 47 f8 84 64   ..l......)..G..d
0420 - 5f 03 36 ea e1 d6 13 97-5b 50 b9 b2 59 cc f8 ef   _.6.....[P..Y...
0430 - 23 01 99 91 6e 5e e8 d0-77 54 38 49 18 58 e7 0e   #...n^..wT8I.X..
0440 - 54 35 c0 37 b5 9e 79 b2-d4 c6 d9 ff 27 31 d4 bf   T5.7..y.....'1..
0450 - 04 ae d3 0a 90 4b bc 34-bc 53 f8 bc e7 4c 22 b7   .....K.4.S...L".
0460 - b3 bc 8c d7 41 44 fc e0-50 2e 9a ac ba 5c ee 88   ....AD..P....\..
0470 - 03 fc 0e 53 32 aa dd a4-24 ee a6 7c 3d dc 9d 7a   ...S2...$..|=..z
0480 - 82 0b 9f b8 91 e0 a1 12-77 a3 95 f7 d0 c4 9e f1   ........w.......
0490 - d7 d9 99 68 80 e8 af ad-68 f5 1a 5f 66 06 78 c9   ...h....h.._f.x.
04a0 - 56 f8 36 37 16 fa 7d 27-df 1d a2 d8 7c 8c 5b 50   V.67..}'....|.[P
04b0 - db c6 fe 06 ff 96 86 f5-1f e4 35 ce cf 43 66 53   ..........5..CfS
04c0 - da a1 50 b5 c0 73 ec 1e-f4 c8 20 13 00 03 d9 30   ..P..s.... ....0
04d0 - 82 03 d5 30 82 02 bd a0-03 02 01 02 02 03 02 36   ...0...........6
04e0 - d1 30 0d 06 09 2a 86 48-86 f7 0d 01 01 05 05 00   .0...*.H........
04f0 - 30 42 31 0b 30 09 06 03-55 04 06 13 02 55 53 31   0B1.0...U....US1
0500 - 16 30 14 06 03 55 04 0a-13 0d 47 65 6f 54 72 75   .0...U....GeoTru
0510 - 73 74 20 49 6e 63 2e 31-1b 30 19 06 03 55 04 03   st Inc.1.0...U..
0520 - 13 12 47 65 6f 54 72 75-73 74 20 47 6c 6f 62 61   ..GeoTrust Globa
0530 - 6c 20 43 41 30 1e 17 0d-31 30 30 32 31 39 32 32   l CA0...10021922
0540 - 34 35 30 35 5a 17 0d 32-30 30 32 31 38 32 32 34   4505Z..200218224
0550 - 35 30 35 5a 30 3c 31 0b-30 09 06 03 55 04 06 13   505Z0<1.0...U...
0560 - 02 55 53 31 17 30 15 06-03 55 04 0a 13 0e 47 65   .US1.0...U....Ge
0570 - 6f 54 72 75 73 74 2c 20-49 6e 63 2e 31 14 30 12   oTrust, Inc.1.0.
0580 - 06 03 55 04 03 13 0b 52-61 70 69 64 53 53 4c 20   ..U....RapidSSL 
0590 - 43 41 30 82 01 22 30 0d-06 09 2a 86 48 86 f7 0d   CA0.."0...*.H...
05a0 - 01 01 01 05 00 03 82 01-0f 00 30 82 01 0a 02 82   ..........0.....
05b0 - 01 01 00 c7 71 f8 56 c7-1e d9 cc b5 ad f6 b4 97   ....q.V.........
05c0 - a3 fb a1 e6 0b 50 5f 50-aa 3a da 0f fc 3d 29 24   .....P_P.:...=)$
05d0 - 43 c6 10 29 c1 fc 55 40-72 ee bd ea df 9f b6 41   C..)..U@r......A
05e0 - f4 48 4b c8 6e fe 4f 57-12 8b 5b fa 92 dd 5e e8   .HK.n.OW..[...^.
05f0 - ad f3 f0 1b b1 7b 4d fb-cf fd d1 e5 f8 e3 dc e7   .....{M.........
0600 - f5 73 7f df 01 49 cf 8c-56 c1 bd 37 e3 5b be b5   .s...I..V..7.[..
0610 - 4f 8b 8b f0 da 4f c7 e3-dd 55 47 69 df f2 5b 7b   O....O...UGi..[{
0620 - 07 4f 3d e5 ac 21 c1 c8-1d 7a e8 e7 f6 0f a1 aa   .O=..!...z......
0630 - f5 6f de a8 65 4f 10 89-9c 03 f3 89 7a a5 5e 01   .o..eO......z.^.
0640 - 72 33 ed a9 e9 5a 1e 79-f3 87 c8 df c8 c5 fc 37   r3...Z.y.......7
0650 - c8 9a 9a d7 b8 76 cc b0-3e e7 fd e6 54 ea df 5f   .....v..>...T.._
0660 - 52 41 78 59 57 ad f1 12-d6 7f bc d5 9f 70 d3 05   RAxYW........p..
0670 - 6c fa a3 7d 67 58 dd 26-62 1d 31 92 0c 79 79 1c   l..}gX.&b.1..yy.
0680 - 8e cf ca 7b c1 66 af a8-74 48 fb 8e 82 c2 9e 2c   ...{.f..tH.....,
0690 - 99 5c 7b 2d 5d 9b bc 5b-57 9e 7c 3a 7a 13 ad f2   .\{-]..[W.|:z...
06a0 - a3 18 5b 2b 59 0f cd 5c-3a eb 68 33 c6 28 1d 82   ..[+Y..\:.h3.(..
06b0 - d1 50 8b 02 03 01 00 01-a3 81 d9 30 81 d6 30 0e   .P.........0..0.
06c0 - 06 03 55 1d 0f 01 01 ff-04 04 03 02 01 06 30 1d   ..U...........0.
06d0 - 06 03 55 1d 0e 04 16 04-14 6b 69 3d 6a 18 42 4a   ..U......ki=j.BJ
06e0 - dd 8f 02 65 39 fd 35 24-86 78 91 16 30 30 1f 06   ...e9.5$.x..00..
06f0 - 03 55 1d 23 04 18 30 16-80 14 c0 7a 98 68 8d 89   .U.#..0....z.h..
0700 - fb ab 05 64 0c 11 7d aa-7d 65 b8 ca cc 4e 30 12   ...d..}.}e...N0.
0710 - 06 03 55 1d 13 01 01 ff-04 08 30 06 01 01 ff 02   ..U.......0.....
0720 - 01 00 30 3a 06 03 55 1d-1f 04 33 30 31 30 2f a0   ..0:..U...3010/.
0730 - 2d a0 2b 86 29 68 74 74-70 3a 2f 2f 63 72 6c 2e   -.+.)http://crl.
0740 - 67 65 6f 74 72 75 73 74-2e 63 6f 6d 2f 63 72 6c   geotrust.com/crl
0750 - 73 2f 67 74 67 6c 6f 62-61 6c 2e 63 72 6c 30 34   s/gtglobal.crl04
0760 - 06 08 2b 06 01 05 05 07-01 01 04 28 30 26 30 24   ..+........(0&0$
0770 - 06 08 2b 06 01 05 05 07-30 01 86 18 68 74 74 70   ..+.....0...http
0780 - 3a 2f 2f 6f 63 73 70 2e-67 65 6f 74 72 75 73 74   ://ocsp.geotrust
0790 - 2e 63 6f 6d 30 0d 06 09-2a 86 48 86 f7 0d 01 01   .com0...*.H.....
07a0 - 05 05 00 03 82 01 01 00-ab bc bc 0a 5d 18 94 e3   ............]...
07b0 - c1 b1 c3 a8 4c 55 d6 be-b4 98 f1 ee 3c 1c cd cf   ....LU......<...
07c0 - f3 24 24 5c 96 03 27 58-fc 36 ae a2 2f 8f f1 fe   .$$\..'X.6../...
07d0 - da 2b 02 c3 33 bd c8 dd-48 22 2b 60 0f a5 03 10   .+..3...H"+`....
07e0 - fd 77 f8 d0 ed 96 67 4f-fd ea 47 20 70 54 dc a9   .w....gO..G pT..
07f0 - 0c 55 7e e1 96 25 8a d9-b5 da 57 4a be 8d 8e 49   .U~..%....WJ...I
0800 - 43 63 a5 6c 4e 27 87 25-eb 5b 6d fe a2 7f 38 28   Cc.lN'.%.[m...8(
0810 - e0 36 ab ad 39 a5 a5 62-c4 b7 5c 58 2c aa 5d 01   .6..9..b..\X,.].
0820 - 60 a6 62 67 a3 c0 c7 62-23 f4 e7 6c 46 ee b5 d3   `.bg...b#..lF...
0830 - 80 6a 22 13 d2 2d 3f 74-4f ea af 8c 5f b4 38 9c   .j"..-?tO..._.8.
0840 - db ae ce af 84 1e a6 f6-34 51 59 79 d3 e3 75 dc   ........4QYy..u.
0850 - bc d7 f3 73 df 92 ec d2-20 59 6f 9c fb 95 f8 92   ...s.... Yo.....
0860 - 76 18 0a 7c 0f 2c a6 ca-de 8a 62 7b d8 f3 ce 5f   v..|.,....b{..._
0870 - 68 bd 8f 3e c1 74 bb 15-72 3a 16 83 a9 0b e6 4d   h..>.t..r:.....M
0880 - 99 9c d8 57 ec a8 01 51-c7 6f 57 34 5e ab 4a 2c   ...W...Q.oW4^.J,
0890 - 42 f6 4f 1c 89 78 de 26-4e f5 6f 93 4c 15 6b 27   B.O..x.&N.o.L.k'
08a0 - 56 4d 00 54 6c 7a b7 b7-00 03 81 30 82 03 7d 30   VM.Tlz.....0..}0
08b0 - 82 02 e6 a0 03 02 01 02-02 03 12 bb e6 30 0d 06   .............0..
08c0 - 09 2a 86 48 86 f7 0d 01-01 05 05 00 30 4e 31 0b   .*.H........0N1.
08d0 - 30 09 06 03 55 04 06 13-02 55 53 31 10 30 0e 06   0...U....US1.0..
08e0 - 03 55 04 0a 13 07 45 71-75 69 66 61 78 31 2d 30   .U....Equifax1-0
08f0 - 2b 06 03 55 04 0b 13 24-45 71 75 69 66 61 78 20   +..U...$Equifax 
0900 - 53 65 63 75 72 65 20 43-65 72 74 69 66 69 63 61   Secure Certifica
0910 - 74 65 20 41 75 74 68 6f-72 69 74 79 30 1e 17 0d   te Authority0...
0920 - 30 32 30 35 32 31 30 34-30 30 30 30 5a 17 0d 31   020521040000Z..1
0930 - 38 30 38 32 31 30 34 30-30 30 30 5a 30 42 31 0b   80821040000Z0B1.
0940 - 30 09 06 03 55 04 06 13-02 55 53 31 16 30 14 06   0...U....US1.0..
0950 - 03 55 04 0a 13 0d 47 65-6f 54 72 75 73 74 20 49   .U....GeoTrust I
0960 - 6e 63 2e 31 1b 30 19 06-03 55 04 03 13 12 47 65   nc.1.0...U....Ge
0970 - 6f 54 72 75 73 74 20 47-6c 6f 62 61 6c 20 43 41   oTrust Global CA
0980 - 30 82 01 22 30 0d 06 09-2a 86 48 86 f7 0d 01 01   0.."0...*.H.....
0990 - 01 05 00 03 82 01 0f 00-30 82 01 0a 02 82 01 01   ........0.......
09a0 - 00 da cc 18 63 30 fd f4-17 23 1a 56 7e 5b df 3c   ....c0...#.V~[.<
09b0 - 6c 38 e4 71 b7 78 91 d4-bc a1 d8 4c f8 a8 43 b6   l8.q.x.....L..C.
09c0 - 03 e9 4d 21 07 08 88 da-58 2f 66 39 29 bd 05 78   ..M!....X/f9)..x
09d0 - 8b 9d 38 e8 05 b7 6a 7e-71 a4 e6 c4 60 a6 b0 ef   ..8...j~q...`...
09e0 - 80 e4 89 28 0f 9e 25 d6-ed 83 f3 ad a6 91 c7 98   ...(..%.........
09f0 - c9 42 18 35 14 9d ad 98-46 92 2e 4f ca f1 87 43   .B.5....F..O...C
0a00 - c1 16 95 57 2d 50 ef 89-2d 80 7a 57 ad f2 ee 5f   ...W-P..-.zW..._
0a10 - 6b d2 00 8d b9 14 f8 14-15 35 d9 c0 46 a3 7b 72   k........5..F.{r
0a20 - c8 91 bf c9 55 2b cd d0-97 3e 9c 26 64 cc df ce   ....U+...>.&d...
0a30 - 83 19 71 ca 4e e6 d4 d5-7b a9 19 cd 55 de c8 ec   ..q.N...{...U...
0a40 - d2 5e 38 53 e5 5c 4f 8c-2d fe 50 23 36 fc 66 e6   .^8S.\O.-.P#6.f.
0a50 - cb 8e a4 39 19 00 b7 95-02 39 91 0b 0e fe 38 2e   ...9.....9....8.
0a60 - d1 1d 05 9a f6 4d 3e 6f-0f 07 1d af 2c 1e 8f 60   .....M>o....,..`
0a70 - 39 e2 fa 36 53 13 39 d4-5e 26 2b db 3d a8 14 bd   9..6S.9.^&+.=...
0a80 - 32 eb 18 03 28 52 04 71-e5 ab 33 3d e1 38 bb 07   2...(R.q..3=.8..
0a90 - 36 84 62 9c 79 ea 16 30-f4 5f c0 2b e8 71 6b e4   6.b.y..0._.+.qk.
0aa0 - f9 02 03 01 00 01 a3 81-f0 30 81 ed 30 1f 06 03   .........0..0...
0ab0 - 55 1d 23 04 18 30 16 80-14 48 e6 68 f9 2b d2 b2   U.#..0...H.h.+..
0ac0 - 95 d7 47 d8 23 20 10 4f-33 98 90 9f d4 30 1d 06   ..G.# .O3....0..
0ad0 - 03 55 1d 0e 04 16 04 14-c0 7a 98 68 8d 89 fb ab   .U.......z.h....
0ae0 - 05 64 0c 11 7d aa 7d 65-b8 ca cc 4e 30 0f 06 03   .d..}.}e...N0...
0af0 - 55 1d 13 01 01 ff 04 05-30 03 01 01 ff 30 0e 06   U.......0....0..
0b00 - 03 55 1d 0f 01 01 ff 04-04 03 02 01 06 30 3a 06   .U...........0:.
0b10 - 03 55 1d 1f 04 33 30 31-30 2f a0 2d a0 2b 86 29   .U...3010/.-.+.)
0b20 - 68 74 74 70 3a 2f 2f 63-72 6c 2e 67 65 6f 74 72   http://crl.geotr
0b30 - 75 73 74 2e 63 6f 6d 2f-63 72 6c 73 2f 73 65 63   ust.com/crls/sec
0b40 - 75 72 65 63 61 2e 63 72-6c 30 4e 06 03 55 1d 20   ureca.crl0N..U. 
0b50 - 04 47 30 45 30 43 06 04-55 1d 20 00 30 3b 30 39   .G0E0C..U. .0;09
0b60 - 06 08 2b 06 01 05 05 07-02 01 16 2d 68 74 74 70   ..+........-http
0b70 - 73 3a 2f 2f 77 77 77 2e-67 65 6f 74 72 75 73 74   s://www.geotrust
0b80 - 2e 63 6f 6d 2f 72 65 73-6f 75 72 63 65 73 2f 72   .com/resources/r
0b90 - 65 70 6f 73 69 74 6f 72-79 30 0d 06 09 2a 86 48   epository0...*.H
0ba0 - 86 f7 0d 01 01 05 05 00-03 81 81 00 76 e1 12 6e   ............v..n
0bb0 - 4e 4b 16 12 86 30 06 b2-81 08 cf f0 08 c7 c7 71   NK...0.........q
0bc0 - 7e 66 ee c2 ed d4 3b 1f-ff f0 f0 c8 4e d6 43 38   ~f....;.....N.C8
0bd0 - b0 b9 30 7d 18 d0 55 83-a2 6a cb 36 11 9c e8 48   ..0}..U..j.6...H
0be0 - 66 a3 6d 7f b8 13 d4 47-fe 8b 5a 5c 73 fc ae d9   f.m....G..Z\s...
0bf0 - 1b 32 19 38 ab 97 34 14-aa 96 d2 eb a3 1c 14 08   .2.8..4.........
0c00 - 49 b6 bb e5 91 ef 83 36-eb 1d 56 6f ca da bc 73   I......6..Vo...s
0c10 - 63 90 e4 7f 7b 3e 22 cb-3d 07 ed 5f 38 74 9c e3   c...{>".=.._8t..
0c20 - 03 50 4e a1 af 98 ee 61-f2 84 3f 12               .PN....a..?.
depth=3 C = US, O = Equifax, OU = Equifax Secure Certificate Authority
verify return:1
depth=2 C = US, O = GeoTrust Inc., CN = GeoTrust Global CA
verify return:1
depth=1 C = US, O = "GeoTrust, Inc.", CN = RapidSSL CA
verify return:1
depth=0 serialNumber = 0TS5WzauQRJ7sc2b-hTGwK1yxSfEDphF, C = CA, O = alteeve.ca, OU = GT13908817, OU = See www.rapidssl.com/resources/cps (c)11, OU = Domain Control Validated - FreeSSL, CN = alteeve.ca
verify return:1
SSL_connect:SSLv3 read server certificate A
read from 0x196a050 [0x1a10903] (5 bytes => 5 (0x5))
0000 - 16 03 01 02 0d                                    .....
read from 0x196a050 [0x1a10908] (525 bytes => 525 (0x20D))
0000 - 0c 00 02 09 00 80 d6 7d-e4 40 cb bb dc 19 36 d6   .......}.@....6.
0010 - 93 d3 4a fd 0a d5 0c 84-d2 39 a4 5f 52 0b b8 81   ..J......9._R...
0020 - 74 cb 98 bc e9 51 84 9f-91 2e 63 9c 72 fb 13 b4   t....Q....c.r...
0030 - b4 d7 17 7e 16 d5 5a c1-79 ba 42 0b 2a 29 fe 32   ...~..Z.y.B.*).2
0040 - 4a 46 7a 63 5e 81 ff 59-01 37 7b ed dc fd 33 16   JFzc^..Y.7{...3.
0050 - 8a 46 1a ad 3b 72 da e8-86 00 78 04 5b 07 a7 db   .F..;r....x.[...
0060 - ca 78 74 08 7d 15 10 ea-9f cc 9d dd 33 05 07 dd   .xt.}.......3...
0070 - 62 db 88 ae aa 74 7d e0-f4 d6 e2 bd 68 b0 e7 39   b....t}.....h..9
0080 - 3e 0f 24 21 8e b3 00 01-02 00 80 51 5c 13 33 38   >.$!.......Q\.38
0090 - 83 ef 76 6f 23 52 55 bf-23 ba 7f f0 a4 ca 35 01   ..vo#RU.#.....5.
00a0 - 9c 70 e1 61 b2 0d 7b 5c-1c 32 02 c1 ac 14 be e9   .p.a..{\.2......
00b0 - b9 7a 5d 11 9b 53 48 64-cd 12 b8 15 4c df cc 10   .z]..SHd....L...
00c0 - 4e 2b e7 cd 3f 33 68 1a-60 cc f7 18 25 7c e5 ca   N+..?3h.`...%|..
00d0 - c8 cb 45 ba 2a 6d dc 84-5f 26 6f 9a a3 73 b9 7f   ..E.*m.._&o..s..
00e0 - 02 cb 7b a7 ac 59 9f f3-6e c9 01 ed b9 35 99 49   ..{..Y..n....5.I
00f0 - 37 77 68 65 ec e2 f7 17-03 e7 f5 f5 86 33 e6 6c   7whe.........3.l
0100 - 06 3c 15 83 98 74 2e b9-83 31 11 01 00 20 6e 17   .<...t...1... n.
0110 - 3d 2d ec 3e 19 b2 9e 5b-37 38 3a 31 57 3d 0e c1   =-.>...[78:1W=..
0120 - 6b c4 b4 83 d9 6b f0 d3-44 db 9f 18 55 15 e1 09   k....k..D...U...
0130 - 73 59 8c 46 3d a4 47 58-b1 71 a3 32 b5 06 26 8c   sY.F=.GX.q.2..&.
0140 - 27 88 9e 13 c8 12 5d 94-9b 24 54 10 aa 79 e5 b4   '.....]..$T..y..
0150 - 43 f5 5e 4c 01 dc 02 aa-69 02 37 71 4e 26 1c 0b   C.^L....i.7qN&..
0160 - 40 19 c9 95 4d af 93 35-07 7a ff b1 96 7f 03 ce   @...M..5.z......
0170 - 7a eb a2 1c 97 6b d2 97-d2 0f 1a f5 b2 af fb 65   z....k.........e
0180 - 86 b9 e3 38 30 ba f5 02-d6 6b fc da 94 93 8b b3   ...80....k......
0190 - 96 b5 b7 58 dc 36 55 6d-e9 47 e5 4a 33 1d b9 d9   ...X.6Um.G.J3...
01a0 - ec 33 e8 fb 58 c8 74 13-ff dd 40 b7 35 56 63 03   .3..X.t...@.5Vc.
01b0 - 9f 16 2f 72 be 56 56 c3-15 3a c3 10 09 f0 9d f2   ../r.VV..:......
01c0 - 42 52 5a ce d6 db 61 0e-d0 e2 ac 2e 9e 04 30 8e   BRZ...a.......0.
01d0 - 0d d7 07 f9 3e 0a a8 3b-8d 11 5c 6e 21 47 28 2d   ....>..;..\n!G(-
01e0 - 28 31 a6 3d d0 e9 2e 7a-de 4a 00 2a a8 6f 5d 82   (1.=...z.J.*.o].
01f0 - 45 df 3e 06 e3 11 e3 3c-b9 1e 34 b8 bd 60 fd a7   E.>....<..4..`..
0200 - a2 c1 c8 19 61 19 da 10-e4 c3 70 7e 5f            ....a.....p~_
SSL_connect:SSLv3 read server key exchange A
read from 0x196a050 [0x1a10903] (5 bytes => 5 (0x5))
0000 - 16 03 01 00 04                                    .....
read from 0x196a050 [0x1a10908] (4 bytes => 4 (0x4))
0000 - 0e                                                .
0004 - <SPACES/NULS>
SSL_connect:SSLv3 read server done A
write to 0x196a050 [0x1a1add0] (139 bytes => 139 (0x8B))
0000 - 16 03 01 00 86 10 00 00-82 00 80 7f 9d d2 3b 68   ..............;h
0010 - 49 c9 dd ed 4f 35 a0 70-3a 28 0f ce c1 5a 81 ce   I...O5.p:(...Z..
0020 - cd 46 c5 e5 a4 44 25 04-4e b4 48 d8 3b a6 d4 44   .F...D%.N.H.;..D
0030 - 4e 9a dc 20 fa 52 9f eb-52 3b 3c 3e 34 dc ed 34   N.. .R..R;<>4..4
0040 - e5 b7 10 f9 6d 3a c0 84-64 bf b8 91 54 6c 37 1b   ....m:..d...Tl7.
0050 - eb 75 7a 95 aa e8 83 6f-e0 16 f2 af 77 0f 7a 0c   .uz....o....w.z.
0060 - a8 82 27 a4 a5 f2 f0 1b-d2 6e 46 c4 ef 10 7c 39   ..'......nF...|9
0070 - 6c 87 74 ec 68 7e d5 9a-10 ab 10 03 75 a2 fb 4b   l.t.h~......u..K
0080 - 8c 49 4c da 64 49 bd 27-ba 51 a4                  .IL.dI.'.Q.
SSL_connect:SSLv3 write client key exchange A
write to 0x196a050 [0x1a1add0] (6 bytes => 6 (0x6))
0000 - 14 03 01 00 01 01                                 ......
SSL_connect:SSLv3 write change cipher spec A
write to 0x196a050 [0x1a1add0] (53 bytes => 53 (0x35))
0000 - 16 03 01 00 30 b4 8a 74-4d a4 bf b1 54 04 8a 25   ....0..tM...T..%
0010 - 24 f8 81 f1 64 9f 1f 6d-fb bd a7 4c 57 6a a5 63   $...d..m...LWj.c
0020 - fb 3a dd 8e e3 f9 38 f6-22 fd 7e 42 81 2e a2 41   .:....8.".~B...A
0030 - 1f 74 d1 27 02                                    .t.'.
SSL_connect:SSLv3 write finished A
SSL_connect:SSLv3 flush data
read from 0x196a050 [0x1a10903] (5 bytes => 5 (0x5))
0000 - 16 03 01 00 ca                                    .....
read from 0x196a050 [0x1a10908] (202 bytes => 202 (0xCA))
0000 - 04 00 00 c6 00 00 00 00-00 c0 6c f3 41 26 c8 6b   ..........l.A&.k
0010 - 1e 9c 2e 78 af 75 b2 46-34 f4 30 c3 bd e4 ee 2f   ...x.u.F4.0..../
0020 - f6 28 37 f6 7c 55 3b c7-08 ad 1e 48 f1 83 9f 9a   .(7.|U;....H....
0030 - d4 ef 9b 7d 5a 9c f7 5b-92 e9 2f ca c3 e5 44 c7   ...}Z..[../...D.
0040 - 7a c1 ed db 98 1a 18 bd-25 30 3c 50 ad 96 23 22   z.......%0<P..#"
0050 - 7e a1 b7 eb 1d b5 cc 69-2a 43 63 13 4f 21 90 32   ~......i*Cc.O!.2
0060 - 87 94 0b 6a 66 da 99 fa-45 79 cc 53 29 35 59 0d   ...jf...Ey.S)5Y.
0070 - 02 93 c6 c6 af f3 52 79-b5 36 c0 a6 4d 22 9f af   ......Ry.6..M"..
0080 - 4a f2 86 b4 50 68 83 b1-ab a6 a6 ac 6e 4e 18 3d   J...Ph......nN.=
0090 - 80 a7 b4 85 77 06 69 60-fa b2 22 9a 79 14 c6 3e   ....w.i`..".y..>
00a0 - 3e 68 33 4e 1e a9 40 09-47 d0 02 97 8b ba 39 db   >h3N..@.G.....9.
00b0 - 2f b1 1c 2e 66 49 d3 bc-99 cc 56 4f 1d f4 c6 7b   /...fI....VO...{
00c0 - 58 3e 28 df b1 ce 2b 45-36 ca                     X>(...+E6.
SSL_connect:SSLv3 read server session ticket A
read from 0x196a050 [0x1a10903] (5 bytes => 5 (0x5))
0000 - 14 03 01 00 01                                    .....
read from 0x196a050 [0x1a10908] (1 bytes => 1 (0x1))
0000 - 01                                                .
read from 0x196a050 [0x1a10903] (5 bytes => 5 (0x5))
0000 - 16 03 01 00 30                                    ....0
read from 0x196a050 [0x1a10908] (48 bytes => 48 (0x30))
0000 - c0 79 35 bf c6 1e 7e d4-04 cf 68 c7 9d f5 9f 42   .y5...~...h....B
0010 - 03 91 5f 72 ae 5b ec a8-aa e7 af e8 f3 39 1b cd   .._r.[.......9..
0020 - 13 05 56 f2 1b 28 c9 42-4b 67 88 48 20 c2 a5 06   ..V..(.BKg.H ...
SSL_connect:SSLv3 read finished A
---
Certificate chain
 0 s:/serialNumber=0TS5WzauQRJ7sc2b-hTGwK1yxSfEDphF/C=CA/O=alteeve.ca/OU=GT13908817/OU=See www.rapidssl.com/resources/cps (c)11/OU=Domain Control Validated - FreeSSL/CN=alteeve.ca
   i:/C=US/O=GeoTrust, Inc./CN=RapidSSL CA
 1 s:/C=US/O=GeoTrust, Inc./CN=RapidSSL CA
   i:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
 2 s:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
   i:/C=US/O=Equifax/OU=Equifax Secure Certificate Authority
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIEvjCCA6agAwIBAgIDAhUkMA0GCSqGSIb3DQEBBQUAMDwxCzAJBgNVBAYTAlVT
MRcwFQYDVQQKEw5HZW9UcnVzdCwgSW5jLjEUMBIGA1UEAxMLUmFwaWRTU0wgQ0Ew
HhcNMTEwNjE0MTIxOTAxWhcNMTEwNzE2MTU1NjE0WjCB2TEpMCcGA1UEBRMgMFRT
NVd6YXVRUko3c2MyYi1oVEd3SzF5eFNmRURwaEYxCzAJBgNVBAYTAkNBMRQwEgYD
VQQKEwthbHRlZXZlLmNvbTETMBEGA1UECxMKR1QxMzkwODgxNzExMC8GA1UECxMo
U2VlIHd3dy5yYXBpZHNzbC5jb20vcmVzb3VyY2VzL2NwcyAoYykxMTErMCkGA1UE
CxMiRG9tYWluIENvbnRyb2wgVmFsaWRhdGVkIC0gRnJlZVNTTDEUMBIGA1UEAxML
YWx0ZWV2ZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDHtXUD
x6m1IbJ6m3CN8kRd4Bj0BVLGk9MXpTrHRgNo0QFTG+i400xWRrLKYzSILE97I0kH
7443XIqs14ib7aEBkLwy2EYwbYIzWeq1OCyKFuFj57o52Cr6imslRQvJTbjSvqk6
4/9hYPmkmU4/wiULIQfGGx5jcS49MUKYAfSIuIAmt79bALFXhrTYcObs6pjhF0Wn
/4Pgdm+KULsdy8WP9AGETlnDTShzcDnI2oVDuQeuVyYEJLLW1HwDr09yAI8g7SZ3
s79OAWKLYhsQFmWS9bta3INc8lbzYDQs72L07s8mbZtKXnQFdPsjhgdvz7BIbbot
iV0P4MABHJGvAF/zAgMBAAGjggEpMIIBJTAfBgNVHSMEGDAWgBRraT1qGEJK3Y8C
ZTn9NSSGeJEWMDAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEG
CCsGAQUFBwMCMBYGA1UdEQQPMA2CC2FsdGVldmUuY29tMEMGA1UdHwQ8MDowOKA2
oDSGMmh0dHA6Ly9yYXBpZHNzbC1jcmwuZ2VvdHJ1c3QuY29tL2NybHMvcmFwaWRz
c2wuY3JsMB0GA1UdDgQWBBShK06vVQh7NL50/FdB3ryP2UodyTAMBgNVHRMBAf8E
AjAAMEkGCCsGAQUFBwEBBD0wOzA5BggrBgEFBQcwAoYtaHR0cDovL3JhcGlkc3Ns
LWFpYS5nZW90cnVzdC5jb20vcmFwaWRzc2wuY3J0MA0GCSqGSIb3DQEBBQUAA4IB
AQBmi2+o1dKEx4kx+6W64RFeL2dv3w08CxpLrNk47ikKTdkGmCwlClm7OQOwzTsG
kz5ZkM8GF3R3u82RNNBvuY9TV+0UML3pbASEtvAWnSmbsUf4hGRfAzbq4dYTl1tQ
ubJZzPjvIwGZkW5e6NB3VDhJGFjnDlQ1wDe1nnmy1MbZ/ycx1L8ErtMKkEu8NLxT
+LznTCK3s7yM10FE/OBQLpqsulzuiAP8DlMyqt2kJO6mfD3cnXqCC5+4keChEnej
lffQxJ7x19mZaIDor61o9RpfZgZ4yVb4NjcW+n0n3x2i2HyMW1Dbxv4G/5aG9R/k
Nc7PQ2ZT2qFQtcBz7B70yCAT
-----END CERTIFICATE-----
subject=/serialNumber=0TS5WzauQRJ7sc2b-hTGwK1yxSfEDphF/C=CA/O=alteeve.ca/OU=GT13908817/OU=See www.rapidssl.com/resources/cps (c)11/OU=Domain Control Validated - FreeSSL/CN=alteeve.ca
issuer=/C=US/O=GeoTrust, Inc./CN=RapidSSL CA
---
No client certificate CA names sent
---
SSL handshake has read 3984 bytes and written 311 bytes
---
New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: zlib compression
Expansion: zlib compression
SSL-Session:
    Protocol  : TLSv1
    Cipher    : DHE-RSA-AES256-SHA
    Session-ID: 2880725EB8BDD73F469C17BCA54DF373DFE8EDE3D52A1C8F5E0A5919694FB111
    Session-ID-ctx: 
    Master-Key: F329DEA0DF39FF181ACFBCA69BEC417D7CAA4399D73229A1D912CC8236A858FD099B834F5B32C9BF979C4B5948196FC9
    Key-Arg   : None
    Krb5 Principal: None
    PSK identity: None
    PSK identity hint: None
    TLS session ticket:
    0000 - 6c f3 41 26 c8 6b 1e 9c-2e 78 af 75 b2 46 34 f4   l.A&.k...x.u.F4.
    0010 - 30 c3 bd e4 ee 2f f6 28-37 f6 7c 55 3b c7 08 ad   0..../.(7.|U;...
    0020 - 1e 48 f1 83 9f 9a d4 ef-9b 7d 5a 9c f7 5b 92 e9   .H.......}Z..[..
    0030 - 2f ca c3 e5 44 c7 7a c1-ed db 98 1a 18 bd 25 30   /...D.z.......%0
    0040 - 3c 50 ad 96 23 22 7e a1-b7 eb 1d b5 cc 69 2a 43   <P..#"~......i*C
    0050 - 63 13 4f 21 90 32 87 94-0b 6a 66 da 99 fa 45 79   c.O!.2...jf...Ey
    0060 - cc 53 29 35 59 0d 02 93-c6 c6 af f3 52 79 b5 36   .S)5Y.......Ry.6
    0070 - c0 a6 4d 22 9f af 4a f2-86 b4 50 68 83 b1 ab a6   ..M"..J...Ph....
    0080 - a6 ac 6e 4e 18 3d 80 a7-b4 85 77 06 69 60 fa b2   ..nN.=....w.i`..
    0090 - 22 9a 79 14 c6 3e 3e 68-33 4e 1e a9 40 09 47 d0   ".y..>>h3N..@.G.
    00a0 - 02 97 8b ba 39 db 2f b1-1c 2e 66 49 d3 bc 99 cc   ....9./...fI....
    00b0 - 56 4f 1d f4 c6 7b 58 3e-28 df b1 ce 2b 45 36 ca   VO...{X>(...+E6.

    Compression: 1 (zlib compression)
    Start Time: 1308161188
    Timeout   : 300 (sec)
    Verify return code: 0 (ok)
---
GET
write to 0x196a050 [0x1a14e56] (74 bytes => 74 (0x4A))
0000 - 17 03 01 00 20 8a 4c 57-8c b9 d5 d4 c6 1b 56 ce   .... .LW......V.
0010 - 93 b5 78 6b 5f 0e c5 a2-39 2a f9 7a 20 7d 68 85   ..xk_...9*.z }h.
0020 - af 52 e3 5f fc 17 03 01-00 20 c6 c4 19 74 61 64   .R._..... ...tad
0030 - 42 59 e0 52 3f 42 44 53-8b c9 40 69 1c 3d 9b 7f   BY.R?BDS..@i.=..
0040 - aa e8 8f a4 5c de c9 d4-0a a4                     ....\.....
read from 0x196a050 [0x1a10903] (5 bytes => 5 (0x5))
0000 - 17 03 01 00 60                                    ....`
read from 0x196a050 [0x1a10908] (96 bytes => 96 (0x60))
0000 - 46 4c 99 93 29 c9 ed 66-81 43 89 39 26 2b d1 b0   FL..)..f.C.9&+..
0010 - 19 73 eb 51 18 45 54 49-74 43 e0 92 1b f8 af f0   .s.Q.ETItC......
0020 - 0d e1 08 79 96 38 e1 5e-29 9d 66 9c 30 04 8e c4   ...y.8.^).f.0...
0030 - 10 83 49 7e 09 d7 8a ff-4b 11 f9 13 3e ac 77 73   ..I~....K...>.ws
0040 - e8 94 e3 f3 74 db 4e 5f-67 13 1d c4 3a 06 98 b3   ....t.N_g...:...
0050 - da 20 41 3c ca 9a fb 3f-f3 d7 64 a1 e9 f4 0a 98   . A<...?..d.....
<head>
	<title>AN!Wiki - SSL Test Server</title>
</head>
<body>
	<h1>SSL Test</h1>
</body>
read from 0x196a050 [0x1a10903] (5 bytes => 5 (0x5))
0000 - 15 03 01                                          ...
0005 - <SPACES/NULS>
read from 0x196a050 [0x1a10908] (32 bytes => 32 (0x20))
0000 - 2e bb a7 d6 dc ce 6c 34-dc 2e 43 c7 89 02 a9 5c   ......l4..C....\
0010 - 3b 3e d0 43 1c ec fa c7-89 48 fd 76 58 82 ef 45   ;>.C.....H.vX..E
SSL3 alert read:warning:close notify
closed
write to 0x196a050 [0x1a14e53] (37 bytes => 37 (0x25))
0000 - 15 03 01 00 20 d8 6f 46-24 e9 fa 0c c9 9f aa 2d   .... .oF$......-
0010 - db 69 2a d8 fb 61 66 b0-23 23 f9 a4 ac 49 b7 e6   .i*..af.##...I..
0020 - 31 73 56 05 ed                                    1sV..
SSL3 alert write:warning:close notify

Perfect!

Open Port 443 On The Firewall

At this point, if you try to connect to the SSL virtual host remotely, you will fail because port 443 is not yet open.

Use your favourite program to open inbound TCP port 443. I like to directly edit the firewall's config.

vim /etc/sysconfig/iptables
# Firewall configuration written by system-config-firewall
# Manual customization of this file is not recommended.
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 443 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT
/etc/init.d/iptables restart
iptables: Flushing firewall rules:                         [  OK  ]
iptables: Setting chains to policy ACCEPT: filter          [  OK  ]
iptables: Unloading modules:                               [  OK  ]
iptables: Applying firewall rules:                         [  OK  ]

Browse to the New Virtual Host

You should now be able to access the new SSL virtual host! Simply browse to https://alteeve.ca (replace with your domain).

Test SSL virtual host in Firefox 4.

Note the 'alteeve.ca' to the left of the address bar showing that the site is encrypted and verified!

Common apachectl -t Configuration Problems

httpd: apr_sockaddr_info_get() failed for <domain>

Make sure that the hostname for the server resolves to an IP address. This is done by ensuring that the name returned by hostname has a DNS entry or has an entry in the /etc/hosts file.

[warn] NameVirtualHost *:80 has no VirtualHosts

This will be shown when no virtual host containers have been configured ye.

PostgreSQL

We need to initialize the postgres core databases before we can start it for the first time.

/etc/init.d/postgresql-9.4 initdb
Initializing database:                                     [  OK  ]

From now on, we can start PostgreSQL normally.

/etc/init.d/postgresql-9.4 restart
Stopping postgresql-9.4 service:                           [  OK  ]
Starting postgresql-9.4 service:                           [  OK  ]

Create the admin user called alteeve which will own the databases we will create and use.

su - postgres
createuser -S -d -R alteeve
psql template1

At the shell, run the following:

Note: If your password has a single-quote in it, escape it with (ie: ALTER USER alteeve WITH PASSWORD 'someones secret password';).
ALTER USER alteeve WITH PASSWORD 'secret';
ALTER ROLE
\q

Tell PostgreSQL to require a password for all local and incoming connections. Also enable access to the database from the local network.

vim /var/lib/pgsql/9.4/data/pg_hba.conf
# TYPE  DATABASE    USER        CIDR-ADDRESS          METHOD
host    all         all         10.222.0.0/16         md5

# "local" is for Unix domain socket connections only
local   all         all                               md5
# IPv4 local connections:
host    all         all         127.0.0.1/32          md5
# IPv6 local connections:
host    all         all         ::1/128               md5

Reload PostgreSQL's configuration.

/etc/init.d/postgresql-9.4 reload

Now create a Database that is owned by the alteeve user, then connect to it to make sure we're asked for a password.

su postgres -c "createdb an_wiki -O alteeve"
psql an_wiki -U alteeve
Password for user alteeve: 
psql (9.4.1)
Type "help" for help.

an_wiki=>

Now load a database from a backup file.

psql an_wiki -U alteeve -f /var/www/ssl_alteeve.ca/temp/an_wiki_3.out
Password for user alteeve:
SET
SET
SET
SET
SET
SET
CREATE SCHEMA
ALTER SCHEMA
psql:/root/an_wiki_2.out:25: ERROR:  language "plpgsql" already exists
ALTER LANGUAGE
SET
CREATE TYPE
ALTER TYPE
CREATE FUNCTION
ALTER FUNCTION
CREATE FUNCTION
ALTER FUNCTION
CREATE FUNCTION
ALTER FUNCTION
CREATE FUNCTION
ALTER FUNCTION
SET
SET
CREATE TABLE
ALTER TABLE
CREATE SEQUENCE
ALTER TABLE
 setval 
--------
     39
(1 row)

CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE SEQUENCE
ALTER TABLE
 setval 
--------
     28
(1 row)

CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE SEQUENCE
ALTER TABLE
 setval 
--------
   2507
(1 row)

CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE SEQUENCE
ALTER TABLE
 setval 
--------
  14274
(1 row)

CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE SEQUENCE
ALTER TABLE
 setval 
--------
   6586
(1 row)

CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE SEQUENCE
ALTER TABLE
 setval 
--------
     50
(1 row)

CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE SEQUENCE
ALTER TABLE
 setval 
--------
   1563
(1 row)

CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE SEQUENCE
ALTER TABLE
 setval 
--------
      1
(1 row)

CREATE TABLE
ALTER TABLE
CREATE SEQUENCE
ALTER TABLE
 setval 
--------
   6335
(1 row)

CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE SEQUENCE
ALTER TABLE
 setval 
--------
   6741
(1 row)

CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE SEQUENCE
ALTER TABLE
 setval 
--------
   6663
(1 row)

CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE SEQUENCE
ALTER TABLE
 setval 
--------
      1
(1 row)

CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE SEQUENCE
ALTER TABLE
 setval 
--------
     20
(1 row)

CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
COPY 137
COPY 2
COPY 9
COPY 0
COPY 0
COPY 2372
COPY 28
COPY 0
COPY 742
COPY 872
COPY 92
COPY 21
COPY 0
COPY 0
COPY 6626
COPY 0
COPY 2
COPY 6586
COPY 0
COPY 2
COPY 16
COPY 44
COPY 28
COPY 51
COPY 104959
COPY 254
COPY 1497
COPY 0
COPY 0
COPY 6335
COPY 3901
COPY 0
COPY 0
COPY 0
COPY 0
COPY 0
COPY 385
COPY 124
COPY 6525
COPY 1
COPY 0
COPY 1276
COPY 0
COPY 0
COPY 1
COPY 7
COPY 0
COPY 2
COPY 0
COPY 29
COPY 0
COPY 12
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE TRIGGER
CREATE TRIGGER
CREATE TRIGGER
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
psql:/root/an_wiki_2.out:145782: WARNING:  no privileges could be revoked for "public"
REVOKE
psql:/root/an_wiki_2.out:145783: WARNING:  no privileges could be revoked for "public"
REVOKE
psql:/root/an_wiki_2.out:145784: WARNING:  no privileges were granted for "public"
GRANT
psql:/root/an_wiki_2.out:145785: WARNING:  no privileges were granted for "public"
GRANT

Voila!

Media Wiki Problem

If you moved a MediaWiki DB and it generated an error like this in the log file:

[Wed Jun 15 21:37:20 2011] [error] [client 206.108.5.162] PHP Warning:  pg_query(): Query failed: ERROR:  relation "objectcache" does not exist\nLINE 1: ...ECT /* SqlBagOStuff::get  */  value,exptime  FROM objectcach...\n
                                                             ^ in /var/www/ssl_alteeve.ca/html/includes/db/DatabasePostgres.php on line 584
[Wed Jun 15 21:37:20 2011] [error] [client 206.108.5.162] PHP Warning:  pg_query(): Query failed: ERROR:  relation "l10n_cache" does not exist\nLINE 1: ... LCStore_DB::get 206.108.5.162 */  lc_value  FROM l10n_cache...\n
                                                             ^ in /var/www/ssl_alteeve.ca/html/includes/db/DatabasePostgres.php on line 584

The fix is to run:

ALTER DATABASE an_wiki SET search_path=mediawiki;

Of course, replace an_wiki with the name of your wiki database.

MySQL

Start MySQL for the first time:

/etc/init.d/mysqld start
Initializing MySQL database:  Installing MySQL system tables...
OK
Filling help tables...
OK

To start mysqld at boot time you have to copy
support-files/mysql.server to the right place for your system

PLEASE REMEMBER TO SET A PASSWORD FOR THE MySQL root USER !
To do so, start the server, then issue the following commands:

/usr/bin/mysqladmin -u root password 'new-password'
/usr/bin/mysqladmin -u root -h asakusa.alteeve.ca password 'new-password'

Alternatively you can run:
/usr/bin/mysql_secure_installation

which will also give you the option of removing the test
databases and anonymous user created by default.  This is
strongly recommended for production servers.

See the manual for more instructions.

You can start the MySQL daemon with:
cd /usr ; /usr/bin/mysqld_safe &

You can test the MySQL daemon with mysql-test-run.pl
cd /usr/mysql-test ; perl mysql-test-run.pl

Please report any problems with the /usr/bin/mysqlbug script!

                                                           [  OK  ]
Starting mysqld:                                           [  OK  ]

Secure the server.

mysql_secure_installation
NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MySQL
      SERVERS IN PRODUCTION USE!  PLEASE READ EACH STEP CAREFULLY!


In order to log into MySQL to secure it, we'll need the current
password for the root user.  If you've just installed MySQL, and
you haven't set the root password yet, the password will be blank,
so you should just press enter here.

Enter current password for root (enter for none): 
OK, successfully used password, moving on...

Setting the root password ensures that nobody can log into the MySQL
root user without the proper authorisation.

Set root password? [Y/n] y
New password: 
Re-enter new password: 
Password updated successfully!
Reloading privilege tables..
 ... Success!


By default, a MySQL installation has an anonymous user, allowing anyone
to log into MySQL without having to have a user account created for
them.  This is intended only for testing, and to make the installation
go a bit smoother.  You should remove them before moving into a
production environment.

Remove anonymous users? [Y/n] y
 ... Success!

Normally, root should only be allowed to connect from 'localhost'.  This
ensures that someone cannot guess at the root password from the network.

Disallow root login remotely? [Y/n]  
 ... Success!

By default, MySQL comes with a database named 'test' that anyone can
access.  This is also intended only for testing, and should be removed
before moving into a production environment.

Remove test database and access to it? [Y/n] 
 - Dropping test database...
 ... Success!
 - Removing privileges on test database...
 ... Success!

Reloading the privilege tables will ensure that all changes made so far
will take effect immediately.

Reload privilege tables now? [Y/n] 
 ... Success!

Cleaning up...



All done!  If you've completed all of the above steps, your MySQL
installation should now be secure.

Thanks for using MySQL!

BIND

Note: This is not meant to cover creating the actual zone files for DNS. It's goal is to setup BIND on your EL6 server only.

This is the BIND named server that handles DNS resolution. It will be setup in two parts; The global options and then the zones file.

Install bind

yum install bind bind-libs bind-utils

Global Configuration

Edit the main configuration file, making a backup first.

cp /etc/named.conf /etc/named.conf.orig
vim /etc/named.conf

Enable queries on any interface and answer queries for any domain, not just ours. Edit or add the following;

        listen-on port 53       { any; };
        allow-query             { any; };
        allow-query-cache       { any; };

For now, we're going to disable DNSSEC. Make the following changes;

        dnssec-enable           no;
        dnssec-validation       no;

Now tell bind where to look for a domain name's IP when we don't know. Add;

        forwarders {
                // These are Google's open DNS servers
                8.8.8.8;
                8.8.4.4;
        };

This server will have a slave, and we want to notify that slave when a record changes. Add;

        notify                  yes;

Done. I like to clean up the file to put the variables in line with one another. With this in mind, let's look at the changes as a unified diff;

diff -u /etc/named.conf.orig /etc/named.conf
--- /etc/named.conf.orig	2012-02-05 00:54:48.434068501 -0500
+++ /etc/named.conf	2012-02-05 13:45:16.484083319 -0500
@@ -8,18 +8,26 @@
 //
 
 options {
-	listen-on port 53 { 127.0.0.1; };
-	listen-on-v6 port 53 { ::1; };
-	directory 	"/var/named";
-	dump-file 	"/var/named/data/cache_dump.db";
-        statistics-file "/var/named/data/named_stats.txt";
-        memstatistics-file "/var/named/data/named_mem_stats.txt";
-	allow-query     { localhost; };
-	recursion yes;
-
-	dnssec-enable yes;
-	dnssec-validation yes;
-	dnssec-lookaside auto;
+	listen-on port		53 { any; };
+	listen-on-v6 port	53 { ::1; };
+	directory		"/var/named";
+	dump-file 		"/var/named/data/cache_dump.db";
+        statistics-file		"/var/named/data/named_stats.txt";
+        memstatistics-file	"/var/named/data/named_mem_stats.txt";
+	allow-query		{ any; };
+	allow-query-cache 	{ any; };
+	recursion 		yes;
+	notify			yes;
+
+	dnssec-enable		no;
+	dnssec-validation	no;
+	dnssec-lookaside	auto;
+
+	forwarders {
+		// These are Google's open DNS servers
+		8.8.8.8;
+		8.8.4.4;
+	};
 
 	/* Path to ISC DLV key */
 	bindkeys-file "/etc/named.iscdlv.key";

Setting Up rndc

This ensures that we're transferring zone data between the real master and slave servers.

Note: This will take a long time to finish. Please be patient!
rndc-confgen -a

Eventually, this will be returned;

wrote key file "/etc/rndc.key"

Now make sure everything is owned by named:named.

chown named:named /etc/rndc.key 
chown -R named:named /etc/named

Now copy the rndc.key to the other node:

rsync -av /etc/rndc.key root@ns2.alteeve.ca:/etc/
root@ns2.alteeve.ca's password: 
sending incremental file list

sent 49 bytes  received 15 bytes  11.64 bytes/sec
total size is 77  speedup is 1.20

Done.

Adding Zones

This is where we tell BIND which zones we have SOA for. This includes the pointers to the actual files on disk with each domain's information.

Backup then edit the zones file.

cp /etc/named.rfc1912.zones /etc/named.rfc1912.zones.orig
vim /etc/named.rfc1912.zones

On the master server:

In here is where we add the entries for the domains we have SOA for at the end of the file. These will differ for every install, so only two examples will be shown.

// Our zones which this server is SOA for.

zone "digimer.ca" in {
	type master;
	file "/etc/named/db.digimer.ca";
	allow-transfer {
		65.39.153.67;
		10.255.5.4;
		10.222.1.4;
	};
};

On the slave server:

// Our zones which this server is SOA for.

zone "digimer.ca" in {
	type slave;
	file "/etc/named/bak.digimer.ca";
	masters {
		65.39.153.66;
		10.255.5.3;
		10.222.1.3;
	};
};


This tutorial does not aim to cover actual zone files, but here is one for reference:

cat /etc/named/db.digimer.ca
$ORIGIN .
$TTL 600	; Time To Live.
digimer.ca		IN SOA ns1.alteeve.ca. admin.alteeve.ca. (
				2013022106	;	Serial Number (yyyymmdd##)
				300		;	refresh (in seconds)
				180		;	retry (in seconds)
				300		;	expire (in seconds)
				300		;	minimum (in seconds)
				)
			NS	ns1.alteeve.ca.
			NS	ns2.alteeve.ca.
			A	65.39.153.65
			MX	10	mail.digimer.ca.
$ORIGIN digimer.ca.
localhost		A	127.0.0.1
mail			A	64.34.141.3
www			CNAME	digimer.ca.

Start the named daemon on the master node;

/etc/init.d/named start
Starting named:                                            [  OK  ]

In syslog, you should see something like this;

Feb 23 18:21:46 vm03-dns01 named[2126]: starting BIND 9.8.2rc1-RedHat-9.8.2-0.10.rc1.el6_3.6 -u named
Feb 23 18:21:46 vm03-dns01 named[2126]: built with '--build=x86_64-redhat-linux-gnu' '--host=x86_64-redhat-linux-gnu' '--target=x86_64-redhat-linux-gnu' '--program-prefix=' '--prefix=/usr' '--exec-prefix=/usr' '--bindir=/usr/bin' '--sbindir=/usr/sbin' '--sysconfdir=/etc' '--datadir=/usr/share' '--includedir=/usr/include' '--libdir=/usr/lib64' '--libexecdir=/usr/libexec' '--sharedstatedir=/var/lib' '--mandir=/usr/share/man' '--infodir=/usr/share/info' '--with-libtool' '--localstatedir=/var' '--enable-threads' '--enable-ipv6' '--with-pic' '--disable-static' '--disable-openssl-version-check' '--with-dlz-ldap=yes' '--with-dlz-postgres=yes' '--with-dlz-mysql=yes' '--with-dlz-filesystem=yes' '--with-gssapi=yes' '--disable-isc-spnego' '--with-docbook-xsl=/usr/share/sgml/docbook/xsl-stylesheets' '--enable-fixed-rrset' 'build_alias=x86_64-redhat-linux-gnu' 'host_alias=x86_64-redhat-linux-gnu' 'target_alias=x86_64-redhat-linux-gnu' 'CFLAGS= -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic' 'CPPFLAGS= -DDIG_SIGCHASE'
Feb 23 18:21:46 vm03-dns01 named[2126]: ----------------------------------------------------
Feb 23 18:21:46 vm03-dns01 named[2126]: BIND 9 is maintained by Internet Systems Consortium,
Feb 23 18:21:46 vm03-dns01 named[2126]: Inc. (ISC), a non-profit 501(c)(3) public-benefit 
Feb 23 18:21:46 vm03-dns01 named[2126]: corporation.  Support and training for BIND 9 are 
Feb 23 18:21:46 vm03-dns01 named[2126]: available at https://www.isc.org/support
Feb 23 18:21:46 vm03-dns01 named[2126]: ----------------------------------------------------
Feb 23 18:21:46 vm03-dns01 named[2126]: adjusted limit on open files from 4096 to 1048576
Feb 23 18:21:46 vm03-dns01 named[2126]: found 2 CPUs, using 2 worker threads
Feb 23 18:21:46 vm03-dns01 named[2126]: using up to 4096 sockets
Feb 23 18:21:46 vm03-dns01 named[2126]: loading configuration from '/etc/named.conf'
Feb 23 18:21:46 vm03-dns01 named[2126]: reading built-in trusted keys from file '/etc/named.iscdlv.key'
Feb 23 18:21:46 vm03-dns01 named[2126]: using default UDP/IPv4 port range: [1024, 65535]
Feb 23 18:21:46 vm03-dns01 named[2126]: using default UDP/IPv6 port range: [1024, 65535]
Feb 23 18:21:46 vm03-dns01 named[2126]: listening on IPv4 interface lo, 127.0.0.1#53
Feb 23 18:21:46 vm03-dns01 named[2126]: listening on IPv4 interface eth0, 65.39.153.66#53
Feb 23 18:21:46 vm03-dns01 named[2126]: listening on IPv4 interface eth0:0, 10.255.5.3#53
Feb 23 18:21:46 vm03-dns01 named[2126]: listening on IPv4 interface eth0:1, 10.222.1.3#53
Feb 23 18:21:46 vm03-dns01 named[2126]: listening on IPv6 interface lo, ::1#53
Feb 23 18:21:46 vm03-dns01 named[2126]: generating session key for dynamic DNS
Feb 23 18:21:46 vm03-dns01 named[2126]: sizing zone task pool based on 7 zones
Feb 23 18:21:46 vm03-dns01 named[2126]: using built-in DLV key for view _default
Feb 23 18:21:46 vm03-dns01 named[2126]: set up managed keys zone for view _default, file '/var/named/dynamic/managed-keys.bind'
Feb 23 18:21:46 vm03-dns01 named[2126]: Warning: 'empty-zones-enable/disable-empty-zone' not set: disabling RFC 1918 empty zones
Feb 23 18:21:46 vm03-dns01 named[2126]: automatic empty zone: 127.IN-ADDR.ARPA
Feb 23 18:21:46 vm03-dns01 named[2126]: automatic empty zone: 254.169.IN-ADDR.ARPA
Feb 23 18:21:46 vm03-dns01 named[2126]: automatic empty zone: 2.0.192.IN-ADDR.ARPA
Feb 23 18:21:46 vm03-dns01 named[2126]: automatic empty zone: 100.51.198.IN-ADDR.ARPA
Feb 23 18:21:46 vm03-dns01 named[2126]: automatic empty zone: 113.0.203.IN-ADDR.ARPA
Feb 23 18:21:46 vm03-dns01 named[2126]: automatic empty zone: 255.255.255.255.IN-ADDR.ARPA
Feb 23 18:21:46 vm03-dns01 named[2126]: automatic empty zone: 0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.IP6.ARPA
Feb 23 18:21:46 vm03-dns01 named[2126]: automatic empty zone: D.F.IP6.ARPA
Feb 23 18:21:46 vm03-dns01 named[2126]: automatic empty zone: 8.E.F.IP6.ARPA
Feb 23 18:21:46 vm03-dns01 named[2126]: automatic empty zone: 9.E.F.IP6.ARPA
Feb 23 18:21:46 vm03-dns01 named[2126]: automatic empty zone: A.E.F.IP6.ARPA
Feb 23 18:21:46 vm03-dns01 named[2126]: automatic empty zone: B.E.F.IP6.ARPA
Feb 23 18:21:46 vm03-dns01 named[2126]: automatic empty zone: 8.B.D.0.1.0.0.2.IP6.ARPA
Feb 23 18:21:46 vm03-dns01 named[2126]: command channel listening on 127.0.0.1#953
Feb 23 18:21:46 vm03-dns01 named[2126]: command channel listening on ::1#953
Feb 23 18:21:46 vm03-dns01 named[2126]: zone 0.in-addr.arpa/IN: loaded serial 0
Feb 23 18:21:46 vm03-dns01 named[2126]: zone 1.0.0.127.in-addr.arpa/IN: loaded serial 0
Feb 23 18:21:46 vm03-dns01 named[2126]: zone 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa/IN: loaded serial 0
Feb 23 18:21:46 vm03-dns01 named[2126]: zone digimer.ca/IN: loaded serial 2013022106
Feb 23 18:21:46 vm03-dns01 named[2126]: zone localhost.localdomain/IN: loaded serial 0
Feb 23 18:21:46 vm03-dns01 named[2126]: zone localhost/IN: loaded serial 0
Feb 23 18:21:46 vm03-dns01 named[2126]: managed-keys-zone ./IN: loaded serial 3
Feb 23 18:21:46 vm03-dns01 named[2126]: zone digimer.ca/IN: sending notifies (serial 2013022106)
Feb 23 18:21:46 vm03-dns01 named[2126]: running

You can test that it's working by querying one of your zones.

dig digimer.ca @localhost
; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.10.rc1.el6_3.6 <<>> digimer.ca @localhost
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 18362
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 1

;; QUESTION SECTION:
;digimer.ca.			IN	A

;; ANSWER SECTION:
digimer.ca.		600	IN	A	65.39.153.65

;; AUTHORITY SECTION:
digimer.ca.		600	IN	NS	ns1.alteeve.ca.
digimer.ca.		600	IN	NS	ns2.alteeve.ca.

;; ADDITIONAL SECTION:
ns2.alteeve.ca.		268	IN	A	78.46.37.135

;; Query time: 0 msec
;; SERVER: ::1#53(::1)
;; WHEN: Sat Feb 23 18:27:04 2013
;; MSG SIZE  rcvd: 104

Now start named on the slave. First though, check /etc/named/ to see that there are no files there yet.

ls -lah /etc/named/
total 8.0K
drwxr-x---   2 named named 4.0K Dec  6 15:49 .
drwxr-xr-x. 66 root  root  4.0K Feb 23 18:13 ..

Now start named;

/etc/init.d/named start
Starting named:                                            [  OK  ]

In syslog on the slave, you will see something like;

Feb 23 18:29:28 vm04-dns02 named[2072]: starting BIND 9.8.2rc1-RedHat-9.8.2-0.10.rc1.el6_3.6 -u named
Feb 23 18:29:28 vm04-dns02 named[2072]: built with '--build=x86_64-redhat-linux-gnu' '--host=x86_64-redhat-linux-gnu' '--target=x86_64-redhat-linux-gnu' '--program-prefix=' '--prefix=/usr' '--exec-prefix=/usr' '--bindir=/usr/bin' '--sbindir=/usr/sbin' '--sysconfdir=/etc' '--datadir=/usr/share' '--includedir=/usr/include' '--libdir=/usr/lib64' '--libexecdir=/usr/libexec' '--sharedstatedir=/var/lib' '--mandir=/usr/share/man' '--infodir=/usr/share/info' '--with-libtool' '--localstatedir=/var' '--enable-threads' '--enable-ipv6' '--with-pic' '--disable-static' '--disable-openssl-version-check' '--with-dlz-ldap=yes' '--with-dlz-postgres=yes' '--with-dlz-mysql=yes' '--with-dlz-filesystem=yes' '--with-gssapi=yes' '--disable-isc-spnego' '--with-docbook-xsl=/usr/share/sgml/docbook/xsl-stylesheets' '--enable-fixed-rrset' 'build_alias=x86_64-redhat-linux-gnu' 'host_alias=x86_64-redhat-linux-gnu' 'target_alias=x86_64-redhat-linux-gnu' 'CFLAGS= -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic' 'CPPFLAGS= -DDIG_SIGCHASE'
Feb 23 18:29:28 vm04-dns02 named[2072]: ----------------------------------------------------
Feb 23 18:29:28 vm04-dns02 named[2072]: BIND 9 is maintained by Internet Systems Consortium,
Feb 23 18:29:28 vm04-dns02 named[2072]: Inc. (ISC), a non-profit 501(c)(3) public-benefit 
Feb 23 18:29:28 vm04-dns02 named[2072]: corporation.  Support and training for BIND 9 are 
Feb 23 18:29:28 vm04-dns02 named[2072]: available at https://www.isc.org/support
Feb 23 18:29:28 vm04-dns02 named[2072]: ----------------------------------------------------
Feb 23 18:29:28 vm04-dns02 named[2072]: adjusted limit on open files from 4096 to 1048576
Feb 23 18:29:28 vm04-dns02 named[2072]: found 2 CPUs, using 2 worker threads
Feb 23 18:29:28 vm04-dns02 named[2072]: using up to 4096 sockets
Feb 23 18:29:28 vm04-dns02 named[2072]: loading configuration from '/etc/named.conf'
Feb 23 18:29:28 vm04-dns02 named[2072]: reading built-in trusted keys from file '/etc/named.iscdlv.key'
Feb 23 18:29:28 vm04-dns02 named[2072]: using default UDP/IPv4 port range: [1024, 65535]
Feb 23 18:29:28 vm04-dns02 named[2072]: using default UDP/IPv6 port range: [1024, 65535]
Feb 23 18:29:28 vm04-dns02 named[2072]: listening on IPv4 interface lo, 127.0.0.1#53
Feb 23 18:29:28 vm04-dns02 named[2072]: listening on IPv4 interface eth0, 65.39.153.67#53
Feb 23 18:29:28 vm04-dns02 named[2072]: listening on IPv4 interface eth0:0, 10.255.5.4#53
Feb 23 18:29:28 vm04-dns02 named[2072]: listening on IPv4 interface eth0:1, 10.222.1.4#53
Feb 23 18:29:28 vm04-dns02 named[2072]: listening on IPv6 interface lo, ::1#53
Feb 23 18:29:28 vm04-dns02 named[2072]: generating session key for dynamic DNS
Feb 23 18:29:28 vm04-dns02 named[2072]: sizing zone task pool based on 7 zones
Feb 23 18:29:28 vm04-dns02 named[2072]: using built-in DLV key for view _default
Feb 23 18:29:28 vm04-dns02 named[2072]: set up managed keys zone for view _default, file '/var/named/dynamic/managed-keys.bind'
Feb 23 18:29:28 vm04-dns02 named[2072]: Warning: 'empty-zones-enable/disable-empty-zone' not set: disabling RFC 1918 empty zones
Feb 23 18:29:28 vm04-dns02 named[2072]: automatic empty zone: 127.IN-ADDR.ARPA
Feb 23 18:29:28 vm04-dns02 named[2072]: automatic empty zone: 254.169.IN-ADDR.ARPA
Feb 23 18:29:28 vm04-dns02 named[2072]: automatic empty zone: 2.0.192.IN-ADDR.ARPA
Feb 23 18:29:28 vm04-dns02 named[2072]: automatic empty zone: 100.51.198.IN-ADDR.ARPA
Feb 23 18:29:28 vm04-dns02 named[2072]: automatic empty zone: 113.0.203.IN-ADDR.ARPA
Feb 23 18:29:28 vm04-dns02 named[2072]: automatic empty zone: 255.255.255.255.IN-ADDR.ARPA
Feb 23 18:29:28 vm04-dns02 named[2072]: automatic empty zone: 0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.IP6.ARPA
Feb 23 18:29:28 vm04-dns02 named[2072]: automatic empty zone: D.F.IP6.ARPA
Feb 23 18:29:28 vm04-dns02 named[2072]: automatic empty zone: 8.E.F.IP6.ARPA
Feb 23 18:29:28 vm04-dns02 named[2072]: automatic empty zone: 9.E.F.IP6.ARPA
Feb 23 18:29:28 vm04-dns02 named[2072]: automatic empty zone: A.E.F.IP6.ARPA
Feb 23 18:29:28 vm04-dns02 named[2072]: automatic empty zone: B.E.F.IP6.ARPA
Feb 23 18:29:28 vm04-dns02 named[2072]: automatic empty zone: 8.B.D.0.1.0.0.2.IP6.ARPA
Feb 23 18:29:28 vm04-dns02 named[2072]: command channel listening on 127.0.0.1#953
Feb 23 18:29:28 vm04-dns02 named[2072]: command channel listening on ::1#953
Feb 23 18:29:28 vm04-dns02 named[2072]: zone 0.in-addr.arpa/IN: loaded serial 0
Feb 23 18:29:28 vm04-dns02 named[2072]: zone 1.0.0.127.in-addr.arpa/IN: loaded serial 0
Feb 23 18:29:28 vm04-dns02 named[2072]: zone 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa/IN: loaded serial 0
Feb 23 18:29:28 vm04-dns02 named[2072]: zone localhost.localdomain/IN: loaded serial 0
Feb 23 18:29:28 vm04-dns02 named[2072]: zone localhost/IN: loaded serial 0
Feb 23 18:29:28 vm04-dns02 named[2072]: managed-keys-zone ./IN: loaded serial 0
Feb 23 18:29:28 vm04-dns02 named[2072]: running
Feb 23 18:29:28 vm04-dns02 named[2072]: zone digimer.ca/IN: Transfer started.
Feb 23 18:29:28 vm04-dns02 named[2072]: transfer of 'digimer.ca/IN' from 65.39.153.66#53: connected using 65.39.153.67#47099
Feb 23 18:29:28 vm04-dns02 named[2072]: zone digimer.ca/IN: transferred serial 2013022106
Feb 23 18:29:28 vm04-dns02 named[2072]: transfer of 'digimer.ca/IN' from 65.39.153.66#53: Transfer completed: 1 messages, 9 records, 247 bytes, 0.001 secs (247000 bytes/sec)

If you look in syslog on the master, you will see that the digimer.ca domain was transferred;

Feb 23 18:29:28 vm03-dns01 named[2126]: client 65.39.153.67#47099: transfer of 'digimer.ca/IN': AXFR started
Feb 23 18:29:28 vm03-dns01 named[2126]: client 65.39.153.67#47099: transfer of 'digimer.ca/IN': AXFR ended

Indeed, you will now see that the /etc/named/bak.digimer.ca file was created.

ls -lah /etc/named/
total 12K
drwxr-x---   2 named named 4.0K Feb 23 18:29 .
drwxr-xr-x. 66 root  root  4.0K Feb 23 18:13 ..
-rw-r--r--   1 named named  438 Feb 23 18:29 bak.digimer.ca

We can confirm that it's working by querying the slave;

dig digimer.ca @localhost
; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.10.rc1.el6_3.6 <<>> digimer.ca @localhost
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 15602
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 0

;; QUESTION SECTION:
;digimer.ca.			IN	A

;; ANSWER SECTION:
digimer.ca.		600	IN	A	65.39.153.65

;; AUTHORITY SECTION:
digimer.ca.		600	IN	NS	ns1.alteeve.ca.
digimer.ca.		600	IN	NS	ns2.alteeve.ca.

;; Query time: 0 msec
;; SERVER: ::1#53(::1)
;; WHEN: Sat Feb 23 18:32:52 2013
;; MSG SIZE  rcvd: 88

Excellent! Now you can add more DNS servers to the master server.

Adding a Firewall Entry

Assuming you have a firewall running, be sure to add an entry for TCP port 53.

(Re)Start BIND

Once all the configuration files and domain zone files are in place, (re)start the named service.

/etc/init.d/named restart
Stopping named: .                                          [  OK  ]
Starting named:                                            [  OK  ]

Testing Name resolution

To properly test name resolution, you will want to resolve a domain we are SOA for and another domain which we are not. We will repeat this twice, once on the server and once from a remote machine to ensure that it is answering remote queries. Note that in the examples below, my DNS server's IP address is 78.46.37.135.

On the server;

Query alteeve.ca, which we're SOA for.

dig alteeve.ca @localhost
; <<>> DiG 9.7.3-P3-RedHat-9.7.3-8.P3.el6_2.2 <<>> alteeve.ca @localhost
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 1418
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 2

;; QUESTION SECTION:
;alteeve.ca.			IN	A

;; ANSWER SECTION:
alteeve.ca.		600	IN	A	192.139.81.121

;; AUTHORITY SECTION:
alteeve.ca.		600	IN	NS	ns1.alteeve.ca.
alteeve.ca.		600	IN	NS	ns2.alteeve.ca.

;; ADDITIONAL SECTION:
ns1.alteeve.ca.	600	IN	A	192.139.81.117
ns2.alteeve.ca.	600	IN	A	192.139.81.119

;; Query time: 0 msec
;; SERVER: ::1#53(::1)
;; WHEN: Sun Feb  5 13:57:11 2012
;; MSG SIZE  rcvd: 113

Now query google.ca which we obviously are not SOA for.

dig google.ca @localhost
; <<>> DiG 9.7.3-P3-RedHat-9.7.3-8.P3.el6_2.2 <<>> google.ca @localhost
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 56760
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 13, ADDITIONAL: 0

;; QUESTION SECTION:
;google.ca.			IN	A

;; ANSWER SECTION:
google.ca.		300	IN	A	74.125.232.56

;; AUTHORITY SECTION:
.			2967	IN	NS	f.root-servers.net.
.			2967	IN	NS	c.root-servers.net.
.			2967	IN	NS	b.root-servers.net.
.			2967	IN	NS	a.root-servers.net.
.			2967	IN	NS	k.root-servers.net.
.			2967	IN	NS	i.root-servers.net.
.			2967	IN	NS	e.root-servers.net.
.			2967	IN	NS	h.root-servers.net.
.			2967	IN	NS	l.root-servers.net.
.			2967	IN	NS	d.root-servers.net.
.			2967	IN	NS	j.root-servers.net.
.			2967	IN	NS	g.root-servers.net.
.			2967	IN	NS	m.root-servers.net.

;; Query time: 12 msec
;; SERVER: ::1#53(::1)
;; WHEN: Sun Feb  5 14:02:03 2012
;; MSG SIZE  rcvd: 254

Now from a remote machine, repeat the same queries to ensure that our DNS server will respond to external queries.

On the server;

Query alteeve.ca, which we're SOA for.

dig alteeve.ca @78.46.37.135
; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.2.rc1.fc16 <<>> alteeve.ca @78.46.37.135
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 46628
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 2

;; QUESTION SECTION:
;alteeve.ca.			IN	A

;; ANSWER SECTION:
alteeve.ca.		600	IN	A	192.139.81.121

;; AUTHORITY SECTION:
alteeve.ca.		600	IN	NS	ns2.alteeve.ca.
alteeve.ca.		600	IN	NS	ns1.alteeve.ca.

;; ADDITIONAL SECTION:
ns1.alteeve.ca.	600	IN	A	192.139.81.117
ns2.alteeve.ca.	600	IN	A	192.139.81.119

;; Query time: 138 msec
;; SERVER: 78.46.37.135#53(78.46.37.135)
;; WHEN: Sun Feb  5 14:04:09 2012
;; MSG SIZE  rcvd: 113

Now query google.ca which we obviously are not SOA for.

dig google.ca @78.46.37.135
; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.2.rc1.fc16 <<>> google.ca @78.46.37.135
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 18204
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 13, ADDITIONAL: 0

;; QUESTION SECTION:
;google.ca.			IN	A

;; ANSWER SECTION:
google.ca.		138	IN	A	74.125.232.56

;; AUTHORITY SECTION:
.			2805	IN	NS	h.root-servers.net.
.			2805	IN	NS	c.root-servers.net.
.			2805	IN	NS	j.root-servers.net.
.			2805	IN	NS	i.root-servers.net.
.			2805	IN	NS	b.root-servers.net.
.			2805	IN	NS	m.root-servers.net.
.			2805	IN	NS	g.root-servers.net.
.			2805	IN	NS	d.root-servers.net.
.			2805	IN	NS	a.root-servers.net.
.			2805	IN	NS	l.root-servers.net.
.			2805	IN	NS	f.root-servers.net.
.			2805	IN	NS	k.root-servers.net.
.			2805	IN	NS	e.root-servers.net.

;; Query time: 140 msec
;; SERVER: 78.46.37.135#53(78.46.37.135)
;; WHEN: Sun Feb  5 14:04:31 2012
;; MSG SIZE  rcvd: 254

Done!

Email

This is a pretty heavily customized postfix install using a custom schema. It was originally based on this Debian Etch tutorial, but adapted for PostgreSQL. Much time has passed and the operating system is now significantly changed, but it's lineage is thus. A more recent, but still Debian-focused version of the tutorial is here. I also used this tutorial to help sort out the PostgreSQL stuff.

This will use a few applications;

  • Postfix - The program that receives email.
  • PostgreSQL - The database used to validate the existence of email accounts and validates incoming user credentials.
  • Dovecot - Takes email coming from postfix, via amavis, and records them to disk. It also answers requests from users wanting to check their email.
  • Amavis - Filters incoming email for spam (via spamassassin) and virsus (via clamav)

We will also be using graylisting, which is a spam fighting tactic where the first email from a given user to one of our users is bounced for a few minutes. Proper mail servers will acknowledge the bound, wait the time and resend. Spam mailers though are usually fire-and-forget and will not resend, thus effectively blocking the spam message. This is a very effective method of blocking spam with minimal chance of losing real mail from real users. Any subsequent message from the user would be allowed through with no delay, provided the user had in fact resent the first message as requested.

Install

To install the applications;

yum install postfix postfix-perl-scripts dovecot dovecot-pgsql spamassassin postgresql-server postgresql-plperl mutt

Configuring Postfix

Installation requires several steps. The AN!Console database must be loaded. Various applications need to be installed. Postfix, Dovecot and helper applications need to be configured and so on.

This tutorial uses the following values that you may need to adjust;

  • Database name; an_tools
  • Database user; alteeve
  • Database password; secret
  • Database host; 127.0.0.1
Note: Do not use the database host "localhost" unless you are certain you can connect to the DB using a standard unix socket.

Building Support for PostgreSQL

Warning: We need to build our own RPM in order to support postgresql. This means we will have to disable postfix from future updates, placing the onus on us to make sure critical updates are applied. This will require downloading the latest source RPMs, re-enabling postgres and recompile/reinstall.

Add the source RPM repository by adding the following;

vim /etc/yum.repos.d/CentOS-Base.repo
# Source RPM repository
[base-source]
name=CentOS-$releasever - Base - Source
#mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=os
baseurl=http://vault.centos.org/6.3/os/Source/
gpgcheck=1
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6

Now download the source RPM for postfix.

yumdownloader --source postfix
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * base: centos.vieth-server.de
 * extras: centos.vieth-server.de
 * updates: centos.vieth-server.de
base                               | 3.7 kB     00:00
base-source                        | 1.9 kB     00:00
extras                             | 3.5 kB     00:00
updates                            | 3.5 kB     00:00
No source RPM found for 2:postfix-2.6.6-2.2.el6_1.x86_64
./postfix-2.6.6-2.el6.src.rpm already exists and appears to be complete
nikko:/etc/postfix# rm postfix-2.6.6-2.el6.src.rpm 
rm: remove regular file `postfix-2.6.6-2.el6.src.rpm'? y
nikko:/etc/postfix# yumdownloader --source postfix
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * base: centos.vieth-server.de
 * extras: centos.vieth-server.de
 * updates: centos.vieth-server.de
No source RPM found for 2:postfix-2.6.6-2.2.el6_1.x86_64
postfix-2.6.6-2.el6.src.rpm        | 3.3 MB     00:00

Now that we have the postfix source RPM, we will install it.

rpm -Uvh postfix-2.6.6-2.el6.src.rpm
   1:postfix                warning: user mockbuild does not exist - using root
warning: group mockbuild does not exist - using root
warning: user mockbuild does not exist - using root
warning: group mockbuild does not exist - using root
warning: user mockbuild does not exist - using root
warning: group mockbuild does not exist - using root
warning: user mockbuild does not exist - using root
warning: group mockbuild does not exist - using root
warning: user mockbuild does not exist - using root
warning: group mockbuild does not exist - using root
warning: user mockbuild does not exist - using root
warning: group mockbuild does not exist - using root
warning: user mockbuild does not exist - using root
warning: group mockbuild does not exist - using root
warning: user mockbuild does not exist - using root
warning: group mockbuild does not exist - using root
########################################### [100%]
warning: user mockbuild does not exist - using root
warning: group mockbuild does not exist - using root
warning: user mockbuild does not exist - using root
warning: group mockbuild does not exist - using root
warning: user mockbuild does not exist - using root
warning: group mockbuild does not exist - using root
warning: user mockbuild does not exist - using root
warning: group mockbuild does not exist - using root

Now edit the .spec file to enable postgres support.

cp ~/rpmbuild/SPECS/postfix.spec ~/rpmbuild/SPECS/postfix.spec.orig
vim ~/rpmbuild/SPECS/postfix.spec

Make the following changes.

  • Enable PostgreSQL support
%{?!PGSQL: %define PGSQL 1}

Increment the release version by one.

Release: 3%{?dist}

We can see the changes here:

diff -u ~/rpmbuild/SPECS/postfix.spec.orig ~/rpmbuild/SPECS/postfix.spec
--- /root/rpmbuild/SPECS/postfix.spec.orig      2012-02-11 16:54:54.495330859 -0500
+++ /root/rpmbuild/SPECS/postfix.spec   2012-02-11 16:53:39.873331101 -0500
@@ -1,5 +1,5 @@
 %{?!MYSQL: %define MYSQL 1}
-%{?!PGSQL: %define PGSQL 0}
+%{?!PGSQL: %define PGSQL 1}
 %define LDAP 2
 %define PCRE 1
 %define SASL 2
@@ -35,7 +35,7 @@
 Name: postfix
 Summary: Postfix Mail Transport Agent
 Version: 2.6.6
-Release: 2%{?dist}
+Release: 3%{?dist}
 Epoch: 2
 Group: System Environment/Daemons
 URL: http://www.postfix.org

Now rebuild the RPM, which means we need to install the build tools.

yum groupinstall development
yum install db4-devel openldap-devel cyrus-sasl-devel pcre-devel mysql-devel postgresql-devel openssl-devel
rpmbuild -bb ~/rpmbuild/SPECS/postfix.spec
(compile output)
Processing files: postfix-debuginfo-2.6.6-3.el6.x86_64
Checking for unpackaged file(s): /usr/lib/rpm/check-files /root/rpmbuild/BUILDROOT/postfix-2.6.6-3.el6.x86_64
Wrote: /root/rpmbuild/RPMS/x86_64/postfix-2.6.6-3.el6.x86_64.rpm
Wrote: /root/rpmbuild/RPMS/x86_64/postfix-perl-scripts-2.6.6-3.el6.x86_64.rpm
Wrote: /root/rpmbuild/RPMS/x86_64/postfix-debuginfo-2.6.6-3.el6.x86_64.rpm
Executing(%clean): /bin/sh -e /var/tmp/rpm-tmp.rymr5C
+ umask 022
+ cd /root/rpmbuild/BUILD
+ cd postfix-2.6.6
+ rm -rf /root/rpmbuild/BUILDROOT/postfix-2.6.6-3.el6.x86_64
+ exit 0

Install the updated postfix.

rpm -Uvh ~/rpmbuild/RPMS/x86_64/postfix-2.6.6-3.el6.x86_64.rpm ~/rpmbuild/RPMS/x86_64/postfix-perl-scripts-2.6.6-3.el6.x86_64.rpm
Preparing...                ########################################### [100%]
   1:postfix                ########################################### [ 50%]
   2:postfix-perl-scripts   ########################################### [100%]

Now exclude postfix from future updates.

cp /etc/yum.conf /etc/yum.conf.orig
vim /etc/yum.conf
diff -u /etc/yum.conf.orig /etc/yum.conf
--- /etc/yum.conf.orig  2012-02-11 16:59:53.720079168 -0500
+++ /etc/yum.conf       2012-02-11 17:00:47.013331283 -0500
@@ -10,6 +10,7 @@
 installonly_limit=5
 bugtracker_url=http://bugs.centos.org/set_project.php?project_id=16&ref=http://bugs.centos.org/bug_report_page.php?category=yum
 distroverpkg=centos-release
+exclude=postfix*
 
 #  This is the default, if you make this bigger yum won't see if the metadata
 # is newer on the remote and so you'll "gain" the bandwidth of not having to

Basic Postfix Configuration

Since we'll be using virtual domains, users, aliases and mailboxes, we'll need to start by commenting out some of the default options in Postfix. By default, Postfix is set up for small numbers of local users, and it only allows connections from the localhost. Our configuration will be more scalable, allowing many domains and users to be stored in the Postgres database.

Comment out the following:

vim /etc/postfix/main.cf
# inet_interfaces = localhost
# mydestination = $myhostname, localhost.$mydomain, localhost 
# alias_maps = hash:/etc/aliases  
# alias_database = hash:/etc/aliases

And uncomment/add these:

vim /etc/postfix/main.cf
inet_interfaces = all   # allows us to connect and test from another machine
mynetworks = 192.168.1.0/32, 127.0.0.0/8  # use the IP or subnet of your test machine here
message_size_limit = 36700160 # increase max message size to 35MB to allow for ~25MB attachments

Setup Virtual Domain Lookup

This tells postfix how to find which domains we have.

vim /etc/postfix/pgsql-virtual-mailbox-domains.cf
user = alteeve
password = secret
hosts = 127.0.0.1
dbname = an_tools
query = SELECT 1 FROM domains WHERE dom_name='%s'

Now tell Postfix to use this new file by appending the following to the main postfix configuration file.

vim /etc/postfix/main.cf
# Tell postfix to validate domains using our postgresql databae via the
# pgsql-virtual-mailbox-domains.cf
virtual_mailbox_domains=pgsql:/etc/postfix/pgsql-virtual-mailbox-domains.cf

Now reload postfix;

/etc/init.d/postfix reload
Reloading postfix:                                         [  OK  ]

Now we can test that domains resolve. In my case, I will test the look-up for alteeve.ca.

postmap -q alteeve.ca pgsql:/etc/postfix/pgsql-virtual-mailbox-domains.cf
1

Now make sure it returns nothing when query a bad domain.

postmap -q example.com pgsql:/etc/postfix/pgsql-virtual-mailbox-domains.cf
<nothing returned>

Setup Mailbox Mapping

This section will tell postfix which users for a given domain are valid.

vim /etc/postfix/pgsql-virtual-mailbox-maps.cf
user = alteeve
password = secret
hosts = 127.0.0.1
dbname = an_tools
query = SELECT 1 FROM email_file WHERE email='%s'

Tell postfix to use this new file when looking up users.

vim /etc/postfix/main.cf

And add:

# Tell postfix which table to look in when validating a local user via their
# email address.
virtual_mailbox_maps=pgsql:/etc/postfix/pgsql-virtual-mailbox-maps.cf

Reload postfix.

/etc/init.d/postfix reload
Reloading postfix:                                         [  OK  ]

Now do a test of a valid user, which should return 1, and an invalid user, which should return nothing.

postmap -q digimer@alteeve.ca pgsql:/etc/postfix/pgsql-virtual-mailbox-maps.cf
1
postmap -q nobody@alteeve.ca pgsql:/etc/postfix/pgsql-virtual-mailbox-maps.cf
<nothing returned>

Setup Email Forwards

This will allow for email addresses to be forwarded to other email addresses.

vim /etc/postfix/pgsql-virtual-alias-maps.cf
user = alteeve
password = secret
hosts = 127.0.0.1
dbname = an_tools
query = SELECT fwd_destination FROM forwards WHERE fwd_source='%s'

Now tell postfix where to look.

vim /etc/postfix/main.cf

Add;

# This tells postfix where to forward incoming email to, where appropriate.
virtual_alias_maps=pgsql:/etc/postfix/pgsql-virtual-alias-maps.cf

Reload;

/etc/init.d/postfix reload
Reloading postfix:                                         [  OK  ]

I've setup a forward where digimer@alteeve.ca forwards to digimer@alteeve.ca, so we will use that for the next test.

postmap -q digimer@alteeve.ca pgsql:/etc/postfix/pgsql-virtual-alias-maps.cf
digimer@alteeve.ca

An email address with no forward should return nothing.

postmap -q digimer@alteeve.ca pgsql:/etc/postfix/pgsql-virtual-alias-maps.cf
<nothing returned>

Excellent.

Setup Postfix Mail Delivery via Dovecot

Define a mail transport method in the main Postfix config.

vim /etc/postfix/main.cf
# this option is ignored, but may be useful for reference
virtual_mailbox_base=/email

# deliver mail via dovecot
virtual_transport = dovecot

# prevent postfix from sending multiple recipients per delivery request,
# since dovecot only supports one recipient for each delivery
dovecot_destination_recipient_limit = 1

Tell Postfix what virtual_transport "dovecot" means, and how to use it.

vim /etc/postfix/master.cf

Append this for RHEL/CentOS 6 machines. For other distros, make sure that /usr/libexec/dovecot/deliver exists and change the path if necessary.

dovecot   unix  -       n       n       -       -       pipe
  flags=DRhu user=vmail:vmail argv=/usr/libexec/dovecot/deliver -f ${sender} -d ${recipient}

Setup Postfix SMTP Authentication using Dovecot

Dovecot provides an SMTP authentication mechanism to Postfix called SASL. Enabling this will require users to authenticate against the server before sending mail.

vim /etc/postfix/main.cf

Append the following to enable smtp authentication:

smtpd_sasl_auth_enable = yes
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
broken_sasl_auth_clients = yes

# allow authenticated users to send mail through Postfix SMTP
# more info at /usr/share/doc/postfix-2.6.6/README_FILES/SMTPD_ACCESS_README
smtpd_recipient_restrictions =
        permit_mynetworks
        permit_sasl_authenticated
        reject_unauth_destination

# general smtpd settings
# - reject clients that speak too early
# - reject mail from a null address to many recipients (usually spam)
smtpd_data_restrictions =
        reject_unauth_pipelining
        reject_multi_recipient_bounce
        permit

Configuring Dovecot

Dovecot handles writing incoming mail to the disk and moving/deleting mail as the user wishes. We're going to create a user and group called vmail which will be used to manage the email stored on disk.

useradd -m vmail
mkdir /email
chown -R vmail:vmail /email

Dovecot is configured in /etc/dovecot and the main configuration file is dovecot.conf.

cp /etc/dovecot/dovecot.conf /etc/dovecot/dovecot.conf.orig
vim /etc/dovecot/dovecot.conf

Dovecot uses .d style configuration files.

  • Authentication
cp /etc/dovecot/conf.d/10-auth.conf /etc/dovecot/conf.d/10-auth.conf.orig
vim /etc/dovecot/conf.d/10-auth.conf

Tell dovecot to accept plain-text passwords (needed for some old email clients, you may not need to enable this).

disable_plaintext_auth = no

Tell it not to use the database, and not local users for mail delivery.

#!include auth-system.conf.ext
!include auth-sql.conf.ext
  • Mail store

Tell dovecot where to store the email. The %d tells dovecot to substitute the user's domain name and %n is substituted by the user's email name. For example, digimer@alteeve.ca becomes /email/alteeve.ca/mkelly.

cp /etc/dovecot/conf.d/10-mail.conf /etc/dovecot/conf.d/10-mail.conf.orig
vim /etc/dovecot/conf.d/10-mail.conf
mail_location = mbox:/email/%d/%n

Dovecot Authentication and SQL Settings

We need to tell dovecot where to look for passwords when authenticating a user. Where to look is controlled in the auth-sql.conf.ext file and is broken down into user and password lookups. We will want to first tell Dovecot which user to use when accessing the mail store on disk.

cp /etc/dovecot/conf.d/auth-sql.conf.ext /etc/dovecot/conf.d/auth-sql.conf.ext.orig
vim /etc/dovecot/conf.d/auth-sql.conf.ext
userdb {
  driver = static
  args = uid=vmail gid=vmail home=/email/%d/%n allow_all_users=yes
}
  • Now configure the SQL server access details.
Note: Make sure that PostgreSQL has sufficient max_connections set in /var/lib/pgsql/data/postgresql.conf to handle enough connections for the expected number of email connections, plus other connections from other applications.
cp /usr/share/doc/dovecot-2.0.9/example-config/dovecot-sql.conf.ext /etc/dovecot/dovecot-sql.conf.ext
chown root:root /etc/dovecot/dovecot-sql.conf.ext
chmod 600 /etc/dovecot/dovecot-sql.conf.ext
vim /etc/dovecot/dovecot-sql.conf.ext

Tell dovecot to use PostgreSQL.

driver = pgsql

Configure the connection string.

Note: If your database uses a password with a space character in it, quote the password. Ie: password='super secret'.
connect = host=127.0.0.1 dbname=an_tools user=alteeve password=secret

Tell dovecot to accept plain-text passwords (this is needed for some stupid MS clients, this will probably change soon).

default_pass_scheme = PLAIN

Tell dovecot how to pull use the user's password.

password_query = SELECT email, password FROM email_password WHERE email='%u'

The last thing to setup is the user query. The query needs to return the UID and GID of the vmail user we setup earlier. To get it, you can use the id command.

id vmail
uid=503(vmail) gid=503(vmail) groups=503(vmail)

The numbers we want are 503 and 503 for the UID and GID, respectively. Knowing this, we can set the userdb SQL string.

user_query = SELECT '/email/'||file AS email_dir, '503' AS uid, '503' AS gid FROM email_file WHERE email='%u'

Configure Listener Sockets

Setup the authentication socket to allow the vmail user. This will allow Dovecot to access the user authentication socket.

vim /etc/dovecot/conf.d/10-master.conf
  unix_listener auth-userdb {
    mode = 0600
    user = vmail
    group = vmail
  }

Configure Dovecot to authenticate Postfix SMTP requests.

vim /etc/dovecot/conf.d/10-master.conf
   unix_listener smtp-auth {
    mode = 0600
    user = postfix
    group = postfix
    path = /var/spool/postfix/private/auth
  }

Tell Dovecot to increase the number of allowed connections and child processes to handle heavier loads.

vim /etc/dovecot/conf.d/10-master.conf
default_process_limit = 200
default_client_limit = 2000

Enable Logging

This is very useful for debugging an initial setup. It will place details about login attempts in /var/log/maillog.

vim /etc/dovecot/conf.d/10-logging.conf
log_path = syslog
auth_verbose = yes
auth_debug = yes
mail_debug = yes

At this point, it's a good idea to restart the Postfix and Dovecot services, and test out the basic configuration.

service postfix restart
service dovecot restart

Watch the maillog while attempting to authenticate with an email client like Thunderbird.

tail -f /var/log/maillog

If basic authentication is working, we can go ahead and add another layer of complexity on top of it: SSL.

SSL/TLS

Add TLS support to Postfix, to encrypt SMTP authentication traffic.

vim /etc/postfix/main.cf
smtpd_use_tls = yes
smtpd_tls_auth_only = yes
smtpd_tls_cert_file = /etc/pki/CA/ssl_mail.alteeve.ca.crt
smtpd_tls_key_file = /etc/pki/CA/private/mail.alteeve.ca.key
smtpd_tls_loglevel = 1

Add TLS support to Dovecot, to encrypt IMAP authentication traffic.

vim /etc/dovecot/conf.d/10-ssl.conf
ssl = yes

# PEM encoded X.509 SSL/TLS certificate and private key.
ssl_cert = </etc/pki/CA/ssl_mail.alteeve.ca.crt
ssl_key = </etc/pki/CA/private/mail.alteeve.ca.key

# PEM encoded trusted certificate authority. Otherwise your CA will be untrusted.
# This is the intermediary certificate.
ssl_ca = </etc/pki/CA/RapidSSL_CA_bundle_alteeve.ca.pem

Dovecot prefers the following permissions for SSL certs, so set them accordingly.

chmod 0444 /etc/pki/CA/ssl_mail.alteeve.ca.crt
chmod 0400 /etc/pki/CA/private/mail.alteeve.ca.key
chmod 0400 /etc/pki/CA/RapidSSL_CA_bundle_alteeve.ca.pem

Restart Postfix and Dovecot, then change your Thunderbird server options to 'STARTTLS'. If you're still able to connect to the mail server and send mail, proceed to the next section.

User Password Encryption

In addition to SSL/TSL, which only encrypts the transport of user credentials, we're also going to encrypt the passwords themselves. This will avoid storing any plaintext passwords in the Postgres database.

vim /etc/dovecot/conf.d/10-auth.conf

Remove the "plain" authentication, and replace with cram-md5.

disable_plaintext_auth = yes
auth_mechanisms = cram-md5

Any user credentials that were previously stored in plaintext will no longer work. To encrypt your password in a way that Dovecot recognizes, use the following command:

doveadm -v pw -s CRAM-MD5 -p mypassword

It will return a hash like this.

{CRAM-MD5}de5924752ad74e36bc271a8dc7fad4b2d341f21f05382f20dedf1fdfbd5a1717

Take the entire hash, including the '{CRAM-MD5}' portion, and use it to replace the password entry in the database for that user. This will allow Dovecot to authenticate the user using the CRAM-MD5 auth mechanism.

To automate this process for all users in the database, you can look at the number of userid's there are and loop through them, encrypting and replacing each password.

#!/bin/bash
#
# a script to encrypt the users.usr_password values of the an_tools database

export PGUSER="alteeve"
export PGPASSWORD='secret'

for usrid in {1..219}; do

    # grab the user's password, removing whitespace
    usrpass=$(psql -d an_tools -c "SELECT users.usr_password FROM users WHERE users.usr_id=$usrid;"\
 | sed -n 3p | sed -e 's/^[ ]*//')

    if [[ "$usrpass" == *CRAM* ]]; then
        echo "Password for user #$usrid is already encrypted; skipping."
    else
        # encrypt and surround in single quotes for psql
        encrypted=\'$(doveadm -v pw -s CRAM-MD5 -p "$usrpass")\'
        echo "old password: [$usrpass] ; encrypted: $encrypted"

        # set password to encrypted value
        psql -d an_tools -c "UPDATE users SET usr_password=$encrypted WHERE usr_id=$usrid;"
    fi
done

unset PGUSER
unset PGPASSWORD

Postgrey Greylisting

Enabling postgrey for anti-spam greylisting.

First install the RPMForge repos. (See Dakini's blog for details.)

yum -y install postgrey

Create the config file with the following options. This will delay mail from untrusted sources by 6 minutes. A legitimate mailserver will resend the request after that time, and be allowed through. But spam is generally sent out only once, so those messages will drop.

vim /etc/sysconfig/postgrey
OPTIONS="--unix=/var/spool/postfix/postgrey/socket --delay=360"

Ensure that Postgrey starts on boot.

chkconfig --levels 345 postgrey on
/etc/postfix/main.cf

Configure Postfix to check SMTP requests through Postgrey. Postgrey will decide if the mail should be blocked or accepted.

smtpd_recipient_restrictions =
        permit_mynetworks
        permit_sasl_authenticated
        reject_unauth_destination
        check_policy_service unix:postgrey/socket

Restart Postfix and Postgrey to take affect.

service postgrey start
service postfix restart

RoundCube Web Mail

Install the packages (these require the EPEL repo);

yum install roundcubemail php-pear-MDB2-Driver-pgsql

You need to set the timezone in the /etc/php.ini file.

cp /etc/php.ini /etc/php.ini.orig
vim /etc/php.ini

Set date.timezone value. If you aren't sure of the format or name of your timezone, run tzselect and follow the prompts. We want America/Toronto.

diff -u /etc/php.ini.orig /etc/php.ini
--- /etc/php.ini.orig	2012-08-18 22:27:05.244670258 -0400
+++ /etc/php.ini	2012-08-18 21:49:37.926938864 -0400
@@ -943,7 +943,7 @@
 [Date]
 ; Defines the default timezone used by the date functions
 ; http://www.php.net/manual/en/datetime.configuration.php#ini.date.timezone
-;date.timezone = 
+date.timezone = America/Toronto
 
 ; http://www.php.net/manual/en/datetime.configuration.php#ini.date.default-latitude
 ;date.default_latitude = 31.7667

Create the database for roundcube

su - postgres
createdb -O alteeve -E UNICODE roundcubemail
psql -U alteeve -D roundcubemail
\i /usr/share/doc/roundcubemail-0.5.4/SQL/postgres.initial.sql

Edit main configuration file

vim /etc/roundcubemail/main.inc.php
$rcmail_config['default_host'] = 'localhost';
$rcmail_config['smtp_server'] = 'tls://mail.alteeve.ca';
$rcmail_config['smtp_user'] = '%u';
$rcmail_config['smtp_pass'] = '%p';
$rcmail_config['smtp_auth_type'] = 'CRAM-MD5';
$rcmail_config['force_https'] = true;
$rcmail_config['use_https'] = true;
$rcmail_config['login_autocomplete'] = 1;

Now setup roundcube for connecting to our DB;

cp /etc/roundcubemail/db.inc.php /etc/roundcubemail/db.inc.php.orig
vim /etc/roundcubemail/db.inc.php

Now set the connection string. Note to switch the DB driver to pgsql.

diff -u /etc/roundcubemail/db.inc.php.orig /etc/roundcubemail/db.inc.php
--- /etc/roundcubemail/db.inc.php.orig	2012-05-06 13:53:52.000000000 -0400
+++ /etc/roundcubemail/db.inc.php	2012-05-06 15:45:30.000000000 -0400
@@ -18,7 +18,7 @@
 // format is db_provider://user:password@host/database 
 // For examples see http://pear.php.net/manual/en/package.database.mdb2.intro-dsn.php
 
-$rcmail_config['db_dsnw'] = 'mysql://roundcube:pass@localhost/roundcubemail';
+$rcmail_config['db_dsnw'] = 'pgsql://alteeve:secret@localhost/roundcubemail';
 // postgres example: 'pgsql://roundcube:pass@localhost/roundcubemail';
 // Warning: for SQLite use absolute path in DSN:

Now setup roundcube to communicate with the mail server.

cp /etc/roundcubemail/main.inc.php /etc/roundcubemail/main.inc.php.orig
vim /etc/roundcubemail/main.inc.php

There are several variables to set. Our server will talk to localhost using tls on port 587 using CRAM_MD5 encryption. We use, and require, https connections. There are a couple special values for querying the user's name and password from the database. Finally, we want to enable the user's browser's auto-complete functions and set the name shown to the users. Once all set, the diff should be similar to the one below.

diff -u /etc/roundcubemail/main.inc.php.orig /etc/roundcubemail/main.inc.php
--- /etc/roundcubemail/main.inc.php.orig	2012-05-06 13:53:59.000000000 -0400
+++ /etc/roundcubemail/main.inc.php	2012-07-06 14:59:07.000000000 -0400
@@ -65,7 +65,7 @@
 // %n - http hostname ($_SERVER['SERVER_NAME'])
 // %d - domain (http hostname without the first part)
 // For example %n = mail.domain.tld, %d = domain.tld
-$rcmail_config['default_host'] = '';
+$rcmail_config['default_host'] = 'localhost';
 
 // TCP port used for IMAP connections
 $rcmail_config['default_port'] = 143;
@@ -121,22 +121,22 @@
 // %d - domain (http hostname without the first part)
 // %z - IMAP domain (IMAP hostname without the first part)
 // For example %n = mail.domain.tld, %d = domain.tld
-$rcmail_config['smtp_server'] = '';
+$rcmail_config['smtp_server'] = 'tls://mail.alteeve.ca';
 
 // SMTP port (default is 25; 465 for SSL)
-$rcmail_config['smtp_port'] = 25;
+$rcmail_config['smtp_port'] = 587;
 
 // SMTP username (if required) if you use %u as the username Roundcube
 // will use the current username for login
-$rcmail_config['smtp_user'] = '';
+$rcmail_config['smtp_user'] = '%u';
 
 // SMTP password (if required) if you use %p as the password Roundcube
 // will use the current user's password for login
-$rcmail_config['smtp_pass'] = '';
+$rcmail_config['smtp_pass'] = '%p';
 
 // SMTP AUTH type (DIGEST-MD5, CRAM-MD5, LOGIN, PLAIN or empty to use
 // best server supported one)
-$rcmail_config['smtp_auth_type'] = '';
+$rcmail_config['smtp_auth_type'] = 'CRAM-MD5';
 
 // Optional SMTP authentication identifier to be used as authorization proxy
 $rcmail_config['smtp_auth_cid'] = null;
@@ -179,16 +179,16 @@
 // enforce connections over https
 // with this option enabled, all non-secure connections will be redirected.
 // set the port for the ssl connection as value of this option if it differs from the default 443
-$rcmail_config['force_https'] = false;
+$rcmail_config['force_https'] = true;
 
 // tell PHP that it should work as under secure connection
 // even if it doesn't recognize it as secure ($_SERVER['HTTPS'] is not set)
 // e.g. when you're running Roundcube behind a https proxy
-$rcmail_config['use_https'] = false;
+$rcmail_config['use_https'] = true;
 
 // Allow browser-autocompletion on login form.
 // 0 - disabled, 1 - username and host only, 2 - username, host, password
-$rcmail_config['login_autocomplete'] = 0;
+$rcmail_config['login_autocomplete'] = 1;
 
 // If users authentication is not case sensitive this must be enabled.
 // You can also use it to force conversion of logins to lower case.
@@ -261,7 +261,7 @@
 $rcmail_config['useragent'] = 'Roundcube Webmail/'.RCMAIL_VERSION;
 
 // use this name to compose page titles
-$rcmail_config['product_name'] = 'Roundcube Webmail';
+$rcmail_config['product_name'] = 'AN!Mail';
 
 // try to load host-specific configuration
 // see http://trac.roundcube.net/wiki/Howto_Config for more details

That should be it.

Error No. [500]

After a recent OS update, 6.3 to 6.4, I started to get:

Error No. [500]

When trying to log into Round Cube. When I tail'ed /var/www/ssl_alteeve.ca/logs/error.log, there were two errors;

[Tue Sep 03 10:39:05 2013] [error] [client 108.168.16.38] PHP Warning:  Error writing to log file /var/log/roundcubemail/errors; Please check permissions in /usr/share/roundcubemail/program/include/main.inc on line 1965, referer: https://alteeve.ca/m/
[Tue Sep 03 10:39:05 2013] [error] [client 108.168.16.38] PHP Notice:  Could not perform encryption; make sure Mcrypt is installed or lib/des.inc is available in /usr/share/roundcubemail/program/include/main.inc on line 2120, referer: https://alteeve.ca/m/

Fixing the first was easy. The owner on /var/log/roundcubemail/errors was root:apache and the mode was 644, so a quick;

chmod 664 /var/log/roundcubemail/errors

Resolved that issue. Then I tail'ed the roundcube log and still saw the "Mcrypt" error. I found this post which had the fix. The trick was to alter /etc/php.d/mcrypt.ini.orig.

cp /etc/php.d/mcrypt.ini /etc/php.d/mcrypt.ini.orig
vim /etc/php.d/mcrypt.ini

Change module.so to mcrypt.so, save and reload apache.

diff -u /etc/php.d/mcrypt.ini.orig /etc/php.d/mcrypt.ini
--- /etc/php.d/mcrypt.ini.orig	2013-09-03 11:10:26.375001302 -0400
+++ /etc/php.d/mcrypt.ini	2013-09-03 10:46:52.340999323 -0400
@@ -1,2 +1,3 @@
 ; Enable mcrypt extension module
-extension=module.so
+;extension=module.so
+extension=mcrypt.so

Reload httpd;

/etc/init.d/httpd reload
Reloading httpd:

RoundCube should now work again.

Adding a password-reset link to the login page

Edit the login page template to insert the AN!Console password recovery link.

vim /usr/share/roundcubemail/skins/default/templates/login.html

(The part we're adding is the '<a href=""></a>'. Other parts of the template file are included here as a reference.)

<div id="login-form">
<div class="boxtitle"><roundcube:label name="welcome" /></div>
<div class="boxcontent">

<form name="form" action="./" method="post">
<roundcube:object name="loginform" form="form" />

<p style="text-align:center;"><input type="submit" class="button mainaction" value="<roundcube:label name='login' />" /></p>

</form>
<a href="../../cgi-bin/t/password.cgi">Forgot your password?</a>
</div>
</div>

Bugzilla

This tutorial covers installing bugzilla 4.4 on AN!'s bugzilla server.

Installing Bugzilla

  • Installed on a fresh minimal CentOS / RHEL 6.4 install.
  • Installed at: /var/www/ssl_bugs.alteeve.ca/html/ on a dedicated server.
  • Databases hosted on an external server running PostgreSQL.

Setup your webserver as above. Be sure to use SSL certificates! In this case, we will host our bugzilla at https://bugs.alteeve.ca.

Create the working directory, go to that directory, download the 4.4 install, extract it and switch into the created bugzilla-4.4 directory.

mkdir -p /var/www/{bugs.alteeve.ca,ssl_bugs.alteeve.ca}/{html,logs,cgi-bin,temp}
cd /var/www/ssl_bugs.alteeve.ca/temp/
wget -c http://ftp.mozilla.org/pub/mozilla.org/webtools/bugzilla-4.4.tar.gz
tar -xvzf bugzilla-4.4.tar.gz 
cd bugzilla-4.4

Install dependent RPMs;

yum groupinstall development
yum install perl-ExtUtils-MakeMaker perl-GD perl-GDTextUtil perl-MIME-tools perl-XML-Twig perl-DBD-Pg openssl-devel mod_perl-devel \
            mod_perl patchutils perl-Authen-SASL perl-BSD-Resource perl-CPAN perl-Class-Singleton perl-Convert-ASN1 perl-DateTime \
            perl-Digest-HMAC perl-Digest-SHA1 vim rsync wget acpid gpm mlocate syslinux perl-GSSAPI perl-LDAP perl-List-MoreUtils \
            perl-Params-Validate perl-SOAP-Lite perl-Test-Simple perl-Text-Iconv perl-XML-Filter-BufferText perl-XML-NamespaceSupport \
            perl-XML-SAX-Writer httpd cvs postgresql

Remove RPMs with perl modules that are too old.

yum remove perl-TimeDate perl-List-MoreUtils

Install from CPAN remaining needed perl modules.

# Don't ask us questions
export PERL_MM_USE_DEFAULT=1

# Optional modules
perl -MCPAN -e 'install("YAML")'
perl -MCPAN -e 'install Chart::Lines'
perl -MCPAN -e 'install Template::Plugin::GD::Image'
perl -MCPAN -e 'install GD::Graph'
perl -MCPAN -e 'install MIME::Parser'
perl -MCPAN -e 'install PatchReader'
perl -MCPAN -e 'install Net::SMTP::SSL'
perl -MCPAN -e 'install Authen::Radius'
perl -MCPAN -e 'install SOAP::Lite'
perl -MCPAN -e 'install JSON::RPC'
perl -MCPAN -e 'install JSON::XS'
perl -MCPAN -e 'install Test::Taint'
perl -MCPAN -e 'install HTML::Scrubber'
perl -MCPAN -e 'install Encode::Detect'
perl -MCPAN -e 'install Email::Reply'
perl -MCPAN -e 'install HTML::FormatText::WithLinks'
perl -MCPAN -e 'install TheSchwartz'
perl -MCPAN -e 'install Daemon::Generic'
perl -MCPAN -e 'install Apache2::SizeLimit'
perl -MCPAN -e 'install File::MimeInfo::Magic'

# Required modules
perl -MCPAN -e 'install DateTime'
perl -MCPAN -e 'install Email::Send'
perl -MCPAN -e 'install Math::Random::ISAAC'

If the above completed successfully, you should be able to run bugzilla's checksetup.pl script and have no missing modules, save for the DB drivers we're not going to use.

./checksetup.pl --check-modules
* This is Bugzilla 4.4 on perl 5.10.1
* Running on Linux 2.6.32-358.18.1.el6.x86_64 #1 SMP Wed Aug 28 17:19:38 UTC 2013

Checking perl modules...
Checking for               CGI.pm (v3.51)     ok: found v3.63 
Checking for           Digest-SHA (any)       ok: found v5.47 
Checking for             TimeDate (v2.23)     ok: found v2.24 
Checking for             DateTime (v0.28)     ok: found v1.03 
Checking for    DateTime-TimeZone (v0.71)     ok: found v1.60 
Checking for                  DBI (v1.54)     ok: found v1.609 
Checking for     Template-Toolkit (v2.22)     ok: found v2.25 
Checking for           Email-Send (v2.04)     ok: found v2.199 
Checking for           Email-MIME (v1.904)    ok: found v1.924 
Checking for                  URI (v1.37)     ok: found v1.60 
Checking for       List-MoreUtils (v0.32)     ok: found v0.33 
Checking for    Math-Random-ISAAC (v1.0.1)    ok: found v1.004 

Checking available perl DBD modules...
Checking for               DBD-Pg (v2.7.0)    ok: found v2.15.1 
Checking for            DBD-mysql (v4.001)    not found 
Checking for           DBD-SQLite (v1.29)     not found 
Checking for           DBD-Oracle (v1.19)     not found 

The following Perl modules are optional:
Checking for                   GD (v1.20)     ok: found v2.44 
Checking for                Chart (v2.1)      ok: found v2.4.6 
Checking for          Template-GD (any)       ok: found v1.56 
Checking for           GDTextUtil (any)       ok: found v0.86 
Checking for              GDGraph (any)       ok: found v1.48 
Checking for           MIME-tools (v5.406)    ok: found v5.504 
Checking for          libwww-perl (any)       ok: found v6.05 
Checking for             XML-Twig (any)       ok: found v3.34 
Checking for          PatchReader (v0.9.6)    ok: found v0.9.6 
Checking for            perl-ldap (any)       ok: found v0.40 
Checking for          Authen-SASL (any)       ok: found v2.13 
Checking for         Net-SMTP-SSL (v1.01)     ok: found v1.01 
Checking for           RadiusPerl (any)       ok: found v0.23 
Checking for            SOAP-Lite (v0.712)    ok: found v1.06 
Checking for             JSON-RPC (any)       ok: found v1.03 
Checking for              JSON-XS (v2.0)      ok: found v2.34 
Checking for           Test-Taint (any)       ok: found v1.06 
Checking for          HTML-Parser (v3.40)     ok: found v3.64 
Checking for        HTML-Scrubber (any)       ok: found v0.09 
Checking for               Encode (v2.21)     ok: found v2.35 
Checking for        Encode-Detect (any)       ok: found v1.01 
Checking for          Email-Reply (any)       ok: found v1.203 
Checking for HTML-FormatText-WithLinks (v0.13)     ok: found v0.14 
Checking for          TheSchwartz (any)       ok: found v1.10 
Use of uninitialized value $ENV{"FLOCK_FORKING_USE"} in string eq at /usr/local/share/perl5/File/Flock/Forking.pm line 13, <DATA> line 522.
Checking for       Daemon-Generic (any)       ok: found v0.83 
Checking for             mod_perl (v1.999022) ok: found v2.000004 
Checking for     Apache-SizeLimit (v0.96)     ok: found v0.96 
Checking for        File-MimeInfo (any)       ok: found v0.18 
Checking for           IO-stringy (any)       ok: found v2.110 
Checking for          mod_headers (any)       ok 
Checking for          mod_expires (any)       ok 
Checking for              mod_env (any)       ok

Excellent!

Now re-run checksetup.pl by itself;

./checksetup.pl
* This is Bugzilla 4.4 on perl 5.10.1
* Running on Linux 2.6.32-358.18.1.el6.x86_64 #1 SMP Wed Aug 28 17:19:38 UTC 2013

Checking perl modules...
Checking for               CGI.pm (v3.51)     ok: found v3.63 
Checking for           Digest-SHA (any)       ok: found v5.47 
Checking for             TimeDate (v2.23)     ok: found v2.24 
Checking for             DateTime (v0.28)     ok: found v1.03 
Checking for    DateTime-TimeZone (v0.71)     ok: found v1.60 
Checking for                  DBI (v1.54)     ok: found v1.609 
Checking for     Template-Toolkit (v2.22)     ok: found v2.25 
Checking for           Email-Send (v2.04)     ok: found v2.199 
Checking for           Email-MIME (v1.904)    ok: found v1.924 
Checking for                  URI (v1.37)     ok: found v1.60 
Checking for       List-MoreUtils (v0.32)     ok: found v0.33 
Checking for    Math-Random-ISAAC (v1.0.1)    ok: found v1.004 

Checking available perl DBD modules...
Checking for               DBD-Pg (v2.7.0)    ok: found v2.15.1 
Checking for            DBD-mysql (v4.001)    not found 
Checking for           DBD-SQLite (v1.29)     not found 
Checking for           DBD-Oracle (v1.19)     not found 

The following Perl modules are optional:
Checking for                   GD (v1.20)     ok: found v2.44 
Checking for                Chart (v2.1)      ok: found v2.4.6 
Checking for          Template-GD (any)       ok: found v1.56 
Checking for           GDTextUtil (any)       ok: found v0.86 
Checking for              GDGraph (any)       ok: found v1.48 
Checking for           MIME-tools (v5.406)    ok: found v5.504 
Checking for          libwww-perl (any)       ok: found v6.05 
Checking for             XML-Twig (any)       ok: found v3.34 
Checking for          PatchReader (v0.9.6)    ok: found v0.9.6 
Checking for            perl-ldap (any)       ok: found v0.40 
Checking for          Authen-SASL (any)       ok: found v2.13 
Checking for         Net-SMTP-SSL (v1.01)     ok: found v1.01 
Checking for           RadiusPerl (any)       ok: found v0.23 
Checking for            SOAP-Lite (v0.712)    ok: found v1.06 
Checking for             JSON-RPC (any)       ok: found v1.03 
Checking for              JSON-XS (v2.0)      ok: found v2.34 
Checking for           Test-Taint (any)       ok: found v1.06 
Checking for          HTML-Parser (v3.40)     ok: found v3.64 
Checking for        HTML-Scrubber (any)       ok: found v0.09 
Checking for               Encode (v2.21)     ok: found v2.35 
Checking for        Encode-Detect (any)       ok: found v1.01 
Checking for          Email-Reply (any)       ok: found v1.203 
Checking for HTML-FormatText-WithLinks (v0.13)     ok: found v0.14 
Checking for          TheSchwartz (any)       ok: found v1.10 
Use of uninitialized value $ENV{"FLOCK_FORKING_USE"} in string eq at /usr/local/share/perl5/File/Flock/Forking.pm line 13, <DATA> line 522.
Checking for       Daemon-Generic (any)       ok: found v0.83 
Checking for             mod_perl (v1.999022) ok: found v2.000004 
Checking for     Apache-SizeLimit (v0.96)     ok: found v0.96 
Checking for        File-MimeInfo (any)       ok: found v0.18 
Checking for           IO-stringy (any)       ok: found v2.110 
Checking for          mod_headers (any)       ok 
Checking for          mod_expires (any)       ok 
Checking for              mod_env (any)       ok 
Reading ./localconfig...

This version of Bugzilla contains some variables that you may want to
change and adapt to your local settings. The following variables are
new to ./localconfig since you last ran checksetup.pl:

create_htaccess, webservergroup, use_suexec, db_driver, db_host,
db_name, db_user, db_pass, db_port, db_sock, db_check, index_html,
cvsbin, interdiffbin, diffpath, site_wide_secret

Please edit the file ./localconfig and then re-run checksetup.pl
to complete your installation.

This will generate a file called localconfig with initial values. Make a backup of this and then edit it.

cp localconfig localconfig.orig
vim localconfig

Change the values as needed. Below is the diff of the configuration use by AN!.

diff -u localconfig.orig localconfig
--- localconfig.orig	2013-09-03 18:21:10.265003147 -0400
+++ localconfig	2013-09-03 18:38:00.231000167 -0400
@@ -47,30 +47,30 @@
 # can be obtained by listing Bugzilla/DB directory - every module corresponds
 # to one supported database and the name of the module (before ".pm")
 # corresponds to a valid value for this variable.
-$db_driver = 'mysql';
+$db_driver = 'Pg';
 
 # The DNS name or IP address of the host that the database server runs on.
-$db_host = 'localhost';
+$db_host = 'vm09-db01.alteeve.ca';
 
 # The name of the database. For Oracle, this is the database's SID. For
 # SQLite, this is a name (or path) for the DB file.
-$db_name = 'bugs';
+$db_name = 'an_bugs';
 
 # Who we connect to the database as.
-$db_user = 'bugs';
+$db_user = 'alteeve';
 
 # Enter your database password here. It's normally advisable to specify
 # a password for your bugzilla database user.
 # If you use apostrophe (') or a backslash (\) in your password, you'll
 # need to escape it by preceding it with a '\' character. (\') or (\)
 # (It is far simpler to just not use those characters.)
-$db_pass = '';
+$db_pass = 'secret';
 
 # Sometimes the database server is running on a non-standard port. If that's
 # the case for your database server, set this to the port number that your
 # database server is running on. Setting this to 0 means "use the default
 # port for my database server."
-$db_port = 0;
+$db_port = 5432;
 
 # MySQL Only: Enter a path to the unix socket for MySQL. If this is
 # blank, then MySQL's compiled-in default will be used. You probably

Create the an_bugs database.

createdb an_bugs -h vm09-db01.alteeve.ca -U alteeve
Password:

Rerun checksetup.pl again to verify your new configuration is sensible.

./checksetup.pl
* This is Bugzilla 4.4 on perl 5.10.1
* Running on Linux 2.6.32-358.18.1.el6.x86_64 #1 SMP Wed Aug 28 17:19:38 UTC 2013

Checking perl modules...
Checking for               CGI.pm (v3.51)     ok: found v3.63 
Checking for           Digest-SHA (any)       ok: found v5.47 
Checking for             TimeDate (v2.23)     ok: found v2.24 
Checking for             DateTime (v0.28)     ok: found v1.03 
Checking for    DateTime-TimeZone (v0.71)     ok: found v1.60 
Checking for                  DBI (v1.54)     ok: found v1.609 
Checking for     Template-Toolkit (v2.22)     ok: found v2.25 
Checking for           Email-Send (v2.04)     ok: found v2.199 
Checking for           Email-MIME (v1.904)    ok: found v1.924 
Checking for                  URI (v1.37)     ok: found v1.60 
Checking for       List-MoreUtils (v0.32)     ok: found v0.33 
Checking for    Math-Random-ISAAC (v1.0.1)    ok: found v1.004 

Checking available perl DBD modules...
Checking for               DBD-Pg (v2.7.0)    ok: found v2.15.1 
Checking for            DBD-mysql (v4.001)    not found 
Checking for           DBD-SQLite (v1.29)     not found 
Checking for           DBD-Oracle (v1.19)     not found 

The following Perl modules are optional:
Checking for                   GD (v1.20)     ok: found v2.44 
Checking for                Chart (v2.1)      ok: found v2.4.6 
Checking for          Template-GD (any)       ok: found v1.56 
Checking for           GDTextUtil (any)       ok: found v0.86 
Checking for              GDGraph (any)       ok: found v1.48 
Checking for           MIME-tools (v5.406)    ok: found v5.504 
Checking for          libwww-perl (any)       ok: found v6.05 
Checking for             XML-Twig (any)       ok: found v3.34 
Checking for          PatchReader (v0.9.6)    ok: found v0.9.6 
Checking for            perl-ldap (any)       ok: found v0.40 
Checking for          Authen-SASL (any)       ok: found v2.13 
Checking for         Net-SMTP-SSL (v1.01)     ok: found v1.01 
Checking for           RadiusPerl (any)       ok: found v0.23 
Checking for            SOAP-Lite (v0.712)    ok: found v1.06 
Checking for             JSON-RPC (any)       ok: found v1.03 
Checking for              JSON-XS (v2.0)      ok: found v2.34 
Checking for           Test-Taint (any)       ok: found v1.06 
Checking for          HTML-Parser (v3.40)     ok: found v3.64 
Checking for        HTML-Scrubber (any)       ok: found v0.09 
Checking for               Encode (v2.21)     ok: found v2.35 
Checking for        Encode-Detect (any)       ok: found v1.01 
Checking for          Email-Reply (any)       ok: found v1.203 
Checking for HTML-FormatText-WithLinks (v0.13)     ok: found v0.14 
Checking for          TheSchwartz (any)       ok: found v1.10 
Use of uninitialized value $ENV{"FLOCK_FORKING_USE"} in string eq at /usr/local/share/perl5/File/Flock/Forking.pm line 13, <DATA> line 522.
Checking for       Daemon-Generic (any)       ok: found v0.83 
Checking for             mod_perl (v1.999022) ok: found v2.000004 
Checking for     Apache-SizeLimit (v0.96)     ok: found v0.96 
Checking for        File-MimeInfo (any)       ok: found v0.18 
Checking for           IO-stringy (any)       ok: found v2.110 
Checking for          mod_headers (any)       ok 
Checking for          mod_expires (any)       ok 
Checking for              mod_env (any)       ok 
Reading ./localconfig...
Checking for               DBD-Pg (v2.7.0)    ok: found v2.15.1 
Checking for           PostgreSQL (v8.03.0000) ok: found v08.04.1300 

Adding new table bz_schema...
Initializing bz_schema...
Creating tables...
Creating function array_accum...
Removing index 'bugs_fulltext_comments_idx' from the bugs_fulltext table...
Removing index 'bugs_fulltext_comments_noprivate_idx' from the bugs_fulltext table...
Adding new index 'profiles_login_name_lower_idx' to the profiles table ...
Adding new index 'fielddefs_name_lower_idx' to the fielddefs table ...
Adding new index 'keyworddefs_name_lower_idx' to the keyworddefs table ...
Adding new index 'products_name_lower_idx' to the products table ...
Setting up choices for standard drop-down fields:
   bug_status priority rep_platform resolution op_sys bug_severity
Creating ./data directory...
Creating ./data/attachments directory...
Creating ./data/db directory...
Creating ./data/extensions directory...
Creating ./data/mining directory...
Creating ./data/webdot directory...
Creating ./graphs directory...
Creating ./skins/custom directory...
Creating ./data/extensions/additional...
Creating ./data/mailer.testfile...
Creating ./Bugzilla/.htaccess...
Creating ./data/.htaccess...
Creating ./data/attachments/.htaccess...
Creating ./data/webdot/.htaccess...
Creating ./graphs/.htaccess...
Creating ./lib/.htaccess...
Creating ./template/.htaccess...
Creating contrib/.htaccess...
Creating t/.htaccess...
Creating xt/.htaccess...
Precompiling templates...done.
Fixing file permissions...
Initializing "Dependency Tree Changes" email_setting ...
Initializing "Product/Component Changes" email_setting ...
Marking closed bug statuses as such...
Creating default classification 'Unclassified'...
Setting up foreign keys...
Setting up the default status workflow...
Creating default groups...
Setting up user preferences...

Looks like we don't have an administrator set up yet. Either this is
your first time using Bugzilla, or your administrator's privileges
might have accidentally been deleted.
Enter the e-mail address of the administrator: admin@alteeve.ca
Enter the real name of the administrator: Alteeve Admin
Enter a password for the administrator account: 
Please retype the password to verify:
admin@alteeve.ca is now set up as an administrator.
Creating initial dummy product 'TestProduct'...

Now that you have installed Bugzilla, you should visit the 'Parameters'
page (linked in the footer of the Administrator account) to ensure it
is set up as you wish - this includes setting the 'urlbase' option to
the correct URL.
checksetup.pl complete.

Configure Apache for Bugzilla

Now move the files into the web root, switch to the web root document

rsync -av /var/www/ssl_bugs.alteeve.ca/temp/bugzilla-4.4/* /var/www/ssl_bugs.alteeve.ca/html/
chown -R apache:apache /var/www/ssl_bugs.alteeve.ca
cd /var/www/ssl_bugs.alteeve.ca/html

Next, setup the apache configuration files. We'll need two;

  • bugs.alteeve.ca.conf; rewrite all non-SSL requests to their SSL version.
  • ssl_bugs.alteeve.ca.conf; The actual configuration file.

The configuration to rewrite any incoming http:// requests to https:// requests.

vim /etc/httpd/conf.d/bugs.alteeve.ca.conf
<VirtualHost *:80>
	ServerAdmin admin@alteeve.ca

	ServerName bugs.alteeve.ca

	RedirectMatch permanent (.*) https://bugs.alteeve.ca$1

	ErrorLog /var/www/bugs.alteeve.ca/logs/error.log

	# Possible values include: debug, info, notice, warn, error, crit,
	# alert, emerg.
	LogLevel debug

	CustomLog /var/www/bugs.alteeve.ca/logs/access.log combined
	ServerSignature On
</VirtualHost>

Now write the actual SSL-enabled configuration for bugzilla.

vim /etc/httpd/conf.d/ssl_bugs.alteeve.ca.conf
<VirtualHost *:443>
	ServerAdmin admin@alteeve.ca

	ServerName bugs.alteeve.ca

	#DirectoryIndex index.cgi
	
	# We can haz security?
	SSLEngine on
	SSLProtocol all
	SSLCACertificateFile /etc/pki/CA/RapidSSL_CA_bundle.pem
	SSLCertificateFile /etc/pki/CA/ssl_bugs.alteeve.ca.crt
	SSLCertificateKeyFile /etc/pki/CA/private/bugs.alteeve.ca.key
    	
	DocumentRoot /var/www/ssl_bugs.alteeve.ca/html/
	Alias /w /var/www/ssl_bugs.alteeve.ca/html/index.php
	<Directory /var/www/ssl_bugs.alteeve.ca/html>
		AddHandler cgi-script .cgi
		Options +ExecCGI
		DirectoryIndex index.cgi index.html
		AllowOverride Limit FileInfo Indexes Options
		#Options +Includes Indexes FollowSymLinks MultiViews
		#AllowOverride All 
		#Order allow,deny
		#allow from all
	</Directory>

	ErrorLog /var/www/ssl_bugs.alteeve.ca/logs/error.log
	TransferLog /var/www/ssl_bugs.alteeve.ca/logs/transfer.log

	# Possible values include: debug, info, notice, warn, error, crit,
	# alert, emerg.
	LogLevel info

	CustomLog /var/www/ssl_bugs.alteeve.ca/logs/access.log combined
	ServerSignature On
</VirtualHost>

Verify the syntax;

apachectl -t
Syntax OK
apachectl -S
VirtualHost configuration:
wildcard NameVirtualHosts and _default_ servers:
*:443                  bugs.alteeve.ca (/etc/httpd/conf.d/ssl_bugs.alteeve.ca.conf:1)
*:80                   is a NameVirtualHost
         default server unknown.alteeve.ca (/etc/httpd/conf.d/00_default.conf:1)
         port 80 namevhost unknown.alteeve.ca (/etc/httpd/conf.d/00_default.conf:1)
         port 80 namevhost bugs.alteeve.ca (/etc/httpd/conf.d/bugs.alteeve.ca.conf:1)
         port 80 namevhost bugs.alteeve.ca (/etc/httpd/conf.d/ssl.conf:74)
Syntax OK

Run a final check of the bugzilla configuration;

cd /var/www/ssl_bugs.alteeve.ca/html
./checksetup.pl
* This is Bugzilla 4.4 on perl 5.10.1
* Running on Linux 2.6.32-358.18.1.el6.x86_64 #1 SMP Wed Aug 28 17:19:38 UTC 2013

Checking perl modules...
Checking for               CGI.pm (v3.51)     ok: found v3.63 
Checking for           Digest-SHA (any)       ok: found v5.47 
Checking for             TimeDate (v2.23)     ok: found v2.24 
Checking for             DateTime (v0.28)     ok: found v1.03 
Checking for    DateTime-TimeZone (v0.71)     ok: found v1.60 
Checking for                  DBI (v1.54)     ok: found v1.609 
Checking for     Template-Toolkit (v2.22)     ok: found v2.25 
Checking for           Email-Send (v2.04)     ok: found v2.199 
Checking for           Email-MIME (v1.904)    ok: found v1.924 
Checking for                  URI (v1.37)     ok: found v1.60 
Checking for       List-MoreUtils (v0.32)     ok: found v0.33 
Checking for    Math-Random-ISAAC (v1.0.1)    ok: found v1.004 

Checking available perl DBD modules...
Checking for               DBD-Pg (v2.7.0)    ok: found v2.15.1 
Checking for            DBD-mysql (v4.001)    not found 
Checking for           DBD-SQLite (v1.29)     not found 
Checking for           DBD-Oracle (v1.19)     not found 

The following Perl modules are optional:
Checking for                   GD (v1.20)     ok: found v2.44 
Checking for                Chart (v2.1)      ok: found v2.4.6 
Checking for          Template-GD (any)       ok: found v1.56 
Checking for           GDTextUtil (any)       ok: found v0.86 
Checking for              GDGraph (any)       ok: found v1.48 
Checking for           MIME-tools (v5.406)    ok: found v5.504 
Checking for          libwww-perl (any)       ok: found v6.05 
Checking for             XML-Twig (any)       ok: found v3.34 
Checking for          PatchReader (v0.9.6)    ok: found v0.9.6 
Checking for            perl-ldap (any)       ok: found v0.40 
Checking for          Authen-SASL (any)       ok: found v2.13 
Checking for         Net-SMTP-SSL (v1.01)     ok: found v1.01 
Checking for           RadiusPerl (any)       ok: found v0.23 
Checking for            SOAP-Lite (v0.712)    ok: found v1.06 
Checking for             JSON-RPC (any)       ok: found v1.03 
Checking for              JSON-XS (v2.0)      ok: found v2.34 
Checking for           Test-Taint (any)       ok: found v1.06 
Checking for          HTML-Parser (v3.40)     ok: found v3.64 
Checking for        HTML-Scrubber (any)       ok: found v0.09 
Checking for               Encode (v2.21)     ok: found v2.35 
Checking for        Encode-Detect (any)       ok: found v1.01 
Checking for          Email-Reply (any)       ok: found v1.203 
Checking for HTML-FormatText-WithLinks (v0.13)     ok: found v0.14 
Checking for          TheSchwartz (any)       ok: found v1.10 
Use of uninitialized value $ENV{"FLOCK_FORKING_USE"} in string eq at /usr/local/share/perl5/File/Flock/Forking.pm line 13, <DATA> line 522.
Checking for       Daemon-Generic (any)       ok: found v0.83 
Checking for             mod_perl (v1.999022) ok: found v2.000004 
Checking for     Apache-SizeLimit (v0.96)     ok: found v0.96 
Checking for        File-MimeInfo (any)       ok: found v0.18 
Checking for           IO-stringy (any)       ok: found v2.110 
Checking for          mod_headers (any)       ok 
Checking for          mod_expires (any)       ok 
Checking for              mod_env (any)       ok 
Reading ./localconfig...
Checking for               DBD-Pg (v2.7.0)    ok: found v2.15.1 
Checking for           PostgreSQL (v8.03.0000) ok: found v08.04.1300 

Removing existing compiled templates...
Precompiling templates...done.
Fixing file permissions...

Now that you have installed Bugzilla, you should visit the 'Parameters'
page (linked in the footer of the Administrator account) to ensure it
is set up as you wish - this includes setting the 'urlbase' option to
the correct URL.
checksetup.pl complete.

Start up the server!

/etc/init.d/httpd start
Starting httpd: Apache/2.2.15 mod_ssl/2.2.15 (Pass Phrase Dialog)
Some of your private key files are encrypted for security reasons.
In order to read them you have to provide the pass phrases.

Server bugs.alteeve.ca:443 (RSA)
Enter pass phrase:

OK: Pass Phrase Dialog successful.
                                                           [  OK  ]

If everything is working, you should be able to browse to your bugzilla install!

Configure Bugzilla Itself

Log in as the adminitrator (user name is the email address you entered earlier with ./checksetup.pl) and go to https://<domain>/editparams.cgi.

  • General
Variab Value
urlbase https://bugs.alteeve.ca
ssl_redirect Click to check On
sslbase https://bugs.alteeve.ca
  • Email
Variab Value
mail_delivery_method SMTP
mailfrom bugs@alteeve.ca
use_mailer_queue Click to check On
smtpserver mail.alteeve.ca
smtp_username bugs@alteeve.ca
smtp_password secret
smtp_ssl Click to check On
globalwatchers admin@alteeve.ca

Mailman

Mailing list software!

Install Mailman

We need mailman 3 in order to get encrypted passwords. So we'll not be using mailman as shipped with RHEL6.

Install Prerequisite RPMs

yum -y install postfix mailx httpd gcc mod_ssl
chkconfig postfix on
chkconfig httpd on

Install Python 2.7

From here.

wget -qO- http://people.redhat.com/bkabrda/scl_python27.repo >> /etc/yum.repos.d/scl.repo
yum update
yum -y install python27
scl enable python27 bash
python -V

You should get:

Python 2.7.5

Configure Local Postfix

vim /etc/postfix/main.cf

Add:

queue_directory = /var/spool/postfix
command_directory = /usr/sbin
daemon_directory = /usr/libexec/postfix
data_directory = /var/lib/postfix
mail_owner = postfix
mydomain = lists.alteeve.ca
inet_interfaces = all
inet_protocols = all
mydestination = lists.alteeve.ca
unknown_local_recipient_reject_code = 550
mynetworks_style = subnet
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
debug_peer_level = 2
debugger_command =
	 PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin
	 ddd $daemon_directory/$process_name $process_id & sleep 5
sendmail_path = /usr/sbin/sendmail.postfix
newaliases_path = /usr/bin/newaliases.postfix
mailq_path = /usr/bin/mailq.postfix
setgid_group = postdrop
html_directory = no
manpage_directory = /usr/share/man
sample_directory = /usr/share/doc/postfix-2.6.6/samples
readme_directory = /usr/share/doc/postfix-2.6.6/README_FILES

(Re)start postfix:

/etc/init.d/postfix restart

Test local mail delivery:

echo hi | mailx -s test admin@alteeve.ca

If you got an email, local mail delivery is working.

Configure Apache for Mailman

Follow the Apache install above. Come back here

We will configure http://lists.alteeve.ca to redirect all calls to https://lists.alteeve.ca.

Specific configs:

Base apache:

diff -U0 /etc/httpd/conf/httpd.conf.orig /etc/httpd/conf/httpd.conf
--- /etc/httpd/conf/httpd.conf.orig	2013-02-25 18:26:51.000000000 -0500
+++ /etc/httpd/conf/httpd.conf	2014-04-03 21:00:51.952003006 -0400
@@ -103,6 +103,6 @@
-StartServers       8
-MinSpareServers    5
-MaxSpareServers   20
-ServerLimit      256
-MaxClients       256
-MaxRequestsPerChild  4000
+StartServers      16
+MinSpareServers   10
+MaxSpareServers   40
+ServerLimit      512
+MaxClients       512
+MaxRequestsPerChild  8000
@@ -119,5 +119,5 @@
-StartServers         4
-MaxClients         300
-MinSpareThreads     25
-MaxSpareThreads     75 
-ThreadsPerChild     25
+StartServers         8
+MaxClients         600
+MinSpareThreads     50
+MaxSpareThreads    150 
+ThreadsPerChild     50
@@ -262 +262 @@
-ServerAdmin root@localhost
+ServerAdmin admin@alteeve.ca
@@ -276 +276 @@
-#ServerName www.example.com:80
+ServerName lists.alteeve.ca:80
@@ -292 +292 @@
-DocumentRoot "/var/www/html"
+DocumentRoot "/var/www/default/html"
@@ -317 +317 @@
-<Directory "/var/www/html">
+<Directory "/var/www/default/html">
@@ -551 +551 @@
-Alias /icons/ "/var/www/icons/"
+Alias /icons/ "/var/www/default/icons/"
@@ -553 +553 @@
-<Directory "/var/www/icons">
+<Directory "/var/www/default/icons">
@@ -576 +576 @@
-ScriptAlias /cgi-bin/ "/var/www/cgi-bin/"
+ScriptAlias /cgi-bin/ "/var/www/default/cgi-bin/"
@@ -579 +579 @@
-# "/var/www/cgi-bin" should be changed to whatever your ScriptAliased
+# "/var/www/default/cgi-bin" should be changed to whatever your ScriptAliased
@@ -582 +582 @@
-<Directory "/var/www/cgi-bin">
+<Directory "/var/www/default/cgi-bin">
@@ -851 +851 @@
-# /var/www/error/include/ files and
+# /var/www/default/error/include/ files and
@@ -855 +855 @@
-Alias /error/ "/var/www/error/"
+Alias /error/ "/var/www/default/error/"
@@ -859 +859 @@
-    <Directory "/var/www/error">
+    <Directory "/var/www/default/error">
@@ -990 +990 @@
-#NameVirtualHost *:80
+NameVirtualHost *:80

SSL setup:

diff -U0 /etc/httpd/conf.d/ssl.conf.orig /etc/httpd/conf.d/ssl.conf
--- /etc/httpd/conf.d/ssl.conf.orig	2014-04-03 21:37:26.431005814 -0400
+++ /etc/httpd/conf.d/ssl.conf	2014-04-03 21:10:16.558004490 -0400
@@ -74 +74 @@
-<VirtualHost _default_:443>
+<VirtualHost _default_:80>

Configure the http redirect to https:

vim /etc/httpd/conf.d/lists.alteeve.ca.conf
<VirtualHost *:80>
	ServerAdmin admin@alteeve.ca

	ServerName lists.alteeve.ca

	RedirectMatch permanent (.*) https://lists.alteeve.ca$1

	ErrorLog /var/www/lists.alteeve.ca/logs/error.log
	LogLevel debug

	CustomLog /var/www/lists.alteeve.ca/logs/access.log combined
	ServerSignature On
</VirtualHost>

Setup the main https page:

vim /etc/httpd/conf.d/ssl_lists.alteeve.ca.conf
<VirtualHost *:443>
        ServerAdmin admin@alteeve.ca
 
        ServerName lists.alteeve.ca
 
        DirectoryIndex index.php index.html
 
        # We can haz security?
        SSLEngine on
        SSLProtocol all
        SSLCACertificateFile /etc/pki/CA/RapidSSL_CA_bundle.pem
        SSLCertificateFile /etc/pki/CA/wildcard_ssl_alteeve.ca.crt
        SSLCertificateKeyFile /etc/pki/CA/private/wildcard_alteeve.ca.key
 
        DocumentRoot /var/www/ssl_lists.alteeve.ca/html/
        Alias /w /var/www/ssl_lists.alteeve.ca/html/index.php
        <Directory /var/www/ssl_lists.alteeve.ca/html>
                Options +Includes Indexes FollowSymLinks MultiViews
                AllowOverride All
                Order allow,deny
                allow from all
        </Directory>
 
        ScriptAlias /cgi-bin/ /var/www/ssl_lists.alteeve.ca/cgi-bin/
        <Directory "/var/www/ssl_lists.alteeve.ca/cgi-bin">
                AllowOverride None
                Options ExecCGI -MultiViews +SymLinksIfOwnerMatch
                Order allow,deny
                Allow from all
        </Directory>
 
        ErrorLog /var/www/ssl_lists.alteeve.ca/logs/error.log
        TransferLog /var/www/ssl_lists.alteeve.ca/logs/transfer.log
 
        # Possible values include: debug, info, notice, warn, error, crit,
        # alert, emerg.
        LogLevel debug
 
        CustomLog /var/www/ssl_lists.alteeve.ca/logs/access.log combined
        ServerSignature On
</VirtualHost>

Copy the wildcard SSL certs into place.

Create a redirect page:

mkdir -p /var/www/ssl_lists.alteeve.ca/{cgi-bin,html,logs}
touch /var/www/ssl_lists.alteeve.ca/html/index.html
chown -R apache:apache /var/www
vim /var/www/ssl_lists.alteeve.ca/html/index.html
<head>
        <title>Alteeve's Niche! - Mailing Lists</title>
</head>
<body>
        <meta http-equiv="refresh" content="0; url=mailman/listinfo/" />
</body>

Connect to http://lists.alteeve.ca and it should automatically redirect to: http://lists.alteeve.ca/mailman/listinfo/.

Add an MX Record to Bind For lists.alteeve.ca

Add an entry in bind so that there is an MX record for lists.alteeve.ca:

/etc/named/db.alteeve.ca

Add:

lists.alteeve.ca.	MX	10	lists.alteeve.ca.

Save and reload named.

/etc/init.d/named reload

Install Mailman v3 from Source

At this time, the only v3 install is beta.

mkdir ~/temp
cd ~/temp/
wget https://launchpad.net/mailman/3.0/3.0.0b3/+download/mailman-3.0.0b3.tar.gz
tar -xvzf mailman-3.0.0b3.tar.gz 
cd mailman-3.0.0b3
python setup.py build
python setup.py install

And here, the best laid plans fell to pieces... Back to mailman 2.

Configure Mailmain

Create the initial mailman list.

/usr/lib/mailman/bin/newlist anvil-users
Enter the email of the person running the list: admin@alteeve.ca
Initial anvil-users password:
To finish creating your mailing list, you must edit your /etc/aliases (or
equivalent) file by adding the following lines, and possibly running the
`newaliases' program:

## anvil-users mailing list
anvil-users:              "|/usr/lib/mailman/mail/mailman post anvil-users"
anvil-users-admin:        "|/usr/lib/mailman/mail/mailman admin anvil-users"
anvil-users-bounces:      "|/usr/lib/mailman/mail/mailman bounces anvil-users"
anvil-users-confirm:      "|/usr/lib/mailman/mail/mailman confirm anvil-users"
anvil-users-join:         "|/usr/lib/mailman/mail/mailman join anvil-users"
anvil-users-leave:        "|/usr/lib/mailman/mail/mailman leave anvil-users"
anvil-users-owner:        "|/usr/lib/mailman/mail/mailman owner anvil-users"
anvil-users-request:      "|/usr/lib/mailman/mail/mailman request anvil-users"
anvil-users-subscribe:    "|/usr/lib/mailman/mail/mailman subscribe anvil-users"
anvil-users-unsubscribe:  "|/usr/lib/mailman/mail/mailman unsubscribe anvil-users"

Hit enter to notify anvil-users owner...

Edit the alias file:

vim /etc/aliases

Append:

## anvil-users mailing list
anvil-users:              "|/usr/lib/mailman/mail/mailman post anvil-users"
anvil-users-admin:        "|/usr/lib/mailman/mail/mailman admin anvil-users"
anvil-users-bounces:      "|/usr/lib/mailman/mail/mailman bounces anvil-users"
anvil-users-confirm:      "|/usr/lib/mailman/mail/mailman confirm anvil-users"
anvil-users-join:         "|/usr/lib/mailman/mail/mailman join anvil-users"
anvil-users-leave:        "|/usr/lib/mailman/mail/mailman leave anvil-users"
anvil-users-owner:        "|/usr/lib/mailman/mail/mailman owner anvil-users"
anvil-users-request:      "|/usr/lib/mailman/mail/mailman request anvil-users"
anvil-users-subscribe:    "|/usr/lib/mailman/mail/mailman subscribe anvil-users"
anvil-users-unsubscribe:  "|/usr/lib/mailman/mail/mailman unsubscribe anvil-users"

And load:

newaliases

WebUI Config

  1. https://lists.alteeve.ca/mailman/admin/anvil-users/general
    1. Hide the sender of a message, replacing it with the list address (Removes From, Sender and Reply-To fields) -> Yes.

Deleting Mail from the Archive

Go to the list directory:

cd /var/lib/mailman/archives/private

Edit the .mbox file for the list.

vim anvil-users.mbox/anvil-users.mbox

Find the message you want to delete and then delete everything from From <sender email> <date> until the same line from the next message (or end of the file if it's the last message in the list).

Example:

From lists@alteeve.ca  Thu Apr  3 23:35:27 2014
Return-Path: <lists@alteeve.ca>
X-Original-To: anvil-users@lists.alteeve.ca
Delivered-To: anvil-users@lists.alteeve.ca
Received: from vm08-mail01.alteeve.ca (unknown [65.39.153.71])
        by vm17-lists.alteeve.ca (Postfix) with ESMTP id DD83313FB13
        for <anvil-users@lists.alteeve.ca>;
        Thu,  3 Apr 2014 23:35:27 -0400 (EDT)
Received: from lemass.alteeve.ca (dhcp-108-168-20-202.cable.user.start.ca
        [108.168.20.202])
        by vm08-mail01.alteeve.ca (Postfix) with ESMTPSA id 80EC720171
        for <anvil-users@lists.alteeve.ca>;
        Thu,  3 Apr 2014 23:00:07 -0400 (EDT)
Message-ID: <533E2037.1020302@alteeve.ca>
Date: Thu, 03 Apr 2014 23:00:07 -0400
From: Digimer <lists@alteeve.ca>
User-Agent: Mozilla/5.0 (X11; Linux x86_64;
        rv:24.0) Gecko/20100101 Thunderbird/24.4.0
MIME-Version: 1.0
To: anvil-users@lists.alteeve.ca
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit
Subject: [Anvil-users] Test
X-BeenThere: anvil-users@lists.alteeve.ca
X-Mailman-Version: 2.1.12
Precedence: list
List-Id: <anvil-users.lists.alteeve.ca>
List-Unsubscribe: <https://lists.alteeve.ca/mailman/options/anvil-users>,
        <mailto:anvil-users-request@lists.alteeve.ca?subject=unsubscribe>
List-Archive: <http://lists.alteeve.ca/pipermail/anvil-users/>
List-Post: <mailto:anvil-users@lists.alteeve.ca>
List-Help: <mailto:anvil-users-request@lists.alteeve.ca?subject=help>
List-Subscribe: <https://lists.alteeve.ca/mailman/listinfo/anvil-users>,
        <mailto:anvil-users-request@lists.alteeve.ca?subject=subscribe>
X-List-Received-Date: Fri, 04 Apr 2014 03:35:27 -0000

Please ignore.

-- 
Digimer
Papers and Projects: https://alteeve.ca/w/
What if the cure for cancer is trapped in the mind of a person without 
access to education?

Once deleted, move the list directory out of the way and then regenerate the list archives.

mv /var/lib/mailman/archives/private/anvil-users /var/lib/mailman/archives/private/anvil-users.1
/usr/lib/mailman/bin/arch anvil-users
#00000 <CA+scbRK1dZAY6Jv5UqBM7-cG_L385QCtFY5UFx3RWRABN7sG1g@mail.gmail.com>
figuring article archives
2014-April
#00001 <CA+scbRJ96jXnx=0iFk220FsoEFghNoR2gwLg-DmTQ3rL2qDw+w@mail.gmail.com>
figuring article archives
2014-April
#00002 <533E2CF6.7080909@alteeve.ca>
figuring article archives
2014-April
Updating index files for archive [2014-April]
  Date
  Subject
  Author
  Thread
Computing threaded index
Updating HTML for article 0
Updating HTML for article 1
Updating HTML for article 2
Pickling archive state into /var/lib/mailman/archives/private/anvil-users/pipermail.pck

Reload the archive page and verify that the email is gone.

If so, delete the backup directory.

rm -rf /var/lib/mailman/archives/private/anvil-users.1

Thanks

 

Any questions, feedback, advice, complaints or meanderings are welcome.
Alteeve's Niche! Enterprise Support:
Alteeve Support
Community Support
© Alteeve's Niche! Inc. 1997-2024   Anvil! "Intelligent Availability®" Platform
legal stuff: All info is provided "As-Is". Do not use anything here unless you are willing and able to take responsibility for your own actions.