# BEGIN CMOX TIENDA ESTATICA # La tienda es un sitio estatico. WordPress se queda instalado debajo: sigue # teniendo los pedidos, los clientes y el panel, y volver atras es quitar este # bloque. # # Lo escribe `despliegue/publicar.sh` en cada despliegue, sustituyendo lo que # hubiera entre BEGIN y END. Se reescribe siempre y no solo si falta: antes # solo se anadia cuando no estaba, asi que ninguna correccion llegaba a un # servidor que ya lo tuviera. Es literalmente por lo que las cabeceras de # cache no existieron durante horas. # # NO se inventan reglas de reescritura aqui. Una regla «protectora» en el # .htaccess de cmox.es tumbo /panelcmox y /wp-admin enteros en su dia. Lo unico # que hace falta para que convivan la tienda estatica y WordPress es el # DirectoryIndex: la reescritura de WordPress solo actua cuando el fichero NO # existe, asi que cada carpeta que trae el sitio nuevo la sirve Apache directo. DirectoryIndex index.html index.php # Sin indices de directorio. # # Medido: https://tienda.cmox.es/img/ devolvia un «Index of /img» con el arbol # entero de fotografias navegable, y wp-content/uploads/ igual. Eso da la lista # completa de nombres de fichero a quien pase por ahi, incluida la de las fotos # que la regla de mas abajo protege de que las enlacen desde fuera: se puede # tapar la puerta y dejar el listin pegado al lado. # # Y no es solo cosa de fotos. Un indice de wp-content/uploads/ ensena que # plugins hay, con sus carpetas, y eso es la mitad del trabajo de quien busca # una version vieja con un agujero conocido. # # No es una regla de reescritura: no enruta nada y no puede tumbar el panel. # Lo unico que hace es que Apache deje de fabricar una pagina de listado cuando # una carpeta no tiene indice. Options -Indexes # Las legales viejas del WordPress, a las nuevas. # # Estaban despublicadas desde ayer, asi que ya caian en el 404 del sitio nuevo. # Un 404 esta bien para /carrito/ o para un articulo de relleno; para una # politica de privacidad no: quien la busca la busca por un motivo, y llevarle # a un error deja peor sabor que no haberla tenido nunca. # # Redirect y no RewriteRule: esto no enruta nada, solo dice que una direccion # se ha movido. # /aviso-legal/ NO lleva redireccion, y es a proposito: la pagina NUEVA vive # en esa misma direccion. Redirigirla a si misma es un bucle infinito, y el # navegador corta con ERR_TOO_MANY_REDIRECTS. La vieja estaba despublicada, # asi que el fichero estatico ya gana sin ayuda. Redirect 301 /privacidad/ https://tienda.cmox.es/politica-de-privacidad/ # /politica-de-cookies/ TAMPOCO lleva redireccion ya. La llevaba mientras la # tienda no tenia analitica y no habia pagina propia que ofrecer; desde que se # anadio Google Analytics existe de verdad, y la redireccion la tapaba: la # pagina se compilaba y el servidor mandaba a otra parte antes de servirla. Redirect 301 /terminos-y-condiciones/ https://tienda.cmox.es/aviso-legal/ RewriteEngine On # Las direcciones viejas que ya no existen, a su sitio nuevo. # # Con destino relativo, Apache reconstruye la URL absoluta y le mete el # puerto: salia «https://tienda.cmox.es:443/catalogo/». Funciona, pero se ve # en la barra y en los buscadores. Con la URL entera no reconstruye nada. RewriteRule ^productos/?$ https://tienda.cmox.es/catalogo/ [R=301,L] RewriteRule ^tienda/?$ https://tienda.cmox.es/catalogo/ [R=301,L] # ^empresa/?$ SE QUITO el 27/08/2026, y conviene saber por que. # # Mandaba a https://cmox.es/sobre-nosotros/, y esa pagina paso a devolver 404 # ese mismo dia --Toni: fuera todo lo que no sea la web nueva--. Quedaba una # redireccion que terminaba en un error: quien pulsara el resultado aterrizaba # en una pagina rota, y Google veia un 301 hacia nada. Eso es peor que # cualquiera de las dos opciones limpias. # # Se elige el 404 y no repuntar a la portada porque repuntar seria reponer, # un salto antes, justo lo que se acababa de quitar. # # Lo que costo, para que este el numero y no la sensacion: /empresa/ tenia 28 # apariciones en 90 dias en POSICION 1,5 --el mejor puesto de toda la # tienda-- y 1 clic. # # Las de arriba se quedan, y no es incoherencia: /productos/ y /tienda/ no son # paginas viejas que sobrevivan, son punteros a /catalogo/, que es pagina de # la web nueva y que por si sola no tiene ni una aparicion en Google. # ── Las fotografias ────────────────────────────────────────────────── # Solo se sirven a paginas de cmox.es. Con esto, otra web no puede # enlazarlas desde aqui —cargandole a CMOX el trafico y la propiedad de la # foto— y no se bajan pegando la URL en la barra. Es lo mismo que ya hacia # cmox.es con /img/v2/ desde el 24/08; la tienda se habia quedado sin ello. # # Lo que NO puede hacer ninguna configuracion del mundo: evitar que quien ve # la foto en la pagina la tenga ya en su ordenador. Para verla, el navegador # ha tenido que descargarla. Eso es la web. # # Se limita a escenas y productos a proposito. El logotipo, los iconos y la # imagen de vista previa tienen que seguir siendo accesibles sin referente, # o WhatsApp, LinkedIn y Google dejan de poder leerlas. RewriteCond %{HTTP_REFERER} !^https?://([a-z0-9-]+\.)?cmox\.es(/|$) [NC] RewriteRule ^img/(escenas|productos)/ - [F,L] AddType image/avif .avif AddType image/webp .webp AddType font/woff2 .woff2 # ── Seguridad ──────────────────────────────────────────────────────── # No habia ninguna. Son las que no rompen nada: NO se pone una # Content-Security-Policy completa porque la tienda usa scripts en linea a # proposito —el captcha, los precios, el idioma— y una CSP mal puesta no # protege: apaga la web. # Que el navegador no adivine el tipo de un fichero. Sin esto, algo subido # como imagen que en realidad lleve HTML puede acabar ejecutandose. Importa # aqui mas que en un sitio estatico normal: WordPress sigue debajo y acepta # subidas. Header always set X-Content-Type-Options "nosniff" # Nadie mete esta tienda en un iframe. Es como se monta una pagina que # parece la tuya y recoge lo que el visitante escribe. Va en CSP porque # X-Frame-Options esta obsoleto, y tambien en X-Frame-Options porque los # navegadores viejos solo entienden aquel. Header always set Content-Security-Policy "frame-ancestors 'self'" Header always set X-Frame-Options "SAMEORIGIN" # Al salir a otra web se manda el dominio, no la direccion completa. Con la # ruta entera, un enlace desde /producto/linak-cb12/ le cuenta a quien lo # recibe que ese visitante estaba mirando esa reparacion. Header always set Referrer-Policy "strict-origin-when-cross-origin" # Camara, microfono, ubicacion y pagos: esta tienda no usa ninguno, y # decirlo impide que los pida un script de terceros que entre por donde sea. Header always set Permissions-Policy "camera=(), microphone=(), geolocation=(), payment=()" # HTTPS obligatorio durante seis meses. SIN `includeSubDomains` a proposito: # eso lo aplicaria tambien a vortex, rain y crm, y no se decide por otros # sitios desde el .htaccess de este. Sin `preload` por lo mismo: entrar en # la lista de los navegadores es facil y salir tarda meses. Header always set Strict-Transport-Security "max-age=15552000" # ── Cache ──────────────────────────────────────────────────────────── # El HTML no se guarda. Sin esto la tienda no mandaba NINGUNA cabecera de # cache, asi que el CDN de OVH se quedaba el HTML por su cuenta y seguia # sirviendo la pagina vieja despues de desplegar: X-CDN-Cache: HIT y una # portada de hace horas. cmox.es ya lo hacia bien; la tienda no. # # `no-store` ademas de `no-cache` porque no-cache permite guardar y # revalidar, y el CDN de por medio hace de eso lo que quiere. Header set Cache-Control "no-store, no-cache, must-revalidate, max-age=0" # Lo de _astro/ lleva el hash del contenido en el nombre: si cambia el # fichero cambia la URL, asi que se puede guardar para siempre. Estaba en 15 # minutos, que es tirar la cache sin ganar nada. Header set Cache-Control "public, max-age=31536000, immutable" # Fotos y fuentes: un mes. No llevan hash, pero cambian poco y cuando # cambian no es urgente que se vea al segundo. Header set Cache-Control "public, max-age=2592000" # END CMOX TIENDA ESTATICA # BEGIN WordPress # Las directivas (líneas) entre «BEGIN WordPress» y «END WordPress» son # generadas dinámicamente y solo deberían ser modificadas mediante filtros de WordPress. # Cualquier cambio en las directivas que hay entre esos marcadores serán sobrescritas. RewriteEngine On RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] RewriteBase / RewriteRule ^index\.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L] # END WordPress