Mein TFPHTTPServer friert ein.

Alle Fragen zur Netzwerkkommunikation
Antworten
Soner
Beiträge: 624
Registriert: Do 27. Sep 2012, 00:07
OS, Lazarus, FPC: Win10Pro-64Bit, Immer letzte Lazarus Release mit SVN-Fixes
CPU-Target: x86_64-win64
Wohnort: Hamburg

Mein TFPHTTPServer friert ein.

Beitrag von Soner »

Ich habe einen einfachen öffentlichen HTTP-Server, einige Verbindungen frieren ein, wenn die QueueSize erreicht ist, dann reagiert der Server nicht mehr, er friert komplett ein.
Ich habe festgestellt, dass bei den Verbindungen die hängen bzw. einfrieren das Ereignis OnHandleRequest nicht aufgerufen wird. Deshalb glaube ich, dass der Fehler beim Parsen von Http-Request sein könnte. Es gibt immer Hackversuche, viele versuchen Standard Wordpress, PHPMyAdmin und andere Hacks und Lücken.
Wenn ich PortExport die hängende Verbindungen bei Abuseipdb nachschaue, dann steht dahinter immer Hacker.
Ich habe ein Bugreport erstellt, aber Michael konnte auch die Ursache nicht finden.
Ich jetzt den Server extrem vereinfacht, aber es reagiert immer noch nach einiger Zeit nicht mehr.
Weiß jemand was ich falsch mache oder was ich besser machen könnte?

Das ist mein derzeitiger Server:

Code: Alles auswählen

{ fpHttpServer demo
  Based up on: fpc\3.2.0\source\packages\fcl-web\examples\httpserver\simplehttpserver.lpi
  Start lazarus\tools\debugserver\debugserver for logs
}
program httptestserver1;

{$mode objfpc}{$H+}
{$IfNDef WINDOWS}
{$define UseCThreads}
{$EndIf WINDOWS}

uses
  {$IFDEF UNIX}{$IFDEF UseCThreads}
  cthreads,
  {$ENDIF}{$ENDIF}
  sysutils, Classes, fphttpserver, fpmimetypes
  //, dbugintf  //for log
  ;

type

  { TTestHTTPServer }

  TTestHTTPServer = Class(TFPHTTPServer)
  public
    constructor Create(AOwner : TComponent); override;
    procedure HandleRequest(var ARequest: TFPHTTPConnectionRequest; var AResponse : TFPHTTPConnectionResponse); override;
  end;

  { TTestHTTPServer }
constructor TTestHTTPServer.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  Threaded:=true;
  ServerBanner:='HELLO';
  QueueSize:=6;
  Port:=80;
end;

procedure TTestHTTPServer.HandleRequest(var ARequest: TFPHTTPConnectionRequest; var AResponse: TFPHTTPConnectionResponse);
begin
  AResponse.Code:=200;
  AResponse.ProtocolVersion:='HTTP/1.1';
  AResponse.ContentType:='text/html';
  AResponse.Content:='Hello!';
  AResponse.ContentLength:=Length(AResponse.Content);
  AResponse.SendContent;
  AResponse.ContentStream:=Nil;
end;

var Serv: TTestHTTPServer;
begin
  Serv:=TTestHTTPServer.Create(Nil);
 try
  //if Serv.DebLog then SendDebugEx('Serv.MimeTypesFile: '+Serv.MimeTypesFile,dlInformation); // Writeln('Serv.MimeTypesFile: '+Serv.MimeTypesFile);
  Serv.Active:=True;
 finally
  Serv.Free;
 end;
end.

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2641
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Mein TFPHTTPServer friert ein.

Beitrag von m.fuchs »

Uff, ich persönlich würde den TFPHttpServer nicht als öffentlichen Webserver benutzen. Das ist doch mehr für die Entwicklungszeit einer Webanwendung gedacht oder wenn man seinem Programm noch eine kleine HTTP-Schnittstelle zur Ansteuerung spendieren will.

Ich würde dann doch lieber eine FCGI-Anwendung daraus machen und die dann von Lighttpd ausliefern lassen. Oder - wenn genug Ressourcen vorhanden sind - ein Apache-Modul schreiben und dort einbinden.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

Warf
Beiträge: 1913
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: Mein TFPHTTPServer friert ein.

Beitrag von Warf »

Ich persönlich Dockere meine HTTPServer immer und steck die hinter einen NGINX reverse Proxy. Hat noch ein paar mehr vorteile, wie das NGINX nach außen hin HTTP/2 spricht wobei FP-Web nur HTTP/1.1 kann, oder das man verschiedene Server in verschiedenen Sub Pfaden ansprechen kann (oder einfach dateien Durchreichen kann). Außerdem muss man sich dann nicht um SSL im FPC Code Kümmern.

Kannst ja mal versuchen ob der Setup so klappt, meine Config Template für NGINX sieht so aus:

Code: Alles auswählen

server {
  server_name ?{HOSTNAME};
  root /srv/?{USERNAME}/www;

#IF SSL_ENABLED
  ssl on;
  listen 443 ssl http2;
  listen [::]:443 ssl http2;

  ssl_certificate /etc/letsencrypt/live/?{HOSTNAME}/fullchain.pem; # managed by Certbot
  ssl_certificate_key /etc/letsencrypt/live/?{HOSTNAME}/privkey.pem; # managed by Certbot
#ENDIF

  client_max_body_size 5G;

  access_log /var/log/nginx/?{USERNAME}_access_log;
  error_log /var/log/nginx/?{USERNAME}_error_log;

  location ~ /.well-known/acme-challenge/ {
    allow all;
  }

  location / {
    proxy_set_header Host $http_host;
    proxy_pass http://localhost:?{DOCKERPORT};
  }
}

#IF USE_WWW
server {
  ssl on;
  server_name www.?{HOSTNAME};
  listen 443 ssl http2;
  listen [::]:443 ssl http2;
  allow all;
  ssl_certificate /etc/letsencrypt/live/?{HOSTNAME}/fullchain.pem; # managed by Certbot
  ssl_certificate_key /etc/letsencrypt/live/?{HOSTNAME}/privkey.pem; # managed by Certbot
  return 301 http://?{HOSTNAME}?request_uri;
}
#ENDIF
Musst dafür nicht mal dockern, einfach deinen webserver auf einen anderen port stellen (z.B. 10080 statt 80), und dann in der NGINX config bei proxy_pass setzen.

Wenn dus vorerst mal ohne SSL und den ganzen hick hack ausprobieren willst ist eine minimale config:

Code: Alles auswählen

server {
  server_name DOMAIN;

  location / {
    proxy_set_header Host $http_host;
    proxy_pass http://localhost:10080;
  }
}
Das server_name ist die domain unter der er erreichbar ist, z.B. beim Lazarusforum ist das "lazarusforum.de", das location "/" sagt an das jeder request einfach an den HTTP server der auf Localhost unter dem port 10080 läuft weitergereicht werden soll.

Soner
Beiträge: 624
Registriert: Do 27. Sep 2012, 00:07
OS, Lazarus, FPC: Win10Pro-64Bit, Immer letzte Lazarus Release mit SVN-Fixes
CPU-Target: x86_64-win64
Wohnort: Hamburg

Re: Mein TFPHTTPServer friert ein.

Beitrag von Soner »

@m.fuchs
Mit öffentlich meine ich, dass es von Internet erreichbar ist. Die Adresse des Servers ist nicht öffentlich. Es ist Subdomain. Es wird von Hackern wahrscheinlich durch IP-Scan gefunden oder wenn Subdomains zentral registriert werden, dann von dieser Stelle bekannt.
Es ist Teil der Firmensoftware, die ich geschrieben habe und soll den Kunden Rechnungen liefern und Bestellungen ermöglichen soll. Benutzer sind ca 500-1000 Benutzer. Ich dachte für 1000 Benutzer ist TFPHTTPServer okay.

Ich hatte auch Sicherheitssysteme eingebaut, wenn jemand unbekannte Adressen oder Requests verwendet, dann wird er für eine Stunde gesperrt. Wenn nach einer Stunde wieder falsches abgefragt wird, dann wird er für 3 Stunden gesperrt usw. Mit gesperrt meine ich, dass es leere Seite geliefert wird.

Aber wie ich beim ersten Beitrag schon geschrieben habe, kommt es bei einigen Verbindungen überhaupt nicht zum OnHandleRequest so das ich nicht reagieren kann.

Ich überlegte auch es als FastCGI für NGINX zu erstellen oder als Apache-Modul. Aber wird der auch nicht dort einfrieren, weil der Nginx oder Apache wird doch die gleiche Anfrage einfach so an den TFPHTTPServer weiterleiten. Ich probiere es mal morgen.

Überigens das gleiche Passiert auch Indy-Httpserver, nur er hat eine Woche gehalten.

Soner
Beiträge: 624
Registriert: Do 27. Sep 2012, 00:07
OS, Lazarus, FPC: Win10Pro-64Bit, Immer letzte Lazarus Release mit SVN-Fixes
CPU-Target: x86_64-win64
Wohnort: Hamburg

Re: Mein TFPHTTPServer friert ein.

Beitrag von Soner »

@warf
Ich habe vor zwei, drei Jahren NGINX ausprobiert, ich kenne mit damit bisschen aus. Mein FastCGI-Programm hat Pascal-Skripte ausgeführt und als Ergebnis HTML-Seiten geliefert.
Ich habe jetzt meinen Server bisschen geändert, wenn es bis morgen nicht durchhält versuche ich dann NGINX.

Warf
Beiträge: 1913
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: Mein TFPHTTPServer friert ein.

Beitrag von Warf »

Das Problem wenn du einen TFPHTTPServer öffentlich zugänglich machst ist das das Teil recht wenig entwicklung erfährt und vermutlich nie richtig ge-pentestet wurde. Dementsprechend solltest du das nie ans Internet hängen, außer du möchtest testen wie lange es dauert bis jemand volle Root Rechte auf deinem Server hat.

Du solltest immer einen gut getesteten Webserver wie Apache oder NGINX vorschalten. Wenn dein Problem tatsächlich misgeformte HTTP anfragen sein sollten, dann sollte an dieser stelle ein vernünftiger Webserver die bereits schon rausfiltern und sich drum kümmern.

Wie gesagt, ich würde dir einfach mal empfehlen den Port zu ändern, und einen Reverse Proxy (wie mit dem NGINX beispiel oben) vor zu schalten, und zu schaun ob du das problem dann immernoch hast.

Ich hab auf meinem Server ein FPC Server als Docker hinter einem NGINX laufen, und auch wenn ich den alleine benutze, hab ich trozdem auf meinem Server auch tausende versuchte "Angriffe" pro minute (hauptsächlich irgendwelche chinesischen IPs die versuchen sich mit Standardpasswörtern anzumelden), bei mir hat sich das Teil noch nicht aufgehängt. Ich benutze auch einen TFPHTTPServer und keine FastCGI oder CGI Anwendung, und das funktioniert Problemlos

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2641
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Mein TFPHTTPServer friert ein.

Beitrag von m.fuchs »

Soner hat geschrieben:
Mi 5. Jul 2023, 23:19
@m.fuchs
Mit öffentlich meine ich, dass es von Internet erreichbar ist. Die Adresse des Servers ist nicht öffentlich.
Das hab ich schon verstanden. Ich will bloss sagen, dass dieser Anwendungsfalleben nicht von TFPHTTPServer abgedeckt wird.
Soner hat geschrieben:
Mi 5. Jul 2023, 23:19
Es ist Teil der Firmensoftware, die ich geschrieben habe und soll den Kunden Rechnungen liefern und Bestellungen ermöglichen soll. Benutzer sind ca 500-1000 Benutzer. Ich dachte für 1000 Benutzer ist TFPHTTPServer okay.
Also bei der Anforderung wäre ich mit Sicherheit bei einem Apache oder Lighttpd. Eventuell sogar geclustert - wenn die Verfügbarkeit wichtig ist.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

Soner
Beiträge: 624
Registriert: Do 27. Sep 2012, 00:07
OS, Lazarus, FPC: Win10Pro-64Bit, Immer letzte Lazarus Release mit SVN-Fixes
CPU-Target: x86_64-win64
Wohnort: Hamburg

Re: Mein TFPHTTPServer friert ein.

Beitrag von Soner »

Mein Server läuft seit gestern Nacht immer noch. :D
Aber ich werde es am Ende hinter Nginx setzen. Ich habe Vermutung dass fpHttpServer auf Windows, wahrscheinlich wegen WinSocks, Probleme hat. Bei Bugreport war noch jemand der es auf Windows verwendet, die meisten Leute die den Server erfolgreich einsetzen verwenden auf Linux.
m.fuchs hat geschrieben:
Do 6. Jul 2023, 09:38
Also bei der Anforderung wäre ich mit Sicherheit bei einem Apache oder Lighttpd. Eventuell sogar geclustert - wenn die Verfügbarkeit wichtig ist.
Was meinst mit geclustert? Rechnerverbund? Wenn es das ist, dann ist das viel zu viel Aufwand.

Ich überlege fpHttpServer als Reverse Proxies für Nginx zu verwenden, einen für die Hauptseite, einen für die Kunden und einen für die Mitarbeiter, damit müsste für die tägliche 200-1000 Benutzer der Last gut verteilt sein.

Soner
Beiträge: 624
Registriert: Do 27. Sep 2012, 00:07
OS, Lazarus, FPC: Win10Pro-64Bit, Immer letzte Lazarus Release mit SVN-Fixes
CPU-Target: x86_64-win64
Wohnort: Hamburg

Re: Mein TFPHTTPServer friert ein.

Beitrag von Soner »

Als ich heute morgen aufwachte reagierte der Server nicht mehr. Eigentlich besuchen kaum Leute den Server als ich Protokollierte waren es 5-30 Leute am Tag.

Soner
Beiträge: 624
Registriert: Do 27. Sep 2012, 00:07
OS, Lazarus, FPC: Win10Pro-64Bit, Immer letzte Lazarus Release mit SVN-Fixes
CPU-Target: x86_64-win64
Wohnort: Hamburg

Re: Mein TFPHTTPServer friert ein.

Beitrag von Soner »

Ich benutze den Server seit Freitag als reverse proxy hinter Nginx und der fpHttpServer läuft immer noch. Jetzt kann ich weiter in Pascal programmieren anstatt in PHP. Ich werde wahrscheinlich zu Apache wechseln.
Danke Warf und M.Fuchs.

Antworten