From Overbyte
Revision as of 19:07, 14 November 2018 by Magsys (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

When originally designed TWSocketServer only supported listening on a single IP address and port, subsequently MultiListenSockets were added to listen on multiple IP addresses and ports, and TSslWSocketServer SSL support required a lot of extra code in the application to specify SSL certificates, protocols, ciphers and security using multiple SslContexts for multiple hosts.

The IcsHosts property is an alternate way for specifying multiple listeners for TSslWSocketServer that allows multiple hosts to be specified, each with one or two IP addresses and non-SSL and SSL port bindings, SSL certificates and private key (perhaps combined in a bundle), SSL context and security level, and other web server host related properties (used by higher level components). Each IcsHost has one or more HostNames to which it will recognise, that can share IP addresses.

If IcsHosts is specified, TSslWSocketServer ignores existing bindings and SSL context, and creates new bindings and initializes an SSL context for each host checking and reporting all server certificate chains. To ease implementation, functions are provided to read IcsHosts and TWSocketServer from an INI file, or they may be specified through IDE form properties and saved by other means.

Note IcsHosts is only available for TSslWSocketServer, not TWSocketServer, but you don't need to use SSL for any Hosts.


One or more domain Host Names to which the server will respond, comma separated list, no quotes. Host Names are matched initially against SSL Server Name Indication (SNI), or against the HTTP Host: header if no SSL or SNI for web and proxy servers. Note INI file reads as Hosts. Wild card host names are not allowed, but SNI may match a wild card certificate to an IcsHost.


True or False if this IcsHost is enabled, NOTE INI file also reads Enabled if HostEnabled missing for backward compatibility.


Listening IP Address for this IcsHost, may be for all IP Addresses, must exist. Multiple IcsHosts can use the same IP Address which will then be chosen from HostNames using SNI or Host: header.


Optional second IP Address for this IcsHost, perhaps an IPv6 address.


Optional non-SSL/TLS Port, may be blank or zero if only SSL is supported by IcsHost, usually 80 for HTTP, required if WellKnownPath specified for SSL automatic certificates.


Optional SSL/TLS Port, may be blank or zero if SSL not supported by IcsHost, if used generally 443 for HTTPS, and several other SSL parameters are required. Either BindNonPort or BindSslPort is required.


A short alphabetic name for the IcsHost, used variously in high level servers. The web application server uses HostTag in the AddGetHandler, AddPostHandler and AddGetAllowedPath to cause that handler to be matched. The proxy server uses HostTag to match source to one or more targets. When SocketServer creates a TWSocketClient for a new connection it sets the IcsHostIdx and HostTag properties to this value, also ServerAddr and ServerPort for the bindings.


Optional free description of the IcsHost, may be used for logging.


Optional high level protocol used by this IcsHost, used variously in servers. The proxy server uses HTTP, SMTP, POP3, etc.


Optional True/False used by the proxy server if this IcsHost is functioning as a Forward Proxy rather than a Reverse Proxy. A forward supports multiple targets according to the URL, while a reverse proxy generally ignores the URL and has a single fixed target, sometimes multiple fixed targets depending on the URL. See OverbyteIcsProxy.pas for more information.


Optional default web document directory for this IcsHost, used by the web server.


Optional default web template directory for this IcsHost, used by the web server.


Optional default web document for this IcsHost, used by the web server.


Optional web logging directory for this IcsHost, for use by web server applications (not by the server itself which has not ogging).


Optional SSL server certificate file name, may be PEM, DER, PFX, P12, P7 format, optionally a bundle including a private key and one or more intermediate certificates. Required if BindSslPort set. If a private key is included, will use SslPassword for an encrypted file. Rather than a file name, may be an ASCII PEM string containing the certificate without any line endings. HostNames will be checked against those listed on the certificate, and a not warning given for mismatches so a single certificate needs to contain all the HostName, or wild cards * so they match. TSslWSocketServer has a method RecheckSslCerts that should be called from the server application periodically, at least once a day, which will check the certificate file time stamp and reload it if changed, issue warnings if it expires within CertExpireDays (default 30) and optionally order a new certificate, see CertSupplierProto below. Note if automatic certificate ordering is used, the file name in SslCert must conform to the format used by the TSslX509Certs component, with the host name having all dots replaced by underscore and * by x, then with suffix .pfx or -bundle.pem, ie test3_telecom-tariffs_co_uk-bundle.pem or test3_telecom-tariffs_co_uk.pfx.


Optional SSL private key file name, PEM format, will use SslPassword for an encrypted file. Ignored if SslCert was a bundle file with a private key. Note all SSL servers need an SSL certificate and matching private key to function, and these are checked before the server will start. Rather than a file name, may be an ASCII PEM string containing the private key without any line endings.


Optional SSL intermediate certificate bundle file name, PEM, DER, P12 or P7 format. Ignored if SslCert was a bundle with intermediate certificates. The SSL certificate chains is checked to ensure the server certificate is signed by an intermediate or trusted root certificate, and likewise the intermediate(s). The TSslWSocketServer RootCA property specifies a PEM bundle file containing the trusted root certificates, if not specified an internal bundle of about 36 major root certificates is used.


Optional password for the SSL private key, if encrypted. Note this is clear text in the INI file, steps should be taken to read an encrypted password if security is required. Beware most PFX/P12 bundles need a password, since Windows will not import them without a password.


Optional SSL server security level, that sets protocol, cipher and SslSecLevel according to eight levels from type TSslSrvSecurity: sslSrvSecNone, sslSrvSecSsl3, sslSrvSecBack, sslSrvSecInter, sslSrvSecInterFS, sslSrvSecHigh, sslSrvSecHigh128, sslSrvSecHigh192. Details of each are in the OverbyteIcsSSLEAY.pas unit. Beware the server may not start, ie High128 requires an RSA private key length greater than the 2,048 bits commonly used. If not specified, sslSrvSecDefault is used which is currently sslSrvSecInterFS meaning TLSv1.1 or later with forward security ciphers.


Optional, full file directory path for .Well-Known web URLs, used by the web and proxy servers for automated SSL certificates.


Optional, a web server redirection URL, used in the proxy server to redirect HTTP connections to HTTPS, if WebRedirectStat is none zero. Not currently used by the web server, but web server applications can add event code to use these values, see event SslHttpAppSrv1GetDocument in OverbyteIcsSslMultiWebServ1.pas. Or more intelligent redirection could be implemented like changing http:// to https://.


Optional, a web server redirection status code, 301, 302, 307 or 308 depending on reason.


Optional, if SSL X509 certificates are to be automatically ordered, downloaded and installed, specifies the Supplier and Protocol to be used as type TSupplierProto. Currently supports SuppProtoNone, SuppProtoAcmeV2 and SuppProtoCertCentre. Ignored unless TSslWSocketServer property SslCertAutoOrder is True. Note any SSL certificates ordered will use all HostNames so must support multiple Subject Alternative Names if more than one host is specified. Note wild card certificates can not currently be ordered by IcsHosts, but can be done using TSslX509Certs. Automatic certificate ordering is triggered by calling the server method RecheckSslCerts after the server has started listening, which checks all certificates and chains for expiry within CertExpireDays (default 30) and will then order a new certificate for any that fail, including certificate file missing. The server application should call RecheckSslCerts at least once a day, but it can be more often to give more chances to check for ordering problems. The TSslX509Certs has an internal timer that checks for order completion and calls an onNewCert event when the new certificate is ready, this event should call RecheckSslCerts again which will find the new certificate file and load it into SslContext.


Optional, if CertSupplierProto is not SuppProtoNone, specifies the Certificate Database Working Directory, in which an account that matches CertSupplierProto should already have been created, see OverbyteIcsSslX509Certs.pas for more information. All new certificates, requests and private keys are saved in the work directory with a unique order number, then again with the final name format, and finally the certificate bundles as PEM and PFX are copied to the directory used by SslCert. CertDirWork must not be the same directory as SslCert. Generally, CertDirWork should be the same for all Hosts that order certificates for the server, because the TSslX509Certs currently only checks for completed order for one supplier database at a time. Different directories can be used, provided certificates do not expire the same day.


Optional, if CertSupplierProto is not SuppProtoNone, specifies the Challenge Type as TChallengeType, used by the supplier to check the domain names for the certificate resolve to this server. Currently supports ChallNone, ChallFileUNC, ChallDNS and ChallEmail. Note that DNS require extra code in the server application to update DNS records. ChallFileUNC means the server will create a special file in the .Well-Known directory which the supplier will read for each different HostName to confirm they can all be accessed from the public internet, this usually happens within a few seconds for domain validated certificates. ChallEmail means that manual validation of the host names will be needed, with notification by email when ready, but the component will periodically check with the supplier to see when the order is completed and can be downloaded and installed.


Optional, primarily for CertSupplierProto is SuppProtoCertCentre to specify the particular certificate issuer and product, currently only AlwaysOnSSL.AlwaysOnSSL supported since all commercial certificates require contact details not in these properties. For SuppProtoAcmeV2, use Let's Encrypt currently for descriptive purposes although in theory other suppliers may use the same Acme2 protocol for other certificates.


Optional, specifies the new SSL certificate Private Key algorithm and key length as type TSslPrivKeyType. Typically use PrivKeyRsa2048, PrivKeyRsa3072, PrivKeyRsa4096, PrivKeyECsecp256, PrivKeyECsecp384, PrivKeyECsecp512 or PrivKeyEd25519, although the supplier may reject any of them. Beware RSA keys longer than 4,096 bits can take many minute to generate blocking the server.


Optional, specifies the new SSL certificate request signing digest as type TEvpDigest. Typically use Digest_sha256, Digest_sha384 or Digest_sha512, there are now SHA3 options but unlikely to be supported by suppliers yet.

Example from \Samples\Delphi\SslInternet\OverbyteIcsSslMultiWebServ.ini which can be read using the function IcsLoadIcsHostsFromIni.

CertProduct=Let's Encrypt

Once IcsHosts have been validated, a number of read only properties are available with more information about the IcsHost from the certificate and bindings, that may be usefully logged for configuration and error checking purposes.

SslCtx TSslContext component used by IcsHost.
HostNameTot Number of items in HostNames TStrings.
DisplayName IcsHost display name, variously using HostTag, Descr, and bind IP addresses and ports.
CertDomains Comma separated list of SSL certificate host names from Subject aternate Names field.
CertInfo A long multiple line text block describing all the main fields of one or more SSL certificates in the chain including subject, issuer, expiry, public key type and signature method.
BindInfo List of one or more IP addresses and ports.
CertExiry SSL certificate expiry date and time, as TDateTime.
CertFStamp Unix file time stamp for SSL server certificate, to check if changed.
InterFStamp Unix file time stamp for SSL intermediate certificates, to check if changed.
CertErrs Description of any errors found in the SSL certificate chain during validation.
CertValRes SSL certificate chain validation result as type TChainResult, chainOK, chainFail, chainWarn, chainNone.
BindIdxNone MultiListenIdx for first IP address, non-SSL.
BindIdxSsl MultiListenIdx for first IP address, SSL.
BindIdx2None MultiListenIdx for second IP address, non-SSL.
BindIdx2Ssl MultiListenIdx for second IP address, SSL.

0Auth2 Consideration

If the CertSupplierProto requirss 0Auth2 authentication, ie SuppProtoCertCentre, a TSslX509Certs event is triggered with a browser URL that should be visited to login to the supplier account. For a background server, the application can send an email to an administrator who performs the login manually on the same PC as the server is running, and the TSslX509Certs component will accept and save the authentication token automatically and use it for the next certificate order attempt. Tokens usually expire after 12 to 24 hours, but the server will automatically refresh the token provided it is not stopped before token expiry.