is it possible for indy10 https to work on port not 443? lazarus / 38-Networking and Web Programming ---------------------------------------------------------------------- Michael Collier · 2019-08-20 08:42 I'm using indylaz 10.6.2.549 , lazarus 2.0.0 , FPC 3.3.1 Using TIdHTTPServer to run a secure web server implementing letsencrypt/cerbot certificates. When I bind to port 443, everything runs fine.. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i   b        := FHTTPServerObject.Bindings.Add();  b.IP     := f_ip_address ;  b.port   := f_port       ; // 443 is the only value that seems to work  But when I try binding different port numbers my browser won't connect. I don't get any errors when running in the debugger..If I remove HTTPS and just use HTTP then my browser will connect so it seems that things are running under under the hood. I'm not sure if I'm doing something wrong in my code or if I need to do something different when creating certificates? Note: I remember doing this before a few months back on a windows7 laptop which I will dig out, recharge and fire up, I think it worked on that, it was a previous version of indy. Also I'm currently doing this on a rapsberryPI3 running raspbian.. Thanks.. ---------------------------------------------------------------------- korba812 · 2019-08-20 09:19 You must have root privileges to start server with port below 1024 https://stackoverflow.com/questions/10182798/why-are-ports- below-1024-privileged ---------------------------------------------------------------------- Michael Collier · 2019-08-20 09:30 Hi korba812 I'm using sudo at the command line when I start Lazarus (to run my app through debugger), and also using sudo when I run the app outside the debugger. (In fact I seemed to need this in order to access the SSL certificate but I don't mind) Port 443 works ok, the port(s) I'm attempting to use are above 8000 so I guess should be ok? ---------------------------------------------------------------------- Thaddy · 2019-08-20 11:12 port 443 is as per RFC 1700  the https reserved port number. But indeed, it is possible to use a high port number and still use https. ---------------------------------------------------------------------- Michael Collier · 2019-08-20 14:50 Hi Thaddy Thanks,yep, I just tried a pre-compiled version of my app on a windows-10 PC and it does allow several high port numbers for https. This version was compiled using an earlier version of indy so I'll update indy and retry. On the RPI3 device, I installed nmap and after opening my app to listen on 8443 executed this: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i nmap -p 8443 192.168.1.90 ..the output was: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i 8443/tcp open  https-alt So nmap seems to be saying that 8443 is being used ok. I put break-point in my source code for requests.. When I try to connect using standard port 443 the debugger stops on my breakpoint, but when I attempt to connect from my browser using port 8443 the debugger does not stop. So it seems there is something going wrong between the browser and the application? There is no firewall installed on the RPI but I did a quick check: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i sudo iptables -L Chain INPUT (policy ACCEPT)target     prot opt source             destination          Chain FORWARD (policy ACCEPT)target     prot opt source               destination          Chain OUTPUT (policy ACCEPT)target     prot opt source               destination and in any event I'm opening the browser on the local RPI so I'm not having to go though routers and still not connecting, so this seems strange to me..?? ---------------------------------------------------------------------- Thaddy · 2019-08-20 17:58 When I use localhost (instead of a qualified IP) the debugger stops. Tested on a RPi3 /trunk/trunk both from today. ---------------------------------------------------------------------- Michael Collier · 2019-08-20 20:03 Good to know it works, thanks I just tried localhost but no luck.. I dug deeper into open ssl.. Executed this on RPI3 Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i openssl s_client -connect localhost:9443 -msg Got this output, note "wrong version number": Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i 1996326384:error:1408F10B:SSL routines:ssl3_get_record:wrong version number:../ssl/record/ssl3_record.c:252:  Also, from firefox browser, got this message: ssl_error_rx_record_too_long ---------------------------------------------------------------------- Thaddy · 2019-08-20 20:24 Why ssl 3? It is insecure and deprecated. Use tls 1.1 at a minimum! The browser is right. All modern browsers won't allow ssl 3/ tls 1.0. Did you select ssl 3 yourself? Or does the fall-back inside the Pascal code did that? ---------------------------------------------------------------------- Michael Collier · 2019-08-20 20:44 I'm not sure why it refers to SSL3, here are the settings I use (I've tried loads of variations) Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i     HTTPIOHandler.SSLOptions.SSLVersions := [sslvTLSv1, sslvTLSv1_1 , sslvTLSv1_2 ];    HTTPIOHandler.SSLOptions.Method := sslvTLSv1_2        ; I'm not sure why openssl  said ss3_get_record? I noticed further down it says:     Protocol  : TLSv1.2 Here is a more complete message: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i 1995470320:error:1408F10B:SSL routines:ssl3_get_record:wrong version number:../ssl/record/ssl3_record.c:252:---no peer certificate available---No client certificate CA names sent---SSL handshake has read 5 bytes and written 176 bytesVerification: OK---New, (NONE), Cipher is (NONE)Secure Renegotiation IS NOT supportedCompression: NONEExpansion: NONENo ALPN negotiatedSSL-Session:    Protocol  : TLSv1.2    Cipher    : 0000    Session-ID:     Session-ID-ctx:     Master-Key:     PSK identity: None    PSK identity hint: None    SRP username: None    Start Time: 1566333269    Timeout   : 7200 (sec)    Verify return code: 0 (ok)    Extended master secret: no ---------------------------------------------------------------------- Remy Lebeau · 2019-08-21 22:04 Quote from: Michael Collier on August 20, 2019, 10:42:57 amBut when I try binding different port numbers my browser won't connect. Are you specifying the alternate port number in the URL you give the browser? Eg: "https://host:port/" Quote from: Michael Collier on August 20, 2019, 10:42:57 amI don't get any errors when running in the debugger..If I remove HTTPS and just use HTTP then my browser will connect so it seems that things are running under under the hood. Indy servers, and particularly TIdHTTPServer, handle non-standard ports just fine.  So if you are having a problem, especially when standard ports work fine, it is likely something outside of Indy. Quote from: Michael Collier on August 20, 2019, 10:42:57 amI'm not sure if I'm doing something wrong in my code What you have shown looks fine to me. Quote from: Michael Collier on August 20, 2019, 10:42:57 amor if I need to do something different when creating certificates? I wouldn't know. Quote from: Michael Collier on August 20, 2019, 10:44:14 pmI'm not sure why it refers to SSL3, here are the settings I use (I've tried loads of variations) Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i     HTTPIOHandler.SSLOptions.SSLVersions := [sslvTLSv1, sslvTLSv1_1 , sslvTLSv1_2 ];    HTTPIOHandler.SSLOptions.Method := sslvTLSv1_2        ; You should NOT be using the SSLVersions and Method properties together like that.  The two properties are mutually exclusive, setting one updates the other, so setting the Method property to sslvTLS1_2 discards sslvTLSv1 and sslvTLSv1_1 from the SSLVersions.  So, in the above case, your server will only talk with TLS1.2 and nothing else. Use ONE OR THE OTHER, not BOTH.  In fact, it is best to just ignore the Method property altogether, pretend it does not exist.  It is an old property that needs to be deprecated and removed.  Just use the SSLVersions property only. Quote from: Michael Collier on August 20, 2019, 10:44:14 pmI'm not sure why openssl  said ss3_get_record? Because TLS 1.x is an extension of SSL 3.0, and internally OpenSSL implements TLS using SSL3 APIs. ---------------------------------------------------------------------- Michael Collier · 2019-08-22 09:12 Hi Remy Thanks for the updates, I am using "https://host:port" , and I removed the .method setting but still no luck. I believe you are right about indy working ok, thaddy got it working pretty quickly, so maybe my raspberry pi3  is missing something. I think I'll revert over to compiling/running on windows so I can get the application tested and demonstrated to my user, then try a clean install on another raspberry. I was thinking about posting a sample project here for users to try, but they would need to be able to produce their own SSL certificate tied to their registered URL e.g. my_lazarus_test.co.uk  hmm.. I just had a look at my own ISP for deals on registering a URL, and it seems they offer free registration of .co.uk for 1 year. I'll email them and confirm before posting a link. Lazarus users could register a URL for free, then use a free Domain Name Server (I use a free one and it works ok) to point their URL to a device on their home network (just forward a port on the home router for it to connect). Finally, get a free SSL certificate via letsencrypt/certbot, again free. I'd be happy to post something on the lazarus wiki if anyone thinks it would help, that way if anyone else has a problem in the future with HTTPS/SSL/DNS/certificates they have a working example to reference? ---------------------------------------------------------------------- Michael Collier · 2019-09-02 16:56 I've download indy10 demos from here: https://indy.fulgan.com/ZIP/Indy10demo.zip But not sure if this is the most recent set of demos available, is this the best link or is there a better one? I had a look at HTTP/SSL Server/ project (it does state "SSL only" and thus expectedly there are no settings for any TLS related items that I can see). Here is snippet Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i function TfrmMain.InternalServerBeforeStart: Boolean;begin  // Preform your startup code here.  If you do not wish the server to start  // then simply return false from this function and report back the proper  // error by calling Log(YourMessage, clRed);  result := true;  try    with OpenSSL.SSLOptions do      begin        CertFile     := edCertFile.Text;        CipherList   := edCipherList.Text;        KeyFile      := edKeyFile.Text;        RootCertFile := edRootCertFile.Text;      end;  except    result := false;  end;end; If there is a more recent link available for TLS I will download and try, otherwise I'll modify what I have and try on debain10 later tonight, then RapsberryPi3. Cheers, Mike ---------------------------------------------------------------------- Remy Lebeau · 2019-09-02 22:03 Quote from: Michael Collier on September 02, 2019, 06:56:08 pmI had a look at HTTP/SSL Server/ project (it does state "SSL only" and thus expectedly there are no settings for any TLS related items that I can see). Because the API used is "Open", not "Open", and OpenSSL predates the existence of TLS, so the properties and classes tend to have "SSL" in their names for historic reasons.  But Indy does support TLS 1.0 - 1.2 (TLS 1.3 will be supported once Indy has been updated to support OpenSSL 1.1.x, which is currently in progress).  You can enable TLS 1.0 - 1.2 in the TIdIOHandlerSocketOpenSSL.SSLOptions.SSLVersions property. ---------------------------------------------------------------------- Michael Collier · 2019-09-03 15:16 OK thanks, Non secure HTTP: I've updated the non secure httpserver indy10  demo project to run on linux (removed references to windows and included cthreads) it should be possible to connect via this link http://a1b2.ddns.net:9010/ (I modified the response so it simply outputs a list of helpful properties.) Secure HTTP: I made similar changes to run indy10 demo on linux ( remove windows add cthreads) I get error "cannot load SSL library" so installed openssl sudo apt-get install libssl-dev So I have OpenSSL 1.1.1c  28 May 2019 Still get same error message? here is the modified code snippet Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i function TfrmMain.InternalServerBeforeStart: Boolean;begin  //m.c. tried both true/false here..  IdSSLOpenSSLHeaders.IdOpenSSLSetLoadSymLinksFirst(False);   // Preform your startup code here.  If you do not wish the server to start  // then simply return false from this function and report back the proper  // error by calling Log(YourMessage, clRed);  result := true;  try    with OpenSSL.SSLOptions do      begin        CertFile     := edCertFile.Text;        CipherList   := edCipherList.Text;        KeyFile      := edKeyFile.Text;        RootCertFile := edRootCertFile.Text;        //m.c.        SSLVersions := [sslvTLSv1, sslvTLSv1_1 , sslvTLSv1_2 ];      end;  except    result := false;  end;end; I'm running under root, so I know I can access the certificates, I'm leaving the CipherList and RootCertFile blank since I didn't use these on my version that works on windows/RaspberryPi - are they needed for TLS to work? Thanks ---------------------------------------------------------------------- Remy Lebeau · 2019-09-03 23:25 Quote from: Michael Collier on September 03, 2019, 05:16:40 pmSecure HTTP: I made similar changes to run indy10 demo on linux ( remove windows add cthreads) I get error "cannot load SSL library" so installed openssl sudo apt-get install libssl-dev So I have OpenSSL 1.1.1c  28 May 2019 Still get same error message? As I stated in my previous reply, Indy does not support OpenSSL 1.1.x yet, so you can't use that version you downloaded from APT.  You need to find and download older OpenSSL 1.0.2 dylibs to use instead for the time being. ---------------------------------------------------------------------- Thaddy · 2019-09-04 06:51 If you need the functionality you can use fcl-net and fcl-web from current trunk (note that new code will compile in 3.0.4 as well). That is not Indy, though...but is up to date since a couple of weeks. ---------------------------------------------------------------------- Michael Collier · 2019-09-04 20:54 Ok my bad, I was confused by the fact that my raspberry pi works with indy10 SSL albeit only on port 443 and is showing "OpenSSL 1.1.0k  28 May 2019" I guess the PI has some older libraries on it.. Thanks for help Mike ---------------------------------------------------------------------- Michael Collier · 2019-09-04 20:55 Quote from: Thaddy on September 04, 2019, 08:51:18 amIf you need the functionality you can use fcl-net and fcl-web from current trunk (note that new code will compile in 3.0.4 as well). That is not Indy, though...but is up to date since a couple of weeks. Thanks I'll give it a go later, I'm updating a WST application that has option to run under indy/synapse so I'm doing them first. Cheers, Mike ---------------------------------------------------------------------- Sartaj · 2024-08-12 18:29 I faced same issue and found correct answer:- use OnQuerySSLPort handler to enable SSL on non standard port otherwise it will work as HTTP server on non standard port. procedure TShttpsServer.HandleSslQuery(APort: TIdPort; var VUseSSL: Boolean); begin    VUseSSL := True;    APort := 8080; end; ---------------------------------------------------------------------- Remy Lebeau · 2024-08-12 19:10 Quote from: Sartaj on August 12, 2024, 08:29:19 pmI faced same issue and found correct answer:- use OnQuerySSLPort handler to enable SSL on non standard port otherwise it will work as HTTP server on non standard port. That is correct.  The OnQuerySSLPort event tells you which port a client has connected to, and then you return whether that port should use SSL/TLS or not.  TIdHTTPServer will use SSL/TLS on the standard HTTPS port 443 by default, but you need to use the OnQuerySSLPort event to activate SSL/TLS on any other non-standard port. Quote from: Sartaj on August 12, 2024, 08:29:19 pmprocedure TShttpsServer.HandleSslQuery(APort: TIdPort; var VUseSSL: Boolean); begin    VUseSSL := True;    APort := 8080; end; You are telling the server to use SSL/TLS for all clients unconditionally, regardless of which port each client has connected to.  If you only have HTTPS ports, that's fine.  But if you need to listen on both HTTP and HTTPS ports then your handler needs to look more like this instead: Code: [Select]procedure TShttpsServer.HandleSslQuery(APort: TIdPort; var VUseSSL: Boolean); begin    VUseSSL := (APort = 8080); // whatever ports your HTTPS bindings are listening on end;