--- /dev/null
+<html>
+ <head>
+ <title>Dovecot on Centos 7</title>
+ <script src="/scripts/charNames.js" ></script>
+ <link rel="icon" type="image/png" href="/favicon.png">
+ <meta name="title" content="Dovecot on Centos 6">
+ <meta name="description" content="Installing and configuring Dovecot and
+ E-mailrelay as an intermediate mail server on a Centos 6 VM.">
+ <style>
+ pre
+ {
+ background-color: #DDD;
+ padding: .5em .75em;
+ margin: 0em;
+ font-weight: 600;
+ }
+
+ .filename
+ {
+ margin-bottom: 0em;
+ padding-bottom: 0em;
+ background-color:#CCCCCC;
+ font-weight: bold;
+ padding: .2em .5em;
+ font-size: 1.1em;
+ }
+
+ .filename:before
+ {
+ content: "nano ";
+ }
+
+ .TODO
+ {
+ background-color: #DD5;
+ font-weight: bold;
+ }
+
+ .var
+ {
+ color: #383;
+ font-weight: bold;
+ }
+
+ .suggested
+ {
+ color: #AA0;
+ font-weight: bold;
+ }
+
+ .security
+ {
+ color: #C44;
+ font-weight: bold;
+ }
+ </style>
+ </head>
+
+<body>
+
+<h1>Legend</h1>
+<p>
+<span class="todo">Work in progress</span><br>
+<span class="var">Installation specific values</span><br>
+<span class="suggested">SC standard configuration</span><br>
+<span class="security">Security configuration</span>
+</p>
+
+<h1>Base System Setup</h1>
+<p>Update the OS and install dovecot and (optionally) nano</p>
+<pre>
+yum update
+yum install sudo nano wget mailx dovecot procmail fetchmail
+</pre>
+
+<p>Create required user accounts.</p>
+<p>For the fetchmail filtering described in the
+ next step, you may also want to create the users <span class="suggested">
+ spam</span> and <span class="suggested">pending</span></p>
+<pre>
+useradd <span class="var"><username></span> -m -d /home/<span class="var"><username></span> -s /bin/bash
+usermod -a -G mail <span class="var"><username></span>
+su - <span class="var"><username></span>
+</pre>
+
+<h1>Configure Fetchmail</h1>
+<p>Create required files:</p>
+<pre>
+touch /home/<span class="var"><username></span>/.fetchmailrc
+chmod 0600 /home/<span class="var"><username></span>/.fetchmailrc
+touch /etc/init.d/fetchmail
+chmod +x /etc/init.d/fetchmail
+</pre>
+
+<p>Create mail filter (if desired).</p>
+<p>The filter shown below has a number of different features. Each block can be removed if
+ not required. Read the script comments for details.</p>
+<p>The first block is spam filtering by address -- any messages sent to an address listed
+ in the file /etc/mailblock.lst (one address per line) will be filtered and delivered to
+ the 'spam' user. You should have a 'spam' user setup the same as your other mail
+ accounts to use this feature.</p>
+<p>The second block is two-step verification filtering -- any messages sent to an address
+ listed in the file /etc/mailverify.lst will be held for verification. To use this feature,
+ you must configure a user 'pending' as well as a wildcard alias on '*-pending'. When a
+ message is delivered for one of the designated addresses, it will be stored with a randomly
+ generated ID number and a message will be sent to the sender from the address '<random>-pending'.
+ When the user replies to that mail, their original message will be sent to the address
+ originally provided</p>
+<p class="filename">/etc/mailDelivery.sh</pre>
+<pre>
+# The destination user can be selected either by an argument to the script,
+# or based on the user who is executing the script
+user="${1}"
+if [ -z "${user}" ]; then
+ user=`whoami`
+fi
+
+# Read the message and filter the destination addresses from it
+# The addresses will have "^" and "$" characters added to the start and end
+# for later grep commands.
+message=$(cat; echo x)
+address="`echo -n \"${message%x}\" | \
+ grep -e '^To: ' -e \$'^[ \t]*for' | \
+ awk '{print \"^\"$2\"\$\"}' | \
+ sed 's/[\"<>;]//g'`"
+
+
+
+
+# If a blacklist is provided at /etc/mailblock.lst, messages sent to that address
+# will be redirected to the inbox of the "spam" user
+if [ `cat /etc/mailblock.lst | grep -ic "${address}"` -gt 0 ]; then
+ user="spam"
+
+
+
+# If a list is provided at /etc/mailverify.lst, messages sent to those address
+# will require additional verification before being delivered.
+# A mail account must be configured for the 'pending' user, with a wildcard alias
+# configured on *-pending@<span class="var">domain</span>
+elif [ `cat /etc/mailverify.lst | grep -ic "${address}"` -gt 0 ]; then
+ # First, generate a random ID number to identify this message
+ idnum=$((RANDOM))
+ attempts=0
+ if [ ! -d /home/pending/messages/ ]; then
+ mkdir -p /home/pending/messages/
+ fi
+
+ # If the number is already used, retry up to ten times
+ while [ -f /home/pending/messages/$idnum.msg ] && [ $attempts -lt 10 ]; do
+ idnum=$((RANDOM))
+ attempts=`expr $attempts + 1`
+ done
+
+ # If we could not find a free number, fail to deliver
+ # The user will be sent the contents of /home/pending/failure.msg
+ # and their original message
+ if [ $attempts -eq 10 ]; then
+ echo "FAILURE"
+ msg=$(cat /home/pending/failure.msg)
+ echo "${msg} ${message}" | mailx -v \
+ -s "Your message could not be delivered" \
+ -S smtp-auth=cram-md5 \
+ -S smtp=smtp://mail.<span class="var">domain</span>:10025 \
+ -S from="<span class="var">domain</span> pending messages <$idnum-pending@<span class="var">domain</span>>" \
+ -S smtp-auth-user=pending \
+ -S smtp-auth-password='<span class="var">password</span>' \
+ -S nss-config-dir="/etc/pki/nssdb/" \
+ -S ssl-verify=warn \
+ -S smtp-use-starttls \
+ "${from}"
+ exit 1
+ fi
+
+ # Save the message, and give all mail users permission to access it
+ # This is required so it can be accessed by the correct destination user
+ echo -n "${message%x}" > /home/pending/messages/$idnum
+ chown `whoami`:mail /home/pending/messages/$idnum
+ chmod 660 /home/pending/messages/$idnum
+
+ # Get the sender's address from the message, and send them the contents of
+ # /home/pending/autoresponse.msg, with their message attached. The message
+ # will be sent from the address <random number>-pending@<span class="var">domain</span>
+ # and will be released when a reply is received to the same address
+ from="`cat /home/pending/messages/$idnum | \
+ grep '^From:' | \
+ cut -d':' -f2- | \
+ sed 's/[^@]*[ <]\([^ ]*@[^ ]*\)[^@]*/\1/g' | \
+ sed 's/[\"<>;]//g'`"
+ cat /home/pending/autoresponse.msg | mailx -v \
+ -a /home/pending/messages/$idnum \
+ -s "Action required: Your message was not delivered" \
+ -S smtp-auth=cram-md5 \
+ -S smtp=smtp://mail.<span class="var">domain</span>:10025 \
+ -S from="<span class="var">domain</span> pending messages >$idnum-pending@<span class="var">domain</span>>" \
+ -S smtp-auth-user=pending \
+ -S smtp-auth-password='<span class="var">password</span>' \
+ -S nss-config-dir="/etc/pki/nssdb/" \
+ -S ssl-verify=warn \
+ -S smtp-use-starttls \
+ "${from}"
+ exit 0
+
+# If a reply is received to a *-pending@<span class="var">domain</span> address,
+# send the saved message instead
+elif [ `ls /home/pending/messages/ | sed 's/$/-pending@bsflowers.net/g' | grep -ic "${address}"` -gt 0 ]; then
+ idnum="`echo \"${address}\" | \
+ sed 's/\^\([0-9]*\)-pending.*/\1/' | \
+ sort -u | \
+ grep -v [^0-9]`"
+ destination="`cat /home/pending/messages/$idnum | \
+ grep -e '^To: ' -e \$'^[ \t]*for' | \
+ awk '{print \"^\"$2\"\$\"}' | \
+ sed 's/[\"<>;]//g'`"
+
+ user=`echo $destination | cut -d '@' -f1 | cut -d'-' -f2 | sed 's/^^//g'`
+ cat /home/pending/messages/$idnum | sudo /usr/bin/procmail -d $user
+ rm /home/pending/messages/$idnum
+ exit 0
+fi
+
+
+
+# Useful for debugging -- saves a copy of each message in the user home
+# echo -n "${message%x}" > /home/$user/mail.tmp
+
+# Send the message
+echo -n "${message%x}" | sudo /usr/bin/procmail -d $user
+</pre>
+
+<p class="filename">/etc/mailblock.lst</p>
+<pre>
+spammy-address@<span class="var">domain</span>
+</pre>
+
+<p class="filename">/home/<span class="var"><username></span>/.fetchmailrc</p>
+<pre>
+set daemon <span class="suggested">300</span>
+poll <span class="var"><external mailserver></span> with proto <span class="suggested">pop3</span>
+ user <span class="var"><username></span>@<span class="var"><domain></span> with password '<span class="var"><password></span>' is '<span class="var"><username></span>' here
+ <span class="security">ssl</span>
+mda '/etc/maildelivery.sh %T'
+
+# Use the mda line below to disable filtering
+#mda '/usr/bin/procmail -d %T'
+</pre>
+
+<p class="filename">/etc/init.d/fetchmail</p>
+<pre>
+#!/bin/bash
+
+cut -d: -f1 /etc/passwd | while read USERNAME
+ do
+ if [ -f /home/${USERNAME}/.fetchmailrc ]; then
+ pid=`head -1 /home/${USERNAME}/.fetchmail.pid 2>/dev/null`
+ if [ "$1" = "start" ] && [ `kill -0 $pid 2>/dev/null; echo $?` -ne 0 ]; then
+ echo "Starting fetchmail for user: ${USERNAME}"
+ su - ${USERNAME} -c "fetchmail --daemon <span class="suggested">300</span> -f ~/.fetchmailrc"
+ elif [ "$1" = "stop" ]; then
+ echo "Stopping fetchmail for user: ${USERNAME}"
+ kill $pid
+ elif [ "$1" = "status" ]; then
+ if [ `kill -0 $pid 2>/dev/null; echo $?` -eq 0 ]; then
+ echo "Fetchmail is UP for user: ${USERNAME}"
+ else
+ echo "Fetchmail is DOWN for user: ${USERNAME}"
+ fi
+ fi
+ fi
+ done
+</pre>
+
+<p class="filename">/etc/systemd/system/fetchmail.service</p>
+<pre>
+[Unit]
+Description=Fetchmail multi-user mail import
+After=local-fs.target network.target network-online.target
+
+[Service]
+Type=oneshot
+ExecStart=/etc/init.d/fetchmail start
+ExecStop=/etc/init.d/fetchmail stop
+RemainAfterExit=yes
+
+[Install]
+WantedBy=multi-user.target
+</pre>
+
+<p>Enable the Fetchmail service</p>
+<pre>
+systemctl enable fetchmail
+</pre>
+
+<h1>Configure Dovecot</h1>
+
+
+<p class="filename">/etc/dovecot/dovecot.conf</p>
+<pre>
+protocols = imap
+listen = <span class="suggested">mail.</span><span class="var"><domain></span>
+verbose_proctitle = <span class="suggested">yes</span>
+shutdown_clients = <span class="suggested">yes</span>
+</pre>
+
+<p class="filename">/etc/dovecot/conf.d/10-auth.conf</p>
+<pre>
+disable_plaintext_auth = <span class="security">yes</span>
+auth_mechanism = <span class="suggested">plain cram-md5</span>
+!include auth-passwdfile.conf.ext
+</pre>
+
+<p class="filename">/etc/dovecot/conf.d/auth-passwdfile.conf.ext</p>
+<pre>
+passdb {
+ driver = passwd-file
+ args = scheme=cram-md5 <span class="suggested">/etc/dovecot/cram-md5.pwd</span>
+}
+
+# userdb { ... }
+</pre>
+
+<p>Get the cram-md5 password hash using emailrelay-passwd and create the password file:</p>
+<pre>
+emailrelay-passwd
+touch <span class="suggested">/etc/dovecot/cram-md5.pwd</span>
+chmod <span class="security">0600</span> <span class="suggested">/etc/dovecot/cram-md5.pwd</span>
+chown dovecot /etc/dovecot/cram-md5.pwd
+nano <span class="suggested">/etc/dovecot/cram-md5.pwd</span>
+</pre>
+
+<p class="filename">/etc/dovecot/cram-md5.pwd</p>
+<pre>
+<span class="var"><username></span>:<span class="var"><cram-md5 formatted password></span>
+</pre>
+
+<p class="filename">/etc/dovecot/conf.d/10-director.conf</p>
+<pre>
+<span class="todo">...</span>
+</pre>
+
+<p class="filename">/etc/dovecot/conf.d/10-logging.conf</p>
+<pre>
+<span class="todo">...</span>
+</pre>
+
+<p class="filename">/etc/dovecot/conf.d/10-mail.conf</p>
+<pre>
+mail_location = mbox:~/mail:INBOX=/var/mail/%u
+mail_attachment_dir = ~/attachments
+</pre>
+
+<p class="filename">/etc/dovecot/conf.d/10-master.conf</p>
+<pre>
+<span class="security">
+#inet_listener imap{<span class="todo">...</span>}
+inet_listener imaps{<span class="todo">...</span>}
+#service pop{<span class="todo">...</span>}
+#service lmtp{<span class="todo">...</span>}
+</span>
+</pre>
+
+<p class="filename">/etc/dovecot/conf.d/10-ssl.conf</p>
+<pre>
+<span class="security">
+ssl = yes
+ssl_cert = <<span class="suggested">/etc/pki/dovecot/certs/<span class="var">domain</span>.crt</span>
+ssl_key = <<span class="suggested">/etc/pki/dovecot/private/<span class="var">domain</span>.key</span>
+ssl_ca = <<span class="suggested">/etc/pki/dovecot/certs/<span class="var">ca</span>.pem</span>
+</span>
+</pre>
+
+<p class="filename">/etc/dovecot/conf.d/15-lda.conf</p>
+<pre>
+<span class="suggested">
+postmaster_address = mail@<span class="var"><domain></span>
+hostname = mail.<span class="var"><domain></span>
+</span>
+</pre>
+
+<p class="filename">/etc/dovecot/conf.d/20-imap.conf</p>
+<pre>
+imap_idle_notify_interval = <span class="suggested">1 mins</span>
+</pre>
+
+<p>Enable the Dovecot service</p>
+<pre>
+systemctl enable dovecot
+</pre>
+
+<h1>Install E-mailrelay</h1>
+<pre>
+sudo yum install gcc gcc-c++ <span class="security">openssl openssl-devel</span>
+cd ~
+wget https://sourceforge.net/projects/emailrelay/files/latest/download?source=files
+mv emailrelay* emailrelay.tar.gz
+tar -xzvf emailrelay.tar.gz
+cd emailrelay*
+./configure <span class="security">--with-openssl</span>
+make
+make install
+</pre>
+
+<h1>Configure E-mailrelay</h1>
+<p>Prepare SSL keys for E-mailrelay</p>
+<pre>
+<span class="security">
+cat <span class="suggested">/etc/pki/dovecot/certs/<span class="var">domain</span>.crt</span> <span class="suggested">/etc/pki/dovecot/private/<span class="var">domain</span>.key</span> > <span class="suggested">/etc/pki/dovecot/private/<span class="var">domain</span>.crt.key</span>
+</span>
+</pre>
+
+<p>Prepare authentication file</p>
+<pre>
+touch /etc/emailrelay.auth
+chmod <span class="security">0600</span> /etc/emailrelay.auth
+</pre>
+
+<p class="filename">/etc/emailrelay.auth</p>
+<pre>
+CRAM-MD5 server <span class="var"><E-mailrelay client login></span> <span class="var"><CRAM-MD5 encoded password></span>
+PLAIN client <span class="var"><remote SMTP server login></span> <span class="var"><plaintext password></span>
+</pre>
+
+<p>Create E-mailrelay filter for local mail delivery</p>
+<p class="filename">/etc/emailrelay-filter.sh</pre>
+<pre>
+#!/bin/sh
+# emailrelay-filter.sh
+
+# Function (if required) to convert incoming mail address to local username
+# As designed, this function will take an address like 'alias-user@domain.com'
+# and deliver it to 'user'
+addrToUser()
+{
+ <span class="suggested">ADDR="${1}"
+ USER=`echo $ADDR | awk -F"-" '{print $NF}'`
+ echo "$USER"</span>
+}
+
+content="${1}"
+envelope="`echo \"${content}\" | sed 's/content/envelope.new/'`"
+destination="`cat ${content} | grep '^To:' | cut -d':' -f2-`"
+
+while [ ! -z "${destination}" ]; do
+ islocal=`echo ${destination} | grep "@<span class="var">domain</span>" | wc -l`
+ if [ "$islocal" -lt 1 ]; then
+ exit 0
+ else
+ user="`echo ${destination} | sed 's/\([^ <]*\)@<span class="var">domain</span>[^ ;]*/\1/'`"
+ destination="`echo ${destination} | sed \"s/${user}@<span class="var">domain</span>//\"`"
+ localuser=`addrToUser ${user}`
+ cat "${content}" | grep -v "^To:" | sudo /usr/bin/procmail -d ${localuser}
+ fi
+ sleep 5
+done
+
+rm ${content} ${envelope}
+exit 100
+</pre>
+
+<p>Configure retry and failure notifications</p>
+<pre>
+<span class="todo">
+/usr/local/libexec/emailrelay/examples/emailrelay-notify.sh
+/usr/local/libexec/emailrelay/examples/emailrelay-resubmit.sh
+</span>
+</pre>
+
+<p>Create init file for E-mailrelay</p>
+<pre>
+touch /etc/init.d/emailrelay
+chmod +x /etc/init.d/emailrelay
+</pre>
+<p class="filename">/etc/init.d/emailrelay</p>
+<pre>
+#!/bin/bash
+
+#. /etc/init.d/functions
+
+if [ "$1" = "start" ]; then
+ /usr/local/sbin/emailrelay --as-proxy <span class="var">remote SMTP server</span>:<span class="security">587</span> <span class="security">--client-tls \
+ --client-auth /etc/emailrelay.auth</span> <span class="suggested">--port 10025</span> -r <span class="security">--server-tls <span class="suggested">/etc/pki/dovecot/private/<span class="var">domain</span>.crt.key</span></span> \
+ <span class="suggested">--filter /etc/emailrelay-filter.sh --pid-file /etc/emailrelay.pid</span> <span class="suggested">--verbose > /var/log/emailrelay.log</span>
+elif [ "$1" = "stop" ]; then
+ kill `cat /etc/emailrelay.pid`
+elif [ "$1" = "status" ]; then
+ pid=`cat /etc/emailrelay.pid`
+ wc=`ps -p $pid | wc -l`
+ if [ ! -z "$pid" ] && [ $wc -gt 1 ]; then
+ echo "E-mailrelay is running"
+ else
+ echo "E-mailrelay is NOT running"
+ fi
+fi
+</pre>
+
+<p class="filename">/etc/systemd/system/emailrelay.service</p>
+<pre>
+[Unit]
+Description=Emailrelay smtp proxy
+After=local-fs.target network.target network-online.target
+
+[Service]
+Type=simple
+PIDFile=/etc/emailrelay.pid
+ExecStart=/usr/local/sbin/emailrelay --as-proxy <span class="var">remote SMTP server</span>:<span class="security">587</span> <span class="security">--client-tls \
+ --client-auth /etc/emailrelay.auth</span> <span class="suggested">--port 10025</span> -r <span class="security">--server-tls <span class="suggested">/etc/pki/dovecot/private/<span class="var">domain</span>.crt.key</span></span> \
+ <span class="security">--server-auth=/etc/emailrelay.auth</span>
+ <span class="suggested">--filter /etc/emailrelay-filter.sh --pid-file /etc/emailrelay.pid</span> <span class="suggested">--verbose > /var/log/emailrelay.log</span>
+ExecStop=kill `cat /etc/emailrelay.pid`
+
+[Install]
+WantedBy=multi-user.target
+</pre>
+
+<p>Enable the Emailrelay service</p>
+<pre>
+systemctl enable emailrelay
+</pre>
+
+<h1>Configure sudo access</h1>
+<pre class="filename">/etc/sudoers</pre>
+<pre>
+# Allow sudo to be used in fetchmail mda script
+#Defaults requiretty
+
+# Allow users to send mail to other users
+daemon mail.bsflowers.net = (root) NOPASSWD: /usr/bin/procmail
+%mail mail.bsflowers.net = (root) NOPASSWD: /usr/bin/procmail
+</pre>
+
+<h1>Reboot and confirm services</h1>
+<pre>
+reboot
+systemctl status dovecot
+systemctl status emailrelay
+systemctl status fetchmail
+</pre>
+
+<h1>Verification</h1>
+<p>The following optional steps will help verify or troubleshoot the installation</p>
+
+<h2>Check Dovecot Status</h2>
+<p>This will show if the Dovecot server is running</p>
+<pre>
+systemctl status dovecot
+</pre>
+
+<h2>Check Dovecot Logs</h2>
+<p>Check for errors, and watch these logs while performing remaining steps</p>
+<pre>
+tail -f /var/log/dovecot.log
+</pre>
+
+<h2>Login to dovecot with SSL</h2>
+<p>The following commands are to login to the Dovecot IMAP server via SSL on port 993,
+and open the user's inbox. </p>
+<pre>
+openssl s_client -crlf -connect mail.<span class="var"><domain></span>:993
+tag login <span class="var"><username></span> "<span class="var"><password></span>"
+tag LIST "" "*"
+tag SELECT INBOX
+</pre>
+<p>You can also use this to check the certificate expiration dates</p>
+<pre>
+openssl s_client -crlf -connect mail.openssl s_client -crlf -connect mail.<span class="var"><domain></span>:993 | openssl x509 -noout -dates
+</pre>
+
+<h2>Check E-mailrelay logs</h2>
+<pre>
+tail -f /var/log/maillog
+</pre>
+
+<h2>Check user's mailbox locally</h2>
+<pre>
+su - <span class="var">user</span> mail
+</pre>
+
+</body>
+</html>
--- /dev/null
+<html>
+ <head>
+ <title>Apache on Centos 7</title>
+ <script src="/scripts/charNames.js" ></script>
+ <link rel="icon" type="image/png" href="/favicon.png">
+ <meta name="title" content="Apache on Centos 6">
+ <meta name="description" content="Installing and configuring Apache
+ web server on a Centos 7 VM.">
+ <style>
+ pre
+ {
+ background-color: #DDD;
+ padding: .5em .75em;
+ margin: 0em;
+ font-weight: 600;
+ }
+
+ .filename
+ {
+ margin-bottom: 0em;
+ padding-bottom: 0em;
+ background-color:#CCCCCC;
+ font-weight: bold;
+ padding: .2em .5em;
+ font-size: 1.1em;
+ }
+
+ .filename:before
+ {
+ content: "nano ";
+ }
+
+ .TODO
+ {
+ background-color: #DD5;
+ font-weight: bold;
+ }
+
+ .var
+ {
+ color: #383;
+ font-weight: bold;
+ }
+
+ .suggested
+ {
+ color: #AA0;
+ font-weight: bold;
+ }
+
+ .security
+ {
+ color: #C44;
+ font-weight: bold;
+ }
+ </style>
+ </head>
+
+<body>
+
+<h1>Legend</h1>
+<p>
+<span class="todo">Work in progress</span><br>
+<span class="var">Installation specific values</span><br>
+<span class="suggested">SC standard configuration</span><br>
+<span class="security">Security configuration</span>
+</p>
+
+<h1>Base System Setup</h1>
+<p>Update the OS and install httpd, ssh, and nano</p>
+<pre>
+yum update
+yum install sudo nano openssh-server mod_ssl openssl httpd
+</pre>
+
+<p>Install any optional plugins. For example, PHP</p>
+<pre>
+<span class="suggested">yum install php</span>
+</pre>
+
+<h1>Configure the server</h1>
+<p class="filename">/etc/httpd/conf/httpd.conf</p>
+<pre>
+<span class="security">#Listen 80</span>
+<span class="suggested">ServerAdmin www@<span class="var">domain</span></span>
+</pre>
+
+<h1>Configure SSL</h1>
+<p>If this server is hosting multiple domains, move the entire virtualhost tag into a separate file
+ (/etc/httpd/conf.d/<span class="var">domain</span>.conf) and create copies of that file for each domain
+<br/>And update certificate filenames as required (these are based on letsencrypt.org certs).</p>
+<p class="filename">/etc/httpd/conf.d/ssl.conf</p>
+<pre>
+<VirtualHost <span class="var">domain</span>:443>
+DocumentRoot "/var/www/html/<span class="var">domain</span>
+ServerAdmin www@<span class="var">domain</span>
+SSLCertificateFile /etc/pki/tls/certs/<span class="var">domain</span>/cert.pem
+SSLCertificateKeyFile /etc/pki/tls/certs/<span class="var">domain</span>/privkey.pem
+SSLCertificateChainFile /etc/pki/tls/certs/<span class="var">domain</span>/chain.pem
+</VirtualHost>
+</pre>
+
+<h1>Start the server</h1>
+<pre>
+systemctl enable httpd
+systemctl start httpd
+systemctl enable sshd
+systemctl start sshd
+</pre>
+</body>
+</html>
--- /dev/null
+<html>
+ <head>
+ <title>Git server on Debian 8</title>
+ <script src="/scripts/charNames.js" ></script>
+ <link rel="icon" type="image/png" href="/favicon.png">
+ <meta name="title" content="Git server on Debian 8">
+ <meta name="description" content="Installing and configuring a Git
+ repo and gitweb server on a Debian 8 VM.">
+ <style>
+ pre
+ {
+ background-color: #DDD;
+ padding: .5em .75em;
+ margin: 0em;
+ font-weight: 600;
+ }
+
+ .filename
+ {
+ margin-bottom: 0em;
+ padding-bottom: 0em;
+ background-color:#CCCCCC;
+ font-weight: bold;
+ padding: .2em .5em;
+ font-size: 1.1em;
+ }
+
+ .filename:before
+ {
+ content: "nano ";
+ }
+
+ .TODO
+ {
+ background-color: #DD5;
+ font-weight: bold;
+ }
+
+ .var
+ {
+ color: #383;
+ font-weight: bold;
+ }
+
+ .suggested
+ {
+ color: #AA0;
+ font-weight: bold;
+ }
+
+ .security
+ {
+ color: #C44;
+ font-weight: bold;
+ }
+ </style>
+ </head>
+
+<body>
+
+<h1>Legend</h1>
+<p>
+<span class="todo">Work in progress</span><br>
+<span class="var">Installation specific values</span><br>
+<span class="suggested">SC standard configuration</span><br>
+<span class="security">Security configuration</span>
+</p>
+
+<h1>Base System Setup</h1>
+<p>Update the OS and install the git server</p>
+<pre>
+apt-get update
+apt-get upgrade
+apt-get install git-core gitweb
+</pre>
+
+<h1>Configure Git server</h1>
+<p class="filename">/etc/gitweb.conf</p>
+<pre>
+$projectroot = "/home/git";
+</pre>
+
+<pre>
+useradd git -m -d /home/git -s /bin/bash
+su - git
+git config --global user.name "<span class="var">Repo Owner's Name</span>"
+git config --global user.email git@<span class="var">domain</span>
+</pre>
+<h1>Add a project</h1>
+<pre>
+mkdir <span class="var">project1</span>.git
+cd <span class="var">project1</span>
+git init --bare
+service apache2 restart
+</pre>
+
+<h1>Configure Apache webserver</h1>
+<p class="filename">/etc/apache2/ports.conf</p>
+<pre>
+#Listen 80
+</pre>
+
+<p class="filename">/etc/apache2/sites-available/default-ssl.conf</p>
+<pre>
+ServerAdmin git@<span class="var">domain</span>
+DocumentRoot /usr/share/gitweb
+
+SSLCertificateFile /etc/ssl/certs/<span class="var">domain</span>/cert.pem
+SSLCertificateKeyFile /etc/ssl/certs/<span class="var">domain</span>/privkey.pem
+SSLCertificateChainFile /etc/ssl/certs/<span class="var">domain</span>/fullchain.pem
+</pre>
+
+<pre>
+rn /etc/apache2/sites-enabled/000-default.conf
+ln /etc/apache2/sites-available/default-ssl.conf /etc/apache2/sites-enabled/default-ssl.conf
+a2enmod cgi
+a2enmod ssl
+service apache2 restart
+</pre>
+
+</body>
+</html>
--- /dev/null
+<html>
+ <head>
+ <title>Dovecot on Centos 7</title>
+ <script src="/scripts/charNames.js" ></script>
+ <link rel="icon" type="image/png" href="/favicon.png">
+ <meta name="title" content="Dovecot on Centos 6">
+ <meta name="description" content="Installing and configuring Dovecot and
+ E-mailrelay as an intermediate mail server on a Centos 6 VM.">
+ <style>
+ pre
+ {
+ background-color: #DDD;
+ padding: .5em .75em;
+ margin: 0em;
+ font-weight: 600;
+ }
+
+ .filename
+ {
+ margin-bottom: 0em;
+ padding-bottom: 0em;
+ background-color:#CCCCCC;
+ font-weight: bold;
+ padding: .2em .5em;
+ font-size: 1.1em;
+ }
+
+ .filename:before
+ {
+ content: "nano ";
+ }
+
+ .TODO
+ {
+ background-color: #DD5;
+ font-weight: bold;
+ }
+
+ .var
+ {
+ color: #383;
+ font-weight: bold;
+ }
+
+ .suggested
+ {
+ color: #AA0;
+ font-weight: bold;
+ }
+
+ .security
+ {
+ color: #C44;
+ font-weight: bold;
+ }
+ </style>
+ </head>
+
+<body>
+
+<h1>Legend</h1>
+<p>
+<span class="todo">Work in progress</span><br>
+<span class="var">Installation specific values</span><br>
+<span class="suggested">SC standard configuration</span><br>
+<span class="security">Security configuration</span>
+</p>
+
+<h1>Base System Setup</h1>
+<p>Update the OS and install dovecot and (optionally) nano</p>
+<pre>
+yum update
+yum install sudo nano wget mailx dovecot procmail fetchmail
+</pre>
+
+<p>Create required user accounts.</p>
+<p>For the fetchmail filtering described in the
+ next step, you may also want to create the users <span class="suggested">
+ spam</span> and <span class="suggested">pending</span></p>
+<pre>
+useradd <span class="var"><username></span> -m -d /home/<span class="var"><username></span> -s /bin/bash
+usermod -a -G mail <span class="var"><username></span>
+su - <span class="var"><username></span>
+</pre>
+
+<h1>Configure Fetchmail</h1>
+<p>Create required files:</p>
+<pre>
+touch /home/<span class="var"><username></span>/.fetchmailrc
+chmod 0600 /home/<span class="var"><username></span>/.fetchmailrc
+touch /etc/init.d/fetchmail
+chmod +x /etc/init.d/fetchmail
+</pre>
+
+<p>Create mail filter (if desired).</p>
+<p>The filter shown below has a number of different features. Each block can be removed if
+ not required. Read the script comments for details.</p>
+<p>The first block is spam filtering by address -- any messages sent to an address listed
+ in the file /etc/mailblock.lst (one address per line) will be filtered and delivered to
+ the 'spam' user. You should have a 'spam' user setup the same as your other mail
+ accounts to use this feature.</p>
+<p>The second block is two-step verification filtering -- any messages sent to an address
+ listed in the file /etc/mailverify.lst will be held for verification. To use this feature,
+ you must configure a user 'pending' as well as a wildcard alias on '*-pending'. When a
+ message is delivered for one of the designated addresses, it will be stored with a randomly
+ generated ID number and a message will be sent to the sender from the address '<random>-pending'.
+ When the user replies to that mail, their original message will be sent to the address
+ originally provided</p>
+<p class="filename">/etc/mailDelivery.sh</pre>
+<pre>
+# The destination user can be selected either by an argument to the script,
+# or based on the user who is executing the script
+user="${1}"
+if [ -z "${user}" ]; then
+ user=`whoami`
+fi
+
+# Read the message and filter the destination addresses from it
+# The addresses will have "^" and "$" characters added to the start and end
+# for later grep commands.
+message=$(cat; echo x)
+address="`echo -n \"${message%x}\" | \
+ grep -e '^To: ' -e \$'^[ \t]*for' | \
+ awk '{print \"^\"$2\"\$\"}' | \
+ sed 's/[\"<>;]//g'`"
+
+
+
+
+# If a blacklist is provided at /etc/mailblock.lst, messages sent to that address
+# will be redirected to the inbox of the "spam" user
+if [ `cat /etc/mailblock.lst | grep -ic "${address}"` -gt 0 ]; then
+ user="spam"
+
+
+
+# If a list is provided at /etc/mailverify.lst, messages sent to those address
+# will require additional verification before being delivered.
+# A mail account must be configured for the 'pending' user, with a wildcard alias
+# configured on *-pending@<span class="var">domain</span>
+elif [ `cat /etc/mailverify.lst | grep -ic "${address}"` -gt 0 ]; then
+ # First, generate a random ID number to identify this message
+ idnum=$((RANDOM))
+ attempts=0
+ if [ ! -d /home/pending/messages/ ]; then
+ mkdir -p /home/pending/messages/
+ fi
+
+ # If the number is already used, retry up to ten times
+ while [ -f /home/pending/messages/$idnum.msg ] && [ $attempts -lt 10 ]; do
+ idnum=$((RANDOM))
+ attempts=`expr $attempts + 1`
+ done
+
+ # If we could not find a free number, fail to deliver
+ # The user will be sent the contents of /home/pending/failure.msg
+ # and their original message
+ if [ $attempts -eq 10 ]; then
+ echo "FAILURE"
+ msg=$(cat /home/pending/failure.msg)
+ echo "${msg} ${message}" | mailx -v \
+ -s "Your message could not be delivered" \
+ -S smtp-auth=cram-md5 \
+ -S smtp=smtp://mail.<span class="var">domain</span>:10025 \
+ -S from="<span class="var">domain</span> pending messages <$idnum-pending@<span class="var">domain</span>>" \
+ -S smtp-auth-user=pending \
+ -S smtp-auth-password='<span class="var">password</span>' \
+ -S nss-config-dir="/etc/pki/nssdb/" \
+ -S ssl-verify=warn \
+ -S smtp-use-starttls \
+ "${from}"
+ exit 1
+ fi
+
+ # Save the message, and give all mail users permission to access it
+ # This is required so it can be accessed by the correct destination user
+ echo -n "${message%x}" > /home/pending/messages/$idnum
+ chown `whoami`:mail /home/pending/messages/$idnum
+ chmod 660 /home/pending/messages/$idnum
+
+ # Get the sender's address from the message, and send them the contents of
+ # /home/pending/autoresponse.msg, with their message attached. The message
+ # will be sent from the address <random number>-pending@<span class="var">domain</span>
+ # and will be released when a reply is received to the same address
+ from="`cat /home/pending/messages/$idnum | \
+ grep '^From:' | \
+ cut -d':' -f2- | \
+ sed 's/[^@]*[ <]\([^ ]*@[^ ]*\)[^@]*/\1/g' | \
+ sed 's/[\"<>;]//g'`"
+ cat /home/pending/autoresponse.msg | mailx -v \
+ -a /home/pending/messages/$idnum \
+ -s "Action required: Your message was not delivered" \
+ -S smtp-auth=cram-md5 \
+ -S smtp=smtp://mail.<span class="var">domain</span>:10025 \
+ -S from="<span class="var">domain</span> pending messages >$idnum-pending@<span class="var">domain</span>>" \
+ -S smtp-auth-user=pending \
+ -S smtp-auth-password='<span class="var">password</span>' \
+ -S nss-config-dir="/etc/pki/nssdb/" \
+ -S ssl-verify=warn \
+ -S smtp-use-starttls \
+ "${from}"
+ exit 0
+
+# If a reply is received to a *-pending@<span class="var">domain</span> address,
+# send the saved message instead
+elif [ `ls /home/pending/messages/ | sed 's/$/-pending@bsflowers.net/g' | grep -ic "${address}"` -gt 0 ]; then
+ idnum="`echo \"${address}\" | \
+ sed 's/\^\([0-9]*\)-pending.*/\1/' | \
+ sort -u | \
+ grep -v [^0-9]`"
+ destination="`cat /home/pending/messages/$idnum | \
+ grep -e '^To: ' -e \$'^[ \t]*for' | \
+ awk '{print \"^\"$2\"\$\"}' | \
+ sed 's/[\"<>;]//g'`"
+
+ user=`echo $destination | cut -d '@' -f1 | cut -d'-' -f2 | sed 's/^^//g'`
+ cat /home/pending/messages/$idnum | sudo /usr/bin/procmail -d $user
+ rm /home/pending/messages/$idnum
+ exit 0
+fi
+
+
+
+# Useful for debugging -- saves a copy of each message in the user home
+# echo -n "${message%x}" > /home/$user/mail.tmp
+
+# Send the message
+echo -n "${message%x}" | sudo /usr/bin/procmail -d $user
+</pre>
+
+<p class="filename">/etc/mailblock.lst</p>
+<pre>
+spammy-address@<span class="var">domain</span>
+</pre>
+
+<p class="filename">/home/<span class="var"><username></span>/.fetchmailrc</p>
+<pre>
+set daemon <span class="suggested">300</span>
+poll <span class="var"><external mailserver></span> with proto <span class="suggested">pop3</span>
+ user <span class="var"><username></span>@<span class="var"><domain></span> with password '<span class="var"><password></span>' is '<span class="var"><username></span>' here
+ <span class="security">ssl</span>
+mda '/etc/maildelivery.sh %T'
+
+# Use the mda line below to disable filtering
+#mda '/usr/bin/procmail -d %T'
+</pre>
+
+<p class="filename">/etc/init.d/fetchmail</p>
+<pre>
+#!/bin/bash
+
+cut -d: -f1 /etc/passwd | while read USERNAME
+ do
+ if [ -f /home/${USERNAME}/.fetchmailrc ]; then
+ pid=`head -1 /home/${USERNAME}/.fetchmail.pid 2>/dev/null`
+ if [ "$1" = "start" ] && [ `kill -0 $pid 2>/dev/null; echo $?` -ne 0 ]; then
+ echo "Starting fetchmail for user: ${USERNAME}"
+ su - ${USERNAME} -c "fetchmail --daemon <span class="suggested">300</span> -f ~/.fetchmailrc"
+ elif [ "$1" = "stop" ]; then
+ echo "Stopping fetchmail for user: ${USERNAME}"
+ kill $pid
+ elif [ "$1" = "status" ]; then
+ if [ `kill -0 $pid 2>/dev/null; echo $?` -eq 0 ]; then
+ echo "Fetchmail is UP for user: ${USERNAME}"
+ else
+ echo "Fetchmail is DOWN for user: ${USERNAME}"
+ fi
+ fi
+ fi
+ done
+</pre>
+
+<p class="filename">/etc/systemd/system/fetchmail.service</p>
+<pre>
+[Unit]
+Description=Fetchmail multi-user mail import
+After=local-fs.target network.target network-online.target
+
+[Service]
+Type=oneshot
+ExecStart=/etc/init.d/fetchmail start
+ExecStop=/etc/init.d/fetchmail stop
+RemainAfterExit=yes
+
+[Install]
+WantedBy=multi-user.target
+</pre>
+
+<p>Enable the Fetchmail service</p>
+<pre>
+systemctl enable fetchmail
+</pre>
+
+<h1>Configure Dovecot</h1>
+
+
+<p class="filename">/etc/dovecot/dovecot.conf</p>
+<pre>
+protocols = imap
+listen = <span class="suggested">mail.</span><span class="var"><domain></span>
+verbose_proctitle = <span class="suggested">yes</span>
+shutdown_clients = <span class="suggested">yes</span>
+</pre>
+
+<p class="filename">/etc/dovecot/conf.d/10-auth.conf</p>
+<pre>
+disable_plaintext_auth = <span class="security">yes</span>
+auth_mechanism = <span class="suggested">plain cram-md5</span>
+!include auth-passwdfile.conf.ext
+</pre>
+
+<p class="filename">/etc/dovecot/conf.d/auth-passwdfile.conf.ext</p>
+<pre>
+passdb {
+ driver = passwd-file
+ args = scheme=cram-md5 <span class="suggested">/etc/dovecot/cram-md5.pwd</span>
+}
+
+# userdb { ... }
+</pre>
+
+<p>Get the cram-md5 password hash using emailrelay-passwd and create the password file:</p>
+<pre>
+emailrelay-passwd
+touch <span class="suggested">/etc/dovecot/cram-md5.pwd</span>
+chmod <span class="security">0600</span> <span class="suggested">/etc/dovecot/cram-md5.pwd</span>
+chown dovecot /etc/dovecot/cram-md5.pwd
+nano <span class="suggested">/etc/dovecot/cram-md5.pwd</span>
+</pre>
+
+<p class="filename">/etc/dovecot/cram-md5.pwd</p>
+<pre>
+<span class="var"><username></span>:<span class="var"><cram-md5 formatted password></span>
+</pre>
+
+<p class="filename">/etc/dovecot/conf.d/10-director.conf</p>
+<pre>
+<span class="todo">...</span>
+</pre>
+
+<p class="filename">/etc/dovecot/conf.d/10-logging.conf</p>
+<pre>
+<span class="todo">...</span>
+</pre>
+
+<p class="filename">/etc/dovecot/conf.d/10-mail.conf</p>
+<pre>
+mail_location = mbox:~/mail:INBOX=/var/mail/%u
+mail_attachment_dir = ~/attachments
+</pre>
+
+<p class="filename">/etc/dovecot/conf.d/10-master.conf</p>
+<pre>
+<span class="security">
+#inet_listener imap{<span class="todo">...</span>}
+inet_listener imaps{<span class="todo">...</span>}
+#service pop{<span class="todo">...</span>}
+#service lmtp{<span class="todo">...</span>}
+</span>
+</pre>
+
+<p class="filename">/etc/dovecot/conf.d/10-ssl.conf</p>
+<pre>
+<span class="security">
+ssl = yes
+ssl_cert = <<span class="suggested">/etc/pki/dovecot/certs/<span class="var">domain</span>.crt</span>
+ssl_key = <<span class="suggested">/etc/pki/dovecot/private/<span class="var">domain</span>.key</span>
+ssl_ca = <<span class="suggested">/etc/pki/dovecot/certs/<span class="var">ca</span>.pem</span>
+</span>
+</pre>
+
+<p class="filename">/etc/dovecot/conf.d/15-lda.conf</p>
+<pre>
+<span class="suggested">
+postmaster_address = mail@<span class="var"><domain></span>
+hostname = mail.<span class="var"><domain></span>
+</span>
+</pre>
+
+<p class="filename">/etc/dovecot/conf.d/20-imap.conf</p>
+<pre>
+imap_idle_notify_interval = <span class="suggested">1 mins</span>
+</pre>
+
+<p>Enable the Dovecot service</p>
+<pre>
+systemctl enable dovecot
+</pre>
+
+<h1>Install E-mailrelay</h1>
+<pre>
+sudo yum install gcc gcc-c++ <span class="security">openssl openssl-devel</span>
+cd ~
+wget https://sourceforge.net/projects/emailrelay/files/latest/download?source=files
+mv emailrelay* emailrelay.tar.gz
+tar -xzvf emailrelay.tar.gz
+cd emailrelay*
+./configure <span class="security">--with-openssl</span>
+make
+make install
+</pre>
+
+<h1>Configure E-mailrelay</h1>
+<p>Prepare SSL keys for E-mailrelay</p>
+<pre>
+<span class="security">
+cat <span class="suggested">/etc/pki/dovecot/certs/<span class="var">domain</span>.crt</span> <span class="suggested">/etc/pki/dovecot/private/<span class="var">domain</span>.key</span> > <span class="suggested">/etc/pki/dovecot/private/<span class="var">domain</span>.crt.key</span>
+</span>
+</pre>
+
+<p>Prepare authentication file</p>
+<pre>
+touch /etc/emailrelay.auth
+chmod <span class="security">0600</span> /etc/emailrelay.auth
+</pre>
+
+<p class="filename">/etc/emailrelay.auth</p>
+<pre>
+CRAM-MD5 server <span class="var"><E-mailrelay client login></span> <span class="var"><CRAM-MD5 encoded password></span>
+PLAIN client <span class="var"><remote SMTP server login></span> <span class="var"><plaintext password></span>
+</pre>
+
+<p>Create E-mailrelay filter for local mail delivery</p>
+<p class="filename">/etc/emailrelay-filter.sh</pre>
+<pre>
+#!/bin/sh
+# emailrelay-filter.sh
+
+# Function (if required) to convert incoming mail address to local username
+# As designed, this function will take an address like 'alias-user@domain.com'
+# and deliver it to 'user'
+addrToUser()
+{
+ <span class="suggested">ADDR="${1}"
+ USER=`echo $ADDR | awk -F"-" '{print $NF}'`
+ echo "$USER"</span>
+}
+
+content="${1}"
+envelope="`echo \"${content}\" | sed 's/content/envelope.new/'`"
+destination="`cat ${content} | grep '^To:' | cut -d':' -f2-`"
+
+while [ ! -z "${destination}" ]; do
+ islocal=`echo ${destination} | grep "@<span class="var">domain</span>" | wc -l`
+ if [ "$islocal" -lt 1 ]; then
+ exit 0
+ else
+ user="`echo ${destination} | sed 's/\([^ <]*\)@<span class="var">domain</span>[^ ;]*/\1/'`"
+ destination="`echo ${destination} | sed \"s/${user}@<span class="var">domain</span>//\"`"
+ localuser=`addrToUser ${user}`
+ cat "${content}" | grep -v "^To:" | sudo /usr/bin/procmail -d ${localuser}
+ fi
+ sleep 5
+done
+
+rm ${content} ${envelope}
+exit 100
+</pre>
+
+<p>Configure retry and failure notifications</p>
+<pre>
+<span class="todo">
+/usr/local/libexec/emailrelay/examples/emailrelay-notify.sh
+/usr/local/libexec/emailrelay/examples/emailrelay-resubmit.sh
+</span>
+</pre>
+
+<p>Create init file for E-mailrelay</p>
+<pre>
+touch /etc/init.d/emailrelay
+chmod +x /etc/init.d/emailrelay
+</pre>
+<p class="filename">/etc/init.d/emailrelay</p>
+<pre>
+#!/bin/bash
+
+#. /etc/init.d/functions
+
+if [ "$1" = "start" ]; then
+ /usr/local/sbin/emailrelay --as-proxy <span class="var">remote SMTP server</span>:<span class="security">587</span> <span class="security">--client-tls \
+ --client-auth /etc/emailrelay.auth</span> <span class="suggested">--port 10025</span> -r <span class="security">--server-tls <span class="suggested">/etc/pki/dovecot/private/<span class="var">domain</span>.crt.key</span></span> \
+ <span class="suggested">--filter /etc/emailrelay-filter.sh --pid-file /etc/emailrelay.pid</span> <span class="suggested">--verbose > /var/log/emailrelay.log</span>
+elif [ "$1" = "stop" ]; then
+ kill `cat /etc/emailrelay.pid`
+elif [ "$1" = "status" ]; then
+ pid=`cat /etc/emailrelay.pid`
+ wc=`ps -p $pid | wc -l`
+ if [ ! -z "$pid" ] && [ $wc -gt 1 ]; then
+ echo "E-mailrelay is running"
+ else
+ echo "E-mailrelay is NOT running"
+ fi
+fi
+</pre>
+
+<p class="filename">/etc/systemd/system/emailrelay.service</p>
+<pre>
+[Unit]
+Description=Emailrelay smtp proxy
+After=local-fs.target network.target network-online.target
+
+[Service]
+Type=simple
+PIDFile=/etc/emailrelay.pid
+ExecStart=/usr/local/sbin/emailrelay --as-proxy <span class="var">remote SMTP server</span>:<span class="security">587</span> <span class="security">--client-tls \
+ --client-auth /etc/emailrelay.auth</span> <span class="suggested">--port 10025</span> -r <span class="security">--server-tls <span class="suggested">/etc/pki/dovecot/private/<span class="var">domain</span>.crt.key</span></span> \
+ <span class="security">--server-auth=/etc/emailrelay.auth</span>
+ <span class="suggested">--filter /etc/emailrelay-filter.sh --pid-file /etc/emailrelay.pid</span> <span class="suggested">--verbose > /var/log/emailrelay.log</span>
+ExecStop=kill `cat /etc/emailrelay.pid`
+
+[Install]
+WantedBy=multi-user.target
+</pre>
+
+<p>Enable the Emailrelay service</p>
+<pre>
+systemctl enable emailrelay
+</pre>
+
+<h1>Configure sudo access</h1>
+<pre class="filename">/etc/sudoers</pre>
+<pre>
+# Allow sudo to be used in fetchmail mda script
+#Defaults requiretty
+
+# Allow users to send mail to other users
+daemon mail.bsflowers.net = (root) NOPASSWD: /usr/bin/procmail
+%mail mail.bsflowers.net = (root) NOPASSWD: /usr/bin/procmail
+</pre>
+
+<h1>Reboot and confirm services</h1>
+<pre>
+reboot
+systemctl status dovecot
+systemctl status emailrelay
+systemctl status fetchmail
+</pre>
+
+<h1>Verification</h1>
+<p>The following optional steps will help verify or troubleshoot the installation</p>
+
+<h2>Check Dovecot Status</h2>
+<p>This will show if the Dovecot server is running</p>
+<pre>
+systemctl status dovecot
+</pre>
+
+<h2>Check Dovecot Logs</h2>
+<p>Check for errors, and watch these logs while performing remaining steps</p>
+<pre>
+tail -f /var/log/dovecot.log
+</pre>
+
+<h2>Login to dovecot with SSL</h2>
+<p>The following commands are to login to the Dovecot IMAP server via SSL on port 993,
+and open the user's inbox. </p>
+<pre>
+openssl s_client -crlf -connect mail.<span class="var"><domain></span>:993
+tag login <span class="var"><username></span> "<span class="var"><password></span>"
+tag LIST "" "*"
+tag SELECT INBOX
+</pre>
+<p>You can also use this to check the certificate expiration dates</p>
+<pre>
+openssl s_client -crlf -connect mail.openssl s_client -crlf -connect mail.<span class="var"><domain></span>:993 | openssl x509 -noout -dates
+</pre>
+
+<h2>Check E-mailrelay logs</h2>
+<pre>
+tail -f /var/log/maillog
+</pre>
+
+<h2>Check user's mailbox locally</h2>
+<pre>
+su - <span class="var">user</span> mail
+</pre>
+
+</body>
+</html>
--- /dev/null
+<html>
+ <head>
+ <title>Apache on Centos 7</title>
+ <script src="/scripts/charNames.js" ></script>
+ <link rel="icon" type="image/png" href="/favicon.png">
+ <meta name="title" content="Apache on Centos 6">
+ <meta name="description" content="Installing and configuring Apache
+ web server on a Centos 7 VM.">
+ <style>
+ pre
+ {
+ background-color: #DDD;
+ padding: .5em .75em;
+ margin: 0em;
+ font-weight: 600;
+ }
+
+ .filename
+ {
+ margin-bottom: 0em;
+ padding-bottom: 0em;
+ background-color:#CCCCCC;
+ font-weight: bold;
+ padding: .2em .5em;
+ font-size: 1.1em;
+ }
+
+ .filename:before
+ {
+ content: "nano ";
+ }
+
+ .TODO
+ {
+ background-color: #DD5;
+ font-weight: bold;
+ }
+
+ .var
+ {
+ color: #383;
+ font-weight: bold;
+ }
+
+ .suggested
+ {
+ color: #AA0;
+ font-weight: bold;
+ }
+
+ .security
+ {
+ color: #C44;
+ font-weight: bold;
+ }
+ </style>
+ </head>
+
+<body>
+
+<h1>Legend</h1>
+<p>
+<span class="todo">Work in progress</span><br>
+<span class="var">Installation specific values</span><br>
+<span class="suggested">SC standard configuration</span><br>
+<span class="security">Security configuration</span>
+</p>
+
+<h1>Base System Setup</h1>
+<p>Update the OS and install httpd, ssh, and nano</p>
+<pre>
+yum update
+yum install sudo nano openssh-server mod_ssl openssl httpd
+</pre>
+
+<p>Install any optional plugins. For example, PHP</p>
+<pre>
+<span class="suggested">yum install php</span>
+</pre>
+
+<h1>Configure the server</h1>
+<p class="filename">/etc/httpd/conf/httpd.conf</p>
+<pre>
+<span class="security">#Listen 80</span>
+<span class="suggested">ServerAdmin www@<span class="var">domain</span></span>
+</pre>
+
+<h1>Configure SSL</h1>
+<p>If this server is hosting multiple domains, move the entire virtualhost tag into a separate file
+ (/etc/httpd/conf.d/<span class="var">domain</span>.conf) and create copies of that file for each domain
+<br/>And update certificate filenames as required (these are based on letsencrypt.org certs).</p>
+<p class="filename">/etc/httpd/conf.d/ssl.conf</p>
+<pre>
+<VirtualHost <span class="var">domain</span>:443>
+DocumentRoot "/var/www/html/<span class="var">domain</span>
+ServerAdmin www@<span class="var">domain</span>
+SSLCertificateFile /etc/pki/tls/certs/<span class="var">domain</span>/cert.pem
+SSLCertificateKeyFile /etc/pki/tls/certs/<span class="var">domain</span>/privkey.pem
+SSLCertificateChainFile /etc/pki/tls/certs/<span class="var">domain</span>/chain.pem
+</VirtualHost>
+</pre>
+
+<h1>Start the server</h1>
+<pre>
+systemctl enable httpd
+systemctl start httpd
+systemctl enable sshd
+systemctl start sshd
+</pre>
+</body>
+</html>
--- /dev/null
+<html>
+ <head>
+ <title>Git server on Debian 8</title>
+ <script src="/scripts/charNames.js" ></script>
+ <link rel="icon" type="image/png" href="/favicon.png">
+ <meta name="title" content="Git server on Debian 8">
+ <meta name="description" content="Installing and configuring a Git
+ repo and gitweb server on a Debian 8 VM.">
+ <style>
+ pre
+ {
+ background-color: #DDD;
+ padding: .5em .75em;
+ margin: 0em;
+ font-weight: 600;
+ }
+
+ .filename
+ {
+ margin-bottom: 0em;
+ padding-bottom: 0em;
+ background-color:#CCCCCC;
+ font-weight: bold;
+ padding: .2em .5em;
+ font-size: 1.1em;
+ }
+
+ .filename:before
+ {
+ content: "nano ";
+ }
+
+ .TODO
+ {
+ background-color: #DD5;
+ font-weight: bold;
+ }
+
+ .var
+ {
+ color: #383;
+ font-weight: bold;
+ }
+
+ .suggested
+ {
+ color: #AA0;
+ font-weight: bold;
+ }
+
+ .security
+ {
+ color: #C44;
+ font-weight: bold;
+ }
+ </style>
+ </head>
+
+<body>
+
+<h1>Legend</h1>
+<p>
+<span class="todo">Work in progress</span><br>
+<span class="var">Installation specific values</span><br>
+<span class="suggested">SC standard configuration</span><br>
+<span class="security">Security configuration</span>
+</p>
+
+<h1>Base System Setup</h1>
+<p>Update the OS and install the git server</p>
+<pre>
+apt-get update
+apt-get upgrade
+apt-get install git-core gitweb
+</pre>
+
+<h1>Configure Git server</h1>
+<p class="filename">/etc/gitweb.conf</p>
+<pre>
+$projectroot = "/home/git";
+</pre>
+
+<pre>
+useradd git -m -d /home/git -s /bin/bash
+su - git
+git config --global user.name "<span class="var">Repo Owner's Name</span>"
+git config --global user.email git@<span class="var">domain</span>
+</pre>
+<h1>Add a project</h1>
+<pre>
+mkdir <span class="var">project1</span>.git
+cd <span class="var">project1</span>
+git init --bare
+service apache2 restart
+</pre>
+
+<h1>Configure Apache webserver</h1>
+<p class="filename">/etc/apache2/ports.conf</p>
+<pre>
+#Listen 80
+</pre>
+
+<p class="filename">/etc/apache2/sites-available/default-ssl.conf</p>
+<pre>
+ServerAdmin git@<span class="var">domain</span>
+DocumentRoot /usr/share/gitweb
+
+SSLCertificateFile /etc/ssl/certs/<span class="var">domain</span>/cert.pem
+SSLCertificateKeyFile /etc/ssl/certs/<span class="var">domain</span>/privkey.pem
+SSLCertificateChainFile /etc/ssl/certs/<span class="var">domain</span>/fullchain.pem
+</pre>
+
+<pre>
+rn /etc/apache2/sites-enabled/000-default.conf
+ln /etc/apache2/sites-available/default-ssl.conf /etc/apache2/sites-enabled/default-ssl.conf
+a2enmod cgi
+a2enmod ssl
+service apache2 restart
+</pre>
+
+</body>
+</html>
--- /dev/null
+(Somewhat dated) tutorials for setup of some of the server software that I use
--- /dev/null
+<html>
+ <head>
+ <title>Initial Setup</title>
+ <link rel="icon" type="image/png" href="/favicon.png">
+ <meta name="title" content="Initial Setup">
+ <meta name="description" content="This tutorial will guide
+ you through configuring a cloud-based Linux desktop accessible
+ from any device with a web browser and HTML5 support.">
+ <style>
+ pre
+ {
+ background-color: #CCC;
+ padding: .3em;
+ margin: .2em;
+ }
+ </style>
+ </head>
+
+<body>
+<h1>Initial Setup</h1>
+
+<p>This tutorial will guide you through configuring a cloud-based Linux desktop
+accessible from any device with a web browser and HTML5 support.</p>
+
+<h2>High-level overview</h2>
+<p>We'll be using the following software and services to make this work:</p>
+<ul>
+ <li><a href="http://www.gandi.net/">Gandi.net cloud hosting</a></li>
+ <li><a href="">Ubuntu Linux</a> as the operating system</li>
+ <li><a href="">vnc4server</a> to create the X session and share it via VNC</li>
+ <li><a href="">Apache Tomcat</a> as the web application server</li>
+ <li><a href="http://guac-dev.org/">Guacamole</a> to convert the VNC session to HTML</li>
+</ul>
+
+<p>This tutorial was based on the following resources:</p>
+<ul>
+ <li>
+ <a href="http://guac-dev.org/doc/gug/users-guide.html">The Guacamole user's guide
+ </li>
+ <li><a href="https://coddswallop.wordpress.com/2012/05/09/ubuntu-12-04-precise-pangolin-complete-vnc-server-setup/">VNC server setup</a></li>
+ <li><a href="https://www.digitalocean.com/community/tutorials/how-to-create-a-ssl-certificate-on-apache-on-arch-linux">
+ How To Create a SSL Certificate</a></li>
+</ul>
+
+<h2>Creating the VPS instance</h2>
+<p>First, visit http://www.gandi.net and register an account.</p>
+<p>After you login to your account, open the My Account page and select
+the Services tab and then the Servers sub-tab. From the server control
+panel, select Create a Server</p>
+<img src="images/01.jpg" alt='Servers page' width="50%">
+<p>How you configure the server will depend on what you plan to use it for.
+For very simple applications, the lowest settings will suffice, but for heavier
+loads you may need to increase these. Higher settings will increase the hourly
+fee. These settings can always be changed later, but some starting estimates
+are included below:</p>
+<p>For a simple Visual Basic 6 application (ex: <em>Organizer's Database</em>)</p>
+<ul>
+ <li><strong>CPU Cores</strong>: <em>1</em></li>
+ <li><strong>RAM</strong>: <em>256MB</em></li>
+ <li><strong>Disk space</strong>: <em>3GB</em></li>
+</ul>
+<p>For a remote office desktop system</p>
+<ul>
+ <li><strong>CPU Cores</strong>: <em>2</em></li>
+ <li><strong>RAM</strong>: <em>1024MB</em></li>
+ <li><strong>Disk space</strong>: <em>10GB</em></li>
+</ul>
+<p>You will probably always want 1 interface, and IPv4 enabled</p>
+<img src="images/02.jpg" alt='Hardware configuration page' width="50%">
+<p>On the next page you will choose the server software configuration.</p>
+<ul>
+ <li><strong>Type of image</strong>: <em>Gandi Image</em></li>
+ <li><strong>OS</strong>: <em>Ubuntu 12.04 32 bits</em></li>
+ <li><strong>Name</strong>: Choose any name for your server</li>
+ <li><strong>Means of Authentication</strong>: <em>Password</em></li>
+</ul>
+<img src="images/03.jpg" alt='Software configuration page' width="50%">
+<p>Once the server is created, you can hover the mouse cursor over the
+information symbol beside the hostname in your server control panel to
+show the server's IP address. For the next section of the tutorial, you
+will need to SSH to this address. For Linux or Mac OS X users, simply
+open a terminal window and type 'ssh admin@<em>[ip address]</em>'
+Windows users can connect using
+<a href="http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html">PuTTY</a>.
+<h2>Installing the software</h2>
+<p>Install the prerequisites. For the <em>su</em> command, you will use the
+same password that you used to connect to the SSH session.</p>
+<pre>
+su -
+apt-get update
+apt-get upgrade
+apt-get install tomcat7 vnc4server
+apt-get install libcairo2-dev libjpeg62-dev libpng12-dev libossp-uuid-dev
+apt-get install libssh2-1-dev libvncserver-dev libssl-dev
+apt-get install guacamole
+apt-get install apache2 ufw openbox xterm
+</pre>
+
+<p>Download and deploy the guacamole Tomcat application</p>
+<pre>
+wget http://downloads.sourceforge.net/project/guacamole/current/binary/guacamole-0.9.8.war?r=http%3A%2F%2Fguac-dev.org%2Frelease%2Frelease-notes-0-9-8&ts=1443744824&use_mirror=superb-dca2
+mv guacamole-0.9.8.war* /var/lib/tomcat7/webapps/guacamole-0.9.8.war
+
+mkdir /usr/share/tomcat7/.guacamole
+ln -s /etc/guacamole/guacamole.properties /usr/share/tomcat7/.guacamole/
+chmod 644 /etc/guacamole/user-mapping.xml
+
+/etc/init.d/tomcat7 restart
+</pre>
+
+
+<p>Update to the latest guacamole install (Yes, it was already installed via
+apt-get...but I couldn't get that version to work. It does help by getting some
+of the configuration set up though!)</p>
+<pre>
+apt-get install build-essential
+wget http://downloads.sourceforge.net/project/guacamole/current/source/guacamole-server-0.9.8.tar.gz?r=http%3A%2F%2Fguac-dev.org%2Frelease
+mv *guacamole-server-0.9.8.tar.gz* guacamole-server-0.9.8.tar.gz
+tar -xzvf guacamole-server-0.9.8.tar.gz
+cd guacamole-server-0.9.8/
+./configure --with-init-dir=/etc/init.d
+make
+make install
+</pre>
+
+<h2>Configuration</h2>
+
+<p>Generate an SSL certificate to secure your connection</p>
+<pre>
+openssl genrsa -des3 -out /etc/ssl/private/guacd.key 2048
+openssl req -new -key /etc/ssl/private/guacd.key -out /etc/ssl/private/guacd.csr
+cp /etc/ssl/private/guacd.key /etc/ssl/private/guacd.key.org
+openssl rsa -in /etc/ssl/private/guacd.key.org -out /etc/ssl/private/guacd.key
+openssl x509 -req -days 365 -in /etc/ssl/private/guacd.csr -signkey /etc/ssl/private/guacd.key -out /etc/ssl/certs/guacd.crt
+</pre>
+
+<p>Configure the firewall</p>
+<pre>
+ufw allow 22
+ufw allow 443
+ufw default deny
+ufw enable
+</pre>
+
+<p>Configure apache for SSL support</p>
+<pre>
+a2enmod ssl
+a2enmod proxy
+a2enmod proxy_http
+a2ensite default-ssl
+service apache2 restart
+</pre>
+<pre>nano /etc/apache2/sites-enabled/default-ssl.conf</pre>
+<pre>
+<IfModule mod_ssl.c>
+<VirtualHost _default_:443>
+ ProxyPass / http://localhost:8080/
+ ProxyPassreverse / http://localhost:8080/
+...
+ SSLCertificateFile /etc/ssl/certs/guacd.crt
+ SSLCertificateKeyFile /etc/ssl/private/guacd.key
+...
+</pre>
+
+<p>Configure GUACAMOLE_HOME</p>
+<pre>
+echo "export JAVA_HOME=/usr/lib/jvm/default-java" >> ~/.bashrc
+echo "export CATALINA_HOME=/var/lib/tomcat7" >> ~/.bashrc
+echo "export GUACAMOLE_HOME=/etc/guacamole" >> ~/.bashrc
+bash
+</pre>
+
+<p>Update your Guacamole user configuration.</p>
+<ul>
+ <li><strong>GUAC-USER</strong>: The username you will use to login</li>
+ <li><strong>GUAC-PASS-MD5</strong>: The password you will use to login, as
+ an MD5 hash (<a href="http://www.miraclesalad.com/webtools/md5.php">
+ MD5 hash calculator</a>)</li>
+ <li><strong>VNCPASS</strong>: The password you will configure for the VNC server</li>
+</ul>
+<pre>nano /etc/guacamole/user-mapping.xml</pre>
+<pre>
+<user-mapping>
+
+ <authorize
+ username="GUAC-USER"
+ password="GUAC-PASS-MD5"
+ encoding="md5">
+ <protocol>vnc</protocol>
+ <param name="hostname">localhost</param>
+ <param name="port">5901</param>
+ <param name="password">VNCPASS</param>
+ </authorize>
+
+</user-mapping>
+</pre>
+<p>Update your guacd configuration</p>
+<pre>nano /etc/guacamole/guacd.conf</pre>
+<pre>
+#
+# guacd configuration file
+#
+
+[daemon]
+
+pid_file = /var/run/guacd.pid
+log_level = info
+
+[server]
+
+bind_host = localhost
+bind_port = 4822
+</pre>
+
+<p>Update guacamole.properties auth provider</p>
+<pre>
+# Hostname and port of guacamole proxy
+guacd-hostname: localhost
+guacd-port: 4822
+
+# Auth provider class (authenticates user/pass combination, needed if using the provi$
+#auth-provider: net.sourceforge.guacamole.net.basic.BasicFileAuthenticationProvider
+user-mapping: /etc/guacamole/user-mapping.xml
+</pre>
+
+<p>Allow DHCP so you can destroy the network interface while not in use</p>
+<pre>nano /etc/default/gandi</pre>
+<pre>
+# set a list of network interfaces which should not be configured by DHCP
+# if you attach a interface setup in your private VLAN, you should consider
+# adding the interface here. If you have multiple interfaces, use space as
+# separator.
+# ex : CONFIG_NODHCP="eth1 eth2"
+#CONFIG_NODHCP="eth0"
+CONFIG_NODHCP=""
+</pre>
+
+<p>Configure the VNC server</p>
+<pre>vncserver</pre>
+<pre>nano ~/.vnc/xstartup</pre>
+<pre>
+[ -x /etc/vnc/xstartup ] && exec /etc/vnc/xstartup
+[ -r $HOME/.Xresources ] && xrdb $HOME/.Xresources
+xsetroot -solid grey
+x-window-manager &
+</pre>
+
+<p>Start the server</p>
+<pre>
+vncserver -geometry 1024x768 -depth 8
+</pre>
+
+<p>Start the vnc sever when the system reboots</p>
+<pre>nano ~/boot.sh</pre>
+<pre>
+~/.bashrc
+/etc/init.d/apache2 start
+/etc/init.d/guacd start
+/etc/init.d/tomcat7 start
+</pre>
+<pre>crontab -e</pre>
+<pre>
+@reboot /root/boot.sh
+@reboot vncserver -geometry 1024x768 -depth 8
+</pre>
+
+<p>Update your system and restart the services!</p>
+<pre>
+apt-get install gandi-hosting-vm2
+apt-get update
+apt-get upgrade
+/etc/init.d/apache2 restart
+/etc/init.d/guacd restart
+/etc/init.d/tomcat7 restart
+</pre>
+
+<p>Open your browser and navigate to your server at:
+https://<em>SERVER IP ADDRESS</em>/guacamole-0.9.8</p>
+
+<h3>Troubleshooting</h3>
+<p>If you encounter any problems getting this working, check for errors
+in the following files:</p>
+
+<pre>
+/var/log/tomcat7/catalina.out
+/var/log/syslog
+/var/log/apache2/error.log
+~/.vnc/*.log
+</pre>
+
+<p>Also be sure to check the servers are running</p>
+<pre>
+/etc/init.d/apache2 status
+/etc/init.d/guacd status
+/etc/init.d/tomcat7 status
+</pre>
+
+<p>If you receive an error that the login is incorrect and you have verified that
+you are using the correct login specified in your user-mapping.xml file, try
+restarting the tomcat server.</p>
+<pre>/etc/init.d/tomcat7 restart</pre>
+
+</body>
+</html>
\ No newline at end of file
--- /dev/null
+<html>
+ <head>
+ <title>Installing Visual Basic 6</title>
+ <link rel="icon" type="image/png" href="/favicon.png">
+ <meta name="title" content="Adding Visual Basic 6">
+ <meta name="description" content="This section will guide you through
+ installing the Visual Basic 6 runtime for running VB6 applications on
+ the cloud desktop.">
+ <style>
+ pre
+ {
+ background-color: #CCC;
+ padding: .3em;
+ margin: .2em;
+ }
+ </style>
+ </head>
+
+<body>
+<h1>Adding VB6</h1>
+
+<p>This tutorial will guide you through installing Visual Basic 6 on a
+VPS server like web desktop. This is designed for systems running
+<em>Ubuntu 12.04 x32</em></p>
+
+<h2>Preparation</h2>
+<p>Since the Visual Basic installation is a graphical program, these
+steps need to be performed from a GUI. Login through Guacamole, then
+right-click anywhere on the desktop to open the software menu and
+launch the terminal emulator.</p>
+<img src="images/vb-01.jpg" width="50%"/>
+
+<h2>Installing VB6</h2>
+<p>First, install the requried prerequisite software</p>
+<pre>
+apt-get install wine unzip
+</pre>
+
+<p>Next, download the VB6 runtime</p>
+<pre>
+wget -O vb6runtime.zip http://downloads.sourceforge.net/project/vb6extendedruntime/Visual%20Basic%206.0%20Extended%20Runtime%201.5.1.zip?r=&ts=1443993940&use_mirror=skylineservers
+unzip vb6runtime.zip
+wine ./VB6\ Extended\ Runtime\ Setup\ 1.5.1.exe
+</pre>
+<img src="images/vb-02.jpg" width="50%"/>
+<img src="images/vb-03.jpg" width="50%"/>
+
+<p>Finally, fix the missing expsrv.dll</p>
+<pre>
+wget -O expsrv.zip http://downloads.dlldll.com/dllfiles/expsrv.dll.zip
+unzip expsrv.zip
+mv expsrv.dll ~/.wine/drive_c/windows/system32
+</pre>
+
+</body>
+</html>
\ No newline at end of file
--- /dev/null
+<html>
+ <head>
+ <title>Installing Organizer's Database</title>
+ <link rel="icon" type="image/png" href="/favicon.png">
+ <meta name="title" content="Adding Organizer's Database">
+ <meta name="description" content="This section will cover installing the
+ Organizer's Database application to the cloud desktop.">
+ <style>
+ pre
+ {
+ background-color: #CCC;
+ padding: .3em;
+ margin: .2em;
+ }
+ </style>
+ </head>
+
+<body>
+<h1>Installing Organizer's Database</h1>
+
+<p>This tutorial will guide you through installing the Organizer's Database
+application on the cloud desktop.</p>
+
+<h2>Preparation</h2>
+<p>You should have already completed the initial setup and Visual Basic 6
+setup tutorials on this system.</p>
+<p>You should also create a .zip file containing your entire ODB installation.
+For example, if your odb.exe is located at C:\ODB\odb.exe, you should create
+a .zip file of the entire C:\ODB directory.</p>
+
+<h2>Uploading ODB</h2>
+<p>There are many ways to upload your ODB zip file to the server. If you are
+able to use SCP, that is probably the quickest. But since that is not available
+on all systems, I will explain a simpler method here.</p>
+
+<p>First, install and run Firefox on your cloud desktop.</p>
+<pre>
+apt-get install firefox
+firefox
+</pre>
+
+<p>Next, use a webmail provider like Gmail, Yahoo mail, or many corporate or
+organization email services. Or you can use a file upload service like
+dropbox. Upload the ODB zip file and use Firefox inside your web desktop
+session to retrieve the file.</p>
+
+<h2>Installing ODB</h2>
+
+<p>Now you simply unzip the file and place it at the correct path.</p>
+<pre>
+unzip odb.zip
+mv -R odb/ ~/.wine/drive_c/
+~/.wine/drive_c/odb/odb.exe
+</pre>
+
+<img src="images/odb-01.jpg" width="50%"/>
+
+
+</body>
+</html>
\ No newline at end of file
--- /dev/null
+<html>
+ <head>
+ <title>Installing basic office software</title>
+ <link rel="icon" type="image/png" href="/favicon.png">
+ <meta name="title" content="Installing basic office software">
+ <meta name="description" content="This section will cover configuring the
+ web desktop for a standard office desktop">
+ <style>
+ pre
+ {
+ background-color: #CCC;
+ padding: .3em;
+ margin: .2em;
+ }
+ </style>
+ </head>
+
+<body>
+<h1>Installing basic office software</h1>
+
+<p>This tutorial will guide you through configuring a standard set of
+office tools in the web desktop environment. You probably want two cores
+and at least 1024MB of ram on the server for this software.</p>
+
+<h2>Install the software</h2>
+<p>Install a simpler desktop environment</p>
+<pre>apt-get install kubuntu-desktop</pre>
+
+<p>Install an office suite</p>
+<pre>apt-get install libreoffice</pre>
+
+<p>Install a web browser and mail client</p>
+<pre>apt-get install firefox thunderbird</pre>
+
+<h2>Configure the VNC</h2>
+<pre>nano ~/.vnc/xstartup</pre>
+<pre>
+...
+#x-window-manager &
+startkde &
+</pre>
+
+<h2>The desktop</h2>
+<img src="images/office-01.jpg" width="50%"/>
+<img src="images/office-02.jpg" width="50%"/>
+
+
+</body>
+</html>
\ No newline at end of file
--- /dev/null
+Old instruction for creating a compatibility tool for running old VB6 apps through a cloud desktop
--- /dev/null
+<html>
+ <head>
+ <link rel="icon" type="image/png" href="/favicon.png">
+ <title>Slightly Cyberpunk | Tutorials | Web Desktop Source</title>
+ <meta name="title" content="Web Desktop Source" />
+ <meta name="description" content="Configuring your own cloud-based desktop
+ environment accessible from any device with an HTML5-capable web browser" />
+ <style>
+ h1
+ {
+ text-align: center;
+ }
+
+ ul
+ {
+ list-style-type: none;
+ }
+
+ ul ul
+ {
+ list-style-type: disc;
+ margin-left: -2em;
+ }
+
+ ul ul li
+ {
+ margin-left: 2em;
+ }
+ </style>
+ </head>
+ <body>
+ <h1>Web Desktop Tutorials</h1>
+
+ <ul>
+ <?php
+ $files = scandir(".");
+ foreach($files as $file)
+ {
+ $meta = get_meta_tags($directory."$file");
+ if( $file != "index.php" && $meta )
+ {
+ $title = $meta['title'];
+ $description = $meta['description'];
+ echo "<li><a href='$file'>$title</a>: $description</li>";
+ }
+ }
+
+ ?>
+ </ul>
+
+ </body>
+</html>
\ No newline at end of file