aaaaaaaaaaaaaaa
  1. Tipos de servidores
  2. Panel de administración de OVH
    1. Vincular un dominio a una IP
  3. Comandos básicos de la shell
  4. Instalar Apache
  5. Instalar PHP
  6. Instalar LAMP
  7. Instalar Apache Tomcat
  8. phpmyadmin
  9. Webmin
    1. Instalar Webmin
  10. Apache
    1. Vincular un dominio a una carpeta del servidor
    2. Configuración general del servidor
    3. Un puerto redirige a una carpeta
  11. php.ini
    1. Algunas variables
    2. Remote File Configurations
    3. Límite de tamaño de un fichero en la subida
  12. FTP
    1. Instalar FTP en webmin
    2. Configuración del FTP
  13. Seguridad
  14. Errores
  15. PHP en un shared hosting
  16. Validar datos con PHP
  17. Ataques comunes
  18. Cookies
  19. Encriptado
  20. Permisos en linux
  21. Copia en linux
  22. Prohibir acceso remoto
  23. Backup de la base de datos
  24. Permitir acceso remoto a la base de datos
  25. No pedir la pass
  26. Crontab
  27. Servidor de correo
  28. mod_rewrite
  29. htaccess
    1. Redirección 301

Tipos de servidores

  1. Compartido (hosting): Permiten servir páginas web y poco más. Tienen una capa de abstracciń que facilita su administración. En este caso, compartimos los recursos de la máquina con los demás usuarios del servidor. Es la empresa de hosting la que se ocupa de realizar las copias de seguridad, de actualizar el software, de la seguridad, etc.
  2. Dedicado: Es un ordenador que podemos administrar a nuestro antojo. Podemos instalarle nuestro propio sistema operativo, aplicaciones, reiniciarlo... Su administración es más compleja, ya que se realiza mediante comandos. Al ser un ordenador físico, si el ordenador falla, podemos perder, de manera irrecuperable, los datos almacenados. Son mucho más caros que los compartidos, empezando su precio a partir de los 30€ mensuales.
  3. VPS (Virtual Private Server): tenemos todas las funcionalidades de un servidor dedicado, aunque la máquina física que estamos utilizando no es enteramente nuestra. Tiene menos recursos (disco duro, RAM...) que un servidor dedicado. Al contrario que en los dedicados, si falla el hardware, no hay problema porque la información está duplicada y nosotros no nos enteraremos del fallo. Es más barato que un servidor dedicado. Al igual que en los servidores dedicados, puedes usarlos para
    • Hosting
    • Reseller (revender alojamiento)
    • Desktop: nos permite conectarnos desde nuestra casa al servidor y utilizarlo como escritorio remoto (usar libreoffice, navegar por internet, instalar aplicaciones de forma visual, etc. )
    • VPN
    • Torretns: tendremos una máquina 24 horas al día descargando información de los torrents.
    • Juegos
    • Aprender

    En general, vienen sin software instalado de serie. Muchos VPS tienen a partir de 2GB de RAM. Para servir páginas web, basta con 256mb como mucho. Tener más RAM es para poder instalar aplicaciones como Cpanel, etc.

    100Mbps de transferencia nos permite tener entre 30-35 páginas web trabajando simultaneamente, sin problemas

    Muchas empresas alquilan y revenden los servicios de OVH, por tanto, esta es una buena empresa a la que comprar directamente, y sin intermediarios, los servicios de VPS.

    Una IP incluída en OVH: esto es muy importante para el posicionamiento. Significa que tu no vas a compartir tu IP con otras 30 máquinas, como ocurre en un alojamiento compartido. Si queremos más IP's, bastará con pagar 2 euros más por IP, una sola vez y tendremos ips que podemos geolocalizar en España.

Panel de administración de OVH

Para un VPS, las opciones de administración estarán en el menú DEDICATED. Las explicaciones siguientes se refieren al contenido de este menú.

VPS -> mi servidor

  1. Activaremos el modo avanzado (advanced mode)
  2. Pulsando en el lápiz podemos cambiarle el nombre
  3. Reboot my VPS: lo borra todo y deja el VPS como estaba cuando lo compramos.

Vincular un dominio a una IP

Lo haremos gestionando las DNS (Domain Name Server). En el caso de OVH:

  1. Entramos en el área de administración del VPS.
  2. Menú Web -> Domains -> pulso sobre el dominio seleccionado.
  3. Zona DNS -> Filtramos por DNS de tipo A.
  4. Pulsamos en el lápiz para editar el dominio que hemos comprado e introducimos la IP que aparecía en el panel de administración del VPS.
  5. Podría ser interesante añadir una nueva entrada de tipo a para el subdominio www.

Cuando modificamos un registro de tipo A, los cambios suelen ser instantáneos. Esto es diferente a cuando modificamos las DNS de los servidores de nuestro proveedor, que los cambios tardan 24-48 horas.

Comandos básicos de la shell

Limpia la pantallaclear
lista los archivos del directorio actualls
Nos dá más información de los ficheros.ls -l #Ubuntu tiene un alias para este comando: ll
Change directorycd [directorio]
Move, mueve o renombra un directorio.mv [origen] [destino]
Make directory,  crea un directorio nuevo.mkdir [directorio]
Elimina un ficherorm [fichero]
Elimina un directoriorm -r [directorio] #No utilizamos el mismo comando para eliminar ficheros y directorios porque no podemos distinguir por el nombre de cuando es una u otra cosa.
print working directory) muestra el directorio actualpwd
copia un fichero o un directoriocp [origen] [destino]
Crea un ficherotouch [fichero]
Muestra el contenido del fichero.cat [fichero]
Muestra el contenido del fichero, página a páginamore [fichero]
Cambia la contraseña del usuario activo.passwd
Descarga la web ubicada en esa url.wget [url]
Conexión por SSH//La contraseña que se nos pedirá, coincidirá la del panel de administración de OVH
ssh [usuario]@[ip]
Conexión por SSH, indicando el usuario//Si ya estábamos logueados con un usuario en Linux, este comando trata de loguearse con ese usuario en lugar de con root
ssh [ip]
Conexión por SSh con la contraseñasudo apt-get install sshpass
sshpass -p [password] ssh [user]@[ip]

En windows, necesitaremos instalar el programa putty para poder ejecutar este comando.

Ejercicio

  1. Crear una carpeta.
  2. Crear un fichero dentro de esa carpeta.
  3. Renombrar la carpeta.
  4. Mover el fichero a la carpeta anterior.
  5. Borrar el fichero y la carpeta.

Instalar un servidor APACHE

Nos permitirá ejecutar páginas html en un servidor web.

  1. Instalamos apache:
    sudo apt-get install apache2 -y
  2. El contenido que querramos publicar lo alojaremos en
    /var/www/html/
    Para visualizarlo, introduciremos en el navegador de raspbian la url localhost
  3. Si queremos modificar el contenido de esta carpeta, tendremos que darle permisos:
    sudo chmod -R 777 /var/www/html/

Instalar PHP

  1. sudo apt-get install php7.0 php7.0-gd sqlite php7.0-sqlite php7.0-curl
  2. Reiniciamos el servidor para que los cambios surtan efecto:
    sudo service apache2 restart

Instalar LAMP

tasksel -lamp server

Instalar Apache Tomcat

  1. Descargamos apache Tomcat
  2. Debemos crear un script de arranque
    sudo gedit /etc/init.d/tomcat
    que tendrá el siguiente código, en el que sustituiremos el valor de la variable CATALINA_HOME por la ubicación de Apache Tomcat
    #!/bin/sh
    # /etc/init.d/tomcat
    # starts the Apache Tomcat service
    ### BEGIN INIT INFO
    # Provides:          tomcat
    # Required-Start:
    # Required-Stop:
    # Default-Start:     2 3 4 5
    # Default-Stop:      0 1 6
    # X-Interactive:     true
    # Short-Description: Start/stop tomcat application server
    ### END INIT INFO
     
    export CATALINA_HOME="/home/pi/Tomcat/apache-tomcat-8.0.41"
    case "$1" in
    start)
      if [ -f $CATALINA_HOME/bin/startup.sh ];
      then
        echo $"Starting Tomcat"
        /bin/su pi $CATALINA_HOME/bin/startup.sh
      fi
      ;;
    stop)
      if [ -f $CATALINA_HOME/bin/shutdown.sh ];
      then
        echo $"Stopping Tomcat"
        /bin/su pi $CATALINA_HOME/bin/shutdown.sh
      fi
      ;;
    *)
      echo $"Usage: $0 {start|stop}"
      exit 1
      ;;
    esac
  3. Hacemos el fichero ejecutable:
    sudo chmod 755 /etc/init.d/tomcat
  4. Damos permisos de ejecución a catalina.sh
    sudo chmod +x [ruta_apache_tomcat]/bin/catalina.sh
  5. Arrancamos el servidor:
    sudo /etc/init.d/tomcat start
  6. Si queremos que este script se ejecute siempre que arranquemos la raspbian:
    sudo update-rc.d tomcat defaults

Subir una aplicación media el administrador de aplicaciones

  1. Debemos tener un usuario con permisos, para ello, editaremos el fichero:
    conf/tomcat-users.xml
  2. y le añadimos el siguiente código:
    <role rolename="manager"/>
    <user username="root" password="pp" roles="manager-gui"/>
  3. Paramos y arrancamos el servidor:
    sudo /etc/init.d/tomcat stop
    sudo /etc/init.d/tomcat start

phpmyadmin

apt-get update && apt-get install phpmyadmin

Corrección del error: Packets larger than max_allowed_packet are not allowed

Editaremos el fichero /etc/my.cnf, añadiendo al final del mismo el siguiente código:

[mysqld]
max_allowed_packet = 1G
innodb_log_file_size = 2G
innodb_log_buffer_size = 512M

innodb_file_format = Barracuda
innodb_file_per_table = 1 
innodb_strict_mode = 0

Cambiar url de acceso

Editaremos el fichero vi /etc/phpmyadmin/apache.conf y cambiamos el primer phpmyadmin por otra cosa:

/etc/apache2/sites-available/000-default.confalias /phpmyadmin /usr/share/phpmyadmin

Webmin

Permite administrar nuestro servidor desde una interfaz web visual, en lugar de utilizando la consola.

Instalar webmin

Es el equivalente gratuito y opensource a cpanel y plesk. Es un panel de control con interfaz visual para gestionar nuestro vps.

  1. Accederemos a este enlace y accederemos a Instaling on Debian, en la columna izquierda.
  2. Antes de instalar webmin, es recomendable tratar de instalar sus dependencias. Podemos hacerlo ejecutando el siguiente código, que aparece en la página en la que acabamos de acceder:
    apt-get install perl libnet-ssleay-perl openssl libauthen-pam-perl libpam-runtime libio-pty-perl apt-show-versions python
  3. Ejecutraremos el comando wget que se muestra. No lo pego aquí para que lo copies de la web y tengas la última versión.
  4. Finalmente ejecutaremos el comando dpkg para realizar la instalación.
  5. Ejecutamos: [miip]:10000
  6. Debemos añadir una excepción de seguridad ya que el vps ha añadido su propio certificado de seguridad y el navegador sólo detecta unos pocos certificados de seguridad oficiales.

Base de datos en webmin

Habrá que actualizarlo: Servers -> MySQL Database Server

Desde aquí podremos crear nuevas bases de datos.

Hacer Backups

Puedo hacer un backup de todas las bases de datos del servidor o meterme dentro de una y hacer un backup de esa.

Es posible programar los backups para que se ejecuten cada cierto tiempo.

Apache

Vincular un dominio a una carpeta del servidor

/etc/apache2/sites-available/000-default.conf<VirtualHost *:80>
	//Si la siguiente línea estuviese comentada, todos los dominios del servidor se ejecutarían en la misma carpeta
	ServerName http://dominio.com/

	ServerAdmin webmaster@localhost
	DocumentRoot /var/www/html/dominio.com

</VirtualHost>

Configuración general del servidor

vi /etc/apache2/apache2.conf#Mantiene abierta la conexión en lugar de abrirla y cerrarla con cada petición (con cada recurso, fotografía, etc.)
KeepAlive On
#Número de peticiones posibles dentro de una misma conexión (tiene que darnos para cargar las fotos, css, etc.)
MaxKeepAliveRequests 100
#Tiempo que durará la conexión
KeepAliveTimeout 5

Configuración de carpetas y subcarpetas. Ahora, cada vez que entramos en un directorio, vemos todos los ficheros que hay dentro, salvo que en dicho directorio exista un fichero index. Para evitar esto, podemos borrar el siguiente código en rojo:

<Directory /var/www/>
	Options Indexes FollowSymLinks
	AllowOverride None
	Require all granted
</Directory>

También podemos bloquear ficheros dentro de una carpeta. El siguiente código bloquea los ficheros llamados amor.php dentro de la carpeta var/www

<Directory /var/www/>
	Options FollowSymLinks
	AllowOverride None
	Require all granted
    
    <Files amor.php>
        Order allow, deny
        Deny from all
	</Files>

</Directory>

Una vez salvados los cambios, habrá que darle al botón de aplicarlos.

Un puerto redirige a una carpeta

vi /etc/apache2/ports.confListen 81
vi /etc/apache2/sites-available/000-default.conf<VirtualHost *:81>
	ServerAdmin webmaster@localhost
	DocumentRoot /var/www/carpeta-nueva
</VirtualHost>

etc/php/7.0

Dentro de esta carpeta están los ficheros de configuración de php.

apache2: la configuración de php para nuestro servidor web.

cli: la configuración de php para nuestra consola.

mods-available: la configuración de los módulos de php.

php.ini

Este archivo contiene información acerca del funcionamiento del servidor apache. Para encontrar su ubicación, podemos ejecutar la función php phpinfo() y su ruta aparecerá en las primeras líneas.

Variables

  1. engine: determina si queremos habilitar o no php dentro del apache.
  2. short_open_tag: permite usar la notación corta. <? en lugar de <?php
  3. asp_tags: permite usar las etiquetas de asp en nuestro código (<%)
  4. precision: los decimales utililizados en nuestras operaciones de coma flotante.
  5. disable_functions: es posible deshabilitar la ejecución de ciertas funciones de php por razones de seguridad. Por ejemplo la función que ejecuta comandos de linux desde php, o la que es capaz de modificar el php.ini desde php, suelen estar deshabilidatas.
  6. expose_php: oculta de las cabeceras que estamos usando php. Puede ser interesante por temas de seguridad.
  7. max_execution_time: define cuantos segundos como máximo puede estar nuestro fichero ejecutándose. 0 es ilimitado.
  8. max_input_vars: define cuantos parámetros GET/POST/COOKIE soporta será posible enviar en cada petición.
  9. memory_limit: define el máximo de memoria RAM que puede consumir un script.
  10. error_reporting: define que tipo de errores van a aparecer por pantalla en caso de error.
  11. default_mimetype: define que va a pasar con nuestros ficheros php (se van a interpretar como páginas web, se van a descargar (el código ya interpretado), etc...)

Remote File Configurations

Es mejor tenerlas deshabilitadas, pero algunos CMS como Wordpress o Joomla los usan para actualizarse.

allow_url_fopen = Off
allow_url_include = Off

Límite de tamaño de un fichero en la subida

Si estamos usando un wordpress y tenemos problemas a la hora de subir ficheros grandes, podemos crear un fichero php.ini y subírlo a la carpeta wp-admin con la siguiente configuración

php.ini
post_max_size = 8M;
upload_max_filesize = 8M;

Directivas php.ini

Podemos conseguir el mismo efecto sin modificar el php.ini. Tendremos que editar (o crear en el caso de que no exista) el archivo .htaccess

Y añadir:

php_value upload_max_filesize 10M

Resolver el error Allowed memory size of 41943040 bytes exhausted (tried to allocate 49152 bytes) in ...

Soluciones:

  • Cambiar el memory_limit en el php.ini del servidor (o en un php.ini dejado en la raíz del server, o si es un wordpress en la raíz de la carpeta wp-admin)
    	
    memory_limit = 256M
    	
    
  • Modificar el .htaccess
    	
    php_value memory_limit 256M
    	
    

FTP

Instalar un servicio de FTP en webmin

  1. Escribimos FTP en la caja de búsqueda de Webmin.
  2. Vamos al primer resultado de búsqueda: Pro FTPD server.
  3. Se nos indica que el módulo no está instalado. Lo instalamos pulsando en el enlace que se nos dá.
  4. El fichero de configuración de este módulo es /etc/proftpd/proftpd.conf.
  5. El módulo instalado coge los usuarios de nuestro vps para establecer conexiones. Sin embargo, si nos conectamos con el usuario root tendremos que hacerlo mediante una conexión segura, escribiendo sftp:// antes de la ip.

Configuración del FTP

Por defecto, el módulo proFTPd no permite el acceso root, aunque esto se puede cambiar.

Crearemos las cuentas de usuario desde la terminal. Estas cuentas de usuario, en el caso de estar usando el módulo proftp, serán a su vez usuarios de FTP.

adduser pablo
Si quisieramos cambiar la password, usaríamos
passwd pablo

Aunque este usuario entra por defecto en su carpeta de usuario, tendrá acceso a todas las carpetas del servidor.

Para limitar los accesos del usuario, usaremos:

vi /etc/passwd#Si en lugar de bash, ponemos false, no será posible acceder por ssh usando esta cuenta (habría que editar /etc/shells y añadir la línea /bin/false)
# Si en lugar de /home/pablo ponermos otra ruta, accederemos a esa ruta por defecto.
pablo:x:1001:1001:Pablo,,,:/home/pablo:/bin/bash

Para evitar que los usuarios puedan navegar por carpetas externas a las que tienen asignadas, habrá descomentar la siguiente línea:

/etc/proftpd/proftpd.conf#DefaultRoot

Para que el usuario no solo pueda ver, sino también modificar el contenido de las carpetas a las que tiene acceso, desde root, por ssh ejecutaremos:

chown -R pablo /var/www

Esto le permitirá modificar el contenido de la carpeta /var/www.

Puertos

Las peticiones http van por el puerto 80.

Las peticiones https van por el 443.

Las peticiones ftp van por el 21.

Las peticiones ssh van por el 22.

Las peticiones para webmin van por el 10000

Menos el puerto 80, de acceso a la web, deberíamos cambiar el resto de los puertos (FTP, SSH, etc.)

Cambiar el puerto SSH

vi /etc/ssh/sshd_configPort 22

Donde pone port, asignaremos un valor por encima de 10000, ya que hay escaneadores de puertos que van escaneando la red, intentando encontrar para cada ip, una vulnerabilidad en el puerto que habitualmente se utiliza para cierto servicio (ftp, ssh, etc). Si no encuentran el puerto, algunos empiezan a escanear desde el primero hasta el último en bsca de esas vulnerabilidades, y por tanto, será mejor asignar un número alto.

Cambiar el puerto FTP

vi /etc/proftpd/proftpd.confPort 21

Cambiar el puerto del WebMin

vi /etc/webmin/miniserv.confport=10000

Principios generales de seguridad.

Algunos tips

Reducir los privilegios. Si una función es accedida sólo dentro de una clase, no necesita poder ser accedida desde fuera y podemos hacerla privada.

Lo simple es más seguro. Cuanto más grande y complejo sea un sistema, más complicado será añadirle seguridad.

Nunca confíes en los usuarios. Cualquiera con un ordenador puede ser un hacker.

Mantén tu código actualizado.

index.php

Este es el fichero que buscará el servidor cuando alguien especifica que quiere acceder mediante el navegador a un directorio, pero no a un archivo. Si no tenemos un fichero index.php incluido en el directorio, es posible que el directorio devuelva la lista de archivos que hay en él, lo cual es un problema de seguridad.

phpinfo() y phpmyadmin

No nos interesa que ninguno de los dos esté presente en nuestro servidor de producción.

Si debemos tener el phpmyadmin en producción, habrá que proteger su acceso mediante password. Una opción puede ser usar el fichero .htaccess para protegerlo, además de la autentificación HTTP que ofrece phpmyadmin.

Para más info:
http://docs.phpmyadmin.net/en/latest/setup.html#securing-your-phpmyadmin-installation

Login

Cuando un usuario falla al tratar de loguerase no deberíamos de indicarlo si ha fallado en el usuario o en la password, porque de lo contrario tendrá la mitad de lo que necesita para acceder a la página.

En el registro, encriptaremos la password y la almacenaremos encriptada en la base de datos.

Luego, en el login, comprobaremos si la password introducido, una vez encriptada, coincide con la que está almacenada en la base de datos.

Magic Quotes

Utiles para prevenir inyección SQL.

Cuando lo activamos, PHP escapa todo lo enviado en peticiones GET, POST y COOKIE.
Es mejor que aprendamos a escapar nosotros mismos esta información y que aprendamos a gestionar inyección SQL por nosotros mismos.

Traían consigo varios problemas que hicieron que se eliminase su uso a partir de PHP 5.4.

Para deshabilitarlo, en el php.ini:

	
magic_quotes_gpc = Off
magic_quotes_runtime = Off
	

Register Globals (eliminado en PHP 5.4)

PHP version < 4.2 → On by default
PHP Version 4.2 >= → Off by default

http://somesite.com/page=1&query=hello

	
<?php echo $page; ?>
<?php echo $query; ?>
	

http://somesite.com/logged_in=true

	
<?php
	if(check_password($username, $password)){
		$logged_in = true;
	}
	if($logged_in){
		//display the page
	}
?>
	
Para evitar este problema debemos tener register_globals en off, o inicializar todas las variables y tener la configurar la gestión de errores para que se nos avise de las variables no inicializadas.

http status codes guide

Error reporting lo configuramos en el php.ini (/etc/php5/apache2 )

  • error_reporting: determina que errores se mostrarán.
  • display_errors: dónde se mostrarán dichos errores
  • log_errors: determina si hay o no log de errores.
  • error_log: el path el log de errores.

Tipos de errores

  • E_ERROR (fatal errors, detienen la ejecución de la página)
  • E_WARNING (non-fatal errors, errores importantes pero que no detienen la ejecución de la página)
  • E_NOTICE (posible error)
  • E_STRICT (>5.0 sugerencias de mejora)
  • E_DEPRECATED (>5.3 el código usado dejará de funcionar en el futuro)
  • E_ALL (todos los errores)
  • http://php.net/manual/en/errorfunc.constants.php

Development error_reporting

< 5.0: error_reporting = E_ALL

5.0 – 5.4: error_reporting = E_ALL | E_STRICT
(Las sugerencias de mejora no fueron incluidas por defecto en la visualización de todos los errores (E_ALL) y debemos incluirla manualmente)

> 5.4: error_reporting = E_ALL

Development y Production

Development: display_errors = on log_errors = off error_log = ''

Production: display_errors = off log_errors = on error_log = /private/path/to/errors.log #error_log = syslog → pone los logs dónde le correponda en función del SO

Firewall

Un firewall es una máquina física que no está en nuestro servidor, sino que está conectada a él. Un host supervisa todos los paquetes que entran y salen de un host, y bloqueará los que puedan contener código malicioso.

Webmin -> Networking -> Linux Firewall -> Setup Firewall

El texto que se indica en Rules File indica el fichero que hay que editar.

El firewall gestiona

  1. Los INPUTS, que son los paquetes que entran en él.
  2. Los OUTPUTS, que son los paquetes que salen de él.
  3. Los FORWARDS, que son los paquetes que nuestro servidor redirige a otros servidores. Estas redirecciones se van haciendo de servidor en servidor hasta que el paquete llega a su destino.

Action to Take: Es lo que se hará por defecto con los paquetes. La diferencia entre drop y reject es que reject informa al usuario de que la petición ha sido rechazada.

Bloquear una ip atacante concreta

Si la ip de entrada (source address or network) es equals [ip] -> Drop

Bloquear una ip a la que nos están atacando concreta

Si la ip de destino (destination address or network) (un servidor vps puede tener varias ips asociadas) es equals [ip] -> Drop

Bloquear las peticiones a cierto puerto

Source TCP or UDP port.

Otros parámetros de configuración

expose_php = Off → es posible ver la versión de PHP en los headers de nuestras peticiones. Esto permitiría a un hacker conocer las vulnerabilidades de nuestro servidor.

curl --head https://pablomonteserin.com/

Disabling configurations

Deshabilitar el uso de ciertas funciones:
disable_functions = show_source, exec, shell_exec, system, passthru, proc_open, popen

Deshabilitar la carga en Apache de dynamic extensions:
enable_dl = Off

PHP en un shared hosting

Lo más cómodo para cambiar la configuración de PHP es editar el fichero php.ini. Si no es posible, podemos usar la función de php ini_set definida en un fichero que debería ser incluido por todos los que queramos que hagan uso de esta configuración.

Ejemplo de uso:

	
<?php
	ini_set('error_reporting', E_ALL ^ E_DEPRECATED);
	ini_set('display_errors', 'Off');
	ini_set('log_errors', 'On');
	ini_set('error_log', '/path/to/errors.log');
?>		
	

Hay algunas configuraciones que no podemos establecer de esta forma; por ejemplo, disable_functions

Validar datos con PHP

Evitar la introducción de valores indeseados en la url

	
<?php 
	function allowed_get_params($allowed_params = []){
		$allowed_array = [];
		foreach ($allowed_params as $param) {
			if(isset($_GET[$param])){
				$allowed_array[$param] = $_GET[$param];
			}else{
				$allowed_array[$param] = NULL;
			}
		}
		return $allowed_array;
	}
	$get_params = allowed_get_params(['username', 'password']);

	var_dump($get_params)
	//allow-parameters.php?username=pablo&password=rqr&oooo=4
 ?>
	
Ver ejemplo.

Validar si se ha escrito algo

		
<?php 
function has_presence($value){
	$trimmed_value = trim($value);
	return isset($trimmed_value) && $trimmed_value!=="";
}

if(has_presence("   ")){
	echo "exito";
}else{
	echo "fracaso";
}

 ?>
		
	
Ver ejemplo.

Validar longitud cadena

		
<?php 
function has_length($value, $options=[]){
	if(isset($options['max']) && (strlen($value) > (int)$options['max'])){
		return false;
	}
	if(isset($options['min']) && (strlen($value) < (int)$options['min'])){
		return false;
	}
	if(isset($options['exact']) && (strlen($value) != (int)$options['exact'])){
		return false;
	}	
	return true;
}

if(has_length("buenos dias", ["min"=>5, "max"=> 18])){
	echo "exito";
}else{
	echo "fracaso";
}
?>
		
	
Ver solución

Evaluar si un número cae dentro de cierto intervalo

		
<?php 
function has_number($value, $options=[]){
	if(!is_numeric($value)){
		return false;
	}
	if(isset($options['max']) && ($value > (int)$options['max'])){
		return false;
	}
	if(isset($options['min']) && ($value < (int)$options['min'])){
		return false;
	}
	return true;
}

if(has_number(43, ["min"=> 33, "max"=>55])){
	echo "exito";
}else echo "fracaso";
?>
		
	
Ver solución

Sanitización o filtrado

Consiste en procesar los datos de entrada para eliminar el posible código malicioso.

  • htmlspecialchars() → HTML encode key chars.
  • htmlentities() → HTML encode.
  • strip_tags() → Elimina todas las etiquetas HTML y PHP.
  • json_encode()
  • mysqli_real_escape_string() → MySQL escape.
  • addslashes()

Ataques comunes

Cross Site Scripting - XSS

Ocurre cuando el usuario es capaz de inyectar javascript en la url y este es ejecutado, por ejemplo porque en alguna parte del código se está haciendo un echo.

Ejecutar javascript dentro de tu página puede servir para robar cookies, o enviar información a otro servidor.

La solución pasa por sanitizar todas las peticiones echas al navegador.

Ver solución

Cross-site request forgery (CSRF)

Una vez que te has logueado en una cuenta privada (facebook, gmail banco), el hacker logra que pulses uno de sus enlaces o visualices cierta foto sin que te hayas deslogueado.

		
<img src=https://bank.com/transfer?amount=1000&to=1238891746” />
		
	

Solución:

  • Las peticiones que hacen cambios deberían ser recogidas siempre con POST.
  • Crear un token en el formulario de envío y comprobarlo en la recepción.

Inyección SQL

Dada la siguiente consulta:

		
$result = mysqli_query("SELECT Username, Password FROM Users WHERE Username = '".$_POST['username']."' and Password = '".$_POST['password']."'"); 		
		
	

Si el usuario introdujese el siguiente usuario en el formulario: ' OR 1=1 #

La consulta que va a ser ejecutada sería esta:

	
SELECT Username, Password FROM Users WHERE Username = '' OR 1=1 #' and Password = '' 
	

La almohadilla (#) le dice aMySQL que todo que le sigue es un comentario y que no debe de hacerle caso. Ejecutará SQL hasta ese punto. Despues 1 es igual a 1, SQL devolverá todos los usuarios y contraseñas de la base de datos. Y como la primera combinación del usuario y de contraseña en la mayoría de las bases de datos es la de el administrador... tendremos un problema.

Solución al problema:

  • Limitar los privilegios del usuario de la base de datos (que no pueda borrar tablas, etc.)
  • Sanitizar la instrucción SQL. → $parametro = addslashes(trim($parametro));
  • Prepared statements (ver código php).

Ver ejemplo.

Ataques desde formularios de otros servidores

		
function request_is_same_domain(){
	if(!isset()){
		return false;
	}else{
		$referer_host = parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST);
		$server_host =  $_SERVER['HTTP_HOST'];
	}
	return ($referer_host == $server_host)?true:false;
}
		
	

COOKIES

Recomendaciones

Las cookies no son seguras. Basta con ir a la sección de preferencias del navegador para ver su contenido.

Recomendaciones:

  • No guardar información sensible (como nombres de usuario, passwords, etc. ) en las cookies.
  • Usar cookies seguras, que no permiten su acceso mediante javascript.
  • Asignarles una fecha de expiración.
  • Asignarle un dominio y una ruta.

ejemplo de una cookie segura

	
setcookie(name, value, expire, path, domain, secure, httponly);

$name = “username”;
$value = “rqr”;
$expire = time() + 60*60*24*7;
$path = “/”;
$domain = “www.pablomonteserin.com”; //sólo accesible en este subdominio. No es lo mismo que poner pablomonteserin.com
$secure = isset($_SERVER['HTTPS']);
$httponly = true; //no será posible acceder a la cookie con js

setcookie($name, $value, $expire, $path, $domain, $secure, $httponly);

	

Encriptado

Usaremos la librería MyCrypt de PHP.

Firmar una cookie

Podemos encriptar el texto de la cookie y añadir dicho código encriptado a la propia cookie, haciendo una comprobación al recuperarla de que el texto y su encriptación coincidan.

	
function sign_string($string){
	$salt = "Simple salt";
	$checksum = sha1($string.$salt);
	return $string."--".$checksum;
}

function signed_string_is_valid($signed_string){
	$array = explode("--", $signed_string);
	if(count($array) != 2){
		return false;
	}
	$signed_string2 = sign_string($array[0]);
	if($signed_string == $signed_string2){
		return true;
	}else{
		return false;
	}
}
	
Ver solución

Funciones de PHP que ejecutan comandos en el servidor

exec
passthru
popen
proc_open
shell_exec
`
system


<?php 
$user_input = "echo 'hello'";
procesa_user_input();

$user_input = escapeshellarg($user_input);
procesa_user_input();

$user_input = "echo 'hello'; echo 'bye!'";
procesa_user_input();

$user_input = "echo 'hello'; head -n 2 /etc/passwd;";
procesa_user_input();

$user_input = escapeshellarg($user_input);
procesa_user_input();

function procesa_user_input(){
	global $user_input;
	echo "Command: ".$user_input."<br/>";
	$result = exec($user_input);
	echo "Result: ".$result."<br/><br/>";
}
?>

sanitize_file_name

		
function sanitize_file_name($filename) {
	// Remove characters that could alter file path.
	// I disallowed spaces because they cause other headaches.
	// "." is allowed (e.g. "photo.jpg") but ".." is not.
	$filename = preg_replace("/([^A-Za-z0-9_\-\.]|[\.]{2})/", "", $filename);
	// basename() ensures a file name and not a path
	$filename = basename($filename);
	return $filename;
}
		
	

MAX_FILE_SIZE

El fichero php.ini limita el tamaño máximo de subida de un fichero. Nosotros podremos reducir ese límite a nivel de formulario utilizando un input con name MAX_FILE_SIZE.

Es una buena idea tomar el value de este campo del servidor y volver a validarlo en el servidor para que no pueda ser trampeado.

Descargar

Permisos en linux

user, group, other
read(4), write(2), execute(1)

Permisos totales: 4 + 2+ 1 → 777
Permisos para ficheros que no van a ser ejecutados como programas(fotos, pdf's, ficheros de texto, etc): 644

Ejecutar un directorio, significa mostrar sus contenidos, por tanto a menudo habrá que darles permisos de ejecución:

Copia en linux

Copiar archivos desde mi máquina al servidor:

scp ~/archivo.txt usuario@servidor.com:/rutaConPermisosDeEscritura
-p Mantiene los registros de fecha de creación y última modificación,así como los permisos.
-r Copia recursivamente los directorios enteros.

Copiar archivos desde el servidor a mi máquina:

scp -pr usuario@servidor.com:ruta/archivo ruta_local

Copiar sólo los nuevos archivos (actualizar o sincronizar) desde mi máquina al servidor:

rsync -avz -e ssh rutaLocal usuario@servidor.com:/rutaConPermisosDeEscritura

-a, --archive obtenemos una copia exacta de una jerarquía de ficheros y directorios. Esta opción combina el parámetro -r para que el recorra toda la estructura de directorios que le indiquemos, el -l para que copie enlaces simbólicos como enlaces simbólicos, la -p para que mantenga los permisos, la -t para que se mantenga la hora del fichero, la -g para que se mantenga el grupo, la -o para que se mantenga el propietario, la -D para que se mantengan los ficheros de dispositivo (sólo para root). Ni se mantienen los hard links (-H) ni las ACLs (-A) por defecto.
-z comprime el bloque antes de enviarlo

Respecto a cómo pasarle los nombres de los directorios, hay que tener una especial atención respecto a si ponemos una barra al final del nombre del directorio o no, ya que significan cosas distintas:
rsync -av /src/foo /dest
rsync -av /src/foo/ /dest/foo
/path/foo significa “el directorio foo“, mientras que /path/foo/ significa “lo que hay dentro de foo“.

No permitir el acceso directo a un servidor como usuario root, sino hacer que sea necesario acceder como usuario sin privilegios y luego loguearse como root

  • Crear usuario sin privilegios → $user add userName
    Después de esto, podremos conectarnos por ssh utilizando este usuario. Tras haber accedido usando este usuario, es posible convertirnos en root utilizando switch user. Si no especificamos a que usuario queremos cambiar, cambiaremos a root. Además, añadiendo un guión especificamos que queremos adoptar las variables de entorno del usuario al que estamos cambiando:
    su -
  • Comprobar que el usuario fue creado correctamente → $less /etc/passwd
    Este fichero contiene todos los usuarios que contiene el sistema (tanto usuarios de servicios como personas):
    [nombre del usuario]:[]:[identificador del usuario]:[identificador de grupo]:[información adicional separada por comas]:[el home del usuario]:[la shell del usuario] br El identificador de usuario para personas suele estar por encima de 500. Esto significa que no tiene privilegios.
    Buscar un usuario concreto en el sistema: $grep paul /etc/passwd

Prohibir acceso remoto directo como root utilizando ssh

$vi /etc/ssh/sshd_config
Seteo Permitrootlogin a no

Reiniciamos el servicio cuya configuración acabamos de modificar.
Podemos hacerlo de dos formas. La primera es útil porque como se trata de un fichero y no necesitamos conocer exactamente el nombre del servicio que deseamos reiniciar(con tab podemos hacer uso de la opción de autocompletar):
$ /etc/init.d/ssh restart
$service ssh restart

Backup de la base de datos

#Syncronize local database with remote one:
ssh user@www.my_domain.com "mysqldump -u my_remote_db_username
--password=my_remote_db_password my_remote_db_name" | mysql -u my_local_db_username
--password=my_local_db_password --host=localhost -C my_local_db_name

#Syncronize remote database with local one:
mysqldump -u my_local_db_username --password=my_local_db_password --host=localhost -C my_local_db_name | ssh user@www.my_domain.com "mysql -u my_remote_db_username --password=my_remote_db_password my_remote_db_name"

Permitir acceso remoto a la base de datos

  1. Acceder a mysql: $mysql -u root -p
  2. Crear un usuario mysql que pueda acceder remotamente y operar sobre las base de datos
    CREATE USER 'paul'@'%' IDENTIFIED BY 'paul';
  3. Comprobar la interfaz del servicio que queremos abrir al exterior: $netstat -tunlp (net status) Me permite obtener información acerca de los puertos de mi equipo. netstat -tunlp
    tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 1480/sendmail: MTA:
    tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN 32547/mysqld

    Comprobamos que el servicio de la base de datos (mysqld) ocupa el puerto 3306 y utiliza una interfaz local (127.0.0.1). Por tanto, no podremos acceder a este servicio desde fuera de la máquina.

    tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 1480/sendmail: MTA: tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN 32547/mysqld ... Comprobamos que el servicio de la base de datos (mysqld) ocupa el puerto 3306 y utiliza una interfaz local (127.0.0.1). Por tanto, no podremos acceder a este servicio desde fuera de la máquina.
  4. Cambiar la configuración de mysql para acceder remotamente: $vi vi /etc/mysql/my.cnf busco "bind address" o "127.0.0.1" y lo cambio por la que tiene una ip que puede salir al exterior (puedo ver cual es la mía con ifconfig):
    bind-address = 87.106.207.78

Usar ssh, scp, rsync, etc sin necesidad de usar la password del servidor

Supongamos que queremos acceder a host_dest desde host_src sin utilizar password.

Desde host_src, logueados como el usuario al que queremos dotar de esta posibilidad de acceso, escribimos el siguiente comando:

  • $ ssh-keygen -t rsa
    This will prompt for a passphrase. Just press the enter key. It'll then generate an identification (private key) and a public key. Do not ever share the private key with anyone! ssh-keygen shows where it saved the public key. This is by default ~/.ssh/id_rsa.pub:
    Your public key has been saved in <your_home_dir>/.ssh/id_rsa.pub
  • Copiamos id_rsa.pub en host_dest.
    scp /home/monty/.ssh/id_rsa.pub user@host.com:directorioDest
  • Nos logueamos en host_dest.
  • Copiamos id_rsa.pub en ~/.ssh/authorized_keys (obtenemos ~ con altgr + 4)
  • Damos permisos de acceso: chmod 700 ~/.ssh/authorized_keys

Ejecutar comandos con crontab

Para cambiar el editor por defecto de la shell de linux: export EDITOR=sublime-text
Para cambiar el editor por defecto de la shell de linux: export VISUAL=sublime-text
crontab -e → edita el fichero de las tareas programadas.
crontab -l → lista de tareas que contiene el fichero crontab

* * * * * tarea
Un * equivale a todas las unidades de tiempo correspondientes a la posición de ese asterisco. Cada uno de los * equivale a:
minutos – horas – día del mes – mes - dia de la semana

Sólo dos asteriscos al final significan "todos los meses":

	
30 6 1 * *        /usr/bin/fetchmail		→ Ejecutarlo el día 1 del mes a las 6:30
	

Sólo tres asteriscos al final significan "todos los días".

	
0 0 * * *      touch /home/monty/Documents/prueba.txt	→ 	Ejecutarlo a las 12 de la noche cada día
15 0 * * *    touch /home/monty/Documents/prueba.txt	→ 	Ejecutarlo a las 12 :15 de la noche cada día
	

Sólo cuatro asteriscos al final significan “cada hora exacta”.

	
25 * * * *    touch /home/monty/Documents/prueba.txt	→ 	Ejecutarlo 15 después de cada hora exacta
	

Otros ejemplos:

Ejecutarlo el día 1 del mes a las 6:30


30 6 1 * *        /usr/bin/fetchmail

Ejecutarlo cada dos día a las 6:30

		
30 6 */2 * *        /usr/bin/fetchmail
		
	

Ejecutarlo de lunes a viernes a las hora en punto

	
0 * * * 1-5        /usr/bin/fetchmail
	

Ejercicio

Definir una tarea con crontab que ejecute una copia de seguridad de la base de datos cada 3 días.

Instalar servidor de correo

  1. Instalar el servidor de mail
    apt-get install postfix

    Seleccionamos Internet-site

    /etc/postfix/main.cf

    Añadimos la siguiente línea al final:

    home_mailbox = Maildir/

    Reiniciamos el servidor de correo:

    /etc/init.d/postfix restart
  2. Instalar los protocolos
  3. apt-get install courier-pop

    Cuando se nos pregunte lo de web administration, le decimos que no.

    apt-get install courier-imap
  4. Instalar un web mail
    apt-get install squirrelmail

    Para configurarlo:

    squirrelmail-configure

    Pulsamos d, para establecer una configuración por defecto -> escribimos courier -> Enter -> Vuelvo a pulsar Enter -> Pulso la s para salvar.

    Pulsamos d, para la configuración del servidor -> pulso 1 -> introduzco el dominio -> s para salvar -> q para salir

    Habrá que copiar el fichero de configuración a la carpeta de apache:

    cp /etc/squirrelmail/apache.conf /etc/apache2/sites-enabled/squirrelmail.conf

    Reiniciamos el servidor:

    /etc/init.d/apache2 restart
  5. Crear cuentas de mail. Debemos crear 2, una será la que mande un mail para crear las carpetas de configuración:
    adduser [nombre]
    	

    Debemos crear una carpeta donde se guardarán los emails. Lo más fácil será mandar un mail a la cuenta de correo creada para que esta se cree automáticamente.

    sudo [nombre] #Cambio de cuenta
    mail info@elamorhallegadoavuestrasapestosasvidas.com #Mandar mail
    

    Tener en cuenta que lo que escribimos tras pulsar enter en el asunto del mail es el cuerpo del mensaje. Para enviar el mail, pulsaremos enter una vez más y lo enviaremos con ctrl + d

Aplicación para mandar mails desde la terminal

apt-get install mailutils

mod_rewrite

Comprobar si está activo

Si este módulo está activo, se verá el texto mod_rewrite en la sección Loaded Modules del php.ini.

<?php

if (in_array('mod_rewrite', apache_get_modules())) {
    echo "Yes, Apache supports mod_rewrite.";
}else {
    echo "Apache is not loading mod_rewrite.";
}?>

Para cargar el módulo usaremos:

	
sudo a2enmod rewrite
sudo /etc/init.d/apache2 restart
	

Para permitir reescritura de url's, teniendo el módulo mod_rewrite habilitado, editaremos el fichero /etc/apache2/sites-available/000-default.conf y dejaremos este código debajo del DocumentRoot

etc/apache2/sites-available/000-default.conf<Directory "/var/www/html">
    AllowOverride All
</Directory>

.htaccess

Redirecciones

Crearemos un fichero .htaccess con el siguiente código:
Ojo!: usando este método de sobreescritura de url's tendremos que usar rutas absolutas ya si utilizo rutas relativas cuando en la url le estoy pasando dos parámetros o más, no funcionará.

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)/?$ index.php?a=$1&b=$2&c=$3
RewriteRule ^([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)/?$ index.php?a=$1&b=$2
RewriteRule ^([a-zA-Z0-9_-]+)/?$ index.php?a=$1
Ver ejemplo.

Redirecciones de http a https

######INICIO NAVEGACION HTTPS######
RewriteEngine on
RewriteCond %{HTTPS} !=on
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
######FIN DE NAVEGACION HTTPS######

Redirección 301

Normalmente pasado un año aproximadamente ya se habrá transmitido todo el posicionamiento de una url a otra y podrás quitar el redireccionamiento y si te aparece como 404 en Google borrar la url antigua.

Redirección de una url a otraRedirect 301 /autocad/ https://pablomonteserin.com/curso-autocad/
Redirección de todas las urls de una subcarpeta al dominio principalRedirectMatch 301 ^/pruebas/(.*)$ http://coptering.com/$1

Redireccionamos todas las urls del tipo https://pablomonteserin.com/curso/redirections.php?opt=rqr a https://pablomonteserin.com/mis-cursos, prescindiendo de los parámetros de redirecions.php

Redirect 301 /curso/redirections.php /mis-cursos/?
RedirectMatch 301 ^/pruebas/(.*)$ http://coptering.com/$1

Aumentar la velocidad de la web

# BEGIN WP Rocket v3.2.2
# Use UTF-8 encoding for anything served text/plain or text/html
AddDefaultCharset UTF-8
# Force UTF-8 for a number of file formats
<IfModule mod_mime.c>
AddCharset UTF-8 .atom .css .js .json .rss .vtt .xml
</IfModule>

# FileETag None is not enough for every server.
<IfModule mod_headers.c>
Header unset ETag
</IfModule>

# Since we’re sending far-future expires, we don’t need ETags for static content.
# developer.yahoo.com/performance/rules.html#etags
FileETag None

# Send CORS headers if browsers request them; enabled by default for images.
<IfModule mod_setenvif.c>
<IfModule mod_headers.c>
# mod_headers, y u no match by Content-Type?!
<FilesMatch "\.(cur|gif|png|jpe?g|svgz?|ico|webp)$">
SetEnvIf Origin ":" IS_CORS
Header set Access-Control-Allow-Origin "*" env=IS_CORS
</FilesMatch>
</IfModule>
</IfModule>

# Allow access to web fonts from all domains.
<FilesMatch "\.(eot|otf|tt[cf]|woff2?)$">
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin "*"
</IfModule>
</FilesMatch>

<IfModule mod_alias.c>
<FilesMatch "\.(html|htm|rtf|rtx|txt|xsd|xsl|xml)$">
<IfModule mod_headers.c>
Header set X-Powered-By "WP Rocket/3.2.2"
Header unset Pragma
Header append Cache-Control "public"
Header unset Last-Modified
</IfModule>
</FilesMatch>

<FilesMatch "\.(css|htc|js|asf|asx|wax|wmv|wmx|avi|bmp|class|divx|doc|docx|eot|exe|gif|gz|gzip|ico|jpg|jpeg|jpe|json|mdb|mid|midi|mov|qt|mp3|m4a|mp4|m4v|mpeg|mpg|mpe|mpp|otf|odb|odc|odf|odg|odp|ods|odt|ogg|pdf|png|pot|pps|ppt|pptx|ra|ram|svg|svgz|swf|tar|tif|tiff|ttf|ttc|wav|wma|wri|xla|xls|xlsx|xlt|xlw|zip)$">
<IfModule mod_headers.c>
Header unset Pragma
Header append Cache-Control "public"
</IfModule>
</FilesMatch>
</IfModule>

# Expires headers (for better cache control)
<IfModule mod_expires.c>
	ExpiresActive on
	# Perhaps better to whitelist expires rules? Perhaps.
	ExpiresDefault                              "access plus 1 month"
	# cache.appcache needs re-requests in FF 3.6 (thanks Remy ~Introducing HTML5)
	ExpiresByType text/cache-manifest           "access plus 0 seconds"
	# Your document html
	ExpiresByType text/html                     "access plus 0 seconds"
	# Data
	ExpiresByType text/xml                      "access plus 0 seconds"
	ExpiresByType application/xml               "access plus 0 seconds"
	ExpiresByType application/json              "access plus 0 seconds"
	# Feed
	ExpiresByType application/rss+xml           "access plus 1 hour"
	ExpiresByType application/atom+xml          "access plus 1 hour"
	# Favicon (cannot be renamed)
	ExpiresByType image/x-icon                  "access plus 1 week"
	# Media: images, video, audio
	ExpiresByType image/gif                     "access plus 4 months"
	ExpiresByType image/png                     "access plus 4 months"
	ExpiresByType image/jpeg                    "access plus 4 months"
	ExpiresByType image/webp                    "access plus 4 months"
	ExpiresByType video/ogg                     "access plus 1 month"
	ExpiresByType audio/ogg                     "access plus 1 month"
	ExpiresByType video/mp4                     "access plus 1 month"
	ExpiresByType video/webm                    "access plus 1 month"
	# HTC files  (css3pie)
	ExpiresByType text/x-component              "access plus 1 month"
	# Webfonts
	ExpiresByType application/x-font-ttf        "access plus 1 month"
	ExpiresByType font/opentype                 "access plus 1 month"
	ExpiresByType application/x-font-woff       "access plus 1 month"
	ExpiresByType application/x-font-woff2      "access plus 1 month"
	ExpiresByType image/svg+xml                 "access plus 1 month"
	ExpiresByType application/vnd.ms-fontobject "access plus 1 month"
	# CSS and JavaScript
	ExpiresByType text/css                      "access plus 1 year"
	ExpiresByType application/javascript        "access plus 1 year"
</IfModule>
# Gzip compression
<IfModule mod_deflate.c>
# Active compression
SetOutputFilter DEFLATE
# Force deflate for mangled headers
<IfModule mod_setenvif.c>
<IfModule mod_headers.c>
SetEnvIfNoCase ^(Accept-EncodXng|X-cept-Encoding|X{15}|~{15}|-{15})$ ^((gzip|deflate)\s*,?\s*)+|[X~-]{4,13}$ HAVE_Accept-Encoding
RequestHeader append Accept-Encoding "gzip,deflate" env=HAVE_Accept-Encoding
# Don’t compress images and other uncompressible content
SetEnvIfNoCase Request_URI \
\.(?:gif|jpe?g|png|rar|zip|exe|flv|mov|wma|mp3|avi|swf|mp?g|mp4|webm|webp|pdf)$ no-gzip dont-vary
</IfModule>
</IfModule>

# Compress all output labeled with one of the following MIME-types
<IfModule mod_filter.c>
AddOutputFilterByType DEFLATE application/atom+xml \
		                          application/javascript \
		                          application/json \
		                          application/rss+xml \
		                          application/vnd.ms-fontobject \
		                          application/x-font-ttf \
		                          application/xhtml+xml \
		                          application/xml \
		                          font/opentype \
		                          image/svg+xml \
		                          image/x-icon \
		                          text/css \
		                          text/html \
		                          text/plain \
		                          text/x-component \
		                          text/xml
</IfModule>
<IfModule mod_headers.c>
Header append Vary: Accept-Encoding
</IfModule>
</IfModule>

<IfModule mod_mime.c>
AddType text/html .html_gzip
AddEncoding gzip .html_gzip
</IfModule>
<IfModule mod_setenvif.c>
SetEnvIfNoCase Request_URI \.html_gzip$ no-gzip
</IfModule>

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{HTTPS} on [OR]
RewriteCond %{SERVER_PORT} ^443$ [OR]
RewriteCond %{HTTP:X-Forwarded-Proto} https
RewriteRule .* - [E=WPR_SSL:-https]
RewriteCond %{HTTP:Accept-Encoding} gzip
RewriteRule .* - [E=WPR_ENC:_gzip]
RewriteCond %{REQUEST_METHOD} GET
RewriteCond %{QUERY_STRING} =""
RewriteCond %{HTTP:Cookie} !(wordpress_logged_in_|wp-postpass_|wptouch_switch_toggle|comment_author_|comment_author_email_) [NC]
RewriteCond %{REQUEST_URI} !^(/(.+/)?feed/?|/finalizar-compra/(.*)|/(index\.php/)?wp\-json(/.*|$))$ [NC]
RewriteCond %{HTTP_USER_AGENT} !^(facebookexternalhit).* [NC]
RewriteCond "%{DOCUMENT_ROOT}/usr/wp-content/cache/wp-rocket/%{HTTP_HOST}%{REQUEST_URI}/index%{ENV:WPR_SSL}.html%{ENV:WPR_ENC}" -f
RewriteRule .* "/usr/wp-content/cache/wp-rocket/%{HTTP_HOST}%{REQUEST_URI}/index%{ENV:WPR_SSL}.html%{ENV:WPR_ENC}" [L]
</IfModule>
# END WP Rocket
icono de mandar un mail¡Contacta conmigo!
contacta conmigoPablo Monteserín

¡Hola! ¿En qué puedo ayudarte?