Ich konnte aufgrund dieses Timeout-Fehlers keine Theme-Komponente abrufen oder aktualisieren, schließlich habe ich es herausgefunden. Entfernen der folgenden Zeilen, die mit - beginnen, in der Datei \u003cDiscourse\u003e/lib/theme_store/git_importer.rb:
def clone_http!
uri = redirected_uri
raise_import_error! if %w[http https].exclude?(@uri.scheme)
- addresses = FinalDestination::SSRFDetector.lookup_and_filter_ips(uri.host)
- raise_import_error! if addresses.empty?
env = { "GIT_TERMINAL_PROMPT" => "0" }
args =
clone_args(
uri.to_s,
- "http.followRedirects" => "false",
- "http.curloptResolve" => "#{uri.host}:#{uri.port}:#{addresses.join(",")}",
)
begin
Discourse::Utils.execute_command(env, *args, timeout: COMMAND_TIMEOUT_SECONDS)
rescue RuntimeError
raise_import_error!
end
end
Dieser Code verarbeitet eine DNS-Vorauslösung und zwingt git, die IP-Adressen zu verwenden, die aus der Vorauslösung stammen. Ich weiß nicht, warum es auf meinem Server immer fehlschlug, also habe ich die Logik entfernt.
Tatsächlich habe ich eine Frage zu seiner Existenz: git selbst führt eine DNS-Lösung durch, warum brauchen wir diese Logik? Das ist nicht eindeutig.
SSRF (wie in FinalDestination::SSRFDetector erwähnt) steht für Server-Side Request Forgery. Es bezeichnet einen Mechanismus, durch den ein Angreifer Ihren Server dazu verleitet, auf Ressourcen zuzugreifen, auf die der Angreifer sonst nicht zugreifen könnte.
Stellen Sie sich zum Beispiel vor, Sie betreiben Discourse in einem privaten Netzwerk mit einem Reverse-Proxy, um den Zugriff aus dem Internet zu ermöglichen. Ein Angreifer könnte ein Thema mit einem Link erstellen, der auf eine IP-Adresse in Ihrem privaten Netzwerk zeigt. Das Onebox-System von Discourse könnte dann diese URL abrufen und ihren Inhalt in einer Onebox anzeigen.
Um dies zu verhindern, greift Discourse nicht auf benutzerseitig bereitgestellte URLs zu, ohne vorher zu prüfen, ob diese nicht auf private IP-Adressen zeigen.
Dies ist möglicherweise weniger wichtig für Git-Repositories, die von Themes und Theme-Komponenten verwendet werden, da diese von Administratoren festgelegt werden, aber Discourse geht hier auf Nummer sicher.
Danke für deine Erklärung. Ich habe die endgültige Lösung für meine Situation gefunden.
Meine Situation: Ich verwende WSL (dem 192.168.1.2 im virtuellen LAN zugewiesen), um Discourse auszuführen, und es ist so konfiguriert, dass es über den auf Windows laufenden Proxy (zugewiesen 192.168.1.1) auf Remote-Server zugreift.
Wenn Discourse versucht, über einen Hostnamen eine Verbindung zu einem Remote-Server herzustellen, versucht SSRF, die im System unter /etc/resolv.conf festgelegte DNS-Auflösung zu verwenden. Standardmäßig ist jedoch die vLAN-IP-Adresse von Windows (meine ist 192.168.1.1) der einzige DNS-Server von WSL. Aber das Subnetz 192.168.0.0/16 wurde von SSRFDetector auf die schwarze Liste gesetzt, sodass es nicht einmal eine DNS-Antwort erhalten kann. (Ich habe nur kurz den Code überflogen, daher weiß ich nicht, ob die obige Annahme korrekt ist.)
Durch das Hinzufügen von 192.168.1.1 zum Konfigurationselement Allowed internal hosts funktioniert alles weiterhin. Hmm, vielleicht sollte Discourse Hostnamen in den Umgebungsvariablen HTTP_PROXY und HTTPS_PROXY nicht auf die schwarze Liste setzen?