DynDNS + MAMP PRO + WordPress (intern + extern)

DynDNS + MAMP PRO + WordPress (intern + extern)

Zwei-Host-Setup Schritt für Schritt
Use case: Intern arbeitest du auf https://codekeks.de, extern soll die gleiche Site über https://codekeks.ddns.net erreichbar sein – mit gültigem Let’s-Encrypt-Zertifikat. Kein Cross-Redirect, gleicher DocumentRoot.


🔧 Voraussetzungen

  • macOS mit MAMP PRO
  • WordPress im Ordner, z. B. /Users/andy/Programmierung/codekeks.test
  • no-ip DynDNS: codekeks.ddns.net
  • Router (z. B. Vodafone Box) leitet Port 80 + 443 → Mac mini (statische LAN-IP!)`

1) DynDNS & Portweiterleitung

  1. DynDNS bei no-ip anlegen: codekeks.ddns.net.
  2. Im Router:

DHCP-Reservierung für Mac mini (z. B. 192.168.0.85).
– Port-Forwarding:
– TCP
80192.168.0.85
– TCP
443192.168.0.85

  1. Test von außen (z. B. aus einem Server / Handy über LTE):
   nc -vz codekeks.ddns.net 80
   nc -vz codekeks.ddns.net 443

2) Zwei Virtual Hosts in MAMP PRO

Beide Hosts zeigen auf denselben DocumentRoot.

Host A (intern):

  • Server Name: codekeks.test
  • SSL: eigenes Dev-Cert
  • Document Root: /Users/andy/Programmierung/codekeks.test

Host B (extern):

  • Server Name: codekeks.ddns.net
  • SSL: Let’s Encrypt (erst gleich einrichten, vorerst Platzhalter)
  • Document Root: /Users/andy/Programmierung/codekeks.test

Wichtig: In MAMP PRO je Host HTTP→HTTPS erzwingen, aber host-agnostisch (kein fest verdrahteter Domainname).

Beispiel (Port 80) – host-agnostischer Redirect

Wenn du die 80er-vHosts manuell pflegst:

<VirtualHost *:80>
    ServerName codekeks.test
    DocumentRoot "/Users/andy/Programmierung/codekeks.test"
    RewriteEngine On
    RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</VirtualHost>

<VirtualHost *:80>
    ServerName codekeks.ddns.net
    DocumentRoot "/Users/andy/Programmierung/codekeks.test"
    RewriteEngine On
    RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</VirtualHost>

3) WordPress sauber für beide Hosts konfigurieren

In wp-config.php (oberhalb der „stop editing“-Zeile) hinzufügen:

// Host- und Schema-basiert, damit .test und .ddns.net parallel funktionieren
if (isset($_SERVER['HTTP_HOST'])) {
    $host   = $_SERVER['HTTP_HOST'];
    $scheme = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
    define('WP_HOME',    $scheme.'://'.$host);
    define('WP_SITEURL', $scheme.'://'.$host);
}

DB-Host korrigieren (falls noch auf .test zeigte):

// Entweder TCP:
define( 'DB_HOST', '127.0.0.1' );
// oder MAMP-MySQL via Socket (Pfad ggf. prüfen):
// define( 'DB_HOST', 'localhost:/Applications/MAMP/tmp/mysql/mysql.sock' );

.htaccess im DocumentRoot: keine feste Domain im Redirect!

RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]


4) Let’s Encrypt Zertifikat mit acme.sh

Wir nehmen TLS-ALPN-01 (nur Port 443 nötig). Das hat bei dir funktioniert.

4.1 acme.sh installieren (robuste Git-Variante)

git clone https://github.com/acmesh-official/acme.sh.git ~/.acme.sh-src
cd ~/.acme.sh-src
./acme.sh --install --home ~/.acme.sh
echo 'alias acme.sh="$HOME/.acme.sh/acme.sh"' >> ~/.zshrc
source ~/.zshrc
acme.sh --version
acme.sh --set-default-ca --server letsencrypt

4.2 Zertifikat ausstellen (ALPN, MAMP kurz stoppen)

sudo /Applications/MAMP/bin/apache2/bin/apachectl -k stop

acme.sh --issue -d codekeks.ddns.net --alpn --standalone

sudo mkdir -p "/Applications/MAMP/Library/OpenSSL/certs"
sudo chown "$USER":staff "/Applications/MAMP/Library/OpenSSL/certs"

acme.sh --install-cert -d codekeks.ddns.net   --key-file       "/Applications/MAMP/Library/OpenSSL/certs/codekeks.ddns.net.key"   --fullchain-file "/Applications/MAMP/Library/OpenSSL/certs/codekeks.ddns.net.crt"   --reloadcmd      "/Applications/MAMP/bin/apache2/bin/apachectl -k graceful"

/Applications/MAMP/bin/apache2/bin/apachectl -k start

5) Verifizieren (extern testen)

curl -I http://codekeks.ddns.net     # 301 → https://codekeks.ddns.net/...
curl -I https://codekeks.ddns.net    # 200 OK
openssl s_client -connect codekeks.ddns.net:443 -servername codekeks.ddns.net </dev/null   | openssl x509 -noout -subject -issuer -dates

6) Intern testen (NAT-Loopback-Problem umgehen)

Falls der Router kein NAT-Loopback kann, intern codekeks.ddns.net auf die LAN-IP mappen (z. B. via Nemo**/lokaler DNS):

codekeks.ddns.net → 192.168.0.85


7) Optional: Security & Performance

<IfModule mod_headers.c>
  Header always set X-Frame-Options "SAMEORIGIN"
  Header always set X-Content-Type-Options "nosniff"
  Header always set Referrer-Policy "strict-origin-when-cross-origin"
  Header always set Permissions-Policy "geolocation=(), microphone=(), camera=()"
</IfModule>

<IfModule mod_deflate.c>
  AddOutputFilterByType DEFLATE text/html text/css application/javascript application/json image/svg+xml
</IfModule>
<IfModule mod_expires.c>
  ExpiresActive On
  ExpiresByType text/css "access plus 7 days"
  ExpiresByType application/javascript "access plus 7 days"
  ExpiresByType image/svg+xml "access plus 30 days"
  ExpiresByType image/png "access plus 30 days"
  ExpiresDefault "access plus 1 hour"
</IfModule>


8) Erneuerung (Renewal)

acme.sh --upgrade --auto-upgrade
acme.sh --renew -d codekeks.ddns.net --force


9) Troubleshooting

  • Redirect auf .test? → .htaccess und wp-config.php prüfen.
  • „MAMP PRO Root CA“ wird angezeigt? → VHost auf fullchain zeigen.
  • Intern geht codekeks.ddns.net nicht? → DNS-Override auf LAN-IP.


10) Quick-Checklist

  • [ ] Router: 80/443 → Mac mini
  • [ ] MAMP: 2 Hosts (codekeks.test, codekeks.ddns.net)
  • [ ] .htaccess: host-agnostisch
  • [ ] wp-config.php: host-basiert, DB_HOST=127.0.0.1
  • [ ] acme.sh: Zert installiert, Apache reload
  • [ ] curl/openssl geprüft
  • [ ] Renewal getestet