Hoy os traigo un post completito sobre la parte de sistemas de WordPress.
Hace ya demasiados días que tenía pendiente la actualización de las debian que alojaban mi wordpress multisite y la base de datos mysql (que las tengo en dos contenedores separados). No digo las versiones porqué se me cae la cara de vergüenza :P
El wordpress que tengo en La Mar de Bits tiene por delante 2 frontales haciendo de proxy http con nginx (donde además hago la gestión de los certificados de letsencrypt y redirección de puerto 80 a 443). Éstos apuntan al puerto expuesto de Varnish (servicio de cache) dentro del contenedor donde está el wordpress (puerto 6081). El varnish apunta en el apache y el apache sirve en el puerto 80 las páginas web de wordpress.
Vamos un cristo para llegar al wordpress que no veas :)
Voy a ir detallando las configuraciones que tengo en cada una de las partes de esta máquina
nginx (frontales)
Estas dos maquinas son las que están expuestas a internet y comparten el directorio de configuración gracias a glusterfs.
Para exponer ambas maquinas en internet en bind lo hago así:
@ IN A 109.69.10.251 @ IN A 109.69.10.241 @ IN AAAA 2a00:1508:6000:501::a1 @ IN AAAA 2a00:1508:6000:501::a2 frontal 1H IN A 109.69.10.241 frontal 1H IN A 109.69.10.251 frontal 1H IN AAAA 2a00:1508:6000:501::a1 frontal 1H IN AAAA 2a00:1508:6000:501::a2 www 1H IN CNAME frontal
A continuación, en nginx para cada sitio del wordpress tengo un fichero de configuración similar a éste de lamardebits.org:
# Redireccionem tots els noms de domini:80 a # https://lamardebits.org server { listen 80; server_name marsupi.org www.marsupi.org www.lamardebits.org lamardebits.org; include snippets/certbot.conf; return 301 https://lamardebits.org$request_uri; #root /var/www/html; } # Responem les consultes de https://lamardebits.org server { server_name lamardebits.org; include snippets/certbot.conf; include snippets/lmdb-error-pages.conf; include snippets/wordpress.conf; listen 443 ssl http2; listen [::]:443 ssl http2; ssl_certificate /etc/letsencrypt/live/lamardebits.org/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/lamardebits.org/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_trusted_certificate /etc/letsencrypt/live/lamardebits.org/chain.pem; }
Destaco el snippet wordpress.conf donde pongo la configuración común de los sitios de wordpress
location / { proxy_pass http://172.31.0.146:80; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto https; proxy_set_header X-Forwarded-Port 443; proxy_set_header Host $host; add_header X-Frame-Options SAMEORIGIN; }
(Actualización: se añade el add_header X-Frame-Options que no permitía que se cargase el editor del plugin elementor. Referencia aquí)
La ip del contenedor donde se encuentra el wordpress es la 172.31.0.146.
Ahora nos posicionamos ya en la máquina de wordpress y vamos a revisar la configuración de cada uno de los elementos.
varnish cache
Pues siguiendo los servicios por el que pasa el usuario al llegar a mis wordpress, ahora sería el turno de varnish. Varnish lo tengo escuchando en el puerto 6081 y recoge la información del apache que está sirviendo en el puerto 80
Varnish es muy importante porque nos permite reducir la carga del servidor (wordpress cada vez es mas tocho), además, varnish hace que el usuario se le carguen las páginas mucho mas rápido.
# vi /etc/default/varnish START=yes NFILES=131072 MEMLOCK=82000 DAEMON_OPTS="-a :6081 \ -T localhost:6082 \ -f /etc/varnish/default.vcl \ -S /etc/varnish/secret \ -s malloc,256m"
# vi /etc/varnish/default.vcl # # This is an example VCL file for Varnish. # # It does not do anything by default, delegating control to the # builtin VCL. The builtin VCL is called when there is no explicit # return statement. # # See the VCL chapters in the Users Guide at https://www.varnish-cache.org/docs/ # and https://www.varnish-cache.org/trac/wiki/VCLExamples for more examples. # Marker to tell the VCL compiler that this VCL has been adapted to the # new 4.0 format. vcl 4.0; # Default backend definition. Set this to point to your content server. backend default { .host = "127.0.0.1"; .port = "80"; } sub vcl_recv { # Set the X-Forwarded-For header so the backend can see the original # IP address. If one is already set by an upstream proxy, we'll just re-use that. #return(pass); if (req.method == "PURGE") { return (purge); } if (req.method == "XCGFULLBAN") { ban("req.http.host ~ .*"); return (synth(200, "Full cache cleared")); } if (req.http.X-Requested-With == "XMLHttpRequest") { return(pass); } if (req.http.Authorization || req.method == "POST") { return (pass); } if (req.method != "GET" && req.method != "HEAD") { return (pass); } if (req.url ~ "(wp-admin|post\.php|edit\.php|wp-login|wp-json)") { return(pass); } if (req.url ~ "/wp-cron.php" || req.url ~ "preview=true") { return (pass); } if (req.url ~ "action=elementor") { return (pass); } if ((req.http.host ~ "my_domain.com" && req.url ~ "^some_specific_filename\.(css|js)")) { return (pass); } set req.http.Cookie = regsuball(req.http.Cookie, "has_js=[^;]+(; )?", ""); # Remove the wp-settings-1 cookie set req.http.Cookie = regsuball(req.http.Cookie, "wp-settings-1=[^;]+(; )?", ""); # Remove the wp-settings-time-1 cookie set req.http.Cookie = regsuball(req.http.Cookie, "wp-settings-time-1=[^;]+(; )?", ""); # Remove the wp test cookie set req.http.Cookie = regsuball(req.http.Cookie, "wordpress_test_cookie=[^;]+(; )?", ""); # Remove the PHPSESSID in members area cookie set req.http.Cookie = regsuball(req.http.Cookie, "PHPSESSID=[^;]+(; )?", ""); unset req.http.Cookie; } sub vcl_purge { set req.method = "GET"; set req.http.X-Purger = "Purged"; #return (synth(200, "Purged")); return (restart); } sub vcl_backend_response { # Happens after we have read the response headers from the backend. # # Here you clean the response headers, removing silly Set-Cookie headers # and other mistakes your backend does. set beresp.grace = 12h; set beresp.ttl = 12h; } sub vcl_deliver { # Happens when we have all the pieces we need, and are about to send the # response to the client. # # You can do accounting or modifying the final object here. }
apache
La configuración de apache entonces es:
# vi /etc/apache2/sites-enabled/wordpress.confServerAdmin administradors@lamardebits.org DocumentRoot /var/www/wp/ # This helps applications behind a proxy know that the pages # were originally requested over https # Prevents browser blocking content because of MIXED CONTENT SetEnvIf X-Forwarded-Proto https HTTPS=on AllowOverride None < /LocationMatch> Options -Indexes AllowOverride All < /Directory> ErrorLog ${APACHE_LOG_DIR}/wp.lmdb.error.log # Possible values include: debug, info, notice, warn, error, crit, # alert, emerg. LogLevel warn #CustomLog ${APACHE_LOG_DIR}/wp.lmdb.access.log combined #CustomLog "| nc -u -j 172.31.0.114 515" combined CustomLog ${APACHE_LOG_DIR}/wp.lmdb.access.log proxy RewriteEngine On RewriteOptions inherit < /VirtualHost>
WordPress
En el wordpress tendremos que modificar el fichero wp-config.php
if (strpos($_SERVER['HTTP_X_FORWARDED_PROTO'], 'https') !== false) { $_SERVER['HTTPS']='on'; }
Si sigue fallando wordpress, jetpack o alguna cosa prueba de añadir éstas otras configuraciones
$_SERVER['SERVER_PORT'] = 80; # IN HTTPS define( 'JETPACK_SIGNATURE__HTTPS_PORT', 80 ); # OUT HTTPS define( 'JETPACK_CLIENT__HTTPS', 'NEVER' );
Finalmente tendremos que activar algún plugin de cache. Antes tenía otro, requería configurar cada sitio manualmente y era un rollo, así que el que tengo ahora es “Proxy Cache Purge” de “Mika Epstein”. Que basicamente lo que hace es hacer un PURGE de las páginas que actualicemos cada vez que hagamos un cambio.
De momento con esto tiene pinta que el wordpress va mucho mas suelto y por fin no se cuelgan las páginas al hacer cambios! además he pasado de 8 errores a 2 en la verificación que hace wordpress del estado del sitio que corresponden a noseque del jetpack.
Seguiremos investigando y probando de afinar mucho mas el sistema.
Cualquier propuesta de mejora y de seguridad será bienvenida :D
Pingback: Wordpress: migrar sitios de un multisite a otro – Blackhold
Pingback: WordPress: migrar sitios de un multisite a otro Blackhold - Blog de Informática