#!/bin/bash
#################################################################
# auto-elearning						#
# Instala automáticamente una Wiki (MediaWiki) y un Campus	#
# Virtual (Moodle).						#
# Para ello instala un entorno LEMP (GNU/Linux+Nginx+MySQL/	#
# MariaDB+PHP) o LAMP (GNU/Linux+Apache+MySQL/MariaDB+PHP).	#
# Además instala certificados SSL/TLS válidos de Let's Encrypt	#
# (o auto-firmados) y genera copias de seguridad diariamente.	#
#								#
# Guzman Castanedo Villalba (guzman@castanedo.es) Junio 2018	#
# GPLv3 (https://www.gnu.org/licenses/gpl.html)			#
#################################################################

ayuda() {
# Muestra ayuda al usuario y termina
	echo -en "AYUDA AUTO-ELEARNING:\n"
	echo -en "  Instala automáticamente una Wiki (MediaWiki) y un Campus Virtual (Moodle).\n"
	echo -en "  Para ello instala un entorno LEMP (GNU/Linux+Nginx+MySQL/MariaDB+PHP) o LAMP (GNU/Linux+Apache+MySQL/MariaD+PHP).\n"
	echo -en "  Además instala certificados SSL/TLS válidos de Let's Encrypt (o auto-firmados) y genera copias de seguridad diariamente.\n"
	echo -en "  Licencia: GPLv3 (Autor: Guzmán Castanedo Villalba [guzman@castanedo.es]).\n"
	echo -en "\nSINOPSIS:\n"
	echo -en "    sudo ./"$(basename $0)" (Forma 1)\n"
	echo -en "    sudo ./"$(basename $0)" [OPCIONES] (Forma 2)\n"
	echo -en "\nDESCRIPCIÓN:\n"
	echo -en "  La primera forma permite instalarlo todo de forma INTERACTIVA (contestando a unas preguntas que saldrán por pantalla).\n"
	echo -en "  La segunda forma permite hacer lo mismo de forma NO INTERACTIVA (indicando todas las opciones desde el terminal).\n"
	echo -en "  Esta aplicación requiere de permisos de administrador (root).\n"
	echo -en "\nCOMPATIBILIDAD:\n"
	echo -en "  Esta aplicación es compatible con Ubuntu 18.04, 16.04, Debian 9, CentOS 7 y Fedora 28.\n"
	echo -en "  Requiere de un sistema moderno que tenga instalado SystemD.\n"
	echo -en "  Se irán añadiendo nuevas distribuciones en futuras versiones.\n"
	echo -en "\nOPCIONES:\n"
	echo -en "  -d, --dominio, --fqdn <dominio>: dominio principal del servidor (OBLIGATORIO)\n"
	echo -en "  --lemp: activa servidor web Nginx (Por Defecto)\n"
	echo -en "  --lamp: activa servidor web Apache2\n"
	echo -en "  --mariadb: activa base de datos mariadb (Por Defecto)\n"
	echo -en "  --mysql: activa base de datos mysql\n"
	echo -en "    Sólo es posible para Ubuntu 18.04\n"
	echo -en "  --password-sql <pass>: contraseña root de base de datos (OBLIGATORIO)\n"
	echo -en "  --max-upload-size <size>: tamaño de subida permitido (Por Defecto: \"100M\")\n"
	echo -en "  --lets-encrypt: activa certificados SSL/TLS de Let's Encrypt\n"
	echo -en "  --auto-firmados: activa certificadaos SSL/TLS auto-firmados (sólo para pruebas)\n"
	echo -en "\nOPCIONES MEDIA WIKI:\n"
	echo -en "  --media-wiki: activa instalación de Media Wiki (Por Defecto)\n"
	echo -en "    Si se activa esta opción --nombre-mw, --dominios-mw y --password-mw son OBLIGARIOS\n"
	echo -en "  --no-media-wiki: desactiva instalación de Media Wiki\n"
	echo -en "  --nombre-mw <nombre>: nombre de la wiki\n"
	echo -en "  --dominios-mw <dominios>: dominios para Media Wiki\n"
	echo -en "    Deben estar configuradas las DNS para que estos apunten a este servidor\n"
	echo -en "    Se pueden indicar más de uno separándolos con espacios\n"
	echo -en "  --password-mw <pass>: contraseña para usuario 'admin'\n"
	echo -en "\nOPCIONES MOODLE:\n"
	echo -en "  --moodle: activa instalación de Moodle (Por Defecto)\n"
	echo -en "    Si se activa esta opción --nombre-mo, --nombre-corto-mo, --dominios-mo y --password-mo son OBLIGARIOS\n"
	echo -en "  --no-moodle: desactiva instalación de Moodle\n"
	echo -en "  --nombre-mo <nombre>: nombre del campus\n"
	echo -en "  --nombre-corto-mo <nombre>: nombre corto del campus (una sola palabra)\n"
	echo -en "  --dominio-mo <dominio>: dominio para Moodle\n"
	echo -en "    Deben estar configuradas las DNS para que estos apunten a este servidor\n"
	echo -en "    Sólo se puede indicar UN DOMINIO\n"
	echo -en "  --password-mo <pass>: contraseña para usuario 'admin'\n"
	echo -en "\nOTRAS OPCIONES:\n"
	echo -en "  --php-info: activa info.php (sólo para pruebas)\n"
	echo -en "  --no-php-info: desactiva info.php (Por Defecto)\n"
	echo -en "  --backup: activa los backups automáticos (Por Defecto)\n"
	echo -en "  --no-backup: desactiva los backups automáticos\n"
	echo -en "\nEJEMPLOS:\n"
	echo -en "  sudo "$0"\n"
	echo -en "    Activa el programa en modo interactivo\n"
	echo -en "  sudo "$0" -d ejemplo.com --lemp --mariadb --password-sql 123456 --media-wiki --nombre-mw \"Wiki de Ejemplo\" --dominios-mw \"ejemplo.com www.ejemplo.com wiki.ejemplo.com\" --password-mw qwerty --no-moodle\n"
	echo -en "    Instala LEMP con mariadb y Media Wiki\n"
	echo -en "  sudo "$0" -d ejemplo.com --lamp --mysql --password-sql 123456 --no-media-wiki --moodle --nombre-mo \"Campus Virtual\" --nombre-corto-mo EJEMPLO --dominio-mo moodle.ejemplo.com --password-mo qwerty\n"
	echo -en "    Instala LAMP con MySQL y Moodle\n\n"
}

comprobarError() {
# Permite comprobar si se ha producido un error y de serlo devuelve un código de error
# comprobarError exitNum codeNum extraInfo
#	1xx: Servidor Web
#	2xx: Base de Datos
#	3xx: PHP
#	4xx: SSL/TLS
#	5xx: MediaWiki
#	6xx: Moodle
#	7xx: Backup automático
#	8xx: Dependencias
#	9xx: Servicios & Firewall
	
	type="ERROR"
	exitNum=$1
	shift
	codeNum=$1
	shift
	extraInfo=$@
	case $codeNum in
		1)
			error="$type $codeNum:\tInstalación interrumpida por el usuario.\n"
			;;
		2)
			error="$type $codeNum:\tError interno (selección express).\n"
			;;
		3)
			error="$type $codeNum:\tError interno (selección avanzada).\n"
			;;
		4)
			error="\n$type $codeNum:\tEl archivo '"$(realpath $extraInfo)"' no existe.\n"
			;;
		5)
			error="\n$type $codeNum:\tEl directorio '"$(realpath $extraInfo)"' no existe.\n"
			;;
		6)
			error="$type $codeNum:\tError interno (selección SSL/TLS).\n"
			;;
		10)
			error="$type $codeNum:\tOpción inesperada '$extraInfo'.\n"
			;;
		11)
			error="$type $codeNum:\tDominio Principal no definido ('--hostname \"ejemplo.com\"').\n"
			;;
		12)
			error="$type $codeNum:\tContraseña SQL no definida ('--password-sql \"pass\"').\n"
			;;
		13)
			error="$type $codeNum:\tTamaño de subida no definido ('--max-upload-size \"100M\"').\n"
			;;
		14)
			error="$type $codeNum:\tNombre Media Wiki no definida (--nombre-mw \"Wiki de Ejemplo\").\n"
			;;
		15)
			error="$type $codeNum:\tDominios Media Wiki no definidos (--dominios-mw \"ejemplo.com wiki.ejemplo.com\").\n"
			;;
		16)
			error="$type $codeNum:\tContraseña Media Wiki no definida (--password-mw \"pass\").\n"
			;;
		17)
			error="$type $codeNum:\tNombre Moodle no definido (--nombre-mo \"Campus Virtual de Ejemplo\").\n"
			;;
		18)
			error="$type $codeNum:\tNombre Corto Moodle no definido (--nombre-corto-mo \"Ejemplo\").\n"
			;;
		19)
			error="$type $codeNum:\tDominio Moodle no definido (--dominio-mo \"moodle.ejemplo.com\").\n"
			;;
		20)
			error="$type $codeNum:\tContraseña Moodle no definida (--password-mo \"pass\").\n"
			;;
		100)
			error="$type $codeNum:\tError interno (selección del servidor web).\n"
			;;
		101)
			error="\n$type $codeNum:\tError al instalar Apache2.\nDetalles:\n$extraInfo\n"
			;;
		102)
			error="\n$type $codeNum:\tError al instalar Nginx.\nDetalles:\n$extraInfo\n"
			;;
		103)
			error="\n$type $codeNum:\tError al nstalar repositorio 'epel-release'.\nDetalles:\n$extraInfo\n"
			;;
		104)
			error="\n$type $codeNum:\tError interno (instalación Apache2).\n"
			;;
		105)
			error="\n$type $codeNum:\tError interno (instalación Nginx).\n"
			;;
		106)
			type="WARNING"
			error="\n$type $codeNum:\tImposible instalar 'info.php'.\n"
			;;
		107)
			error="\n$type $codeNum:\tError al configurar Nginx.\n"
			;;
		108)
			error="\n$type $codeNum:\tError al configurar Apache2.\n"
			;;
		200)
			error="$type $codeNum:\tError interno (selección de base de datos).\n"
			;;
		201)
			error="\n$type $codeNum:\tError al instalar MySQL.\nDetalles:\n$extraInfo\n"
			;;
		202)
			error="\n$type $codeNum:\tError al instalar MariaDB.\nDetalles:\n$extraInfo\n"
			;;
		203)
			error="\n$type $codeNum:\tError interno (instalación MySQL).\n"
			;;
		204)
			error="\n$type $codeNum:\tError interno (instalación MariaDB).\n"
			;;
		205)
			error="\n$type $codeNum:\t$DIST no incluye MySQL en sus repositorios.\n"
			;;
		206)
			type="WARNING"
			error="\n$type $codeNum:\tUsuario 'root' ya dispone de contraseña."
			;;
		207)
			error="\n$type $codeNum:\tImposible cambiar la contraseña de 'root'."
			;;
		208)
			error="\n$type $codeNum:\tImposible desactivar acceso 'root' desde el exterior."
			;;
		209)
			error="\n$type $codeNum:\tImposible eliminar usuarios anónimos."
			;;
		210)
			type="WARNING"
			error="\n$type $codeNum:\tImposible eliminar bases de datos de pruebas."
			;;
		211)
			type="WARNING"
			error="\n$type $codeNum:\tImposible eliminar los permisos de las bases de datos de pruebas."
			;;
		212)
			error="\n$type $codeNum:\tImposible recargar base de datos."
			;;
		213)
			error="\n$type $codeNum:\tImposible configurar SQL.\n"
			;;
		214)
			type="WARNING"
			error="\n$type $codeNum:\tSQL ya está configurado."
			;;
		300)
			error="\n$type $codeNum:\tError interno (instalación PHP-7).\n"
			;;
		301)
			error="\n$type $codeNum:\tError interno (Web Server no seleccionado).\n"
			;;
		302)
			error="\n$type $codeNum:\tError al instalar PHP-7.\nDetalles:\n$extraInfo\n"
			;;
		303)
			error="\n$type $codeNum:\tError al instalar Repositorio Remi.\nDetalles:\n$extraInfo\n"
			;;
		304)
			error="\n$type $codeNum:\tSistema Operativo no compatible con PHP-7 ($OS $DIST $REV).\n"
			;;
		305)
			error="\n$type $codeNum:\tImposible configurar PHP-7.\n"
			;;
		401)
			error="\n$type $codeNum:\tError al instalar 'certbot' (Let's Encrypt).\n"
			;;
		402)
			error="\n$type $codeNum:\tImposible generar Certificados Autofirmados.\n"
			;;
		403)
			error="\n$type $codeNum:\tImposible generar claves de intercambio Diffie-Hellman.\n"
			;;
		404)
			error="\n$type $codeNum:\tImposible generar Certificados Let's Encrypt.\n"
			;;
		501)
			error="\n$type $codeNum:\tImposible descargar MediaWiki-1.31.0.\n"
			;;
		502)
			error="\n$type $codeNum:\tImposible configurar MediaWiki-1.31.0.\n"
			;;
		503)
			type="WARNING"
			error="\n$type $codeNum:\tYa existe una copia configurada de MediaWiki en el dominio: '$extraInfo'."
			;;
		601)
			error="\n$type $codeNum:\tImposible descargar Moodle-3.5.1.\n"
			;;
		602)
			error="\n$type $codeNum:\tImposible configurar Moodle-3.5.1.\n"
			;;
		603)
			type="WARNING"
			error="\n$type $codeNum:\tYa existe una copia configurada de Moodle en el dominio: '$extraInfo'."
			;;
		604)
			error="\n$type $codeNum:\tImposible configurar SELinux.\n"
			;;
		605)
			error="\n$type $codeNum:\tImposible instalar 'policycoreutils-python'.Detalles:\n$extraInfo\n"
			;;
		701)
			type="WARNING"
			error="\n$tupe $codeNum:\tImposible configurar actualizaciones automáticas.\n"
			;;
		800)
			error="$type $codeNum:\tEs necesario ser root ('sudo $0').\n"
			;;
		801)
			error="$type $codeNum:\t'whiptail' no instalado.\n"
			;;
		802)
			error="$type $codeNum:\t'hostnamectl' no instalado.\n"
			;;
		803)
			error="$type $codeNum:\t'apt-get' no instalado.\n"
			;;
		804)
			error="$type $codeNum:\t'yum' no instalado.\n"
			;;
		805)
			error="\n$type $codeNum:\tImposible actualizar repositorio\nDetalles:\n$extraInfo.\n"
			;;
		806)
			error="$type $codeNum:\t'ufw' no instalado.\nDetalles:\n$extraInfo\n"
			;;
		807)
			error="$type $codeNum:\t'firewall-cmd' no instalado.\n"
			;;
		808)
			error="$type $codeNum:\t'tput' no instalado.\nDetalles:\n$extraInfo\n"
			;;
		809)
			error="$type $codeNum:\t'sed' no instalado.\nDetalles:\n$extraInfo\n"
			;;
		810)
			error="$type $codeNum:\t'curl' no instalado.\nDetalles:\n$extraInfo\n"
			;;
		811)
			error="$type $codeNum:\t'tar' no instalado.\nDetalles:\n$extraInfo\n"
			;;
		812)
			error="$type $codeNum:\t'gzip' no instalado.\nDetalles:\n$extraInfo\n"
			;;
		813)
			error="$type $codeNum:\t'bzip2' no instalado.\nDetalles:\n$extraInfo\n"
			;;
		814)
			error="$type $codeNum:\t'xz' no instalado.\nDetalles:\n$extraInfo\n"
			;;
		815)
			error="$type $codeNum:\t'openssl' no instalado.\nDetalles:\n$extraInfo\n"
			;;
		816)
			error="$type $codeNum:\t'find' no instalado.\n"
			;;
		817)
			error="$type $codeNum:\tLa Distribución '$OS $DIST $REV' no está soportada.\nSoportadas: Ubuntu 16.04, 18.04, Debian 9, CentOS 7 y Fedora 28.\n"
			;;
		900)
			error="$type $codeNum:\tError interno (habilitar servicio).\n"
			;;
		901)
			error="$type $codeNum:\tImposible encender servicio '$extraInfo'.\n"
			;;
		902)
			error="$type $codeNum:\tImposible habilitar servicio '$extraInfo' durante el arranque.\n"
			;;
		903)
			error="$type $codeNum:\tError interno (deshabilitar servicio).\n"
			;;
		904)
			error="$type $codeNum:\tImposible parar servicio '$extraInfo'.\n"
			;;
		905)
			error="$type $codeNum:\tImposible deshabilitar servicio '$extraInfo' durante el arranque.\n"
			;;
		906)
			type="WARNING"
			error="\n$type $codeNum:\tImposible añadir regla al cortafuegos ('$extraInfo').\n"
			;;
		907)
			type="WARNING"
			error="\n$type $codeNum:\tImposible encender cortafuegos.\n"
			;;
		908)
			error="\n$type $codeNum:\tError interno (instalar Virtual Host).\n"
			;;
		909)
			error="\n$type $codeNum:\tVirtual Host '$extraInfo' no existe.\n"
			;;
		910)
			error="\n$type $codeNum:\tImposible copiar Virtual Host '$extraInfo'.\n"
			;;
		911)
			error="\n$type $codeNum:\tImposible activar Virtual Host '$extraInfo'.\n"
			;;
		912)
			error="\n$type $codeNum:\tError interno (recargar servicio).\n"
			;;
		913)
			error="\n$type $codeNum:\tImposible recargar servicio '$extraInfo'.\n"
			;;
		*)
			error="ERROR 13:\tError interno (comprobación de errores)\n"
			exitNum=1
			codeNum=13
			;;
	esac
	if [ $exitNum -ne 0 ];then
		echo -en "$error" | tee -a $logFile
		if [ $type = "ERROR" ];then
			exit $codeNum
		fi
	fi
	unset error exitNum codeNum type
}

OSInfo() {
# Detecta el OS en el que se está ejecutando el programa, así como su versión
# Sólo continuará si se trata de una distribución compatible
	echo -en "Detectando SO..." >> $logFile
	OS=$(uname -s)
	if [ $OS = "Linux" ]; then
		OS="GNU/Linux"
		if [ -f /etc/os-release ]; then
			DIST=$(grep ^NAME= /etc/os-release | cut -d = -f 2 | cut -d '"' -f 2)
			REV=$(grep ^VERSION= /etc/os-release | cut -d = -f 2 | cut -d '"' -f 2)
			ID=$(grep ^ID= /etc/os-release | cut -d = -f 2 | cut -d '"' -f 2)
			VERSION=$(grep ^VERSION_ID= /etc/os-release | cut -d = -f 2 | cut -d '"' -f 2)
			for i in $ID; do
				case $i in
					debian)
						case $VERSION in
							9)
								# Debian 9 Soportado
								;;
							*)
								comprobarError 1 817
								;;
						esac
						break
						;;
					ubuntu)
						case $VERSION in
							18.04)
								# Ubuntu 18.04 Soportado
								;;
							16.04)
								# Ubuntu 16.04 Soportado
								;;
							*)
								comprobarError 1 817
								;;
						esac
						break
						;;
					rhel|centos)
						case $VERSION in
							7)
								# CentOS 7 Soportado
								;;
							*)
								comprobarError 1 817
								;;
						esac
						break
						;;
					fedora)
						case $VERSION in
							28)
								# Fedora 28 Soportado
								;;
							*)
								comprobarError 1 817
								;;
						esac
						break
						;;
					*)
						comprobarError 1 817
						;;
				esac
			done
		else
			# Other Linux (No Soportado)
			comprobarError 1 817
		fi
	else
		# UNIX, OS X, ... (No Soportado)
		comprobarError 1 817
	fi
	echo -en " $OS $DIST $REV\n" >> $logFile
	HDInfo=$(df -h | head -1)"\n"$(df -h | grep ^/dev/sd)"\n"$(df -h | grep ^/dev/mapper)
	echo -en "$HDInfo\n" >> $logFile
}

comprobarRoot() {
# Comprueba si se está ejecutando con privilegios de root
	comprobarError $(id -u) 800
}

comprobarDependencias() {
# Comprueba si están instalados todos los programas necesarios.
# En la mayoría de los casos, trata de instalarlos.
	# Comprobamos whiptail
	which whiptail > /dev/null 2>&1
	comprobarError $? 801
	# Comprobamos hostnamectl
	which hostnamectl > /dev/null 2>&1
	comprobarError $? 802
	which find > /dev/null 2>&1
	comprobarError $? 816
	case $ID in
		debian|ubuntu)
			# Comprobamos apt-get
			which apt-get > /dev/null 2>&1
			comprobarError $? 803
			# Actualizamos base de datos del repositorio
			echo -en "Actualizando repositorio APT..." | tee -a $logFile
			result=$(apt-get -q -y update 2>&1)
			comprobarError $? 805 $result
			echo -en " OK.\n" | tee -a $logFile
			# Comprobamos Firewall (ufw)
			which ufw > /dev/null 2>&1
			if [ $? -ne 0 ];then
				result=$(apt-get -q -y install ufw 2>&1)
				comprobarError $? 806 $result
			fi
			# Comprobamos tput
			which tput > /dev/null 2>&1
			if [ $? -ne 0 ];then
				result=$(apt-get -q -y install ncurses-bin 2>&1)
				comprobarError $? 808 $result
			fi
			# Comprobar sed
			which sed > /dev/null 2>&1
			if [ $? -ne 0 ];then
				result=$(apt-get -q -y install sed 2>&1)
				comprobarError $? 809 $result
			fi
			# Comprobar curl
			which curl > /dev/null 2>&1
			if [ $? -ne 0 ];then
				result=$(apt-get -q -y install curl 2>&1)
				comprobarError $? 810 $result
			fi
			# Comprobamos tar, gzip, bzip2 y xz
			which tar > /dev/null 2>&1
			if [ $? -ne 0 ];then
				result=$(apt-get -q -y install tar 2>&1)
				comprobarError $? 811 $result
			fi
			which gzip > /dev/null 2>&1
			if [ $? -ne 0 ];then
				result=$(apt-get -q -y install gzip 2>&1)
				comprobarError $? 812 $result
			fi
			which bzip2 > /dev/null 2>&1
			if [ $? -ne 0 ];then
				result=$(apt-get -q -y install bzip2 2>&1)
				comprobarError $? 813 $result
			fi
			which xz > /dev/null 2>&1
			if [ $? -ne 0 ];then
				result=$(apt-get -q -y install xz-utils 2>&1)
				comprobarError $? 814 $result
			fi
			which openssl > /dev/null 2>&1
			if [ $? -ne 0 ];then
				result=$(apt-get -q -y install openssl 2>&1)
				comprobarError $? 815 $result
			fi
			;;
		centos|fedora)
			# Comprobamos yum
			which yum > /dev/null 2>&1
			comprobarError $? 804
			# Actualizamos base de datos del repositorio
			echo -en "Actualizando repositorio YUM..." | tee -a $logFile
			result=$(yum -y makecache 2>&1)
			comprobarError $? 805 $result
			echo -en " OK.\n" | tee -a $logFile
			# Comprobamos Firewall (firewall-cmd)
			which firewall-cmd > /dev/null 2>&1
			comprobarError $? 807
			# Comprobamos tput
			which tput > /dev/null 2>&1
			if [ $? -ne 0 ];then
				result=$(yum -y install ncurses 2>&1)
				comprobarError $? 808 $result
			fi
			# Comprobar sed
			which sed > /dev/null 2>&1
			if [ $? -ne 0 ];then
				result=$(yum -y install sed 2>&1)
				comprobarError $? 809 $result
			fi
			# Comprobar curl
			which curl > /dev/null 2>&1
			if [ $? -ne 0 ];then
				result=$(yum -y install curl 2>&1)
				comprobarError $? 810 $result
			fi
			# Comprobamos tar, gzip, bzip2 y xz
			which tar > /dev/null 2>&1
			if [ $? -ne 0 ];then
				result=$(yum -y install tar 2>&1)
				comprobarError $? 811 $result
			fi
			which gzip > /dev/null 2>&1
			if [ $? -ne 0 ];then
				result=$(yum -y install gzip 2>&1)
				comprobarError $? 812 $result
			fi
			which bzip2 > /dev/null 2>&1
			if [ $? -ne 0 ];then
				result=$(yum -y install bzip2 2>&1)
				comprobarError $? 813 $result
			fi
			which xz > /dev/null 2>&1
			if [ $? -ne 0 ];then
				result=$(yum -y install xz 2>&1)
				comprobarError $? 814 $result
			fi
			which openssl > /dev/null 2>&1
			if [ $? -ne 0 ];then
				result=$(yum -y install openssl 2>&1)
				comprobarError $? 815 $result
			fi
			;;
	esac
}

inicializarVariables() {
# Inicializa las variables que necesitan de un estado previo
	apacheOn=false
	nginxOn=false
	mySQLOn=false
	mariaDBOn=false
	phpOn=false
	sslOn=false
	letsEncryptOn=false
	mediaWikiOn=false
	moodleOn=false
	infoPHPOn=false
	backupOn=false
	hostname=""
	logFile="./."$(basename $0)".log"
	maxUpload="100M"
	webServerName=""
	webServerUser=""
	webServerGroup=""
	sqlServerName=""
	dbType=""
	phpFPMName=""
	nombreMediaWiki=""
	dominioMediaWiki=""
	passwdMediaWiki=""
	nombreMoodle=""
	nombreCortoMoodle=""
	dominioMoodle=""
	passwdMoodle=""
}

instalacionExpress() {
# Permite una instalación rápida, haciendo el menor número de preguntas
# Defecto: Nginx + MariaDB + PHP + Let's Encrypt + MediaWiki + Moodle + Backup
	nginxOn=true
	case $ID in
		debian)
			mySQLOn=true
			dbType="mariadb"
			;;
		ubuntu|centos|fedora)
			mariaDBOn=true
			dbType="mariadb"
			;;
	esac
	phpOn=true
	sslOn=true
	letsEncryptOn=true
	mediaWikiOn=true
	moodleOn=true
	backupOn=true
}

mostrarBienvenida() {
# Pantalla de bienvenida y muestra SO y estado de los discos
	ANCHO=$(tput cols)
	ALTO=$(tput lines)
	whiptail --title "INSTALACION AUTO-ELEARNING" --yesno "Este script automatiza completamente la instalación de una WIKI y un CAMPUS VIRTUAL.\nPara ello instala un servidor LAMP o LEMP, MediaWiki, Moodle y configura todo lo necesario.\n\nInformación del sistema:\nOS: $OS $DIST $REV\n$HDInfo" $((ALTO * 9 / 10)) $((ANCHO * 9 / 10)) --yes-button "Continuar" --no-button "Salir"
	comprobarError $? 1
}

mostrarExpress() {
# Pantalla de elección entre instalación express o avanzada
	express=$(whiptail --title "INSTALACION EXPRESS" --radiolist "<ESPACIO>: seleccionar   <TAB>: cambiar   <FLECHAS>: moverse\n\nLa instalación express instala Nginx, MariaDB, PHP-7, Let's Encrypt, MediaWiki, Moodle y backups automáticos.\nSeleccione el tipo de instalación que desee:" $((ALTO * 9 / 10)) $((ANCHO * 9 / 10)) 2 \
	"Express" "Instalación rápida" ON \
	"Avanzada" "Permite escoger todas las opciones disponibles" OFF \
	--ok-button "Continuar" --cancel-button "Salir" 3>&1 1>&2 2>&3)
	comprobarError $? 1
	case $express in
		Express)
			instalacionExpress
			# Preguntas mínimas
			establecerFQDN
			leerSQLPasswd
			mostrarMediaWiki
			mostrarMoodle
			mostrarConfirmacion
			;;
		Avanzada)
			mostrarAvanzada
			;;
		*)
			comprobarError 1 2
			;;
	esac
	unset express
}

mostrarAvanzada() {
# Pantalla que permite instalar un servidor LAMP o LEMP
	webServer=$(whiptail --title "INSTALACION AVANZADA" --radiolist "<ESPACIO>: seleccionar   <TAB>: cambiar   <FLECHAS>: moverse\n\nEscoge el tipo de SERVIDOR WEB a instalar:" $((ALTO * 9 / 10)) $((ANCHO * 9 / 10)) 2 \
	"LEMP" "GNU/Linux + (E)Nginx + MySQL/MariaDB + PHP-7" ON \
	"LAMP" "GNU/Linux + Apache + MySQL/MariaDB + PHP-7" OFF \
	--ok-button "Continuar" --cancel-button "Salir" 3>&1 1>&2 2>&3)
	comprobarError $? 1
	for i in $webServer; do
		case $i in
			LEMP)
				nginxOn=true
				;;
			LAMP)
				apacheOn=true
				;;
			*)
				comprobarError 1 100
				;;
		esac
	done
	# Opciones comunes
	establecerFQDN
	mostrarDatabase
	phpOn=true
	establecerMaxUpload
	mostrarComponentes
	mostrarConfirmacion
	unset webServer
}

leerSQLPasswd() {
# Pantalla para leer la contraseña para el usuario root de SQL
	control=false
	error=""
	# Leemos la contreseña (stdin) y confirmamos
	while [ $control = false ]; do
		sqlPasswd=$(whiptail --title "CONTRASEÑA SQL" --passwordbox "$error""Introduzca la CONTRASEÑA para el usuario 'root' de la base de datos:" $((ALTO * 9 / 10)) $((ANCHO * 9 / 10)) --ok-button "Continuar" --nocancel 3>&1 1>&2 2>&3)
		comprobarError $? 1
		sqlPasswd2=$(whiptail --title "CONTRASEÑA SQL" --passwordbox "Confirme la CONTRASEÑA:" $((ALTO * 9 / 10)) $((ANCHO * 9 / 10)) --ok-button "Continuar" --nocancel 3>&1 1>&2 2>&3)
		comprobarError $? 1
		#echo -en "SQL Password 1: $sqlPasswd\n"
		#echo -en "SQL Password 2: $sqlPasswd2\n"
		if [ -z "$sqlPasswd" ] || [ -z "$sqlPasswd2" ]; then
			error="ERROR: LA CONTRASEÑA NO PUEDE ESTAR VACIA.\n"
		elif [ $sqlPasswd != $sqlPasswd2 ];then
			error="ERROR: LAS CONTRASEÑAS NO COINCIDEN.\n"
		else
			control=true
		fi
	done
	#echo -en "SQL Password: $sqlPasswd\n"
	unset control error sqlPasswd2
}

establecerFQDN() {
# Configura el FQDN (dominio principal del servidor)
	while [ -z "$hostname" ]; do
		hostname=$(whiptail --title "FQDN" --inputbox "El nombre de DOMINIO PRINCIPAL (FQDN) de este servidor es:\n"$(hostname)"\n\n¿Quieres cambiarlo por otro?" $((ALTO * 9 / 10)) $((ANCHO * 9 / 10)) --ok-button "Cambiar" --cancel-button "No Cambiar" 3>&1 1>&2 2>&3)
		if [ $? -eq 0 ] && [ ! -z "$hostname" ]; then
			hostnamectl set-hostname $hostname
		else
			hostname=$(hostname)
		fi
	done
	echo -en "Hostname: $hostname\n" >> $logFile
}

mostrarDatabase() {
# Pantalla que permite escoger entre instalar MariaDB o MySQL
	case $ID in
		debian)
			whiptail --title "BASE DE DATOS" --yesno "Para su distribucion $OS $DIST $REV, sólo está disponible la base de datos MariaDB." $((ALTO * 9 / 10)) $((ANCHO * 9 / 10)) --yes-button "Continuar" --no-button "Salir"
			comprobarError $? 1
			# Excepción: aunque es MariaDB (se instala con el nombre de mysql-server)
			mySQLOn=true
			dbType="mariadb"
			;;
		ubuntu)
			case $VERSION in
				18.04)
					database=$(whiptail --title "BASE DE DATOS" --radiolist "<ESPACIO>: seleccionar   <TAB>: cambiar   <FLECHAS>: moverse\n\nEscoge la BASE DE DATOS que quieres usar:" $((ALTO * 9 / 10)) $((ANCHO * 9 / 10)) 2 \
					"MariaDB" "Instalar la base de datos MariaDB (fork de MySQL)" ON \
					"MySQL" "Instalar la base de datos MySQL (uso no comercial)" OFF \
					--ok-button "Continuar" --cancel-button "Salir" 3>&1 1>&2 2>&3)
					comprobarError $? 1
					case $database in
						MariaDB)
							mariaDBOn=true
							dbType="mariadb"
							;;
						MySQL)
							mySQLOn=true
							dbType="mysqli"
							;;
						*)
							comprobarError 1 200
							;;
					esac
					;;
				16.04)
					# Ubuntu 16.04 presenta un bug en MySQL (así que lo deshabilitamos)
					whiptail --title "BASE DE DATOS" --yesno "Para su distribucion $OS $DIST $REV, sólo está disponible la base de datos MariaDB." $((ALTO * 9 / 10)) $((ANCHO * 9 / 10)) --yes-button "Continuar" --no-button "Salir"
					comprobarError $? 1
					mariaDBOn=true
					dbType="mariadb"
					;;
			esac
			;;
		centos|fedora)
			whiptail --title "BASE DE DATOS" --yesno "Para su distribucion $OS $DIST $REV, sólo está disponible la base de datos MariaDB." $((ALTO * 9 / 10)) $((ANCHO * 9 / 10)) --yes-button "Continuar" --no-button "Salir"
			comprobarError $? 1
			mariaDBOn=true
			dbType="mariadb"
			;;
		*)
			comprobarError 1 200
			;;
	esac
	# Otras opciones (contraseña)
	leerSQLPasswd
}

establecerMaxUpload() {
# Pantalla para establecer el máximo de subida al servidor (vía PHP)
	control=false
	error=""
	while [ $control = false ];do
		maxUpload2=$(whiptail --title "PHP MAX UPLOAD" --inputbox "$error""Introduzca el TAMAÑO MAXIMO permitido de los ficheros subidos al servidor:\n(<K:Kilobyte>   <M:Megabyte>   <G:Gigabyte>)" $((ALTO * 9 / 10)) $((ANCHO * 9 / 10)) $maxUpload --ok-button "Continuar" --cancel-button "Salir" 3>&1 1>&2 2>&3)
		comprobarError $? 1
		if [ -z "$maxUpload2" ];then
			error="ERROR: NO PUEDES DEJAR ESTE PARÁMETRO VACIO.\n"
		else
			control=true
		fi
	done
	maxUpload=$maxUpload2
	unset control maxUpload2
}

mostrarComponentes() {
# Pantalla de elección de componentes (SSL/TLS, MediaWiki, Moodle, InfoPHP y Backup)
	componentes=$(whiptail --title "INSTALACION AVANZADA" --checklist "<ESPACIO>: seleccionar   <TAB>: cambiar   <FLECHAS>: moverse\n\nEscoja los componentes a instalar:" $((ALTO * 9 / 10)) $((ANCHO * 9 / 10)) 5 \
	"SSL/TLS" "Instalar certificados para activar HTTPS" ON \
	"MediaWiki" "Instalar wiki con MediaWiki" ON \
	"Moodle" "Instalar campus virtual con Moodle" ON \
	"InfoPHP" "Instalar info.php (sólo para pruebas)" OFF \
	"Backup" "Programar backups automáticos" ON \
	--ok-button "Continuar" --cancel-button "Salir" 3>&1 1>&2 2>&3)
	comprobarError $? 1
	for i in $componentes; do
		case $i in
			\"SSL/TLS\")
				# 2 Opciones: Let's Encrypt o Autofirmado
				mostrarSSL
				;;
			\"MediaWiki\")
				mediaWikiOn=true
				mostrarMediaWiki
				;;
			\"Moodle\")
				moodleOn=true
				mostrarMoodle
				;;
			\"InfoPHP\")
				infoPHPOn=true
				;;
			\"Backup\")
				backupOn=true
				;;
			*)
				comprobarError 1 3
				;;
		esac
	done
	unset componentes
}

mostrarSSL() {
# Pantalla que permite seleccionar el tipo de certificados
	ssl=$(whiptail --title "INSTALACION SSL/TLS" --radiolist "<ESPACIO>: seleccionar   <TAB>: cambiar   <FLECHAS>: moverse\n\nEscoja el tipo de Certificado SSL/TLS a instalar:" $((ALTO * 9 / 10)) $((ANCHO * 9 / 10)) 2 \
	"LetsEncrypt" "Compatible con todos los navegadores" ON \
	"Auto-Firmado" "Certificados auto-firmados (sólo para pruebas)" OFF \
	--ok-button "Continuar" --cancel-button "Salir" 3>&1 1>&2 2>&3)
	comprobarError $? 1
	for i in $ssl; do
		case $i in
			LetsEncrypt)
				sslOn=true
				letsEncryptOn=true
				;;
			Auto-Firmado)
				sslOn=true
				;;
			*)
				comprobarError 1 6
				;;
		esac
	done
	unset ssl
}

mostrarMediaWiki(){
# Pantalla que pregunta sobre las opciones necesarias para configurar MediaWiki
	# Introducir nombre wiki
	while [ -z "$nombreMediaWiki" ]; do
		nombreMediaWiki=$(whiptail --title "CONFIGURACION MEDIAWIKI" --inputbox "Introduzca el NOMBRE de la Wiki:" $((ALTO * 9 / 10)) $((ANCHO * 9 / 10)) --ok-button "Continuar" --cancel-button "Salir" 3>&1 1>&2 2>&3)
		comprobarError $? 1
	done
	# Introducir dominio
	while [ -z "$dominioMediaWiki" ]; do
		dominioMediaWiki=$(whiptail --title "CONFIGURACION MEDIAWIKI" --inputbox "Introduzca el DONIMIO/SUBDOMINIO de la Wiki.\nTenga en cuenta que el dominio debe de apuntar a la dirección IP de la máquina mediante un registro DNS.\nSi quiere introducir varios dominios sepárelos con espacios.\nEl primero será el principal.\nPor ejemplo: 'www.$hostname $hostname wiki.$hostname'" $((ALTO * 9 / 10)) $((ANCHO * 9 / 10)) wiki.$hostname --ok-button "Continuar" --cancel-button "Salir" 3>&1 1>&2 2>&3)
		comprobarError $? 1
	done
	cont=1
	serverName=""
	aliasMediaWiki=""
	for dominio in $dominioMediaWiki;do
		if [ $cont -eq 1 ];then
			# Dominio Principal (ServerName)
			serverName=$dominio
		else
			# Dominios Secundarios (ServerAlias)
			aliasMediaWiki=$aliasMediaWiki" "$dominio
		fi
		cont=$((cont + 1))
	done
	dominioMediaWiki=$serverName
	# Introducir contraseña
	control=false
	error=""
	while [ $control = false ]; do
		passwdMediaWiki=$(whiptail --title "CONFIGURACION MEDIAWIKI" --passwordbox "$error""Introduzca la CONTRASEÑA para el usuario administrador 'admin':" $((ALTO * 9 / 10)) $((ANCHO * 9 / 10)) --ok-button "Continuar" --nocancel 3>&1 1>&2 2>&3)
		comprobarError $? 1
		passwdMediaWiki2=$(whiptail --title "CONFIGURACION MEDIAWIKI" --passwordbox "Confirme la CONTRASEÑA:" $((ALTO * 9 / 10)) $((ANCHO * 9 / 10)) --ok-button "Continuar" --nocancel 3>&1 1>&2 2>&3)
		comprobarError $? 1
		if [ -z "$passwdMediaWiki" ] || [ -z "$passwdMediaWiki2" ]; then
			error="ERROR: LA CONTRASEÑA NO PUEDE ESTAR VACIA.\n"
		elif [ $passwdMediaWiki != $passwdMediaWiki2 ];then
			error="ERROR: LAS CONTRASEÑAS NO COINCIDEN.\n"
		else
			control=true
		fi
	done
	unset control error passwdMediaWiki2 dominio cont serverName
}

mostrarMoodle() {
# Pantalla que pregunta sobre las opciones necesarias para configurar Moodle
	# Introducir Nombre Moodle
	while [ -z "$nombreMoodle" ]; do
		nombreMoodle=$(whiptail --title "CONFIGURACION MOODLE" --inputbox "Introduzca el NOMBRE COMPLETO del campus virtual.\nPor ejemplo: 'Campus Virtual Ejemplo'." $((ALTO * 9 / 10)) $((ANCHO * 9 / 10)) --ok-button "Continuar" --cancel-button "Salir" 3>&1 1>&2 2>&3)
		comprobarError $? 1
	done
	# Introducir Nombre Corto Moodle
	while [ -z "$nombreCortoMoodle" ]; do
		nombreCortoMoodle=$(whiptail --title "CONFIGURACION MOODLE" --inputbox "Introduzca el NOMBRE CORTO del campus virtual.\nPor ejemplo: 'Ejemplo'." $((ALTO * 9 / 10)) $((ANCHO * 9 / 10)) --ok-button "Continuar" --cancel-button "Salir" 3>&1 1>&2 2>&3)
		comprobarError $? 1
	done
	nombreCortoMoodle=$(echo $nombreCortoMoodle | cut -d ' ' -f 1)
	# Introducir dominio
	while [ -z "$dominioMoodle" ]; do
		dominioMoodle=$(whiptail --title "CONFIGURACION MOODLE" --inputbox "Introduzca el DOMINIO/SUBDOMINIO del campus virtual.\nTenga en cuenta que el dominio debe de apuntar a la dirección IP de la máquina mediante un registro DNS.\nMoodle SÓLO permite un ÚNICO DOMINIO." $((ALTO * 9 / 10)) $((ANCHO * 9 / 10)) moodle.$hostname --ok-button "Continuar" --cancel-button "Salir" 3>&1 1>&2 2>&3)
		comprobarError $? 1
	done
	cont=1
	serverName=""
	aliasMoodle=""
	for dominio in $dominioMoodle;do
		if [ $cont -eq 1 ];then
			# Dominio Principal (ServerName)
			serverName=$dominio
		else
			# Dominios Secundarios (ServerAlias)
			aliasMoodle=$aliasMoodle" "$dominio
		fi
		cont=$((cont + 1))
	done
	dominioMoodle=$serverName
	# Introducir contraseña
	control=false
	error=""
	while [ $control = false ]; do
		passwdMoodle=$(whiptail --title "CONFIGURACION MOODLE" --passwordbox "$error""Introduzca la CONTRASEÑA para el usuario administrador 'admin':" $((ALTO * 9 / 10)) $((ANCHO * 9 / 10)) --ok-button "Continuar" --nocancel 3>&1 1>&2 2>&3)
		comprobarError $? 1
		passwdMoodle2=$(whiptail --title "CONFIGURACION MOODLE" --passwordbox "Confirme la CONTRASEÑA:" $((ALTO * 9 / 10)) $((ANCHO * 9 / 10)) --ok-button "Continuar" --nocancel 3>&1 1>&2 2>&3)
		comprobarError $? 1
		if [ -z "$passwdMoodle" ] || [ -z "$passwdMoodle2" ]; then
			error="ERROR: LA CONTRASEÑA NO PUEDE ESTAR VACIA.\n"
		elif [ $passwdMoodle != $passwdMoodle2 ];then
			error="ERROR: LAS CONTRASEÑAS NO COINCIDEN.\n"
		else
			control=true
		fi
	done
	unset control error passwdMoodle2 dominio cont serverName aliasMoodle
}

mostrarConfirmacion() {
# Pantalla que presenta una confirmación antes de realizar la instalación
	whiptail --title "INSTALACION" --yesno "ESTA TODO LISTO PARA LA INSTALACION.\nNO SE OLVIDE DE GUARDAR LAS CONFIGURACIONES EN UN LUGAR SEGURO, YA QUE SERÁN IMPORTANTES POR SI DESEA REALIZAR ALGÚN CAMBIO EN EL FUTURO.\n¿DESEA CONTINUAR?" $((ALTO * 9 / 10)) $((ANCHO * 9 / 10)) --yes-button "Instalar" --no-button "Salir"
	comprobarError $? 1
}

instalarApache() {
# Instala Apache2
	case $ID in
		debian|ubuntu)
			webServerName="apache2"
			result=$(apt-get -q -y install apache2 2>&1)
			comprobarError $? 101 $result
			;;
		centos|fedora)
			webServerName="httpd"
			result=$(yum -y install httpd 2>&1)
			comprobarError $? 101 $result
			if [ $sslOn = true ];then
				# Instalamos módulo mod_ssl (no se instala por defecto)
				result=$(yum -y install mod_ssl 2>&1)
				comprobarError $? 101 $result
			fi
			;;
		*)
			comprobarError 1 104
			;;
	esac
	deshabilitarServicio $webServerName
}

configurarApache() {
# Configura Apache2
	case $ID in
		debian|ubuntu)
			apacheConfFile="./etc/apache2/apache2.conf"
			if [ ! -f $apacheConfFile ];then
				comprobarError 1 4 $apacheConfFile
			fi
			cp -f $apacheConfFile /etc/$webServerName/apache2.conf 2>/dev/null
			comprobarError $? 108
			webServerUser=$(grep ^User /etc/$webServerName/apache2.conf | cut -d ' ' -f 2)
			webServerGroup=$(grep ^Group /etc/$webServerName/apache2.conf | cut -d ' ' -f 2)
			if [ ! -L /etc/$webServerName/logs ];then
				ln -s /var/log/apache2 /etc/$webServerName/logs 2>/dev/null
				comprobarError $? 108
			fi
			# Activamos mod_rewrite (no viene activado por defecto)
			a2enmod rewrite >/dev/null 2>&1
			comprobarError $? 108
			# Activamos mod_ssl y mod_headers (no viene activado por defecto)
			if [ $sslOn = true ];then
				a2enmod ssl >/dev/null 2>&1
				comprobarError $? 108
				a2enmod headers >/dev/null 2>&1
				comprobarError $? 108
			fi
			unset apacheConfFile
			;;
		centos|fedora)
			apacheConfFile="./etc/apache2/conf/httpd.conf"
			sslConfFile="./etc/apache2/conf.d/ssl.conf"
			welcomeConfFile="/etc/apache2/conf.d/welcome.conf"
			if [ ! -f $apacheConfFile ];then
				comprobarError 1 4 $apacheConfFile
			fi
			cp -f $apacheConfFile /etc/$webServerName/conf/httpd.conf 2>/dev/null
			comprobarError $? 108
			# Desactivamos Mensaje de Bienvenida
			if [ -f $welcomeConfFile ];then
				sed -i -e 's/^/#/' $welcomeConfFile
				comprobarError $? 108
			fi
			# Configuramos mod_ssl
			if [ $sslOn = true ];then
				if [ ! -f $sslConfFile ];then
					comprobarError 1 4 $sslConfFile
				fi
				cp -f $sslConfFile /etc/$webServerName/conf.d/ssl.conf 2>/dev/null
				comprobarError $? 108
			fi
			webServerUser=$(grep ^User /etc/$webServerName/conf/httpd.conf | cut -d ' ' -f 2)
			webServerGroup=$(grep ^Group /etc/$webServerName/conf/httpd.conf | cut -d ' ' -f 2)
			unset apacheConfFile sslConfFile welcomeConfFile
			;;
		*)
			comprobarError 1 108
			;;
	esac
	# Creamos directorios sites-available y sites-enabled
	if [ ! -d "/etc/$webServerName/sites-available" ];then
		mkdir "/etc/$webServerName/sites-available" 2>/dev/null
		comprobarError $? 5 "/etc/$webServerName/sites-available"
	fi
	if [ ! -d "/etc/$webServerName/sites-enabled" ]; then
		mkdir "/etc/$webServerName/sites-enabled" 2>/dev/null
		comprobarError $? 5 "/etc/$webServerName/sites-enabled"
	else
		# Eliminar Virtual Host por defecto
		if [ -f /etc/$webServerName/sites-enabled/000-default.conf ];then
			rm -f /etc/$webServerName/sites-enabled/000-default.conf 2>/dev/null
		fi
	fi
}

instalarNginx() {
# Instala Nginx
	webServerName="nginx"
	case $ID in
		ubuntu|debian)
			result=$(apt-get -q -y install nginx 2>&1)
			comprobarError $? 102 $result
			;;
		centos)
			# Sólo para CentOS
			result=$(yum -y install epel-release)
			comprobarError $? 103 $result
			result=$(yum -y install nginx 2>&1)
			comprobarError $? 102 $result
			;;
		fedora)
			result=$(yum -y install nginx 2>&1)
			comprobarError $? 102 $result
			;;
		*)
			comprobarError 1 105
			;;
	esac
	deshabilitarServicio $webServerName
}

configurarNginx() {
# Configura Nginx
	rm -Rf "/etc/$webServerName/!(sites-available|sites-enabled)" 2>/dev/null
	comprobarError $? 107
	nginxConfFile="./etc/$webServerName"
	if [ -d "$nginxConfFile" ];then
		cp -Rf $nginxConfFile/* /etc/$webServerName/ 2>/dev/null
		comprobarError $? 107
	else
		comprobarError 1 5 "$nginxConfFile"
	fi
	# Creamos directorios sites-available y sites-enabled
	if [ ! -d "/etc/$webServerName/sites-available" ];then
		mkdir "/etc/$webServerName/sites-available" 2>/dev/null
		comprobarError $? 5 "/etc/$webServerName/sites-available"
	fi
	if [ ! -d "/etc/$webServerName/sites-enabled" ]; then
		mkdir "/etc/$webServerName/sites-enabled" 2>/dev/null
		comprobarError $? 5 "/etc/$webServerName/sites-enabled"
	else
		# Eliminar Virtual Host por defecto
		if [ -f /etc/$webServerName/sites-enabled/default ];then
			rm -f /etc/$webServerName/sites-enabled/default 2>/dev/null
		fi
	fi
	# Configuramos Usuario y Grupo
	case $ID in
		debian|ubuntu)
			webServerUser="www-data"
			webServerGroup=$webServerUser
			;;
		centos|fedora)
			webServerUser="nginx"
			webServerGroup=$webServerUser
			;;
	esac
	sed -i '/user /c\user '$webServerUser';' /etc/$webServerName/nginx.conf
	comprobarError $? 107
	unset nginxConfFile
}

instalarVirtualHost() {
# Configuramos un Virtual Host para Apache o Nginx
# Uso: instalarVirtualHost $root $virtualHost $dominio $alias
	if [ $# -ge 3 ];then
		rootVirtualHost=$(realpath $1)
		shift
		virtualHostFile=$(realpath $1)
		shift
		dominioVirtualHost=$1
		virtualHostName=$dominioVirtualHost".conf"
		shift
		aliasVirtualHost=$@
	else
		comprobarError 1 908
	fi
	if [ ! -f $virtualHostFile ];then
		comprobarError 1 909 $virtualHostName
	fi
	if [ $apacheOn = true ];then
		# Configuramos root, dominio y logs
		sed -i '/ServerName /c\\tServerName '"$dominioVirtualHost" $virtualHostFile
		comprobarError $? 908
		if [ ! -z "$aliasVirtualHost" ];then
			sed -i '/ServerName /a\\tServerAlias '"$aliasVirtualHost" $virtualHostFile
			comprobarError $? 908
		fi
		sed -i '/DocumentRoot /c\\tDocumentRoot '"$rootVirtualHost" $virtualHostFile
		comprobarError $? 908
		sed -i '/ErrorLog /c\\tErrorLog logs/'"$dominioVirtualHost"'-error.log' $virtualHostFile
		comprobarError $? 908
		sed -i '/CustomLog /c\\tCustomLog logs/'"$dominioVirtualHost"'-access.log common' $virtualHostFile
		comprobarError $? 908
		if [ $sslOn = true ];then
			sed -i '/SSLCertificateFile /c\\tSSLCertificateFile ssl/'"$dominioVirtualHost"'.crt' $virtualHostFile
			comprobarError $? 908
			sed -i '/SSLCertificateKeyFile /c\\tSSLCertificateKeyFile ssl/'"$dominioVirtualHost"'.key' $virtualHostFile
			comprobarError $? 908
		fi
	elif [ $nginxOn = true ];then
		# Configuramos root, dominio, logs y php-fpm.sock (NGINX)
		sed -i '/root /c\\troot '$rootVirtualHost';' "$virtualHostFile"
		comprobarError $? 908
		sed -i '/server_name /c\\tserver_name '"$dominioVirtualHost"' '"$aliasVirtualHost"';' $virtualHostFile
		comprobarError $? 908
		sed -i '/access_log /c\\taccess_log /var/log/nginx/'"$dominioVirtualHost"'-access.log;' $virtualHostFile
		comprobarError $? 908
		sed -i '/error_log /c\\terror_log /var/log/nginx/'"$dominioVirtualHost"'-error.log;' $virtualHostFile
		comprobarError $? 908
		socket=$(find /var/run/ -type s -name 'php*.sock')
		sed -i '/fastcgi_pass /c\\t\tfastcgi_pass unix:'"$socket"';' $virtualHostFile
		comprobarError $? 908
		if [ $sslOn = true ];then
			sed -i '/ssl_certificate /c\\tssl_certificate ssl/'"$dominioVirtualHost"'.crt;' $virtualHostFile
			comprobarError $? 908
			sed -i '/ssl_certificate_key /c\\tssl_certificate_key ssl/'"$dominioVirtualHost"'.key;' $virtualHostFile
			comprobarError $? 908
		fi
	fi
	# Copiamos ficheros de configuración
	cp -f $virtualHostFile "/etc/$webServerName/sites-available/$virtualHostName" >> $logFile 2>&1
	comprobarError $? 910
	if [ -f "/etc/$webServerName/sites-enabled/$virtualHostName" ];then
		rm -f /etc/$webServerName/sites-enabled/$virtualHostName 2>/dev/null
		comprobarError 911 $virtualHostName
	fi
	ln -s "/etc/$webServerName/sites-available/$virtualHostName" "/etc/$webServerName/sites-enabled/$virtualHostName" >> $logFile 2>&1
	comprobarError $? 911 $virtualHostName
	recargarServicio $webServerName
	unset rootVirtualHost dominioVirtualHost virtualHostFile virtualHostName aliasVirtualHost socket
}

establecerSQLPasswd() {
# Establecemos SQL root passwd y securizamos BD (mysql_secure_installation)
	# Comprobamos si ya tiene una contraseña asignada
	mysql -e "FLUSH PRIVILEGES" >> $logFile 2>&1
	if [ $? -eq 0 ];then
		# Establecemos contraseña del usuario root (y desactivamos posibles plugins para forzar login por contraseña)
		mysql -e "UPDATE mysql.user SET plugin = '', Password = PASSWORD('$sqlPasswd') WHERE User = 'root'" >> $logFile 2>&1
		if [ $? -ne 0 ];then
			# Lo intentamos de otra forma (para versiones modernas de mysql)
			mysql -e "ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '$sqlPasswd'" >> $logFile 2>&1
			comprobarError $? 207
		fi
		# Aplicamos el cambio de contraseña
		mysql -e "FLUSH PRIVILEGES" >> $logFile 2>&1
		# Desactivamos acceso root desde el exterior (solo localhost)
		mysql -u root --password=$sqlPasswd -e "DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1')" >> $logFile 2>&1
		comprobarError $? 208
		# Eliminamos todos los usuarios anónimos
		mysql -u root --password=$sqlPasswd -e "DELETE FROM mysql.user WHERE User=''" >> $logFile 2>&1
		comprobarError $? 209
		# Eliminamos bases de datos 'test'
		mysql -u root --password=$sqlPasswd -e "DROP DATABASE IF EXISTS test" >> $logFile 2>&1
		comprobarError $? 210
		# Eliminamos privilegios de la base de datos 'test'
		mysql -u root --password=$sqlPasswd -e "DELETE FROM mysql.db WHERE Db='test' OR Db='test\\_%'" >> $logFile 2>&1
		comprobarError $? 211
		# Aplicamos los cambios
		mysql -u root --password=$sqlPasswd -e "FLUSH PRIVILEGES" >> $logFile 2>&1
		comprobarError $? 212
	else
		comprobarError 1 206
	fi
}

instalarMySQL() {
# Instala MySQL (sólo para Debian)
	sqlServerName="mysql"
	case $ID in
		debian|ubuntu)
			result=$(apt-get -q -y install mysql-server mysql-client 2>&1)
			comprobarError $? 201 $result
			;;
		centos|fedora)
			# MySQL no disponible en RHEL.
			# No se instalará MySQL en distribuciones RHEL
			comprobarError 1 205
			;;
		*)
			comprobarError 1 203
			;;
	esac
	deshabilitarServicio $sqlServerName
}

instalarMariaDB() {
# Instala MariaDB
	sqlServerName="mariadb"
	case $ID in
		debian)
			result=$(apt-get -q -y install mariadb-server mariadb-client 2>&1)
			comprobarError $? 202 $result
			;;
		ubuntu)
			case $VERSION in
				16.04)
					sqlServerName="mysql"
					;;
			esac
			result=$(apt-get -q -y install mariadb-server mariadb-client 2>&1)
			comprobarError $? 202 $result
			;;
		centos|fedora)
			result=$(yum -y install mariadb-server mariadb 2>&1)
			comprobarError $? 202 $result
			;;
		*)
			comprobarError 1 204
			;;
	esac
	deshabilitarServicio $sqlServerName
}

configurarSQL() {
# Configura BarracudaFS en mysql (necesario para Moodle)
	# Configura MariaDB o MySQL
	case $ID in
		debian|ubuntu)
			sqlConfFile="/etc/mysql/my.cnf"
			;;
		centos|fedora)
			sqlConfFile="/etc/my.cnf"
			;;
		*)
			comprobarError 1 213
			;;
	esac
	if [ ! -f $sqlConfFile ];then
		comprobarError 1 213
	fi
	grep "# Configuration for Moodle" $sqlConfFile >/dev/null 2>&1
	if [ $? -ne 0 ];then
		# Establecemos UTF8 (codificación de caracteres) y Barracuda (sistema de ficheros)
		echo -en "\n# Configuration for Moodle\n" >> $sqlConfFile
		echo -en "[client]\n" >> $sqlConfFile
		echo -en "default-character-set = utf8mb4\n\n" >> $sqlConfFile
		echo -en "[mysqld]\n" >> $sqlConfFile
		echo -en "innodb_file_format = Barracuda\n" >> $sqlConfFile
		echo -en "innodb_file_per_table = 1\n" >> $sqlConfFile
		echo -en "innodb_large_prefix\n\n" >> $sqlConfFile
		echo -en "character-set-server = utf8mb4\n" >> $sqlConfFile
		echo -en "collation-server = utf8mb4_unicode_ci\n" >> $sqlConfFile
		echo -en "skip-character-set-client-handshake\n\n" >> $sqlConfFile
		echo -en "[mysql]\n" >> $sqlConfFile
		echo -en "default-character-set = utf8mb4\n" >> $sqlConfFile
	else
		comprobarError 1 214
	fi
	unset sqlConfFile
}

instalarPHP() {
# Instalamos PHP-7 y los módulos PHP que necesitan MediaWiki y Moodle
	case $ID in
		debian)
			phpFPMName="php7.0-fpm"
			if [ $apacheOn = true ]; then
				result=$(apt-get -q -y install php libapache2-mod-php php-mysql php-intl php-mbstring php-xml php-apcu php-gd php-curl php-zip php-soap php-xmlrpc 2>&1)
				comprobarError $? 302 $result
			elif [ $nginxOn = true ];then
				result=$(apt-get -q -y install php-fpm php-mysql php-intl php-mbstring php-xml php-apcu php-gd php-curl php-zip php-soap php-xmlrpc 2>&1)
				comprobarError $? 302 $result
				deshabilitarServicio $phpFPMName
			else
				comprobarError 1 301
			fi
			;;
		ubuntu)
			case $VERSION in
				18.04)
					phpFPMName="php7.2-fpm"
					;;
				16.04)
					phpFPMName="php7.0-fpm"
					;;
			esac
			if [ $apacheOn = true ]; then
				result=$(apt-get -q -y install php libapache2-mod-php php-mysql php-intl php-mbstring php-xml php-apcu php-gd php-curl php-zip php-soap php-xmlrpc 2>&1)
				comprobarError $? 302 $result
			elif [ $nginxOn = true ];then
				result=$(apt-get -q -y install php-fpm php-mysql php-intl php-mbstring php-xml php-apcu php-gd php-curl php-zip php-soap php-xmlrpc 2>&1)
				comprobarError $? 302 $result
				deshabilitarServicio $phpFPMName
			else
				comprobarError 1 301
			fi
			;;
		centos)
			phpFPMName="php-fpm"
			# Necesitamos un repositorio adicional para PHP-7 (EPEL-RELEASE) sólo en CentOS
			result=$(yum -y install epel-release yum-utils 2>&1)
			comprobarError $? 103 $result
			# Necesitamos un repositorio adicional para PHP-7 (REMI-RELEASE)
			if [ ! -f /etc/yum.repos.d/remi-php72.repo ];then
				result=$(yum -y install "http://remi.mirrors.cu.be/enterprise/remi-release-7.rpm" 2>&1)
				comprobarError $? 303 $result
			fi
			# Activamos repositorio remi-php72
			result=$(yum-config-manager --enable remi-php72 2>&1)
			comprobarError $? 303 $result
			# Instalamos PHP-7.2
			if [ $apacheOn = true ];then
				result=$(yum -y install php php-mysql php-intl php-mbstring php-mcrypt php-xml php-pecl-apcu php-gd php-pear-Net-Curl php-pecl-zip php-soap php-xmlrpc 2>&1)
				comprobarError $? 302 $result
			elif [ $nginxOn = true ];then
				result=$(yum -y install php php-fpm php-mysql php-intl php-mbstring php-mcrypt php-xml php-pecl-apcu php-gd php-pear-Net-Curl php-pecl-zip php-soap php-xmlrpc 2>&1)
				comprobarError $? 302 $result
				deshabilitarServicio $phpFPMName
			else
				comprobarError 1 301
			fi
			;;
		fedora)
			phpFPMName="php-fpm"
			# Instalamos PHP-7.2
			if [ $apacheOn = true ];then
				result=$(yum -y install php php-mysqlnd php-intl php-mbstring php-pecl-mcrypt php-xml php-pecl-apcu php-gd php-pear-Net-Curl php-pecl-zip php-soap php-xmlrpc php-json 2>&1)
				comprobarError $? 302 $result
			elif [ $nginxOn = true ];then
				result=$(yum -y install php php-fpm php-mysqlnd php-intl php-mbstring php-pecl-mcrypt php-xml php-pecl-apcu php-gd php-pear-Net-Curl php-pecl-zip php-soap php-xmlrpc php-json 2>&1)
				comprobarError $? 302 $result
				deshabilitarServicio $phpFPMName
			else
				comprobarError 1 301
			fi
			;;
		*)
			comprobarError 1 300
			;;
	esac
}

configurarPHP() {
# Configura PHP para segurizarlo y establecer máximo de subida.
	case $ID in
		debian)
			phpConfFile="./etc/php/php.ini.debian"
			phpDest="/etc/php/7.0/cli/php.ini"
			;;
		ubuntu)
			phpConfFile="./etc/php/php.ini.debian"
			case $VERSION in
				18.04)
					phpDest="/etc/php/7.2/cli/php.ini"
					;;
				16.04)
					phpDest="/etc/php/7.0/cli/php.ini"
					;;
			esac
			;;
		centos|fedora)
			phpConfFile="./etc/php/php.ini.rhel"
			phpDest="/etc/php.ini"
			;;
		*)
			comprobarError 1 305
			;;
	esac
	if [ ! -f $phpConfFile ];then
		comprobarError 1 4 "$phpConfFile"
	fi
	# Copiamos configuración
	cp -f $phpConfFile $phpDest 2>/dev/null
	comprobarError $? 305
	# Configuramos cgi.fix_pathinfo
	sed -i '/cgi.fix_pathinfo=/c\cgi.fix_pathinfo=0' $phpDest
	comprobarError $? 305
	# Configuramos post_max_size
	sed -i '/post_max_size =/c\post_max_size = '$maxUpload $phpDest
	comprobarError $? 305
	# Configuramos upload_max_filesize
	sed -i '/upload_max_filesize =/c\upload_max_filesize = '$maxUpload $phpDest
	comprobarError $? 305
	# Configurar php-fpm (sólo en RHEL con Nginx)
	case $ID in
		centos|fedora)
			if [ $nginxOn = true ];then
				# Configurar Socket UNIX
				phpConfFile="./etc/php/php-fpm.d/www.conf"
				phpDest="/etc/php-fpm.d/www.conf"
				if [ ! -f $phpConfFile ];then
					comprobarError $? 4 "$phpConfFile"
				fi
				cp -f $phpConfFile $phpDest 2>/dev/null
				comprobarError $? 305
				# Configurar Permisos /var/lib/php
				chown -R $webServerUser:$webServerGroup /var/lib/php/
				comprobarError $? 305
			fi
			;;
	esac
	
	unset phpConfFile phpDest
}

instalarLetsEncrypt() {
# Instala certbot (para certificados Let's Encrypt)
	# Comprobamos si cerbot está instalado
	which certbot > /dev/null 2>&1
	if [ $? -ne 0 ];then
		# Descargar Let's Encrypt, hacer ejecutable e instalar
		curl -o ./var/certbot https://dl.eff.org/certbot-auto 2>/dev/null
		comprobarError $? 401
		chmod 755 ./var/certbot 2>/dev/null
		comprobarError $? 401
		cp -f ./var/certbot /usr/bin/certbot 2>/dev/null
		comprobarError $? 401
		# Configurar /etc/cron.d/certbot para renovar automáticamente los certificados
		echo -en "# /etc/cron.d/certbot: certbot autorenew the certificates twice a day\n" > /etc/cron.d/certbot
		echo -en "SHELL=/bin/sh\n" >> /etc/cron.d/certbot
		echo -en "PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin\n\n" >> /etc/cron.d/certbot
		echo -en "# Job start twice per day (4am & 2pm) in a random minute" >> /etc/cron.d/certbot
		echo -en "0 4,14 * * * root python -c 'import random; import time; time.sleep(random.random() * 3600)' && certbot renew\n" >> /etc/cron.d/certbot
	fi
}

generarCertLetsEncrypt() {
# Generar Certificados SEGUROS Let's Encrypt
	dominios=""
	if [ $apacheOn = true ];then
		# Usamos plugin para apache
		if [ $mediaWikiOn = true ];then
			if [ ! -z "$aliasMediaWiki" ];then
				dominios=$dominioMediaWiki$(echo "$aliasMediaWiki" | sed -e 's/ /,/g')
			else
				dominios=$dominioMediaWiki
			fi
			certbot -n --agree-tos --email "admin@$hostname" --apache --domains "$dominios" >> $logFile 2>&1
			comprobarError $? 404
		fi
		if [ $moodleOn = true ];then
			certbot -n --agree-tos --email "admin@$hostname" --apache --domains "$dominioMoodle" >> $logFile 2>&1
			comprobarError $? 404
		fi
	elif [ $nginxOn = true ];then
		# Usamos plugin para nginx
		if [ $mediaWikiOn = true ];then
			if [ ! -z "$aliasMediaWiki" ];then
				dominios=$dominioMediaWiki$(echo "$aliasMediaWiki" | sed -e 's/ /,/g')
			else
				dominios=$dominioMediaWiki
			fi
			certbot -n --agree-tos --email "admin@$hostname" --nginx --domains "$dominios" >> $logFile 2>&1
			comprobarError $? 404
		fi
		if [ $moodleOn = true ];then
			certbot -n --agree-tos --email "admin@$hostname" --nginx --domains "$dominioMoodle" >> $logFile 2>&1
			comprobarError $? 404
		fi
	else
		comprobarError 1 404
	fi
	unset dominios
}

generarCertAutofirmado() {
# Genera certificados autofirmados
# Estos certificados no son seguros, pero valen para pruebas o como paso intermedio para obtener los válidos
# Uso: generarCertAutofirmado $dominio
	dominio=$1
	sslDir="/etc/$webServerName/ssl"
	keyFile="$sslDir/$dominio.key"
	reqFile="$sslDir/$dominio.csr"
	certFile="$sslDir/$dominio.crt"
	dhParamFile="$sslDir/dhparam.pem"
	if [ ! -d "$sslDir" ];then
		mkdir "$sslDir" 2>/dev/null
		comprobarError $? 5 "$sslDir"
	fi
	# Generamos clave privada RSA de 2048 bits
	openssl genrsa -out "$keyFile" 2048 >/dev/null 2>&1
	comprobarError $? 402
	# Generamos petición de firma
	echo -en "ES\nMadrid\nMadrid\n$dominio\n$dominio\n$dominio\nadmin@$dominio\n\n\n" | openssl req -new -key "$keyFile" -out "$reqFile" >/dev/null 2>&1
	comprobarError $? 402
	# Autofirmados clave para 2 años (730 días)
	openssl x509 -req -days 730 -in "$reqFile" -signkey "$keyFile" -out "$certFile" >/dev/null 2>&1
	comprobarError $? 402
	# Eliminamos petición
	rm -f $reqFile
	comprobarError $? 402
	# Añadimos clave Diffie-Hellman al certificado
	if [ -f "$dhParamFile" ];then
		cat "$dhParamFile" >> $certFile
		comprobarError $? 402
	fi
	# Cambiamos permisos
	chmod 644 $certFile
	comprobarError $? 402
	chmod 400 $keyFile
	comprobarError $? 402
	unset dominio sslDir keyFile reqFile certFile dhParamFile
}

generarDHParam() {
# Genera clave de intercambio Diffie-Hellman y lo configuramos
# Esto aumenta notablemente la seguridad de SSL/TLS
	sslDir="/etc/$webServerName/ssl"
	dhParamFile="$sslDir/dhparam.pem"
	nginxConfFile="/etc/$webServerName/nginx.conf"
	if [ ! -d "$sslDir" ];then
		mkdir "$sslDir" 2>/dev/null
		comprobarError $? 5 "$sslDir"
	fi
	openssl dhparam -out "$dhParamFile" 2048 >/dev/null 2>&1
	comprobarError $? 403
	# Configuramos Servidor Web
	if [ $nginxOn = true ];then
		sed -i '/ssl_param /c\\tssl_dhparam '$dhParamFile';' $nginxConfFile
		comprobarError $? 403
	fi
#	unset sslDir dhParamFile apacheConfFile nginxConfFile
	unset sslDir dhParamFile nginxConfFile
}

habilitarServicio() {
# Arrancamos y habilitamos el servicio (con SystemD, Upstart o SystemV)
	# Intentamos con systemctl (SystemD)
	#echo -en "Habilitando Servicio '$1'" | tee -a $logFile
	if [ $# -le 0 ];then
		comprobarError 1 900
	fi
	which systemctl > /dev/null 2>&1
	if [ $? -eq 0 ]; then
		#echo -en " (SystemD)..." | tee -a $logFile
		systemctl start $1 > /dev/null 2>&1
		comprobarError $? 901 $1
		systemctl enable $1 > /dev/null 2>&1
		comprobarError $? 902 $1
	else
		# Intentamos con service (Upstart)
		which service > /dev/null 2>&1
		if [ $? -eq 0 ]; then
			#echo -en " (Upstart)..." | tee -a $logFile
			service $1 start > /dev/null 2>&1
			comprobarError $? 901 $1
		else
			# Intentamos con init.d (SystemV)
			#echo -en " (SystemV)..." | tee -a $logFile
			/etc/init.d/$1 start > /dev/null 2>&1
			comprobarError $? 901 $1
		fi
		# Intentamos habilitar en el arranque (Upstart)
		which update-rc.d > /dev/null 2>&1
		if [ $? -eq 0 ];then
			update-rc.d $1 enable
			comprobarError $? 902 $1
		else
			# Intentamos habilitar en el arranque (SystemV)
			which chkconfig > /dev/null 2>&1
			if [ $? -eq 0 ];then
				chkconfig $1 on
				comprobarError $? 902 $1
			else
				# ¿Qué mas opciones nos quedan?
				comprobarError 1 902 $1
			fi
		fi
	fi
	# Mejora: comprobar si el servicio está parado
	#echo -en " OK.\n" | tee -a $logFile
}

deshabilitarServicio() {
# Paramos y deshabilitamos el servicio (con SystemD, Upstart o SystemV)
	# Intentamos con systemctl (SystemD)
	#echo -en "Deshabilitando Servicio '$1'" | tee -a $logFile
	if [ $# -le 0 ];then
		comprobarError 1 903
	fi
	which systemctl > /dev/null 2>&1
	if [ $? -eq 0 ]; then
		#echo -en " (SystemD)..." | tee -a $logFile
		systemctl stop $1 > /dev/null 2>&1
		comprobarError $? 904 $1
		systemctl disable $1 > /dev/null 2>&1
		comprobarError $? 905 $1
	else
		# Intentamos con service (Upstart)
		which service > /dev/null 2>&1
		if [ $? -eq 0 ]; then
			#echo -en " (Upstart)..." | tee -a $logFile
			service $1 stop > /dev/null 2>&1
			comprobarError $? 904 $1
		else
			# Intentamos con init.d (SystemV)
			#echo -en " (SystemV)..." | tee -a $logFile
			/etc/init.d/$1 stop > /dev/null 2>&1
			comprobarError $? 904 $1
		fi
		# Intentamos habilitar en el arranque (Upstart)
		which update-rc.d > /dev/null 2>&1
		if [ $? -eq 0 ];then
			update-rc.d $1 disable
			comprobarError $? 905 $1
		else
			# Intentamos habilitar en el arranque (SystemV)
			which chkconfig > /dev/null 2>&1
			if [ $? -eq 0 ];then
				chkconfig $1 off
				comprobarError $? 905 $1
			else
				# ¿Qué mas opciones nos quedan?
				comprobarError 1 905 $1
			fi
		fi
	fi
	# Mejora: comprobar si el servicio está funcionando
	#echo -en " OK.\n" | tee -a $logFile
}

recargarServicio() {
# Recargamos el servicio (con SystemD, Upstart o SystemV)
	# Intentamos con systemctl (SystemD)
	#echo -en "Recargando Servicio '$1'" | tee -a $logFile
	if [ $# -le 0 ];then
		comprobarError 1 912
	fi
	which systemctl > /dev/null 2>&1
	if [ $? -eq 0 ]; then
		#echo -en " (SystemD)..." | tee -a $logFile
		systemctl reload $1 > /dev/null 2>&1
		comprobarError $? 913 $1
	else
		# Intentamos con service (Upstart)
		which service > /dev/null 2>&1
		if [ $? -eq 0 ]; then
			#echo -en " (Upstart)..." | tee -a $logFile
			service $1 reload > /dev/null 2>&1
			comprobarError $? 913 $1
		else
			# Intentamos con init.d (SystemV)
			#echo -en " (SystemV)..." | tee -a $logFile
			/etc/init.d/$1 reload > /dev/null 2>&1
			comprobarError $? 913 $1
		fi
	fi
	# Mejora: comprobar si el servicio está funcionando
	#echo -en " OK.\n" | tee -a $logFile
}

configurarCortafuegos() {
# Configuramos cortafuegos (añadir reglas y encender)
	# Comprobamos si estamos usando SSH
	esSSH $PPID
	case $ID in
		debian|ubuntu)
			ufw allow 80/tcp >> $logFile 2>&1
			comprobarError $? 906 "80/tcp"
			if [ $sshControl = true ];then
				ufw allow 22/tcp >> $logFile 2>&1
				comprobarError $? 906 "22/tcp"
			fi
			if [ $sslOn = true ];then
				ufw allow 443/tcp >> $logFile 2>&1
				comprobarError $? 906 "443/tcp"
			fi
			ufw --force enable >> $logFile 2>&1
			comprobarError $? 907
			;;
		centos|fedora)
			firewall-cmd --add-port=80/tcp >> $logFile 2>&1
			comprobarError $? 906 "80/tcp"
			if [ $sshControl = true ];then
				firewall-cmd --add-port=22/tcp >> $logFile 2>&1
				comprobarError $? 906 "22/tcp"
			fi
			if [ $sslOn = true ];then
				firewall-cmd --add-port=443/tcp >> $logFile 2>&1
				comprobarError $? 906 "443/tcp"
			fi
			firewall-cmd --runtime-to-permanent >> $logFile 2>&1
			comprobarError $? 907
			habilitarServicio firewalld >> $logFile 2>&1
			comprobarError $? 907
			;;
	esac
	unset sshControl
}

esSSH() {
# Comprobamos si nuestro terminal usa SSH
	p=${1:-$PPID}
	#read pid name x ppid y < <( cat /proc/$p/stat )
	read pid name ppid < <( ps -o pid= -o comm= -o ppid= -p $p)
	[[ "$name" =~ sshd ]] && { sshControl=true; return 0; }
	[ "$ppid" -le 1 ] && { sshControl=false; return 1; }
	esSSH $ppid
}

descargarMediaWiki() {
# Descargar la versión 1.31.0 de MediaWiki
	if [ ! -d ./var ];then
		comprobarError 1 5 "./var"
	fi
	curl "https://releases.wikimedia.org/mediawiki/1.31/mediawiki-1.31.0.tar.gz" 2>/dev/null | tar -xz -C "./var/"
	comprobarError $? 501
}

configurarMediaWiki() {
# Configuramos MediaWiki
	if [ ! -f /var/www/$dominioMediaWiki/LocalSettings.php ];then
		# Copiamos archivos
		cp -fR ./var/mediawiki-1.31.0/ /var/www/$dominioMediaWiki
		comprobarError $? 502
		# Configuramos LocalSettings.php (y crea la base de datos por nosotros)
		nombreDBMW=$(echo $dominioMediaWiki | sed -e 's/\./_/g' | sed -e 's/-/_/g')
		userDBMW=$(echo "mediawiki_user" | sed -e 's/\./_/g' | sed -e 's/-/_/g')
		php /var/www/$dominioMediaWiki/maintenance/install.php --dbname=$nombreDBMW --dbserver="localhost" --installdbuser=root --installdbpass=$sqlPasswd --dbuser=$userDBMW --dbpass=$sqlPasswd --scriptpath="" --lang=es --pass=$passwdMediaWiki --with-extensions "$nombreMediaWiki" "admin" >> $logFile 2>&1
		comprobarError $? 502
		# Configuraciones adicionales
		sed -i '/$wgLanguageCode =/c\$wgLanguageCode = "es";' /var/www/$dominioMediaWiki/LocalSettings.php
		comprobarError $? 502
		sed -i '/$wgEnableEmail =/c\$wgEnableEmail = false;' /var/www/$dominioMediaWiki/LocalSettings.php
		comprobarError $? 502
		sed -i '/$wgEnableUploads =/c\$wgEnableUploads = true;' /var/www/$dominioMediaWiki/LocalSettings.php
		comprobarError $? 502
		echo -en "\$wgArticlePath = \"/wiki/\$1\";\n" >> /var/www/$dominioMediaWiki/LocalSettings.php
		echo -en "\$wgUsePathInfo = true;\n" >> /var/www/$dominioMediaWiki/LocalSettings.php
		echo -en "\$wgGroupPermissions['*']['createaccount'] = true;\n" >> /var/www/$dominioMediaWiki/LocalSettings.php
		echo -en "\$wgGroupPermissions['*']['edit'] = false;\n" >> /var/www/$dominioMediaWiki/LocalSettings.php
		echo -en "\$wgGroupPermissions['*']['read'] = true;\n" >> /var/www/$dominioMediaWiki/LocalSettings.php
		# Actualizamos permisos
		chown -R $webServerUser:$webServerGroup /var/www/$dominioMediaWiki
		comprobarError $? 502
		# Configuramos VirtualHost
		if [ $apacheOn = true ] && [ $sslOn = false ];then
			virtualHost="./etc/apache2/sites-available/mediawiki.conf"
		elif [ $nginxOn = true ] && [ $sslOn = false ];then
			virtualHost="./etc/nginx/sites-available/mediawiki.conf"
		elif [ $apacheOn = true ] && [ $sslOn = true ];then
			virtualHost="./etc/apache2/sites-available/mediawiki-ssl.conf"
		elif [ $nginxOn = true ] && [ $sslOn = true ];then
			virtualHost="./etc/nginx/sites-available/mediawiki-ssl.conf"
		else
			comprobarError 1 502
		fi
		if [ ! -f $virtualHost ];then
			comprobarError $? 502
		fi
		instalarVirtualHost "/var/www/$dominioMediaWiki" $virtualHost $dominioMediaWiki $aliasMediaWiki
		unset virtualHost
	else
		comprobarError 1 503 $dominioMediaWiki
	fi
}

descargarMoodle() {
# Descargar la versión 1.31.0 de MediaWiki
	if [ ! -d ./var ];then
		comprobarError 1 5 "./var"
	fi
	#echo -en "Descargando Moodle-3.5-1..." | tee -a $logFile
	#curl -o "./var/moodle-3.5.1.tgz" "https://download.moodle.org/download.php/direct/stable35/moodle-latest-35.tgz" >> $logFile 2>&1
	curl "https://download.moodle.org/download.php/direct/stable35/moodle-latest-35.tgz" 2>/dev/null | tar -xz -C "./var/"
	comprobarError $? 501
	#echo -en " OK.\n" | tee -a $logFile
}

configurarMoodle() {
# Configurar Moodle
	if [ ! -f /var/www/$dominioMoodle/config.php ];then
		# Copiamos archivos
		cp -Rf ./var/moodle/ /var/www/$dominioMoodle
		comprobarError $? 602
		# Crear carperta de datos (no online)
		if [ ! -d /var/www/moodledata ];then
			mkdir /var/www/moodledata 2>/dev/null
			comprobarError $? 602
		fi
		#Actualizamos permisos
		perm=$(stat -c %a /var/www/moodledata)
		if [ $perm -ne 777 ];then
			chmod -R 777 /var/www/moodledata 2>/dev/null
			comprobarError $? 602
		fi
		perm=$(stat -c %U /var/www/moodledata)
		if [ $perm != "$webServerUser" ];then
			chown -R $webServerUser:$webServerGroup /var/www/moodledata 2>/dev/null
			comprobarError $? 602
		fi
		unset perm
		# Creamos Base de Datos
		nombreDBMo=$(echo $dominioMoodle | sed -e 's/\./_/g' | sed -e 's/-/_/g')
		userDBMo=$(echo "moodle_user" | sed -e 's/\./_/g' | sed -e 's/-/_/g')
		crearDBMoodle
		# Configuramos e instalamos Moodle
		if [ $sslOn = true ];then
			wwwroot="https://$dominioMoodle"
		else
			wwwroot="http://$dominioMoodle"
		fi
		php /var/www/$dominioMoodle/admin/cli/install.php --lang=es --wwwroot="$wwwroot" --dataroot="/var/www/moodledata" --dbtype="$dbType" --dbname="$nombreDBMo" --dbuser="$userDBMo" --dbpass="$sqlPasswd" --fullname="$nombreMoodle" --shortname="$nombreCortoMoodle" --adminuser=admin --adminpass="$passwdMoodle" --adminemail="admin@$dominioMoodle" --agree-license --non-interactive >>$logFile 2>&1
		comprobarError $? 602
		# Actualizamos permisos
		chown -R $webServerUser:$webServerGroup /var/www/$dominioMoodle /var/www/moodledata
		# Configurar SE-Linux (RHEL)
		case $ID in
			centos|fedora)
				configurarSELinux
				;;
		esac
		# Configuramos VirtualHost
		if [ $apacheOn = true ] && [ $sslOn = false ];then
			virtualHost="./etc/apache2/sites-available/moodle.conf"
		elif [ $nginxOn = true ] && [ $sslOn = false ];then
			virtualHost="./etc/nginx/sites-available/moodle.conf"
		elif [ $apacheOn = true ] && [ $sslOn = true ];then
			virtualHost="./etc/apache2/sites-available/moodle-ssl.conf"
		elif [ $nginxOn = true ] && [ $sslOn = true ];then
			virtualHost="./etc/nginx/sites-available/moodle-ssl.conf"
		else
			comprobarError 1 602
		fi
		instalarVirtualHost "/var/www/$dominioMoodle" $virtualHost $dominioMoodle
		unset virtualHost wwwroot
	else
		comprobarError 1 603 $dominioMoodle
	fi
}

crearDBMoodle() {
# Crear base de datos para Moodle
	dbDir="./etc/db"
	if [ ! -d $dbDir ];then
		mkdir $dbDir 2>/dev/null
		comprobarError $? 603
	fi
	dbFile=$dbDir"/moodle.sql"
	echo -en "CREATE DATABASE IF NOT EXISTS $nombreDBMo DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;\n" > $dbFile
	echo -en "GRANT ALL PRIVILEGES ON $nombreDBMo.* TO '$userDBMo'@'localhost' IDENTIFIED BY '$sqlPasswd';\n" >> $dbFile
	mysql -u root --password=$sqlPasswd < $dbFile > /dev/null 2>&1
	control=$?
	rm -f $dbFile 2>/dev/null
	comprobarError $? 603
	comprobarError $control 603
	unset control dbFile dbDir
}

configurarSELinux() {
# Configurar SELinux
	which semanage >/dev/null 2>&1
	if [ $? -ne 0 ];then
		case $ID in
			centos)
				result=$(yum -y install policycoreutils-python 2>&1)
				comprobarError $? 605 $result
				;;
			fedora)
				result=$(yum -y install policycoreutils-python-utils 2>&1)
				comprobarError $? 605 $result
				;;
			*)
				comprobarError 1 604
				;;
		esac
	fi
	semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/moodledata(/.*)?" > /dev/null 2>&1
	#comprobarError $? 604
	restorecon -R /var/www/ > /dev/null 2>&1
	comprobarError $? 604
}

instalarPHPInfo() {
# Instalar fichero info.php y su VirtualHost
	if [ ! -f /etc/$webServerName/sites-enabled/phpinfo.conf ];then
		infoFile="./var/www/info.php"
		if [ ! -f $infoFile ];then
			comprobarError 1 4 "$infoFile"
		fi
		mkdir /var/www/localhost 2>/dev/null
		comprobarError $? 106
		cp -f $infoFile /var/www/localhost/ 2>/dev/null
		comprobarError $? 106
		chown -R $webServerUser:$webServerGroup /var/www/localhost 2>/dev/null
		comprobarError $? 106
		unset infoFile
		# Instalar VirtualHost
		if [ $apacheOn = true ] && [ $sslOn = false ];then
			virtualHost="./etc/apache2/sites-available/phpinfo.conf"
		elif [ $nginxOn = true ] && [ $sslOn = false ];then
			virtualHost="./etc/nginx/sites-available/phpinfo.conf"
		elif [ $apacheOn = true ] && [ $sslOn = true ];then
			virtualHost="./etc/apache2/sites-available/phpinfo-ssl.conf"
		elif [ $nginxOn = true ] && [ $sslOn = true ];then
			virtualHost="./etc/nginx/sites-available/phpinfo-ssl.conf"
		else
			comprobarError 1 106
		fi
		instalarVirtualHost "/var/www/localhost" $virtualHost "localhost"
		unset virtualHost
		return 0
	else
		return 1
	fi
}

configurarBackups() {
# Instala backup-server y lo configura
	letsEncryptCode=""
	if [ ! -d "./var" ];then
		comprobarError 1 5 "./var"
	fi
	which backup-server > /dev/null 2>&1
	if [ $? -ne 0 ];then
		# Descargamos backup-server
		curl "https://code.castanedo.es/guzman/backup-server/archive/2.1.tar.gz" 2>/dev/null | tar -xz -C "./var/"
		if [ $? -ne 0 ];then
			comprobarError 1 701
			return 1
		fi
		# Copiamos backup-server y logrotate
		cp -f ./var/backup-server/backup-server /usr/bin/backup-server
		if [ $? -ne 0 ];then
			comprobarError 1 701
			return 1
		fi
		cp -f ./var/backup-server/scripts/logrotate.d/backup-server /etc/logrotate.d/backup-server
		if [ $? -ne 0 ];then
			comprobarError 1 701
			return 1
		fi
		# Creamos carpeta de backups
		if [ ! -d /var/backup ];then
			mkdir /var/backup 2>/dev/null
			comprobarError $? 5 "/var/backup"
		fi
		# Configuramos cron.d
		if [ $letsEncryptOn = false ];then
			letsEncryptCode="--no-letsencrypt "
		fi
		echo -en "# /etc/cron.d/backup-server: crontab for $hostname\n\n" > /etc/cron.d/backup-server
		echo -en "# Backup every day at 4:00 am\n" >> /etc/cron.d/backup-server
		echo -en "0 4 * * * root [ -x /usr/bin/backup-server ] && /usr/bin/backup-server --xz -u $webServerUser -g $webServerGroup --no-encryption --sql-user root --sql-pass $sqlPasswd --nginx-dir /etc/$webServerName $letsEncryptCode--no-mail --no-gogs --no-postfix --no-dovecot --no-opendkim --no-spf --no-opendmarc --no-amavis --no-spamassassin /var/backup >> /var/log/backup-server.log 2>&1" >> /etc/cron.d/backup-server
		comprobarError $? 701
	fi
	unset letsEncryptCode
}

# Comprobación del sistema e inicialización
	inicializarVariables
	OSInfo

# Leer opciones
	which getopt >/dev/null 2>&1
	if [ $? -eq 0 ] && [ $# -ne 0 ];then
		# Configuración por defecto (opciones de Express)
		instalacionExpress
		# Leer opciones
		TEMP=$(getopt -q -o hd: --longoptions help,dominio:,fqdn:,lamp,lemp,mariadb,mysql,password-sql:,max-upload-size:,letsencrypt,auto-firmados,media-wiki,no-media-wiki,nombre-mw:,dominios-mw:,password-mw:,moodle,no-moodle,nombre-mo:,nombre-corto-mo:,dominio-mo:,password-mo:,php-info,no-php-info,backup,no-backup --name $(basename $0) -- "$@")
		eval set -- $TEMP
		unset TEMP
		while true; do
			case $1 in
				-h|--help)
					ayuda
					exit 0
					;;
				-d|--dominio|--fqdn)
					hostname=$2
					shift 2
					;;
				--lamp)
					apacheOn=true
					shift
					;;
				--lemp)
					nginxOn=true
					shift
					;;
				--mariadb)
					case $ID in
						debian)
							mySQLOn=true
							dbType="mariadb"
							;;
						ubuntu|centos|fedora)
							mariaDBOn=true
							dbType="mariadb"
					esac
					shift
					;;
				--mysql)
					if [ $ID = "ubuntu" ] && [ $VERSION = "18.04" ];then
						mySQLOn=true
						dbType="mysqli"
					else
						# No está soportado
						ayuda
						comprobarError 1 205
					fi
					shift
					;;
				--password-sql)
					sqlPasswd=$2
					shift 2
					;;
				--max-upload-size)
					maxUpload=$2
					shift 2
					;;
				--lets-encrypt)
					sslOn=true
					letsEncryptOn=true
					shift
					;;
				--auto-firmados)
					sslOn=true
					letsEncryptOn=false
					shift
					;;
				--media-wiki)
					mediaWikiOn=true
					shift
					;;
				--no-media-wiki)
					mediaWikiOn=false
					shift
					;;
				--nombre-mw)
					nombreMediaWiki=$2
					shift 2
					;;
				--dominios-mw)
					dominioMediaWiki=$2
					cont=1
					serverName=""
					aliasMediaWiki=""
					for dominio in $dominioMediaWiki;do
						if [ $cont -eq 1 ];then
							# Dominio Principal (ServerName)
							serverName=$dominio
						else
							# Dominios Secundarios (ServerAlias)
							aliasMediaWiki=$aliasMediaWiki" "$dominio
						fi
						cont=$((cont + 1))
					done
					dominioMediaWiki=$serverName
					unset cont serverName dominio
					shift 2
					;;
				--password-mw)
					passwdMediaWiki=$2
					shift 2
					;;
				--moodle)
					moodleOn=true
					shift
					;;
				--no-moodle)
					moodleOn=false
					shift
					;;
				--nombre-mo)
					nombreMoodle=$2
					shift 2
					;;
				--nombre-corto-mo)
					nombreCortoMoodle=$(echo $2 | cut -d ' ' -f 1)
					shift 2
					;;
				--dominio-mo)
					dominioMoodle=$2
					cont=1
					serverName=""
					aliasMoodle=""
					for dominio in $dominioMoodle;do
						if [ $cont -eq 1 ];then
							# Dominio Principal (ServerName)
							serverName=$dominio
						else
							# Dominios Secundarios (ServerAlias)
							aliasMoodle=$aliasMoodle" "$dominio
						fi
						cont=$((cont + 1))
					done
					dominioMoodle=$serverName
					unset cont ServerName dominio aliasMoodle
					shift 2
					;;
				--password-mo)
					passwdMoodle=$2
					shift 2
					;;
				--php-info)
					infoPHPOn=true
					shift
					;;
				--no-php-info)
					infoPHPOn=false
					shift
					;;
				--backup)
					backupOn=true
					shift
					;;
				--no-backup)
					backupOn=false
					shift
					;;
				--)
					#Ultimo
					shift
					break
					;;
				*)
					# Inesperado
					ayuda
					comprobarError 1 10 $1
					;;
			esac
		done
		# Comprobar si los datos son correctos
		if [ -z "$hostname" ];then
			ayuda
			comprobarError 1 11
		else
			hostnamectl set-hostname $hostname >/dev/null 2>&1
		fi
		if [ -z "$sqlPasswd" ];then
			ayuda
			comprobarError 1 12
		fi
		if [ -z "$maxUpload" ];then
			ayuda
			comprobarError 1 13
		fi
		if [ $mediaWikiOn = true ];then
			if [ -z "$nombreMediaWiki" ];then
				ayuda
				comprobarError 1 14
			fi
			if [ -z "$dominioMediaWiki" ];then
				ayuda
				comprobarError 1 15
			fi
			if [ -z "$passwdMediaWiki" ];then
				ayuda
				comprobarError 1 16
			fi
		fi
		if [ $moodleOn = true ];then
			if [ -z "$nombreMoodle" ];then
				ayuda
				comprobarError 1 17
			fi
			if [ -z "$nombreCortoMoodle" ];then
				ayuda
				comprobarError 1 18
			fi
			if [ -z "$dominioMoodle" ];then
				ayuda
				comprobarError 1 19
			fi
			if [ -z "$passwdMoodle" ];then
				ayuda
				comprobarError 1 20
			fi
		fi
		# Comprobaciones
		comprobarRoot
		comprobarDependencias
	else
		# Preguntas interactivas
		# Comprobaciones
		comprobarRoot
		comprobarDependencias
		# Bienvenida
		mostrarBienvenida
		# Selección de componentes (express vs avanzada)
		mostrarExpress
	fi

# Instalación Servidor Web
	horaInicial=$(date +"%s")
	if [ $apacheOn = true ]; then
		echo -en "Instalando Servidor Web Apache..." | tee -a $logFile
		instalarApache
		echo -en " OK.\n" | tee -a $logFile
	elif [ $nginxOn = true ]; then
		echo -en "Instalando Servidor Web Nginx..." | tee -a $logFile
		instalarNginx
		echo -en " OK.\n" | tee -a $logFile
	fi

# Instalación Base de Datos
	if [ $mySQLOn = true ]; then
		echo -en "Instalando Base de Datos MySQL..." | tee -a $logFile
		instalarMySQL
		echo -en " OK.\n" | tee -a $logFile
	elif [ $mariaDBOn = true ]; then
		echo -en "Instalando Base de Datos MariaDB..." | tee -a $logFile
		instalarMariaDB
		echo -en " OK.\n" | tee -a $logFile
	fi

# Instalación PHP-7
	if [ $phpOn = true ]; then
		echo -en "Instalando PHP-7..." | tee -a $logFile
		instalarPHP
		echo -en " OK.\n" | tee -a $logFile
	fi
# Instalación Let's Encrypt
	if [ $letsEncryptOn = true ];then
		echo -en "Instalando Let's Encrypt..." | tee -a $logfile
		instalarLetsEncrypt
		echo -en " OK.\n" | tee -a $logFile
	fi

# Configuración Web Server
	if [ $apacheOn = true ];then
		echo -en "Configurando Servidor Web Apache..." | tee -a $logFile
		configurarApache
		echo -en " OK.\n" | tee -a $logFile
	elif [ $nginxOn = true ]; then
		echo -en "Configurando Servidor Web Nginx..." | tee -a $logFile
		configurarNginx
		echo -en " OK.\n" | tee -a $logFile
	fi

# Configuración Database (Configurar Ficheros, Arrancar Base de Datos, establecer contraseña y configuración segura)
	if [ $mySQLOn = true ] || [ $mariaDBOn = true ];then
		echo -en "Configurando Base de Datos..." | tee -a $logFile
		configurarSQL
		echo -en " OK.\n" | tee -a $logFile
		habilitarServicio "$sqlServerName"
		echo -en "Estableciendo contraseña de la Base de Datos..." | tee -a $logFile
		establecerSQLPasswd
		echo -en " OK.\n" | tee -a $logFile
	fi

# Configuración PHP (cgi.fix_pathinfo=0 y Configurar máximo de subida de archivos)
	if [ $phpOn = true ];then
		echo -en "Configurando PHP-7..." | tee -a $logFile
		configurarPHP
		echo -en " OK.\n" | tee -a $logFile
	fi

# Configuración SSL/TLS
	# Generar certificados auto-firmados
	if [ $sslOn = true ];then
		echo -en "Generando claves de intercambio Diffie-Hellman (puede llevar un largo tiempo)..." | tee -a $logFile
		generarDHParam
		echo -en " OK.\n" | tee -a $logFile
		echo -en "Generando Certificados Auto-Firmados..." | tee -a $logFile
		if [ $mediaWikiOn = true ];then
			generarCertAutofirmado $dominioMediaWiki
		fi
		if [ $moodleOn = true ];then
			generarCertAutofirmado $dominioMoodle
		fi
		if [ $infoPHPOn = true ];then
			generarCertAutofirmado "localhost"
		fi
		echo -en " OK.\n" | tee -a $logFile
	fi

# Arrancar y habilitar todos los servicios (SystemD, Service o SystemV)
	echo -en "Habilitando todos los servicios..." | tee -a $logFile
	if [ $apacheOn = true ] || [ $nginxOn = true ];then
		habilitarServicio $webServerName
	fi
	if [ $nginxOn = true ] && [ $phpOn = true ];then
		habilitarServicio $phpFPMName
	fi
	echo -en " OK.\n" | tee -a $logFile

# Instalar MediaWiki
	if [ $mediaWikiOn = true ]; then
		# Descargar MediaWiki
		echo -en "Descargando MediaWiki-1.31.0..." | tee -a $logFile
		descargarMediaWiki
		echo -en " OK.\n" | tee -a $logFile
		# Configurar MediWiki
		echo -en "Configurando MediaWiki..." | tee -a $logFile
		configurarMediaWiki
		echo -en " OK.\n" | tee -a $logFile
	fi

# Instalar Moodle
	if [ $moodleOn = true ]; then
		# Descargar Moodle
		echo -en "Descargando Moodle-3.5.1..." | tee -a $logFile
		descargarMoodle
		echo -en " OK.\n" | tee -a $logFile
		# Configuración Moodle
		echo -en "Configurando Moodle (puede llevar un tiempo largo)..." | tee -a $logFile
		configurarMoodle
		echo -en " OK.\n" | tee -a $logFile
	fi

# Instalar info.php
	if [ $infoPHPOn = true ];then
		echo -en "Configurando 'info.php'..." | tee -a $logFile
		instalarPHPInfo
		if [ $? -eq 0 ];then
			echo -en " OK.\n" | tee -a $logFile
		else
			echo -en " Ya se encuentra configurado.\n" | tee -a $logFile
		fi
	fi

# Añadir reglas del cortafuegos
	echo -en "Configurando Cortafuegos..." | tee -a $logFile
	configurarCortafuegos
	echo -en " OK.\n" | tee -a $logFile

# Generar certificados Let's Encrypt
	if [ $letsEncryptOn = true ];then
		echo -en "Generando Certificados Válidos Let's Encrypt..." | tee -a $logFile
		generarCertLetsEncrypt
		echo -en " OK.\n" | tee -a $logFile
	fi

# Configurar Backup
	if [ $backupOn = true ]; then
		echo -en "Configurando Backup Automático..." | tee -a $logFile
		configurarBackups
		echo -en " OK.\n" | tee -a $logFile
	fi

# Finalizamos
	horaFinal=$(date +"%s")
	echo -en "\n-------------------------------------------------------------\n" | tee -a $logFile
	echo -en "\t¡INSTALACION FINALIZADA CON EXITO! \n" | tee -a $logFile
	echo -en "\tDuración: "$((horaFinal-horaInicial))" seg." | tee -a $logFile
	echo -en "\n-------------------------------------------------------------\n" | tee -a $logFile
	echo -en " GUARDE LA CONFIGURACION EN UN LUGAR SEGURO\n"
	echo -en " LE SERÁ IMPRESCINDIBLE PARA CUALQUIER CAMBIO FUTURO\n"
	echo -en " Dominio:              $hostname\n"
	echo -en " Usuarios SQL:         root\n"
	echo -en "                       $userDBMW\n"
	echo -en "                       $userDBMo\n"
	echo -en " Contraseña SQL:       $sqlPasswd\n"
	if [ $mediaWikiOn = true ];then
		echo -en " Nombre MediaWiki:     $nombreMediaWiki\n"
		echo -en " Dominios MediaWiki:   $dominioMediaWiki\n"
		for dominio in $aliasMediaWiki;do
			echo -en "                       $dominio\n"
		done
		echo -en " Usuario MediaWiki:    admin\n"
		echo -en " Contraseña MediaWiki: $passwdMediaWiki\n"
	fi
	if [ $moodleOn = true ];then
		echo -en " Nombre Moodle:        $nombreMoodle\n"
		echo -en " Dominio Moodle:       $dominioMoodle\n"
		echo -en " Usuario Moodle:       admin\n"
		echo -en " Contraseña Moodle:    $passwdMoodle"
	fi
	echo -en "\n-------------------------------------------------------------\n"