SSL Management
SSL:close()
Terminates the SSL/TLS connection during the handshake phase, allowing FortiWeb to enforce early-session security decisions based on SSL context. This function is particularly useful in scenarios where you need to prevent connections from proceeding beyond the SSL layer, such as when rejecting traffic based on the Server Name Indication (SNI) value or other handshake metadata before HTTP parsing or WAF processing occurs.
Internally, SSL:close() triggers a connection teardown by sending a TCP FIN or RST (depending on timing and state) without completing the handshake or generating application-level logs. Because the TLS handshake is aborted, this function minimizes resource usage and ensures the transaction is dropped silently from the client’s perspective.
This function can only be used in the CLIENTSSL_HANDSHAKE or SERVERSSL_HANDSHAKE script events, where SSL-specific inspection (e.g., SNI retrieval via SSL:sni()) is supported.
Syntax
SSL:close()
Availability
-
Events:
CLIENTSSL_HANDSHAKE,SERVERSSL_HANDSHAKE
Behavior
-
Terminates the SSL connection immediately, preventing further processing (including HTTP and WAF modules).
-
Can be combined with functions like
SSL:sni()to enforce domain-level access control. -
The connection is dropped silently without alerting the client (no TLS alerts or HTTP response).
Example: Block clients based on SNI
when CLIENTSSL_HANDSHAKE {
local svr_name = SSL:sni()
if svr_name == "www.blocked-site.com" then
SSL:close()
debug("Blocked connection with SNI: %s\n", svr_name)
end
}
Example: Block server-side handshake for specific domain
when SERVERSSL_HANDSHAKE {
local svr_name = SSL:sni()
if svr_name == "internal-only.example.com" then
SSL:close()
debug("Terminating server handshake for internal domain: %s\n", svr_name)
end
}
SSL_RENEGOTIATE()
When the system evaluates the command under a client-side context, the system immediately renegotiates a request for the associated client-side connection. This function is temporarily ONLY available in HTTP_REQUEST event.
Return true for success and false for failure.
Example
In this sample script, when an HTTPS request with the prefix "autotest" is received, it triggers client certificate verification through SSL renegotiation.
Once the SSL renegotiation is completed, it checks the content-routing policy.
If the client certificate presented by the client meets certain conditions that matches a specific HTTP content routing policy, the traffic will be directed to a designated server pool.
--
#a function to print a table, i represents the number of \t for formatting purpose.
function print_table(table, indent)
local space = string.rep('\t',indent)
for key, value in pairs(table) do
if(type(value)=='table') then
debug("%s sub-table[%s]\n", space, key)
print_table(value, indent+1)
else
debug("%s %s: %s\n", space, key, value)
end
end
end
when HTTP_REQUEST {
local url = HTTP:url()
if url:find("^/autotest") and HTTP:is_https() and SSL:client_cert_verify() then
-- Trigger SSL renegotiate only when it's https request and SSL connection has already been established
-- Example URL-based certificate verify and then Content-Routing
debug("url: %s match rule, need client certificate verify\n", url)
local cert_count = SSL:cert_count()
debug("cert_count = %s\n", cert_count)
if cert_count and cert_count == 0 then
SSL:renegotiate()
debug("emit SSL renegotiation\n")
end
end
}
when CLIENTSSL_RENEGOTIATE {
local cert_count = SSL:cert_count()
debug("cert_count = %s\n", cert_count)
if cert_count and cert_count > 0 then
local cert_table = SSL:get_peer_cert_by_idx(0)
print_table(cert_table, 0)
local subject = cert_table["subject"]
-- match CN value with regular expression
local cn_value = subject:match("CN%s-=%s-([^,%s]+)")
debug("CN value in X509 subject is: %s\n", cn_value)
if cn_value and cn_value == "test1" then
LB:routing("ctrt")
end
end
}