Start Mini FTP Server
Zuletzt geändert: 14.03.2026 05:56

Start-MiniFtpServer #

ÜBERSICHT #

Minimaler FTP-Server in PowerShell 5.1. Multi-Session (RunspacePool), PASV/EPSV (nur Passive Mode), optionale Auth (USER/PASS), UTF-8 auf der Kontrollverbindung, Datei-Infos (SIZE/MDTM), Umbenennen (RNFR/RNTO), STAT-Listing über Control, Datei-Checksummen (HASH; XMD5/XSHA1/XSHA256; OPTS HASH …), Auto-Stop (Default 60 Minuten), IP-Allowlist (Einzel-IPs oder CIDR).

SYNTAX #

Start-MiniFtpServer [[-Root] <string>] [[-Port] <int>] [[-User] <string>] [[-Password] <string>]
    [[-ListenAddress] <string>] [[-PassivePorts] <int[]>] [[-MaxSessions] <int>]
    [[-AutoStopMinutes] <int>] [[-AllowedClientIPs] <string[]>] [<CommonParameters>]

BESCHREIBUNG #

Zweck #

  • Ad-hoc-Support-FTP ohne Installation eines Windows-Dienstes.
  • Der Server arbeitet ausschließlich im Passivmodus (PASV/EPSV). Active Mode (PORT) ist nicht implementiert.

Warum Passivmodus #

  • Im Passivmodus baut der Client alle TCP-Verbindungen selbst auf (Control und Data).
  • Vorteil: Funktioniert typischerweise hinter NAT/Firewalls, da nur ausgehende Verbindungen vom Client nötig sind.
  • Der Server öffnet neben dem Kommunikationsport 21 bzw. 2121 speziell für Datentransfers Ports aus einer definierten Passiv-Range (z.B. 50000 ..).
  • EPSV (= Erweiterter Passiver Modus) wird bevorzugt, funktioniert auch mit IPv6 und vermeidet IP-Transport in der Antwort.

Ports, Firewall, NAT #

  • Control-Port: standardmäßig -Port 2121 (alternativ 21; Ports <1024 erfordern Administratorrechte).
  • Data-Ports (Passiv-Range): per -PassivePorts definierbar. Wenn leer, setzt der Server einen sinnvollen Default: ungefähr MaxSessions*4, mindestens 8 Ports, beginnend ab 50000 (Beispiel: 50000-50011 bei MaxSessions=3).
  • Server-Firewall: Control-Port INBOUND ermöglichen; Passiv-Range INBOUND ermöglichen.
  • Router/NAT (Server hinter NAT): Control-Port und Passiv-Range an die interne Server-IP weiterleiten. Ohne Portweiterleitung ist ein externer Zugriff aus dem Internet nicht möglich.
  • Public Static IP ist nicht zwingend. Es geht auch mit dynamischer IP plus DynDNS, solange Portweiterleitungen korrekt sind. Achtung bei CGNAT: Portweiterleitungen sind dann oft nicht möglich.

Client-Anforderungen #

  • Client-Firewall: Ausgehende TCP-Verbindungen zum Control-Port und zur Passiv-Range des Servers erlauben.
  • Passive Mode im Client aktivieren (Standard bei modernen Clients).
  • Wenn der Server 2121 nutzt (default) muss dies beim Client in der Verbindung angegeben werden, FileZilla hat da ein eigenes Port-Feld.

Sicherheit #

  • Optionale Authentifizierung mit -User und -Password.
  • Optionale IP-Allowlist via -AllowedClientIPs (Einzel-IPs und/oder CIDR). Nicht erlaubte Verbindungen werden mit “530 Not allowed” abgewiesen, bevor eine Session startet.
  • Auto-Stop reduziert das geöffnete Zeitfenster. Default 60 Minuten; -AutoStopMinutes 0 deaktiviert.
  • Root-Sandbox: Alle Dateioperationen bleiben strikt unterhalb -Root.

Interner Ablauf (Kurzübersicht) #

  • Listener (TCP) auf -ListenAddress/-Port starten.
  • Passiv-Range setzen (Default oder Custom) und loggen.
  • Ctrl+C-Handler registrieren (graceful shutdown).
  • RunspacePool für parallele Sessions erstellen.

Hauptloop

  • Deadline (Auto-Stop) prüfen.
  • Abgeschlossene Sessions aufräumen.
  • Pending akzeptieren, Remote-IP ermitteln.
  • IP-Allowlist prüfen; ggf. mit “530 Not allowed” ablehnen.
  • Session-Code im Pool starten (pro Control-Verbindung).

Session-Code

  • Kommandos: USER, PASS, SYST, FEAT, OPTS (UTF8 ON|OFF, HASH [ALGO]), PWD, CWD, LIST, NLST, TYPE, PASV, EPSV, RETR, STOR, DELE, MKD, RMD, SIZE, MDTM, RNFR, RNTO, STAT, HASH, XMD5, XSHA1, XSHA256, NOOP, QUIT.
  • Bei PASV/EPSV wird pro Datentransfer ein TCP-Listener auf einem Port aus der Passiv-Range (oder Ephemeral) geöffnet.
  • Pfadnormalisierung stellt sicher, daß nichts außerhalb des -Root erreichbar ist.
  • Shutdown
  • Listener stoppen, Sessions beenden, Pool dispose, Ctrl+C-Handler deregistrieren.

PARAMETER #

-Root #

Type: string
Default: $PWD.Path

Optionales Wurzelverzeichnis (Sandbox). Alle Dateioperationen sind auf dieses Verzeichnis und seine Childs beschränkt. Falls nicht angegeben, wird das aktuelle Arbeitsverzeichnis verwendet.

-Port #

Type: int
Default: 2121

Control-Port (TCP) für den FTP-Server. Default 2121. Hinweis: Ports <1024 erfordern auf Windows Administratorrechte.

-User #

Type: string

Optionaler Benutzername. Wird nur geprüft, wenn auch -Password gesetzt ist.

-Password #

Type: string

Optionales Passwort. Wird nur geprüft, wenn auch -User gesetzt ist.

-ListenAddress #

Type: string
Default: '0.0.0.0'

IP-Adresse, auf der der Control-Listener bindet. Default 0.0.0.0 (alle IPv4-Interfaces).

-PassivePorts #

Type: int[]
Default: $null

Liste bzw. Range von TCP-Ports für passive Datenverbindungen (z. B. 50000..50011). Wenn nicht angegeben, setzt der Server einen Default: Start 50000, Anzahl ca. MaxSessions*4 (mindestens 8 Ports).

-MaxSessions #

Type: int
Default: 3

Maximale parallele Control-Sessions (RunspacePool MaxSize). Default 3.

-AutoStopMinutes #

Type: int
Default: 60

Minuten bis zur automatischen Selbstabschaltung. 0 deaktiviert. Default 60.

-AllowedClientIPs #

Type: string[]
Default: $null

Optional. Liste von erlaubten Client-IPs oder CIDR-Netzen (IPv4/IPv6). Beispiele:

  • Einzel-IP: 84.137.55.101
  • CIDR: 203.0.113.0/24 Verbindungen aus nicht erlaubten Netzen werden mit “530 Not allowed” direkt abgewiesen.

AUSGABEN #

none

Keine Rückgabe. Die Funktion läuft bis Auto-Stop, Strg+C oder Aufruf von Stop-MiniFtpServer.

BEISPIELE #

# Minimalstart mit Defaults (Control 2121, Passiv-Range Default 50000-50011 bei MaxSessions=3)
Start-MiniFtpServer -Root C:\Temp
# Eigene Passiv-Range und 5 parallele Sessions
Start-MiniFtpServer -Root C:\Temp -Port 2121 -MaxSessions 5 -PassivePorts (50000..50031)
# Benutzer/Passwort aktivieren
Start-MiniFtpServer -Root C:\Temp -User support -Password secret
# Zwei konkrete Public-IPs erlauben (und sonst niemanden)
Start-MiniFtpServer -Root C:\Temp -AllowedClientIPs @('84.137.55.101','198.51.100.23')
# Ein Netz plus eine Einzel-IP erlauben
Start-MiniFtpServer -Root C:\Temp -AllowedClientIPs @('203.0.113.0/24','84.137.55.101')
# Hinter NAT/Router (Server im LAN):
# 1) Am Router Port-Forwarding einrichten: Control-Port (z. B. 2121) und Passiv-Range (z. B. 50000-50011) auf die interne Server-IP.
# 2) In der Windows-Firewall die gleichen Ports INBOUND erlauben.
# 3) DynDNS oder Public IP an den Client kommunizieren.
Start-MiniFtpServer -Root C:\Temp -PassivePorts (50000..50011)
# Automatische Abschaltung nach 30 Minuten
Start-MiniFtpServer -Root C:\Temp -AutoStopMinutes 30

HINWEISE #

Windows-Firewall-Beispiele (Server): #

New-NetFirewallRule -DisplayName 'MiniFTP Control' -Direction Inbound -Protocol TCP -LocalPort 2121 -Action Allow
New-NetFirewallRule -DisplayName 'MiniFTP Passive' -Direction Inbound -Protocol TCP -LocalPort 50000-50011 -Action Allow

Port 21 verwenden #

# Beachten: Administratorrechte nötig, Port 21 ist Angriffsziel. Passive-ALG in Routern ggf. deaktivieren.
Start-MiniFtpServer -Root C:\Temp -Port 21

Einschränkungen #

  • Active Mode (PORT) nicht implementiert.
  • TLS/FTPS nicht implementiert.
  • Kein rekursives LIST (nur das aktuelle Ziel).

Weiteres #

Prüfsumme einer Datei (Default SHA-256), Algorithmus wechseln mit:

  • opts HASH sha512

Client-Kommando (z. B. FileZilla/WinSCP):

  • quote HASH /datei.bin

Test mit FTP.exe aus einer PowerShell-Sitzung, lediglich Kommandos, keinen Datenkanal, da FTP.exe kein PASSIV-Modus kann #

FTP.exe                 # Programm starten
open 127.0.0.1 2121     # Localhost mit Port 2121
user any                # Fake Benutzer
(password any)          # Passworteingabe
binary                  # Aktiviere Binär-Dateimodus
quote FEAT              # Abruf der Sonderfeatures
quote OPTS UTF8 ON      # Aktiviere UTF8 Zeichensatz
quote STAT /            # Dir /
quote STAT /test        # Dir /test
quote SIZE /output.pdf  # Dateigröße abrufen  -> 167361
quote MDTM /output.pdf  # Dateidatum abrufen  -> 20250802075858
quote HASH /output.pdf  # Hashwert abrufen    -> d34a1dd3a83ba7683ebde204bee7a43ed612c89a61e776317ae25aeaafe72000
quote OPTS HASH md5     # Aktiviere MD5 Prüfsumme
quote HASH /output.pdf  # Hashwert abrufen    -> 76f197068be84e775d3c4f368f22c83e
quote MKD /neuordner    # Ordner anlegen
quote RMD /neuordner    # Ordner löschen

Test mit CURL.exe, dieser kann auch Downloads im Passiv-Modus #

curl.exe -v ftp://127.0.0.1:2121/ --user any:any                          # Login mit jedem user und jedem Passwort
curl.exe -u any:any ftp://127.0.0.1:2121/output.pdf -o "$pwd\output.pdf"  # Download der Datei output.pdf