waf_ip_update.py 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. """
  2. Update an AWS IP set with the the top 10 IP addresses from Apache logs
  3. """
  4. import sys
  5. import re
  6. import boto3
  7. from collections import Counter
  8. from tabulate import tabulate
  9. def get_top_n_ip_addresses(num):
  10. """
  11. Parses apache logs to find the top n X-Forwarded-For ip addresses
  12. """
  13. all_ip_addresses = []
  14. with open('/var/log/httpd/access_log') as content:
  15. for line in content:
  16. # the first "cell" surrounded with brackets is the X-Forwarded-For
  17. regex = re.search(r'\((.*?)\)', line)
  18. if regex:
  19. # format is X-Forwarded-For: client, proxy1, proxy2
  20. # we want the right most IP, the IP that hit cloudfront
  21. forwarded_for = re.findall(r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}', regex.group(0))
  22. if forwarded_for:
  23. all_ip_addresses.append(forwarded_for[-1])
  24. return Counter(all_ip_addresses).most_common(num)
  25. def main():
  26. """
  27. Grab top 10 X-Forwarded-For ip addresses and send to a WAF ip list
  28. """
  29. top_ip_addresses = get_top_n_ip_addresses(10)
  30. print
  31. print "Top 10 IP Addresses"
  32. print "==================="
  33. print
  34. print tabulate(top_ip_addresses, headers=["IP", "Count"])
  35. print
  36. updates_list = [{
  37. 'Action': 'INSERT',
  38. 'IPSetDescriptor': {
  39. 'Type': 'IPV4',
  40. 'Value': "%s/32" % ip[0]
  41. }
  42. } for ip in top_ip_addresses]
  43. waf = boto3.client('waf')
  44. waf_ip_sets = waf.list_ip_sets(
  45. Limit=100
  46. )['IPSets']
  47. if len(waf_ip_sets) < 1:
  48. sys.exit('WAF IP sets appear to be misconfigured. Expecting 1 IP set.')
  49. waf_ip_set_id = waf_ip_sets[0]['IPSetId']
  50. print "Updating IP set: ", waf_ip_sets[0]['Name']
  51. waf.update_ip_set(IPSetId=waf_ip_set_id,
  52. ChangeToken=waf.get_change_token()['ChangeToken'],
  53. Updates=updates_list)
  54. print "Done!"
  55. if __name__ == "__main__":
  56. main()