WordPress hinter Ihrer Nextcloud v. 2.1

Nextcloud & WordPress (nginx Reverse Proxy)

Um WordPress neben bzw. unterhalb Ihrer Nextcloud nutzen zu können und somit WordPress in einem Unterverzeichnis
zu betreiben, fungieren wir den Webserver nginx in einen sogenannten Reverse Proxy um.
Wechseln Sie dafür in den privilegierten Benutzermodus, legen das WordPress-Verzeichnis an,
konfigurieren nginx um und installieren WordPress:

sudo -s
sudo -u www-data mkdir -p /var/www/wordpress

Passen Sie nun die NGINX-Konfiguration an:

nano /etc/nginx/nginx.conf
user www-data;
worker_processes auto;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
multi_accept on; use epoll;
}
http {
server_names_hash_bucket_size 64;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log warn;
set_real_ip_from 127.0.0.1;
#optional, Sie können das eigene Subnetz ergänzen, bspw.:
# set_real_ip_from 192.168.2.0/24;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
include /etc/nginx/mime.types;
default_type application/octet-stream;
sendfile on;
send_timeout 3600;
tcp_nopush on;
tcp_nodelay on;
open_file_cache max=500 inactive=10m;
open_file_cache_errors on;
keepalive_timeout 65;
reset_timedout_connection on;
server_tokens off;
resolver 127.0.0.53 valid=30s;
resolver_timeout 5s;
include /etc/nginx/conf.d/*.conf;
}

Erweitern Sie ihren virtuellen Host (vhost), der die Anfragen an Ihre Domäne entsprechend verteilt und die SSL Zertifikate verwaltet. Passen Sie die roten Parameter entsprechend Ihre Umgebung an:

nano /etc/nginx/conf.d/nextcloud.conf
server {
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
server_name ihre.domain.de;
ssl_certificate /etc/letsencrypt/rsa-certs/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/rsa-certs/privkey.pem;
ssl_certificate /etc/letsencrypt/ecc-certs/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/ecc-certs/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/ecc-certs/chain.pem;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
ssl_protocols TLSv1.3 TLSv1.2;
ssl_ciphers 'TLS-CHACHA20-POLY1305-SHA256:TLS-AES-256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384';
ssl_ecdh_curve X448:secp521r1:secp384r1; 
ssl_prefer_server_ciphers on;
ssl_stapling on;
ssl_stapling_verify on;
add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;" always;
add_header Referrer-Policy "no-referrer" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Download-Options "noopen" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Permitted-Cross-Domain-Policies "none" always;
add_header X-Robots-Tag "none" always;
add_header X-XSS-Protection "1; mode=block" always;
fastcgi_hide_header X-Powered-By;
fastcgi_read_timeout 3600;
fastcgi_send_timeout 3600;
fastcgi_connect_timeout 3600;
root /var/www/nextcloud;
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
location = /.well-known/carddav {
return 301 $scheme://$host:$server_port/remote.php/dav;
}
location = /.well-known/caldav {
return 301 $scheme://$host:$server_port/remote.php/dav;
}
client_max_body_size 10240M;
fastcgi_buffers 64 4K;
gzip on;
gzip_vary on;
gzip_comp_level 4;
gzip_min_length 256;
gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;
### WordPress ####
location ^~ /wordpress/ {
client_max_body_size 1024M;
proxy_buffering off;
proxy_connect_timeout 3600;
proxy_max_temp_file_size 1024M;
proxy_pass http://127.0.0.1:82;
proxy_redirect off;
proxy_request_buffering off;
proxy_read_timeout 3600;
proxy_send_timeout 3600;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
send_timeout 3600;
}
location / {
rewrite ^ /index.php;
}
location ~ ^\/(?:build|tests|config|lib|3rdparty|templates|data)\/ {
deny all;
}
location ~ ^\/(?:\.|autotest|occ|issue|indie|db_|console) {
deny all;
}
location ^~ /apps/rainloop/app/data {
deny all;
}
location ~ ^\/(?:index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|oc[ms]-provider\/.+|.+\/richdocumentscode\/proxy)\.php(?:$|\/) {
fastcgi_split_path_info ^(.+?\.php)(\/.*|)$;
set $path_info $fastcgi_path_info;
try_files $fastcgi_script_name =404;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $path_info;
fastcgi_param HTTPS on;
fastcgi_param modHeadersAvailable true;
fastcgi_param front_controller_active true;
fastcgi_pass php-handler;
fastcgi_intercept_errors on;
fastcgi_request_buffering off;
}
location ~ ^\/(?:updater|oc[ms]-provider)(?:$|\/) {
try_files $uri/ =404;
index index.php;
}
location ~ \.(?:css|js|woff2?|svg|gif|map)$ {
try_files $uri /index.php$request_uri;
add_header Cache-Control "public, max-age=15778463";
add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;" always;
add_header Referrer-Policy "no-referrer" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Download-Options "noopen" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Permitted-Cross-Domain-Policies "none" always;
add_header X-Robots-Tag "none" always;
add_header X-XSS-Protection "1; mode=block" always;
access_log off;
}
location ~ \.(?:png|html|ttf|ico|jpg|jpeg|bcmap|mp4|webm)$ {
try_files $uri /index.php$request_uri;
access_log off;
}
}

Erzeugen Sie die vhost-Datei für WordPress:

nano /etc/nginx/conf.d/wordpress.conf
server {
server_name 127.0.0.1;
listen 127.0.0.1:82;
root /var/www/;
location ^~ /wordpress { 
index index.php;
location /wordpress {
try_files $uri $uri/ /wordpress/index.php$is_args$args;
}
location = /wordpress/favicon.ico {
log_not_found off;
access_log off;
}
location = /wordpress/robots.txt {
allow all;
log_not_found off;
access_log off;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+?\.php)(\/.*|)$;
set $path_info $fastcgi_path_info;
try_files $fastcgi_script_name =404;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $path_info;
fastcgi_param HTTPS on;
fastcgi_param modHeadersAvailable true;
fastcgi_param front_controller_active true;
fastcgi_pass php-handler;
fastcgi_intercept_errors on;
fastcgi_request_buffering off;
}
location ~* /wordpress/\.(js|css|png|jpg|jpeg|gif|ico)$ {
expires max;
log_not_found off;
}
location /wordpress/wp-admin {
auth_basic "Restricted Area";
auth_basic_user_file /etc/nginx/wordpress-access;
}
location ~* /(?:uploads|files)/.*.(html|htm|shtml|php|js|swf)$ {
deny all;
}
}
}

Ihr Webserver ist nun bereits als Reverse Proxy für WordPress konfiguriert. Härten Sie nun den späteren WordPress-Administrationsbereich durch eine Passwortabfrage ab:

apt install apache2-utils -y

Generieren Sie den Benutzer und das dazugehörige Passwort:

htpasswd -c /etc/nginx/wordpress-access Ihr.Name

Nach einem NGINX Neustart ist der wp-admin Bereich bereits durch ein Passwort geschützt und wird von Fauil2Ban überwacht (nginx-http-auth).

service nginx restart

Laden Sie nun das aktuelle WordPress Release in ein Arbeitsverzeichnis (/usr/local/src) herunter und entpacken es nach /var/www/wordpress:

cd /usr/local/src
wget https://wordpress.org/latest.tar.gz
tar xfvz latest.tar.gz && mv wordpress /var/www/

Setzen Sie die richtigen Berechtigungen:

chown -R www-data:www-data /var/www/wordpress

Erzeugen Sie die WordPress Datenbank – ersetzen Sie dabei bitte das Beispielpasswort ‚wordpressDBpassword‚ durch ein von Ihnen frei wählbares Passwort:

mysql -uroot -p
CREATE DATABASE wordpress CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
CREATE USER wordpress@localhost identified by 'wordpressDBpassword';
GRANT ALL PRIVILEGES on wordpress.* to wordpress@localhost;
flush privileges;
quit;

Erzeugen Sie nun die WordPress Konfigurationsdatei (wp-config.php) mit den Werten Ihrer zukünftigen WordPress-Seite und :

sudo -u www-data nano /var/www/wordpress/wp-config.php
<?php
if (strpos($_SERVER['HTTP_X_FORWARDED_PROTO'], 'https') !== false)
    $_SERVER['HTTPS']='on';
if(isset($_SERVER['HTTP_X_FORWARDED_HOST']))
    $_SERVER['HTTP_HOST'] = $_SERVER['HTTP_X_FORWARDED_HOST'];
define('WP_HOME', 'https://ihre.domain.de/wordpress');
define('WP_SITEURL', 'https://ihre.domain.de/wordpress');
define('DB_NAME', 'wordpress');
define('DB_USER', 'wordpress');
define('DB_PASSWORD', 'wordpressDBpassword');
define('DB_HOST', 'localhost');
define('DB_CHARSET', 'utf8mb4');
define('DB_COLLATE', '');
define('AUTH_KEY',         'von hier: https://api.wordpress.org/secret-key/1.1/salt/');
define('SECURE_AUTH_KEY',  'von hier: https://api.wordpress.org/secret-key/1.1/salt/');
define('LOGGED_IN_KEY',    'von hier: https://api.wordpress.org/secret-key/1.1/salt/');
define('NONCE_KEY',        'von hier: https://api.wordpress.org/secret-key/1.1/salt/');
define('AUTH_SALT',        'von hier: https://api.wordpress.org/secret-key/1.1/salt/');
define('SECURE_AUTH_SALT', 'von hier: https://api.wordpress.org/secret-key/1.1/salt/');
define('LOGGED_IN_SALT',   'von hier: https://api.wordpress.org/secret-key/1.1/salt/');
define('NONCE_SALT',       'von hier: https://api.wordpress.org/secret-key/1.1/salt/');
$table_prefix = 'ncblog_';
define('WP_DEBUG', false);
if ( !defined('ABSPATH') )
 define('ABSPATH', dirname(__FILE__) . '/');
require_once(ABSPATH . 'wp-settings.php');

Um die obigen Werte generieren zu lassen, rufen Sie einfach die nachfolgende URL auf:
https://api.wordpress.org/secret-key/1.1/salt/
und fügen diese 1:1 in die Datei ein.

Richten Sie dann die WordPress-Instanz im Browser ein – rufen Sie dazu die URL
https://your.dedyn.io/wordpress
auf und folgen dem Wizard wie in den Bildern exemplarisch beschrieben:

Wählen Sie sich nach der Einrichtung in Ihre Nextcloud ein und wechseln in die Admineinstellungen. Dort gehen Sie zu den „Externen Seiten / External Sites“ und tragen die WordPress Instanz ein:

Neuer Eintrag: https://your.dedyn.io/wordpress

Dadurch erscheint Ihre WordPress Instanz innerhalb ihrer Nextcloud als App-Link:

Aus Sicherheitsgründen sollte die wp-config.php aus dem Webverzeichnis verschoben werden. Erzeugen SIe dafür eine neue new wp-config.php, die auf die verschobene Datei ausserhalb des Webverzeichnisses verweist:

cd /var/www/wordpress
mv wp-config.php /etc/nginx
nano wp-config.php

Tragen Sie diese Zeilen in die leere Datei ein:

<?php
include('/etc/nginx/wp-config.php');

Setzen Sie die notwendigen Berechtigungen:

chown www-data:www-data /etc/nginx/wp-config.php /var/www/wordpress/wp-config.php
chmod 400 /var/www/wordpress/wp-config.php

Zu guter Letzt härten Sie WordPress noch durch das PlugIn GoogleAuthenticator:

Hinweis:
Google Authenticator von Ivan Kruchkoff

Aktivieren Sie dieses Plugin und richten Ihren 2. Faktor für WordPress ein:

Hinweis:
Vergessen Sie nicht den abschließenden Slash beim Aufruf der wp-admin-Seite:
https://your.dedyn.io/wordpress/wp-admin/
Die Seite bleibt sonst leer/blank!

Es wird dringend empfohlen sich einen dedizierten und neuen Administrator einzurichten, sich mit diesem anzumelden und den 2. Faktor zu aktivieren:

Der Standard-Administrator sollte im Anschluß deaktiviert oder entfernt werden!

Glückwunsch, das war es schon! Über eine Spende würden sich meine Frau, meine Zwillinge und ich sehr freuen!

© Carsten Rieger IT-Services