Gut zu wissen: Die Ländersperre ist ein zusätzliches Schloss, kein Ersatz für die anderen. Updates, starke Passwörter und eine Zwei-Faktor-Anmeldung für Admins bleiben Pflicht.
Warum das so viel bringt
Automatische Angriffe auf WordPress laufen fast immer gleich ab: Ein Programm ruft wp-login.php oder xmlrpc.php auf und probiert Benutzernamen und Passwörter durch, tausendfach. Mit der Ländersperre bekommt jeder Zugriff von außerhalb deiner Länder nur noch „Seite nicht gefunden“. Es gibt keine Anmeldeseite, also auch nichts zu raten.
Die Website selbst bleibt weltweit erreichbar. Besucher im Urlaub, Google und andere Suchmaschinen merken nichts. Gesperrt ist nur die Tür zum Backend. Nebenbei wird der Server entlastet, und im Protokoll ist es deutlich ruhiger.
Wir haben das gerade bei einem Verein mit Mitgliederbereich so eingebaut. Hier steht die schlanke Fassung, die auf jeder WordPress-Website funktioniert.
Wie es funktioniert
Jede IP-Adresse gehört zu einem Land. Der Anbieter DB-IP veröffentlicht jeden Monat eine kostenlose Liste, welche Adressen zu welchem Land gehören. Diese Liste lädst du einmal herunter und legst sie auf deinen eigenen Server. Ein kleines Plugin schaut bei jedem Anmeldeversuch in dieser Liste nach.
Es gibt also keine Abfrage bei einem fremden Dienst, keinen API-Schlüssel, kein Cookie, und die IP-Adresse wird nicht gespeichert. Alles bleibt auf deinem Server, auch die Liste selbst.
Was du brauchst
Einen Zugang zu den Dateien deiner Website: per FTP (zum Beispiel mit FileZilla) oder über den Dateimanager deines Hosters. Dazu etwa 15 Minuten und für den Test ein Handy mit einer VPN-App. Programmieren musst du nicht.
Schritt 1: Sicherung machen
Bevor du an den Dateien arbeitest, sicherst du die Website. Bei vielen Hostern geht das mit einem Klick im Kundenmenü, sonst mit einem Backup-Plugin. Lies außerdem schon jetzt den Abschnitt „Notfall“ weiter unten. Dann weißt du, was zu tun ist, falls du dich aussperrst.
Schritt 2: Die Länderliste herunterladen
Öffne auf db-ip.com die Seite „IP to Country Lite“ und lade die Datei im Format CSV herunter. Sie heißt zum Beispiel dbip-country-lite-2026-11.csv.gz und ist ein paar Megabyte groß. Eine Anmeldung braucht es dafür nicht.
Wichtig: Die Datei nicht entpacken und nicht umbenennen. Das Plugin liest sie genau so, wie sie ist.
Die Liste steht unter der Lizenz CC BY 4.0. Sie verlangt einen Hinweis auf DB-IP. Den setzt das Plugin automatisch klein unter die Anmeldeseite.
Schritt 3: Ordner anlegen und Liste hochladen
Verbinde dich per FTP mit deiner Website und öffne den Ordner wp-content. Lege darin einen neuen Ordner laendersperre an und lade die Datei aus Schritt 2 hinein:
wp-content/
laendersperre/
dbip-country-lite-2026-11.csv.gzSchritt 4: Das Plugin anlegen
Im selben Ordner wp-content brauchst du einen Ordner mu-plugins. Gibt es ihn noch nicht, legst du ihn an. Plugins in diesem Ordner lädt WordPress automatisch. Sie lassen sich im Backend nicht versehentlich abschalten und erscheinen unter Plugins als „Unverzichtbar“.
Lege dort eine Datei laendersperre.php an und kopiere diesen Code hinein. Speichern, hochladen, fertig:
<?php
/**
* Plugin Name: Ländersperre für den WordPress-Login
* Description: wp-login.php und wp-admin sind nur aus den erlaubten Ländern erreichbar. Die Länderdaten liegen auf dem eigenen Server, es wird nichts an fremde Dienste übertragen.
* Version: 1.0.0
* Author: modulstyle.com
* Author URI: https://modulstyle.com/blog/wp-admin-laendersperre/
* License: GPL-2.0-or-later
*
* Gehört in den Ordner wp-content/mu-plugins/ (wird dort automatisch geladen).
* Die Länderliste „IP to Country Lite“ von DB-IP (CC BY 4.0) kommt als .csv.gz in wp-content/laendersperre/.
* Anleitung: https://modulstyle.com/blog/wp-admin-laendersperre/
*
* Notschalter, falls du dich aussperrst – diese Zeile in die wp-config.php:
* define( 'MS_LAENDERSPERRE_AUS', true );
*/
defined( 'ABSPATH' ) || exit;
/* =====================================================================
* EINSTELLUNGEN – nur hier etwas ändern
* ================================================================== */
// Erlaubte Länder als zweistellige Codes: DE Deutschland, AT Österreich, CH Schweiz, ES Spanien, NL Niederlande …
// Wer in einem anderen Land wohnt, trägt eben dieses Land ein, z. B. array( 'ES' ) oder array( 'DE', 'ES' ).
// Alternativ in der wp-config.php: define( 'MS_LAENDERSPERRE_LAENDER', 'DE,AT' );
const MS_LS_LAENDER = array( 'DE' );
// Einzelne IP-Adressen, die immer dürfen (z. B. ein Monitoring-Dienst). Normalerweise leer lassen.
const MS_LS_IMMER = array();
/* =====================================================================
* Ab hier nichts ändern
* ================================================================== */
define( 'MS_LS_ORDNER', WP_CONTENT_DIR . '/laendersperre' );
/** Erlaubte Länder (wp-config.php hat Vorrang vor der Liste oben). */
function ms_ls_laender(): array {
$liste = defined( 'MS_LAENDERSPERRE_LAENDER' ) ? explode( ',', (string) MS_LAENDERSPERRE_LAENDER ) : MS_LS_LAENDER;
return array_values( array_filter( array_map( fn( $c ) => strtoupper( trim( (string) $c ) ), $liste ), fn( $c ) => (bool) preg_match( '/^[A-Z]{2}$/', $c ) ) );
}
/** Ländercode zu einer IP-Adresse: 'DE', 'US' …; '' = unbekannt (keine Daten, interne Adresse, nicht zugeordnet). */
function ms_ls_land( string $ip ): string {
static $cache = array();
if ( isset( $cache[ $ip ] ) ) {
return $cache[ $ip ];
}
if ( ! filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE ) ) {
return $cache[ $ip ] = '';
}
$bin = inet_pton( $ip );
if ( 16 === strlen( $bin ) && str_starts_with( $bin, str_repeat( "\0", 10 ) . "\xff\xff" ) ) {
$bin = substr( $bin, 12 ); // IPv4 in IPv6-Schreibweise (::ffff:1.2.3.4)
}
[ $datei, $breite ] = 4 === strlen( $bin ) ? array( 'geo4.bin', 4 ) : array( 'geo6.bin', 8 );
$pfad = MS_LS_ORDNER . '/' . $datei;
$fh = is_readable( $pfad ) ? fopen( $pfad, 'rb' ) : false; // phpcs:ignore WordPress.WP.AlternativeFunctions
if ( ! $fh ) {
return $cache[ $ip ] = '';
}
// Binärsuche in Datensätzen „Startadresse + Ländercode“, aufsteigend sortiert und lückenlos.
$suche = substr( $bin, 0, $breite );
$satz = $breite + 2;
$lo = 0;
$hi = (int) ( filesize( $pfad ) / $satz ) - 1;
$land = '';
while ( $lo <= $hi ) {
$mitte = ( $lo + $hi ) >> 1;
fseek( $fh, $mitte * $satz );
$rec = (string) fread( $fh, $satz ); // phpcs:ignore WordPress.WP.AlternativeFunctions
if ( strcmp( substr( $rec, 0, $breite ), $suche ) <= 0 ) {
$land = substr( $rec, $breite, 2 );
$lo = $mitte + 1;
} else {
$hi = $mitte - 1;
}
}
fclose( $fh ); // phpcs:ignore WordPress.WP.AlternativeFunctions
return $cache[ $ip ] = ( '--' === $land ? '' : $land );
}
/** Kommt die aktuelle Anfrage aus einem nicht erlaubten Land? Im Zweifel nein – lieber offen als ausgesperrt. */
function ms_ls_ausland(): bool {
if ( defined( 'MS_LAENDERSPERRE_AUS' ) && MS_LAENDERSPERRE_AUS ) {
return false;
}
// Bewusst nur REMOTE_ADDR: Weitergeleitete Kopfzeilen (X-Forwarded-For) kann jeder fälschen.
$ip = (string) ( $_SERVER['REMOTE_ADDR'] ?? '' );
if ( in_array( $ip, MS_LS_IMMER, true ) ) {
return false;
}
$land = ms_ls_land( $ip );
return '' !== $land && ! in_array( $land, ms_ls_laender(), true );
}
/** Antwort für gesperrte Zugriffe: eine schlichte „Seite nicht gefunden“. Der Login verrät sich nicht. */
function ms_ls_404(): void {
status_header( 404 );
nocache_headers();
header( 'Content-Type: text/html; charset=utf-8' );
header( 'X-Robots-Tag: noindex' );
echo '<!doctype html><html lang="de"><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Seite nicht gefunden</title>'
. '<body style="font:16px/1.5 system-ui,sans-serif;max-width:36rem;margin:15vh auto;padding:0 1rem"><h1>Seite nicht gefunden</h1>'
. '<p><a href="' . esc_url( home_url( '/' ) ) . '">Zur Startseite</a></p></body></html>';
exit;
}
/* ---------------------------------------------------------------------
* Die eigentliche Sperre
* ------------------------------------------------------------------ */
// XML-RPC: altes Einfallstor für Passwort-Raten. Aus dem Ausland gar nicht erst bearbeiten.
if ( defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST && ms_ls_ausland() ) {
status_header( 403 );
exit;
}
// wp-login.php (Anmelden, Registrieren, Passwort vergessen) – Abmelden und passwortgeschützte Beiträge bleiben.
add_action( 'login_init', function () {
$aktion = sanitize_key( $_REQUEST['action'] ?? 'login' ); // phpcs:ignore WordPress.Security.NonceVerification
if ( ! in_array( $aktion, array( 'logout', 'postpass' ), true ) && ms_ls_ausland() ) {
ms_ls_404();
}
}, 0 );
// wp-admin ohne Anmeldung (WordPress würde sonst zur Anmeldeseite weiterleiten).
// admin-ajax.php und admin-post.php bleiben offen, weil Formulare im Frontend sie brauchen.
add_action( 'init', function () {
if ( ! is_admin() || wp_doing_ajax() || wp_doing_cron() || is_user_logged_in() ) {
return;
}
if ( in_array( basename( (string) ( $_SERVER['SCRIPT_NAME'] ?? '' ) ), array( 'admin-ajax.php', 'admin-post.php' ), true ) ) {
return;
}
if ( ms_ls_ausland() ) {
ms_ls_404();
}
}, 0 );
// Jede andere Anmeldung (eigene Login-Formulare, Shop-Konto …): Aus gesperrten Ländern scheitert sie immer,
// mit derselben Meldung – egal ob das Passwort stimmt.
add_filter( 'authenticate', function ( $user, $name = '' ) {
if ( '' !== trim( (string) $name ) && ms_ls_ausland() ) {
return new WP_Error( 'ms_laendersperre', 'Eine Anmeldung ist von deinem Standort aus nicht möglich.' );
}
return $user;
}, 99, 2 );
// Anwendungspasswörter (Zugriff über die Schnittstelle) aus dem Ausland abschalten.
add_filter( 'wp_is_application_passwords_available', fn( $an ) => $an && ! ms_ls_ausland() );
/* ---------------------------------------------------------------------
* Länderliste einlesen: aus der .csv.gz von DB-IP werden zwei kompakte Dateien
* ------------------------------------------------------------------ */
/** Neueste hochgeladene Länderliste (dbip-country-lite-JJJJ-MM.csv.gz). */
function ms_ls_quelle(): string {
$dateien = glob( MS_LS_ORDNER . '/dbip-country-lite-*.csv.gz' ) ?: array();
sort( $dateien );
return (string) end( $dateien );
}
function ms_ls_plus_eins( string $b ): ?string {
for ( $i = strlen( $b ) - 1; $i >= 0; $i-- ) {
$o = ord( $b[ $i ] );
if ( $o < 255 ) {
$b[ $i ] = chr( $o + 1 );
return $b;
}
$b[ $i ] = "\0";
}
return null; // Ende des Adressraums
}
/** Liest die Liste ein. Rückgabe: '' bei Erfolg, sonst eine Fehlermeldung. */
function ms_ls_einlesen( string $quelle ): string {
@set_time_limit( 300 ); // phpcs:ignore
$gz = gzopen( $quelle, 'rb' );
if ( ! $gz ) {
return 'Die Datei ' . basename( $quelle ) . ' lässt sich nicht öffnen.';
}
$aus = array( 4 => fopen( MS_LS_ORDNER . '/geo4.tmp', 'wb' ), 6 => fopen( MS_LS_ORDNER . '/geo6.tmp', 'wb' ) ); // phpcs:ignore
$ende = array( 4 => null, 6 => null ); // Ende des letzten Bereichs
$start = array( 4 => null, 6 => null ); // Start des letzten Bereichs (Sortierprüfung)
$land = array( 4 => null, 6 => null );
$zahl = array( 4 => 0, 6 => 0 );
if ( ! $aus[4] || ! $aus[6] ) {
return 'Im Ordner wp-content/laendersperre kann nicht geschrieben werden.';
}
$schreib = function ( int $f, string $von, string $cc ) use ( &$aus, &$land, &$zahl ) {
if ( $cc !== $land[ $f ] ) { // gleiche Länder hintereinander zusammenfassen
fwrite( $aus[ $f ], $von . $cc ); // phpcs:ignore
$land[ $f ] = $cc;
++$zahl[ $f ];
}
};
$fehler = '';
while ( false !== ( $zeile = gzgets( $gz, 256 ) ) ) {
$t = explode( ',', str_replace( '"', '', trim( $zeile ) ) );
if ( count( $t ) < 3 ) {
continue;
}
$a = @inet_pton( trim( $t[0] ) ); // phpcs:ignore
$b = @inet_pton( trim( $t[1] ) ); // phpcs:ignore
// Spalten: erste IP, letzte IP, Land – manche Ausgaben haben vor dem Land noch den Kontinent (EU, NA …).
$cc = strtoupper( trim( $t[2] ) );
if ( count( $t ) > 3 && in_array( $cc, array( 'AF', 'AN', 'AS', 'EU', 'NA', 'OC', 'SA' ), true ) && preg_match( '/^[A-Za-z]{2}$/', trim( $t[3] ) ) ) {
$cc = strtoupper( trim( $t[3] ) );
}
if ( false === $a || false === $b || strlen( $a ) !== strlen( $b ) ) {
continue;
}
$cc = preg_match( '/^[A-Z]{2}$/', $cc ) && 'ZZ' !== $cc ? $cc : '--';
$f = 4 === strlen( $a ) ? 4 : 6;
$w = 4 === $f ? 4 : 8; // IPv6: die ersten 64 Bit genügen fürs Land
$von = substr( $a, 0, $w );
$bis = substr( $b, 0, $w );
if ( null !== $start[ $f ] && strcmp( $von, $start[ $f ] ) < 0 ) {
$fehler = 'Die Länderliste ist nicht sortiert. Bitte die Originaldatei von DB-IP hochladen.';
break;
}
$start[ $f ] = $von;
if ( null === $ende[ $f ] ) {
if ( trim( $von, "\0" ) !== '' ) {
$schreib( $f, str_repeat( "\0", $w ), '--' ); // Anfang des Adressraums ohne Land
}
} elseif ( strcmp( $von, $ende[ $f ] ) <= 0 ) {
if ( strcmp( $bis, $ende[ $f ] ) <= 0 ) {
continue; // liegt im vorigen Bereich (IPv6 unter /64)
}
$von = ms_ls_plus_eins( $ende[ $f ] );
} elseif ( $von !== ms_ls_plus_eins( $ende[ $f ] ) ) {
$schreib( $f, ms_ls_plus_eins( $ende[ $f ] ), '--' ); // Lücke ohne Land
}
$schreib( $f, $von, $cc );
$ende[ $f ] = $bis;
}
gzclose( $gz );
foreach ( array( 4, 6 ) as $f ) {
$danach = null === $ende[ $f ] ? null : ms_ls_plus_eins( $ende[ $f ] );
if ( null !== $danach ) {
$schreib( $f, $danach, '--' ); // Ende des Adressraums ohne Land
}
}
fclose( $aus[4] ); // phpcs:ignore
fclose( $aus[6] ); // phpcs:ignore
if ( '' === $fehler && $zahl[4] < 10000 ) {
$fehler = 'Die Länderliste ist unvollständig (nur ' . $zahl[4] . ' IPv4-Bereiche).';
}
if ( '' !== $fehler ) {
@unlink( MS_LS_ORDNER . '/geo4.tmp' ); // phpcs:ignore
@unlink( MS_LS_ORDNER . '/geo6.tmp' ); // phpcs:ignore
return $fehler;
}
rename( MS_LS_ORDNER . '/geo6.tmp', MS_LS_ORDNER . '/geo6.bin' );
rename( MS_LS_ORDNER . '/geo4.tmp', MS_LS_ORDNER . '/geo4.bin' );
file_put_contents( MS_LS_ORDNER . '/stand.txt', basename( $quelle ) ); // phpcs:ignore
if ( ! file_exists( MS_LS_ORDNER . '/index.php' ) ) {
file_put_contents( MS_LS_ORDNER . '/index.php', "<?php\n// Stille ist Gold.\n" ); // phpcs:ignore
}
return '';
}
// Neue Liste hochgeladen? Dann beim nächsten Besuch eines Admins im Backend einlesen (dauert einige Sekunden).
add_action( 'admin_init', function () {
if ( wp_doing_ajax() || ! current_user_can( 'manage_options' ) ) {
return;
}
$quelle = ms_ls_quelle();
$bin = MS_LS_ORDNER . '/geo4.bin';
if ( '' === $quelle || ( is_file( $bin ) && filemtime( $bin ) >= filemtime( $quelle ) ) || get_transient( 'ms_ls_laeuft' ) ) {
return;
}
$kennung = basename( $quelle ) . '|' . filemtime( $quelle );
$alt = (array) get_option( 'ms_ls_fehler', array() );
if ( ( $alt['datei'] ?? '' ) === $kennung ) {
return; // diese Datei ist schon einmal gescheitert – erst eine neue hochladen
}
set_transient( 'ms_ls_laeuft', 1, 5 * MINUTE_IN_SECONDS );
$fehler = ms_ls_einlesen( $quelle );
delete_transient( 'ms_ls_laeuft' );
if ( '' !== $fehler ) {
update_option( 'ms_ls_fehler', array( 'datei' => $kennung, 'text' => $fehler ), false );
} else {
delete_option( 'ms_ls_fehler' );
}
} );
/* ---------------------------------------------------------------------
* Hinweise: Status im Dashboard, Namensnennung für DB-IP auf der Anmeldeseite
* ------------------------------------------------------------------ */
add_action( 'admin_notices', function () {
$screen = function_exists( 'get_current_screen' ) ? get_current_screen() : null;
if ( ! current_user_can( 'manage_options' ) || ! $screen || 'dashboard' !== $screen->id ) {
return;
}
$fehler = (string) ( ( (array) get_option( 'ms_ls_fehler', array() ) )['text'] ?? '' );
$ip = (string) ( $_SERVER['REMOTE_ADDR'] ?? '' );
$land = ms_ls_land( $ip );
$stand = is_readable( MS_LS_ORDNER . '/stand.txt' ) ? trim( (string) file_get_contents( MS_LS_ORDNER . '/stand.txt' ) ) : ''; // phpcs:ignore
$aus = defined( 'MS_LAENDERSPERRE_AUS' ) && MS_LAENDERSPERRE_AUS;
if ( $fehler ) {
$typ = 'error';
$text = 'Ländersperre: ' . $fehler;
} elseif ( ! is_readable( MS_LS_ORDNER . '/geo4.bin' ) ) {
$typ = 'warning';
$text = 'Ländersperre: noch nicht aktiv. Lade die Länderliste (dbip-country-lite-….csv.gz) in den Ordner wp-content/laendersperre hoch und öffne danach das Dashboard erneut.';
} elseif ( $aus ) {
$typ = 'warning';
$text = 'Ländersperre: abgeschaltet über MS_LAENDERSPERRE_AUS in der wp-config.php.';
} else {
$typ = 'success';
$text = 'Ländersperre aktiv. Anmeldung erlaubt aus: ' . implode( ', ', ms_ls_laender() ) . '. Dein Anschluss: ' . ( $land ?: 'unbekannt' ) . '. Länderliste: ' . $stand . '.';
}
printf( '<div class="notice notice-%s"><p>%s <small><a href="https://db-ip.com" rel="noopener">IP Geolocation by DB-IP</a></small></p></div>', esc_attr( $typ ), esc_html( $text ) );
} );
// Die Lizenz von DB-IP (CC BY 4.0) verlangt eine Namensnennung.
add_action( 'login_footer', function () {
echo '<p style="text-align:center;font-size:12px;opacity:.6"><a href="https://db-ip.com" rel="noopener">IP Geolocation by DB-IP</a></p>';
} );
Lieber als Datei? Hier gibt es das Plugin als ZIP zum Herunterladen. Entpacken und die Datei laendersperre.php in den Ordner mu-plugins laden.
Schritt 5: Deine Länder eintragen
Ganz oben in der Datei steht, aus welchen Ländern die Anmeldung erlaubt ist. Voreingestellt ist Deutschland:
const MS_LS_LAENDER = array( 'DE' );Du wohnst in einem anderen Land? Dann trägst du eben dieses ein. Mehrere Länder trennst du mit Komma:
const MS_LS_LAENDER = array( 'ES' ); // nur Spanien
const MS_LS_LAENDER = array( 'DE', 'AT', 'CH' ); // Deutschland, Österreich, SchweizDie Codes sind die üblichen zweistelligen Länderkürzel: DE Deutschland, AT Österreich, CH Schweiz, NL Niederlande, FR Frankreich, IT Italien, ES Spanien, PL Polen, GB Großbritannien, US USA. Arbeiten mehrere Leute an der Website, gehören alle ihre Länder in die Liste.
Schritt 6: Einmal im Backend anmelden
Melde dich wie gewohnt an und öffne das Dashboard. Beim ersten Mal liest das Plugin die Länderliste ein, das dauert ein paar Sekunden. Danach steht oben ein grüner Hinweis, zum Beispiel: „Ländersperre aktiv. Anmeldung erlaubt aus: DE. Dein Anschluss: DE.“
Steht bei „Dein Anschluss“ ein anderes Land als erwartet, meldest du dich jetzt nicht ab. Trag zuerst dieses Land ein oder nimm das Plugin wieder heraus. Das kommt selten vor, zum Beispiel bei Firmennetzen, die über ein anderes Land ins Internet gehen.
Schritt 7: Testen
Schalte am Handy das WLAN aus und in der VPN-App ein anderes Land ein, etwa die Niederlande. Ruf dann deine-domain.de/wp-admin und deine-domain.de/wp-login.php auf. Beide Male sollte „Seite nicht gefunden“ erscheinen. Die Startseite muss dagegen ganz normal laden.
Schalte das VPN wieder aus. Über das deutsche Mobilfunknetz erscheint die Anmeldeseite wie gewohnt.
Notfall: Du hast dich ausgesperrt
Kein Grund zur Panik, dafür gibt es zwei Wege. Entweder du öffnest per FTP die Datei wp-config.php und fügst über der Zeile „That's all, stop editing“ diese Zeile ein:
define( 'MS_LAENDERSPERRE_AUS', true );Oder du benennst die Datei wp-content/mu-plugins/laendersperre.php um, zum Beispiel in laendersperre.aus. In beiden Fällen ist die Sperre sofort aus. Wenn alles wieder läuft, nimmst du die Zeile heraus beziehungsweise benennst die Datei zurück.
Im Urlaub oder auf Dienstreise
Wer schon angemeldet ist, bleibt angemeldet, auch im Ausland. Gesperrt ist nur die neue Anmeldung. Willst du dich unterwegs neu anmelden, trägst du das Reiseland vorher zusätzlich ein und nimmst es nach der Rückkehr wieder heraus.
Ohne die Plugin-Datei anzufassen, geht das auch über die wp-config.php. Diese Zeile hat Vorrang vor der Liste im Plugin:
define( 'MS_LAENDERSPERRE_LAENDER', 'DE,IT' );Einmal im Monat: die Liste erneuern
IP-Adressen wechseln immer wieder das Land. DB-IP aktualisiert die Liste deshalb jeden Monat. Lade die neue Datei in den Ordner laendersperre und lösch die alte. Beim nächsten Besuch im Dashboard liest das Plugin sie automatisch ein.
Vergisst du es einmal, passiert nichts Schlimmes: Die alte Liste arbeitet weiter. Adressen, die in der Liste noch fehlen, lässt das Plugin im Zweifel durch. Lieber eine Lücke als ein ausgesperrter Redakteur.
Was die Sperre nicht kann
Wer ein VPN mit deutschem Server nutzt oder einen gekaperten Rechner in Deutschland, kommt an der Ländersperre vorbei. Sie hält also nicht jeden ab, aber den allergrößten Teil der automatischen Versuche. Für die übrigen sorgen ein starkes Passwort, eine Zwei-Faktor-Anmeldung und eine Sperre nach mehreren Fehlversuchen.
Läuft deine Website hinter einem Dienst wie Cloudflare, sieht der Server nur dessen Adresse. Dann funktioniert die Sperre so nicht. Solche Dienste haben eigene Länderregeln, die du dort einstellst.
Eigene Anmeldeformulare, zum Beispiel im Shop-Konto, sind mit abgedeckt: Aus gesperrten Ländern scheitert jede Anmeldung, egal ob das Passwort stimmt. Das alte xmlrpc.php antwortet dorthin gar nicht erst.
Und der Datenschutz?
Technisch ist die Sache schlank: Die Länderprüfung passiert nur auf deinem Server, es wird nichts übertragen, nichts gespeichert und kein Cookie gesetzt. Die IP-Adresse wird trotzdem verarbeitet, nur eben kurz und lokal.
Wichtig: Wir prüfen keine rechtlichen Fragen. Ob und wie die Ländersperre in deiner Datenschutzerklärung erwähnt werden sollte, klärst du mit einem Anwalt oder deinem Datenschutzbeauftragten.
Kurz gesagt
Liste herunterladen, eine Datei anlegen, Land eintragen, testen. Danach ist die Anmeldeseite deiner WordPress-Website für den Großteil der Angreifer schlicht nicht mehr da. Einmal im Monat die Liste tauschen, das war's.
Keine Lust auf FTP? Wir richten die Ländersperre gern für dich ein und schauen bei der Gelegenheit, wie es sonst um die Sicherheit deiner Website steht. Schreib uns. Ob deine Website außerdem fremde Dienste nachlädt, zeigt unser kostenloser Cookie-Check.