Steps used to install my Ubuntu server on Linode (UK) ====== Basic ====== ===== Reference Docs ===== [[http://library.linode.com/advanced/migrate-server-to-linode]]\\ [[http://library.linode.com/networking/rdiff-backup-sshfs]]\\ [[http://library.linode.com/]]\\ [[http://articles.slicehost.com/ubuntu-intrepid]]\\ Checkout the DokuWiki plugins [[http://www.dokuwiki.org/plugins]]\\ [[http://library.linode.com/web-servers/nginx/php-fastcgi-ubuntu9.10-karmic]]\\ For Mail Filtering [[http://wiki.dovecot.org/LDA/Sieve]] http://www.kirya.net/articles/setting-up-dspam-as-a-filter-for-postfix-on-debian-etch/\\ http://yoonkit.blogspot.com/2008/05/dspam-webgui-modifications-javascript.html\\ http://www.directadmin.com/forum/showthread.php?t=16015\\ http://diymacserver.com/installing-the-mailserver/adding-a-spam-filter/purging-the-dspam-database-automatically/\\ http://209.85.129.132/search?q=cache:dzru2MmA7zQJ:github.com/kuroneko/dspam+dspam+domain+dictionary&cd=9&hl=en&ct=clnk&client=safari\\ ===== MySQL & phpMyAdmin ===== - Installed the following packages apt-get install mysql-server mysql-client phpMyAdmin - In the post install phase, set a password for both the mysql root user and for phpmyadmin - Then mkdir -p ./srv/www/pma.tarasis.net/logs ln -s /usr/share/phpmyadmin /srv/www/pma.tarasis.net/public - Enable SSL support in NGINX - Create SSL server certificates (or install existing ones if you have them) - Create the NGINX conf for the site nano /etc/nginx/sites-available/pma.tarasis.net and then: server { } - Enable the site - restart NGINX ====== Web ====== Went with NGINX again (as Slicehost), this time with the stock Ubuntu version, not custom built. ===== NGINX ===== Basically per the initial instructions on [[http://library.linode.com/web-servers/nginx/php-fastcgi-ubuntu9.10-karmic|Linode]] - Update you /etc/apt/sources.list to be similar too ## main & restricted repositories deb http://us.archive.ubuntu.com/ubuntu/ karmic main restricted universe multiverse deb-src http://us.archive.ubuntu.com/ubuntu/ karmic main restricted universe multiverse deb http://security.ubuntu.com/ubuntu karmic-security main restricted universe multiverse deb-src http://security.ubuntu.com/ubuntu karmic-security main restricted universe multiverse deb http://security.ubuntu.com/ubuntu karmic-updates main restricted universe multiverse deb-src http://security.ubuntu.com/ubuntu karmic-updates main restricted universe multiverse - Then issue the following to update the catalog files, upgrade the non essential packages and then install the required packages apt-get update apt-get upgrade apt-get install nginx php5-cli php5-cgi build-essential wget **NOTE** While trying to figure out what was causing some problems I installed the latest dev release via the [[http://wiki.nginx.org/NginxInstall|instructions]] on the NGINX site: Ubuntu PPA Jeff Waugh maintains recent versions of Nginx in his PPA. echo "deb http://ppa.launchpad.net/jdub/devel/ubuntu hardy main" >> /etc/apt/sources.list apt-key adv --keyserver keyserver.ubuntu.com --recv-keys E9EEF4A1 apt-get update apt-get install nginx I should likely revert to the stock Ubuntu release. ===== PHP ===== For providing PHP sites I have followed the steps [[http://library.linode.com/web-servers/nginx/php-fastcgi-ubuntu9.10-karmic|Nginx and PHP-FastCGI on Ubuntu 9.10 (Karmic)]] Well I did but as I kept getting 502 Bad Gateway errors, I thought I would go back to the setup I used on Slicehost which doesn't use spawn-fcgi. - Create a defaults file nano /etc/default/php-fcgi into which you place the following # # Settings for php-cgi in external FASTCGI Mode # # Should php-fastcgi run automatically on startup? (default: no) START=yes # Which user runs PHP? (default: www-data) EXEC_AS_USER=www-data # Host and TCP port for FASTCGI-Listener (default: localhost:9000) FCGI_HOST=localhost FCGI_PORT=9000 # Environment variables, which are processed by PHP PHP_FCGI_CHILDREN=2 PHP_FCGI_MAX_REQUESTS=500 - Next create nano /etc/init.d/php-fastcgi and put the following in #!/bin/sh ### BEGIN INIT INFO # Provides: php-fastcgi # Required-Start: $all # Required-Stop: $all # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Start and stop php-cgi in external FASTCGI mode # Description: Start and stop php-cgi in external FASTCGI mode ### END INIT INFO # Author: Kurt Zankl # Do NOT "set -e" PATH=/sbin:/usr/sbin:/bin:/usr/bin DESC="php-cgi in external FASTCGI mode" NAME=php-fastcgi DAEMON=/usr/bin/php-cgi PIDFILE=/var/run/$NAME.pid SCRIPTNAME=/etc/init.d/$NAME PHP_CONFIG_FILE=/etc/php5/cgi/php.ini # Exit if the package is not installed [ -x "$DAEMON" ] || exit 0 # Read configuration variable file if it is present [ -r /etc/default/$NAME ] && . /etc/default/$NAME # Load the VERBOSE setting and other rcS variables #. /lib/init/vars.sh # Define LSB log_* functions. # Depend on lsb-base (>= 3.0-6) to ensure that this file is present. . /lib/lsb/init-functions # If the daemon is not enabled, give the user a warning and then exit, # unless we are stopping the daemon if [ "$START" != "yes" -a "$1" != "stop" ]; then log_warning_msg "To enable $NAME, edit /etc/default/$NAME and set START=yes" exit 0 fi # Process configuration export PHP_FCGI_CHILDREN PHP_FCGI_MAX_REQUESTS DAEMON_ARGS="-q -b $FCGI_HOST:$FCGI_PORT -c $PHP_CONFIG_FILE" do_start() { # Return # 0 if daemon has been started # 1 if daemon was already running # 2 if daemon could not be started start-stop-daemon --start --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \ || return 1 start-stop-daemon --start --pidfile $PIDFILE --exec $DAEMON \ --background --make-pidfile --chuid $EXEC_AS_USER --startas $DAEMON -- \ $DAEMON_ARGS \ || return 2 } do_stop() { # Return # 0 if daemon has been stopped # 1 if daemon was already stopped # 2 if daemon could not be stopped # other if a failure occurred start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE > /dev/null # --name $DAEMON RETVAL="$?" [ "$RETVAL" = 2 ] && return 2 # Wait for children to finish too if this is a daemon that forks # and if the daemon is only ever run from this initscript. # If the above conditions are not satisfied then add some other code # that waits for the process to drop all resources that could be # needed by services started subsequently. A last resort is to # sleep for some time. start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON [ "$?" = 2 ] && return 2 # Many daemons don't delete their pidfiles when they exit. rm -f $PIDFILE return "$RETVAL" } case "$1" in start) [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME" do_start case "$?" in 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; esac ;; stop) [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME" do_stop case "$?" in 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; esac ;; restart|force-reload) log_daemon_msg "Restarting $DESC" "$NAME" do_stop case "$?" in 0|1) do_start case "$?" in 0) log_end_msg 0 ;; 1) log_end_msg 1 ;; # Old process is still running *) log_end_msg 1 ;; # Failed to start esac ;; *) # Failed to stop log_end_msg 1 ;; esac ;; *) echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2 exit 3 ;; esac - Then issue the following commands to make php-fcgi launch on startup & run it now chmod 755 /etc/init.d/php-fastcgi update-rc.d php-fastcgi defaults /etc/init.d/php-fastcgi start ==== XCACHE ==== apt-get install php5-xcache Edit /etc/php5/conf.d/xcache.ini to (remembering to change username & password) # configuration for php Xcache module [xcache-common] ;; install as zend extension (recommended), normally "$extension_dir/xcache.so" zend_extension = /usr/lib/php5/20060613+lfs/xcache.so [xcache.admin] xcache.admin.enable_auth = On # Configure this to use admin pages xcache.admin.user = "AUSER" ; xcache.admin.pass = md5($your_password) xcache.admin.pass = "AN MD5'd PASSWORD" [xcache] ; ini only settings, all the values here is default unless explained ; select low level shm/allocator scheme implemenation xcache.shm_scheme = "mmap" ; to disable: xcache.size=0 ; to enable : xcache.size=64M etc (any size > 0) and your system mmap allows xcache.size = 64M ; set to cpu count (cat /proc/cpuinfo |grep -c processor) xcache.count = 4 ; just a hash hints, you can always store count(items) > slots xcache.slots = 8K ; ttl of the cache item, 0=forever xcache.ttl = 0 ; interval of gc scanning expired items, 0=no scan, other values is in seconds xcache.gc_interval = 0 ; same as aboves but for variable cache xcache.var_size = 64M xcache.var_count = 4 xcache.var_slots = 8K ; default ttl xcache.var_ttl = 0 xcache.var_maxttl = 0 xcache.var_gc_interval = 300 xcache.test = Off ; N/A for /dev/zero xcache.readonly_protection = Off ; for *nix, xcache.mmap_path is a file path, not directory. ; Use something like "/tmp/xcache" if you want to turn on ReadonlyProtection ; 2 group of php won't share the same /tmp/xcache ; for win32, xcache.mmap_path=anonymous map name, not file path xcache.mmap_path = "/dev/zero" ; leave it blank(disabled) or "/tmp/phpcore/" ; make sure it's writable by php (without checking open_basedir) xcache.coredump_directory = "" ; per request settings xcache.cacher = On xcache.stat = On xcache.optimizer = On [xcache.coverager] ; per request settings ; enable coverage data collecting for xcache.coveragedump_directory and xcache_coverager_start/stop/get/clean() functions (will hurt executing performance) xcache.coverager = Off ; ini only settings ; make sure it's readable (care open_basedir) by coverage viewer script ; requires xcache.coverager=On xcache.coveragedump_directory = "" Setup a vhost for xcache Note for my type of vps do I really need this? what are the best mem options? 32mb? ===== wiki.tarasis.net ===== - Copied data off Slicehost using rsync -aHSKDvz -e ssh wiki.tarasis.net AUSER@109.74.199.95:/srv/www - Upgraded DokuWiki version to latest stable release per [[http://www.dokuwiki.org/install:upgrade]] - Created /etc/nginx/sites-available/wiki.tarasis.net - Add the following which tells NGINX about the website, where to put the logs, denies access to the .htaccess files (though they aren't used as NGINX doesn't support them) and defines the rewrite rules for having clean urls. server { listen 80; server_name wiki.tarasis.net; access_log /srv/www/wiki.tarasis.net/logs/access.log; error_log /srv/www/wiki.tarasis.net/logs/error.log; location ~ /\.ht { deny all; } root /srv/www/wiki.tarasis.net/public/; rewrite ^(/)_media/(.*) $1lib/exe/fetch.php?media=$2 last; rewrite ^(/)_detail/(.*) $1lib/exe/detail.php?media=$2 last; rewrite ^(/)_export/([^/]+)/(.*) $1doku.php?do=export_$2&id=$3 last; if (!-f $request_filename) { rewrite ^(/)(.*)?(.*) $1doku.php?id=$2&$3 last; rewrite ^(/)$ $1doku.php last; } location ~ \.php$ { include /etc/nginx/fastcgi_params; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /srv/www/wiki.tarasis.net/public$fastcgi_script_name; } } - Edit /srv/www/wiki.tarasis.net/public/conf/local.php and add $conf['userewrite'] = 1; which tells dokuwiki to use clean urls and that the webserver will be handling it. - Make the site available for NGINX and then restart it. ln -s /etc/nginx/sites-available/wiki.tarasis.net /etc/nginx/sites-enabled /etc/init.d/nginx restart ===== tarasis.net ===== Basically a Blog running Wordpress ===== pma.tarasis.net ===== phpMyAdmin ====== Mail ====== Existing setup is Exim (using vexim for vhosts), Dovecot, dspam & clamd Considering going Postfix (with postfixadmin for vhosts), dovecot and not sure about Antispam & antivirus this time around. Using combination of - [[http://wiki.dovecot.org/HowTo/DovecotLDAPostfixAdminMySQL]] - [[http://flurdy.com/docs/postfix/]] - [[work:mdn:email]] - [[http://johnny.chadda.se/2007/04/15/mail-server-howto-postfix-and-dovecot-with-mysql-and-tlsssl-postgrey-and-dspam/]] ===== Step 1 ===== Install Postfix & Dovecot-imap3d root@indy:~# aptitude install postfix postfix-mysql Reading package lists... Done Building dependency tree Reading state information... Done Initializing package states... Done Writing extended state information... Done The following NEW packages will be installed: postfix postfix-mysql ssl-cert{a} 0 packages upgraded, 3 newly installed, 0 to remove and 0 not upgraded. Need to get 1359kB of archives. After unpacking 3457kB will be used. Do you want to continue? [Y/n/?] y Writing extended state information... Done Get:1 http://us.archive.ubuntu.com karmic/main ssl-cert 1.0.23ubuntu2 [10.9kB] Get:2 http://us.archive.ubuntu.com karmic/main postfix 2.6.5-3 [1304kB] Get:3 http://us.archive.ubuntu.com karmic/main postfix-mysql 2.6.5-3 [44.0kB] Fetched 1359kB in 0s (6043kB/s) Preconfiguring packages ... Selecting previously deselected package ssl-cert. (Reading database ... 20776 files and directories currently installed.) Unpacking ssl-cert (from .../ssl-cert_1.0.23ubuntu2_all.deb) ... Selecting previously deselected package postfix. Unpacking postfix (from .../postfix_2.6.5-3_i386.deb) ... Selecting previously deselected package postfix-mysql. Unpacking postfix-mysql (from .../postfix-mysql_2.6.5-3_i386.deb) ... Processing triggers for man-db ... Setting up ssl-cert (1.0.23ubuntu2) ... Setting up postfix (2.6.5-3) ... Adding group `postfix' (GID 108) ... Done. Adding system user `postfix' (UID 105) ... Adding new user `postfix' (UID 105) with group `postfix' ... Not creating home directory `/var/spool/postfix'. Creating /etc/postfix/dynamicmaps.cf Adding tcp map entry to /etc/postfix/dynamicmaps.cf Adding group `postdrop' (GID 109) ... Done. setting myhostname: indy setting alias maps setting alias database changing /etc/mailname to daffy.tarasis.net setting myorigin setting destinations: daffy.tarasis.net, indy, localhost.localdomain, localhost setting relayhost: setting mynetworks: 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 setting mailbox_size_limit: 0 setting recipient_delimiter: + setting inet_interfaces: all /etc/aliases does not exist, creating it. WARNING: /etc/aliases exists, but does not have a root alias. Postfix is now set up with a default configuration. If you need to make changes, edit /etc/postfix/main.cf (and others) as needed. To view Postfix configuration values, see postconf(1). After modifying main.cf, be sure to run '/etc/init.d/postfix reload'. When it asks set the system mail name to System mail name: daffy.tarasis.net **NOTE** Need to change the //myhostname: indy// Next Dovecot root@indy:/etc/postfix# aptitude install dovecot-postfix Reading package lists... Done Building dependency tree Reading state information... Done Reading extended state information Initializing package states... Done The following NEW packages will be installed: dovecot-common{a} dovecot-imapd{a} dovecot-pop3d{a} dovecot-postfix libpq5{a} 0 packages upgraded, 5 newly installed, 0 to remove and 0 not upgraded. Need to get 5879kB of archives. After unpacking 11.5MB will be used. Do you want to continue? [Y/n/?] y Install Amavisd-new root@indy:/etc/dovecot# aptitude install amavisd-new Reading package lists... Done Building dependency tree Reading state information... Done Reading extended state information Initializing package states... Done The following NEW packages will be installed: amavisd-new libarchive-zip-perl{a} libberkeleydb-perl{a} libconvert-binhex-perl{a} libconvert-tnef-perl{a} libconvert-uulib-perl{a} libcrypt-openssl-bignum-perl{a} libcrypt-openssl-rsa-perl{a} libdigest-hmac-perl{a} libdigest-sha1-perl{a} liberror-perl{a} libio-multiplex-perl{a} libio-stringy-perl{a} libmail-dkim-perl{a} libmailtools-perl{a} libmime-tools-perl{a} libnet-cidr-perl{a} libnet-dns-perl{a} libnet-ip-perl{a} libnet-server-perl{a} libunix-syslog-perl{a} pax{a} The following packages are RECOMMENDED but will NOT be installed: libcompress-raw-zlib-perl Install Spamassassin, spamc, Postgrey root@indy:/etc/dovecot# aptitude install spamassassin spamc postgrey Reading package lists... Done Building dependency tree Reading state information... Done Reading extended state information Initializing package states... Done The following NEW packages will be installed: libhtml-tree-perl{a} libsocket6-perl{a} libsys-hostname-long-perl{a} libwww-perl{a} postgrey spamassassin spamc The following packages are RECOMMENDED but will NOT be installed: libcompress-bzip2-perl libhtml-format-perl libio-socket-inet6-perl libmail-spf-perl libnet-rblclient-perl libparse-syslog-perl re2c For testing root@daffy:~# aptitude install mailx telnet ===== Forgot this step ===== Set the server name to **daffy.tarasis.net** root@indy:~# nano /etc/hostname root@indy:~# nano /etc/hosts Also setup the Reverse DNS on Linode (Linode>duemoko>Network) IP Address RDNS 109.74.199.95 daffy.tarasis.net ===== Step 2 ===== root@daffy:~# dpkg-reconfigure postfix * Stopping Postfix Mail Transport Agent postfix ...done. setting synchronous mail queue updates: false setting myorigin setting destinations: daffy.tarasis.net, tarasis.net, localhost.localdomain, localhost setting relayhost: setting mynetworks: 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 setting mailbox_size_limit: 0 setting recipient_delimiter: + setting inet_interfaces: all setting inet_protocols: ipv4 WARNING: /etc/aliases exists, but does not have a root alias. ===== Install Postfix Admin ===== Download the lastest version (for me 2.3), after untarring it. Move it to the right place root@daffy:~/source# mkdir -p /srv/www/pfa.tarasis.net/logs root@daffy:~/source# mv postfixadmin-2.3/ /srv/www/pfa.tarasis.net/public Fix the file ownership root@daffy:~/source# cd /srv/www/pfa.tarasis.net/ root@daffy:/srv/www# chown -R www-data:www-data public/ Create a NGNIX config file for it and restart nano /etc/nginx/sites-available/pfa.tarasis.net server { listen 80; server_name pfa.tarasis.net; access_log /srv/www/pfa.tarasis.net/logs/access.log; error_log /srv/www/pfa.tarasis.net/logs/error.log; location / { index index.php index.html; root /srv/www/pfa.tarasis.net/public; } # redirect postfixadmin to the https page location ~\.php$ { include /etc/nginx/fastcgi_params; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /srv/www/pfa.tarasis.net/public$fastcgi_script_name; } } #save it and symlink it and restart nginx ln -s /etc/nginx/sites-available/pfa.tarasis.net /etc/nginx/sites-enabled/ /etc/init.d/nginx restart Create a Database for postfixadmin. Using the command line mysql -p Then (remembering to set a real password) CREATE DATABASE postfix; CREATE USER 'postfix'@'localhost' IDENTIFIED BY 'choose_a_password'; GRANT ALL PRIVILEGES ON `postfix` . * TO 'postfix'@'localhost'; Next edit config.inc.php and change the following lines to: $CONF['configured'] = false; << true $CONF['postfix_admin_url'] = ''; << http://pfa.tarasis.net $CONF['setup_password'] = 'postfixadmin'; << $CONF['database_type'] = 'mysql'; << mysqli $CONF['database_password'] = 'postfixadmin'; << the password $CONF['default_aliases'] = array ( 'abuse' => 'abuse@change-this-to-your.domain.tld', 'hostmaster' => 'hostmaster@change-this-to-your.domain.tld', 'postmaster' => 'postmaster@change-this-to-your.domain.tld', 'webmaster' => 'webmaster@change-this-to-your.domain.tld' ); $CONF['domain_path'] = 'NO'; << YES $CONF['domain_in_mailbox'] = 'YES'; << NO $CONF['mailboxes'] = '10'; << 20 Goto http://pfa.tarasis.net/setup.php, should be lots of okays and so on. One error is that php5-imap module is not installed and then restart php so that the new module is picked up aptitude install php5-imap /etc/init.d/php-fastcgi restart Now return to setup.php and add a Setup password & admin user. When you click Add Admin it will complain password is not in the right format and copy the password hash into the config.inc.php file. Reload the page and the admin user is created. **NOTE** "Warning: Magic Quotes: ON (internal workaround used)" << checkout if this is a problem Add a user & group for the mail groupadd virtual -g 5000 useradd virtual -u 5000 -g 5000 chown -R virtual:virtual /srv/mail Next create the files which will give Postfix access to the DB with the aliases. Remember to change THE_PASSWORD to the real password. root@daffy:/etc/postfix$ nano mysql_virtual_alias_maps.cf user = postfix password = THE_PASSWORD hosts = localhost dbname = postfix query = SELECT goto FROM alias WHERE address='%s' AND active = 1 root@daffy:/etc/postfix# nano mysql_virtual_domains_maps.cf user = postfix password = THE_PASSWORD hosts = localhost dbname = postfix query = SELECT domain FROM domain WHERE domain='%s' #optional query to use when relaying for backup MX #query = SELECT domain FROM domain WHERE domain='%s' and backupmx = '0' and active = '1' root@daffy:/etc/postfix# nano mysql_virtual_mailbox_maps.cf user = postfix password = THE_PASSWORD hosts = localhost dbname = postfix #query = SELECT CONCAT(domain,'/',maildir) FROM mailbox WHERE username='%s' AND active = 1 query = SELECT maildir FROM mailbox WHERE username='%s' AND active = 1 root@daffy:/etc/postfix# nano mysql_virtual_mailbox_limit_maps.cf user = postfix password = THE_PASSWORD hosts = localhost dbname = postfix query = SELECT quota FROM mailbox WHERE username='%s' root@daffy:/etc/postfix# nano mysql_relay_domains_maps user = postfix password = THE_PASSWORD hosts = localhost dbname = postfix query = SELECT domain FROM domain WHERE domain='%s' and backupmx = '1' ===== Install & Configure Dovecot ===== Create a sql conf file so Dovecot knows how to find the users. In **/etc/dovecot/** create **dovecot-mysql.conf** driver = mysql connect = dbname=postfix user=postfix host=localhost password=!postfixadmin* default_pass_scheme = md5-crypt user_query = SELECT maildir, maildir AS home, 5000 AS uid, 5000 AS gid FROM mailbox WHERE username = '%u' AND active = '1' password_query = SELECT password FROM mailbox WHERE username = '%u' AND active = '1' # Later two lines are from http://www.miphol.com/muse/2009/06/setting-up-a-lightweight-mail.html, keeping around for ideas. #user_query = SELECT '/home/vmail/%u' as home, 'maildir:/home/vmail/%u' as mail, 5000 AS uid, 12 AS gid, concat('*:storage=', quota, 'M') AS quota_rule FROM mailbox WHERE username = '%u' AND active = '1' #password_query = SELECT username as user, password, '/home/vmail/%u' as userdb_home, 'maildir:/home/vmail/%u' as userdb_mail, 5000 as userdb_uid, 12 as userdb_gid FROM mailbox WHERE username = '%u' AND active = '1' Configure **/etc/dovecot/dovecot.conf** **Note mailfiltering disabled for the moment.** protocols = imap imaps listen = * ssl_disable = no ssl_cert_file = /etc/ssl/certs/myssl.crt ssl_key_file = /etc/ssl/private/myssl.key # the trailing Maildir is left over from when mail was handled by Exim / Courier # given Dovecot can handle it by appending Maildir I shall simply do that. mail_location = maildir:/srv/mail/%d/%n/Maildir first_valid_uid = 5000 last_valid_uid = 5000 first_valid_gid = 5000 last_valid_gid = 5000 Uncomment #protocol ldap { postmaster_address = postmaster@tarasis.net auth_socket_path = /var/run/dovecot/auth-master # Enabling Sieve plugin for server-side mail filtering mail_plugins = cmusieve #sieve_global_dir = /srv/mail/ global_script_path = /srv/mail/.dovecot.sieve log_path = /var/log/dovecot-deliver.log info_log_path = /var/log/dovecot-deliver.log Uncomment } at end of ldap block Comment out the passdb pam block In auth default { mechanisms = digest-md5 plain login passdb sql { # Path for SQL configuration file args = /etc/dovecot/dovecot-mysql.conf } userdb sql { # Path for SQL configuration file args = /etc/dovecot/dovecot-mysql.conf } user = nobody socket listen { master { # Master socket provides access to userdb information. It's typically # used to give Dovecot's local delivery agent access to userdb so it # can find mailbox locations. path = /var/run/dovecot/auth-master mode = 0660 # Default user/group is the one who started dovecot-auth (root) user = virtual group = virtual } client { # The client socket is generally safe to export to everyone. Typical use # is to export it to your SMTP server so it can do SMTP AUTH lookups # using it. path = /var/spool/postfix/private/auth mode = 0660 user = postfix group = postfix } } At the very end add so that the sieve knowns where to find my sieve file (replaces procmail) plugin { # NOTE: %variable expansion works only with Dovecot v1.0.2+ sieve = /srv/mail/%d/%n/.dovecot.sieve } Add the following to the end of **/etc/postfix/master.cf** to have postfix use Dovecot for delivery dovecot unix - n n - - pipe flags=DRhu user=virtual:virtual argv=/usr/lib/dovecot/deliver -f ${sender} -d ${recipient} Next edit **/etc/postfix/main.cf** to this. This version permits SASL, TLS and Virtual Mail via Dovecot # See /usr/share/postfix/main.cf.dist for a commented, more complete version # Debian specific: Specifying a file name will cause the first # line of that file to be used as the name. The Debian default # is /etc/mailname. myorigin = /etc/mailname smtpd_banner = $myhostname ESMTP $mail_name (Ubuntu) biff = no # appending .domain is the MUA's job. append_dot_mydomain = no # Uncomment the next line to generate "delayed mail" warnings delay_warning_time = 4h readme_directory = no myhostname = daffy.tarasis.net alias_maps = hash:/etc/aliases alias_database = hash:/etc/aliases mydestination = daffy.tarasis.net, daffy, localhost.localdomain, localhost relayhost = mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 mailbox_size_limit = 0 recipient_delimiter = + inet_interfaces = all home_mailbox = smtpd_sender_restrictions = mailbox_command = # Per http://bliki.rimuhosting.com/space/knowledgebase/linux/mail/postfixadmin+on+debian+sarge # ---- Virtual Domains / account handling ---- virtual_mailbox_base = /srv/mail/ # The domains we accept mail for virtual_mailbox_domains = proxy:mysql:/etc/postfix/mysql_virtual_domains_maps.cf # Determine mailbox location virtual_mailbox_maps = proxy:mysql:/etc/postfix/mysql_virtual_mailbox_maps.cf virtual_alias_maps = proxy:mysql:/etc/postfix/mysql_virtual_alias_maps.cf virtual_uid_maps = static:5000 virtual_gid_maps = static:5000 virtual_transport = dovecot dovecot_destination_recipient_limit = 1 # ---- TLS parameters ---- smtp_tls_cert_file=/etc/ssl/certs/myssl.crt smtp_tls_key_file=/etc/ssl/private/myssl.key smtpd_tls_cert_file=/etc/ssl/certs/myssl.crt smtpd_tls_key_file=/etc/ssl/private/myssl.key smtpd_tls_security_level = may smtpd_tls_received_header = yes smtpd_tls_loglevel = 1 smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache smtpd_tls_mandatory_protocols = SSLv3, TLSv1 smtpd_tls_mandatory_ciphers = medium inet_protocols = ipv4 tls_random_source = dev:/dev/urandom # See /usr/share/doc/postfix/TLS_README.gz in the postfix-doc package for # information on enabling SSL in the smtp client. # ---- support SASL2 ---- smtpd_sasl_auth_enable = yes smtpd_sasl_local_domain = $myhostname smtpd_sasl_authenticated_header = yes smtpd_sasl_security_options = noanonymous smtpd_sasl_type = dovecot smtpd_sasl_path = private/auth broken_sasl_auth_clients = yes smtpd_recipient_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_unauth_destination ===== Test for open relays ===== From the Linode telnet rt.njabl.org 2500 It will then run a barrage of relay tests against the server. Check that none are allowed. root@daffy:~# telnet rt.njabl.org 2500 Trying 69.28.95.130... Connected to rt.njabl.org. Escape character is '^]'. <<< 250 DSN >>> MAIL FROM: <<< 250 2.1.0 Ok >>> RCPT TO: <<< 554 5.7.1 : Relay access denied >>> RSET <<< 250 2.0.0 Ok >>> RCPT TO: <<< 554 5.7.1 : Relay access denied Can't relay Connection closed by foreign host. Next Goto [[http://www.abuse.net/relay.html]] and enter the server name as the address to test and press "Test For Relay". Again it should complete the tests without any relays being allowed. ===== Configure Postgrey ===== Edit the config file **/etc/default/postgrey** to change the default delay (countdown from 3) root@daffy:~# nano /etc/default/postgrey POSTGREY_OPTS="--inet=10023 --delay=" Tell Postfix to use Postgrey by adding **check_policy_service inet:127.0.0.1:10023** in **/etc/postfix/main.cf** smtpd_recipient_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_unauth_destination, check_policy_service inet:127.0.0.1:10023, permit **NOTE** Consider putting the delay back up to 300 or even increase it. Though people don't tend to want their mail delayed 5 minutes at first. ===== Tweaking Postfix for Anti-Spam measures ===== [[http://dman13.dyndns.org/~dman/config_docs/antispam-postfix/node3.html]]\\ [[http://www.mail-archive.com/postfix-users@postfix.org/msg07601.html]] for some check_helo_access examples\\ [[http://www.linuxquestions.org/questions/linux-server-73/how-to-configure-postfix-to-reject-spams-474799/]]\\ ===== Install & Configure Amavis-New, Clamav, Spamassassin / DSPAM ===== ===== Building DSPAM ===== Ubuntu comes with DSPAM 3.6.8 which is rather old now, so I am going to build the very recent release of DSPAM 3.9.0 The following additional packages need to be installed: root@daffy:/opt# aptitude install libmysqlclient16-dev Reading package lists... Done Building dependency tree Reading state information... Done Reading extended state information Initializing package states... Done The following NEW packages will be installed: libmysqlclient-dev{a} libmysqlclient16-dev zlib1g-dev{a} Add the dspam group and user root@daffy:/opt# groupadd dspam root@daffy:/opt# useradd -M -s /sbin/nologin -g dspam dspam Now configure the package, with the mysql driver, to locate it in /opt, to enable the daemon mode and virtual users ./configure --enable-domain-scale --with-storage-driver=mysql_drv,hash_drv --prefix=/opt --enable-daemon --enable-virtual-users --enable-preferences-extension --enable-clamav --with-mysql-libraries=/usr/lib/mysql/ --with-mysql-includes=/usr/include/mysql/ --with-dspam_owner=dspam --with-dspam_group=dspam --enable-debug Now make and install it & the webui root@daffy:~/dspam-3.9.0# make && make install root@daffy:~/dspam-3.9.0# cp -a webui /opt/var/dspam Change the ownership of the dspam files **/opt/var/dspam** root@daffy:/opt/var# chown -R dspam:dspam dspam Create the dspam database and add a dspam user to the db root@daffy:~/dspam-3.9.0/src/tools.mysql_drv# mysqladmin -u root -p create dspam root@daffy:~/dspam-3.9.0/src/tools.mysql_drv# mysql -u root -p mysql> GRANT SELECT, INSERT, UPDATE, DELETE ON dspam.* TO 'dspam'@'localhost' IDENTIFIED BY 'A PASSWORD'; Inject the db tables root@daffy:~/dspam-3.9.0/src/tools.mysql_drv# mysql -u root -p dspam < mysql_objects-4.1.sql Enter password: root@daffy:~/dspam-3.9.0/src/tools.mysql_drv# mysql -u root -p dspam < virtual_users.sql Enter password: We will need **root@daffy:~/dspam-3.9.0/src/tools.mysql_drv# less purge-4.1.sql** later for purging the dspam db nightly of unneeded tokens. Next edit **/opt/etc/dspam.conf** and change the MySQL lines as follows MySQLServer /var/run/mysqld/mysqld.sock #MySQLPort MySQLUser dspam MySQLPass A PASSWORD MySQLDb dspam MySQLCompress true MySQLReconnect true Edit **/etc/default/dspam** and set start to yes START=YES For notes, installing dspam package adds following entries to file system and doesn't remove them when the dspam package is removed. Handy :) added dspam added cron.daily/dspam added default/dspam added dspam/default.prefs added dspam/dspam.conf added dspam/dspam.d added init.d/dspam added logrotate.d/dspam added rc0.d/K21dspam added rc1.d/K21dspam added rc2.d/S21dspam added rc3.d/S21dspam added rc4.d/S21dspam added rc5.d/S21dspam added rc6.d/K21dspam ===== Configure DSPAM ===== Edit **/opt/etc/dspam.conf** Trust postfix Trust www-data Feature chained Preference "spamAction=tag" # { quarantine | tag | deliver } -> default:quarantine Preference "signatureLocation=headers" # { message | headers } -> default:message Preference "tagSpam=on" # { on | off } DeliveryHost 127.0.0.1 DeliveryPort 10024 DeliveryIdent localhost DeliveryProto SMTP #ServerHost 127.0.0.1 #ServerPort 11124 #ServerQueueSize 32 ServerDomainSocketPath "/var/run/dspam/dspam.sock" ServerPID /var/run/dspam/dspam.pid ServerMode auto ServerParameters "--deliver=innocent,spam" ServerIdent "localhost.localdomain" ParseToHeaders on ChangeModeOnParse on ChangeUserOnParse full TrackSources spam nonspam virus ===== Start dspam ===== Quickly edit **/etc/init.d/dspam** and make following edits. PATH=/opt/bin:/sbin:/bin:/usr/sbin:/usr/bin DAEMON=/opt/bin/$NAME ** CHANGE THE LEFT OVER DSPAM INIT SCRIPT ** Then /etc/init.d/dspam start ---- ** TIDY THIS UP ** ---- In Postfix main.cf, add the following to your smtpd_recipient_restrictions: smtpd_recipient_restrictions = [...] check_recipient_access pcre:/etc/postfix/dspam_filter_access where dspam_filter_access contains: /./ FILTER dspam:dspam Add he following service at the end of master.cf: dspam unix - n n - - pipe flags=Ru user=dspam argv=/usr/bin/dspam --client --deliver=innocent,spam --user ${recipient} --mail-from=${sender} You will also have to add the following line in main.cf: dspam_destination_recipient_limit = 1 Step 3: Configure a reinjection port You'll also need to configure Postfix to listen on a local port for reinjection. This is where DSPAM sends back the "good" mail (or alternatively, tagged mail also). Add this to your master.cf: localhost:10026 inet n - n - - smtpd -o content_filter= -o receive_override_options=no_unknown_recipient_checks,no_header_body_checks -o smtpd_helo_restrictions= -o smtpd_client_restrictions= -o smtpd_sender_restrictions= -o smtpd_recipient_restrictions=permit_mynetworks,reject -o mynetworks=127.0.0.0/8 -o smtpd_authorized_xforward_hosts=127.0.0.0/8 ===== WEB UI ===== Need to install the following perl libraries root@daffy:/opt/var/dspam/webui/cgi-bin# aptitude install libgd-gd2-noxpm-perl libgd-gd2-perl libgd-graph3d-perl Reading package lists... Done Building dependency tree Reading state information... Done Reading extended state information Initializing package states... Done Writing extended state information... Done The following NEW packages will be installed: libgd-gd2-perl libgd-graph-perl{a} libgd-graph3d-perl libgd-text-perl{a} libgd2-xpm{a} libxpm4{a} The following packages will be REMOVED: libgd-gd2-noxpm-perl{a} libgd2-noxpm{a} Copy contents of **/opt/var/dspam/webui/htdocs** Permissions root@daffy:/opt/var# chown www-data /opt/var/dspam root@daffy:/opt/var# chown www-data /opt/var/dspam/webui root@daffy:/opt/var/dspam/webui# chown www-data base.css dspam* Make dir for logs root@daffy:/opt/var/dspam/webui# mkdir logs Make a site file for nginx and enable it. root@daffy:/opt/var# nano /etc/nginx/sites-available/dspam.tarasis.net server { listen 80; server_name dspam.tarasis.net; access_log /opt/var/dspam/webui/logs/access.log; error_log /opt/var/dspam/webui/logs/error.log; root /opt/var/dspam/webui; index dspam.cgi; auth_basic "DSPAM Restricted Site"; auth_basic_user_file htpasswd; location ~ \.cgi$ { gzip off; #gzip makes scripts feel slower since they have to complete before getting gzipped fastcgi_pass 127.0.0.1:8999; fastcgi_index dspam.cgi; fastcgi_param SCRIPT_FILENAME /opt/var/dspam/webui/cgi-bin$fastcgi_script_name; fastcgi_param REMOTE_USER $remote_user; include /etc/nginx/fastcgi_params; } } Next create an auth file with a crypt3 password (htpasswd would work or search for online generator) Get NGINX setup for Perl based FCGI per the steps on [[http://library.linode.com/web-servers/nginx/perl-fastcgi-ubuntu-9.10|this]] Linode article. Finally edit **/opt/var/dspam/webui/cgi-bin/configure.pl** # Change following to my domain $CONFIG{'LOCAL_DOMAIN'} = "domain.tld"; # comment out following line #$CONFIG{'AUTODETECT'} = 1; # uncomment following block # Or, if you're running dspam.cgi as untrusted, it won't be able to auto-detect # so you will need to specify some features manually: $CONFIG{'AUTODETECT'} = 0; $CONFIG{'LARGE_SCALE'} = 0; $CONFIG{'DOMAIN_SCALE'}= 1; $CONFIG{'PREFERENCES_EXTENSION'} = 1; Restart NGINX and goto to the url and sign in. ===== DSPAM Maintenance ===== Pruging via purge-4.1.sql script & possibly using the dspam_maintenance script Copy the purge-4.1.sql script to /opt/var/dspam cp src/tools.mysql_drv/purge-4.1.sql /opt/var/dspam Next create a cron script to run nightly (though weekly possibly okay) nano /etc/cron.daily/dspam.purge #!/bin/sh - PATH=/bin:/sbin:/usr/sbin:/usr/bin:/usr/libexec:/opt/bin export PATH MYSQL=/usr/bin/mysql echo "Purging the Dspam database" $MYSQL -password=A PASSWORD dspam -user=dspam < /opt/var/dspam/purge-4.1.sql Make it executable chmod +x /etc/cron.daily/dspam.purge Also using a user as a tar pit to make corpus for everyone. Finally ===== Other Things ===== ===== Things Missing ===== Jan 21 21:42:37 daffy amavis[2132]: Amavis::DB code loaded Jan 21 21:42:37 daffy amavis[2132]: Amavis::Cache code loaded Jan 21 21:42:37 daffy amavis[2132]: SQL base code NOT loaded Jan 21 21:42:37 daffy amavis[2132]: SQL::Log code NOT loaded Jan 21 21:42:37 daffy amavis[2132]: SQL::Quarantine NOT loaded Jan 21 21:42:37 daffy amavis[2132]: Lookup::SQL code NOT loaded Jan 21 21:42:37 daffy amavis[2132]: Lookup::LDAP code NOT loaded Jan 21 21:42:37 daffy amavis[2132]: AM.PDP-in proto code loaded Jan 21 21:42:37 daffy amavis[2132]: SMTP-in proto code loaded Jan 21 21:42:37 daffy amavis[2132]: Courier proto code NOT loaded Jan 21 21:42:37 daffy amavis[2132]: SMTP-out proto code loaded Jan 21 21:42:37 daffy amavis[2132]: Pipe-out proto code NOT loaded Jan 21 21:42:37 daffy amavis[2132]: BSMTP-out proto code NOT loaded Jan 21 21:42:37 daffy amavis[2132]: Local-out proto code loaded Jan 21 21:42:37 daffy amavis[2132]: OS_Fingerprint code NOT loaded Jan 21 21:42:37 daffy amavis[2132]: ANTI-VIRUS code NOT loaded Jan 21 21:42:37 daffy amavis[2132]: ANTI-SPAM code NOT loaded Jan 21 21:42:37 daffy amavis[2132]: ANTI-SPAM-EXT code NOT loaded Jan 21 21:42:37 daffy amavis[2132]: ANTI-SPAM-C code NOT loaded Jan 21 21:42:37 daffy amavis[2132]: ANTI-SPAM-SA code NOT loaded Jan 21 21:42:37 daffy amavis[2132]: Unpackers code loaded Jan 21 21:42:37 daffy amavis[2132]: DKIM code loaded Jan 21 21:42:37 daffy amavis[2132]: Tools code NOT loaded Jan 21 21:42:37 daffy amavis[2132]: Found $file at /usr/bin/file Jan 21 21:42:37 daffy amavis[2132]: No $altermime, not using it Jan 21 21:42:37 daffy amavis[2132]: Internal decoder for .mail Jan 21 21:42:37 daffy amavis[2132]: No decoder for .F Jan 21 21:42:37 daffy amavis[2132]: Found decoder for .Z at /bin/uncompress Jan 21 21:42:37 daffy amavis[2132]: Internal decoder for .gz Jan 21 21:42:37 daffy amavis[2132]: Found decoder for .bz2 at /bin/bzip2 -d Jan 21 21:42:37 daffy amavis[2132]: No decoder for .lzo tried: lzop -d Jan 21 21:42:37 daffy amavis[2132]: No decoder for .rpm tried: rpm2cpio.pl, rpm2cpio Jan 21 21:42:37 daffy amavis[2132]: Found decoder for .cpio at /usr/bin/pax Jan 21 21:42:37 daffy amavis[2132]: Found decoder for .tar at /usr/bin/pax Jan 21 21:42:37 daffy amavis[2132]: Found decoder for .deb at /usr/bin/ar Jan 21 21:42:37 daffy amavis[2132]: Internal decoder for .zip Jan 21 21:42:37 daffy amavis[2132]: No decoder for .7z tried: 7zr, 7za, 7z Jan 21 21:42:37 daffy amavis[2132]: No decoder for .rar tried: unrar-free Jan 21 21:42:37 daffy amavis[2132]: No decoder for .arj tried: arj, unarj Jan 21 21:42:37 daffy amavis[2132]: No decoder for .arc tried: nomarch, arc Jan 21 21:42:37 daffy amavis[2132]: No decoder for .zoo tried: zoo Jan 21 21:42:37 daffy amavis[2132]: No decoder for .lha Jan 21 21:42:37 daffy amavis[2132]: No decoder for .doc tried: ripole Jan 21 21:42:37 daffy amavis[2132]: No decoder for .cab tried: cabextract Jan 21 21:42:37 daffy amavis[2132]: No decoder for .tnef Jan 21 21:42:37 daffy amavis[2132]: Internal decoder for .tnef Jan 21 21:42:37 daffy amavis[2132]: No decoder for .exe tried: unrar-free; arj, unarj