logo_header

icon_bubbles Forum

icon_bubbles Wiki

icon_bubbles Planet

RootForum Community » Wiki

FreeBSD Hosting System

From RootForum Community » Wiki

Jump to:navigation, search

Contents

Einleitung

Dieses HowTo setzt ein wie in FreeBSD Remote Installation beschriebenes, installiertes und konfiguriertes FreeBSD Basissystem voraus.

Folgende Punkte sind in diesem HowTo zu beachten:

  • Alle Dienste werden mit einem möglichst minimalen und bewährten Funktionsumfang installiert.
  • Alle Dienste werden mit einer möglichst sicheren und dennoch flexiblen Konfiguration versehen.
  • Alle Konfigurationen sind selbstständig auf notwendige individuelle Anpassungen zu kontrollieren.
  • Alle Passworte werden als !!!SECRET!!! dargestellt und sind selbstständig durch sichere Passworte zu ersetzen.
  • Die Domain der virtuellen Maschine lautet example.org und ist selbstständig durch die eigene Domain zu ersetzen.
  • Der Hostname (FQDN) des Servers lautet devnull.example.org und ist selbstständig durch den eigenen Hostnamen zu ersetzen.
  • Postfix und Dovecot teilen sich sowohl den FQDN mail.example.org als auch das SSL-Zertifikat.

Unser Hosting System wird folgende Dienste umfassen:

  • MySQL
  • Postfix
  • Dovecot
  • Apache
  • mod_php

Desweiteren werden wir folgende Applikationen installieren:

  • phpMyAdmin
  • PostfixAdmin
  • RoundCube


OpenSSL

OpenSSL konfigurieren

Sofern noch nicht während der FreeBSD Remote Installation erledigt, müssen folgende Optionen in der /etc/ssl/openssl.cnf im Abschnitt [ req_distinguished_name ] angepasst beziehungsweise ergänzt werden:

[ req_distinguished_name ]
countryName_default             = DE
stateOrProvinceName_default     = Bundesland
localityName_default            = Stadt
0.organizationName_default      = Example Organization
organizationalUnitName_default  = Administration
commonName_default              = devnull.example.org
emailAddress_default            = admin@example.org


OpenSSL CA

Sofern noch nicht während der FreeBSD Remote Installation erledigt, wird als Nächstes ein eigenes CA Zertifikat erstellt und selbst signiert. Dabei verwenden wir devnull.example.org als Common Name und übernehmen ansonsten jeweils die Default-Werte und wählen selbstverständliche sehr sichere Passworte. Die Option A challenge password sollte jedoch leer gelassen werden, andernfalls kann es zu Problemen mit einigen Diensten kommen:

cd /etc/ssl
mkdir -p demoCA
mkdir -p demoCA/certs
mkdir -p demoCA/crl
mkdir -p demoCA/newcerts
mkdir -p demoCA/private
touch demoCA/index.txt

openssl req -new -keyout demoCA/private/cakey.pem -out demoCA/careq.pem
openssl ca -create_serial -out demoCA/cacert.pem -days 3650 -batch -keyfile demoCA/private/cakey.pem -selfsign -extensions v3_ca -infiles demoCA/careq.pem

openssl req -new -keyout devnull.example.org_key.pem -out devnull.example.org_req.pem
openssl ca -policy policy_anything -out devnull.example.org_cert.pem -infiles devnull.example.org_req.pem
openssl rsa -in devnull.example.org_key.pem -out devnull.example.org_keyrsa.pem

cd


OpenSSL Zertifikate

Wir erstellen uns die nachfolgend benötigten selbstsignierten Zertifikate. Dabei verwenden wir für das Mailserver-Zertifikat mail.example.org und für das Webserver-Zertifikat www.example.org als Common Name. Die anderen Fragen beantworten wir jeweils mit den Default-Vorgaben.

cd /etc/ssl
openssl dhparam -out dh_512.pem -2 -rand /dev/urandom 512
openssl dhparam -out dh_1024.pem -2 -rand /dev/urandom 1024

openssl req -new -keyout mail.example.org_key.pem -out mail.example.org_req.pem
openssl ca -policy policy_anything -out mail.example.org_cert.pem -infiles mail.example.org_req.pem
openssl rsa -in mail.example.org_key.pem -out mail.example.org_keyrsa.pem

openssl req -new -keyout www.example.org_key.pem -out www.example.org_req.pem
openssl ca -policy policy_anything -out www.example.org_cert.pem -infiles www.example.org_req.pem
openssl rsa -in www.example.org_key.pem -out www.example.org_keyrsa.pem
cd


MySQL

MySQL unterstützt mehrere Engines, dieses HowTo beschränkt sich allerdings auf die Beiden am Häufigsten verwendeten: MyISAM und InnoDB.

Hinweis: Die Konfiguration wird entsprechend diesem Forenbeitrag durchgeführt.


MySQL installieren

MySQL und seine Dependicies werden mit den Default-Optionen installiert:

portmaster --force-config -dB databases/mysql55-client
portmaster --force-config -dB databases/mysql55-server
rehash

echo 'mysql_enable="YES"' >> /etc/rc.conf


MySQL konfigurieren

cat > /var/db/mysql/my.cnf <<"EOF"
[client]
port                            = 3306

[mysql]
prompt                          = \u@\h [\d]>\_
no_auto_rehash

[mysqld]
user                            = mysql
port                            = 3306
bind-address                    = 127.0.0.1
basedir                         = /usr/local
datadir                         = /var/db/mysql
tmpdir                          = /var/tmp
slave-load-tmpdir               = /var/tmp
log-bin                         = /var/db/mysql/mysql-bin
relay-log                       = /var/db/mysql/relay.log
relay-log-index                 = /var/db/mysql/relay.index
relay-log-info-file             = /var/db/mysql/relay.info
master-info-file                = /var/db/mysql/master.info
#master-host                     = <hostname>
#master-user                     = <username>
#master-password                 = <password>
#master-port                     = 3306
#auto_increment_increment        = 10
#auto_increment_offset           = 1
server-id                       = 1
back_log                        = 50
sync_binlog                     = 1
binlog_cache_size               = 1M
max_binlog_size                 = 100M
binlog-format                   = MIXED
expire_logs_days                = 7
slow-query-log                  = 1
slow-query-log-file             = /var/db/mysql/slow-query.log
slave_compressed_protocol       = 1
lower_case_table_names          = 1
safe-user-create                = 1
delay-key-write                 = ALL
myisam-recover                  = FORCE,BACKUP
key_buffer_size                 = 256M
join_buffer_size                = 2M
sort_buffer_size                = 2M
read_buffer_size                = 2M
read_rnd_buffer_size            = 8M
myisam_sort_buffer_size         = 64M
max_allowed_packet              = 32M
max_heap_table_size             = 64M
tmp_table_size                  = 64M
table_cache                     = 2048
table_definition_cache          = 2048
query_cache_type                = 1
query_cache_size                = 128M
query_cache_limit               = 16M
thread_concurrency              = 8
thread_cache_size               = 20
max_connections                 = 20
ft_max_word_len                 = 20
ft_min_word_len                 = 3
long_query_time                 = 3
local-infile                    = 0
log-warnings                    = 2
log-slave-updates
log-queries-not-using-indexes
skip-external-locking
innodb_thread_concurrency       = 8
innodb_buffer_pool_size         = 2G
innodb_additional_mem_pool_size = 128M
innodb_data_home_dir            = /var/db/mysql
innodb_log_group_home_dir       = /var/db/mysql
innodb_data_file_path           = ibdata1:2000M;ibdata2:10M:autoextend
innodb_flush_method             = O_DIRECT
innodb_log_file_size            = 128M
innodb_log_buffer_size          = 16M
innodb_log_files_in_group       = 2
innodb_flush_log_at_trx_commit  = 2
innodb_max_dirty_pages_pct      = 90
innodb_lock_wait_timeout        = 120
innodb_file_per_table           = 1

[mysqldump]
max_allowed_packet              = 32M
quote_names
quick

[isamchk]
key_buffer_size                 = 256M

[myisamchk]
key_buffer_size                 = 256M

[mysqlhotcopy]
interactive_timeout
"EOF"


MySQL absichern

MySQL wird nun zum ersten Mal gestartet, was durch das Erzeugen der InnoDB-Files einige Minuten dauern und zu einer falschen Fehlermeldung des Init-Scripts führen kann. Daher warten wir bis im tail -f eine Zeile ähnlich der folgenden erscheint und beenden tail mittels ^C (STRG+C).

Version: '5.5.9-log'  socket: '/tmp/mysql.sock'  port: 3306  Source distribution

Abschliessend wird MySQL mittels mysql_secure_installation abgesichert. Hierzu werden alle Fragen, abgesehen vom zuvor gesetztem root-Passwort, jeweils mit einem beherzten Druck auf die Return-Taste beantwortet.

/usr/local/etc/rc.d/mysql-server start

tail -f /var/db/mysql/devnull.example.org.err

mysql_secure_installation


Dovecot

Dovecot wird inklusive MySQL und TLS/SSL Support installiert und für das Zusammenspiel mit PostfixAdmin konfiguriert.


Dovecot installieren

Wir erweitern die Default-Optionen um den MySQL-Support:

portmaster --force-config -dB mail/dovecot
rehash

echo 'dovecot_enable="YES"' >> /etc/rc.conf


Dovecot konfigurieren

dovecot.conf einrichten:

cat > /usr/local/etc/dovecot.conf <<"EOF"
protocols = imap pop3 imaps pop3s
listen = *, [::]
disable_plaintext_auth = no
ssl = yes
ssl_cert_file = /etc/ssl/mail.example.org_cert.pem
ssl_key_file = /etc/ssl/mail.example.org_keyrsa.pem
ssl_cipher_list = RSA:!EXP:!NULL:+HIGH:+MEDIUM:-LOW:-SSLv2
login_process_per_connection = yes
login_processes_count = 3
login_max_processes_count = 128
mail_location = maildir:/usr/local/virtual/%d/%n
mail_privileged_group = mail
dotlock_use_excl = yes
verbose_proctitle = yes
first_valid_uid = 125
last_valid_uid = 125
first_valid_gid = 125
last_valid_gid = 125
maildir_copy_with_hardlinks = yes
protocol imap {
  mail_plugins = quota imap_quota
  imap_client_workarounds = delay-newmail netscape-eoh tb-extra-mailbox-sep
}
protocol pop3 {
  pop3_uidl_format = %08Xu%08Xv
  mail_plugins = quota
  pop3_client_workarounds = outlook-no-nuls oe-ns-eoh
}
protocol lda {
  postmaster_address = postmaster@example.org
  hostname = mail.example.org
  quota_full_tempfail = no
  sendmail_path = /usr/local/sbin/sendmail
}
auth_username_format = %Lu
auth default {
  mechanisms = plain login
  passdb sql {
    args = /usr/local/etc/dovecot-sql.conf
  }
  userdb sql {
    args = /usr/local/etc/dovecot-sql.conf
  }
  user = root
  socket listen {
    master {
      path = /var/run/dovecot/auth-master
      mode = 0600
    }
    client {
      path = /var/spool/postfix/private/auth
      mode = 0660
      user = postfix
      group = postfix
    }
  }
}
dict {
}
plugin {
  quota = maildir
  quota_rule = *:storage=1048576
}
"EOF"

dovecot-sql.conf einrichten:

cat > /usr/local/etc/dovecot-sql.conf <<"EOF"
driver = mysql
connect = host=localhost dbname=postfix user=postfix password=!!!SECRET!!!
default_pass_scheme = MD5-CRYPT
password_query = SELECT password FROM mailbox WHERE username = '%u'
user_query = SELECT maildir, 125 AS uid, 125 AS gid, CONCAT('maildir:storage=', FLOOR( quota / 1024 ) ) AS quota FROM mailbox WHERE username = '%u' AND active = '1'
"EOF"


Postfix

Postfix wird inklusive MySQL, Dovecot-SASL und TLS/SSL Support installiert und für das Zusammenspiel mit PostfixAdmin konfiguriert. Zudem werden die Empfehlungen aus dem Postfix Anti-UCE Cheat Sheet umgesetzt. Zusätzlich wird als gute und recht zuverlässige Anti-Spam Lösung policyd-weight eingerichtet.


policyd-weight installieren

policyd-weight und seine Dependicies werden mit den Default-Optionen installiert:

portmaster --force-config -dB mail/postfix-policyd-weight
rehash

echo 'policyd_weight_enable="YES"' >> /etc/rc.conf


Postfix installieren

Wir aktivieren die Optionen PCRE, DOVECOT, TLS, MySQL und VDA. Den User postfix wollen wir der Gruppe mail hinzufügen lassen und wir wollen Postfix auch in der /etc/mail/mailer.conf aktivieren:

portmaster --force-config -dB mail/postfix
rehash

echo 'postfix_enable="YES"' >> /etc/rc.conf

Als nächstes deaktivieren wir den standardmässig installierten Sendmail vollständig:

sed -e 's/^#sendmail/sendmail/g' /etc/rc.conf > /etc/rc.conf.new
mv -f /etc/rc.conf.new /etc/rc.conf

cat >> /etc/periodic.conf <<"EOF"
daily_clean_hoststat_enable="NO"
daily_status_mail_rejects_enable="NO"
daily_status_include_submit_mailq="NO"
daily_submit_queuerun="NO"
"EOF"


Postfix konfigurieren

Alias für root einrichten:

cat > /etc/mail/aliases << "EOF"
# $FreeBSD: src/etc/mail/aliases,v 1.22.2.1.6.1 2010/12/21 17:09:25 kensmith Exp $
#       @(#)aliases     5.3 (Berkeley) 5/24/90
#
#  Aliases in this file will NOT be expanded in the header from
#  Mail, but WILL be visible over networks.
#
#       >>>>>>>>>>      The program "newaliases" must be run after
#       >> NOTE >>      this file is updated for any changes to
#       >>>>>>>>>>      show through to sendmail.
#
#
# See also RFC 2142, `MAILBOX NAMES FOR COMMON SERVICES, ROLES
# AND FUNCTIONS', May 1997
#       http://tools.ietf.org/html/rfc2142

# Pretty much everything else in this file points to "root", so
# you would do well in either reading root's mailbox or forwarding
# root's email from here.

root:   admin@example.org

# Basic system aliases -- these MUST be present
MAILER-DAEMON: postmaster
postmaster: root

# General redirections for pseudo accounts
_dhcp:  root
_pflogd: root
bin:    root
bind:   root
daemon: root
games:  root
kmem:   root
mailnull: postmaster
man:    root
news:   root
nobody: root
operator: root
pop:    root
proxy:  root
smmsp:  postmaster
sshd:   root
system: root
toor:   root
tty:    root
usenet: news
uucp:   root

# Well-known aliases -- these should be filled in!
# manager:
# dumper:

# BUSINESS-RELATED MAILBOX NAMES
# info:
# marketing:
# sales:
# support:

# NETWORK OPERATIONS MAILBOX NAMES
abuse:  root
# noc:          root
security:       root

# SUPPORT MAILBOX NAMES FOR SPECIFIC INTERNET SERVICES
ftp:            root
ftp-bugs:       ftp
hostmaster:     root
webmaster:      root
www:            webmaster

# NOTE: /var/msgs and /var/msgs/bounds must be owned by sendmail's
#       DefaultUser (defaults to mailnull) for the msgs alias to work.
#
# msgs: "| /usr/bin/msgs -s"

# bit-bucket: /dev/null
# dev-null: bit-bucket
"EOF"

/usr/bin/newaliases

main.cf einrichten:

cat > /usr/local/etc/postfix/main.cf <<"EOF"
allow_percent_hack = no
append_at_myorigin = no
append_dot_mydomain = no
biff = no
broken_sasl_auth_clients = yes
disable_vrfy_command = yes
home_mailbox = .maildir/
mydestination = $myhostname, localhost.$mydomain, localhost
mydomain = example.org
myhostname = mail.$mydomain
mynetworks_style = host
myorigin = $mydomain
proxy_read_maps =
  $local_recipient_maps
  $mydestination
  $virtual_alias_maps
  $virtual_alias_domains
  $virtual_mailbox_maps
  $virtual_mailbox_domains
  $relay_recipient_maps
  $relay_domains
  $canonical_maps
  $sender_canonical_maps
  $recipient_canonical_maps
  $relocated_maps
  $transport_maps
  $mynetworks
  $sender_bcc_maps
  $recipient_bcc_maps
  $smtp_generic_maps
  $lmtp_generic_maps
  $virtual_mailbox_limit_maps
relay_domains = proxy:mysql:/usr/local/etc/postfix/sql/mysql_relay_domains_maps.cf
smtp_tls_ciphers = high
smtp_tls_exclude_ciphers = aNULL, RC4, MD5
smtp_tls_mandatory_ciphers = high
smtp_tls_mandatory_exclude_ciphers = aNULL, RC4, MD5
smtp_tls_mandatory_protocols = SSLv3, TLSv1, !SSLv2
smtp_tls_note_starttls_offer = yes
smtp_tls_protocols = SSLv3, TLSv1, !SSLv2
smtp_tls_security_level = may
smtp_tls_session_cache_database = btree:/var/db/postfix/smtp_scache
smtp_tls_session_cache_timeout = 3600s
smtp_use_tls = yes
smtpd_client_restrictions =
  permit_mynetworks,
  permit_sasl_authenticated,
  reject_unknown_reverse_client_hostname,
  reject_unauth_pipelining,
  permit
smtpd_data_restrictions =
  permit_mynetworks,
  permit_sasl_authenticated,
  reject_unauth_pipelining,
  permit
smtpd_helo_required = yes
smtpd_helo_restrictions =
  permit_mynetworks,
  permit_sasl_authenticated,
  reject_invalid_helo_hostname,
  reject_non_fqdn_helo_hostname,
  reject_unauth_pipelining,
  permit
smtpd_recipient_restrictions =
  permit_mynetworks,
  permit_sasl_authenticated,
  reject_non_fqdn_recipient,
  reject_unknown_recipient_domain,
  check_recipient_mx_access cidr:/usr/local/etc/postfix/mx_access,
  reject_unauth_destination,
  check_recipient_access pcre:/usr/local/etc/postfix/recipient_checks.pcre,
  check_policy_service inet:127.0.0.1:12525,
  reject_unauth_pipelining,
  permit
smtpd_sasl_auth_enable = yes
smtpd_sasl_authenticated_header = yes
smtpd_sasl_path = private/auth
smtpd_sasl_type = dovecot
smtpd_sender_restrictions =
  permit_mynetworks,
  permit_sasl_authenticated,
  reject_non_fqdn_sender,
  reject_unknown_sender_domain,
  reject_unauth_pipelining,
  permit
smtpd_tls_CAfile = /etc/ssl/demoCA/cacert.pem
smtpd_tls_auth_only = yes
smtpd_tls_cert_file = /etc/ssl/mail.example.org_cert.pem
smtpd_tls_ciphers = high
smtpd_tls_dh1024_param_file = /etc/ssl/dh_1024.pem
smtpd_tls_dh512_param_file = /etc/ssl/dh_512.pem
smtpd_tls_exclude_ciphers = aNULL, RC4, MD5
smtpd_tls_key_file = /etc/ssl/mail.example.org_keyrsa.pem
smtpd_tls_mandatory_ciphers = high
smtpd_tls_mandatory_exclude_ciphers = aNULL, RC4, MD5
smtpd_tls_mandatory_protocols = SSLv3, TLSv1, !SSLv2
smtpd_tls_protocols = SSLv3, TLSv1, !SSLv2
smtpd_tls_received_header = yes
smtpd_tls_security_level = may
smtpd_tls_session_cache_database = btree:/var/db/postfix/smtpd_scache
smtpd_tls_session_cache_timeout = 3600s
smtpd_use_tls = yes
strict_rfc821_envelopes = yes
transport_maps = hash:/usr/local/etc/postfix/transport
unknown_local_recipient_reject_code = 450
virtual_minimum_uid = 125
virtual_uid_maps = static:125
virtual_gid_maps = static:125
virtual_mailbox_base = /usr/local/virtual
virtual_mailbox_domains = proxy:mysql:/usr/local/etc/postfix/sql/mysql_virtual_domains_maps.cf
virtual_alias_maps =
   proxy:mysql:/usr/local/etc/postfix/sql/mysql_virtual_alias_maps.cf,
   proxy:mysql:/usr/local/etc/postfix/sql/mysql_virtual_alias_domain_maps.cf,
   proxy:mysql:/usr/local/etc/postfix/sql/mysql_virtual_alias_domain_catchall_maps.cf
virtual_mailbox_maps =
   proxy:mysql:/usr/local/etc/postfix/sql/mysql_virtual_mailbox_maps.cf,
   proxy:mysql:/usr/local/etc/postfix/sql/mysql_virtual_alias_domain_mailbox_maps.cf
virtual_create_maildirsize = yes
virtual_mailbox_extended = yes
virtual_mailbox_limit_maps = mysql:/usr/local/etc/postfix/sql/mysql_virtual_mailbox_limit_maps.cf
virtual_mailbox_limit_override = yes
virtual_overquota_bounce = yes
"EOF"

master.cf einrichten:

cat > /usr/local/etc/postfix/master.cf <<"EOF"
#
# Postfix master process configuration file.  For details on the format
# of the file, see the master(5) manual page (command: "man 5 master").
#
# Do not forget to execute "postfix reload" after editing this file.
#
# ==========================================================================
# service type  private unpriv  chroot  wakeup  maxproc command + args
#               (yes)   (yes)   (yes)   (never) (100)
# ==========================================================================
smtp      inet  n       -       n       -       -       smtpd
submission inet n       -       n       -       -       smtpd
  -o smtpd_tls_security_level=encrypt
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_client_restrictions=permit_sasl_authenticated,reject
  -o milter_macro_daemon_name=ORIGINATING
smtps     inet  n       -       n       -       -       smtpd
  -o smtpd_tls_wrappermode=yes
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_client_restrictions=permit_sasl_authenticated,reject
  -o milter_macro_daemon_name=ORIGINATING
#628       inet  n       -       n       -       -       qmqpd
pickup    fifo  n       -       n       60      1       pickup
cleanup   unix  n       -       n       -       0       cleanup
qmgr      fifo  n       -       n       300     1       qmgr
#qmgr     fifo  n       -       n       300     1       oqmgr
tlsmgr    unix  -       -       n       1000?   1       tlsmgr
rewrite   unix  -       -       n       -       -       trivial-rewrite
bounce    unix  -       -       n       -       0       bounce
defer     unix  -       -       n       -       0       bounce
trace     unix  -       -       n       -       0       bounce
verify    unix  -       -       n       -       1       verify
flush     unix  n       -       n       1000?   0       flush
proxymap  unix  -       -       n       -       -       proxymap
proxywrite unix -       -       n       -       1       proxymap
smtp      unix  -       -       n       -       -       smtp
# When relaying mail as backup MX, disable fallback_relay to avoid MX loops
relay     unix  -       -       n       -       -       smtp
        -o smtp_fallback_relay=
#       -o smtp_helo_timeout=5 -o smtp_connect_timeout=5
showq     unix  n       -       n       -       -       showq
error     unix  -       -       n       -       -       error
retry     unix  -       -       n       -       -       error
discard   unix  -       -       n       -       -       discard
local     unix  -       n       n       -       -       local
virtual   unix  -       n       n       -       -       virtual
lmtp      unix  -       -       n       -       -       lmtp
anvil     unix  -       -       n       -       1       anvil
scache    unix  -       -       n       -       1       scache
#
# ====================================================================
# Interfaces to non-Postfix software. Be sure to examine the manual
# pages of the non-Postfix software to find out what options it wants.
#
# Many of the following services use the Postfix pipe(8) delivery
# agent.  See the pipe(8) man page for information about ${recipient}
# and other message envelope options.
# ====================================================================
#
# maildrop. See the Postfix MAILDROP_README file for details.
# Also specify in main.cf: maildrop_destination_recipient_limit=1
#
#maildrop  unix  -       n       n       -       -       pipe
#  flags=DRhu user=vmail argv=/usr/local/bin/maildrop -d ${recipient}
#
# ====================================================================
#
# Recent Cyrus versions can use the existing "lmtp" master.cf entry.
#
# Specify in cyrus.conf:
#   lmtp    cmd="lmtpd -a" listen="localhost:lmtp" proto=tcp4
#
# Specify in main.cf one or more of the following:
#  mailbox_transport = lmtp:inet:localhost
#  virtual_transport = lmtp:inet:localhost
#
# ====================================================================
#
# Cyrus 2.1.5 (Amos Gouaux)
# Also specify in main.cf: cyrus_destination_recipient_limit=1
#
#cyrus     unix  -       n       n       -       -       pipe
#  user=cyrus argv=/cyrus/bin/deliver -e -r ${sender} -m ${extension} ${user}
#
# ====================================================================
#
# Old example of delivery via Cyrus.
#
#old-cyrus unix  -       n       n       -       -       pipe
#  flags=R user=cyrus argv=/cyrus/bin/deliver -e -m ${extension} ${user}
#
# ====================================================================
#
# See the Postfix UUCP_README file for configuration details.
#
#uucp      unix  -       n       n       -       -       pipe
#  flags=Fqhu user=uucp argv=uux -r -n -z -a$sender - $nexthop!rmail ($recipient)
#
# ====================================================================
#
# Other external delivery methods.
#
#ifmail    unix  -       n       n       -       -       pipe
#  flags=F user=ftn argv=/usr/lib/ifmail/ifmail -r $nexthop ($recipient)
#
#bsmtp     unix  -       n       n       -       -       pipe
#  flags=Fq. user=bsmtp argv=/usr/local/sbin/bsmtp -f $sender $nexthop $recipient
#
#scalemail-backend unix -       n       n       -       2       pipe
#  flags=R user=scalemail argv=/usr/lib/scalemail/bin/scalemail-store
#  ${nexthop} ${user} ${extension}
#
#mailman   unix  -       n       n       -       -       pipe
#  flags=FR user=list argv=/usr/lib/mailman/bin/postfix-to-mailman.py
#  ${nexthop} ${user}
#
"EOF"

mysql_*_maps.cf einrichten:

Hinweis: Bitte jeweils das gleiche Passwort wie in der dovecot-sql.conf aus der Dovecot Konfiguration verwenden.

mkdir -p /usr/local/etc/postfix/sql

cat > /usr/local/etc/postfix/sql/mysql_relay_domains_maps.cf <<"EOF"
user = postfix
password = !!!SECRET!!!
hosts = localhost
dbname = postfix
query = SELECT domain FROM domain WHERE domain = '%s' AND backupmx = '1' AND active = '1'
"EOF"

cat > /usr/local/etc/postfix/sql/mysql_virtual_alias_domain_catchall_maps.cf <<"EOF"
user = postfix
password = !!!SECRET!!!
hosts = localhost
dbname = postfix
query = SELECT goto FROM alias,alias_domain WHERE alias_domain.alias_domain = '%d' and alias.address = CONCAT('@', alias_domain.target_domain) AND alias.active = '1' AND alias_domain.active = '1'
"EOF"

cat > /usr/local/etc/postfix/sql/mysql_virtual_alias_domain_mailbox_maps.cf <<"EOF"
user = postfix
password = !!!SECRET!!!
hosts = localhost
dbname = postfix
query = SELECT maildir FROM mailbox,alias_domain WHERE alias_domain.alias_domain = '%d' and mailbox.username = CONCAT('%u', '@', alias_domain.target_domain) AND mailbox.active = '1' AND alias_domain.active = '1'
"EOF"

cat > /usr/local/etc/postfix/sql/mysql_virtual_alias_domain_maps.cf <<"EOF"
user = postfix
password = !!!SECRET!!!
hosts = localhost
dbname = postfix
query = SELECT goto FROM alias,alias_domain WHERE alias_domain.alias_domain = '%d' and alias.address = CONCAT('%u', '@', alias_domain.target_domain) AND alias.active = '1' AND alias_domain.active = '1'
"EOF"

cat > /usr/local/etc/postfix/sql/mysql_virtual_alias_maps.cf <<"EOF"
user = postfix
password = !!!SECRET!!!
hosts = localhost
dbname = postfix
query = SELECT goto FROM alias WHERE address = '%s' AND active = '1'
"EOF"

cat > /usr/local/etc/postfix/sql/mysql_virtual_domains_maps.cf <<"EOF"
user = postfix
password = !!!SECRET!!!
hosts = localhost
dbname = postfix
query = SELECT domain FROM domain WHERE domain = '%s' AND backupmx = '0' AND active = '1'
"EOF"

cat > /usr/local/etc/postfix/sql/mysql_virtual_mailbox_limit_maps.cf <<"EOF"
user = postfix
password = !!!SECRET!!!
hosts = localhost
dbname = postfix
query = SELECT quota FROM mailbox WHERE username = '%s' AND active = '1'
"EOF"

cat > /usr/local/etc/postfix/sql/mysql_virtual_mailbox_maps.cf <<"EOF"
user = postfix
password = !!!SECRET!!!
hosts = localhost
dbname = postfix
query = SELECT maildir FROM mailbox WHERE username = '%s' AND active = '1'
"EOF"

chown root:postfix /usr/local/etc/postfix/sql/mysql_*_maps.cf
chmod 0640 /usr/local/etc/postfix/sql/mysql_*_maps.cf

Transport map einrichten:

cat >> /usr/local/etc/postfix/transport <<"EOF"
autoreply.example.org   vacation:
"EOF"

postmap /usr/local/etc/postfix/transport

Restriktionen einrichten:

cat > /usr/local/etc/postfix/recipient_checks.pcre <<"EOF"
/^\@/             550 Invalid address format.
/[!%\@].*\@/      550 This server disallows weird address syntax.
/^postmaster\@/   OK
/^hostmaster\@/   OK
/^abuse\@/        OK
"EOF"

cat > /usr/local/etc/postfix/mx_access <<"EOF"
0.0.0.0/8         REJECT Domain MX in broadcast network
10.0.0.0/8        REJECT Domain MX in RFC 1918 private network
127.0.0.0/8       REJECT Domain MX in loopback network
169.254.0.0/16    REJECT Domain MX in link local network
172.16.0.0/12     REJECT Domain MX in RFC 1918 private network
192.0.2.0/24      REJECT Domain MX in TEST-NET network
192.168.0.0/16    REJECT Domain MX in RFC 1918 private network
224.0.0.0/4       REJECT Domain MX in class D multicast network
240.0.0.0/5       REJECT Domain MX in class E reserved network
248.0.0.0/5       REJECT Domain MX in reserved network
"EOF"

postmap /usr/local/etc/postfix/mx_access

Abschliessende Arbeiten:

mkdir -p /usr/local/virtual
chmod 0750 /usr/local/virtual
chown postfix:postfix /usr/local/virtual

Apache

Die folgende Konfiguration verwendet für den Default-Host den Pfad /usr/local/www/vhosts/_default_ und für die regulären Virtual-Hosts den Pfad /usr/local/www/vhosts/sub.domain.tld.


Apache installieren

Apache und seine Dependicies werden mit den Default-Optionen installiert:

portmaster --force-config -dB www/apache22

echo 'apache22_enable="YES"' >> /etc/rc.conf


Apache konfigurieren

Docroots für die Default-Hosts erstellen:

mkdir -p /usr/local/www/vhosts/_default_/logs
mkdir -p /usr/local/www/vhosts/_default_/data
chmod 0750 /usr/local/www/vhosts/_default_/data
chown www:www /usr/local/www/vhosts/_default_/data

mkdir -p /usr/local/www/vhosts/www.example.org/logs
mkdir -p /usr/local/www/vhosts/www.example.org/data
chmod 0750 /usr/local/www/vhosts/www.example.org/data
chown www:www /usr/local/www/vhosts/www.example.org/data

httpd.conf einrichten:

cat > /usr/local/etc/apache22/httpd.conf <<"EOF"
ServerRoot "/usr/local"
PidFile "/var/run/httpd.pid"
LockFile "/var/log/accept.lock"
Timeout 30
KeepAlive On
KeepAliveTimeout 2
MaxKeepAliveRequests 32
<IfModule mpm_prefork_module>
    ServerLimit          256
    StartServers          64
    MinSpareServers        4
    MaxSpareServers        8
    MaxClients           256
    MaxRequestsPerChild  500
</IfModule>
<IfModule mpm_worker_module>
    StartServers           2
    MinSpareThreads       25
    MaxSpareThreads       75
    ThreadsPerChild       25
    MaxClients           150
    MaxRequestsPerChild  500
</IfModule>
Listen *:80
LoadModule authn_file_module libexec/apache22/mod_authn_file.so
#LoadModule authn_dbm_module libexec/apache22/mod_authn_dbm.so
#LoadModule authn_anon_module libexec/apache22/mod_authn_anon.so
LoadModule authn_default_module libexec/apache22/mod_authn_default.so
#LoadModule authn_alias_module libexec/apache22/mod_authn_alias.so
LoadModule authz_host_module libexec/apache22/mod_authz_host.so
LoadModule authz_groupfile_module libexec/apache22/mod_authz_groupfile.so
LoadModule authz_user_module libexec/apache22/mod_authz_user.so
#LoadModule authz_dbm_module libexec/apache22/mod_authz_dbm.so
#LoadModule authz_owner_module libexec/apache22/mod_authz_owner.so
LoadModule authz_default_module libexec/apache22/mod_authz_default.so
LoadModule auth_basic_module libexec/apache22/mod_auth_basic.so
#LoadModule auth_digest_module libexec/apache22/mod_auth_digest.so
#LoadModule file_cache_module libexec/apache22/mod_file_cache.so
LoadModule cache_module libexec/apache22/mod_cache.so
LoadModule disk_cache_module libexec/apache22/mod_disk_cache.so
#LoadModule mem_cache_module libexec/apache22/mod_mem_cache.so
#LoadModule dumpio_module libexec/apache22/mod_dumpio.so
#LoadModule reqtimeout_module libexec/apache22/mod_reqtimeout.so
#LoadModule ext_filter_module libexec/apache22/mod_ext_filter.so
LoadModule include_module libexec/apache22/mod_include.so
#LoadModule filter_module libexec/apache22/mod_filter.so
#LoadModule charset_lite_module libexec/apache22/mod_charset_lite.so
LoadModule deflate_module libexec/apache22/mod_deflate.so
LoadModule log_config_module libexec/apache22/mod_log_config.so
#LoadModule log_forensic_module libexec/apache22/mod_log_forensic.so
#LoadModule logio_module libexec/apache22/mod_logio.so
LoadModule env_module libexec/apache22/mod_env.so
#LoadModule mime_magic_module libexec/apache22/mod_mime_magic.so
#LoadModule cern_meta_module libexec/apache22/mod_cern_meta.so
LoadModule expires_module libexec/apache22/mod_expires.so
LoadModule headers_module libexec/apache22/mod_headers.so
#LoadModule usertrack_module libexec/apache22/mod_usertrack.so
LoadModule unique_id_module libexec/apache22/mod_unique_id.so
LoadModule setenvif_module libexec/apache22/mod_setenvif.so
#LoadModule version_module libexec/apache22/mod_version.so
#LoadModule proxy_module libexec/apache22/mod_proxy.so
#LoadModule proxy_connect_module libexec/apache22/mod_proxy_connect.so
#LoadModule proxy_ftp_module libexec/apache22/mod_proxy_ftp.so
#LoadModule proxy_http_module libexec/apache22/mod_proxy_http.so
#LoadModule proxy_scgi_module libexec/apache22/mod_proxy_scgi.so
#LoadModule proxy_balancer_module libexec/apache22/mod_proxy_balancer.so
LoadModule ssl_module libexec/apache22/mod_ssl.so
LoadModule mime_module libexec/apache22/mod_mime.so
#LoadModule dav_module libexec/apache22/mod_dav.so
LoadModule status_module libexec/apache22/mod_status.so
LoadModule autoindex_module libexec/apache22/mod_autoindex.so
#LoadModule asis_module libexec/apache22/mod_asis.so
LoadModule info_module libexec/apache22/mod_info.so
#LoadModule suexec_module libexec/apache22/mod_suexec.so
LoadModule cgi_module libexec/apache22/mod_cgi.so
#LoadModule cgid_module libexec/apache22/mod_cgid.so
#LoadModule dav_fs_module libexec/apache22/mod_dav_fs.so
#LoadModule vhost_alias_module libexec/apache22/mod_vhost_alias.so
#LoadModule negotiation_module libexec/apache22/mod_negotiation.so
LoadModule dir_module libexec/apache22/mod_dir.so
#LoadModule imagemap_module libexec/apache22/mod_imagemap.so
LoadModule actions_module libexec/apache22/mod_actions.so
#LoadModule speling_module libexec/apache22/mod_speling.so
#LoadModule userdir_module libexec/apache22/mod_userdir.so
LoadModule alias_module libexec/apache22/mod_alias.so
LoadModule rewrite_module libexec/apache22/mod_rewrite.so
LoadModule php5_module        libexec/apache22/libphp5.so
User www
Group www
ServerTokens OS
ServerSignature On
UseCanonicalName On
TraceEnable Off
<Directory "/">
    Options -All +FollowSymLinks
    AllowOverride None
    Order Deny,Allow
    Deny from all
</Directory>
ServerName devnull.examble.org
ServerAdmin webmaster@examble.org
DocumentRoot "/usr/local/www/vhosts/_default_/data"
<Directory "/usr/local/www/vhosts/_default_/data">
    Options -All +FollowSymLinks +ExecCGI
    AllowOverride Options FileInfo AuthConfig Limit
    Order Allow,Deny
    Allow from all
</Directory>
DirectoryIndex index.html index.htm index.php
AccessFileName .htaccess
<FilesMatch "^[\._]">
    Order Allow,Deny
    Deny from all
</FilesMatch>
TypesConfig "/usr/local/etc/apache22/mime.types"
DefaultType text/plain
<IfModule mime_magic_module>
    MIMEMagicFile "/usr/local/etc/apache22/magic"
</IfModule>
HostnameLookups On
<IfModule logio_module>
    LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio
</IfModule>
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%h %l %u %t \"%r\" %>s %b" common
CustomLog "/usr/local/www/vhosts/_default_/logs/access_log" combined
ErrorLog "/usr/local/www/vhosts/_default_/logs/error_log"
LogLevel warn
<IfModule cgid_module>
    Scriptsock "/var/run/cgisock"
</IfModule>
ReadmeName README.html
HeaderName HEADER.html
IndexOptions FancyIndexing VersionSort FoldersFirst IgnoreCase IgnoreClient NameWidth=* SuppressDescription XHTML
IndexIgnore .??* *~ *# HEADER* README* RCS CVS *,v *,t .svn
IndexOrderDefault Ascending Name
Alias "/icons/" "/usr/local/www/apache22/icons/"
<Directory "/usr/local/www/apache22/icons">
    Options -All +MultiViews
    AllowOverride None
    Order Allow,Deny
    Allow from all
</Directory>
AddIconByEncoding (CMP,/icons/compressed.gif) x-compress x-gzip
AddIconByType (TXT,/icons/text.gif) text/*
AddIconByType (IMG,/icons/image2.gif) image/*
AddIconByType (SND,/icons/sound2.gif) audio/*
AddIconByType (VID,/icons/movie.gif) video/*
AddIcon /icons/binary.gif .bin .exe
AddIcon /icons/binhex.gif .hqx
AddIcon /icons/tar.gif .tar
AddIcon /icons/world2.gif .wrl .wrl.gz .vrml .vrm .iv
AddIcon /icons/compressed.gif .Z .z .tgz .gz .zip
AddIcon /icons/a.gif .ps .ai .eps
AddIcon /icons/layout.gif .html .shtml .htm .pdf
AddIcon /icons/text.gif .txt
AddIcon /icons/c.gif .c
AddIcon /icons/p.gif .pl .py
AddIcon /icons/f.gif .for
AddIcon /icons/dvi.gif .dvi
AddIcon /icons/uuencoded.gif .uu
AddIcon /icons/script.gif .conf .sh .shar .csh .ksh .tcl
AddIcon /icons/tex.gif .tex
AddIcon /icons/bomb.gif core
AddIcon /icons/back.gif ..
AddIcon /icons/hand.right.gif README
AddIcon /icons/folder.gif ^^DIRECTORY^^
AddIcon /icons/blank.gif ^^BLANKICON^^
DefaultIcon /icons/unknown.gif
AddDefaultCharset utf-8
AddCharset utf-8 .html .css .js .xml .json .atom .rss
AddType application/x-httpd-php-source phps
AddType application/x-httpd-php        php
AddType application/x-gzip             gz tgz
AddType application/x-compress         Z
AddType audio/ogg                      oga ogg
AddType video/ogg                      ogv
AddType video/mp4                      mp4
AddType video/webm                     webm
AddType image/svg+xml                  svg svgz
AddEncoding gzip                       svgz
AddType application/vnd.ms-fontobject  eot
AddType font/truetype                  ttf
AddType font/opentype                  otf
AddType application/x-font-woff        woff
AddType image/x-icon                   ico
AddType image/webp                     webp
AddType text/cache-manifest            appcache manifest
AddType text/x-component               htc
AddType application/x-chrome-extension crx
AddType application/x-xpinstall        xpi
AddType application/octet-stream       safariextz
AddType text/html                      shtml
AddOutputFilter INCLUDES .shtml
AddHandler php5-script .php .phps
AddHandler cgi-script .cgi .pl
<FilesMatch "favicon\.ico$">
    AddType image/vnd.microsoft.icon .ico
</FilesMatch>
<IfModule setenvif_module>
    <IfModule headers_module>
        BrowserMatch "MSIE" ie
        Header set X-UA-Compatible "IE=Edge;chrome=1" env=ie
    </IfModule>
</IfModule>
<IfModule headers_module>
    Header append Vary User-Agent
</IfModule>
<IfModule deflate_module>
    <IfModule setenvif_module>
        <IfModule headers_module>
            SetEnvIfNoCase ^(Accept-EncodXng|X-cept-Encoding|X{15}|~{15}|-{15})$ ^((gzip|deflate)\s,?\s(gzip|deflate)?|X{4,13}|~{4,13}|-{4,13})$ HAVE_Accept-Encoding
            RequestHeader append Accept-Encoding "gzip,deflate" env=HAVE_Accept-Encoding
        </IfModule>
    </IfModule>
    <IfModule filter_module>
        FilterDeclare   COMPRESS
        FilterProvider  COMPRESS  DEFLATE resp=Content-Type /text/(html|css|javascript|plain|x(ml|-component))/
        FilterProvider  COMPRESS  DEFLATE resp=Content-Type /application/(javascript|json|xml|x-javascript)/
        FilterChain     COMPRESS
        FilterProtocol  COMPRESS  change=yes;byteranges=no
    </IfModule>
    <IfModule !filter_module>
        AddOutputFilterByType DEFLATE text/html text/plain text/css application/json
        AddOutputFilterByType DEFLATE text/javascript application/javascript application/x-javascript
        AddOutputFilterByType DEFLATE text/xml application/xml text/x-component
    </IfModule>
    <FilesMatch "\.(ttf|otf|eot|svg)$">
        SetOutputFilter DEFLATE
    </FilesMatch>
</IfModule>
<IfModule expires_module>
    ExpiresActive on
    ExpiresDefault                          "access plus 1 month"
    ExpiresByType text/cache-manifest       "access plus 0 seconds"
    ExpiresByType text/html                 "access plus 0 seconds"
    ExpiresByType text/xml                  "access plus 0 seconds"
    ExpiresByType application/xml           "access plus 0 seconds"
    ExpiresByType application/json          "access plus 0 seconds"
    ExpiresByType application/rss+xml       "access plus 1 hour"
    ExpiresByType image/x-icon              "access plus 1 week"
    ExpiresByType image/gif                 "access plus 1 month"
    ExpiresByType image/png                 "access plus 1 month"
    ExpiresByType image/jpg                 "access plus 1 month"
    ExpiresByType image/jpeg                "access plus 1 month"
    ExpiresByType video/ogg                 "access plus 1 month"
    ExpiresByType audio/ogg                 "access plus 1 month"
    ExpiresByType video/mp4                 "access plus 1 month"
    ExpiresByType video/webm                "access plus 1 month"
    ExpiresByType text/x-component          "access plus 1 month"
    ExpiresByType font/truetype             "access plus 1 month"
    ExpiresByType font/opentype             "access plus 1 month"
    ExpiresByType application/x-font-woff   "access plus 1 month"
    ExpiresByType image/svg+xml             "access plus 1 month"
    ExpiresByType application/vnd.ms-fontobject "access plus 1 month"
    ExpiresByType image/vnd.microsoft.icon  "access plus 2 months"
    ExpiresByType text/css                  "access plus 2 months"
    ExpiresByType application/javascript    "access plus 2 months"
    ExpiresByType text/javascript           "access plus 2 months"
    <IfModule headers_module>
        Header append Cache-Control "public"
    </IfModule>
</IfModule>
FileETag None
<IfModule headers_module>
    Header unset ETag
</IfModule>
<IfModule setenvif_module>
    BrowserMatch "MSIE" brokenvary=1
    BrowserMatch "Mozilla/4.[0-9]{2}" brokenvary=1
    BrowserMatch "Opera" !brokenvary
    SetEnvIf brokenvary 1 force-no-vary
</IfModule>
<IfModule dav_module>
    <IfModule dav_fs_module>
        DavLockDB "/var/db/dav/lockdb"
        Alias "/uploads/" "/usr/local/www/uploads/"
        <Directory "/usr/local/www/uploads">
            Dav On
            AuthType Digest
            AuthName DAV-upload
            AuthUserFile "/usr/local/www/.htpasswd-dav"
            Order allow,deny
            Allow from all
            <LimitExcept GET OPTIONS>
                require user admin
            </LimitExcept>
        </Directory>
    </IfModule>
</IfModule>
<IfModule cache_module>
    <IfModule mem_cache_module>
        CacheEnable mem "/"
        MCacheSize 131072
        MCacheMaxObjectCount 1000
        MCacheMinObjectSize 1
        MCacheMaxObjectSize 2048
    </IfModule>
    <IfModule disk_cache_module>
        CacheRoot "/usr/local/www/cache/"
        CacheEnable disk "/"
        CacheDirLevels 2
        CacheDirLength 1
    </IfModule>
</IfModule>
<IfModule userdir_module>
    UserDir public_html
    UserDir disabled root toor daemon operator bin tty kmem games news man sshd bind proxy _pflogd _dhcp uucp pop www nobody mailnull smmsp admin
    <Directory "/home/*/public_html">
        AllowOverride FileInfo AuthConfig Limit Indexes
        Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
        <Limit GET POST OPTIONS>
            Order Allow,Deny
            Allow from all
        </Limit>
        <LimitExcept GET POST OPTIONS>
            Order Deny,Allow
            Deny from all
        </LimitExcept>
    </Directory>
</IfModule>
<IfModule info_module>
    <IfModule status_module>
        <Location "/server-status">
            SetHandler server-status
            Order Deny,Allow
            Deny from all
            Allow from localhost
        </Location>
        ExtendedStatus On
        <Location "/server-info">
            SetHandler server-info
            Order Deny,Allow
            Deny from all
            Allow from localhost
        </Location>
    </IfModule>
</IfModule>
NameVirtualHost *:80
<VirtualHost *:80>
    ServerName devnull.examble.org
    CustomLog "/usr/local/www/vhosts/_default_/logs/access_log" combined
    ErrorLog "/usr/local/www/vhosts/_default_/logs/error_log"
    DocumentRoot "/usr/local/www/vhosts/_default_/data"
    <Directory "/usr/local/www/vhosts/_default_/data">
        Options -All +FollowSymLinks +ExecCGI
        AllowOverride Options FileInfo AuthConfig Limit
        Order Allow,Deny
        Allow from all
    </Directory>
    AcceptPathInfo On
</VirtualHost>
<IfModule ssl_module>
    Listen *:443
    NameVirtualHost *:443
    SSLStrictSNIVHostCheck On
    AddType application/x-x509-ca-cert .crt
    AddType application/x-pkcs7-crl .crl
    SSLRandomSeed startup builtin
    SSLRandomSeed connect builtin
    SSLPassPhraseDialog builtin
    SSLSessionCache "shmcb:/var/run/ssl_scache(512000)"
    SSLSessionCacheTimeout 300
    SSLMutex "file:/var/run/ssl_mutex"
    <VirtualHost *:443>
        ServerName devnull.examble.org
        CustomLog "/usr/local/www/vhosts/_default_/logs/ssl_request_log" "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" $
        TransferLog "/usr/local/www/vhosts/_default_/logs/ssl_access_log"
        ErrorLog "/usr/local/www/vhosts/_default_/logs/ssl_error_log"
        DocumentRoot "/usr/local/www/vhosts/_default_/data"
        <Directory "/usr/local/www/vhosts/_default_/data">
            Options -All +FollowSymLinks +ExecCGI
            AllowOverride Options FileInfo AuthConfig Limit
            Order Allow,Deny
            Allow from all
        </Directory>
        SSLEngine on
        SSLProtocol all -SSLv2
        SSLCipherSuite RSA:!EXP:!NULL:+HIGH:+MEDIUM:-LOW:-SSLv2
        SSLCertificateFile "/etc/ssl/devnull.examble.org_cert.pem"
        SSLCertificateKeyFile "/etc/ssl/devnull.examble.org_keyrsa.pem"
        <FilesMatch "\.(phps|php|pl|py|cgi|shtml)$">
            SSLOptions +StdEnvVars
        </FilesMatch>
        BrowserMatch ".*MSIE.*" nokeepalive ssl-unclean-shutdown downgrade-1.0 force-response-1.0
        AcceptPathInfo On
    </VirtualHost>
</IfModule>
<VirtualHost *:80>
    ServerName www.examble.org
    CustomLog "/usr/local/www/vhosts/www.examble.org/logs/access_log" combined
    ErrorLog "/usr/local/www/vhosts/www.examble.org/logs/error_log"
    DocumentRoot "/usr/local/www/vhosts/www.examble.org/data"
    <Directory "/usr/local/www/vhosts/www.examble.org/data">
        Options -All +FollowSymLinks +ExecCGI
        AllowOverride Options FileInfo AuthConfig Limit
        Order Allow,Deny
        Allow from all
    </Directory>
    AcceptPathInfo On
</VirtualHost>
<IfModule ssl_module>
    <VirtualHost *:443>
        ServerName www.examble.org
        CustomLog "/usr/local/www/vhosts/www.examble.org/logs/ssl_request_log" "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" $
        TransferLog "/usr/local/www/vhosts/www.examble.org/logs/ssl_access_log"
        ErrorLog "/usr/local/www/vhosts/www.examble.org/logs/ssl_error_log"
        DocumentRoot "/usr/local/www/vhosts/www.examble.org/data"
        <Directory "/usr/local/www/vhosts/www.examble.org/data">
            Options -All +FollowSymLinks +ExecCGI
            AllowOverride Options FileInfo AuthConfig Limit
            Order Allow,Deny
            Allow from all
        </Directory>
        SSLEngine on
        SSLProtocol all -SSLv2
        SSLCipherSuite RSA:!EXP:!NULL:+HIGH:+MEDIUM:-LOW:-SSLv2
        SSLCertificateFile "/etc/ssl/www.examble.org_cert.pem"
        SSLCertificateKeyFile "/etc/ssl/www.examble.org_keyrsa.pem"
        <FilesMatch "\.(phps|php|pl|py|cgi|shtml)$">
            SSLOptions +StdEnvVars
        </FilesMatch>
        BrowserMatch ".*MSIE.*" nokeepalive ssl-unclean-shutdown downgrade-1.0 force-response-1.0
        AcceptPathInfo On
    </VirtualHost>
</IfModule>
<IfDefine NOHTTPACCEPT>
    AcceptFilter http none
    AcceptFilter https none
</IfDefine>
"EOF"


PHP

Die Konfiguration entspricht weitestgehend den Empfehlungen der PHP-Entwickler und ist somit sowohl auf Security als auch auf Performance getrimmt.


PHP installieren

Wir aktivieren zusätzlich zu den Default-Optionen die Optionen APACHE, MULTIBYTE und MAILHEAD. Die Dependicies werden mit den Default-Optionen installiert:

portmaster --force-config -dB lang/php5


PHP-Extensions installieren

Wir aktivieren alle Extensions ausser FRIBIDI, INTERBASE, LDAP, MSSQL, ODBC, PGSQL, PSPELL, READLINE, RECODE, SNMP, SYBASE_CT, TIDY und YAZ. Für php5-sqlite aktivieren wir UTF8, für curl aktivieren wir zusätzlich LIBIDN und LIBSSH2 und für cclient aktivieren wir zusätzlich SSL_AND_PLAINTEXT. Die restlichen Dependicies werden mit den Default-Optionen installiert:

portmaster --force-config -dB lang/php5-extensions


PHP konfigurieren

php.ini einrichten:

cat > /usr/local/etc/php.ini <<"EOF"
[PHP]
user_ini.filename =
user_ini.cache_ttl = 300
engine = On
short_open_tag = Off
asp_tags = Off
precision = 14
y2k_compliance = On
output_buffering = 4096
output_handler =
zlib.output_compression = Off
zlib.output_compression_level = -1
zlib.output_handler =
implicit_flush = Off
unserialize_callback_func =
serialize_precision = 100
allow_call_time_pass_reference = Off
safe_mode = Off
safe_mode_gid = Off
safe_mode_include_dir =
safe_mode_exec_dir =
safe_mode_allowed_env_vars = PHP_
safe_mode_protected_env_vars = LD_LIBRARY_PATH
open_basedir =
disable_functions =
disable_classes =
highlight.string = #DD0000
highlight.comment = #FF9900
highlight.keyword = #007700
highlight.bg = #FFFFFF
highlight.default = #0000BB
highlight.html = #000000
ignore_user_abort = Off
realpath_cache_size = 16k
realpath_cache_ttl = 120
expose_php = Off
max_execution_time = 30
max_input_time = 60
max_input_nesting_level = 64
memory_limit = 128M
error_reporting = E_ALL & ~E_DEPRECATED
display_errors = Off
display_startup_errors = Off
log_errors = On
log_errors_max_len = 1024
ignore_repeated_errors = Off
ignore_repeated_source = Off
report_memleaks = On
;report_zend_debug = 0
track_errors = Off
;xmlrpc_errors = 0
;xmlrpc_error_number = 0
html_errors = Off
;docref_root = "/phpmanual/"
;docref_ext = .html
;error_prepend_string = "<font color=#ff0000>"
;error_append_string = "</font>"
;error_log = php_errors.log
arg_separator.output = "&"
arg_separator.input = ";&"
variables_order = "GPCS"
request_order = "GP"
register_globals = Off
register_long_arrays = Off
register_argc_argv = Off
auto_globals_jit = On
post_max_size = 8M
magic_quotes_gpc = Off
magic_quotes_runtime = Off
magic_quotes_sybase = Off
auto_prepend_file =
auto_append_file =
default_mimetype = "text/html"
;default_charset = "iso-8859-1"
;always_populate_raw_post_data = On
include_path = ".:/usr/local/share/php:/usr/local/share/pear"
doc_root =
user_dir =
;extension_dir = "ext"
enable_dl = Off
cgi.force_redirect = 1
;cgi.nph = 1
;cgi.redirect_status_env = ;
cgi.fix_pathinfo=1
;fastcgi.impersonate = 1;
;fastcgi.logging = 0
;cgi.rfc2616_headers = 0
file_uploads = On
upload_tmp_dir = "/tmp"
upload_max_filesize = 2M
max_file_uploads = 20
allow_url_fopen = On
allow_url_include = Off
from = "anonymous@example.com"
user_agent = ""
default_socket_timeout = 60
;auto_detect_line_endings = Off

[Date]
date.timezone = Europe/Berlin
;date.default_latitude = 31.7667
;date.default_longitude = 35.2333
;date.sunrise_zenith = 90.583333
;date.sunset_zenith = 90.583333

[filter]
;filter.default = unsafe_raw
;filter.default_flags =

[iconv]
;iconv.input_encoding = ISO-8859-1
;iconv.internal_encoding = ISO-8859-1
;iconv.output_encoding = ISO-8859-1

[intl]
;intl.default_locale =
;intl.error_level = E_WARNING

[sqlite]
;sqlite.assoc_case = 0

[sqlite3]
;sqlite3.extension_dir =

[Pcre]
;pcre.backtrack_limit = 100000
;pcre.recursion_limit = 100000

[Pdo]
;pdo_odbc.connection_pooling = strict
;pdo_odbc.db2_instance_name =

[Pdo_mysql]
pdo_mysql.cache_size = 2000
pdo_mysql.default_socket =

[Phar]
;phar.readonly = On
;phar.require_hash = On
;phar.cache_list =

[Syslog]
define_syslog_variables  = Off

[mail function]
SMTP = localhost
smtp_port = 25
;sendmail_from = me@example.com
;sendmail_path =
;mail.force_extra_parameters =
mail.add_x_header = On
;mail.log =

[SQL]
sql.safe_mode = Off

[ODBC]
;odbc.default_cursortype =
odbc.allow_persistent = On
odbc.check_persistent = On
odbc.max_persistent = -1
odbc.max_links = -1
odbc.defaultlrl = 4096
odbc.defaultbinmode = 1
;birdstep.max_links = -1

[Interbase]
ibase.allow_persistent = 1
ibase.max_persistent = -1
ibase.max_links = -1
;ibase.default_db =
;ibase.default_user =
;ibase.default_password =
;ibase.default_charset =
ibase.timestampformat = "%Y-%m-%d %H:%M:%S"
ibase.dateformat = "%Y-%m-%d"
ibase.timeformat = "%H:%M:%S"

[MySQL]
mysql.allow_local_infile = On
mysql.allow_persistent = On
mysql.cache_size = 2000
mysql.max_persistent = -1
mysql.max_links = -1
mysql.default_port =
mysql.default_socket =
mysql.default_host =
mysql.default_user =
mysql.default_password =
mysql.connect_timeout = 60
mysql.trace_mode = Off

[MySQLi]
mysqli.max_persistent = -1
mysqli.allow_local_infile = On
mysqli.allow_persistent = On
mysqli.max_links = -1
mysqli.cache_size = 2000
mysqli.default_port = 3306
mysqli.default_socket =
mysqli.default_host =
mysqli.default_user =
mysqli.default_pw =
mysqli.reconnect = Off

[mysqlnd]
mysqlnd.collect_statistics = On
mysqlnd.collect_memory_statistics = Off
;mysqlnd.net_cmd_buffer_size = 2048
;mysqlnd.net_read_buffer_size = 32768

[OCI8]
;oci8.privileged_connect = Off
;oci8.max_persistent = -1
;oci8.persistent_timeout = -1
;oci8.ping_interval = 60
;oci8.connection_class =
;oci8.events = Off
;oci8.statement_cache_size = 20
;oci8.default_prefetch = 100
;oci8.old_oci_close_semantics = Off

[PostgresSQL]
pgsql.allow_persistent = On
pgsql.auto_reset_persistent = Off
pgsql.max_persistent = -1
pgsql.max_links = -1
pgsql.ignore_notice = 0
pgsql.log_notice = 0

[Sybase-CT]
sybct.allow_persistent = On
sybct.max_persistent = -1
sybct.max_links = -1
sybct.min_server_severity = 10
sybct.min_client_severity = 10
;sybct.timeout =
;sybct.packet_size =
;sybct.login_timeout =
;sybct.hostname =
;sybct.deadlock_retry_count =

[bcmath]
bcmath.scale = 0

[browscap]
;browscap = extra/browscap.ini

[Session]
session.save_handler = files
session.save_path = "/tmp"
session.use_cookies = 1
;session.cookie_secure =
session.use_only_cookies = 1
session.name = PHPSESSID
session.auto_start = 0
session.cookie_lifetime = 0
session.cookie_path = /
session.cookie_domain =
session.cookie_httponly =
session.serialize_handler = php
session.gc_probability = 1
session.gc_divisor = 1000
session.gc_maxlifetime = 1440
session.bug_compat_42 = Off
session.bug_compat_warn = Off
session.referer_check =
session.entropy_file = /dev/urandom
session.entropy_length = 16
session.cache_limiter = nocache
session.cache_expire = 180
session.use_trans_sid = 0
session.hash_function = 1
session.hash_bits_per_character = 6
url_rewriter.tags = "a=href,area=href,frame=src,input=src,form=fakeentry,fieldset="

[MSSQL]
mssql.allow_persistent = On
mssql.max_persistent = -1
mssql.max_links = -1
mssql.min_error_severity = 10
mssql.min_message_severity = 10
mssql.compatability_mode = Off
;mssql.connect_timeout = 5
;mssql.timeout = 60
;mssql.textlimit = 4096
;mssql.textsize = 4096
;mssql.batchsize = 0
;mssql.datetimeconvert = On
mssql.secure_connection = Off
;mssql.max_procs = -1
;mssql.charset = "ISO-8859-1"

[Assertion]
;assert.active = On
;assert.warning = On
;assert.bail = Off
;assert.callback = 0
;assert.quiet_eval = 0

[COM]
;com.typelib_file =
;com.allow_dcom = true
;com.autoregister_typelib = true
;com.autoregister_casesensitive = false
;com.autoregister_verbose = true
;com.code_page =

[mbstring]
;mbstring.language = Japanese
;mbstring.internal_encoding = EUC-JP
;mbstring.http_input = auto
;mbstring.http_output = SJIS
;mbstring.encoding_translation = Off
;mbstring.detect_order = auto
;mbstring.substitute_character = none;
;mbstring.func_overload = 0
;mbstring.strict_detection = Off
;mbstring.http_output_conv_mimetype =
;mbstring.script_encoding =

[gd]
;gd.jpeg_ignore_warning = 0

[exif]
;exif.encode_unicode = ISO-8859-15
;exif.decode_unicode_motorola = UCS-2BE
;exif.decode_unicode_intel = UCS-2LE
;exif.encode_jis =
;exif.decode_jis_motorola = JIS
;exif.decode_jis_intel = JIS

[Tidy]
;tidy.default_config = /usr/local/lib/php/default.tcfg
tidy.clean_output = Off

[soap]
soap.wsdl_cache_enabled = 1
soap.wsdl_cache_dir = "/tmp"
soap.wsdl_cache_ttl = 86400
soap.wsdl_cache_limit = 5

[sysvshm]
;sysvshm.init_mem = 10000

[ldap]
ldap.max_links = -1

[mcrypt]
;mcrypt.algorithms_dir =
;mcrypt.modes_dir =

[dba]
;dba.default_handler =
"EOF"


PHP-PEAR installieren

portmaster --force-config -dB devel/pear


phpMyAdmin

phpMyAdmin installieren

fetch ftp://ftp.mirrorservice.org/sites/download.sourceforge.net/pub/sourceforge/p/project/ph/phpmyadmin/phpMyAdmin/3.3.6/phpMyAdmin-3.3.6-all-languages.tar.gz

tar xzf phpMyAdmin-3.3.6-all-languages.tar.gz
mv phpMyAdmin-3.3.6-all-languages /usr/local/www/vhosts/www.examble.org/data/phpmyadmin
mkdir -p /usr/local/www/vhosts/www.examble.org/data/phpmyadmin/save
mkdir -p /usr/local/www/vhosts/www.examble.org/data/phpmyadmin/upload
chown -R www:www /usr/local/www/vhosts/www.examble.org/data/phpmyadmin
find /usr/local/www/vhosts/www.examble.org/data/phpmyadmin -type d -print0 | xargs -0 chmod 0750
find /usr/local/www/vhosts/www.examble.org/data/phpmyadmin -type f -print0 | xargs -0 chmod 0640


phpMyAdmin konfigurieren

mkdir -p /usr/local/www/vhosts/www.examble.org/data/phpmyadmin/config
chown www:www /usr/local/www/vhosts/www.examble.org/data/phpmyadmin/config

Nun bitte https://www.examble.org/phpmyadmin/setup/index.php im Browser aufrufen und phpMyAdmin konfigurieren. Danach muss die config.inc.php noch installiert werden:

mv /usr/local/www/vhosts/www.examble.org/data/phpmyadmin/config/config.inc.php /usr/local/www/vhosts/www.examble.org/data/phpmyadmin/config.inc.php
chmod 0640 /usr/local/www/vhosts/www.examble.org/data/phpmyadmin/config.inc.php
rm -r /usr/local/www/vhosts/www.examble.org/data/phpmyadmin/config


PostfixAdmin

PostfixAdmin installieren

fetch ftp://ftp.mirrorservice.org/sites/download.sourceforge.net/pub/sourceforge/p/project/po/postfixadmin/postfixadmin/postfixadmin-2.3.2/postfixadmin-2.3.2.tar.gz

tar xzf postfixadmin-2.3.2.tar.gz
mv postfixadmin-2.3.2 /usr/local/www/vhosts/www.examble.org/data/postfixadmin
chown -R www:www /usr/local/www/vhosts/www.examble.org/data/postfixadmin
find /usr/local/www/vhosts/www.examble.org/data/postfixadmin -type d -print0 | xargs -0 chmod 0750
find /usr/local/www/vhosts/www.examble.org/data/postfixadmin -type f -print0 | xargs -0 chmod 0640

Anlegen der Datenbank und der Datenbank-User:

Hinweis: Bitte jeweils das gleiche Passwort wie in der dovecot-sql.conf aus der Dovecot Konfiguration verwenden.

mysql -uroot -p
CREATE DATABASE postfix DEFAULT CHARACTER SET utf8;
GRANT ALL PRIVILEGES ON postfix.* TO 'postfix'@'localhost' IDENTIFIED BY '!!!SECRET!!!';
GRANT ALL PRIVILEGES ON postfix.* TO 'postfixadmin'@'localhost' IDENTIFIED BY '!!!SECRET!!!';
FLUSH PRIVILEGES;
QUIT;


PostfixAdmin konfigurieren

Anlegen der config.local.php:

cat > /usr/local/www/vhosts/www.examble.org/data/postfixadmin/config.local.php <<"EOF"
<?php
$CONF['configured'] = true;
$CONF['postfix_admin_url'] = 'https://www.examble.org/postfixadmin/';
$CONF['database_type'] = 'mysqli';
$CONF['database_password'] = '!!!SECRET!!!'; // Password of database-user postfix
$CONF['admin_email'] = 'postmaster@example.org';
$CONF['min_password_length'] = 8;
$CONF['default_aliases'] = array (
    'abuse' => 'abuse@example.org',
    'admin' => 'admin@example.org',
    'hostmaster' => 'hostmaster@example.org',
    'postmaster' => 'postmaster@example.org',
    'webmaster' => 'webmaster@example.org'
);
$CONF['domain_path'] = 'YES';
$CONF['domain_in_mailbox'] = 'NO';
$CONF['aliases'] = '50';
$CONF['mailboxes'] = '50';
$CONF['maxquota'] = '1024';
$CONF['quota'] = 'YES';
$CONF['quota_multiplier'] = '1048576';
$CONF['vacation_domain'] = 'autoreply.example.org';
$CONF['alias_control'] = 'YES';
$CONF['alias_control_admin'] = 'YES';
$CONF['fetchmail'] = 'NO';
$CONF['user_footer_link'] = "http://www.example.org/";
$CONF['show_footer_text'] = 'YES';
$CONF['footer_text'] = 'Return to Homepage';
$CONF['footer_link'] = 'http://www.example.org';
$CONF['show_status'] = 'YES';
$CONF['show_status_key'] = 'YES';
"EOF"

chmod 0640 /usr/local/www/vhosts/www.examble.org/data/postfixadmin/config.local.php
chown www:www /usr/local/www/vhosts/www.examble.org/data/postfixadmin/config.local.php

Nun bitte https://www.examble.org/postfixadmin/setup.php im Browser aufrufen, am Ende der Seite das Setup-Passwort generieren und in der config.local.php nachtragen:

cat >> /usr/local/www/vhosts/www.examble.org/data/postfixadmin/config.local.php <<"EOF"
$CONF['setup_password'] = '!!!SECRET!!!';
"EOF"

Abschliessend mit den Anweisungen auf der Webseite fortfahren.


RoundCube

RoundCube installieren

fetch ftp://ftp.mirrorservice.org/sites/download.sourceforge.net/pub/sourceforge/r/project/ro/roundcubemail/roundcubemail/0.4/roundcubemail-0.4.tar.gz

tar xzf roundcubemail-0.4.tar.gz
mv roundcubemail-0.4 /usr/local/www/vhosts/www.examble.org/data/roundcube
chown -R www:www /usr/local/www/vhosts/www.examble.org/data/roundcube
find /usr/local/www/vhosts/www.examble.org/data/roundcube -type d -print0 | xargs -0 chmod 0750
find /usr/local/www/vhosts/www.examble.org/data/roundcube -type f -print0 | xargs -0 chmod 0640

Anlegen der Datenbank und des Datenbank-User:

mysql -uroot -p
CREATE DATABASE roundcube DEFAULT CHARACTER SET utf8;
GRANT ALL PRIVILEGES ON roundcube.* TO 'roundcube'@'localhost' IDENTIFIED BY '!!!SECRET!!!';
FLUSH PRIVILEGES;
QUIT;


RoundCube konfigurieren

mysql -uroot -p roundcube < /usr/local/www/vhosts/www.examble.org/data/roundcube/SQL/mysql.initial.sql
rm /usr/local/www/vhosts/www.examble.org/data/roundcube/.htaccess
mv /usr/local/www/vhosts/www.examble.org/data/roundcube/config/db.inc.php.dist /usr/local/www/vhosts/www.examble.org/data/roundcube/config/db.inc.php
mv /usr/local/www/vhosts/www.examble.org/data/roundcube/config/main.inc.php.dist /usr/local/www/vhosts/www.examble.org/data/roundcube/config/main.inc.php

Folgende Zeile muss in der config/db.inc.php angepasst werden:

$rcmail_config['db_dsnw'] = 'mysqli://roundcube:!!!SECRET!!!@localhost/roundcube';

Folgende Zeilen müssen in der config/main.inc.php angepasst werden:

$rcmail_config['default_host'] = 'ssl://mail.example.org';
$rcmail_config['default_port'] = 993;
$rcmail_config['imap_auth_type'] = plain;
$rcmail_config['smtp_server'] = 'tls://mail.example.org';
$rcmail_config['smtp_user'] = '%u';
$rcmail_config['smtp_pass'] = '%p';
$rcmail_config['smtp_helo_host'] = 'mail.example.org';
$rcmail_config['force_https'] = true;
$rcmail_config['des_key'] = 'rcmail-!24ByteDESkey*Str';
$rcmail_config['max_recipients'] = 50;
$rcmail_config['max_group_members'] = 50;
$rcmail_config['mime_magic'] = '/usr/share/misc/magic';
$rcmail_config['prefer_html'] = false;