|
|
@@ -0,0 +1,68 @@
|
|
|
+"""
|
|
|
+Update an AWS IP set with the the top 10 IP addresses from Apache logs
|
|
|
+"""
|
|
|
+import sys
|
|
|
+import re
|
|
|
+import boto3
|
|
|
+from collections import Counter
|
|
|
+from tabulate import tabulate
|
|
|
+
|
|
|
+def get_top_n_ip_addresses(num):
|
|
|
+ """
|
|
|
+ Parses apache logs to find the top n X-Forwarded-For ip addresses
|
|
|
+ """
|
|
|
+ all_ip_addresses = []
|
|
|
+
|
|
|
+ with open('/var/log/httpd/access_log') as content:
|
|
|
+ for line in content:
|
|
|
+ # the first "cell" surrounded with brackets is the X-Forwarded-For
|
|
|
+ regex = re.search(r'\((.*?)\)', line)
|
|
|
+ if regex:
|
|
|
+ # format is X-Forwarded-For: client, proxy1, proxy2
|
|
|
+ # we want the right most IP, the IP that hit cloudfront
|
|
|
+ forwarded_for = re.findall(r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}', regex.group(0))
|
|
|
+ if forwarded_for:
|
|
|
+ all_ip_addresses.append(forwarded_for[-1])
|
|
|
+
|
|
|
+ return Counter(all_ip_addresses).most_common(num)
|
|
|
+
|
|
|
+def main():
|
|
|
+ """
|
|
|
+ Grab top 10 X-Forwarded-For ip addresses and send to a WAF ip list
|
|
|
+ """
|
|
|
+ top_ip_addresses = get_top_n_ip_addresses(10)
|
|
|
+
|
|
|
+ print
|
|
|
+ print "Top 10 IP Addresses"
|
|
|
+ print "==================="
|
|
|
+ print
|
|
|
+ print tabulate(top_ip_addresses, headers=["IP", "Count"])
|
|
|
+ print
|
|
|
+
|
|
|
+ updates_list = [{
|
|
|
+ 'Action': 'INSERT',
|
|
|
+ 'IPSetDescriptor': {
|
|
|
+ 'Type': 'IPV4',
|
|
|
+ 'Value': "%s/32" % ip[0]
|
|
|
+ }
|
|
|
+ } for ip in top_ip_addresses]
|
|
|
+
|
|
|
+ waf = boto3.client('waf')
|
|
|
+ waf_ip_sets = waf.list_ip_sets(
|
|
|
+ Limit=100
|
|
|
+ )['IPSets']
|
|
|
+
|
|
|
+ if len(waf_ip_sets) < 1:
|
|
|
+ sys.exit('WAF IP sets appear to be misconfigured. Expecting 1 IP set.')
|
|
|
+
|
|
|
+ waf_ip_set_id = waf_ip_sets[0]['IPSetId']
|
|
|
+ print "Updating IP set: ", waf_ip_sets[0]['Name']
|
|
|
+
|
|
|
+ waf.update_ip_set(IPSetId=waf_ip_set_id,
|
|
|
+ ChangeToken=waf.get_change_token()['ChangeToken'],
|
|
|
+ Updates=updates_list)
|
|
|
+
|
|
|
+ print "Done!"
|
|
|
+
|
|
|
+if __name__ == "__main__":
|
|
|
+ main()
|