Virtual Hosting Howto With Virtualmin On CentOS 5.1 - Page 6

Configure Virtualmin


Virtualmin is a powerful and flexible hosting control panel that integrates with webmin. We will be using it to provide the virtual hosting functions such as creation of domains, accounts and maintaining configurations on the system.


Start Services

You need to start up services that are required to be able to configure virtualmin. Start the following services:

service named start
service spamassassin start
service spamass-milter start
service clamav-milter start
service postfix start
service dovecot start
service imapproxy start
service httpd start


Initial Settings


Webmin needs to be able to communicate with mysql since we have set a password for mysql we need to set that up in webmin, go to servers ? mysql and enter this information:


Configure Features

You need to enable the features and plugins that we want to use. On login this is the screen that you will see.

  • Enable the following features and save
    • Home directory
    • Administration user
    • Mail for domain
    • BIND DNS domain
    • Apache website
    • Webalizer reporting
    • Log file rotation
    • Mysql database
    • Webmin user


Configure Server Templates

Server template are used to customize the services and to create packages for different hosting account types.


Apache Template

You can make changes to the way apache virtual hosts are created by editing this template, The defaults however will do for purposes of this howto.


Domain Owner Template

This template is used to configure various server limits such as number of mailboxes,aliases,databases,virtual servers and other options like bandwidth limits, admin abilities. For this howto we will use the default values.


Home Directory Template

This template allows you to set a skel directory to hold setting for new users for this howto we will use the defaults.


Administration User

This template lets you set the quota for the virtual server and the admin user for this howto we will use the default quota 1GB.


Mail For Domain Template

This template sets various mail related options, we will modify the email message sent on server creation to have the content below:

The following virtual server has been set up successfully :
Domain name:             ${DOM}
Hosting server:          ${HOSTNAME}
Virtual IP address:      ${IP}
Administration login:    ${USER}
Administration password: ${PASS}
Administration URL:      ${WEBMIN_PROTO}://www.${DOM}:${WEBMIN_PORT}/
Website:                 http://www.${DOM}/
Webalizer log reporting: Enabled
Webalizer log reporting: Disabled
Email domain:            ${DOM}
SMTP server:             mail.${DOM}
POP3 server:             mail.${DOM}
Webmail:                 webmail.${DOM}
DNS domain:              ${DOM}
Nameserver:              ${HOSTNAME}
MySQL database:          ${DB}
MySQL login:             ${MYSQL_USER}
MySQL password:          ${PASS}
PostgreSQL database:     ${DB}
PostgreSQL login:        ${USER}
PostgreSQL password:     ${PASS}

We will leave the other options as the defaults.


BIND DNS Domain Template

This template is used to customize the zones that will be created by virtualmin. The changes to be made are adding a spf record, add the following records to auto generated text box (replace with your slave server):

@     IN NS ;slave
admin IN A ;virtualmin
webmail IN A ;webmail

In the directives text box add the following with the IP address of your slave server such that the slave is allowed to do zone transfers.

allow-transfer {; };


MySQL Database Template

Contains options on creation of databases by virtualmin, for the howto we will use the defaults.


Webmin Login Template

Contains option on creation of new users by virtualmin, for the howto we will use the defaults.


Create Virtual Server

Finally we have a working virtual server system, lets create our first virtual server. Go to servers ? virtualmin virtual servers and click add new virtual server, owned by new user.

Fill in the require fields and click create.

Add a mail user to the domain. click on the domain name, then click edit mail and FTP users, then add user and fill in the information.





telnet 25
Connected to localhost.
Escape character is '^]'.
220 tds mail cluster
helo me
250 hosting1
250 2.1.0 Ok
250 2.1.0 Ok
354 End data with <CR><LF>.<CR><LF>
Subject:This is a test
This is a test
250 2.0.0 Ok: queued as 4ACCC7C5A6

telnet 25
Connected to localhost.
Escape character is '^]'.
220 tds mail cluster
ehlo me
250-SIZE 10240000
250 DSN


Test dkim

Send a mail to


Test domainkeys

Send a mail to



Test POP3

telnet 110
+OK Dovecot ready.
user andrew.example
pass password
+OK Logged in.
+OK Logging out.



telnet 143
* OK Dovecot ready.
01 login andrew.example password
01 OK User logged in
01 list "" "*"

* LIST (\HasNoChildren) "." "Trash"
* LIST (\HasNoChildren) "." "Drafts"
* LIST (\HasNoChildren) "." "Junk"
* LIST (\HasNoChildren) "." "Sent"

* LIST (\HasNoChildren) "." "INBOX"
01 OK List completed.
01 logout
* BYE LOGOUT received
01 OK Completed



dig @



We are using the test virus from

telnet 25
Connected to localhost.
Escape character is '^]'.
220 tds mail cluster
helo me
250 hosting1
250 2.1.0 Ok
250 2.1.0 Ok
354 End data with <CR><LF>.<CR><LF>

550 5.7.1 virus Eicar-Test-Signature detected by ClamAV -
221 2.0.0 Bye

Take a lot at your /var/log/maillog you should see something like this:

73BC87C4E4: milter-reject: END-OF-MESSAGE from localhost[]:
5.7.1 virus Eicar-Test-Signature detected by ClamAV -; 
from=<> to=<> proto=SMTP helo=<me>



We are using the test message from

telnet 25
Connected to localhost.
Escape character is '^]'.
220 tds mail cluster
helo me
250 hosting1
250 2.1.0 Ok
250 2.1.0 Ok
354 End data with <CR><LF>.<CR><LF>

550 5.7.1 Blocked by SpamAssassin
221 2.0.0 Bye

You will see this in your log files:

spamd: result: Y 1002 - AWL,GTUBE,MISSING_SUBJECT,TVD_SPACE_RATIO,UNPARSEABLE_RELAY scantime=0.5,size=723,user=root,uid=99,required_score=5.0,
Share this page:

17 Comment(s)

Add comment


From: Anonymous at: 2008-10-21 17:17:16

Kudo's to Andrew and his howto for virtualmin.  I have utilized this in the past to install virtualmin and it works well.  However, since the latest version of virtualmin, there really isn't any need anymore.  Download the script from there site and it will download every needed package and configure them for virtualmin.  Just a little heads up. 

From: Anonymous at: 2009-02-20 07:35:08

I tired the installation script on Fresh CentOS 5.2 , the installation went well and the sctipt logs shows successful but it dont allow you to log in to the virtualmin. I think its only for liecenced users.

From: Anonymous at: 2009-02-21 10:02:13

The installation script work perfectly on a clean CentOS 5 or 5.2. Make sure you have clean copy of Cent OS , rest the script do everything. I have tested it by myself today and now its working perfectly.

** Its awesome, replaced this whole tutorial with one command and FREE Official Virtualmin script available at Enjoy **

From: at: 2008-03-25 05:19:39

Great tutorial, a real real real time saver!

On the RPMForge setup, point people to

Especially if they are using x86_64 or a different distro.


From: at: 2009-03-26 19:12:15

I would take things one step further and follow the directions here:

By using the priorities plugin for yum, you will not need to disable the rpmforge repo (i.e. the 'enable=0' step above) and then constantly use '--enablerepo=rpmforge' when installing packages from rpmforge.  Furthermore, you can just do one 'yum update' to update everything from the base and the rpmforge repositories...just make sure to make the rpmforge lower priority than base!



From: at: 2008-03-25 05:23:07

/etc/yum.repos.d for me

From: Anonymous at: 2011-04-01 02:33:32

rpm -Uvh

is no long working any alternatives?


Thanks Kyle.

From: at: 2008-03-26 08:00:58

It's really a very good tutorial, it just might need some tuning ... anyway I suggest those modifications to for better performance ... this is a modified copy of with modifications applied .. Modification are mainly to allow non-tls smtp authentication and to stop buggy slow recipient address verification and use "reject_unlisted_recipient" instead ..

command_directory = /usr/sbin
daemon_directory = /usr/libexec/postfix
#mydomain =
#myorigin = $mydomain
unknown_local_recipient_reject_code = 550
unverified_recipient_reject_code = 550
unverified_sender_reject_code = 550
mynetworks =
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
virtual_alias_maps = hash:/etc/postfix/virtual
canonical_maps = hash:/etc/postfix/canonical
sender_canonical_maps = hash:/etc/postfix/canonical
recipient_canonical_maps = hash:/etc/postfix/canonical
#address_verify_map = btree:/var/spool/postfix/verify
smtpd_sender_restrictions = hash:/etc/postfix/sender_access
mail_spool_directory = /var/spool/mail
home_mailbox = Maildir/
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_use_tls = yes
smtpd_tls_key_file = /etc/pki/postfix/smtpd.key
smtpd_tls_cert_file = /etc/pki/postfix/smtpd.crt
smtpd_tls_CAfile = /etc/pki/postfix/cacert.pem
smtpd_tls_loglevel = 1
smtpd_tls_received_header = yes
smtpd_tls_session_cache_timeout = 3600s
smtpd_tls_session_cache_database = btree:/var/spool/postfix/smtpd_tls_cache
smtp_use_tls = yes
smtp_tls_key_file = /etc/pki/postfix/smtpd.key
smtp_tls_cert_file = /etc/pki/postfix/smtpd.crt
smtp_tls_CAfile = /etc/pki/postfix/cacert.pem
smtp_tls_session_cache_database = btree:/var/spool/postfix/smtp_tls_cache
smtp_tls_note_starttls_offer = yes
smtpd_tls_auth_only = no
tls_random_source = dev:/dev/urandom
smtpd_sasl_auth_enable = yes
debug_peer_level = 2
debugger_command =
         xxgdb $daemon_directory/$process_name $process_id & sleep 5
sendmail_path = /usr/sbin/sendmail.postfix
newaliases_path = /usr/bin/newaliases.postfix
mailq_path = /usr/bin/mailq.postfix
setgid_group = postdrop
html_directory = no
manpage_directory = /usr/share/man
sample_directory = /usr/share/doc/postfix-2.3.3/samples
readme_directory = /usr/share/doc/postfix-2.3.3/README_FILES
smtpd_banner = tds mail cluster
smtpd_helo_required = yes
disable_vrfy_command = yes
show_user_unknown_table_name = no
policy_time_limit = 3600
smtpd_milters = unix:/var/clamav/clmilter.socket unix:/var/run/spamass.sock
non_smtpd_milters = unix:/var/clamav/clmilter.socket unix:/var/run/spamass.sock
smtpd_error_sleep_time = 5s
smtpd_soft_error_limit = 10
smtpd_hard_error_limit = 20
smtpd_data_restrictions = reject_unauth_pipelining
smtpd_recipient_restrictions =
        check_recipient_access hash:/etc/postfix/access
        check_policy_service unix:private/spfpolicy 

From: at: 2008-03-26 10:59:22

reject_unlisted_recipient seems like a good idea i will update the sample config Actually i have smtp auth over tls only on purpose due to the fact that LOGIN and PLAIN authentication methods which are used by M$ clients are not secure and can lead to the user details being captured by anyone who is eaves dropping on the traffic, but i guess getting users to setup TLS on the client side is a pain at times.

From: at: 2008-07-28 12:12:52

You've done a great job here.  I ran across some errors, but worked through each so far.  

I need some clarification on one point, though:

You appear to be configuring postfix to use secure authentication.  As the hosting provider, my domain may be, but my clients will all have their own domains which will use mail under each.

So, as I follow your tutorial, should I be using my own host name (i/e in place of, when creating server certificates, and/or generating keys for DKIM?

Will I have to manually configure each client this way?

Please excuse my ignorance, but this is all very new to me.





From: at: 2008-07-30 08:19:28

1. Yes for outbound mail they will have to use your domain name as the smtp server hostname as the certificate will hold your name, for receiving however they can use their own domain name for the imap/pop3 server hostname.

2. As for DKIM you can have multiple keys so you can sign mail for all your customers domains.

From: at: 2009-04-10 20:29:17

It seems that in Centos 5.3, the clamav-milter daemon periodically reloads and loses the group permission that the clamav-milter.patch sets up.  In other words, it's reverts back to the clamav group which causes a permission problem with Postfix.  The easiest fix is to make the postfix user a member of the clamav group.

From: Acorp Computers at: 2008-09-19 02:45:25

In case it helps anyone else, my "Spamassassin Basic Config" was located in:



From: Pawel at: 2009-02-08 14:43:36

/etc/httpd/conf.d/ssl.conf in CentOS 5.2

 Great tutorial!

From: at: 2008-11-01 15:35:33

the vsftp has some mistake ,the virtualmin can't write the new user to the choort_list_user ?just keep the chroot_local=yes.

From: ??? at: 2008-11-05 09:02:03

what about the suexec home? now i have a web ,and the upload file such as picture .it's groups is apache not the site user.

and i run suexec -V the home is /var/www/   it's the problem?

From: Tanczos Andras at: 2009-02-15 21:34:52

rcpt to: instead of rcpt: at postfix tests