Forum Discussion
Creating an iRule from external source using AS3
I am attempting to create a new iRule using AS3 by pointing to an external file and can't seem to get the declaration and/or rule correct. I am receiving the below error when trying as is. I have tried iterations of braces around each when clause and around the entire iRule, but can't seem to get the syntax right.
Anyone have any luck with this? If not, how are you declaring complex iRules within your AS3 declaration without having to manually escape all the json special characters?
Error:
{"message":"Declaration failed: 01070151:3: Rule [/Common/Shared/log4j_mitigation] error: /Common/Shared/log4j_mitigation:1: error: [braces are required around the expression][when HTTP_REQUEST {\n # Version 2.0 - 2021-12-11 23:40 Eastern\n # - Handling nested URI encoding\n # - Improved matching\n # Version 1.0 - 2021-12-11 06:10 Eastern\n # - Initial release\n # less aggressive regexp for those concerned about false positives \\\"\\\\$\\\\{(\\\\$\\\\{env:[^:]+:-|\\\\$\\\\{[a-z]+:)\\?j\\\\}\\?(\\\\$\\\\{env:[^:]+:-|\\\\$\\\\{[a-z]+:)\\?n.+:.+\\\\}\\\" (remove quotes)\n # very aggressive regexp \\\"\\\\$\\\\{.+\\?\\\\}\\\" (remove quotes)\n # URI – based on 200004474\n set tmpUri [HTTP::uri -normalized]\n set uri [URI::decode $tmpUri]\n while { $uri ne $tmpUri } {\n set tmpUri $uri\n set uri [URI::decode $tmpUri]\n }\n if {[string tolower $uri] matches_regex {\\\\$\\\\{}} {\n log local0. \\\"log4j_rce_detection drop on URI: $uri\\\"\n drop\n event disable all\n return\n }\n set tmpReq [HTTP::request]\n set req [URI::decode $tmpReq]\n while { $req ne $tmpReq } {\n set tmpReq $req\n set req [URI::de","level":"error"}
iRule:
when HTTP_REQUEST {
# Version 2.0 - 2021-12-11 23:40 Eastern
# - Handling nested URI encoding
# - Improved matching
# Version 1.0 - 2021-12-11 06:10 Eastern
# - Initial release
# less aggressive regexp for those concerned about false positives "\$\{(\$\{env:[^:]+:-|\$\{[a-z]+:)?j\}?(\$\{env:[^:]+:-|\$\{[a-z]+:)?n.+:.+\}" (remove quotes)
# very aggressive regexp "\$\{.+?\}" (remove quotes)
# URI – based on 200004474
set tmpUri [HTTP::uri -normalized]
set uri [URI::decode $tmpUri]
while { $uri ne $tmpUri } {
set tmpUri $uri
set uri [URI::decode $tmpUri]
}
if {[string tolower $uri] matches_regex {\$\{}} {
log local0. "log4j_rce_detection drop on URI: $uri"
drop
event disable all
return
}
set tmpReq [HTTP::request]
set req [URI::decode $tmpReq]
while { $req ne $tmpReq } {
set tmpReq $req
set req [URI::decode $tmpReq]
}
# Header – looks for ${j…} or ${${…}}
if {[string tolower $req] matches_regex {\$\{\s*(j|\$\{).+?\}}} {
log local0. "log4j_rce_detection drop on header: $req"
drop
event disable all
return
}
# Payload – looks for ${j…} or ${${…}}
if {[HTTP::method] eq "POST"}{
# Trigger collection for up to 1MB of data
if {[HTTP::header "Content-Length"] ne "" && [HTTP::header "Content-Length"] <= 1048576}{
set content_length [HTTP::header "Content-Length"]
} else {
set content_length 1048576
}
# Check if $content_length is not set to 0
if { $content_length > 0} {
HTTP::collect $content_length
}
}
}
when HTTP_REQUEST_DATA {
set tmpPayload [HTTP::payload]
set payload [URI::decode $tmpPayload]
while { $payload ne $tmpPayload } {
set tmpPayload $payload
set payload [URI::decode $tmpPayload]
}
if {[string tolower $payload] matches_regex {\$\{\s*(j|\$\{).+?\}}} {
log local0. "log4j_rce_detection drop on payload"
drop
event disable all
}
}
AS3 json:
{
"class": "AS3",
"action": "deploy",
"persist": true,
"declaration": {
"class": "ADC",
"schemaVersion": "3.0.0",
"id": "molecule_192.168.121.79_1642700459",
"label": "molecule_192.168.121.79_2022-01-20T17:40:59Z",
"remark": "DTI f5 as3 declaration for molecule_192.168.121.79",
"Common":{
"Shared": {
"class": "Application",
"log4j_mitigation": {
"class": "iRule",
"iRule": {
"url": {
"skipCertificateCheck": true,
"url": "https://xxxxxxx/Bradley.Anderson/irules_test/-/raw/main/log4j_mitigation.irule"
}
}
},
"template": "shared"
},
"class": "Tenant"
},"Molecule":{
"Molecule-API": {
"class": "Application",
"molecule_api": {
"class": "Service_HTTP",
"pool": "molecule_api_pool",
"virtualAddresses": [
"192.168.100.101"
]
},
"molecule_api_pool": {
"class": "Pool",
"members": [
{
"serverAddresses": [
"10.0.1.5",
"10.0.1.6"
],
"servicePort": 80
}
],
"monitors": [
"http"
]
}
},
"Molecule-Web": {
"class": "Application",
"molecule_web": {
"class": "Service_HTTP",
"pool": "molecule_web_pool",
"virtualAddresses": [
"192.168.100.100"
]
},
"molecule_web_pool": {
"class": "Pool",
"members": [
{
"serverAddresses": [
"10.0.1.3",
"10.0.1.4"
],
"servicePort": 80
}
],
"monitors": [
"http"
]
}
},
"class": "Tenant"
},"Foo":{
"Foo-Web": {
"class": "Application",
"foo_web": {
"class": "Service_HTTP",
"pool": "foo_web_pool",
"virtualAddresses": [
"192.168.100.102"
]
},
"foo_web_pool": {
"class": "Pool",
"members": [
{
"serverAddresses": [
"10.0.1.7",
"10.0.1.8"
],
"servicePort": 80
}
],
"monitors": [
"http"
]
}
},
"class": "Tenant"
}}
}
- Brad_AndersonNimbostratus
It was non-UTF-8 characters!
Why you want to do this as with Ansible Jinja2 templates AS3 is much easier or just Big IQ ?
https://support.f5.com/csp/article/K45530030
Also for triggering scripts this may help:
Recent Discussions
Related Content
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com