WordPress Blog von http auf https umstellen

Hier möchte ich kurz beschreiben wie man seinen WordPress Blog von http:// auf https:// umstellen kann. Voraussetzung ist, dass für die Blog Domain bereits ein Zertifikat eingerichtet ist. Also die Domain schon unter https://domain.tld erreichbar ist. Die Website, die ich hier für die Umstellung nehme, ist die von meinem Schwager, da ich meine bereits umgestellt habe.

Es wird nicht nur das Backend umgestellt, sondern die ganze Webseite.
Deshalb müssen auch keine Konstanten in der wp-config.php definiert werden.
Durch das umstellen der ganzen Webseite wird sich das positiv auf das Google Ranking auswirken und auch Besuchern eine höhere Sicherheit angezeigt. Natürlich kommt hinzu, dass keine Daten mehr unverschlüsselt übertragen werden, was ja nicht nur bei Shops interessant ist.

Zur Umstellung:

Im Backend unter „Einstellungen > Allgemein“ die URLs von http://… aud https://… ändern und Speichern. Danach wieder neu Anmelden.
Falls die Felder ausgegraut sind habt ihr diese in der wp-config.php definiert und müsst sie dort ändern.

wp_ssl_umstellem_1

Eigentlich war das schon das wesentliche. Allerdings müssen wir jetzt noch den bestehenden Content anpassen. Dies machen wir mittels Search&Replace in der Datenbank.

Ich verwende dafür, da es sich für mich bewährt das Better Search Replace Plugin. Also das Plugin installieren und Aktivieren.

wp_ssl_umstellem_2

Dann unter „Werkzeuge > Better Search Replace“ öffnen. Bei „Suchen nach“ die Alte Blog URL eintragen und bei „Ersetzen durch“ die gleiche URL nur mit https. Bitte immer die vollständige Blog URL verwenden da es sonst zu Problemen kommen kann.
Danach alle Tabellen auswählen und den Haken bei „Auch GUIDs ersetzen“ setzen. Es kann nach Wunsch auch erst ein Testlauf gemacht werden. Damit die Änderungen endgültig durchgeführt werden, muss der Haken auf jeden Fall entfernt werden.
Man sollte vorher natürlich seine Datenbank sichern!

wp_ssl_umstellem_3

Nachdem die Änderungen durchgeführt wurden erscheint folgende Meldung

wp_ssl_umstellem_4

Damit sollten jetzt alle Blog URLs von http auf https umgestellt sein und das Plugin kann wieder deaktiviert und deinstalliert werden.

In Chrome sollte die Webseite dann mit einem grünen Schloss angezeigt werden.
Wenn nicht alle Inhalte mittels https ausgeliefert werden, ist das Schloss grau und nicht grün. Man erhält in der URL-Leiste einen Hinweis. Wenn das der Fall ist, muss noch in seinen Anpassungen (Widgets, PHP Dateien, usw.) suchen, ob dort noch URLs enthalten sind, die nicht mit https anfangen und diese umstellen.

wp_ssl_umstellem_5

Zusätzlich sollte man jetzt noch alle Aufrufe der Webseite auf die https URL umleiten. Dafür kann man mit folgendem Eintrag zusätzlich in die .htacssess einfügen.

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</IfModule>

Viel Spaß beim Umstellen.

WordPress Sicherheit erhöhen ohne Plugins

Ich bin der Meinung, dass man die Sicherheit von WordPress auch ohne Plugins erhöhen kann. Oder andersherum: Hackern und automatisierten Angriffen das Leben schwerer machen. Wie das geht, werde ich hier beschreiben.

Eins vorweg: Wenn man keine sicheren Passwörter verwendet, nützt einem auch die beste Absicherung nichts. Und das gilt nicht nur für deinen WordPress Zugang, sonder für alle Zugangsmöglichkeiten zu Webspace (FTP, SSH, MySQL, …). Außerdem bietet heute nahezu jeder Hoster die Möglichkeit Daten verschlüsselt zu übertragen. Insbesondere bei E-Mail oder FTP.

Die Installation:

Ich habe WordPress in einem unter Ordner installiert.  Ich bin der Meinung, wenn man diese Art der Installation wählt, hat ein automatisierter Angriff es zumindest etwas schwerer den WordPress Ordner zu finden. Außerdem finde ich es etwas aufgeräumter, da ich in dem Root Ordner noch weitere Dienste installiert habe, damit ich sie alle mit einem https Zertifikat nutzen kann. Dazu kommt noch, dass ich den „wp-content“ Ordner umbenannt habe.FTP-Ordner-wp-subfolder-install

Um den „wp-content“ Ordner umzuebnen, bedarf es zwei Einträge in der „wp-config.php“.

define( 'WP_CONTENT_DIR', realpath( dirname(__FILE__) . '/../content' ) );
define( 'WP_CONTENT_URL', 'https://dhue.de/content' );

Dies sollten heute alle Plugins unterstützen.

Zusätzliche Absicherungen:

.htaccess im Root (Haupt) Ordner.

<FilesMatch "(.htaccess|readme.html|liesmich.html|license.txt|license.md|readme.txt|readme.md|wp-config.php)"> Deny from all </FilesMatch> php_flag display_errors off

Der „FilesMatch“ Eintrag sorgt dafür, dass auf die Dateien in der Liste nicht direkt über eine URL zugegriffen werden kann. Hier sind auch die Readme Dateien enthalten, damit man darüber nicht erkennen kann, ob etwas vorhanden ist oder sogar die Version herausbekommt.

Die letzte Zeile sorgt dafür, dass PHP keine Fehlermeldungen ausgibt und man somit den Server Pfad nicht in Erfahrung bringen kann.

Im neuen „Content“ Ordner habe ich eine zusätzliche .htaccess liegen mit folgenden Einträgen.

<Files *.php>
 order allow,deny
 deny from all
</Files>
<Files debug.log>
 Order allow,deny
 Deny from all
</Files>

Das sorgt dafür, dass keine .php Dateien mehr direkt im „Content“ Ordner aufgerufen werden können. Allerdings muss hier getestet werden, ob auch alle Plugins und Themes damit funktionieren. Gute Plugins und Themes sollten aber kein Problem damit haben. Alle anderen Dateiformate können weiterhin direkt aufgerufen werden.

WordPress verschleiern:

Mit diesem Stück Code kann man noch einiges im HTML Kopf der Website verbergen oder dekatieren. Dieser kann in die funktions.php eures Child Themes geschrieben werden oder eben doch in ein Kleins Plugin. Hier bitte selber entscheiden, was ihr braucht oder nicht. Der wichtigste Punkt ist hier der „wp_generator“ da dieser auf jeder Seite im HTML  folgendes im Kopf hinzufügt <meta name="generator" content="WordPress 4.1" />.

// Head cleanup
function dh2015_head_cleanup() {
   // category feeds
   //remove_action( 'wp_head', 'feed_links_extra', 3 );
   // post and comment feeds
   //remove_action( 'wp_head', 'feed_links', 2 );
   // EditURI link
   remove_action( 'wp_head', 'rsd_link' );
   // windows live writer
   remove_action( 'wp_head', 'wlwmanifest_link' );
   // index link
   remove_action( 'wp_head', 'index_rel_link' );
   // previous link
   remove_action( 'wp_head', 'parent_post_rel_link', 10, 0 );
   // start link
   remove_action( 'wp_head', 'start_post_rel_link', 10, 0 );
   // links for adjacent posts
   remove_action( 'wp_head', 'adjacent_posts_rel_link_wp_head', 10, 0 );
   // WP version
   remove_action( 'wp_head', 'wp_generator' );
}
add_action( 'init', 'dh2015_head_cleanup' );

Anmerkung:

Darüber hinaus sollten natürlich auch das nicht benutzen des Standard DB Präfixes und das Rechte setzen der Ordner Berechtigungen nicht fehlen. Es gibt einen Artikel auf WordPress.org über das abhärten von WordPress der auch durchgegangen werden sollte.

WordPress Links Menü Walker

Hier eine kleine Walker Klasse für WordPress, um sich ein Menü in der Form “ Link1 | Link2 | Link3 “ zu erstellen.

Einfach die Klasse in die functions.php des Themes und den Menü Eintrag dort im Template platzieren, wo er hin soll.

<?php
wp_nav_menu(
   array(
      'container'      => FALSE,
      'menu'           => 'The Footer Links',
      'menu_class'     => 'nav',
      'theme_location' => 'footer-nav',
      'items_wrap'     => '<nav id="%1$s" class="%2$s" role="navigation">%3$s</nav>',
      'depth'          => 1,
      'walker'         => new Links_Walker_Nav_Menu()
   )
);

class Links_Walker_Nav_Menu extends Walker_Nav_Menu {

   function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) {

      //Add attributes to link element.
      $attributes = ! empty( $item->attr_title ) ? ' title="' . esc_attr( $item->attr_title ) . '"' : '';
      $attributes .= ! empty( $item->target ) ? ' target="' . esc_attr( $item->target ) . '"' : '';
      $attributes .= ! empty( $item->xfn ) ? ' rel="' . esc_attr( $item->xfn ) . '"' : '';
      $attributes .= ! empty( $item->url ) ? ' href="' . esc_attr( $item->url ) . '"' : '';
      $attributes .= ( $item->current ) ? ' class="active"' : '';

      $output .= ( $item->menu_order > 1 ) ? ' | ' : '';
      $output .= '<a' . $attributes . '>';
      $output .= $args->link_before . apply_filters( 'the_title', $item->title, $item->ID ) . $args->link_after;
      $output .= '</a>';

   }

   function end_el( &$output, $item, $depth = 0, $args = array() ) {

      $output .= '';
   }

}

Standard WordPress Plugin Funktionen

Zwei der Funktionen/Methoden, die man in Zukunft wohl in allen meinen Plugins finden wird, sind:
Voraussetzung ist PHP 5.1.2 für die Autoload Funktion.

1. Zum Ermitteln von Plugin Daten, damit nicht immer alles per Constante definiert wird, um Namensraum freizuhalten:

<?php
public static function get_plugin_data( $get_data = FALSE ) {

	$plugin_data = wp_cache_get( 'plugin_data', 'pluginname' );
	if ( $plugin_data === FALSE || empty( $plugin_data[ 'Version' ] ) ) {
		$plugin_data               = get_file_data(
			__FILE__, array(
				'Name'        => 'Plugin Name',
				'PluginURI'   => 'Plugin URI',
				'Version'     => 'Version',
				'Description' => 'Description',
				'Author'      => 'Author',
				'AuthorURI'   => 'Author URI',
				'TextDomain'  => 'Text Domain',
				'DomainPath'  => 'Domain Path'
			), 'plugin'
		);
		$plugin_data[ 'BaseName' ] = plugin_basename( __FILE__ );
		$plugin_data[ 'Folder' ]   = dirname( plugin_basename( __FILE__ ) );
		$plugin_data[ 'URL' ]      = plugins_url( '', __FILE__ );
		if ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) {
			$plugin_data[ 'JSVersion' ] = time();
		} else {
			$plugin_data[ 'JSVersion' ] = $plugin_data[ 'Version' ];
		}
		wp_cache_add( 'plugin_data', $plugin_data, 'pluginname' );
	}

	if ( ! $get_data ) {
		return $plugin_data;
	}

	return $plugin_data[ $get_data ];
}

2. Die Autoload Funktion von PHP zum automatischen Laden von Klassen, damit sie nur dann geladen werden, wenn sie auch benötigt werden. Das heißt, verwendet man ein „add_action“ wird die Klasse erst geladen, wenn wirklich ein „do_action“ erfolgt oder die Seitenklasse für einen Menüeintrag erst geladen wird, wenn der Menüpunkt tatsächlich aufgerufen wird. Voraussetzung ist, dass man das ganze Plugin klassenbasierend aufbaut. Das kann dann nicht nur Ressourcen sparen.

<?php
public function __construct() {
	//register autoloader
	spl_autoload_register( array( $this, 'autoloader' ) );
}

public static function autoloader( $class_name ) {
	//WordPress classes loader
	$wpclass='/class-'.strtolower(str_replace('_','-',$class_name)).'.php';
	if ( is_file(ABSPATH .'wp-admin'.DIRECTORY_SEPARATOR.'includes'.$wpclass) ) {
		require(ABSPATH .'wp-admin'.DIRECTORY_SEPARATOR.'includes'.$wpclass);
		return true;
	}
	if ( is_file(ABSPATH . WPINC . $wpclass) ) {
		require(ABSPATH . WPINC . $wpclass);
		return true;
	}

	//Plugin classes to load
	if ( strpos( $class_name,'PluginClass_') !== false ) {
		$class_load = dirname( __FILE__ ) . DIRECTORY_SEPARATOR.'inc'.DIRECTORY_SEPARATOR.'class-' . strtolower( str_replace( array( 'PluginClass_', '_' ), array( '', '-' ), $class_name ) ) . '.php';
		if ( is_file( $class_load ) ) {
			require($class_load);
			return true;
		}

	}
	return false;
}

Diese sollten sich innerhalb der Haupt Plugin Datei in einer Klasse befinden.

PHP Verzeichnis Übergabe prüfen

Ich muss in meinem Plugin für WordPress den ABSPATH übergeben, um eine eigene Ajax Behandlung zu haben.
Was meint ihr ist der Codeschnipsel dafür geeignet, um es möglicht sicher gegen Angriffe zu machen?

<?php
if ( is_file( dirname( dirname( dirname( dirname( __FILE__ ) ) ) ) . '/wp-load.php' ) ) {
	require_once( dirname( dirname( dirname( dirname( __FILE__ ) ) ) ) . '/wp-load.php' );
} else {
	$abspath = filter_input( INPUT_POST, 'ABSPATH', FILTER_SANITIZE_URL );
	$abspath = rtrim( realpath( $abspath ), '/' );
	if ( ! empty( $abspath ) && is_dir( $abspath . '/' ) && is_file( realpath( $abspath . '/wp-load.php' ) ) ) {
		require_once( $abspath . '/wp-load.php' );
	} else {
		die();
	}
}

Erläuterung:
Wenn der Plugins Ordner im Standard Verzeichnis ist oder zumindest in der selben Verzeichnis Tiefe muss die Übergabe nicht genutzt werden.
Sonst.
Das übergebene Verzeichnis vorfiltern (nur in URLs erlaubte Zeichen werden zugelassen)
mit ‚realpath()‘ alle ‚../‘,‘./‘ entfernen und prüfen, ob das Verzeichnis existiert.
Da ‚realpath()‘ auch das aktuelle Verzeichnis ausgibt nochmal Verzeichnis und Datei auf Existenz prüfen.
WP-load.php laden.

Ressourcen sparen bei Ajax Calls in WordPress

Bei meiner Arbeit am Plugin BackWPup habe ich nach einer Möglichkeit gesucht Ressourcen bei Ajax Calls und bei der Auftragsausführung zu sparen. Die einzige große Einsparung, die ich bisher gefunden habe, ist es die Übersetzungen anderer Plugins nicht mit zu laden, da die enorm viel Speicher verbrauchen. Dies bringt in meiner Testinstallation mit 20 Plugins eine Einsparung von 31 MB auf 25,5 MB Script Speicher. Da die Dateien auch nicht geöffnet werden, wird das auch noch eine Einsparung bringen, die ich im Moment nicht beziffern kann.

Hier die Umsetzung:
Wichtig ist hierbei, dass ich nur die Übersetzungen nicht lade, wenn es sich um Calls meines Plugins handelt.

<?php
define( 'PLUGIN_MENU_PAGES', 'page1,page2' );
if ( defined( 'DOING_AJAX' ) and DOING_AJAX and in_array(
		$_POST[ 'backwpupajaxpage' ], explode( ',', PLUGIN_MENU_PAGES )
	)
) {
	add_filter(
		'override_load_textdomain', create_function(
			'$default, $domain, $mofile', 'if ($domain=="textdomain") return $default; else return true;'
		), 1, 3
	);
}

Zusätzlich musste ich noch einbauen, dass mein Plugin als erstes geladen wird:

<?php
define( 'PLGUNINNAME_PLUGIN_BASENAME', plugin_basename( __FILE__ ) );

public function pluginname_first_plugin( $newvalue, $oldvalue ) {

	if ( ! is_array( $newvalue ) ) {
		return $newvalue;
	}
	for ( $i = 0; $i < count( $newvalue ); $i++ ) {
		if ( $newvalue[ $i ] == PLGUNINNAME_PLUGIN_BASENAME ) {
			unset( $newvalue[ $i ] );
		}
	}
	array_unshift( $newvalue, PLGUNINNAME_PLUGIN_BASENAME );

	return $newvalue;
}

add_filter( 'pre_update_option_active_plugins', 'pluginname_first_plugin', 1, 2 );

Vielleicht kennt ja noch jemand eine Lösung die Ressourcen weiter zu optimieren und die WordPress eigene Ajax Behandlung zu nutzen…

Update:
mit einer etwas geänderten Funktion ist es nicht mehr notwendig das Plugin nach vorne zu schieben.

<?php
define( 'PLUGIN_MENU_PAGES', 'page1,page2' );
function overide_textdomain( $default, $domain, $mofile ) {

	if ( ( defined( 'DOING_CRON' ) && DOING_CRON )
		&& in_array(
			$_POST[ 'backwpupajaxpage' ], explode( ',', PLUGIN_MENU_PAGES )
		)
	) {
		global $l10n;
		if ( $domain == 'owntextdomainname' ) {
			foreach ( array_keys( $l10n ) as $domainkey ) {
				unset( $l10n[ $domainkey ] );
			}
		} else {
			return TRUE;
		}
	}

	return $default;
}

add_filter( 'override_load_textdomain', 'overide_textdomain' );

Update: Ich glaub das beste ist es, wenn in WordPress der WP-Performance-Gettext-Patch integriert wird. Nach meinen Tests bringt das am meisten. Der Speicherverbrauch geht dann auf ca. 17MB runter.

Warum BackWPup von mir entwickelt wurde

Diese Frage tauchte heute in einem Kommentar eines Blog Beitrages über BackWPup von David Decker auf.

Also es war vor ca. etwas über einem Jahr, da war ich auf der Suche nach einer Backup Lösung für meinen Blog.

Diese sollte folgendes können:

  • Datei Backup
  • Datenbank Backup
  • die Backup Datei transferieren (FTP, Mail,…)

Außerdem wollte ich ab und zu ganz gerne mal ein automatisches Optimize der Datenbank durchführen.

Warum BackWPup von mir entwickelt wurde weiterlesen

BackWPup: Sicherung für deinen WP Blog

Ich habe ein neues Plugin für WordPress geschrieben mit dem man die Datenbank und die Dateien von WordPress sichern kann. Das Plugin heißt „BackWPup“ und steht ab sofort in der Version 0.5.0 zur Verfügung. Ich habe das Plugin ins Leben gerufen, weil ich auf der WordPress Homepage nur ein Plugin gefunden habe, was dieses unterstützt. Dieses Plugin wird aber zurzeit nicht mehr weiter entwickelt. Ich habe außerdem meinem Plugin eine Funktion zur automatischen Optimierung der Datenbank hinzugefügt, damit ich hierfür kein zusätzliches mehr brauche. Mein Plugin nutzt das in WordPress enthaltene PCLzip zum Komprimieren der Sicherung.

Wer will, kann das Plugin gerne mal downloaden und testen. Die aktuelle Version ist zwar noch in der Entwicklung, aber soweit ich testen konnte, läuft es jetzt schon sehr gut.

Für Anregungen und Verbesserungen bin ich gerne zu haben.