12 de julio de 2015

Servidor de correo administrado con ViMbAdmin + DKIM

ViMbAdmin

Instalando Composer
# curl -sS https://getcomposer.org/installer | php
mv composer.phar /usr/local/bin/composer

Instando dependencias de ViMbAdmin:
# apt-get install mysql-server php5-cgi php5-mcrypt php5-memcache php5-json php5-mysql php-gettext pkg-php-tools git bcrypt

Creamos un usuario para que maneje el correo

# groupadd -g 2000 vmail
# useradd -c 'Virtual Mailboxes' -d /srv/vmail -g 2000 -u 2000 -s /usr/sbin/nologin -m vmail
Usamos el gid y uid 2000 así como la ruta /srv/vmail para modificar lo mínimo el fichero de ViMbAdmin.


Descargamos la última versión del repositorio.
# export INSTALL_PATH=/srv/vmail/www
# git clone https://github.com/opensolutions/ViMbAdmin.git $INSTALL_PATH
# cd $INSTALL_PATH
# composer install --dev
chown -R www-data: ./var
# cp ./public/.htaccess.dist ./public/.htaccess
# cp ./application/configs/application.ini.dist ./application/configs/application.ini

Creamos la base de datos y el usuario para la conexión:

$ mysql -u root -p
mysql > CREATE DATABASE `vimbadmin`;
mysql > GRANT ALL ON `vimbadmin`.* TO `vimbadmin`@`localhost` IDENTIFIED BY 'password';
mysql > FLUSH PRIVILEGES;
mysql > QUIT;

Insertamos los datos para la base de datos:

$ nano +48 ./application/configs/application.ini

Debemos modifica:
resources.doctrine2.connection.options.driver = 'pdo_mysql' resources.doctrine2.connection.options.dbname = 'vimbadmin' resources.doctrine2.connection.options.user = 'vimbadmin' resources.doctrine2.connection.options.password = 'password' resources.doctrine2.connection.options.host = 'localhost'

Además para almacenar las claves cifradas usaremos:

$ nano +149 ./application/configs/application.ini
defaults.mailbox.password_scheme = "dovecot:SHA512-CRYPT"

Ya podemos crear la base de datos, para ello:

$ ./bin/doctrine2-cli.php orm:schema-tool:create

En este punto debemos crear la claves "salt" para el sistema y la cuenta de administración.
Para ello podemos esperar ha hacerlo tras configurar todo o seguir usando:
$ php -S 0.0.0.0:8080 -t public/

Accedemos a la nuestro servidor via web y copiamos las "salt" generadas(en la web) en:

$ nano +24 ./application/configs/application.ini
Además podemos aprovechar para cambiar las apariciones de "example.com" por el nombre de nuestro servidor.
Una vez guardadas las "salts" podemos crear un administrador para el sistema de administración del correo.
Si no configuramos Dovecot y Postfix los cambios que realizemos en la web no tendrán efecto alguno, así que continuemos.

Dovecot

Instalando Dovecot
# apt-get install dovecot-core dovecot-imapd dovecot-pop3d dovecot-managesieved dovecot-sieve dovecot-mysql dovecot-lmtpd dovecot-common

Editamos /etc/dovecot/conf.d/10-mail.conf  para que quede:

mail_location = maildir:/srv/vmail/%d/%n
mail_uid = 2000
mail_gid = 2000
mail_privileged_group = vmail
first_valid_uid = 2000
last_valid_uid = 2000
maildir_copy_with_hardlinks = yes

Editamos /etc/dovecot/conf.d/10-auth.conf  para que quede:
disable_plaintext_auth = yes
auth_mechanisms = plain login
#!include auth-system.conf.ext
!include auth-sql.conf.ext

Editamos /etc/dovecot/conf.d/auth-sql.conf.ext para que quede:
passdb {
  driver = sql
  args = /etc/dovecot/dovecot-sql.conf.ext
}
userdb {
  driver = prefetch
}
userdb {
  driver = sql
  args = /etc/dovecot/dovecot-sql.conf.ext
}

Editamos /etc/dovecot/conf.d/10-master.conf para que quede:
service auth {
  unix_listener auth-userdb {
    mode = 0600
    user = vmail
    group = vmail
  }
  # Postfix smtp-auth
  unix_listener /var/spool/postfix/private/auth {
    mode = 0660
    user = postfix
    group = postfix
  }
}

Editamos /etc/dovecot/conf.d/15-lda.conf para que quede:
protocol lda {
  postmaster_address = postmaster@example.com
  mail_plugins = sieve
  auth_socket_path = /var/run/dovecot/auth-userdb
  log_path = /srv/vmail/dovecot-deliver.log
}

Editamos /etc/dovecot/dovecot-sql.conf.ext para que quede:
driver = mysql
default_pass_scheme = SHA512-CRYPT
user_query = SELECT homedir AS home, maildir AS mail, \
        concat('*:bytes=', quota) as quota_rule, uid, gid \

    FROM mailbox WHERE username = '%u'
password_query = SELECT username AS user, password, \
        homedir AS home, maildir AS mail, \
        concat('*:bytes=', quota) AS quota_rule, uid, gid \
    FROM mailbox \
        WHERE username = '%Lu' AND active = '1' \
            AND ( access_restriction = 'ALL' OR LOCATE( access_restriction, '%Us' ) > 0 )
iterate_query = SELECT username AS user FROM mailbox


Habilitamos los protocolos que queramos:
# nano +25 /etc/dovecot/dovecot.conf
protocols = imap pop3

Por último vamos a dar los permisos:
# chgrp vmail /etc/dovecot/dovecot.conf
# chmod g+r /etc/dovecot/dovecot.conf

Postfix

Instalando Postfix:
# apt-get install postfix postfix-mysql

Configuramos el servidor para que conecte con la base de datos:

# mkdir /etc/postfix/mysql
# echo "

virtual_uid_maps = static:2000
virtual_gid_maps = static:2000
virtual_alias_maps = mysql:/etc/postfix/mysql/virtual-aliases.cf
virtual_mailbox_domains = mysql:/etc/postfix/mysql/virtual-domains.cf
virtual_mailbox_maps = mysql:/etc/postfix/mysql/virtual-mailboxes.cf
virtual_transport = lmtp:unix:private/dovecot-lmtp
smtpd_tls_auth_only = yes
smtpd_sasl_auth_enable = yes
broken_sasl_auth_clients = yes

smtpd_sasl_authenticated_header = yes

smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_security_options = noanonymous, noplaintext
smtpd_sasl_tls_security_options = noanonymous
smtpd_recipient_restrictions =
    permit_mynetworks,
    permit_sasl_authenticated,
    reject_unauth_destination,
    reject_invalid_hostname,
    reject_unauth_pipelining,
    reject_non_fqdn_sender,
    reject_unknown_sender_domain,
    reject_non_fqdn_recipient,
    reject_unknown_recipient_domain,
    reject_rbl_client sbl.spamhaus.org,
    permit
" >> /etc/postfix/main.cf
# echo "user = vimbadmin
password = password
hosts = 127.0.0.1
dbname = aC2w1cIiSB
query = SELECT goto FROM alias WHERE address = '%s' AND active = '1'" > /etc/postfix/mysql/virtual-aliases.cf
# echo "user = vimbadmin
password = password
hosts = 127.0.0.1
dbname = aC2w1cIiSB
query = SELECT domain FROM domain WHERE domain = '%s' AND backupmx = '0' AND active = '1'" > /etc/postfix/mysql/virtual-domains.cf
# echo "user = vimbadmin
password = password
hosts = 127.0.0.1
dbname = aC2w1cIiSB
query = SELECT maildir FROM mailbox WHERE username = '%s' AND active = '1'" > /etc/postfix/mysql/virtual-mailboxes.cf
# echo "
dovecot   unix  -       n       n       -       -       pipe flags=DRhu
  user=vmail:vmail argv=/usr/lib/dovecot/deliver -d ${recipient}
" >> /etc/postfix/master.cf


Modificar /etc/postfix/master.cf para que quede:
smtps     inet  n       -       -       -       -       smtpd
  -o smtpd_tls_wrappermode=yes
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_sasl_type=dovecot
  -o smtpd_sasl_path=private/auth
  -o smtpd_relay_restrictions=permit_sasl_authenticated,reject
  -o milter_macro_daemon_name=ORIGINATING

Apache

Instalamos Apache:
# apt-get install apache2 libapache2-mod-php5
# a2enmod rewrite# echo "Alias /vimbadmin $INSTALL_PATH/public

<Directory $INSTALL_PATH/public>
    Options FollowSymLinks
    AllowOverride None

    # For Apache <= 2.3:
    #Order allow,deny
    #allow from all

    # For Apache >= 2.4
    Require all granted

    SetEnv APPLICATION_ENV production

    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} -s [OR]
    RewriteCond %{REQUEST_FILENAME} -l [OR]
    RewriteCond %{REQUEST_FILENAME} -d
    RewriteRule ^.*$ - [NC,L]
    RewriteRule ^.*$ /vimbadmin/index.php [NC,L]
</Directory>" > /etc/apache2/conf-available/vimbadmin.conf
# ln -sf ../conf-available/vimbadmin.conf /etc/apache2/conf-enabled/vimbadmin.conf

Mejoramos un poco la seguridad descomentando:
# a2enmod headers ssl
# a2ensite default-ssl

Aplicamos los siguientes cambios:
# nano +26 /etc/apache2/conf-enabled/security.conf
ServerTokens Prod
#ServerTokens OS
ServerSignature Off
#ServerSignature OnHeader set X-Content-Type-Options: "nosniff"
Header set X-Frame-Options: "sameorigin"

DKIM

Instalamos OpneDKIM
# apt-get install opendkim opendkim-tools
# mkdir /etc/opendkim/
# mkdir /etc/opendkim/keys/
# nano /etc/opendkim.conf
Modificar /etc/postfix/master.cf para que quede:
AutoRestart             Yes
AutoRestartRate         10/1h
Syslog                  yes
SyslogSuccess           Yes
LogWhy                  Yes
Canonicalization       relaxed/simple
ExternalIgnoreList      refile:/etc/opendkim/TrustedHosts
InternalHosts           refile:/etc/opendkim/TrustedHosts
KeyTable                refile:/etc/opendkim/KeyTable
SigningTable            refile:/etc/opendkim/SigningTable
Mode                    sv
PidFile                 /var/run/opendkim/opendkim.pid
SignatureAlgorithm      rsa-sha256
UserID                  opendkim:opendkim
Socket                  inet:12301@localhost

# nano /etc/default/opendkim
Descomentamos la linea que aparece: SOCKET="inet:12301@localhost"


Modificar /etc/postfix/main.cf y añadimos:
milter_protocol = 2
milter_default_action = accept
smtpd_milters = inet:localhost:12301
non_smtpd_milters = inet:localhost:12301

# nano /etc/opendkim/TrustedHosts
Dejamos /etc/opendkim/TrustedHosts del siguiente modo:
127.0.0.1
localhost
*.example.com

# nano /etc/opendkim/KeyTable
Dejamos /etc/opendkim/KeyTable del siguiente modo:
mail._domainkey.example.com example.com:mail:/etc/opendkim/keys/example.com/mail.private

# nano /etc/opendkim/SigningTable
Dejamos /etc/opendkim/SigningTable del siguiente modo:

*@example.com mail._domainkey.example.com

# cd /etc/opendkim/keys
# mkdir /etc/opendkim/keys/example.com
# cd example.com
# opendkim-genkey -s mail -d example.com
# chown opendkim:opendkim mail.private
# cat mail.txt

Copiar el contenido en el registro TXT del DNS

# service postfix restart
# service opendkim restart

Actualizando ViMbAdmin

# cd /srv/vmail/www
# git pull
# composer update
# ./bin/doctrine2-cli.php orm:schema-tool:update --dump-sql
# ./bin/doctrine2-cli.php orm:schema-tool:update --force
# ./bin/doctrine2-cli.php orm:validate-schema

Referencias:

http://pietervogelaar.nl/ubuntu-12-04-install-postfix-dovecot-and-vimbadmin
https://github.com/opensolutions/ViMbAdmin/wiki/Mail-System-Install-on-Ubuntu
https://gist.github.com/barryo/8918488
http://mxtoolbox.com/diagnostic.aspx
https://www.mail-tester.com/

2 de mayo de 2015

Cuida tu server, para evitar ataques


Cuidar el Software Podemos ver todos los programas instalados usando:
# dpkg --list

Y obtener más información con:
# dpkg --info packageName

Por ultimo lo eliminamos si no es necesario.
# apt-get remove packageName

Tener todo el sofware actualizado:
# apt-get update && apt-get upgrade

Para actualiza de forma automática el sistema podemos usar "unattended-upgrades"
# apt-get install unattended-upgrades
Existen varios ficheros de configuración para indicar distintas acciones, por ejemplo para que el sistema te envíe un mail informando de un "Upgrade" editamos el parametro Unattended-Upgrade de:
# nano /etc/apt/apt.conf.d/50unattended-upgrades
Para poder activar este programa deberemos editar el fichero APT:
# nano /etc/apt/apt.conf.d/10periodic
APT::Periodic::Unattended-Upgrade "1";



Instalar Software que nos defienda
Bloquea las IPs con intentos de acceso fallidos
# apt-get install fail2ban
El fichero de configuración de Fail2Ban se encuentra en:
# nano /etc/fail2ban/fail2ban.conf
# nano /etc/fail2ban/jail.conf



Detecta rootkits y cambios del sistema
# apt-get install tripwire
Para recibir los reportes en por correo.
# nano /etc/tripwire/twpol.txt

MAIL_TO = "user@host";
Y Añadimos "emailto = $(MAIL_TO)" en cada política.


# twadmin --create-polfile /etc/tripwire/twpol.txt

# tripwire --init # tripwire --check




# apt-get install rkhunter unhide mailutils
# nano /etc/rkhunter.conf
SSH_CONFIG_DIR=/etc/ssh
MAIL-ON-WARNING="correo@mail"
DISABLE_TESTS=""

PKGMGR=DPKG
ALLOWHIDDENDIR="/dev/.udev"

ALLOWHIDDENFILE="/dev/.initramfs"
MAIL_CMD=sendmail -s "[rkhunter] Warnings found for ${HOST_NAME}" -A /var/log/rkhunter.log
# rkhunter --propupd
# rkhunter --check


Para no tener problemas de falsos positivos tras actualizar deberemos hacer:
# rkhunter --propupd
# tripwire --init --local-passphrase
Monitoriza los logs
# apt-get install logwatch
# nano /etc/logwatch/conf/logwatch.conf

Output = mail
Format = html
MailTo = you@mail
MailFrom = correo@mail.example
Detail = High


Detectar ataques a puestos UDP y TCP mediante: # apt-get install portsentry
Para configurar correctamente portsentry y que no nos bloque debemos añadir el puerto 22 a:
# nano /etc/portsentry/portsentry.conf
#FTP,SSH,Telnet,SMTP,DNS,Time,Whois,Mail,Http,POP3,SQL,NTP,IMAP,SMB,ModBus,SHELL,SMTP,SOCKS,OpenVPN,IPsec,Cpanel,MySQL,PostgreSQL,VNC,
TCP_PORTS="20,21,22,23,25,37,43,56,57,80,8080,8000,8443,443,110,118,123,143,445,502,514,587,1080,1194,1293,2082,2083,2095,2096,3306,5432,5500,5800,5900"
#WoL
UDP_PORTS="9,20,23,37,56,118,123,502,1194,1293,3306,5432"

ADVANCED_EXCLUDE_TCP="22,80,113,139"

Si tenemos Apache:
# apt-get install libapache2-modsecurity
# a2enmod security2# cp /etc/modsecurity/modsecurity.conf-recommended /etc/modsecurity/modsecurity.conf
# nano +7 /etc/apache2/conf-enabled/security.conf

SecRuleEngine On



# apt-get install libapache2-mod-spamhaus

# a2enmod spamhaus # a2enmod headers

# a2enconf security
# nano +26 /etc/apache2/conf-enabled/security.conf
ServerTokens Prod
#ServerTokens OS ServerSignature Off
#ServerSignature On
Header set X-Content-Type-Options: "nosniff"

Header set X-Frame-Options: "sameorigin"

Siendo más estrictos
Usando IpTables podemos hacer más seguro nuestro server restringiendo los puestos que pueden recibir y enviar datos.

Borramos la configuración anterior
# iptables -F

Permitimos las conexiones existentes
# iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

Permitimos la conexiones por el puerto 22
# iptables -I INPUT -p tcp --dport 22 -j ACCEPT
# iptables -I OUTPUT -p tcp --sport 22 -j ACCEPT

Permitimos las conexiones locales
# iptables -A INPUT -i lo -j ACCEPT
# iptables -A OUTPUT -o lo -j ACCEPT

Cambiamos las políticas por defecto
# iptables -P FORWARD DROP
# iptables -P INPUT DROP
# iptables -P OUTPUT DROP

!!Tened en cuenta que si queremos que se acceda a los puertos de PortEntry, hay que abrirlos
# iptables -I INPUT -p tcp --dport 80 -j ACCEPT
# iptables -I OUTPUT -p tcp --sport 80 -j ACCEPT


Para tener conectividad hay que permitir el trafico DNS y la salida de trafico http/s
# iptables -A OUTPUT -p TCP --dport 53 -j ACCEPT
# iptables -A OUTPUT -p UDP --dport 53 -j ACCEPT

# iptables -A INPUT -p TCP --sport 53 -j ACCEPT # iptables -A INPUT -p UDP --sport 53 -j ACCEPT# iptables -A OUTPUT -p TCP --dport 80 -j ACCEPT
# iptables -A OUTPUT -p TCP --dport 443 -j ACCEPT

Mostramos el los logs las conexiones rechazadas
# iptables -A INPUT -j LOG --log-level debug --log-prefix "Drop INPUT:"
# iptables -A OUTPUT -j LOG --log-level debug --log-prefix "Drop OUTPUT: " --log-uid

Debemos denegar el acceso a "root", debe existir al menos otro usuario:
# nano +28 /etc/ssh/sshd_config
PermitRootLogin no
# useradd NuevoUsuario
# passwd NuevoUsuario
# mkdir /home/NuevoUsuario

Para poder evitar ataques de diccionario y fuerza bruta contra ssh, podemos configurarlo para que realice el login usando un certificado, para ello guardamos la clave publica del usuario en:
# nano /home/NuevoUsuario/.ssh/authorized_keys
# chmod 400 /home/NuevoUsuario/.ssh/authorized_keys
# chown NuevoUsuario:NuevoUsuario /home/NuevoUsuario -R
# nano /etc/ssh/sshd_config
PasswordAuthentication no
# service ssh restart



Referencias: https://openwebinars.net/10-minutos-para-securizar-tu-servidor/
https://www.digitalocean.com/community/tutorials/how-to-use-tripwire-to-detect-server-intrusions-on-an-ubuntu-vps