Upload via GUI (39 Dateien)

This commit is contained in:
2026-08-14 07:59:43 +00:00
parent 05a2e1c7b6
commit 90f388f49c
31 changed files with 16919 additions and 5554 deletions
+405
View File
@@ -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');