# Write the header
self.write_header(f)
- args = {
- "name" : self.list,
- "list" : self.list.slug,
- }
-
# XXX Maybe we should look into having different priority for different lists.
# For example, blocking some advertising has a lower priority than accessing
# a malware/phishing domain.
- rules = (
+ rules = {
# DNS
- (
- "alert dns any any -> any any ("
- " msg:\"IPFire DNSBL [%(name)s] Blocked DNS Query\";"
- " dns.query; "
- " domain; "
- " dataset:isset,%(list)s,type string,load datasets/%(list)s.txt;"
- " classtype:policy-violation;"
- " priority:3;"
- " sid:1;"
- " rev:1;"
- " reference:url,https://www.ipfire.org/dnsbl/%(list)s;"
- " metadata:dnsbl %(list)s.dnsbl.ipfire.org;"
- ")\n"
- ),
+ "dns" : {
+ "msg" : "\"IPFire DNSBL [%s] Blocked DNS Query\"" % self.list,
+ "dns.query" : None,
+ "domain" : None,
+ "dataset" : (
+ "isset",
+ self.list.slug,
+ "type string",
+ "load datasets/%s.txt" % self.list.slug,
+ ),
+ "classtype" : "policy-violation",
+ "priority" : "3",
+ "sid" : "1",
+ "rev" : "1",
+ "reference" : (
+ "url",
+ "https://www.ipfire.org/dnsbl/%s" % self.list.slug,
+ ),
+ "metadata" : {
+ "dnsbl" : "%s.dnsbl.ipfire.org" % self.list.slug,
+ },
+ },
# HTTP
- (
- "alert http any any -> any any ("
- " msg:\"IPFire DNSBL [%(name)s] Blocked HTTP Request\";"
- " http.host;"
- " domain;"
- " dataset:isset,%(list)s,type string,load datasets/%(list)s.txt;"
- " classtype:policy-violation;"
- " priority:3;"
- " sid:2;"
- " rev:1;"
- " reference:url,https://www.ipfire.org/dnsbl/%(list)s;"
- " metadata:dnsbl %(list)s.dnsbl.ipfire.org;"
- ")\n"
- ),
+ "http" : {
+ "msg" : "\"IPFire DNSBL [%s] Blocked HTTP Request\"" % self.list,
+ "http.host" : None,
+ "domain" : None,
+ "dataset" : (
+ "isset",
+ self.list.slug,
+ "type string",
+ "load datasets/%s.txt" % self.list.slug,
+ ),
+ "classtype" : "policy-violation",
+ "priority" : "3",
+ "sid" : "1",
+ "rev" : "1",
+ "reference" : (
+ "url",
+ "https://www.ipfire.org/dnsbl/%s" % self.list.slug,
+ ),
+ "metadata" : {
+ "dnsbl" : "%s.dnsbl.ipfire.org" % self.list.slug,
+ },
+ },
# TLS
- (
- "alert tls any any -> any any ("
- " msg:\"IPFire DNSBL [%(name)s] Blocked TLS SNI\";"
- " tls.sni;"
- " domain; "
- " dataset:isset,%(list)s,type string,load datasets/%(list)s.txt;"
- " classtype:policy-violation;"
- " priority:3;"
- " sid:3;"
- " rev:1;"
- " reference:url,https://www.ipfire.org/dnsbl/%(list)s;"
- " metadata:dnsbl %(list)s.dnsbl.ipfire.org;"
- ")\n"
- ),
+ "tls" : {
+ "msg" : "\"IPFire DNSBL [%s] Blocked TLS Connection\"" % self.list,
+ "tls.sni" : None,
+ "domain" : None,
+ "dataset" : (
+ "isset",
+ self.list.slug,
+ "type string",
+ "load datasets/%s.txt" % self.list.slug,
+ ),
+ "classtype" : "policy-violation",
+ "priority" : "3",
+ "sid" : "1",
+ "rev" : "1",
+ "reference" : (
+ "url",
+ "https://www.ipfire.org/dnsbl/%s" % self.list.slug,
+ ),
+ "metadata" : {
+ "dnsbl" : "%s.dnsbl.ipfire.org" % self.list.slug,
+ },
+ },
# QUIC
- (
- "alert quic any any -> any any ("
- " msg:\"IPFire DNSBL [%(name)s] Blocked QUIC SNI\";"
- " quic.sni;"
- " domain; "
- " dataset:isset,%(list)s,type string,load datasets/%(list)s.txt;"
- " classtype:policy-violation;"
- " priority:3;"
- " sid:4;"
- " rev:1;"
- " reference:url,https://www.ipfire.org/dnsbl/%(list)s;"
- " metadata:dnsbl %(list)s.dnsbl.ipfire.org;"
- ")\n"
- ),
- )
+ "quic" : {
+ "msg" : "\"IPFire DNSBL [%s] Blocked QUIC Connection\"" % self.list,
+ "quic.sni" : None,
+ "domain" : None,
+ "dataset" : (
+ "isset",
+ self.list.slug,
+ "type string",
+ "load datasets/%s.txt" % self.list.slug,
+ ),
+ "classtype" : "policy-violation",
+ "priority" : "3",
+ "sid" : "1",
+ "rev" : "1",
+ "reference" : (
+ "url",
+ "https://www.ipfire.org/dnsbl/%s" % self.list.slug,
+ ),
+ "metadata" : {
+ "dnsbl" : "%s.dnsbl.ipfire.org" % self.list.slug,
+ },
+ },
+ }
# Write all rules
- for rule in rules:
- f.write(rule % args)
+ for engine, attrs in rules.items():
+ rule = []
+
+ for attr, value in attrs.items():
+ # Attributes without a value go on their own
+ if value is None:
+ rule.append(attr)
+
+ # Join values in a tuple together
+ elif type(value) == tuple:
+ rule.append("%s:%s" % (attr, ",".join(value)))
+
+ # Join values in a dict together
+ elif type(value) == dict:
+ value = ",".join((
+ "%s %s" % (key, value[key]) for key in value
+ ))
+ rule.append("%s:%s" % (attr, value))
+
+ # Pass anything else on as it is
+ else:
+ rule.append("%s:%s" % (attr, value))
+
+ f.write("alert %s any any -> any any (%s)\n" % (engine, "; ".join(rule)))
class SuricataDatasetExporter(TextExporter):