Upload via GUI (39 Dateien)
This commit is contained in:
@@ -0,0 +1,405 @@
|
||||
<?php
|
||||
/**
|
||||
* WP Multi – Modul: Brute-Force-Schutz
|
||||
*
|
||||
* Automatisch aus wp-multi.php ausgelagert. Wird über den Loader in
|
||||
* wp-multi.php eingebunden (nur wenn das WP Multi Toolkit aktiv ist).
|
||||
*/
|
||||
|
||||
if (!defined('ABSPATH')) { exit; }
|
||||
|
||||
/*
|
||||
* Schutz vor Brute-Force-Angriffen mit wöchentlicher Zusammenfassung
|
||||
* Sperr-E-Mails entfernt, Zusammenfassung deaktivierbar unter Benutzer mit verbessertem Design
|
||||
*/
|
||||
|
||||
// Funktion zur Erfassung der echten IP-Adresse des Benutzers
|
||||
function get_user_ip() {
|
||||
if (!empty($_SERVER['HTTP_CLIENT_IP']) && filter_var($_SERVER['HTTP_CLIENT_IP'], FILTER_VALIDATE_IP)) {
|
||||
return $_SERVER['HTTP_CLIENT_IP'];
|
||||
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
|
||||
$ips = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
|
||||
$ip = trim($ips[0]);
|
||||
return filter_var($ip, FILTER_VALIDATE_IP) ? $ip : $_SERVER['REMOTE_ADDR'];
|
||||
}
|
||||
return filter_var($_SERVER['REMOTE_ADDR'], FILTER_VALIDATE_IP) ? $_SERVER['REMOTE_ADDR'] : '0.0.0.0';
|
||||
}
|
||||
|
||||
// Funktion zur Verfolgung von fehlgeschlagenen Anmeldeversuchen
|
||||
function wp_multi_log_failed_login($username) {
|
||||
global $wpdb;
|
||||
|
||||
$ip = get_user_ip();
|
||||
if ($ip === '0.0.0.0') {
|
||||
return;
|
||||
}
|
||||
|
||||
$blocked_table = $wpdb->prefix . 'blocked_ips';
|
||||
$attempts_table = $wpdb->prefix . 'login_attempts';
|
||||
$block_threshold = 5;
|
||||
|
||||
// Anmeldeversuch in attempts-Tabelle speichern
|
||||
$wpdb->insert(
|
||||
$attempts_table,
|
||||
array(
|
||||
'ip' => $ip,
|
||||
'username' => $username,
|
||||
'attempt_time' => current_time('mysql'),
|
||||
),
|
||||
array('%s', '%s', '%s')
|
||||
);
|
||||
|
||||
// Prüfen, ob IP bereits in blocked_ips existiert
|
||||
$row = $wpdb->get_row($wpdb->prepare("SELECT * FROM $blocked_table WHERE ip = %s", $ip));
|
||||
|
||||
if ($row) {
|
||||
$wpdb->update(
|
||||
$blocked_table,
|
||||
array(
|
||||
'attempts' => $row->attempts + 1,
|
||||
'last_attempt' => current_time('mysql'),
|
||||
),
|
||||
array('ip' => $ip),
|
||||
array('%d', '%s'),
|
||||
array('%s')
|
||||
);
|
||||
$attempts = $row->attempts + 1;
|
||||
} else {
|
||||
$wpdb->insert(
|
||||
$blocked_table,
|
||||
array(
|
||||
'ip' => $ip,
|
||||
'attempts' => 1,
|
||||
'last_attempt' => current_time('mysql'),
|
||||
),
|
||||
array('%s', '%d', '%s')
|
||||
);
|
||||
$attempts = 1;
|
||||
}
|
||||
|
||||
// IP sperren, wenn Schwellenwert erreicht
|
||||
if ($attempts >= $block_threshold) {
|
||||
wp_die(
|
||||
__('Deine IP-Adresse wurde aufgrund zu vieler Fehlversuche gesperrt. Bitte versuche es später noch einmal.', 'wp-multi'),
|
||||
__('Zugriff gesperrt', 'wp-multi'),
|
||||
array('response' => 403)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Hook für fehlgeschlagene Anmeldungen
|
||||
add_action('wp_login_failed', 'wp_multi_log_failed_login', 10, 1);
|
||||
|
||||
// Funktion zur Erstellung der Tabellen
|
||||
function wp_multi_create_blocked_ips_table() {
|
||||
global $wpdb;
|
||||
|
||||
$blocked_table = $wpdb->prefix . 'blocked_ips';
|
||||
$attempts_table = $wpdb->prefix . 'login_attempts';
|
||||
$charset_collate = $wpdb->get_charset_collate();
|
||||
$version = get_option('wp_multi_blocked_ips_version', '1.0');
|
||||
|
||||
if (version_compare($version, '1.1', '<')) {
|
||||
$sql_blocked = "CREATE TABLE $blocked_table (
|
||||
id mediumint(9) NOT NULL AUTO_INCREMENT,
|
||||
ip varchar(45) NOT NULL,
|
||||
attempts int NOT NULL DEFAULT 0,
|
||||
last_attempt datetime NOT NULL,
|
||||
PRIMARY KEY (id),
|
||||
KEY ip (ip)
|
||||
) $charset_collate;";
|
||||
|
||||
$sql_attempts = "CREATE TABLE $attempts_table (
|
||||
id mediumint(9) NOT NULL AUTO_INCREMENT,
|
||||
ip varchar(45) NOT NULL,
|
||||
username varchar(255) NOT NULL,
|
||||
attempt_time datetime NOT NULL,
|
||||
PRIMARY KEY (id),
|
||||
KEY ip (ip),
|
||||
KEY attempt_time (attempt_time)
|
||||
) $charset_collate;";
|
||||
|
||||
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
|
||||
dbDelta($sql_blocked);
|
||||
dbDelta($sql_attempts);
|
||||
update_option('wp_multi_blocked_ips_version', '1.1');
|
||||
}
|
||||
}
|
||||
register_activation_hook(WP_MULTI_FILE, 'wp_multi_create_blocked_ips_table');
|
||||
|
||||
// Wöchentliche Zusammenfassung
|
||||
function wp_multi_send_weekly_summary() {
|
||||
global $wpdb;
|
||||
|
||||
// Prüfen, ob Zusammenfassung aktiviert ist
|
||||
$summary_enabled = get_option('wp_multi_summary_enabled', 1);
|
||||
if (!$summary_enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
$attempts_table = $wpdb->prefix . 'login_attempts';
|
||||
$last_email_time = get_option('wp_multi_last_summary_email', 0);
|
||||
$current_time = time();
|
||||
|
||||
// Prüfen, ob eine Woche vergangen ist (7 Tage = 604800 Sekunden)
|
||||
if (($current_time - $last_email_time) < 604800) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Zeitraum für die Zusammenfassung (letzte Woche)
|
||||
$week_ago = date('Y-m-d H:i:s', strtotime('-7 days'));
|
||||
$now = date('Y-m-d H:i:s');
|
||||
|
||||
// Gesamtzahl der Anmeldeversuche
|
||||
$total_attempts = $wpdb->get_var(
|
||||
$wpdb->prepare(
|
||||
"SELECT COUNT(*) FROM $attempts_table WHERE attempt_time >= %s",
|
||||
$week_ago
|
||||
)
|
||||
);
|
||||
$total_attempts = $total_attempts ? $total_attempts : 0;
|
||||
|
||||
// Top 10 IPs mit den meisten Anmeldeversuchen
|
||||
$top_attempts = $wpdb->get_results(
|
||||
$wpdb->prepare(
|
||||
"SELECT ip, username, COUNT(*) as attempt_count, MAX(attempt_time) as last_attempt
|
||||
FROM $attempts_table
|
||||
WHERE attempt_time >= %s
|
||||
GROUP BY ip, username
|
||||
ORDER BY attempt_count DESC
|
||||
LIMIT 10",
|
||||
$week_ago
|
||||
)
|
||||
);
|
||||
|
||||
// E-Mail-Inhalt
|
||||
$message = __("Wöchentliche Anmeldeversuche-Zusammenfassung\n\n", 'wp-multi');
|
||||
$message .= sprintf(__("Zeitraum: %s bis %s\n\n", 'wp-multi'), $week_ago, $now);
|
||||
$message .= sprintf(__("Gesamtzahl der Anmeldeversuche: %d\n\n", 'wp-multi'), $total_attempts);
|
||||
$message .= __("Top 10 Anmeldeversuche (nach IP und Benutzername):\n", 'wp-multi');
|
||||
|
||||
if ($top_attempts) {
|
||||
foreach ($top_attempts as $index => $attempt) {
|
||||
$message .= sprintf(
|
||||
__("%d. IP: %s, Benutzername: %s, Versuche: %d, Letzter Versuch: %s\n", 'wp-multi'),
|
||||
$index + 1,
|
||||
$attempt->ip,
|
||||
$attempt->username,
|
||||
$attempt->attempt_count,
|
||||
$attempt->last_attempt
|
||||
);
|
||||
}
|
||||
} else {
|
||||
$message .= __("Keine Anmeldeversuche in diesem Zeitraum.\n", 'wp-multi');
|
||||
}
|
||||
|
||||
// E-Mail an Admin senden
|
||||
$admin_email = get_option('admin_email');
|
||||
wp_mail(
|
||||
$admin_email,
|
||||
__('Wöchentliche Anmeldeversuche-Zusammenfassung', 'wp-multi'),
|
||||
$message,
|
||||
array('Content-Type: text/plain; charset=UTF-8')
|
||||
);
|
||||
|
||||
// Aktualisiere den Zeitstempel der letzten E-Mail
|
||||
update_option('wp_multi_last_summary_email', $current_time);
|
||||
}
|
||||
|
||||
// Planen der wöchentlichen Zusammenfassung (jeden Montag um 8:00 Uhr)
|
||||
function wp_multi_schedule_weekly_summary() {
|
||||
if (!wp_next_scheduled('wp_multi_weekly_summary_event')) {
|
||||
wp_schedule_event(strtotime('next Monday 08:00'), 'weekly', 'wp_multi_weekly_summary_event');
|
||||
}
|
||||
}
|
||||
add_action('wp', 'wp_multi_schedule_weekly_summary');
|
||||
|
||||
// Hook für die Ausführung der Zusammenfassung
|
||||
add_action('wp_multi_weekly_summary_event', 'wp_multi_send_weekly_summary');
|
||||
|
||||
// Einstellungsoption für die Zusammenfassung
|
||||
function wp_multi_users_register_settings() {
|
||||
add_option('wp_multi_summary_enabled', 1);
|
||||
register_setting('wp_multi_users_settings_group', 'wp_multi_summary_enabled', array(
|
||||
'type' => 'integer',
|
||||
'sanitize_callback' => 'absint',
|
||||
'default' => 1,
|
||||
));
|
||||
|
||||
// Settings Section hinzufügen
|
||||
add_settings_section(
|
||||
'wp_multi_security_section',
|
||||
__('Brute-Force-Schutz Einstellungen', 'wp-multi'),
|
||||
'wp_multi_security_section_callback',
|
||||
'wp_multi_users_security_settings'
|
||||
);
|
||||
|
||||
// Settings Field hinzufügen
|
||||
add_settings_field(
|
||||
'wp_multi_summary_enabled',
|
||||
__('Wöchentliche Zusammenfassung', 'wp-multi'),
|
||||
'wp_multi_summary_enabled_callback',
|
||||
'wp_multi_users_security_settings',
|
||||
'wp_multi_security_section'
|
||||
);
|
||||
}
|
||||
add_action('admin_init', 'wp_multi_users_register_settings');
|
||||
|
||||
// Callback für die Settings Section
|
||||
function wp_multi_security_section_callback() {
|
||||
echo '<p>' . __('Konfiguriere die Sicherheitseinstellungen für den Brute-Force-Schutz deiner Website. Aktiviere oder deaktiviere die wöchentliche Zusammenfassung der fehlgeschlagenen Anmeldeversuche.', 'wp-multi') . '</p>';
|
||||
}
|
||||
|
||||
// Callback für das Settings Field
|
||||
function wp_multi_summary_enabled_callback() {
|
||||
$summary_enabled = get_option('wp_multi_summary_enabled', 1);
|
||||
?>
|
||||
<input type="checkbox" name="wp_multi_summary_enabled" id="wp_multi_summary_enabled" value="1" <?php checked(1, $summary_enabled); ?> />
|
||||
<label for="wp_multi_summary_enabled"><?php _e('Wöchentliche E-Mail-Zusammenfassung für fehlgeschlagene Anmeldeversuche aktivieren', 'wp-multi'); ?></label>
|
||||
<p class="description"><?php _e('Wenn aktiviert, erhält der Administrator jeden Montag um 8:00 Uhr eine E-Mail mit einer Zusammenfassung der fehlgeschlagenen Anmeldeversuche der letzten Woche.', 'wp-multi'); ?></p>
|
||||
<?php
|
||||
}
|
||||
|
||||
// Blockierte IPs & Sicherheitseinstellungen werden zentral in wp_multi_register_admin_menus() registriert.
|
||||
|
||||
// Einstellungsseite unter Benutzer
|
||||
function wp_multi_users_security_settings_page() {
|
||||
wpmt_admin_page_open(
|
||||
__('Benutzer-Sicherheit', 'wp-multi'),
|
||||
__('Brute-Force-Schutz und Benachrichtigungen für fehlgeschlagene Logins', 'wp-multi')
|
||||
);
|
||||
|
||||
wpmt_admin_card_open(__('Brute-Force-Schutz', 'wp-multi'));
|
||||
?>
|
||||
<p><?php _e('Verwalte die Einstellungen für den Schutz vor Brute-Force-Angriffen. Passe die Benachrichtigungen für fehlgeschlagene Anmeldeversuche an.', 'wp-multi'); ?></p>
|
||||
<form method="post" action="options.php">
|
||||
<?php
|
||||
settings_fields('wp_multi_users_settings_group');
|
||||
do_settings_sections('wp_multi_users_security_settings');
|
||||
submit_button(__('Einstellungen speichern', 'wp-multi'));
|
||||
?>
|
||||
</form>
|
||||
<?php
|
||||
wpmt_admin_card_close();
|
||||
|
||||
wpmt_admin_page_close();
|
||||
}
|
||||
|
||||
// Anzeige der blockierten IPs im Admin-Bereich
|
||||
function wp_multi_display_blocked_ips() {
|
||||
global $wpdb;
|
||||
$table_name = $wpdb->prefix . 'blocked_ips';
|
||||
|
||||
$five_days_ago = date('Y-m-d H:i:s', strtotime('-5 days'));
|
||||
$per_page = 50;
|
||||
$page = max(1, isset($_GET['paged']) ? intval($_GET['paged']) : 1);
|
||||
$offset = ($page - 1) * $per_page;
|
||||
|
||||
$blocked_ips = $wpdb->get_results(
|
||||
$wpdb->prepare(
|
||||
"SELECT * FROM $table_name WHERE last_attempt >= %s ORDER BY last_attempt DESC LIMIT %d OFFSET %d",
|
||||
$five_days_ago,
|
||||
$per_page,
|
||||
$offset
|
||||
)
|
||||
);
|
||||
|
||||
$total_ips = $wpdb->get_var($wpdb->prepare("SELECT COUNT(*) FROM $table_name WHERE last_attempt >= %s", $five_days_ago));
|
||||
$total_pages = ceil($total_ips / $per_page);
|
||||
|
||||
wpmt_admin_page_open(
|
||||
__('Blockierte IPs', 'wp-multi'),
|
||||
__('Vom Brute-Force-Schutz erfasste IP-Adressen der letzten 5 Tage', 'wp-multi')
|
||||
);
|
||||
|
||||
wpmt_admin_card_open();
|
||||
if (empty($blocked_ips)) {
|
||||
wpmt_admin_notice('info', __('Keine blockierten IPs gefunden.', 'wp-multi'));
|
||||
} else {
|
||||
?>
|
||||
<div class="wpm-table-wrap">
|
||||
<table class="wpm-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?php _e('ID', 'wp-multi'); ?></th>
|
||||
<th><?php _e('IP-Adresse', 'wp-multi'); ?></th>
|
||||
<th><?php _e('Versuche', 'wp-multi'); ?></th>
|
||||
<th><?php _e('Letzter Versuch', 'wp-multi'); ?></th>
|
||||
<th><?php _e('Aktionen', 'wp-multi'); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($blocked_ips as $ip) : ?>
|
||||
<tr>
|
||||
<td><?php echo esc_html($ip->id); ?></td>
|
||||
<td><?php echo esc_html($ip->ip); ?></td>
|
||||
<td><span class="wpm-badge <?php echo $ip->attempts >= 5 ? 'wpm-badge--danger' : 'wpm-badge--warning'; ?>"><?php echo esc_html($ip->attempts); ?></span></td>
|
||||
<td><?php echo esc_html($ip->last_attempt); ?></td>
|
||||
<td>
|
||||
<a class="wpm-btn wpm-btn--danger" href="<?php echo esc_url(wp_nonce_url(admin_url('admin-post.php?action=remove_blocked_ip&id=' . $ip->id), 'wp_multi_remove_blocked_ip_' . $ip->id)); ?>">
|
||||
<?php _e('Entfernen', 'wp-multi'); ?>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<?php if ($total_pages > 1) : ?>
|
||||
<div class="tablenav">
|
||||
<div class="tablenav-pages">
|
||||
<?php
|
||||
echo paginate_links(array(
|
||||
'base' => add_query_arg('paged', '%#%'),
|
||||
'format' => '',
|
||||
'prev_text' => __('«'),
|
||||
'next_text' => __('»'),
|
||||
'total' => $total_pages,
|
||||
'current' => $page,
|
||||
));
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php
|
||||
}
|
||||
wpmt_admin_card_close();
|
||||
|
||||
// Aufräumen: alte Einträge mit wenigen Versuchen entfernen
|
||||
$three_days_ago = date('Y-m-d H:i:s', strtotime('-3 days'));
|
||||
$wpdb->query(
|
||||
$wpdb->prepare(
|
||||
"DELETE FROM $table_name WHERE attempts < 10 AND last_attempt < %s",
|
||||
$three_days_ago
|
||||
)
|
||||
);
|
||||
|
||||
wpmt_admin_page_close();
|
||||
}
|
||||
|
||||
// Funktion zum Entfernen einer blockierten IP
|
||||
function wp_multi_remove_blocked_ip() {
|
||||
if (!current_user_can('manage_options')) {
|
||||
wp_die(__('Du hast nicht die erforderlichen Berechtigungen.', 'wp-multi'), '', array('response' => 403));
|
||||
}
|
||||
|
||||
$id = isset($_GET['id']) ? intval($_GET['id']) : 0;
|
||||
|
||||
if (!$id || !isset($_GET['_wpnonce']) || !wp_verify_nonce(wp_unslash($_GET['_wpnonce']), 'wp_multi_remove_blocked_ip_' . $id)) {
|
||||
wp_die(__('Ungültige oder abgelaufene Anfrage.', 'wp-multi'), '', array('response' => 403));
|
||||
}
|
||||
|
||||
global $wpdb;
|
||||
|
||||
if ($id > 0) {
|
||||
$table_name = $wpdb->prefix . 'blocked_ips';
|
||||
$wpdb->delete($table_name, array('id' => $id), array('%d'));
|
||||
}
|
||||
|
||||
wp_safe_redirect(admin_url('admin.php?page=wp_multi_blocked_ips'));
|
||||
exit;
|
||||
}
|
||||
add_action('admin_post_remove_blocked_ip', 'wp_multi_remove_blocked_ip');
|
||||
|
||||
|
||||
Reference in New Issue
Block a user