########################################################################
#			Instalar/upgradear sistema antes de trabajar
########################################################################

# apt update
# apt upgrade
# apt dist-upgrade

########################################################################
#							Utilitarios
########################################################################

Antes de instalar algo debemos instalar los utilitarios básicos o herramientas que 
necesitaremos para nuestro trabajo:

# apt install arj bzip2 cabextract cpio file lzop rpm2cpio gzip nomarch pax rar unrar unzip zoo unace razor pyzor tnef ripole zip p7zip-full mc

########################################################################
#							Grupo y usuario
########################################################################

Comenzamos con añadir el grupo de nuestros sistema de correo al que llamaré vmail:

# groupadd -g 5000 vmail

Usuario del sistema:

# useradd -d /home/vmail -s /bin/false -m -u 5000 -g 5000 -c "Virtual Mailbox Storage" vmail

########################################################################
#							Soporte Web
########################################################################

# apt install nginx php-cgi php-fpm php-pear php-mcrypt php-mysql php-imap php-memcache memcached php-pear php-intl mariadb-server phpmyadmin

Configurar MariaDB

MariaDB -> /etc/mysql/my.cnf
El archivo my.cnf sólo hace referencia a donde estan guardados los archivos de configuracion. Sólo necesitaremos modificar 
/etc/mysql/mariadb.conf.d/50-server.cnf modificando/ajustando las siguientes variables según nuestras necesidades:

max_connections        = 100
max_user_connections   = 100

general_log_file        = /var/log/mysql/mysql.log
general_log             = 1

Sólo queda guardar los cambios.

Ahora debemos ejecutar el script de seguridad para la configuración de MariaDB:

# mysql_secure_installation

Responder las preguntas lo más certeramente posible.
	
Configurar Nginx y PHP7

Cambiar de la siguiente manera:

Nginx -> /etc/nginx/nginx.conf

#----------------------------------------------------------------------#

user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

events {
	worker_connections 768;
	# multi_accept on;
}

http {

	##
	# Basic Settings
	##

	sendfile on;
	tcp_nopush on;
	tcp_nodelay on;
	keepalive_timeout 65;
	types_hash_max_size 2048;
	server_tokens off;

	# server_names_hash_bucket_size 64;
	# server_name_in_redirect off;

	include /etc/nginx/mime.types;
	default_type application/octet-stream;

	##
	# SSL Settings
	##

	ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
	ssl_prefer_server_ciphers on;

	##
	# Logging Settings
	##
	
	log_format specialLog '$http_x_real_ip - $remote_user [$time_local]' '"$request" $status $body_bytes_sent' '"$http_referer" "$http_user_agent"';
	access_log /var/log/nginx/access.log;
	error_log /var/log/nginx/error.log;

	##
	# Gzip Settings
	##

	gzip on;
	gzip_disable "MSIE [1-6].(?!.*SV1)";
	#gzip_disable "msie6";

	gzip_vary on;
	gzip_proxied any;
	gzip_comp_level 6;
	gzip_buffers 16 8k;
	gzip_http_version 1.1;
	gzip_static on;
	gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
	
	ignore_invalid_headers on;
	keepalive_requests 100;
	keepalive_disable none;
	max_ranges 1;
	
	


	##
	# Virtual Host Configs
	##

	include /etc/nginx/conf.d/*.conf;
	include /etc/nginx/sites-enabled/*;
}


#mail {
#	# See sample authentication script at:
#	# http://wiki.nginx.org/ImapAuthenticateWithApachePhpScript
# 
#	# auth_http localhost/auth.php;
#	# pop3_capabilities "TOP" "USER";
#	# imap_capabilities "IMAP4rev1" "UIDPLUS";
# 
#	server {
#		listen     localhost:110;
#		protocol   pop3;
#		proxy      on;
#	}
# 
#	server {
#		listen     localhost:143;
#		protocol   imap;
#		proxy      on;
#	}
#}

#----------------------------------------------------------------------#

Para procesar php en sites-available:

Editar /etc/nginx/sites-available/default

#----------------------------------------------------------------------#

##
# You should look at the following URL's in order to grasp a solid understanding
# of Nginx configuration files in order to fully unleash the power of Nginx.
# https://www.nginx.com/resources/wiki/start/
# https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/
# https://wiki.debian.org/Nginx/DirectoryStructure
#
# In most cases, administrators will remove this file from sites-enabled/ and
# leave it as reference inside of sites-available where it will continue to be
# updated by the nginx packaging team.
#
# This file will automatically load configuration files provided by other
# applications, such as Drupal or Wordpress. These applications will be made
# available underneath a path with that package name, such as /drupal8.
#
# Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples.
##

# Default server configuration
#
server {
	listen 80 default_server;

	# SSL configuration
	#
	# listen 443 ssl default_server;
	# listen [::]:443 ssl default_server;
	#
	# Note: You should disable gzip for SSL traffic.
	# See: https://bugs.debian.org/773332
	#
	# Read up on ssl_ciphers to ensure a secure configuration.
	# See: https://bugs.debian.org/765782
	#
	# Self signed certs generated by the ssl-cert package
	# Don't use them in a production server!
	#
	# include snippets/snakeoil.conf;

	root /var/www/html;

	# Add index.php to the list if you are using PHP
	index index.php index.html index.htm index.nginx-debian.html;

	server_name _;

	location / {
		# First attempt to serve request as file, then
		# as directory, then fall back to displaying a 404.
		try_files $uri $uri/ =404;
	}

	# pass PHP scripts to FastCGI server
	#
	location ~ \.php$ {
		include snippets/fastcgi-php.conf;
	#
	#	# With php-fpm (or other unix sockets):
		fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
	#	# With php-cgi (or other tcp sockets):
		#fastcgi_pass 127.0.0.1:9000;
	}

	# deny access to .htaccess files, if Apache's document root
	# concurs with nginx's one
	#
	location ~ /\.ht {
		deny all;
	}
}


# Virtual Host configuration for example.com
#
# You can move that to a different file under sites-available/ and symlink that
# to sites-enabled/ to enable it.
#
#server {
#	listen 80;
#	listen [::]:80;
#
#	server_name example.com;
#
#	root /var/www/example.com;
#	index index.html;
#
#	location / {
#		try_files $uri $uri/ =404;
#	}
#}

#----------------------------------------------------------------------#

Guardar al configuración y probar que funciona OK:

# nginx -t

Debe devolver:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

PHP7 -> /etc/php/7.0/fpm/php.ini

Editar la variable date.timezone, para ajustarla a nuestro país:

	date.timezone = "America/Havana"

Ahora sólo nos queda hacer un link para phpmyadmin:

ln -s /usr/share/phpmyadmin/ /var/www/html/
	
Reiniciar Nginc y PHP7/:
	
	# /etc/init.d/mysql restart
	# /etc/init.d/php7.0-fpm restart
	# /etc/init.d/nginx restart
	
Ahora podemos entrar a nuestro phpmyadmin:

http://IP_del_server/phpmyadmin/
	
Lo que necesitamos es dos bases de datos, una para el roundcube y otra para el postfixadmin, lo 
cual podemos usar el phpmyadmin o de forma gráfica con el phpmyadmin. Cada base de datos sólo 
la usará el usuario que la necesite[en este caso roundcube o postfixadmin] y nadie más.

Recomiendo crear un usuario por la consola si desean usar el phpmyadmin, pues si usan root, tendrán 
problemas de autenticación via web.

# mysql -u root -p -e "CREATE USER 'admin'@'%' IDENTIFIED BY 'pass';"
# mysql -u root -p -e "GRANT ALL PRIVILEGES ON *.* TO 'admin'@'%' WITH GRANT OPTION;"
# mysql -u root -p -e "FLUSH PRIVILEGES;"
# /etc/init.d/mysql restart

Ahora se pueden loguear con el usuario admin por la interfaz web del phpmyadmin.

PHPMyAdmin:
#----------------------------------------------------------------------#
	Crear usuario y base de datos para:
	- PostfixAdmin
	- Roundcube

	Ir a Privilegios/Agregar nuevo usuario:
	nombre: postfixadmin
	servidor: localhost
	password: ***************
	confirmar password: ***************
	marcar: Crear base de datos con el mismo nombre y otorgar todos los privilegios

Hacer el mismo proceso para la base de datos de Roundcube
#----------------------------------------------------------------------#

Consola:

Base de datos para Roundcube:
#----------------------------------------------------------------------#
# mysql -u root -p
mysql> CREATE DATABASE roundcube DEFAULT CHARACTER SET = utf8;
mysql> USE roundcube;
mysql> CREATE USER 'roundcube'@'localhost' IDENTIFIED BY 'roundcube';
mysql> GRANT USAGE ON *.* TO 'roundcube'@'localhost' IDENTIFIED BY 'roundcube';
mysql> GRANT ALL PRIVILEGES ON roundcube .* TO 'roundcube'@'localhost';
mysql> FLUSH PRIVILEGES;
mysql> quit;
#----------------------------------------------------------------------#
	
Base de datos para Postfixadmin:
#----------------------------------------------------------------------#
# mysql -u root -p
mysql> CREATE DATABASE postfixadmin DEFAULT CHARACTER SET = utf8;
mysql> USE postfixadmin;
mysql> CREATE USER 'postfixadmin'@'localhost' IDENTIFIED BY 'postfixadmin';
mysql> GRANT USAGE ON *.* TO 'postfixadmin'@'localhost' IDENTIFIED BY 'postfixadmin';
mysql> GRANT ALL PRIVILEGES ON postfixdamin .* TO 'postfixadmin'@'localhost';
mysql> FLUSH PRIVILEGES;
mysql> quit;	
#----------------------------------------------------------------------#
	
Ahora crearemos un virtualhosting para roundcube, que veremos más adelante:

En /etc/nginx/sites-available/ crear el archivo roundcube.conf y añadirle el siguiente contenido:

roundcube.conf
#----------------------------------------------------------------------#
server {
	listen 80;
	server_name webmail.inutil.cu;
	include /etc/nginx/php.conf;
	index index.php index.html index.htm;
	root /var/www/webmail.inutil.cu;
    index index.php index.html index.htm;

	location / {
		try_files $uri $uri/ /index.php?$args ;
	}
    access_log  /var/log/nginx/roundcube-access.log;
    error_log   /var/log/nginx/roundcube-error.log;

	include /etc/nginx/ban_exploits.conf;
	include /etc/nginx/favicon.conf;
}

server {
	listen 443 ssl http2;
	server_name webmail.inutil.cu;
	include /etc/nginx/ssl.conf;
	include /etc/nginx/php.conf;
	include /etc/nginx/ban_exploits.conf;
	include /etc/nginx/favicon.conf;
	index index.php index.html index.htm;
	root /var/www/webmail.inutil.cu;
    index index.php index.html index.htm;

	location / {
		try_files $uri $uri/ /index.php?$args;
	}
    access_log	/var/log/nginx/roundcube-access.log;
    error_log	/var/log/nginx/roundcube-error.log;
}
#----------------------------------------------------------------------#

Creamos la carpeta del virtualhosting:
#----------------------------------------------------------------------#
mkdir -p /var/www/webmail.inutil.cu
#----------------------------------------------------------------------#

Ahora pongámosle toda la seguridad necesaria:

Si tenemos conexión a internet podemos ponerle certificados Let´s Encrypt. 
Tutoriales de uso de Let´s Encrypt hay miles en internet. Pero como esto es un tutorial offline, 
generaremos los certificados SSL, autofirmados. 

#----------------------------------------------------------------------#
mkdir -p /etc/nginx/ssl
cd /etc/nginx/ssl
openssl req -x509 -nodes -days 3650 -newkey rsa:4096 -keyout /etc/nginx/ssl/cert.key -out /etc/nginx/ssl/cert.pem
openssl dhparam -out /etc/nginx/ssl/dh_2048.pem -2 2048
#----------------------------------------------------------------------#

Ahora crearemos los archivos incluidos en el procesamiento del virtualhosting con SSL:

/etc/nginx/ssl.conf
/etc/nginx/php.conf
/etc/nginx/ban_exploits.conf
/etc/nginx/favicon.conf

ssl.conf
#----------------------------------------------------------------------#
resolver 10.10.2.2 valid=300s;
resolver_timeout 5s;
ssl_certificate	/etc/nginx/ssl/cert.pem;
ssl_certificate_key	/etc/nginx/ssl/cert.key;
#ssl_trusted_certificate /etc/nginx/ssl/chain.pem;
ssl on;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_dhparam /etc/nginx/ssl/dh_1024.pem;
ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:DES-CBC3-SHA:HIGH:SEED:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!RSAPSK:!aDH:!aECDH:!EDH-DSS-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA:!SRP';
ssl_session_timeout 1d;
ssl_session_cache builtin:1000 shared:SSL:50m;
#spdy_headers_comp 0;

location ~ /.well-known {
	allow all;
}

if ($request_method !~ ^(GET|HEAD|POST)$ ) {
	return 444;
}

location ~ /(\.|wp-config.php|readme.html|license.txt|schema.txt|password.txt|passwords.txt) 
{ 
	deny all; 
}
#----------------------------------------------------------------------#

php.conf
#----------------------------------------------------------------------#
location ~ \.php$ {
	include fastcgi_params;
	include snippets/fastcgi-php.conf;
	fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
}

#location ~ \.php$ {
#        try_files $uri =404;
#        fastcgi_split_path_info ^(.+\.php)(/.+)$;
#        fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
#        fastcgi_index index.php;
#        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
#        include fastcgi_params;
#    }
#----------------------------------------------------------------------#

/etc/nginx/ban_exploits.conf
#----------------------------------------------------------------------#
## Block SQL injections
    set $block_sql_injections 0;
    if ($query_string ~ "union.*select.*\(") {
        set $block_sql_injections 1;
    }
    if ($query_string ~ "union.*all.*select.*") {
        set $block_sql_injections 1;
    }
    if ($query_string ~ "concat.*\(") {
        set $block_sql_injections 1;
    }
    if ($block_sql_injections = 1) {
        return 403;
    }

    ## Block file injections
    set $block_file_injections 0;
    if ($query_string ~ "[a-zA-Z0-9_]=http://") {
        set $block_file_injections 1;
    }
    if ($query_string ~ "[a-zA-Z0-9_]=(\.\.//?)+") {
        set $block_file_injections 1;
    }
    if ($query_string ~ "[a-zA-Z0-9_]=/([a-z0-9_.]//?)+") {
        set $block_file_injections 1;
    }
    if ($block_file_injections = 1) {
        return 403;
    }

    ## Block common exploits
    set $block_common_exploits 0;
    if ($query_string ~ "(<|%3C).*script.*(>|%3E)") {
        set $block_common_exploits 1;
    }
    if ($query_string ~ "GLOBALS(=|\[|\%[0-9A-Z]{0,2})") {
        set $block_common_exploits 1;
    }
    if ($query_string ~ "_REQUEST(=|\[|\%[0-9A-Z]{0,2})") {
        set $block_common_exploits 1;
    }
    if ($query_string ~ "proc/self/environ") {
        set $block_common_exploits 1;
    }
    if ($query_string ~ "mosConfig_[a-zA-Z_]{1,21}(=|\%3D)") {
        set $block_common_exploits 1;
    }
    if ($query_string ~ "base64_(en|de)code\(.*\)") {
        set $block_common_exploits 1;
    }
    if ($block_common_exploits = 1) {
        return 403;
    }

    ## Block spam
    set $block_spam 0;
    if ($query_string ~ "\b(ultram|unicauca|valium|viagra|vicodin|xanax|ypxaieo)\b") {
        set $block_spam 1;
    }
    if ($query_string ~ "\b(erections|hoodia|huronriveracres|impotence|levitra|libido)\b") {
        set $block_spam 1;
    }
    if ($query_string ~ "\b(ambien|blue\spill|cialis|cocaine|ejaculation|erectile)\b") {
        set $block_spam 1;
    }
    if ($query_string ~ "\b(lipitor|phentermin|pro[sz]ac|sandyauer|tramadol|troyhamby)\b") {
        set $block_spam 1;
    }
    if ($block_spam = 1) {
        return 403;
    }

    ## Block user agents
    set $block_user_agents 0;

    # Don't disable wget if you need it to run cron jobs!
    #if ($http_user_agent ~ "Wget") {
    #    set $block_user_agents 1;
    #}

    # Disable Akeeba Remote Control 2.5 and earlier
    if ($http_user_agent ~ "Indy Library") {
        set $block_user_agents 1;
    }

    # Common bandwidth hoggers and hacking tools.
    if ($http_user_agent ~ "libwww-perl") {
        set $block_user_agents 1;
    }
    if ($http_user_agent ~ "GetRight") {
        set $block_user_agents 1;
    }
    if ($http_user_agent ~ "GetWeb!") {
        set $block_user_agents 1;
    }
    if ($http_user_agent ~ "Go!Zilla") {
        set $block_user_agents 1;
    }
    if ($http_user_agent ~ "Download Demon") {
        set $block_user_agents 1;
    }
    if ($http_user_agent ~ "Go-Ahead-Got-It") {
        set $block_user_agents 1;
    }
    if ($http_user_agent ~ "TurnitinBot") {
        set $block_user_agents 1;
    }
    if ($http_user_agent ~ "GrabNet") {
        set $block_user_agents 1;
    }

    if ($block_user_agents = 1) {
        return 403;
    }
#----------------------------------------------------------------------#

favicon.conf
#----------------------------------------------------------------------#
location ~ /favicon.ico {
	access_log off;
	log_not_found off;
	alias /var/www/favicon.ico;
}
#----------------------------------------------------------------------#

El favicon no es tan importante, por lo cual si no lo tenemos no dará error en los logs.

Ahora solo queda activar el virtualhost y reiniciar nginx:
#----------------------------------------------------------------------#
ln -s /etc/nginx/sites-available/roundcube.conf /etc/nginx/sites-enabled/roundcube.conf

/etc/init.d/nginx restart
#----------------------------------------------------------------------#

Ahora instalaremos Roundcube.

La ruta de instalacion de roundcube en el virtualhosting fue /var/www/webmail.inutil.cu.
Después de descargarlo:
#----------------------------------------------------------------------#
cd /var/www/webmail.inutil.cu
tar xfv roundcubemail-1.3.3-complete.tar.gz
rm roundcubemail-1.3.4-complete.tar.gz
cd roundcubemail-1.3.4
mv * ../
cd ..
rm -rf roundcubemail-1.3.4
chmod -R 755 *; chown -R www-data:www-data *
mkdir -p /etc/roundcube
mv config /etc/roundcube
ln -s /etc/roundcube/config/ /var/www/webmail.inutil.cu/
chmod 777 logs
chmod 777 temp
#----------------------------------------------------------------------#

Para ahorrarnos molestias cuando termine el instalador copiando/pegando la configuración, 
le daremos permisos de escritura a la carpeta /etc/roundcube/config para que automáticamente 
se acabe la instalación de roundcube cree el archivo de configuración, el cual posteriormente 
le daremos permisos de sólo lectura.

chmod 777 /etc/roundcube/config

Abrir el navegador e ir a http://ip_del_server/roundcube/installer/
	- Revisar que todos los valores necesarios están en "ON" y hacer click en "NEXT"
	- Revisar los campos del setup y editar según nuestras preferencias. En este punto sólo deberíamos 
	editar "identities_level" dejándolo en "one identity with possibility to edit only signature"
	- Configurar la conexion a MySQL en el apartado "Database setup"
	- En el apartado "username_domain" debemos poner nuestro dominio
	- Idioma "es_ES", y rellenar cualquier info necesaria en dependencia de nuestras necesidades y hacer 
	click en "NEXT"
	- Copiar/guardar la config en nuestro directorio de configuración /etc/roundcube/config/config.inc.php. Si 
	usted le dio permisos de escritura a /etc/roundcube/config, sólo debe dar next y listo, la configuración de 
	roundcube será salvada automáticamente sin preguntar nada.

NOTA: 
	En caso de usar "*" en los password debemos editar la config y arreglar ese detalle puesto que php nos genera 
	el caracter html para el * y cuando roundcube intenta conectarse a la base de datos no va a poder
	
	- Dar click en "Continue" e inicializar la base de datos, recuerde hacer los cambios pertinentes a la config 
	antes de dar siguiente.
	- Inicializar la base de datos dando click en el boton "Initialize database"
	- Si todo ha ido bien[si no, reintentar instalar desde el principio], sólo nos restará borrar el instalador
	# rm -rf /var/www/webmail.inutil.cu/installer
	- Dar permisos de lectura nuevamente a la carpeta de la configuración.
	# chmod 755 /etc/roundcube/config 
	# chmod -R 755 /etc/roundcube/config/; chown -R www-data:www-data /etc/roundcube/config/
	
Plugin de cambio de password
	En config.inc.php:
	
	- $config['plugins'] = array('password');
	- Ir a /usr/share/roundcube/plugins/password y renombrar config.inc.php.dist
	- # mv config.inc.php.dist config.inc.php
	- Editar:
		$config['password_driver'] = 'sql';
		$config['password_db_dsn'] = 'mysql://postfix:contraseña_de_postfixdb@localhost/postfix';
		$config['password_query'] = 'UPDATE mailbox SET password=%c,modified=NOW() WHERE username=%u LIMIT 1';
		
Ahora, cuando un usuario desee cambiarse el password solamente debe ir a "Configuración/Contraseña", rellenar los 
campos y listo.

NOTA: Si usted tiene implementada la politica de correos nacionales e internacionales[muy común en Cuba], debe cambiar en 
la configuración de roundcube[config.inc.php] el default_host[$config['default_host'] = 'localhost';] por el ip de su server 
de correo así obliga al usuario a hacer login por el ip no por localhost, y postfix lo reconoce como una ip externa a 127.0.0.1.

########################################################################
#							SASL
########################################################################

Instalando SASL
#----------------------------------------------------------------------#

# apt install sasl2-bin libsasl2-modules libpam-mysql libsasl2-modules-sql

#----------------------------------------------------------------------#
	
Como bien nos dice el instalador de saslauthd debe iniciar con el sistema por lo que debemos 
hacerlo en /etc/default/saslauthd

	START=yes

Guardamos y salimos

Ahora debemos modificar la carpeta donde va a trabajar Postfix con SASL, hay que hacerle algunos pequeños ajustes:

#----------------------------------------------------------------------#
	# mkdir -p /var/spool/postfix/var/run/saslauthd
	# rm -rf /var/run/saslauthd
	# ln -s /var/spool/postfix/var/run/saslauthd /var/run/saslauthd
#----------------------------------------------------------------------#

Ahora bien, debemos crear el fichero para extraer las contraseñas encriptadas de la base de datos con los datos del 
usuario, contraseña, base de datos, tabla, la columna donde se encuentra el usuario y la columna donde se encuentra 
la contraseña.

# touch /etc/pam.d/smtp

smtp
#----------------------------------------------------------------------#
auth required pam_mysql.so user=postfix passwd=password_usuario_mysql host=127.0.0.1 db=postfix table=mailbox usercolumn=name passwdcolumn=password crypt=1 md5=1

account sufficient pam_mysql.so user=postfix passwd=password_usuario_mysql host=127.0.0.1 db=postfix table=mailbox usercolumn=name passwdcolumn=password crypt=1 md5=1
#----------------------------------------------------------------------#

Cada sentencia anterior debe ir en una sola línea. Es decir, el fichero smtp sólo debe contener dos líneas.

Y por supuesto, los permisos:

	# chmod 644 /etc/pam.d/smtp

Y reiniciamos SASL

	# /etc/init.d/saslauthd restart

########################################################################
#						PostfixAdmin
########################################################################

Después de descargarlo de Sourceforge:
#----------------------------------------------------------------------#
# tar xfv postfixadmin-3.1.tar.gz
# mv postfixadmin-3.1 postfixadmin
# mv postfixadmin /usr/share/
# cd /usr/share/postfixadmin
# mkdir templates_c
# chmod -R 755 *; chown -R www-data:www-data *
# chmod -R 777 templates_c
# mkdir -p /etc/postfixadmin
# mv /usr/share/postfixadmin/config.inc.php /etc/postfixadmin/
# ln -s /etc/postfixadmin/config.inc.php /usr/share/postfixadmin/config.inc.php
# ln -s /usr/share/postfixadmin /var/www/webmail.inutil.cu/
# /etc/init.d/nginx restart
#----------------------------------------------------------------------#

Editar la configuración[config.inc.php]:
Directivas...
#----------------------------------------------------------------------#
	$CONF['configured'] = true;
	
	$CONF['default_language'] = 'es';

	$CONF['database_type'] = 'mysqli';
	$CONF['database_host'] = 'localhost';
	$CONF['database_user'] = 'postfix';
	$CONF['database_password'] = 'postfixadmin';
	$CONF['database_name'] = 'postfix';

	$CONF['quota'] = 'YES';

	$CONF['quota_multiplier'] = '1048576';
	
Esta directiva se usa cuando aún no se tiene nombre de dominio así el postfixadmin no 
chequea el dominio de email del administrador que sea válido. Se usa para pruebas solamente...
	$CONF['emailcheck_resolve_domain']='YES';
	
	$CONF['used_quotas'] = 'YES';
	
Esta directiva se usa desde Dovecot 1.2	o superior, si usted tiene dovecot >=1.1 poner a NO
	$CONF['new_quota_table'] = 'YES';
	
Abrir el navegador e ir a http://ip_del_server/postfixadmin/setup.php
	- Rellenar el campo del setup password
	- Rellenar los campos del setup con los datos del formulario anterior
	- Editar el config.inc.php y setear la variable $CONF['setup_password'] con el valor dado en la instalación
	- Añadir el email del administrador y listo

En el navegador ir a http://ip_del_server/postfixadmin/
	- Loguearnos con la info del administrador del sitio
	- Lo primero es ir a "Lista de dominios/Nuevo dominio" y rellenar los datos
	- Después ir a "Lista de direcciones virtuales/Añadir buzón" y rellenar los datos
	- Añadir cuantos buzones sean necesarios...
	- Listo!


########################################################################
#						Dovecot
########################################################################

# apt install dovecot-pop3d dovecot-imapd  dovecot-core dovecot-mysql dovecot-sieve

Dovecot antes nos creaba un certificado autofirmado válido por 10 años[ya NO]. Existe un script en /usr/share/dovecot llamado mkcert.sh 
que se encarga de esa tarea, pero la primera vez que instalé Dovecot no sabía esto y usé openssl directamente para crearlo:

# openssl req -x509 -nodes -days 3650 -newkey rsa:4096 -keyout /etc/dovecot/dovecot.pem -out /etc/dovecot/dovecot.pem

Y después de completar toda la info que nos pide openssl para crear el certificado, lo tendremos disponible en:
	
	/etc/dovecot/dovecot.pem

El cual usaremos para nuestra configuración[es de prueba, no? :D]...

Nota: Dovecot divide en varios archivos la configuración, yo acostumbro a poner todo en un mismo archivo 
para no perderme después.

	Algunos cambios antes de configurar Dovecot

# mkdir -p /var/log/dovecot/
# cd /var/log/dovecot/
# touch dovecot.log dovecot-info.log dovecot-deliver.log dovecot-debug.log

Debido a que Dovecot a cambiado mucho no es posible adaptarle una config anterior[si, me pasó cuando migré 
de Dovecot 1.1 a 2.1], por lo que debemos hacer lo siguiente:	
	
# doveconf -n > /etc/dovecot/dovecot.conf
	
Doveconf genera una configuración bastante acertada, pero demasiado pobre, por lo que hay que pasarle la mano 
para que quede a nuestro gusto.

La configuración de Dovecot:

	<dovecot.conf>
	
	  # 2.2.27: /etc/dovecot/dovecot.conf

	  listen = *
	  protocols = imap pop3

	  login_log_format = %$: %s
	  login_log_format_elements = user=<%u> method=%m rip=%r lip=%l %c
	  deliver_log_format = msgid=%m: %$ : Subject: %s
	  mail_access_groups = vmail
	  mail_location = maildir:/home/vmail/%d/%n/Maildir:INDEX=/home/vmail/%d/%n/Maildir
	  mail_log_prefix = "%Us(%u): "
	  maildir_stat_dirs = yes

	  log_path = /var/log/dovecot/dovecot.log
	  info_log_path = /var/log/dovecot/dovecot-info.log
	  log_timestamp = "%Y-%m-%d %H:%M:%S "

	  ssl = required
	  ssl_protocols = !SSLv2 !SSLv3
	  # Good bye SSLv3
	  ssl_cipher_list = ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA
	  ssl_cert = </etc/dovecot/dovecot.pem
	  ssl_key = </etc/dovecot/dovecot.pem
	  verbose_proctitle = no
	  verbose_ssl = no

	  mail_plugins = quota expire mailbox_alias mail_log notify acl

	  mail_temp_dir = /tmp
	  disable_plaintext_auth = yes
	  auth_username_chars = abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890.-_@
	  auth_mechanisms = plain login
	  auth_verbose = no
	  auth_debug = no
	  auth_debug_passwords = no
	  auth_verbose_passwords = plain
	  # For debbugging purposes only, set to yes
	  mail_debug = no
	  debug_log_path = /var/log/dovecot/dovecot-debug.log

	  login_greeting = Dovecot ready OK+.

	  first_valid_gid = 2
	  first_valid_uid = 2
	  last_valid_gid = 5000
	  last_valid_uid = 5000

	  service imap-login {
	      inet_listener imap {
		  address = *
		  port = 143
		  }
	      inet_listener imaps {
		  address = *
		  port = 993
		  ssl = yes
		  }
	      service_count = 1
	      }

	  service imap {
	      process_limit = 512
	      vsz_limit = 1 G
	      }

	  service pop3-login {
	      inet_listener pop3 {
		  address = *
		  port = 110
	      }
	      inet_listener pop3s {
		  address = *
		  port = 995
	      }
	      service_count = 1
	      }

	  service pop3 {
	      process_limit = 512
	      vsz_limit = 1 G
	      }

	  service dict {
	      unix_listener dict {
		  mode = 0600
		  user = vmail
		  group = vmail
	      }
	  }

	  namespace {
	      type = private
	      separator = /
	      prefix =
	      #location defaults to mail_location.
	      inbox = yes

	      # Refer to document for more details about alias mailbox:
	      # http://wiki2.dovecot.org/MailboxSettings
	      #
	      # Sent
	      mailbox Sent {
		  auto = subscribe
		  special_use = \Sent
	      }
	      mailbox "Sent Messages" {
		  auto = no
		  special_use = \Sent
	      }
	      mailbox "Sent Items" {
		  auto = no
		  special_use = \Sent
	      }

	      mailbox Drafts {
		  auto = subscribe
		  special_use = \Drafts
	      }

	      # Trash
	      mailbox Trash {
		  auto = subscribe
		  special_use = \Trash
	      }

	      mailbox "Deleted Messages" {
		  auto = no
		  special_use = \Trash
	      }

	      # Junk
	      mailbox Junk {
		  auto = subscribe
		  special_use = \Junk
	      }
	      mailbox Spam {
		  auto = no
		  special_use = \Junk
	      }
	      mailbox "Junk E-mail" {
		  auto = no
		  special_use = \Junk
	      }

	      # Archive
	      mailbox Archive {
		  auto = subscribe
		  special_use = \Archive
	      }
	      mailbox Archives {
		  auto = no
		  special_use = \Archive
	      }
	  }

	  protocol imap {
	    mail_max_userip_connections = 10
	    mail_plugin_dir = /usr/lib/dovecot/modules
	    mail_plugins = $mail_plugins imap_quota imap_acl
	    imap_client_workarounds = tb-extra-mailbox-sep
	  }
	  protocol pop3 {
	    mail_max_userip_connections = 10
	    pop3_client_workarounds = outlook-no-nuls oe-ns-eoh
	    pop3_logout_format = top=%t/%p, retr=%r/%b, del=%d/%m, size=%s
	    mail_plugin_dir = /usr/lib/dovecot/modules
	    mail_plugins = $mail_plugins
	    pop3_uidl_format = %08Xu%08Xv
	  }
	  protocol lda {
	    auth_socket_path = /var/run/dovecot/auth-master
	    hostname = correo.nauta.cu
	    lda_mailbox_autocreate = yes
	    info_log_path = /var/log/dovecot/dovecot-deliver.log
	    log_path = /var/log/dovecot/dovecot.log
	    mail_plugin_dir = /usr/lib/dovecot/modules
	    mail_plugins = $mail_plugins
	    postmaster_address = postmaster@nauta.cu
	    sendmail_path = /usr/lib/sendmail
	  }

	  passdb {
	    driver = sql
	    args = /etc/dovecot/dovecot-sql.conf
	  }

	  service auth {
	    unix_listener /var/spool/postfix/private/dovecot-auth {
	      group = postfix
	      mode = 0660
	      user = postfix
	    }
	    unix_listener auth-master {
	      group = vmail
	      mode = 0660
	      user = vmail
	    }
	    user = root
	  }

	  userdb {
		  args = /etc/dovecot/dovecot-sql.conf
		  driver = sql
	  }

	  dict {
		  quotadict = mysql:/etc/dovecot/dovecot-quota.conf
	  }

	  quota_full_tempfail = yes

	  plugin {
	    quota = dict:User quota::proxy::quotadict
	    quota_rule = *:storage=10M:messages=1000
	    quota_rule2 = Trash:storage=+10%

	    # New & WORKS!!!
	    quota_warning = storage=95%% quota-warning 95 %u
	    quota_warning2 = storage=90%% quota-warning 90 %u
	    quota_warning3 = storage=85%% quota-warning 85 %u
	    quota_grace = 10%%

	    trash = /etc/dovecot/trash.conf
	    mail_log_events = delete undelete expunge copy mailbox_delete mailbox_rename
	    mail_log_fields = uid box msgid size

	  }

	  service quota-warning {
	    executable = script /etc/dovecot/scripts/quota-warning.sh
	    user = vmail
	    unix_listener quota-warning {
	      user = vmail
	    }
	  }

	</dovecot.conf>

Conexión a MySQL y obtener de datos

	<dovecot-sql.conf>
	
	  driver = mysql
	  connect = host=localhost dbname=db_name user=db_user password=db_user_password
	  default_pass_scheme = md5-crypt

	  password_query = SELECT password FROM mailbox WHERE username = '%u' AND active='1'

	  user_query = SELECT maildir, 5000 AS uid, 5000 AS gid, CONCAT('*:bytes=', quota) AS quota_rule FROM mailbox WHERE username = '%u' AND active='1' 

	</dovecot-sql.conf>

Obtener la quota

	<dovecot-quota.conf>
	
	    connect = host=localhost dbname=db_name user=db_user password=db_user_password

	    map {
		    pattern = priv/quota/storage
		    table = quota2
		    username_field = username
		    value_field = bytes
	    }

	    map {
		    pattern = priv/quota/messages
		    table = quota2
		    username_field = username
		    value_field = messages
	    }
	
	</dovecot-quota.conf>


	<trash.conf>

		1 Spam
		2 Trash

	</trash.conf>

<quota-warning.sh>

#!/bin/bash

PERCENT=$1
USER=$2

cat << EOF | /usr/lib/dovecot/dovecot-lda -d $USER -o "plugin/quota=maildir:User quota:noenforcing"
From: postmaster@inutil.cu
Subject: Advertencia de quota en el servidor

Su buzon esta $PERCENT% lleno.

Usted deberia borrar algunos mensajes del servidor.


ADVERTENCIA: No ignore este mensaje, pues si su buzon alcanza 
llenarse al 100%, los correos nuevos seran rechazados.

EOF

</quota-warning.sh>

En caso de no necesitar todo esto sólo diríjase a http://wiki2.dovecot.org/QuickConfiguration 
para configurar Dovecot rápido y sin dolor... No lo recomiendo, estudie un poquito, 
diga NO a la neuroapatía.

Para probar el certificado en dovecot
# openssl s_client -starttls imap -connect imap.inutil.cu:143

########################################################################
#						Postfix
########################################################################

# apt install postfix postfix-pcre postfix-mysql mlock mailutils postfix-policyd-spf-perl

Lo primero es agregar el usuario postfix al grupo sasl

# adduser postfix sasl

Así postfix trabajará con la autenticación SASL.

Debemos agregar a postfix las directivas smtpd_tls_dh1024_param_file y smtpd_tls_dh512_param_file que lo que hacen es añadir ECC 
con el fin de mejorar la seguridad de nuestro servidor:

	smtpd_tls_dh1024_param_file = /etc/postfix/certs/dh_2048.pem.pem
	smtpd_tls_dh512_param_file = /etc/postfix/certs/dh_1024.pem

Y para generar los certificados:
	
# mkdir /etc/postfix/certs
# cd /etc/postfix/certs
# openssl req -x509 -nodes -days 3650 -newkey rsa:4096 -keyout postfix.pem -out postfix.pem
# openssl dhparam /etc/postfix/certs/dh_2048.pem -2 2048
# openssl dhparam/etc/postfix/certs/dh_1024.pem -2 1024
	
Después de hecho esto, debemos crear el fichero smtpd.conf dentro de la carpeta sasl de Postfix 
para indicarle el método de autenticación smtp con sasl.

# touch /etc/postfix/sasl/smtpd.conf

	<smtpd.conf>

	pwcheck_method: saslauthd
	mech_list: PLAIN LOGIN
	log_level: 7
	auxprop_plugin: mysql
	sql_hostnames: 127.0.0.1
	sql_user: postfix
	sql_passwd: password_usuario_mysql
	sql_database: postfix
	sql_select: select password from mailbox where username = '%u'

	</smtpd.conf>

Y los permisos:

root@happyharry: # chmod 644 /etc/postfix/sasl/smtpd.conf

Si tenemos alguna duda instalando postfix recomiendo hacer un dpkg-reconfigure postfix y analizar el instalador...

Como estamos instalando postfix contra mysql debemos crear los archivos que vinculen a postfix con mysql

	# mkdir -p /etc/postfix/sql
	# cd /etc/postfix/sql/
	
	# touch mysql_sender_login_maps.cf
Nota: Este fichero va a contener la query que chequea y evita la suplantación de identidad

	<mysql_sender_login_maps.cf>
	
		user        = postfix
		password    = postfix_db_password
		hosts       = 127.0.0.1
		port        = 3306
		dbname      = postfix
		query       = SELECT mailbox.username FROM mailbox,domain WHERE mailbox.username='%s' AND mailbox.domain='%d' AND mailbox.domain=domain.domain AND mailbox.active=1 AND domain.backupmx=0 AND domain.active=1
		
	</mysql_sender_login_maps.cf>
	
	# touch mysql_virtual_alias_domainaliases_maps.cf
Nota: Este fichero va a contener la query de los alias de dominio
	
	<mysql_virtual_alias_domainaliases_maps.cf>
	
		user      = postfix
		password  = postfix_db_password
		hosts     = 127.0.0.1
		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
		
	</mysql_virtual_alias_domainaliases_maps.cf>

	# touch mysql_virtual_alias_maps.cf
Nota: Este fichero va a contener la query de los alias de correo virtuales

	<mysql_virtual_alias_maps.cf>
	
		user         = postfix
		password     = postfix_db_password
		hosts        = 127.0.0.1
		dbname       = postfix
		table        = alias
		select_field = goto
		where_field  = address
		additional_conditions = and active = '1'
		
	</mysql_virtual_alias_maps.cf>
	
	#touch mysql_virtual_domains_maps.cf
Nota: Este fichero va a contener la query de los dominios de correo virtuales

	<mysql_virtual_domains_maps.cf>
		user         = postfix
		password     = postfix_db_password
		hosts        = 127.0.0.1
		dbname       = postfix
		table        = domain
		select_field = domain
		where_field  = domain
		additional_conditions = and backupmx = '0' and active = '1'
	</mysql_virtual_domains_maps.cf>

	# touch mysql_virtual_mailbox_domainaliases_maps.cf	
Nota: Este fichero va a contener la query de los alias de buzón virtuales

	<mysql_virtual_mailbox_domainaliases_maps.cf>
	
		user     = postfix
		password = postfix_db_password
		hosts    = 127.0.0.1
		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
	
	</mysql_virtual_mailbox_domainaliases_maps.cf>
	
	# touch mysql_virtual_mailbox_maps.cf
Nota: Este fichero va a contener la query de los buzones virtuales
	
	<mysql_virtual_mailbox_maps.cf>
	
	user     = postfix
	password = postfix_db_password
	hosts    = 127.0.0.1
	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
	
	</mysql_virtual_mailbox_maps.cf>
		
Ahora pasaremos a configurar postfix:

<main.cf>
	
###################################################
#	Configuraciones del dominio[ESPECIFICO]
###################################################

# Dominio de correo desde el cual se enviará correo, es decir, nuestro dominio
mydomain   = inutil.cu

# Declarar FQDN del equipo usando la variable del dominio
myhostname = correo.$mydomain

# Declarar el dominio del cual proviene y al cual se entrega el correo
myorigin = /etc/mailname

# Declarar destino para el transporte local (mensajes locales y del mailserver)
mydestination = $myorigin, $myhostname, localhost, localhost.$mydomain

# Personalizar banner (el protocolo SMTP requiere que la primera palabra
# sea el FQDN del equipo)
smtpd_banner = $myhostname ESMTP $mail_name

# Desactivar servicio de notificaciones de nuevo correo (mejor rendimiento)
biff = no

# Backguard compatibility, mandatory for Postfix 3
#compatibilizando expresiones de Postfix 2 con Postfix 3[OBLIGATORIO]
compatibility_level=2

# Backguard compatibility
# Prohibir direcciones de correo sin dominio
append_dot_mydomain = no

readme_directory     = no

# Plantilla personalizada para correos de error
bounce_template_file = /etc/postfix/warn/bounce.msg

###################################################
#	Network Config [ESPECIFICO]
###################################################
# Backguard compatibility
#mynetworks_style = subnet
mynetworks_style = host

# A menos que realmente se haga de relayhost para otros MTAs, restringir la red
# de confianza a las direcciones loopback
mynetworks = 127.0.0.0/8

# Interfaces para escuchar peticiones
inet_interfaces = all

# Protocolos a utilizar
inet_protocols = ipv4
# all -> for ipv4 & ipv6

# Dirección para verificar la existencia de remitentes en otro MTA
address_verify_sender = mailer-daemon@$mydomain

# Establecer un tiempo de vida a las verificaciones
address_verify_sender_ttl = 8h

###################################################
#	Notificaciones [ESPECIFICO]
###################################################

# Clases para errores que se reportan al postmaster
notify_classes = bounce, 2bounce, delay, policy, protocol, resource, software

###################################################
#	Configuraciones del relayhost[ESPECIFICO]
###################################################

# No se utiliza otro MTA intermedio para enviar el correo
relayhost =

###################################################
#	Configuracion de los usuarios virtuales@MySQL[ESPECIFICO]
###################################################

virtual_minimum_uid     = 5000
virtual_mailbox_base    = /home/vmail
virtual_uid_maps        = static:5000
virtual_gid_maps        = static:5000
virtual_transport       = dovecot

virtual_alias_maps      = mysql:/etc/postfix/sql/mysql_virtual_alias_maps.cf, mysql:/etc/postfix/sql/mysql_virtual_alias_domainaliases_maps.cf
virtual_mailbox_domains = mysql:/etc/postfix/sql/mysql_virtual_domains_maps.cf
virtual_mailbox_maps    = mysql:/etc/postfix/sql/mysql_virtual_mailbox_maps.cf, mysql:/etc/postfix/sql/mysql_virtual_mailbox_domainaliases_maps.cf

show_user_unknown_table_name = no

# Do not set virtual_alias_domains.
virtual_alias_domains =

###################################################
#	Save all In/Out messages [ESPECIFICO]
###################################################

# Guardar copia de los correos para Seguridad Informática
always_bcc = bcc@inutil.cu

###################################################
#	Message/Inbox config [ESPECIFICO]
###################################################

#NEW, testing

# Requerir que las direcciones de MAIL FROM y RCPT TO estén encerradas entre <>
strict_rfc821_envelopes = yes

invalid_hostname_reject_code = 554
multi_recipient_bounce_reject_code = 554
non_fqdn_reject_code = 554
relay_domains_reject_code = 554
unknown_address_reject_code = 554
unknown_client_reject_code = 554
unknown_hostname_reject_code = 554
unknown_relay_recipient_reject_code = 554
unknown_virtual_alias_reject_code = 554
unknown_virtual_mailbox_reject_code = 554
unverified_recipient_reject_code = 554
unverified_sender_reject_code = 554

# Delimitador de destinatarios
recipient_delimiter       = +

enable_original_recipient = no
### Maximum mailbox size (0 = unlimited - is already limited by Dovecot quota)
mailbox_size_limit        = 0
message_size_limit        = 1572864

# 1MB   -> 1048576
# 1.5MB -> 1572864

# Máximo de destinatarios en un mensaje
#default_destination_recipient_limit = 20

# Cantidad maxima de destinatarios para un mensaje
smtpd_recipient_limit     = 15

# Dovecot
dovecot_destination_recipient_limit = 1

# Enviar alertas sobre correo demorado
delay_warning_time        = 4h
smtpd_error_sleep_time    = 1s

# Tiempo en cola de los mensajes
bounce_queue_lifetime     = 4d

# Tiempo maximo de vida en la cola
maximal_queue_lifetime    = 7d

# Tiempo minimo y maximo de reconexion cuando la conexion falla
minimal_backoff_time      = 1000s
maximal_backoff_time      = 8000s

# Limite de entrega simultanea a un mismo usuario local
local_destination_concurrency_limit = 15

# Desactivar anuncio de comandos dependiendo de la ip del cliente
smtpd_discard_ehlo_keyword_address_maps = cidr:/etc/postfix/rules/ehlo_map.cidr

# Definir límite de conexiones simultáneas que un cliente puede establecer
smtpd_client_connection_count_limit = 3

# Definir límite de errores que un cliente puede cometer antes de desconectarlo
smtpd_hard_error_limit = 5
#
# Definir límite de errores que un cliente puede cometer antes de reducir la
# velocidad de su conexión
smtpd_soft_error_limit = 1
#
# Definir límite de comandos basura que un cliente puede realizar antes de
# incrementarle el conteo
smtpd_junk_command_limit = 2

###################################################
#	Chequeos de mensajes[ESPECIFICO] con RE
###################################################

body_checks        = pcre:/etc/postfix/rules/body_checks, regexp:/etc/postfix/rules/avchk, pcre:/etc/postfix/rules/avchkre
header_checks      = pcre:/etc/postfix/rules/header_checks, pcre:/etc/postfix/rules/headerchkmsg
mime_header_checks = pcre:/etc/postfix/rules/mime_header_checks

###################################################
#	Parametros de seguridad SASL/TLS[GENERALES]
###################################################

# Usar como cliente el cifrado TLS, si el otro MTA lo admite
smtp_tls_security_level         = may

# Anunciar a los clientes/servidores el soporte de cifrado TLS, pero no obligar a su uso
smtpd_tls_security_level        = may


smtp_sasl_auth_enable           = no
smtpd_reject_unlisted_recipient = yes
smtpd_reject_unlisted_sender    = yes
smtpd_sasl_authenticated_header = yes

# Habilitar autenticación SASL
smtpd_sasl_auth_enable          = yes

# Compatibilidad con clientes de correo viejos como Outlook Express 4
# o MS Exchange 5.0
broken_sasl_auth_clients        = yes

# Deshabilitar otros comandos que no pertenecen al protocolo SMTP
smtpd_forbidden_commands = CONNECT, EXPN, GET, PASS, POST, USER

# Dovecot SASL support.

smtpd_sasl_type                 = dovecot
smtpd_sasl_path                 = private/dovecot-auth

# Reino (ámbito) de autenticación local SASL
smtpd_sasl_local_domain         = inutil.cu

# Mecanismos de authenticación SASL que Postfix usará para sesiones TLS
# (la autenticación sin TLS está deshabilitada, por lo que no hace falta
# declarar smtpd_sasl_security_options)
smtpd_sasl_tls_security_options = noanonymous
#smtpd_sasl_security_options     = noanonymous

# No anunciar o soportar autenticación SASL sobre conexiones en claro
smtpd_tls_auth_only             = yes

# Redes a las que no se ofrecerá soporte AUTH
smtpd_sasl_exceptions_networks = !10.10.0.0/16

smtpd_enforce_tls               = yes
smtpd_use_tls                   = yes
smtp_use_tls                    = yes
smtp_enforce_tls                = no
smtp_tls_note_starttls_offer    = yes


smtpd_tls_received_header       = yes
smtpd_tls_session_cache_timeout = 3600s

############################################################################
# Config TLS/SSL protocols[ESPECIFICO]
############################################################################

smtpd_tls_CAfile              = /etc/postfix/certs/postfix.pem
smtpd_tls_cert_file           = /etc/postfix/certs/postfix.pem
smtpd_tls_key_file            = /etc/postfix/certs/postfix.pem

tls_random_source             = dev:/dev/urandom

smtpd_tls_protocols           = !SSLv2 !SSLv3
smtp_tls_protocols            = !SSLv2 !SSLv3
lmtp_tls_protocols            = !SSLv2 !SSLv3
smtpd_tls_mandatory_protocols = !SSLv2 !SSLv3
smtp_tls_mandatory_protocols  = !SSLv2 !SSLv3
lmtp_tls_mandatory_protocols  = !SSLv2 !SSLv3

# Good bye SSLv3 and fuck you POODLE!!!

############################################################################
# Config TLS/SSL Fix Lockjam attack [ESPECIFICO]
############################################################################

# Archivo de cache para las sesiones TLS de los clientes
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
#
# Archivo de cache para las sesiones TLS de Postfix como cliente
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache

# Dejar en las trazas un sumario de la sesión TLS y los niveles
# de negociación
smtpd_tls_loglevel = 2
smtp_tls_loglevel = 2

smtpd_tls_eecdh_grade = strong
smtpd_tls_ciphers = high
tls_ssl_options = NO_COMPRESSION

# Excluir cifrados nulos (o sea, autenticación sin cifrado)
smtpd_tls_exclude_ciphers = aNULL, eNULL, EXPORT, DES, RC2, IDEA, SEED, LOW, RC4, MD5, PSK, aECDH, EDH-DSS-DES-CBC3-SHA, EDH-RSA-DES-CDC3-SHA, KRB5-DE5, CBC3-SHA

# Usar cifrados medios o superiores para TLS mandatorio
smtpd_tls_mandatory_ciphers = medium

# Adicionalmente, excluir cifrados bajos para TLS mandatorio
smtpd_tls_mandatory_exclude_ciphers = aNULL, MD5, DES

smtpd_tls_dh1024_param_file = /etc/postfix/certs/dh_2048.pem
smtpd_tls_dh512_param_file = /etc/postfix/certs/dh_1024.pem
smtp_tls_exclude_ciphers = EXPORT, LOW, MD5, aDSS, kECDHe, kECDHr, kDHd, kDHr,SEED, IDEA, RC2
tls_preempt_cipherlist = yes

###################################################
#	Parametros de seguridad[GENERALES]
###################################################

# Disable the SMTP VRFY command. This stops some techniques used to
# harvest email addresses.
disable_vrfy_command = yes

###################################################
#	EVITAR SUPLANTACION DE IDENTIDAD AL ENVIAR
###################################################

smtpd_sender_login_maps = mysql:/etc/postfix/sql/mysql_sender_login_maps.cf

###################################################
# Restricciones de envio[n/i]/recepcion/suplantacion
###################################################

#smtpd_restriction_classes = cu-in, cu-out, int-in, int-out

#cu-in = check_sender_access regexp:/etc/postfix/rules/cu, reject
#cu-out = check_recipient_access regexp:/etc/postfix/rules/cu, reject
#int-in = check_sender_access regexp:/etc/postfix/rules/int, reject
#int-out = check_recipient_access regexp:/etc/postfix/rules/int, reject

###################################################
#	Parametros de seguridad[RESTRICCIONES]
###################################################

# Requerir que el cliente se presente con el comando HELO/EHLO antes de entregar
smtpd_helo_required = yes

# Esperar al comando RCPT TO antes de evaluar $smtpd_client_restrictions,
# $smtpd_helo_restrictions y $smtpd_sender_restrictions
smtpd_delay_reject = yes

# Restricciones para el equipo del cliente
smtpd_client_restrictions = permit_mynetworks, permit_sasl_authenticated, 
 check_client_access cidr:/etc/postfix/rules/local_network.cidr, 
 reject_unknown_client_hostname, permit

# Restricciones para la identificación del cliente
smtpd_helo_restrictions = permit_mynetworks, permit_sasl_authenticated,
 reject_non_fqdn_helo_hostname, reject_invalid_helo_hostname, 
 reject_unknown_helo_hostname, reject_unknown_sender_domain, reject_invalid_hostname,
 check_helo_access pcre:/etc/postfix/rules/helo_checks,
 check_client_access cidr:/etc/postfix/rules/local_network.cidr
 permit

# Restricciones para los remitentes
smtpd_sender_restrictions = permit_mynetworks, permit_sasl_authenticated,
 reject_sender_login_mismatch, reject_unknown_sender_domain, reject_non_fqdn_sender,
 reject_unlisted_sender, check_sender_access hash:/etc/postfix/rules/spamaddress,
 #check_recipient_access hash:/etc/postfix/rules/access-in,

# Restricciones para destinatarios y relay
smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated,
 reject_unknown_sender_domain, reject_unknown_recipient_domain,
 reject_unlisted_recipient, reject_non_fqdn_recipient, 
 #check_sender_access hash:/etc/postfix/rules/access-out,
 reject_unauth_destination, check_policy_service unix:private/policy-spf,
 check_sender_mx_access cidr:/etc/postfix/rules/bogus_mx,
 reject_rbl_client dsn.rfc-ignorant.org,
 reject_rbl_client dul.dnsbl.sorbs.net,
 reject_rbl_client list.dsbl.org,
 reject_rbl_client sbl-xbl.spamhaus.org,
 reject_rbl_client bl.spamcop.net,
 reject_rbl_client dnsbl.sorbs.net,
 reject_rbl_client cbl.abuseat.org,
 reject_rbl_client ix.dnsbl.manitu.net,
 reject_rbl_client combined.rbl.msrbl.net,
 reject_rbl_client rabl.nuclearelephant.com

# Tiempo de espera para SPF
policy-spf_time_limit = 3600s

smtpd_data_restrictions = reject_unauth_pipelining, reject_multi_recipient_bounce, permit

smtpd_etrn_restrictions = reject

# Drop connections if other server is sending too quickly
postscreen_greet_action = drop


### DNS blocklists
postscreen_dnsbl_threshold = 2
postscreen_dnsbl_sites =    ix.dnsbl.manitu.net*2
                            zen.spamhaus.org*2
postscreen_dnsbl_action = drop

# Tras poner en cola, entregar el contenido a un transporte (Amavis)
#content_filter = smtp-amavis:[127.0.0.1]:10024

###################################################
# Configuracion de ID en los mensajes[ESPECIFICO]
###################################################

enable_long_queue_ids = yes

###################################################
# Configuracion de SMTP[GENERALES]
###################################################

smtp_mx_address_limit   = 5
# from 0 to 5

smtp_connect_timeout    = 30
smtp_helo_timeout       = 60s
smtp_rcpt_timeout       = 240s
smtp_quit_timeout       = 240s
smtp_rset_timeout       = 20s

###################################################
#
# Configuraciones de alias+mailman[ESPECIFICO]
#
###################################################

# Mapeo de alias
alias_database = hash:/etc/aliases
alias_maps = hash:/etc/aliases
#, hash:/var/lib/mailman/data/aliases


# Mailman
transport_maps = hash:/etc/postfix/transport
mailman_destination_recipient_limit = 1
owner_request_special = no

###################################################
#
# Otras configuraciones[ESPECIFICO]
#
###################################################

queue_directory   = /var/spool/postfix
command_directory = /usr/sbin
daemon_directory  = /usr/lib/postfix/sbin
data_directory = /var/lib/postfix
setgid_group = postdrop
mail_owner        = postfix
default_privs     = nobody
unknown_local_recipient_reject_code = 550

local_recipient_maps =  $alias_maps, proxy:unix:passwd.byname

in_flow_delay       = 1s

home_mailbox        = Maildir/

mail_spool_directory = /var/spool/mail

# Debug

debugger_command = PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin
    xxgdb $daemon_directory/$process_name $process_id & sleep 5
    
# Definir para quienes incrementar el nivel de información en las trazas
debug_peer_list = $mydomain

# Nivel de información en las trazas (el valor predeterminado es 2)
# Descomentar y aumentar hasta 4 solo para diagnosticar, pero preferiblemente
# no para producción
debug_peer_level  = 4

sendmail_path = /usr/sbin/sendmail
newaliases_path = /usr/bin/newaliases
mailq_path = /usr/bin/mailq

# Comando externo opcional a usar para la entrega local del correo
mailbox_command = /usr/lib/dovecot/deliver

# Disable the rewriting of "site!user" into "user@site".
swap_bangpath = no

# Disable the rewriting of the form "user%domain" to "user@domain".
allow_percent_hack = no

# Allow recipient address start with '-'.
allow_min_user = no

</main.cf>
	
En el archivo master.cf añadir:

#----------------------------------------------------------------------#

# Dovecot
dovecot   unix  -       n       n       -       -       pipe
    flags=DRhu user=vmail:vmail argv=/usr/lib/dovecot/deliver -d ${recipient}

# Mailman
mailman   unix  -       n       n       -       -       pipe
  flags=FR user=list argv=/usr/lib/mailman/bin/postfix-to-mailman.py
  ${nexthop} ${user}

# SPF
policy-spf unix -       n       n       -       -       spawn
  user=nobody argv=/usr/sbin/postfix-policyd-spf-perl

#----------------------------------------------------------------------#

Los demás archivos de configuración por ser demasiado grandes van incluidos en el compactado adjunto.

Al terminar todos los cambios en el server, reiniciar los servicios y revisar los log para 
chequear que todo está funcionando como debe ser...

# /etc/init.d/nginx restart
# /etc/init.d/mysql restart
# /etc/init.d/saslauthd restart
# /etc/init.d/dovecot restart
# /etc/init.d/postfix restart

Para probar el certificado:

# openssl s_client -starttls smtp -connect mail.inutil.cu:25

Para debuguear posibles errores:

# postfix check

# egrep '(reject|warning|error|fatal|panic):' /var/log/postfix/mail.log

Revisamos con estas 2 líneas la salida de los posibles errores en el postfix.
