Virtual Domain Hosting Guide
From OpenBSD-Wiki
| Written for: OpenBSD Version 4.2 |
This article is out of date and is currently abandoned. Tread carefully.
Contents
|
[edit] Summary
This guide is going to step you through, and explain what is going on, configuring an OpenBSD installation to be able to answer email, web requests, and allow users to get that email (via IMAP or POP3) for more than a single domain using LDAP. LDAP is chosen because it is used in many businesses.
[edit] Credits
- Kennith Mann / Nazadus
- Chromebob
- irc.freenode.net #apache #openbsd
- http://www.gentoo.org/doc/en/virt-mail-howto.xml
- http://forums.gentoo.org (Gentoo was my first server to test this type of configuration)
- misc@
[edit] Warming up
[edit] PKG_PATH
The PKG_PATH variable allows you to save on carpel tunnel syndrome and/or your sanity. It does this by keeping your package pkg (PKG_PATH) in a string that you can call with just a few short letters. It also allows you to easily copy and paste the commands in these articles without fear of breakage due to a mirror being down. All you have to do is modify your PKG_PATH variable.
| Command: pkg_path export |
# export PKG_PATH=ftp://ftp.openbsd.org/pub/OpenBSD/`uname -r`/packages/`uname -m` |
[edit] Apache
[edit] Summary
This section of the article is going to describe how to configure Apache (a forked version of Apache v1) to answer to multiple domains (e.g. www.domain.com, some_sub_domain.domain.com, domain2.org).
[edit] Things to know
- SSL certificates only apply to a single IP address. 'This is by design!. An alternative is to have Apache listen on multiple ports to get around this, per domain. Doing so is beyond the scope of this article.
- Settings permissions to allow users to write to their files *and* give Apache the rights is something I would like to cover eventually, however at this point in time it is not covered. Please post in the discussion if can assist and are so inclined.
[edit] /etc/hosts
Because Apache is chrooted it will not see your /etc/hosts/ file and thusly will reach out to DNS. If you don't have a relative /etc/resolv.conf it may even fail there depending on your scripts and what is needed. Also, because we are running virtual domains -- using IP's is a bad idea because Apache will not know which website you are referring to.
Editing your /etc/hosts file is optional. You may want to place a copy in /var/www/etc/hosts and also place your resolv.conf in there as well. Here are some examples to place in your hosts file:
| Config File: /etc/hosts |
127.0.0.1 domain1.com www.domain1.com 127.0.0.1 domain2.com www.domain2.com |
[edit] Configuring Apache
Apache is installed by default, so the only thing left to do is to enable it so it launches at startup. We will manually start it up after we change some config files. We can do so by modifying the 'httpd_flags' variable in the /etc/rc.conf.local file:
| Config File: /etc/rc.conf.local |
httpd_flags="" |
Personally, I prefer to have my htdocs directories organized by domain name, so it's easier to track. I also like my logs to be seperated by the domain name and to have access and error logs be their own as well. Also, if you want (ohh say, wiki.domain1.com) you can do subdomain and have it under it's own structure -- incase you need to move it to another machine late. For example, I have the following directory structure:
| Config File: Directory Structure |
/var/www/domains/www.domain1.com/cgi-bin /var/www/domains/www.domain1.com/htdocs /var/www/domains/www.domain1.com/logs /var/www/domains/www.domain2.com/cgi-bin /var/www/domains/www.domain2.com/htdocs /var/www/domains/www.domain2.com/logs |
This can quickly be accomplished by doing this:
| Command: mkdir |
# mkdir -p /var/www/domains/{www.domain1.com,www.domain2.com}/{cgi-bin,htdocs,logs}
|
Now change the following variables to match your primary domain:
| Config File: /var/www/conf/httpd.conf |
ServerAdmin webmaster@domain1.com ... # # If you want to use name-based virtual hosts you need to define at # least one IP address (and port number) for them. # #NameVirtualHost 12.34.56.78:80 #NameVirtualHost 12.34.56.78 Include /var/www/conf/vhosts.conf |
Now we need to create and edit our vhosts.conf file. This file will include all of your domain information. You should no longer need to edit httpd.conf. vhosts.conf should be the file you use that will include *all* information about each domain.
| Config File: /var/www/conf/vhosts.conf |
NameVirtualHost *:80
###################################################
# www.domain1.com
###################################################
<VirtualHost *:80>
ServerName domain1.com
Serveralias www.domain1.com
DocumentRoot /var/www/domains/www.domain1.com/htdocs
DirectoryIndex index.php index.html
ErrorLog /var/www/domains/www.domain1.com/logs/error
CustomLog /var/www/domains/www.domain1.com/logs/access combined
ScriptAlias /cgi-bin/ /var/www/www.domains/domain1.com/cgi-bin/
</VirtualHost>
###################################################
# www.domain2.com
###################################################
<VirtualHost *:80>
ServerName domain2.com
Serveralias www.domain2.com
DocumentRoot /var/www/domains/www.domain2.com/htdocs
DirectoryIndex index.php index.html
ErrorLog /var/www/domains/www.domain2.com/logs/error
CustomLog /var/www/domains/www.domain2.com/logs/access combined
ScriptAlias /cgi-bin/ /var/www/domains/www.domain2.com/cgi-bin/
</VirtualHost>
|
If you want to have a subdomain like gaming.domain1.com, for example, then you would add the following in your vhosts.conf file:
| Config File: /var/www/conf/vhosts.conf |
###################################################
# gaming.domain1.com
###################################################
<VirtualHost *:80>
ServerName gaming.domain1.com
DocumentRoot /var/www/domains/gaming.domain1.com/htdocs
DirectoryIndex index.php index.html
ErrorLog /var/www/domains/gaming.domain1.com/logs/error
CustomLog /var/www/domains/gaming.domain1.com/logs/access combined
ScriptAlias /cgi-bin/ /var/www/domains/gaming.domain1.com/cgi-bin/
</VirtualHost>
|
and, of course, make the appropriate directories:
| Commands: Making directories for the new subdomain |
# mkdir -p /var/www/domains/gaming.domain1.com/{cgi-bin,htdocs,logs}
|
Now we need to create a blank favicon.ico file otherwise it will appear in your logs frequently as an error. The favicon.ico is the icon you seein browsers when you bookmark a site or on some browser you may see it in the address bar.
| Command: favicon.ico |
# touch /var/www/domains/www.domain1.com/htdocs/favicon.ico # touch /var/www/domains/www.domain2.com/htdocs/favicon.ico # touch /var/www/domains/gaming.domain1.com/htdocs/favicon.ico |
Wash, rinse, repeat the above step for each domain.
Nextly, we need to adjust permissions so everything will run smoothly. While it should work without this step, when you want to start actually adding content, it won't let you due to it being owned by root (or whomever you made the directories as). We will pick a user to be in charge.
| Command: chown |
# chown -R user:daemon /var/www/domains # chmod -R 775 /var/www/domains |
Finally, we should restart Apache so the changes are applied. I seem to get problems using the 'restart'. According to the FAQ (which I recommend you stop reading this article and read that before continuing) this is because not all modules reload and causes httpd to exit. So instead, we will use the 'stop and start' method, as illustrated below:
| Command: Restart Apache |
# apachectl stop && sleep 1 && apachectl start |
[edit] Apache and chroot
Something to note that is *very* important: Apache runs CHROOTED in '/var/www', as you no doubt read in the previous FAQ link you read (you did read it, right?). I didn't include this above just in case someone jumps the gun and just does it without paying attention.
If you install other software that needs to access something outside of '/var/www', like sendmail for example, then you will need to do a hardlink (or copy) that software PLUS the libraries they use. These kinds of things can get very hair, very quick. It is possible to turn off Apache's jail. An example is the mail function in PHP. This uses sendmail to send the mail, however since Apache is chrooted, it can not access /whatever/sendmail. To disable Apache's chroot jail, change your /etc/rc.conf httpd_flags variable however, this is not recommended. Find the real solution.
This is not recommended, only offered as an alternative to some situations and for testing purposes.
| Config File: /etc/rc.conf.local |
# use -u to disable chroot, see httpd(8) httpd_flags="-u" |
[edit] Troubleshooting
Q: I am getting a _default_ VirtualHost overlap error on my page. Infact, it looks something like:
[Thu Oct 6 12:27:55 2005] [warn] _default_ VirtualHost overlap on port 80, the first has precedence
A: You probably forgot the NameVirtualHost *:80 value at the top of your vhosts.conf file. Make sure it's there.
[edit] Extending Apache
[edit] Summary
Apache is much more powerful when combined with several other programs. This is where LAMP comes from ( Linux, Apache, MySQL, PHP). While we aren't running Linux, most of the documentation associated with it applies here. Aside from Apache being chrooted, it should be a fairly direct conversion.
[edit] MySQL
MySQL is a database engine. SQL has become very popular lately and MySQL isn't the only implementation. Postgre and Microsoft have their own. But MySQL seems to be most commonly chosen, so we will use it so you can get the feel of how things work.
| Command: Installing MySQL |
# pkg_add -v ${PKG_PATH}/mysql-server-5.0.45.tgz
|
Some of this information here can be found at /usr/local/share/doc/mysql/README.OpenBSD -- which you should read.
We now need to have MySQL create the base databases.
| Command: mysql install db |
# /usr/local/bin/mysql_install_db |
| Config File: /etc/sysctl.conf |
kern.maxfiles=4096 |
We need to start the MySQL daemon so we can do things to it. If it says it can't find the command, you will need to logout and log back in -- if you do that, don't forget to reset your PKG_PATH variable.
Note: There is a better way to do this... I need to understand it before I put it here though.
| Command: Start MySQL |
# su -c mysql root -c '/usr/local/bin/mysqld_safe >/dev/null 2>&1 &' |
Now we should change the password, for security reasons (you should choose your own password):
| Command: Change MySQL Password |
# /usr/local/bin/mysqladmin -u root password 'Passw0rd' |
Now we need to make a link for Apache to connect to ( because Apache is chrooted, it can't access anything outside of /var/www ). It is possible to change the config file to change the socket to be in the home directory for apache, however I would prefer to avoid that, if possible:
| Command: Link MySQL Socket |
# mkdir -p /var/www/var/run/mysql # ln /var/run/mysql/mysql.sock /var/www/var/run/mysql/mysql.sock |
Append this to /etc/rc.local, so MySQL starts with every server boot:
| Config File: /etc/rc.local |
# Start the MySQL daemon if [ -x /usr/local/bin/mysqld_safe ] ; then /usr/local/bin/mysqld_safe >/dev/null 2>&1 & echo -n ' mysql' fi |
If you copied and pasted the above code, make certain that the 'ln -f' command is all on one line and your editor didn't wrap it.
[edit] PHP 5
PHP is the engine for phpMyAdmin and phpLDAPadmin, which is how we will be editing out mail accounts (unless you want to do them all by hand made LDAP or SQL queries). We'll actually be using LDAP however changing it to use SQL is fairly simple and Google should be able to point you on the correct path. PHP's basic goal in life is to give dynamic content. We create a /var/www/tmp directory because Apache uses the /tmp directory to store session cookie stuff -- and since Apache is chroot'ed, some software (like phpLDAPadmin) won't work correctly because it can't keep cookies. On a seperate note, I suggest mounting /tmp as noexec to in case your php scripts get exploited -- those exploits won't run on that partition outside of Apache.
| Command: Install PHP5 |
# pkg_add -v ${PKG_PATH}/php5-core-5.2.3.tgz
# /usr/local/sbin/phpxs -s
# cp /usr/local/share/examples/php5/php.ini-recommended /var/www/conf/php.ini
# mkdir -p /var/www/{bin,etc,tmp}
# chown www:daemon /var/www/{bin,etc,tmp}
# chmod 1755 /var/www/{bin,etc,tmp}
# cp /etc/resolv.conf /var/www/etc
|
Now we need to add the type .php and associate it with the php software. By default, it's commented out, so uncomment the first line so it looks like the second line:
| Config File: /var/www/conf/httpd.conf |
#AddType application/x-httpd-php .php AddType application/x-httpd-php .php |
Now, we need to install the basic modules that go along with it:
| Commands: MySQL Extension |
# pkg_add -v ${PKG_PATH}/php5-mysql-5.0.4.tgz
# /usr/local/sbin/phpxs -a mysql
|
| Commands: LDAP Extension |
# pkg_add -v ${PKG_PATH}/php5-ldap-5.0.4.tgz
# /usr/local/sbin/phpxs -a ldap
|
| Commands: IMAP Extension |
# pkg_add -v ${PKG_PATH}/php5-imap-5.0.4.tgz
# /usr/local/sbin/phpxs -a imap
|
| Commands: BZ2 Extension |
# pkg_add -v ${PKG_PATH}/php5-bz2-5.0.4.tgz
# /usr/local/sbin/phpxs -a bz2
|
| Commands: GD -- Thier is a no X11 version |
# pkg_add -v ${PKG_PATH}/php5-gd-5.0.4.tgz
# /usr/local/sbin/phpxs -a gd
|
| Command: Pear |
# pkg_add -v ${PKG_PATH}/php5-pear-5.0.4.tgz
|
Now we need to restart Apache for the settings to take affect:
| Commands: Restart Apache |
# apachectl stop && apachectl start |
[edit] Testing PHP
Now we should test it, to make certain that it works.
We will create a file in our htdocs directory (of any domain) and call it phpinfo.php and in it should contain this:
| Config File: phpinfo.php |
<?php phpinfo(); ?> |
Now point your browser to that file. It might look something like: http://www.domain1.com/phpinfo.php
You should delete this file once you have confirmed it works.
[edit] Mail
Now we need to setup the ability to email. Normally this isn't a problem, but since Apache is chroot'ed, then we need to do some fancy schmancy stuff. You have two choices: mini_sendmail' or PearMail. In my opinoin, mini_sendmail is easier to configure but I've heard that it's not very reliable for everyone. I don't know why as I haven't ran into this myself, but if you have having this problem then try PearMail. I'll explain how to set them both up, just incase. While it is possible to use the actual sendmail program, you have to hunt down libraries and send a bit of time getting it all sorted out. I spent an hour and gave up (becuase mini_sendmail and PearMail where just easier). Remember that none of these programs have access to your /etc/hosts file due to Apache being chroot'ed when it calls them.
[edit] mini_sendmail
| Command: mini_sendmail |
# pkg_add -v ${PKG_PATH}/mini_sendmail-chroot-1.3.5.tgz
|
Now we need to tell PHP to use this instead of sendmail, so we will need to edit the /var/www/conf/php.ini file:
| Config File: /var/www/conf/php.ini |
;sendmail_path = sendmail_path = "/bin/mini_sendmail -t" |
and get some shell stuff as well as some name resolution, then restart Apache:
| Commands: dns and restarting Apache, again |
# cp /etc/hosts /var/www/etc/hosts # cp /etc/resolv.conf /var/www/etc/resolv.conf # cp /bin/sh /var/www/bin # apachectl stop # apachectl start |
[edit] PearMail
PearMail is just classes in Pear for Mail.
http://pear.php.net/package/Mail -- is where it can be found. The drawback seems to be that you need to edit the php files to include the new mail function, but that shouldn't be too difficult as its just adding headers to the top of your files.
[edit] TODO
- Would be nice to have SSL stuff talked about.
[edit] OpenLDAP
[edit] Summary
LDAP stands for Lightweight Directory Access Protocol. It's tuned towards faster reads than writes. This is ideal for a virtual mailing system because you probably doing lookups allot more often than adding users.
[edit] The VMAIL user
The vmail user is the user to holds all mail, as far as permissions are concerned. This means two things:
- The vmail user is *very* powerful and can peak at other user's emails.
- Becuase of the above, user's should not be allowed to change their own mail directory.
- The Vmail user should *not* be allowed to have a shell or login -- but should have a home directory.
| Command: The VMAIL user |
# adduser (add the vmail user)
# cd ~vmail
# mkdir -p domains/{domain1.com,domain2.com}
# chown -R vmail:vmail /home/vmail/domains
|
[edit] OpenLDAP Server
Now we will install the actual LDAP software: OpenLDAP. The _openldap user is the user that will be the user that the OpenLDAP process will be ran as. This user should also not be allowed to login. The _openldap user does not need a home directory, so you can delete that after it creates one.
| Command: OpenLDAP Server |
# pkg_add -v ${PKG_PATH}/openldap-server-2.2.27p0.tgz
# mkdir /var/run/openldap
# mkdir /var/openldap-data
# chown _openldap:_openldap /var/run/openldap
# chown _openldap:_openldap /var/openldap-data
# chmod 700 /var/openldap-data
|
[edit] authldap.schema
I couldn't seem to find the authldap.schema file on the OpenBSD install, so the best I could find was one off of sourceforge. If anyone knows a place where I can reliably (and trust) aquire the file, please let me know. In the mean time... download the latest authldap.schema file from sourceforge.
It is important that your download manager does *not* wordwrap the file. OpenLDAP won't start if the lines are wrapped. Thusly you should check this file and make certain it is correct.
| Command: Get authldap.schema |
# lynx -source "http://courier.cvs.sourceforge.net/*checkout*/courier/libs/authlib/authldap.schema" > /etc/openldap/schema/courier.schema |
[edit] slappasswd
Now we will get our password for our manager account in our LDAP database. I've given an example password in here, you will get a different hash though.
| Command: slappasswd |
# slappasswd
New password:
Re-enter new password:
{SSHA}FO/hj4S43k6zpwWwXqvxWBVhOu7gq238
|
[edit] slapd.conf
Now we need to edit our ldap conf file: slapd.conf. This file contains all the important stuff to our OpenLDAP service and should *not* be world readable. We will use a fake domain (and you should too) becuase LDAP won't allow us to have two domains of the same name in it's tree. This is important becuase when we do lookups, we will be using a certain section of the LDAP tree to do a domain/user lookup -- not at the top. Notice that the suffix is a *FAKE* domain. I chose 'tehmonkey' just becuase it made me giggle. Feel free to make one up yourself. You will need the hash from earlier, so keep it handy. Something else to note, courier.schema relies on nis.schema, which nis relies on cosine.schema. You don't need to keep this in your concious memory, but this is important to know when troubleshooting problems.
I'd like to have access control be something like the following:
- Manager can do anything
- A verified user can modify their password -- that's it (and, of course, read access to everything else -- except other user's passwords)
- Anonymous binds has read only access to everything except passwords
I'm not that skilled with access control, so that will come later.
Modify/add the following (leave the rest as it is):
| Config File: /etc/openldap/slapd.conf |
include /etc/openldap/schema/core.schema
include /etc/openldap/schema/cosine.schema
include /etc/openldap/schema/nis.schema
include /etc/openldap/schema/courier.schema
...
pidfile /var/run/openldap/slapd.pid
argsfile /var/run/openldap/slapd.args
...
database ldbm
suffix "dc=tehmonkey,dc=com"
rootdn "cn=Manager,dc=tehmonkey,dc=com"
...
rootpw {SSHA}FO/hj4S43k6zpwWwXqvxWBVhOu7gq238
|
[edit] Start slapd
Now that we have everything configured, let's get the primary LDAP process started so we can move on into getting some data in our tree!
| Command: Start Slapd |
# /usr/local/libexec/slapd -u _openldap -g _openldap |
If you run into any problems, put a -d 1 at the end of that and it will throw some statements onto the screen as to what is going on. If it's not starting, then more than likely this will be your primary tool to troubleshoot it. This tool
[edit] phpLDAPadmin
Now we need to install phpLDAPadmin so we can begin adding items to our new domain. While you can do these by hand, I've found it's good to start learning early on how to use the phpLDAPadmin interface, since it will be the thing you will use for everything else.
| Commands: Installing phpLDAPadmin |
# pkg_add -v ${PKG_PATH}/phpldapadmin-0.9.7.tgz
# ln -s ../../../phpldapadmin-0.9.7 /var/www/domains/domain1.com/htdocs/phpldapadmin
|
For JPEG photo's to work properly, we must do the following where 'tmp' is the $jpeg_temp_dir configured in config.php (/tmp is default and applied to the above commands). This *should* have been done in the OpenBSD 3.7: Extending Apache section already. If so, you can skip this part.
| Commands: tmp tweaky |
# mkdir /var/www/tmp # chown www:daemon /var/www/tmp # chmod 1755 /var/www/tmp |
Now we need to edit the config.php file. No, the $blowfish_secret is *not* a joke. It needs to some some random stuff. You won't need to remember it or anything. The stuff doesn't really matter, just enter something that makes you laugh (we could use a laugh about now... running low on that laugh juice here -- it's not like this is satire or anything). If you want, you can set the 'auth_type' variable to be 'config' and place your LDAP root password in there, so it will automagically log you in. Keep in mind though, that's only useful while in a lab -- not in the real world. In the real world, hackers will find that *fast* and do things to your directory. Things are bad!
| Config File: /var/www/phpldapadmin-0.9.6/config.php |
$blowfish_secret = 'thecowjumpedovertehm00n!!!oneone!!!111eleventy'; ... $servers[$i]['host'] = '127.0.0.1'; ... $servers[$i]['base'] = 'dc=tehmonkey,dc=com'; ... $servers[$i]['auth_type'] = 'session'; ... $servers[$i]['login_dn'] = 'cn=Manager,dc=tehmonkey,dc=com'; ... $servers[$i]['login_pass'] = ''; ... $servers[$i]['default_hash'] = 'ssha'; ... |
[edit] Building your LDAP Tree
[edit] Logging in
- Now, goto http://your_ip_address/phpldapadmin and see if it works. If it doesn't, go back and make sure you followed the steps correctly. If your tree doesn't expand, you probably messed on on the '/var/www/tmp' permissions (like I did). Otherwise, continue on.
phpLDAPAdmin will now want you to create your base tree. Let's give it what it wants, so click the link.
[edit] Initial Tree
- It will now want you to create the tree and it's asking for some information.
The rootdn should be 'dc=tehmonkey,dc=com', the container should be blank, and you should select 'domain' in the combo box below. Then click 'Proceed'.
- It will now require you to enter a 'domainComponent'. Put 'tehmonkey' and click 'Create Object'.
- Now create a child entry under 'dc=tehmonkey,dc=com'.
- Click the "Custom" option button and click Proceed.
- Important information to fill in
| Config File: Manager entry |
RDN: cn=Manager Container: dc=tehmonkey,dc=com objectClass: organizationalRole cn: Manager |
- Create another child entry under 'dc=tehmonkey,dc=com'.
- Click the "Custom" option button and click Proceed.
- Important information to note:
| Config File: Manager entry |
RDN: o=hosting Container: dc=tehmonkey,dc=com objectClass: organization o: hosting |
[edit] Our first domain
- Create your first real domain (of custom type):
| Config File: domain1.com entry |
RDN: o=domain1.com Container: o=hosting,dc=tehmonkey,dc=com objectClass: organization |
- wash, rinse, repeat (the previous step) for each domain you are hosting / plan on hosting.
- you should note that their is an option for domain, however we aren't using that.
[edit] Our first user
- Create your first real user (of Custom-CourierMailAccount/organizational person).
- RND: cn=username
- Container: dc=domain1.com,o=hosting,dc=tehmonkey,dc=com
- Object Classes: CoutierMailAccount and Organizational Person
- cn: username
- Home Directory: /home/vmail/domains
- mail: nazadus@etherpunk.com
- sn: Full_User_Name (IE: Kenny Mann)
- mailbox: domain1.com/username/.maildir/ (<-- note the trailing slash -- this tells postfix that it's a directory and not a file this is important)
- userPassword: some_temp_password (<--we will change this in our next step)
- Now click the create object to create the user.
- It should take you to the new users account. Goto the bottom, where the userPassword field is. Give them a real temp password, like Passw0rd and change the type to crypt. Something intersting to note about the userPassword field. If you forgot to put it in and want to add it as an attribute later, PHP will complain saying it doesn't have the mhash function and can't do it. I don't really know what that means... but it sucks. I'll have to do some diggin' later.
[edit] Running into problems
http://www.linuxjournal.com/article/5917 [http://newinteractive.linuxjournal.com/article/5917] <-- That guide is what got me *really* started on this and helped out allot. If something isn't working, and you're certain you followed this guide, check out the linux journal's guide. The Jamm guide uses Jamm, but this actually uses the authldap schema. It is using an elder version of OpenLDAP, so you can't use their ldif files without some minor tweaking (notice the mail: value is empty... and that some of the items don't have a structural class -- which is required in version OpenLDAP 2.2)
[edit] Start Scripts
| Config File: /etc/rc.local |
# Start OpenLDAP
if [ -x /usr/local/libexec/slapd ]; then
echo -n ' openldap'
/usr/local/libexec/slapd -u _openldap -g _openldap > /dev/null &
fi
|
[edit] Q&A and Troubleshooting
[edit] Postfix
[edit] Summary
We will be using Postfix as our MTA (mail transfer agent). It's (some say) arguably more secure than Sendmail and more effecient all the way around. More importantly, it allows you to keep your sanity and not learn a (slight exageration) gazillion things to get going.
[edit] Hosts File
Firstly, we need to add an alias to our hostname as we can also be mail. I think this is required due to [[RFC 2821], while I haven't been able to prove (or disprove) it -- I went to #postfix and asked -- they pointed me to that RFC. Someone else disagrees and think syou don't have to have it. While I believe you don't *have* to have it, I know it's a common thing; So we will do it anyways! Also add your other domains you plan on hosting. It should be noted that the chrooted apache will *NOT* have access to this file. Remember this or you will have greif later.
| Config File: /etc/hosts |
127.0.0.1 domain1.com www.domain1.com mail.domain1.com 127.0.0.1 domain2.com www.domain2.com mail.domain2.com |
[edit] Installing Cyrus-SASL
Becuase we need Postfix to compile with SASL and LDAP, we need the SASL with LDAP libraries (otherwise you have to uninstall cyrus-sasl *and* postfix-sasl-ldap which sucks). So, here we go:
| Commands: Installing Cyrus-SASL |
# pkg_delete -v cyrus-sasl-2.1.20p4
# pkg_add -v ${PKG_PATH}/cyrus-sasl-2.1.20p4-ldap.tgz
# mkdir /var/sasl2
|
SASL has some config files that we need to edit to get it working properly:
The smtpd.conf file is the authentication method file (in a nut shell).
| Config File: /usr/local/lib/sasl2/smtpd.conf |
pwcheck_method: saslauthd mech_list: plain |
The saslauthd.conf file is the more detailed version of the authentication.
| Config File: /etc/saslauthd.conf |
ldap_servers: ldap://127.0.0.1/ ldap_search_base: o=hosting,dc=tehmonkey,dc=com ldap_timeout: 10 ldap_filter: mail=%u@%r |
Because we want it to start everytime we boot, we need to place it in our rc.local file. Edit rc.local (The -O is the letter, nut the number):
| Config File: /etc/rc.local |
# Start the SASL2 auth daemon
if [ -x /usr/local/sbin/saslauthd ]; then
echo -n 'SASL2/'
/usr/local/sbin/saslauthd -r -a rimap -O 127.0.0.1
sleep 2
mkdir -p /var/spool/postfix/var/sasl2
ln -f /var/sasl2/mux /var/spool/postfix/var/sasl2/mux
fi
|
[edit] Installing Postfix
Now we need to install Postfix. Becuase we want SASL *and* LDAP, we will have to compile our own using the ports system. The reason why we want LDAP is obvious, that is our database, but the reason we want SASL may be less obvious. SASL is only really needed so you can relay outside of your network -- it will allow your users to authenticate with their passwords and relay. You _can_ open up so anyone can relay, but spammers will hose you very quickly.
| Command: Install Postfix |
# cd /tmp # ftp ftp://ftp.openbsd.org/pub/OpenBSD/3.8/ports.tar.gz # cd /usr # tar -xzf /tmp/ports.tar.gz # cd ports/mail/postfix/stable # FLAVOR="sasl2 ldap" make # FLAVOR="sasl2 ldap" make install |
[edit] Configuring main.cf
Now we need to modify some of the variables for Postfix. The ones listed below are already existant, so you will need to find them and modify them. The values with $ are literal words, so don't put your domain. The mynetworks should also fit your network block -- remember, it's your entire block -- not just a single IP. I'm not good at the whole subnetting thing though, so I can't offer advice for that. I just know what works.
| Config File: /etc/postfix/main.cf |
... myhostname = hostname.domain1.com ... mydomain = mail.domain1.com ... mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain, $transport_maps ... mynetworks = 192.168.0.0/16, 127.0.0.0/8 ... home_mailbox = .maildir/ ... |
Append this to the bottom of the main.cf file. I'm using o=hosting,dc=tehmonkey,dc=com and you need to change your gid and uid values to match your vmail's account gid and uid.
| Config File: /etc/postfix/main.cf |
# LDAP Configy transport_maps = hash:/etc/postfix/transport aliases_server_host = localhost aliases_search_base = o=hosting,dc=tehmonkey,dc=com aliases_query_filter = (&(mail=%s)(objectClass=CourierMailAlias)) aliases_result_attribute = maildrop aliases_bind = no accounts_server_host = localhost accounts_search_base = o=hosting,dc=tehmonkey,dc=com accounts_query_filter = (&(mail=%s)(objectClass=CourierMailAccount)) accounts_result_attribute = mailbox accounts_bind = no accountsmap_server_host = localhost accountsmap_search_base = o=hosting,dc=tehmonkey,dc=com accountsmap_query_filter = (&(mail=%s)(objectClass=CourierMailAccount)) accountsmap_result_attribute = mail accountsmap_bind = no virtual_maps = ldap:aliases virtual_mailbox_base = /home/vmail/domains virtual_mailbox_maps = ldap:accounts virtual_minimum_uid = 1002 virtual_uid_maps = static:1002 virtual_gid_maps = static:1002 local_recipient_maps = $alias_maps $virtual_mailbox_maps # SASL configy broken_sasl_auth_clients = yes smtpd_sasl_auth_enable = yes smtpd_sasl2_auth_enable = yes smtpd_sasl_local_domain = smtpd_recipient_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_unauth_destination |
[edit] Transport map
We need a transport table to list what domains we host. It will reside in /etc/postfix/transport
Append your domains to the bottom of it (it should come blank, except for the comments):
| Config File: /etc/postfix/transport |
... domain1.com virtual: domain2.com virtual: |
To generate the tranport hash, we need to run this:
| Command: |
# /usr/local/sbin/postmap /etc/postfix/transport |
Eventually, I plan on figuring out a way (if possible) to get Postfix to do a lookup in our LDAP directory. If anyone knows how to do this, please let me know.
[edit] Postfix as your primary MTA
It's possible Postfix won't be started yet or your shell won't have the path to start it. In which case use /usr/local/sbin/postfix start instead of postfix reload. Sendmail is the default and it's already explained why we aren't using Sendmail -- so it's continue:
| Command: Enable Postfix |
# /usr/local/sbin/postfix-enable # ln -s /etc/postfix/aliases /etc/aliases # /usr/local/sbin/newaliases # postfix start |
[edit] /etc/rc.conf.local
Add the following to your /etc/rc.conf.local
| Config File: /etc/rc.conf.local |
sendmail_flags="-bd -q30m" |
[edit] Crontab
Remove the "sendmail clientmqueue runner" from root's crontab.
| Command: Edit crontab |
# crontab -eu root |
Comment this line out (with a hash) like done below:
| Config File: Crontab |
#*/30 * * * * /usr/sbin/sendmail -L sm-msp-queue -Ac -q |
[edit] vmail directory
Now we need to make our vmail directories so Postfix doesn't freak, however if you are following the guide then you have already done this and can skip this step.
| Commands: I've been creating Postfix directories, doo dah, doo dah |
# mkdir -p /home/vmail/domains/{domain1.com,domain2.com}
# chown -R vmail:vmail /home/vmail
|
[edit] Reboot
Now you need to reboot your system for all these changes to take affect. Why? Becuase Sendmail is still running and rebooting just makes it a less chance of a mistake. Plus, you should check to make sure all your services work, so on we go.
| Commands: Reboot your server |
# reboot |
[edit] Test it!
Ok, I had to reboot my computer to get this working for some reason (the heck?) -- but it *did* fix whatever weirdness I had. De-ja-vu Windows users? :-P
Ok, now we whould test it and make sure it works! So do that we shall (colors that are highlightes in red are commands you need to type; colors that are in black are the responses you should get):
telnet 127.0.0.1 25 Trying 127.0.0.1... Connected to 127.0.0.1. Escape character is '^]'. 220 mail.domain.tld ESMTP Postfix helo mail.domain.tld 250-mail.etherpunk.com 250-PIPELINING 250-SIZE 10240000 250-VRFY 250-ETRN 250 8BITMIME mail from: a@a.com 250 Ok rcpt to: user@domain1.com 250 Ok data 354 End data with <CR><LF>.<CR><LF> To: user@domain1.com Subject: Test Email <enter> Cows go moo. . 250 Ok: queued as CC89074009 quit 221 Bye Connection closed by foreign host.
Your queued number should be different than listed above.
It's also important to note that we could have shortened the above to simply:
telnet 127.0.0.1 25 Trying 127.0.0.1... Connected to 127.0.0.1. Escape character is '^]'. 220 mail.domain.tld ESMTP Postfix mail from: a@a.com 250 Ok rcpt to: user@domain1.com 250 Ok data 354 End data with <CR><LF>.<CR><LF> moo . 250 Ok: queued as CC89074009 quit 221 Bye Connection closed by foreign host.
While the former way is more 'official' becuase it contains all the common headers, the latter way will save on your carpel tunnel syndrome (as you develop it making mistakes / typos in this guide -- everyone does it) and is more useful for when you are 'just wanting it to work' and probably not going to be keeping the mail anyways.
If you recieve any problems, you should troubleshoot them before proceeding any further.
[edit] Errors
Some issues that I ran across while learning this stuff:
- error 451 temporary lookup failure was due to the 'unix:passwd.byname' in the variable 'local_recipient_maps' -- so I removed it.
- error 451 temporary lookup failure was also due to the fact it wouldn't find a mailbox (doh!) becuase I got confused on the 'mail' 'mailbox' and 'homeDirectory' variables. Watch that first step, it's a d00zi3! (3 hours worth of troubleshooting in this issue and the one before it)
- You can add a -vv or -v in your /etc/postfix/master.cf file (and postfix reload it) to have your postfix do more verbose logging. I usually only add the verbosity to the smtpd', local, virtual, error, and trivial.
- When I'm telnet 'ed in, it seems to hang when I do mail from: or rcpt to: -- this means that you configured postfix wrong, your ldap server isn't working, or permissions aren't allowing postfix to talk ldap.
- Why does it hang while doing mail from? because it's doing a lookup to see if it will be sending mail to iself. Why? I dunno... seems stupid to me, but I'm sure it's their for a reason. It's not like they would just throw the code in 'just cuz'.
- I get an error with the end of it saying something close to: mail for domain.tld loops back to myself . You might want to change your myhostname and mydomain values to be something different. What is happening is the manager is saying "I handle this." then saying "No I don't you handle this." and later saying "but I am you? bah, this is recursive... screw this. It's also *very* likely that you messed up in your /etc/postfix/transport file -- remake that file.
[edit] Courier
[edit] Summary
Courier will be our daemon that will actually make our mail system show it's colors. Courier is often associated with it's IMAP functionality, however it does have a POP3 daemon that we will make use of as well.
Now is the time I should explain the difference between POP3 and IMAP.
POP3 stores the mail on the server until the users checks it. While it is possible for the user not to delete the email, it's not very common. This is becuase the user will download the same email everytime until it's gone. It's kind of like an all or nothing thing.
IMAP stores the mail on the server permanantly (sp?). Period. This is very useful for webmail style applications or for those who aren't always checking their mail from the same computer.
Which one is better? There isn't one 'perfect' one and their never will be until computer resources become a little more... available. IMAP is useful for a smaller business or for those who are just doing this as a hobby and have a few friends who want it. It's not very ideal for those with allot of connections over the internet unless you have a reasonable big internet connection (not DSL or cable).
[edit] Install core software
Install Courier (both IMAP and POP3) as well as the config files.
| Commands: notes |
# pkg_add -v ${PKG_PATH}/courier-ldap-3.0.5p0.tgz
# pkg_add -v ${PKG_PATH}/courier-imap-3.0.5p2.tgz
# pkg_add -v ${PKG_PATH}/courier-pop3-3.0.5p0.tgz
# cp -R /usr/local/share/examples/courier-imap/ /etc/
|
[edit] Config files
The only real part of the authdaemon rc part we are concerned about is the authmodule list. It contains the list of the modules that courier can speak. MySQL, LDAP, userdb are among the more common things most people use it for.
| Config File: /etc/courier-imap/authdaemonrc |
#authmodulelist="authcustom authcram authuserdb authldap authpgsql authmysql authpwd" authmodulelist="authldap" |
Don't use bindpw or binddn, this is *very* insecure. Use authbind instead. authbind binds as the user that is attempting to login.
| Config File: /etc/courier-imap/authldaprc |
LDAP_SERVER 127.0.0.1 LDAP_BASEDN o=hosting,dc=tehmonkey,dc=com #LDAP_BINDDN this should be commented out #LDAP_BINDPW this should be commented out LDAP_AUTHBIND 1 LDAP_GLOB_UID vmail LDAP_GLOB_GID vmail LDAP_FULLNAME sn |
[edit] Starting the daemon and keeping it started
| Commands: start imapd daemon |
# mkdir /var/run/courier-imap # /usr/local/libexec/imapd.rc start # /usr/local/libexec/pop3d.rc start |
We need the daemons to start up each time, so we should add them to our startup file. We also need to make their directories that store their pid files. I attempte to create that directory each time... for the sake of sanity. Append this to the end of your rc.local file.
| Config File: /etc/rc.local |
# Start the IMAP daemon
if [ -x /usr/local/libexec/imapd.rc ]; then
echo -n ' imap'
mkdir /var/run/courier-imap
/usr/local/libexec/imapd.rc start > /dev/null &
fi
# Start the POP3 daemon
if [ -x /usr/local/libexec/pop3d.rc ]; then
echo -n ' pop3'
mkdir /var/run/courier-imap
/usr/local/libexec/pop3d.rc start > /dev/null &
fi
|
[edit] Troubleshooting / Notes
- If you have problems, make sure you don't have spaces or tabs at the end of variables (this one threw me for a loop for a day or so).
