Teilstring ersetzen mit REPLACE

Gelegentlich kommt es vor, dass man nur einzelne Zeichenfolgen in bestimmten Feldern einer mySQL-Datenbank ersetzen möchte.

Ein Anwendungsfall kann zum Beispiel ein seit vielen Jahren betriebener WordPress-Blog sein, welcher bereits betrieben wurde, als SSL-/TLS-Verschlüsselung bei privaten Webseiten noch nicht Usus war.

In diesem Fall können in der Datanbank obsolete href-Attribute mit HTTP (anstatt HTTPS) enthalten sein, die heute zu Sicherheitshinweisen in modernen Browsern führen.

Bei mitunter Tausenden von Einträgen kann folgendes Statement dann sehr hilfreich sein:

UPDATE `table`
SET `column` = REPLACE(`column`, 'http://example.com', 'https://example.com')
WHERE `column` LIKE '%http://example.com%'
;

Tabelle, Spaltenbezeichnungen und Suchstring müssen nur noch auf die eigenen Bedürfnisse angepassst werden.

iOS: VPN On-Demand-Profil für Verbindung zur FRITZ!Box in fremden WLAN-Netzwerken

Die unten dargestellte Profildatei ist zum Import auf einem iOS-Gerät vorgesehen, um in fremden (= nicht auf der Whitelist stehenden) WLAN- bzw. WiFi-Netzwerken immer automatisch eine VPN-Verbindung aufzubauen.

Das Shared Secret muss nach Base64 kodiert werden. Link zu einem Base64-Encoder

Die nachfolgende XML-Datei* basiert auf einer Version von GitHub. Die EvaluateConnection-Funktion wurde auskommentiert, damit immer eine VPN-Verbindung aufgebaut wird, und nicht nur bei bestimmten URLs im heimischen WLAN (z.B. zur FRITZ!Box oder *.local)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>PayloadContent</key>
	<array>
		<dict>
			<key>IPSec</key>
			<dict>
				<key>AuthenticationMethod</key>
				<string>SharedSecret</string>
				<key>LocalIdentifier</key>
				<!-- FRITZ!Box Benutzername -->
				<string>FRITZ!Box Benutzername</string>
				<key>LocalIdentifierType</key>
				<string>KeyID</string>
				<key>RemoteAddress</key>
				<!-- DDNS-URL der FRITZ!Box -->				
				<string>DDNS-URL der FRITZ!Box</string>
				<key>SharedSecret</key>
				<data>
				xxxxxxxxxxxxxxxxxx
				</data>
				<key>XAuthEnabled</key>
				<integer>1</integer>
				<key>XAuthName</key>
				<!-- FRITZ!Box Benutzername -->
				<string>FRITZ!Box Benutzername</string>
				<key>XAuthPassword</key>
				<!-- FRITZ!Box Passwort des Benutzers -->
				<string>xxxxxxxxxxxxxxxxxx</string>
				<!-- VPN-On-Demand Codeblock -->
				<key>OnDemandEnabled</key>
				<integer>1</integer>
				<key>OnDemandRules</key>
				<array>
				<!-- VPN beim Zugriff auf Heimnetz-Adressen aufbauen -->
					<!-- <dict> -->
						<!-- <key>Action</key> -->
						<!-- <string>EvaluateConnection</string> -->
						<!-- <key>ActionParameters</key> -->
						<!-- <array> -->
							<!-- <dict> -->
								<!-- <key>Domains</key> -->
								<!-- <array> -->
									<!-- <string>*.local</string> -->
									<!-- <string>*.fritz.box</string> -->
									<!-- <string>fritz.box</string> -->
								<!-- </array> -->
								<!-- <key>DomainAction</key> -->
								<!-- <string>ConnectIfNeeded</string> -->
							<!-- </dict> -->
						<!-- </array> -->
					<!-- </dict> -->
					<dict>
						<!-- VPN bei ausgewählten WLAN-Netzen deaktivieren -->
						<key>InterfaceTypeMatch</key>
						<string>WiFi</string>
						<key>SSIDMatch</key>
						<array>
							<string>Name of my Home Network</string>
							<string>Company WiFi</string>
						</array>
						<key>Action</key>
						<string>Disconnect</string>
					</dict>
					<dict>
						<!-- VPN bei aktiver WLAN-Verbindung aktivieren -->
						<key>InterfaceTypeMatch</key>
						<string>WiFi</string>
						<key>Action</key>
						<string>Connect</string>
					</dict>
					<dict>
						<!-- VPN im Mobilfunknetz nicht aktivieren -->
						<key>InterfaceTypeMatch</key>
						<string>Cellular</string>
						<key>Action</key>
						<string>Disconnect</string>
					</dict>
					<dict>
						<!-- VPN Default state -->
						<key>Action</key>
						<string>Disconnect</string>
					</dict>
				</array>
				<!-- VPN-On-Demand Codeblock ENDE-->
			</dict>
			<key>IPv4</key>
			<dict>
				<key>OverridePrimary</key>
				<integer>1</integer>
			</dict>
			<key>PayloadDescription</key>
			<string>Configures VPN settings</string>
			<key>PayloadDisplayName</key>
			<string>VPN</string>
			<key>PayloadIdentifier</key>
			<string>com.apple.vpn.managed.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx</string>
			<key>PayloadType</key>
			<string>com.apple.vpn.managed</string>
			<key>PayloadUUID</key>
			<!-- PayloadUUID -->
			<string>xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx</string>
			<key>PayloadVersion</key>
			<real>1</real>
			<key>Proxies</key>
			<dict>
				<key>HTTPEnable</key>
				<integer>0</integer>
				<key>HTTPSEnable</key>
				<integer>0</integer>
			</dict>
			<key>UserDefinedName</key>
			<string>VPN FRITZ!Box</string>
			<key>VPNType</key>
			<string>IPSec</string>
		</dict>
	</array>
	<key>PayloadDisplayName</key>
	<string>VPN on Demand-Profildatei</string>
	<key>PayloadIdentifier</key>
	<!-- PayloadIdentifier -->
	<string>xxxxxxxxxxxxxxxxxx</string>
	<key>PayloadRemovalDisallowed</key>
	<false/>
	<key>PayloadType</key>
	<string>Configuration</string>
	<key>PayloadUUID</key>
	<!-- PayloadUUID -->
	<string>xxxxxxxxxxxxxxxxxx</string>
	<key>PayloadVersion</key>
	<integer>1</integer>
</dict>
</plist>

Die Datei muss mit der Dateiendung .mobileconfig gespeichert werden, z.B. vpn.mobileconfig

Diese Profildatei wurde erfolgreich unter iOS 13.4.1 getestet.

* XML = Extensible Markup Language

WordPress: xmlrpc.php mittels BrowserMatch absichern

.htaccess-Datei im WordPress-Root-Verzeichnis um folgende Zeilen ergänzen:

<IfModule mod_setenvif.c>
  <Files xmlrpc.php>
    BrowserMatch "WordPress" allowed
    BrowserMatch "wp-iphone" allowed
    BrowserMatch "Jetpack by WordPress.com" allowed
    Order Deny,Allow
    Deny from All
    Allow from env=allowed
  </Files>
</IfModule>

Anderslautende User-Agents werden vom Server abgewiesen.

WordPress: Verzeichnis wp-admin mit Jetpack-Whitelist absichern

.htaccess-Datei mit folgendem Inhalt generieren und unter /wp-admin/ speichern:

order deny,allow
deny from all
allow from 122.248.245.244/32
allow from 54.217.201.243/32
allow from 54.232.116.4/32
allow from 192.0.80.0/20
allow from 192.0.96.0/20
allow from 192.0.112.0/20
allow from 195.234.108.0/22
allow from 192.0.96.202/32
allow from 192.0.98.138/32
allow from 192.0.102.71/32
allow from 192.0.102.95/32
### EIGENE IP ###
allow from 127.0.0.1
### EIGENE IP ###

127.0.0.1 ist durch die eigene, externe IP-Adresse zu ersetzen.

Über die oben dargestellten IPv4-Ranges ist sichergestellt, dass Jetpack auf das Verzeichnis zugreifen kann. Dies ist erforderlich, wenn die Website in einem WordPress.com-Konto registriert ist und das Posten neuer Beiträge über die WordPress-App auf einem mobilen Endgerät erfolgen soll.

Die Liste wird regelmäßig aktualisiert und kann hier abgerufen werden.

Domain-Root auf HTTPS umleiten

Folgender Code gilt nur für den direkten Aufruf von domain.tld und nicht für domain.tld/index.php oder Unterordner:

RewriteCond %{HTTPS} off
RewriteCond %{REQUEST_URI} ^/$
Rewriterule ^(.*)$ https://domain.tld/ [L,R=302]

302 = Temporärer Redirect, um Browser-Caching zu vermeiden

MD5-Hashwert aus Passwort erzeugen

Message-Digest Algorithm 5

Datei md5hash.php mit folgendem Inhalt erzeugen:

<?php
$password = 'MyPassword';
$salt = mt_rand( 10000, 99999 );
$encrypted = 'salt:' . $salt . ' md5:' . md5( $salt . $password );
echo $encrypted;
?>

Verzeichnis-Spiegelung/-Synchronisation mit Robocopy inkl. Logfile

Datei SYNC.cmd mit folgendem Inhalt anlegen und anpassen:

echo on
robocopy "C:\Origin" "Y:\Destination" /mir /r:3 /Unilog:"C:\Users\xyz\Desktop\Backup.log" /v /FP
cmd

/mir
= Spiegelung unter Berücksichtigung geänderter und gelöschter Dateien/Ordner

/r:3
= Anzahl der Wiederholungsversuche bei Zugriffsproblemen

/Unilog
= Ausgabe des Logfiles im Unicode-Format für die korrekte Darstellung von bspw. Umlauten

/v /FP
= Ausführliche Ausgabe inkl. Pfade und Dateinamen

Es handelt sich um eine reine Verzeichnis-Spiegelung/-Synchronisation und nicht um ein inkrementelles bzw. differentielles Backup. Für Letzteres sind andere Parameter erforderlich.