6 Replies Latest reply on Sep 21, 2017 3:27 PM by jebeling

    Certificate Error Warnings with Logging

    jebeling

      While it is not generally advisable to allow users to freely access sites with bad certificates (expired, self-signed, unknown authorities, common name mismatch, etc) the flexibility of the MWG rule engine does allow you to block on some types of errors, warn on others and allow on others with extensive logging when they click through the warning. It is highly recommended that regardless of category decryption should be performed whenever a certificate error is encountered. The attached rulesets allow the connection to be established, decrypted, and logged whenever a certificate verification error is encountered. It also demonstrates how to implement end user warnings that are customized for your environment. The ruleset includes rules for logging only, blocking and logging and Warn and log. One ruleset replaces the Certificate Verification rules, another is inserted in the URL filter ruleset and the last goes in the log handler rulesets. The Certificate verification rulesets and Logging rulesets combine the functionality described in the comments of this discussion: MWG7 SSL - Incident Manager?

       

      Certificate Verification Ruleset:

      To warn users and allow click through use this ruleset with the "Log" rule enabled for the types of errors you want to warn

       

       

      Rule Sets

      Certificate verification

      [Ruleset for certificate verification.]

      [✔] Enabled [✔] Enabled in Cloud
      Applies to: [✔] Requests [✘] Responses [✘] Embedded Objects
      1: Command.Name equals "CERTVERIFY"
      EnabledRuleActionEventsComments
      [✔] Enabled Skip verification for certificates found in Certificate White List
      1: SSL.Server.Certificate.HostAndCertificate is in list Certificate White List
      Stop Rule SetSkips verification for certificates found in Certificate White List.
      [✘] Disabled Modified Allow and Log Self Signed Certificates
      1: SSL.Server.Certificate.SelfSigned equals true
      ContinueSet User-Defined.SSLIncident = true
      Set User-Defined.SSLCertReason = "SSL Cert: SelfSigned"
      PDStorage.AddGlobalData.String(URL.Host,User-Defined.SSLCertReason)<Add 1 day storage>
      Allows if certificate is self signed and sets host reason in PDStorage globally.
      [✔] Enabled Log Self Signed Certificates
      1: SSL.Server.Certificate.SelfSigned equals true
      ContinueSet User-Defined.SSLIncident = true
      Set User-Defined.SSLCertReason = "SelfSigned"
      Logs if certificate is self signed.
      [✘] Disabled Block and Log Self Signed Certificates
      1: SSL.Server.Certificate.SelfSigned equals true
      Block<Selfsigned certificate>Set User-Defined.SSLIncident = true
      Set User-Defined.SSLCertReason = "SelfSigned"
      Blocks if certificate is self signed.
      [✘] Disabled Block self signed certificates
      1: SSL.Server.Certificate.SelfSigned equals true
      Block<Selfsigned certificate>Blocks if certificate is self signed.
      [✔] Enabled Log Expired Server (7 Day Tolerance) and Expired CA Certificates
      1: SSL.Server.Certificate.DaysExpired greater than 7
      2: OR SSL.Server.CertificateChain.ContainsExpiredCA<Default> equals true
      ContinueSet User-Defined.SSLIncident = true
      Set User-Defined.SSLCertReason = "Expired"
      Logs if a server or if a certificate has been expired.
      [✘] Disabled Block and Log Expired Server (7 Day Tolerance) and Expired CA Certificates
      1: SSL.Server.Certificate.DaysExpired greater than 7
      2: OR SSL.Server.CertificateChain.ContainsExpiredCA<Default> equals true
      Block<Expired certificate>Set User-Defined.SSLIncident = true
      Set User-Defined.SSLCertReason = "Expired"
      Logs if a server or if a certificate has been expired.
      [✘] Disabled Block expired server (7 day tolerance) and expired CA certificates
      1: SSL.Server.Certificate.DaysExpired greater than 7
      2: OR SSL.Server.CertificateChain.ContainsExpiredCA<Default> equals true
      Block<Expired certificate>Blocks if a server or if a certificate has been expired.
      [✔] Enabled Block and Log Too Long Certificate Chains
      1: SSL.Server.CertificateChain.PathLengthExceeded<Default> equals true
      Block<Certificate incident>Set User-Defined.SSLIncident = true
      Set User-Defined.SSLCertReason = "ChainTooLong"
      Blocks if a certificate chain is too long.
      [✘] Disabled Block too long certificate chains
      1: SSL.Server.CertificateChain.PathLengthExceeded<Default> equals true
      Block<Certificate incident>Blocks if a certificate chain is too long.
      [✔] Enabled Block and Log Revoked Certificates
      1: SSL.Server.CertificateChain.ContainsRevoked<Default> equals true
      Block<Selfsigned certificate>Set User-Defined.SSLIncident = true
      Set User-Defined.SSLCertReason = "Revoked"
      Blocks if a certificate chain contains a revoked certificate.
      [✘] Disabled Block revoked certificates
      1: SSL.Server.CertificateChain.ContainsRevoked<Default> equals true
      Block<Revoked certificate>Blocks if a certificate chain contains a revoked certificate.
      [✔] Enabled Paranoid certificate chain verification logging
      1: SSL.Server.CertificateChain.AllRevocationStatusesKnown<Default> equals false
      2: OR SSL.Server.CertificateChain.IsComplete<Default> equals false
      ContinueSet User-Defined.SSLIncident = true
      Set User-Defined.SSLCertReason = "ParanoidChain"
      [✘] Disabled Paranoid certificate chain verification
      1: SSL.Server.CertificateChain.AllRevocationStatusesKnown<Default> equals false
      2: OR SSL.Server.CertificateChain.IsComplete<Default> equals false
      Block<Certificate incident>
      [✘] Disabled Log Unknown certificate authorities
      1: SSL.Server.CertificateChain.FoundKnownCA<Default> equals false
      2: AND SSL.Server.CertificateChain.FoundKnownCA<SaaS CAs> equals false
      3: AND SSL.Server.Certificate.CN does not match in list CA Check Bypass
      ContinueSet User-Defined.SSLIncident = true
      Set User-Defined.SSLCertReason = "UnknownCA"
      Logs if a certificate authoritiy is unknown.
      [✔] Enabled Block and Log Unknown certificate authorities
      1: SSL.Server.CertificateChain.FoundKnownCA<Default> equals false
      2: AND SSL.Server.CertificateChain.FoundKnownCA<SaaS CAs> equals false
      3: AND SSL.Server.Certificate.CN does not match in list CA Check Bypass
      Block<Unknown certificate authorities>Set User-Defined.SSLIncident = true
      Set User-Defined.SSLCertReason = "UnknownCA"
      Blocks if a certificate authoritiy is unknown.
      [✘] Disabled Block Unknown certificate authorities
      1: SSL.Server.CertificateChain.FoundKnownCA<Default> equals false
      2: AND SSL.Server.CertificateChain.FoundKnownCA<SaaS CAs> equals false
      3: AND SSL.Server.Certificate.CN does not match in list CA Check Bypass
      Block<Unknown certificate authorities>Blocks if a certificate authoritiy is unknown.
      [✘] Disabled Log Untrusted certificate authorities
      1: SSL.Server.CertificateChain.FirstKnownCAIsTrusted<Default> equals false
      2: AND SSL.Server.CertificateChain.FirstKnownCAIsTrusted<SaaS CAs> equals false
      3: AND SSL.Server.Certificate.CN does not match in list CA Check Bypass
      ContinueSet User-Defined.SSLIncident = true
      Set User-Defined.SSLCertReason = "UntrustedCA"
      Blocks if a certificate authoritiy is untrusted.
      [✔] Enabled Block and Log Untrusted certificate authorities
      1: SSL.Server.CertificateChain.FirstKnownCAIsTrusted<Default> equals false
      2: AND SSL.Server.CertificateChain.FirstKnownCAIsTrusted<SaaS CAs> equals false
      3: AND SSL.Server.Certificate.CN does not match in list CA Check Bypass
      Block<Untrusted certificate authorities>Set User-Defined.SSLIncident = true
      Set User-Defined.SSLCertReason = "UntrustedCA"
      Blocks if a certificate authoritiy is untrusted.
      [✘] Disabled Block Untrusted certificate authorities
      1: SSL.Server.CertificateChain.FirstKnownCAIsTrusted<Default> equals false
      2: AND SSL.Server.CertificateChain.FirstKnownCAIsTrusted<SaaS CAs> equals false
      3: AND SSL.Server.Certificate.CN does not match in list CA Check Bypass
      Block<Untrusted certificate authorities>Blocks if a certificate authoritiy is untrusted.
      Verify common name (proxy setup)

      [Ruleset to verify common names if transparent SSL connection is disabled.]

      [✔] Enabled [✘] Disabled in Cloud
      Applies to: [✔] Requests [✘] Responses [✘] Embedded Objects
      1: Connection.SSL.TransparentCNHandling equals false
      EnabledRuleActionEventsComments
      [✔] Enabled Allow matching hostname
      1: URL.Host equals SSL.Server.Certificate.CN
      Stop Rule Set
      [✔] Enabled Allow wildcard certificates
      1: SSL.Server.Certificate.CN.HasWildcards equals true
      2: AND URL.Host matches SSL.Certificate.CN.ToWildcard(SSL.Server.Certificate.CN)
      Stop Rule SetStatistics.Counter.Increment("CertWildCardMatch",1)<Default>
      [✔] Enabled Allow alternative common names
      1: URL.Host matches in list SSL.Server.Certificate.AlternativeCNs
      Stop Rule Set
      [✘] Disabled Cert Verify Troubleshooting
      1: URL.Host matches in list CertVerify Troubleshoot Block Hosts
      Block<Certificate incident>
      [✔] Enabled Block if Certificate is not in Certificate White List
      1: SSL.Server.Certificate.HostAndCertificate is not in list Certificate White List
      ContinueStatistics.Counter.Increment("CertNameMismatch",1)<Default>
      Set User-Defined.SSLIncident = true
      Set User-Defined.SSLCertReason = "CN_Mismatch"
      [✘] Disabled Block if Certificate is not in Certificate White List
      1: SSL.Server.Certificate.HostAndCertificate is not in list Certificate White List
      Block<Common name mismatch>Statistics.Counter.Increment("CertNameMismatch",1)<Default>
      Set User-Defined.SSLIncident = true
      Set User-Defined.SSLCertReason = "CN_Mismatch"
      [✘] Disabled Block incident
      Always
      Block<Common name mismatch>Statistics.Counter.Increment("CertNameMismatch",1)<Default>

       

      Coaching Ruleset:

       

      Enable the appropriate rulesets to match errors that you want to warn rather than just log. Each error type has its own coaching config as you may want to set your timeouts differently based on the type of error. If you want to log all accesses after a click through enable the second rule in each coaching ruleset

       

      Rule Sets
      Coaching

      [This ruleset contains rules for coaching for urls, user and ip. This ruleset will not be exectued if SSL is disabled and a HTTPS request has been done.]

      [✔] Enabled [✘] Disabled in Cloud
      Applies to: [✔] Requests [✘] Responses [✘] Embedded Objects
      1: SSL.ClientContext.IsApplied equals true
      2: OR Command.Name does not equal "CONNECT"
      Coaching For Expired Certificate Errors
      [✔] Enabled [✘] Disabled in Cloud
      Applies to: [✔] Requests [✔] Responses [✔] Embedded Objects
      1: (User-Defined.SSLIncident equals true
      2: AND User-Defined.SSLCertReason equals "Expired")
      3: OR Quota.Coaching.IsActivationRequest.Strict<Expired Certificate> equals true
      EnabledRuleActionEventsComments
      [✔] EnabledRedirect After Starting New Coaching Session and Write Coaching Present Log
      1: Quota.Coaching.SessionExceeded<Expired Certificate> equals true
      Redirect<Redirection After Coaching Session Activation>Set User-Defined.logLine =
           "Click(Expired):" +
           DateTime.ToWebReporterString +
           " "" +
           Authentication.Realm +
           "\" +
           Authentication.UserName +
           "" " +
           String.ReplaceIfEquals(IP.ToString(Client.IP),"","-") +
           " " +
           String.ReplaceIfEquals(Number.ToString(Response.StatusCode),"","-") +
           " "" +
           Request.Header.FirstLine +
           "" " +
           """ +
           List.OfCategory.ToString(URL.Categories<Default>) +
           "" "" +
           String.ReplaceIfEquals(URL.ReputationString<Default>,"","-") +
           "" "" +
           MediaType.ToString(MediaType.FromHeader) +
           "" " +
           String.ReplaceIfEquals(Number.ToString(Body.Size),"","-") +
           " "" +
           Header.Get("User-Agent") +
           "" "" +
           Number.ToString(Block.ID) +
           "" "" +
           Cache.Status +
           "" "" +
           User-Defined.Geolocation +
           """
      FileSystemLogging.WriteLogEntry(User-Defined.logLine)<Coaching Present Log Config>
      [✘] DisabledWrite Coaching Present Log
      1: Quota.Coaching.SessionExceeded<URL Category Configuration> equals false
      Stop Rule SetSet User-Defined.logLine =
           "Access(Expired):" +
           DateTime.ToWebReporterString +
           " "" +
           Authentication.Realm +
           "\" +
           Authentication.UserName +
           "" " +
           String.ReplaceIfEquals(IP.ToString(Client.IP),"","-") +
           " " +
           String.ReplaceIfEquals(Number.ToString(Response.StatusCode),"","-") +
           " "" +
           Request.Header.FirstLine +
           "" " +
           """ +
           List.OfCategory.ToString(URL.Categories<Default>) +
           "" "" +
           String.ReplaceIfEquals(URL.ReputationString<Default>,"","-") +
           "" "" +
           MediaType.ToString(MediaType.FromHeader) +
           "" " +
           String.ReplaceIfEquals(Number.ToString(Body.Size),"","-") +
           " "" +
           Header.Get("User-Agent") +
           "" "" +
           Number.ToString(Block.ID) +
           "" "" +
           Cache.Status +
           "" "" +
           User-Defined.Geolocation +
           """
      FileSystemLogging.WriteLogEntry(User-Defined.logLine)<Coaching Access Log Config>
      [✔] EnabledCheck if Coaching Session Has Been Exceeded and Write Coaching Present Log
      1: Quota.Coaching.SessionExceeded<Expired Certificate> equals true
      Block<CoachingExpiredCert>Set User-Defined.logLine =
           "Present(Expired):" +
           DateTime.ToWebReporterString +
           " "" +
           Authentication.Realm +
           "\" +
           Authentication.UserName +
           "" " +
           String.ReplaceIfEquals(IP.ToString(Client.IP),"","-") +
           " " +
           String.ReplaceIfEquals(Number.ToString(Response.StatusCode),"","-") +
           " "" +
           Request.Header.FirstLine +
           "" " +
           """ +
           List.OfCategory.ToString(URL.Categories<Default>) +
           "" "" +
           String.ReplaceIfEquals(URL.ReputationString<Default>,"","-") +
           "" "" +
           MediaType.ToString(MediaType.FromHeader) +
           "" " +
           String.ReplaceIfEquals(Number.ToString(Body.Size),"","-") +
           " "" +
           Header.Get("User-Agent") +
           "" "" +
           Number.ToString(Block.ID) +
           "" "" +
           Cache.Status +
           "" "" +
           User-Defined.Geolocation +
           """
      FileSystemLogging.WriteLogEntry(User-Defined.logLine)<Coaching Present Log Config>
      Coaching For Self-Signed Certificate Errors
      [✔] Enabled [✘] Disabled in Cloud
      Applies to: [✔] Requests [✔] Responses [✔] Embedded Objects
      1: (User-Defined.SSLIncident equals true
      2: AND User-Defined.SSLCertReason equals "SelfSigned")
      3: OR Quota.Coaching.IsActivationRequest.Strict<Self-Signed Certificate> equals true
      EnabledRuleActionEventsComments
      [✔] EnabledRedirect After Starting New Coaching Session and Write Coaching Present Log
      1: Quota.Coaching.IsActivationRequest.Strict<Self-Signed Certificate> equals true
      Redirect<Redirection After Coaching Session Activation>Set User-Defined.logLine =
           "Click(SelfSign):" +
           DateTime.ToWebReporterString +
           " "" +
           Authentication.Realm +
           "\" +
           Authentication.UserName +
           "" " +
           String.ReplaceIfEquals(IP.ToString(Client.IP),"","-") +
           " " +
           String.ReplaceIfEquals(Number.ToString(Response.StatusCode),"","-") +
           " "" +
           Request.Header.FirstLine +
           "" " +
           """ +
           List.OfCategory.ToString(URL.Categories<Default>) +
           "" "" +
           String.ReplaceIfEquals(URL.ReputationString<Default>,"","-") +
           "" "" +
           MediaType.ToString(MediaType.FromHeader) +
           "" " +
           String.ReplaceIfEquals(Number.ToString(Body.Size),"","-") +
           " "" +
           Header.Get("User-Agent") +
           "" "" +
           Number.ToString(Block.ID) +
           "" "" +
           Cache.Status +
           "" "" +
           User-Defined.Geolocation +
           """
      FileSystemLogging.WriteLogEntry(User-Defined.logLine)<Coaching Present Log Config>
      [✘] DisabledWrite Coaching Present Log
      1: Quota.Coaching.SessionExceeded<URL Category Configuration> equals false
      Stop Rule SetSet User-Defined.logLine =
           "Access(SelfSign):" +
           DateTime.ToWebReporterString +
           " "" +
           Authentication.Realm +
           "\" +
           Authentication.UserName +
           "" " +
           String.ReplaceIfEquals(IP.ToString(Client.IP),"","-") +
           " " +
           String.ReplaceIfEquals(Number.ToString(Response.StatusCode),"","-") +
           " "" +
           Request.Header.FirstLine +
           "" " +
           """ +
           List.OfCategory.ToString(URL.Categories<Default>) +
           "" "" +
           String.ReplaceIfEquals(URL.ReputationString<Default>,"","-") +
           "" "" +
           MediaType.ToString(MediaType.FromHeader) +
           "" " +
           String.ReplaceIfEquals(Number.ToString(Body.Size),"","-") +
           " "" +
           Header.Get("User-Agent") +
           "" "" +
           Number.ToString(Block.ID) +
           "" "" +
           Cache.Status +
           "" "" +
           User-Defined.Geolocation +
           """
      FileSystemLogging.WriteLogEntry(User-Defined.logLine)<Coaching Access Log Config>
      [✔] EnabledCheck if Coaching Session Has Been Exceeded and Write Coaching Present Log
      1: Quota.Coaching.SessionExceeded<Self-Signed Certificate> equals true
      Block<CoachingSelfSignedCert>Set User-Defined.logLine =
           "Present(SelfSign):" +
           DateTime.ToWebReporterString +
           " "" +
           Authentication.Realm +
           "\" +
           Authentication.UserName +
           "" " +
           String.ReplaceIfEquals(IP.ToString(Client.IP),"","-") +
           " " +
           String.ReplaceIfEquals(Number.ToString(Response.StatusCode),"","-") +
           " "" +
           Request.Header.FirstLine +
           "" " +
           """ +
           List.OfCategory.ToString(URL.Categories<Default>) +
           "" "" +
           String.ReplaceIfEquals(URL.ReputationString<Default>,"","-") +
           "" "" +
           MediaType.ToString(MediaType.FromHeader) +
           "" " +
           String.ReplaceIfEquals(Number.ToString(Body.Size),"","-") +
           " "" +
           Header.Get("User-Agent") +
           "" "" +
           Number.ToString(Block.ID) +
           "" "" +
           Cache.Status +
           "" "" +
           User-Defined.Geolocation +
           """
      FileSystemLogging.WriteLogEntry(User-Defined.logLine)<Coaching Present Log Config>
      Coaching For Certificate CN Mismatch Errors
      [✔] Enabled [✘] Disabled in Cloud
      Applies to: [✔] Requests [✔] Responses [✔] Embedded Objects
      1: (User-Defined.SSLIncident equals true
      2: AND User-Defined.SSLCertReason equals "CNMismatch")
      3: OR Quota.Coaching.IsActivationRequest.Strict<Certificate CN Mismatch> equals true
      EnabledRuleActionEventsComments
      [✔] EnabledRedirect After Starting New Coaching Session and Write Coaching Present Log
      1: Quota.Coaching.IsActivationRequest.Strict<Certificate CN Mismatch> equals true
      Redirect<Redirection After Coaching Session Activation>Set User-Defined.logLine =
           "Click(CNMismatch):" +
           DateTime.ToWebReporterString +
           " "" +
           Authentication.Realm +
           "\" +
           Authentication.UserName +
           "" " +
           String.ReplaceIfEquals(IP.ToString(Client.IP),"","-") +
           " " +
           String.ReplaceIfEquals(Number.ToString(Response.StatusCode),"","-") +
           " "" +
           Request.Header.FirstLine +
           "" " +
           """ +
           List.OfCategory.ToString(URL.Categories<Default>) +
           "" "" +
           String.ReplaceIfEquals(URL.ReputationString<Default>,"","-") +
           "" "" +
           MediaType.ToString(MediaType.FromHeader) +
           "" " +
           String.ReplaceIfEquals(Number.ToString(Body.Size),"","-") +
           " "" +
           Header.Get("User-Agent") +
           "" "" +
           Number.ToString(Block.ID) +
           "" "" +
           Cache.Status +
           "" "" +
           User-Defined.Geolocation +
           """
      FileSystemLogging.WriteLogEntry(User-Defined.logLine)<Coaching Present Log Config>
      [✘] DisabledWrite Coaching Present Log
      1: Quota.Coaching.SessionExceeded<URL Category Configuration> equals false
      Stop Rule SetSet User-Defined.logLine =
           "Access(CNMismatch):" +
           DateTime.ToWebReporterString +
           " "" +
           Authentication.Realm +
           "\" +
           Authentication.UserName +
           "" " +
           String.ReplaceIfEquals(IP.ToString(Client.IP),"","-") +
           " " +
           String.ReplaceIfEquals(Number.ToString(Response.StatusCode),"","-") +
           " "" +
           Request.Header.FirstLine +
           "" " +
           """ +
           List.OfCategory.ToString(URL.Categories<Default>) +
           "" "" +
           String.ReplaceIfEquals(URL.ReputationString<Default>,"","-") +
           "" "" +
           MediaType.ToString(MediaType.FromHeader) +
           "" " +
           String.ReplaceIfEquals(Number.ToString(Body.Size),"","-") +
           " "" +
           Header.Get("User-Agent") +
           "" "" +
           Number.ToString(Block.ID) +
           "" "" +
           Cache.Status +
           "" "" +
           User-Defined.Geolocation +
           """
      FileSystemLogging.WriteLogEntry(User-Defined.logLine)<Coaching Access Log Config>
      [✔] EnabledCheck if Coaching Session Has Been Exceeded and Write Coaching Present Log
      1: Quota.Coaching.SessionExceeded<Certificate CN Mismatch> equals true
      Block<Coaching Certificate CN Mismatch>Set User-Defined.logLine =
           "Present(CNMismatch):" +
           DateTime.ToWebReporterString +
           " "" +
           Authentication.Realm +
           "\" +
           Authentication.UserName +
           "" " +
           String.ReplaceIfEquals(IP.ToString(Client.IP),"","-") +
           " " +
           String.ReplaceIfEquals(Number.ToString(Response.StatusCode),"","-") +
           " "" +
           Request.Header.FirstLine +
           "" " +
           """ +
           List.OfCategory.ToString(URL.Categories<Default>) +
           "" "" +
           String.ReplaceIfEquals(URL.ReputationString<Default>,"","-") +
           "" "" +
           MediaType.ToString(MediaType.FromHeader) +
           "" " +
           String.ReplaceIfEquals(Number.ToString(Body.Size),"","-") +
           " "" +
           Header.Get("User-Agent") +
           "" "" +
           Number.ToString(Block.ID) +
           "" "" +
           Cache.Status +
           "" "" +
           User-Defined.Geolocation +
           """
      FileSystemLogging.WriteLogEntry(User-Defined.logLine)<Coaching Present Log Config>
      Coaching For Untrusted CA Errors
      [✔] Enabled [✘] Disabled in Cloud
      Applies to: [✔] Requests [✔] Responses [✔] Embedded Objects
      1: (User-Defined.SSLIncident equals true
      2: AND User-Defined.SSLCertReason equals "UntrustedCA")
      3: OR Quota.Coaching.IsActivationRequest.Strict<Untrusted CA> equals true
      EnabledRuleActionEventsComments
      [✔] EnabledRedirect After Starting New Coaching Session and Write Coaching Present Log
      1: Quota.Coaching.IsActivationRequest.Strict<Untrusted CA> equals true
      Redirect<Redirection After Coaching Session Activation>Set User-Defined.logLine =
           "Click(UntrustedCA):" +
           DateTime.ToWebReporterString +
           " "" +
           Authentication.Realm +
           "\" +
           Authentication.UserName +
           "" " +
           String.ReplaceIfEquals(IP.ToString(Client.IP),"","-") +
           " " +
           String.ReplaceIfEquals(Number.ToString(Response.StatusCode),"","-") +
           " "" +
           Request.Header.FirstLine +
           "" " +
           """ +
           List.OfCategory.ToString(URL.Categories<Default>) +
           "" "" +
           String.ReplaceIfEquals(URL.ReputationString<Default>,"","-") +
           "" "" +
           MediaType.ToString(MediaType.FromHeader) +
           "" " +
           String.ReplaceIfEquals(Number.ToString(Body.Size),"","-") +
           " "" +
           Header.Get("User-Agent") +
           "" "" +
           Number.ToString(Block.ID) +
           "" "" +
           Cache.Status +
           "" "" +
           User-Defined.Geolocation +
           """
      FileSystemLogging.WriteLogEntry(User-Defined.logLine)<Coaching Present Log Config>
      [✘] DisabledWrite Coaching Present Log
      1: Quota.Coaching.SessionExceeded<URL Category Configuration> equals false
      Stop Rule SetSet User-Defined.logLine =
           "Access(UntrustedCA):" +
           DateTime.ToWebReporterString +
           " "" +
           Authentication.Realm +
           "\" +
           Authentication.UserName +
           "" " +
           String.ReplaceIfEquals(IP.ToString(Client.IP),"","-") +
           " " +
           String.ReplaceIfEquals(Number.ToString(Response.StatusCode),"","-") +
           " "" +
           Request.Header.FirstLine +
           "" " +
           """ +
           List.OfCategory.ToString(URL.Categories<Default>) +
           "" "" +
           String.ReplaceIfEquals(URL.ReputationString<Default>,"","-") +
           "" "" +
           MediaType.ToString(MediaType.FromHeader) +
           "" " +
           String.ReplaceIfEquals(Number.ToString(Body.Size),"","-") +
           " "" +
           Header.Get("User-Agent") +
           "" "" +
           Number.ToString(Block.ID) +
           "" "" +
           Cache.Status +
           "" "" +
           User-Defined.Geolocation +
           """
      FileSystemLogging.WriteLogEntry(User-Defined.logLine)<Coaching Access Log Config>
      [✔] EnabledCheck if Coaching Session Has Been Exceeded and Write Coaching Present Log
      1: Quota.Coaching.SessionExceeded<Untrusted CA> equals true
      Block<Coaching Untrusted CA>Set User-Defined.logLine =
           "Present(UntrustedCA):" +
           DateTime.ToWebReporterString +
           " "" +
           Authentication.Realm +
           "\" +
           Authentication.UserName +
           "" " +
           String.ReplaceIfEquals(IP.ToString(Client.IP),"","-") +
           " " +
           String.ReplaceIfEquals(Number.ToString(Response.StatusCode),"","-") +
           " "" +
           Request.Header.FirstLine +
           "" " +
           """ +
           List.OfCategory.ToString(URL.Categories<Default>) +
           "" "" +
           String.ReplaceIfEquals(URL.ReputationString<Default>,"","-") +
           "" "" +
           MediaType.ToString(MediaType.FromHeader) +
           "" " +
           String.ReplaceIfEquals(Number.ToString(Body.Size),"","-") +
           " "" +
           Header.Get("User-Agent") +
           "" "" +
           Number.ToString(Block.ID) +
           "" "" +
           Cache.Status +
           "" "" +
           User-Defined.Geolocation +
           """
      FileSystemLogging.WriteLogEntry(User-Defined.logLine)<Coaching Present Log Config>
      Coaching For Unknown CA Errors
      [✔] Enabled [✘] Disabled in Cloud
      Applies to: [✔] Requests [✔] Responses [✔] Embedded Objects
      1: (User-Defined.SSLIncident equals true
      2: AND User-Defined.SSLCertReason equals "UnknownCA")
      3: OR Quota.Coaching.IsActivationRequest.Strict<Unknown CA> equals true
      EnabledRuleActionEventsComments
      [✔] EnabledRedirect After Starting New Coaching Session and Write Coaching Present Log
      1: Quota.Coaching.IsActivationRequest.Strict<Unknown CA> equals true
      Redirect<Redirection After Coaching Session Activation>Set User-Defined.logLine =
           "Click(UnknownCA):" +
           DateTime.ToWebReporterString +
           " "" +
           Authentication.Realm +
           "\" +
           Authentication.UserName +
           "" " +
           String.ReplaceIfEquals(IP.ToString(Client.IP),"","-") +
           " " +
           String.ReplaceIfEquals(Number.ToString(Response.StatusCode),"","-") +
           " "" +
           Request.Header.FirstLine +
           "" " +
           """ +
           List.OfCategory.ToString(URL.Categories<Default>) +
           "" "" +
           String.ReplaceIfEquals(URL.ReputationString<Default>,"","-") +
           "" "" +
           MediaType.ToString(MediaType.FromHeader) +
           "" " +
           String.ReplaceIfEquals(Number.ToString(Body.Size),"","-") +
           " "" +
           Header.Get("User-Agent") +
           "" "" +
           Number.ToString(Block.ID) +
           "" "" +
           Cache.Status +
           "" "" +
           User-Defined.Geolocation +
           """
      FileSystemLogging.WriteLogEntry(User-Defined.logLine)<Coaching Present Log Config>
      [✘] DisabledWrite Coaching Present Log
      1: Quota.Coaching.SessionExceeded<URL Category Configuration> equals false
      Stop Rule SetSet User-Defined.logLine =
           "Access(UnknownCA):" +
           DateTime.ToWebReporterString +
           " "" +
           Authentication.Realm +
           "\" +
           Authentication.UserName +
           "" " +
           String.ReplaceIfEquals(IP.ToString(Client.IP),"","-") +
           " " +
           String.ReplaceIfEquals(Number.ToString(Response.StatusCode),"","-") +
           " "" +
           Request.Header.FirstLine +
           "" " +
           """ +
           List.OfCategory.ToString(URL.Categories<Default>) +
           "" "" +
           String.ReplaceIfEquals(URL.ReputationString<Default>,"","-") +
           "" "" +
           MediaType.ToString(MediaType.FromHeader) +
           "" " +
           String.ReplaceIfEquals(Number.ToString(Body.Size),"","-") +
           " "" +
           Header.Get("User-Agent") +
           "" "" +
           Number.ToString(Block.ID) +
           "" "" +
           Cache.Status +
           "" "" +
           User-Defined.Geolocation +
           """
      FileSystemLogging.WriteLogEntry(User-Defined.logLine)<Coaching Access Log Config>
      [✔] EnabledCheck if Coaching Session Has Been Exceeded and Write Coaching Present Log
      1: Quota.Coaching.SessionExceeded<Unknown CA> equals true
      Block<Coaching Unknown Certificate Authority>Set User-Defined.logLine =
           "Present(UnknownCA):" +
           DateTime.ToWebReporterString +
           " "" +
           Authentication.Realm +
           "\" +
           Authentication.UserName +
           "" " +
           String.ReplaceIfEquals(IP.ToString(Client.IP),"","-") +
           " " +
           String.ReplaceIfEquals(Number.ToString(Response.StatusCode),"","-") +
           " "" +
           Request.Header.FirstLine +
           "" " +
           """ +
           List.OfCategory.ToString(URL.Categories<Default>) +
           "" "" +
           String.ReplaceIfEquals(URL.ReputationString<Default>,"","-") +
           "" "" +
           MediaType.ToString(MediaType.FromHeader) +
           "" " +
           String.ReplaceIfEquals(Number.ToString(Body.Size),"","-") +
           " "" +
           Header.Get("User-Agent") +
           "" "" +
           Number.ToString(Block.ID) +
           "" "" +
           Cache.Status +
           "" "" +
           User-Defined.Geolocation +
           """
      FileSystemLogging.WriteLogEntry(User-Defined.logLine)<Coaching Present Log Config>
      Coaching With URL Configuration
      [✔] Enabled [✘] Disabled in Cloud
      Applies to: [✔] Requests [✔] Responses [✔] Embedded Objects
      1: URL.Categories<Default> at least one in list URL Category Blocklist for Coaching
      2: OR URL.Host matches in list URL Hosts Blocklist for Coaching°
      3: OR Quota.Coaching.IsActivationRequest.Strict<URL Category Configuration> equals true
      EnabledRuleActionEventsComments
      [✔] EnabledRedirect After Starting New Coaching Session and Write Coaching Present Log
      1: Quota.Coaching.IsActivationRequest.Strict<URL Category Configuration> equals true
      Redirect<Redirection After Coaching Session Activation>Set User-Defined.logLine =
           "Click(Cat\Host):" +
           DateTime.ToWebReporterString +
           " "" +
           Authentication.Realm +
           "\" +
           Authentication.UserName +
           "" " +
           String.ReplaceIfEquals(IP.ToString(Client.IP),"","-") +
           " " +
           String.ReplaceIfEquals(Number.ToString(Response.StatusCode),"","-") +
           " "" +
           Request.Header.FirstLine +
           "" " +
           """ +
           List.OfCategory.ToString(URL.Categories<Default>) +
           "" "" +
           String.ReplaceIfEquals(URL.ReputationString<Default>,"","-") +
           "" "" +
           MediaType.ToString(MediaType.FromHeader) +
           "" " +
           String.ReplaceIfEquals(Number.ToString(Body.Size),"","-") +
           " "" +
           Header.Get("User-Agent") +
           "" "" +
           Number.ToString(Block.ID) +
           "" "" +
           Cache.Status +
           "" "" +
           User-Defined.Geolocation +
           """
      FileSystemLogging.WriteLogEntry(User-Defined.logLine)<Coaching Present Log Config>
      [✘] DisabledWrite Coaching Present Log
      1: Quota.Coaching.SessionExceeded<URL Category Configuration> equals false
      Stop Rule SetSet User-Defined.logLine =
           "Access(Cat\Host):" +
           DateTime.ToWebReporterString +
           " "" +
           Authentication.Realm +
           "\" +
           Authentication.UserName +
           "" " +
           String.ReplaceIfEquals(IP.ToString(Client.IP),"","-") +
           " " +
           String.ReplaceIfEquals(Number.ToString(Response.StatusCode),"","-") +
           " "" +
           Request.Header.FirstLine +
           "" " +
           """ +
           List.OfCategory.ToString(URL.Categories<Default>) +
           "" "" +
           String.ReplaceIfEquals(URL.ReputationString<Default>,"","-") +
           "" "" +
           MediaType.ToString(MediaType.FromHeader) +
           "" " +
           String.ReplaceIfEquals(Number.ToString(Body.Size),"","-") +
           " "" +
           Header.Get("User-Agent") +
           "" "" +
           Number.ToString(Block.ID) +
           "" "" +
           Cache.Status +
           "" "" +
           User-Defined.Geolocation +
           """
      FileSystemLogging.WriteLogEntry(User-Defined.logLine)<Coaching Access Log Config>
      [✔] EnabledCheck if Coaching Session Has Been Exceeded and Write Coaching Present Log
      1: Quota.Coaching.SessionExceeded<URL Category Configuration> equals true
      Block<ActionCoachingBlocked>Set User-Defined.logLine =
           "Present(Cat\Host):" +
           DateTime.ToWebReporterString +
           " "" +
           Authentication.Realm +
           "\" +
           Authentication.UserName +
           "" " +
           String.ReplaceIfEquals(IP.ToString(Client.IP),"","-") +
           " " +
           String.ReplaceIfEquals(Number.ToString(Response.StatusCode),"","-") +
           " "" +
           Request.Header.FirstLine +
           "" " +
           """ +
           List.OfCategory.ToString(URL.Categories<Default>) +
           "" "" +
           String.ReplaceIfEquals(URL.ReputationString<Default>,"","-") +
           "" "" +
           MediaType.ToString(MediaType.FromHeader) +
           "" " +
           String.ReplaceIfEquals(Number.ToString(Body.Size),"","-") +
           " "" +
           Header.Get("User-Agent") +
           "" "" +
           Number.ToString(Block.ID) +
           "" "" +
           Cache.Status +
           "" "" +
           User-Defined.Geolocation +
           """
      FileSystemLogging.WriteLogEntry(User-Defined.logLine)<Coaching Present Log Config>
      Uncategorized Coaching
      [✔] Enabled [✘] Disabled in Cloud
      Applies to: [✔] Requests [✔] Responses [✔] Embedded Objects
      1: Quota.Coaching.IsActivationRequest.Strict<Uncategorized Configuration> equals true
      2: OR URL.Categories<Default> equals Empty Category List°
      EnabledRuleActionEventsComments
      [✔] EnabledRedirect After Starting New Coaching Session and Write Coaching Present Log
      1: Quota.Coaching.IsActivationRequest.Strict<Uncategorized Configuration> equals true
      Redirect<Redirection After Coaching Session Activation>Set User-Defined.logLine =
           "Click(Uncat):" +
           DateTime.ToWebReporterString +
           " "" +
           Authentication.Realm +
           "\" +
           Authentication.UserName +
           "" " +
           String.ReplaceIfEquals(IP.ToString(Client.IP),"","-") +
           " " +
           String.ReplaceIfEquals(Number.ToString(Response.StatusCode),"","-") +
           " "" +
           Request.Header.FirstLine +
           "" " +
           """ +
           List.OfCategory.ToString(URL.Categories<Default>) +
           "" "" +
           String.ReplaceIfEquals(URL.ReputationString<Default>,"","-") +
           "" "" +
           MediaType.ToString(MediaType.FromHeader) +
           "" " +
           String.ReplaceIfEquals(Number.ToString(Body.Size),"","-") +
           " "" +
           Header.Get("User-Agent") +
           "" "" +
           Number.ToString(Block.ID) +
           "" "" +
           Cache.Status +
           "" "" +
           User-Defined.Geolocation +
           """
      FileSystemLogging.WriteLogEntry(User-Defined.logLine)<Coaching Present Log Config>
      [✔] EnabledWrite Coaching Present Log
      1: Quota.Coaching.SessionExceeded<Uncategorized Configuration> equals false
      Stop Rule SetSet User-Defined.logLine =
           "Present(Uncat):" +
           DateTime.ToWebReporterString +
           " "" +
           Authentication.Realm +
           "\" +
           Authentication.UserName +
           "" " +
           String.ReplaceIfEquals(IP.ToString(Client.IP),"","-") +
           " " +
           String.ReplaceIfEquals(Number.ToString(Response.StatusCode),"","-") +
           " "" +
           Request.Header.FirstLine +
           "" " +
           """ +
           List.OfCategory.ToString(URL.Categories<Default>) +
           "" "" +
           String.ReplaceIfEquals(URL.ReputationString<Default>,"","-") +
           "" "" +
           MediaType.ToString(MediaType.FromHeader) +
           "" " +
           String.ReplaceIfEquals(Number.ToString(Body.Size),"","-") +
           " "" +
           Header.Get("User-Agent") +
           "" "" +
           Number.ToString(Block.ID) +
           "" "" +
           Cache.Status +
           "" "" +
           User-Defined.Geolocation +
           """
      FileSystemLogging.WriteLogEntry(User-Defined.logLine)<Coaching Access Log Config>
      [✔] EnabledBlock if Coaching Session Exceeded and Write Coaching Present Log
      1: Quota.Coaching.SessionExceeded<Uncategorized Configuration> equals true
      Block<ActionCoachingBlocked>Set User-Defined.logLine =
           "Access(Uncat):" +
           DateTime.ToWebReporterString +
           " "" +
           Authentication.Realm +
           "\" +
           Authentication.UserName +
           "" " +
           String.ReplaceIfEquals(IP.ToString(Client.IP),"","-") +
           " " +
           String.ReplaceIfEquals(Number.ToString(Response.StatusCode),"","-") +
           " "" +
           Request.Header.FirstLine +
           "" " +
           """ +
           List.OfCategory.ToString(URL.Categories<Default>) +
           "" "" +
           String.ReplaceIfEquals(URL.ReputationString<Default>,"","-") +
           "" "" +
           MediaType.ToString(MediaType.FromHeader) +
           "" " +
           String.ReplaceIfEquals(Number.ToString(Body.Size),"","-") +
           " "" +
           Header.Get("User-Agent") +
           "" "" +
           Number.ToString(Block.ID) +
           "" "" +
           Cache.Status +
           "" "" +
           User-Defined.Geolocation +
           """
      FileSystemLogging.WriteLogEntry(User-Defined.logLine)<Coaching Present Log Config>
      Coaching With IP Configuration
      [✘] Disabled [✘] Disabled in Cloud
      Applies to: [✔] Requests [✔] Responses [✔] Embedded Objects
      1: Client.IP is in list IP Blocklist for Coaching°
      2: OR Quota.Coaching.IsActivationRequest.Strict<IP Configuration> equals true
      EnabledRuleActionEventsComments
      [✔] EnabledRedirecting After Starting New Coaching Session
      1: Quota.Coaching.IsActivationRequest.Strict<IP Configuration> equals true
      Redirect<Redirection After Coaching Session Activation>This rule redirects the user back to the requested url after the user started a new session by pushing the button in the HTML Session template.
      [✔] EnabledCheck If Coaching Session Has Been Exceeded
      1: Quota.Coaching.SessionExceeded<IP Configuration> equals true
      Block<ActionCoachingBlocked>This rule shows a block html site for Coaching after the session for Coaching has been exceeded and the ip is in the ip blocklist.
      Coaching With Authenticated User Configuration
      [✘] Disabled [✘] Disabled in Cloud
      Applies to: [✔] Requests [✔] Responses [✔] Embedded Objects
      1: Authentication.RawUserName is in list User Blocklist for Coaching°
      2: OR Quota.Coaching.IsActivationRequest.Strict<Authenticated User Configuration> equals true
      EnabledRuleActionEventsComments
      [✔] EnabledRedirecting After Starting New Coaching Session
      1: Quota.Coaching.IsActivationRequest.Strict<Authenticated User Configuration> equals true
      Redirect<Redirection After Coaching Session Activation>This rule redirects the user back to the requested url after the user started a new session by pushing the button in the HTML Session template.
      [✔] EnabledCheck If Coaching Session Has Been Exceeded
      1: Authentication.UserName is in list User Blocklist for Coaching°
      2: AND Quota.Coaching.SessionExceeded<Authenticated User Configuration> equals true
      Block<ActionCoachingBlocked>This rule shows a block html site for Coaching after the Coaching session has been exceeded and one of the user is in the user blocklist.

       

      SSL Incident Log Handler Ruleset:

      Writes SSL Incident log on any SSL Incident

      Rule Sets
      SSL Incident
      [✔] Enabled [✘] Disabled in Cloud
      Applies to: [✔] Requests [✔] Responses [✔] Embedded Objects
      Always
      EnabledRuleActionEventsComments
      [✔] Enabled Write SSLIncident.log
      1: User-Defined.SSLIncident equals true
      ContinueSet User-Defined.logLine =
           DateTime.ToWebReporterString +
           " "" +
           Authentication.UserName +
           "" " +
           String.ReplaceIfEquals(IP.ToString(Client.IP),"","-") +
           " " +
           String.ReplaceIfEquals(Number.ToString(Response.StatusCode),"","-") +
           " "" +
           Request.Header.FirstLine +
           "" " +
           SSL.Server.Certificate.CN +
           " " +
           User-Defined.SSLCertReason +
           " SelfSigned=" +
           Boolean.ToString(SSL.Server.Certificate.SelfSigned) +
           " Expired=" +
           Boolean.ToString(SSL.Server.CertificateChain.ContainsExpiredCA<MostRecent>) +
           " "" +
           Header.Get("User-Agent") +
           "" "" +
           List.OfString.ToString(Antimalware.VirusNames<MostRecent>,", ") +
           "" " +
           Number.ToString(Block.ID)
      FileSystemLogging.WriteLogEntry(User-Defined.logLine)<SSL Incident Log>
        • 1. Re: Certificate Error Warnings with Logging
          btlyric

          Some quick feedback/comments...

           

          In general, if a certificate is self-signed, the issuing CA will be unknown and therefore, by definition, untrusted.

           

          Given a self-signed certificate, a log entry will be written for each reason until a block rule is reached. In other words, if the relevant rules before UntrustedCA have action = continue, then 3 log lines will be created: SelfSigned, UnknownCA and UntrustedCA. Alternately, if SelfSigned has action = block, then UnknownCA and UntrustedCA will never be logged.

           

          If the server certificate isn't self-signed, but the issuing CA is unknown, it will always be untrusted since it has to be known in order to be trusted. The previous log entry concept is also applicable.

          • 2. Re: Certificate Error Warnings with Logging
            jebeling

            Good points and feedback. The reason for continue rather than block in the verification ruleset is to allow coaching/warning of the end user. Unless I am mistaken, if you block during certificate verification, there is no opportunity to provide a warning with a click through option.

             

            The logging for Cert Verification only happens in the log handler so there will be only one entry per certverify, even if the action is continue. However depending on the rules that single entry will have either the last violation that was continued, or the one that had a block action.

            • 3. Re: Certificate Error Warnings with Logging
              btlyric

              Right-- using continue facilitates allowing a click-through after providing a warning to the client. (My comments are based on my experience with doing something very similar...)

               

              One thing that you could do is stack the CertReason data and then have a single logging rule that will fire if User-Defined.SSLIncident = true.

               

              Rule1: cert is self signed --> User-Defined.CertReason = "SelfSigned" / User-Defined.SSLIncident = true

              Rule2: cert has unknown CA --> User-Defined.CertReason = User-Defined.CertReason + "UnknownCA" / User-Defined.SSLIncident = true

              Rule3: cert has untrusted CA --> User-Defined.CertReason = User-Defined.CertReason + "UntrustedCA"/ User-Defined.SSLIncident = true

              Rule4: User-Defined.CertProblem = true -> write log line

               

              Some fiddling with the reason field will probably be necessary in order to make it so that you don't end up with a reason that looks like: "SelfSignedUnknownCAUntrustedCA"

               

              Something like this could work:

               

              Rule1: cert is self signed --> User-Defined.CertReason = "::SelfSigned" / User-Defined.SSLIncident = true

              Rule2: cert has unknown CA --> User-Defined.CertReason = User-Defined.CertReason + "::UnknownCA" / User-Defined.SSLIncident = true

              Rule3: cert has untrusted CA --> User-Defined.CertReason = User-Defined.CertReason + "::UntrustedCA"/ User-Defined.SSLIncident = true

              Rule4: User-Defined.SSLIncident = true -> write log line with CertReason::User-Defined.CertReason

               

              That would give you CertReason::SelfSigned::UnknownCA::UntrustedCA in the log line.

               

              Depending on an entity's user-base/business/focus, the number of self-signed and/or expired certificates on "mission-critical" websites may result in a need for a coaching implementation. Coaching multiple times for essentially the same reason annoys folks being coached...and doesn't necessarily behave well itself, so my recommendation would be to add up the reasons for the certificate problem and then present a single coaching page/option.

              • 4. Re: Certificate Error Warnings with Logging
                jebeling

                Excellent thoughts. Not sure when I'll get to it. My thinking was that you might want to have different timeouts for different types of cert errors, and I didn't think that it would be a good thing if a user was allowed to click through an expired cert, then they would also be allowed to access a common name mismatch, or self signed cert without prompt. Again, don't know when I'll have the opportunity to look at this further. The feedback is greatly appreciated.

                • 5. Re: Certificate Error Warnings with Logging
                  btlyric

                  I figure that even if you don't have time to look at this again in the near future, the info may be useful for others.

                   

                  I classified certificate errors into two groups with corresponding rule sets.

                   

                  - Group One: Never coach (revoked, for example)

                  - Various specific SSL inspection whitelisting rules

                  - Group Two: Offer coaching

                   

                  For the ones where coaching is offered, I use PDStorage to save the certificate hash value so that acknowledging the coaching for one site that has a self-signed [or other problem] certificate doesn't mean that coaching will be skipped if a different site with the same issue is subsequently encountered.

                   

                  Even places that should know better have expired certs. Example: https://eca-dsgw.orc.com/dsgw/bin/search?context=eca

                  • 6. Re: Certificate Error Warnings with Logging
                    jebeling

                    Thank you! Much appreciated.