Universeller C#-Proxy-Server mit FTP-Authentifizierung
Dieser C#-Proxy-Server lauscht auf einem lokalen Port, erkennt Verkehrsarten und leitet sie mit smarter Handhabung weiter. Für FTP injiziert er automatisch Zugangsdaten, indem er USER/PASS-Befehle abfängt und Ihre Logindaten einsetzt. Er unterstützt HTTP, HTTPS (über CONNECT) und FTP – nur mit integrierten TcpClient und NetworkStream, ohne externe Bibliotheken.
Architektur und Initialisierung
Der Server nutzt TcpListener, um die Loopback-Schnittstelle auf dem gewählten Port zu überwachen. FTP-Zugangsdaten werden in einem ConcurrentDictionary threadsicher gespeichert.
public class FullProxyServer
{
private readonly TcpListener _listener;
private readonly ConcurrentDictionary<string, string> _ftpCredentials;
public FullProxyServer(int proxyPort, string ftpServer, string ftpUser, string ftpPassword)
{
_listener = new TcpListener(IPAddress.Loopback, proxyPort);
_ftpCredentials = new ConcurrentDictionary<string, string>();
_ftpCredentials.TryAdd(ftpServer, $"{ftpUser}:{ftpPassword}");
}
}
Starten Sie ihn aus Program.Main:
static async Task Main(string[] args)
{
var proxy = new FullProxyServer(8888, "ftp.example.com", "my_username", "my_password");
await proxy.StartAsync();
}
Erkennung des Anfragetyp s
Nach Erhalt der Client-Daten wird der Puffer analysiert:
string request = Encoding.ASCII.GetString(buffer, 0, bytesRead);
if (request.StartsWith("CONNECT"))
{
await HandleConnectRequest(clientStream, request, id);
}
else if (request.Contains("FTP") || request.Contains("ftp"))
{
await HandleFtpRequest(clientStream, buffer, bytesRead, id);
}
else
{
await TunnelConnection(clientStream, buffer, bytesRead, id);
}
Das leitet den Verkehr protokollbasiert weiter.
HTTPS-Handhabung über CONNECT
Für HTTPS wird ein direkter Tunnel eingerichtet:
var parts = connectLine.Split(' ');
string host = targetParts[0];
int port = int.Parse(targetParts[1]);
var targetClient = new TcpClient();
await targetClient.ConnectAsync(host, port);
string response = "HTTP/1.1 200 Connection Established\r\n\r\n";
await clientStream.WriteAsync(responseBytes);
await TunnelBidirectional(clientStream, targetStream, id);
Bidirektionales Stream-Kopieren ist vollständig asynchron mit CancellationTokenSource für saubere Beendigungen.
private async Task TunnelBidirectional(NetworkStream clientStream, NetworkStream targetStream, string id)
{
var cts = new CancellationTokenSource();
var clientToTarget = CopyDataAsync(clientStream, targetStream, id, "C->T", cts.Token);
var targetToClient = CopyDataAsync(targetStream, clientStream, id, "T->C", cts.Token);
await Task.WhenAny(clientToTarget, targetToClient);
cts.Cancel();
}
FTP-Proxy mit Auto-Authentifizierung
Das Highlight: Abfangen und Anpassen von FTP-Befehlen. Bei USER vom Client wird Ihr Benutzername eingesetzt. Auf die Server-Antwort 331 (Passwort gefordert) folgt automatisch PASS.
private async Task FtpTunnelWithAuth(NetworkStream clientStream, NetworkStream ftpStream,
string username, string password, string id)
{
bool authenticated = false;
// FTP-Server-Antworten abfangen
if (!authenticated && response.Contains("331")) // Passwort gefordert
{
string passCmd = $"PASS {password}\r\n";
await ftpStream.WriteAsync(passBytes);
}
// Client-Befehle abfangen
if (!authenticated && command.ToUpper().StartsWith("USER"))
{
// Eigener Benutzername einsetzen
string userCmd = $"USER {username}\r\n";
await ftpStream.WriteAsync(userBytes);
}
}
Nach der Authentifizierung (230-Antwort) werden alle Befehle unverändert getunnelt.
Client-Konfiguration
- Browser: HTTP/HTTPS/FTP-Proxy auf 127.0.0.1:8888 einstellen
- FileZilla & Co.: Generischer Proxy, Host 127.0.0.1, Port 8888
Logs erfassen den Ablauf:
[abc12345] FTP-Anfrage
[abc12345] ->FTP: USER anonymous\r\n
[abc12345] FTP->: 331 Benutzername okay, Passwort benötigt\r\n
[abc12345] Passwort automatisch gesendet
[abc12345] FTP->: 230 Benutzer angemeldet\r\n
[abc12345] Authentifizierung erfolgreich
Wichtige Vorteile
Dieser leichte Server passt in eine Datei und nutzt async/await für Skalierbarkeit. Ideal für:
- Umgehung von Proxy-Einschränkungen in Firmennetzen
- Automatisierte FTP-Zugriffe ohne Client-Anpassungen
- Traffic-Debugging mit detaillierten Logs
- Erweiterung auf andere Protokolle durch Befehls-Parsing
Wichtige Erkenntnisse
- Automatischer Austausch von USER/PASS für FTP – Client merkt nichts.
- Asynchrone bidirektionale Tunneling mit NetworkStream.
- Threadsichere Credentials via ConcurrentDictionary.
- Volle HTTPS-CONNECT- und einfache HTTP-Unterstützung.
- Läuft plattformübergreifend auf .NET 5+.
— Editorial Team
Noch keine Kommentare.