jcomeau_ictx

server_iptables.py

Feb 10th, 2014
165
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/usr/bin/python -OO
  2. '''
  3. set up iptables for typical server
  4.  
  5. make sure to edit /etc/services accordingly
  6. '''
  7. import sys, os, socket
  8. from subprocess import Popen, PIPE
  9. TCP_SERVICES = ['ssh', 'smtp', 'http', 'https', 'rootssh',
  10.  'lighttpd']
  11. UDP_SERVICES = ['domain', 'bootps', 'resolver', 'ntp']
  12. CRYPTO_COINS = ['americancoin', 'coinyecoin', 'bitcoin', 'dogecoin',
  13.  'betacoin', 'ppcoin', 'freicoin', 'nexuscoin']
  14. TCP_CLIENTS = ['ssh', 'http', 'https', 'whois', 'ircd'] + CRYPTO_COINS
  15. UDP_CLIENTS = ['domain', 'bootps', 'resolver', 'ntp', 'skype']
  16. ACCEPT_ALL_LOCAL = True  # if False, must enable cryptocoin RPC
  17. # be sure to also add _rpc entries for each, e.g. bitcoin_rpc in /etc/services
  18. def check_service(service_name):
  19.  try:
  20.   return socket.getservbyname(service_name)
  21.  except:
  22.   raise Exception('no such service "%s"' % service_name)
  23. def iptables(args):
  24.  command = ['iptables'] + args
  25.  pipeline = Popen(command, stdout = PIPE, stderr = PIPE)
  26.  result = pipeline.wait()
  27.  if result:
  28.   raise Exception('"%s" error: "%s"' % (' '.join(command),
  29.    pipeline.stderr.readlines()[-1].rstrip()))
  30. def accept_all_local():
  31.  iptables(['--append', 'INPUT', '--in-interface', 'lo', '--jump', 'ACCEPT'])
  32.  iptables(['--append', 'OUTPUT', '--out-interface', 'lo', '--jump', 'ACCEPT'])
  33. def accept_local_input(port, protocol = 'tcp'):
  34.  iptables(['--append', 'INPUT', '--in-interface', 'lo', '--protocol', protocol,
  35.   '--destination-port', port, '--jump', 'ACCEPT'])
  36. def accept_local_output(port, protocol = 'tcp'):
  37.  iptables(['--append', 'OUTPUT', '--out-interface', 'lo',
  38.   '--protocol', protocol, '--source-port', port, '--jump', 'ACCEPT'])
  39. def accept_local(port, protocol = 'tcp'):
  40.  accept_local_input(port, protocol)
  41.  accept_local_output(port, protocol)
  42. def accept_server_input(port, protocol = 'tcp'):
  43.  iptables(['--append', 'INPUT', '--protocol', protocol,
  44.   '--destination-port', port, '--jump', 'ACCEPT'])
  45. def accept_server_output(port, protocol = 'tcp'):
  46.  iptables(['--append', 'OUTPUT', '--protocol', protocol,
  47.   '--source-port', port, '--jump', 'ACCEPT'])
  48. def accept_client_input(port, protocol = 'tcp'):
  49.  iptables(['--append', 'INPUT', '--protocol', protocol,
  50.   '--source-port', port, '--jump', 'ACCEPT'])
  51. def accept_client_output(port, protocol = 'tcp'):
  52.  iptables(['--append', 'OUTPUT', '--protocol', protocol,
  53.   '--destination-port', port, '--jump', 'ACCEPT'])
  54. def accept_server_traffic(port, protocol = 'tcp'):
  55.  accept_server_input(port, protocol)
  56.  accept_server_output(port, protocol)
  57. def accept_client_traffic(port, protocol = 'tcp'):
  58.  accept_client_input(port, protocol)
  59.  accept_client_output(port, protocol)
  60. def init():
  61.  for service in TCP_SERVICES + CRYPTO_COINS:
  62.   check_service(service)
  63.  for service in CRYPTO_COINS:
  64.   service += '_rpc'
  65.   check_service(service)
  66.  init_firewall()
  67. def init_firewall():
  68.  'start from a clean but paranoid slate, dropping everything on the floor'
  69.  flush_firewall()
  70.  for chain in ['INPUT', 'OUTPUT', 'FORWARD']:
  71.   iptables(['--policy', chain, 'DROP'])
  72. def flush_firewall():
  73.  'flush built-in chains, delete non-builtins, and zero counters'
  74.  for initializer in ['--flush', '--delete-chain', '--zero']:
  75.   iptables([initializer])
  76. def reset_firewall():
  77.  'start from a clean slate, allowing all traffic'
  78.  flush_firewall
  79.  for chain in ['INPUT', 'OUTPUT', 'FORWARD']:
  80.   iptables(['--policy', chain, 'ACCEPT'])
  81. def firewall(*args):
  82.  '''
  83. set up firewall
  84.  
  85. if anything breaks, undo firewall so we aren't locked out
  86. '''
  87.  if os.geteuid() > 0:
  88.   print >>sys.stderr, 'Must be root (sudo may work)'
  89.   sys.exit(1)
  90.  if __debug__:
  91.   bad_command()
  92.  try:
  93.   init()
  94.   enable_some_inputs()
  95.   enable_some_outputs()
  96.   for service in TCP_SERVICES + CRYPTO_COINS:
  97.    accept_server_traffic(service)
  98.   for service in UDP_SERVICES:
  99.    accept_server_traffic(service, protocol = 'udp')
  100.   for client in TCP_CLIENTS:
  101.    accept_client_traffic(client)
  102.   for client in UDP_CLIENTS:
  103.    accept_client_traffic(client, protocol = 'udp')
  104.   if ACCEPT_ALL_LOCAL:
  105.    accept_all_local()
  106.   else:
  107.    for service in CRYPTO_COINS:
  108.     service += '_rpc'
  109.     accept_local(service)
  110.   block_unwanted_inputs()
  111.   block_unwanted_outputs()
  112.  except Exception, error:
  113.   reset_firewall()
  114.   raise error
  115. def bad_command():
  116.  'something that iptables will reject, as a test'
  117.  iptables(['not', 'understood'])
  118. def block_unwanted_inputs():
  119.  '''
  120. log and reject connection attempts and other questionable packets
  121.  
  122. null packets, pingflood, christmastree
  123. '''
  124.  iptables(['--append', 'INPUT', '--match', 'state', '!', '--state', 'NEW',
  125.   '--jump', 'LOG', '--log-prefix', 'unmatched INPUT '])
  126.  iptables(['--append', 'INPUT', '--match', 'state', '!', '--state', 'NEW',
  127.   '--jump', 'REJECT'])
  128.  iptables(['--append', 'INPUT', '--protocol', 'tcp', '--tcp-flags', 'ALL',
  129.   'NONE', '--jump', 'DROP'])  # null packets
  130.  iptables(['--append', 'INPUT', '--protocol', 'tcp', '--tcp-flags', 'ALL',
  131.   'ALL', '--jump', 'DROP'])  # christmastree
  132.  iptables(['--append', 'INPUT', '--protocol', 'tcp', '!', '--syn', '--match',
  133.   'state', '--state', 'NEW', '--jump', 'DROP'])  # pingflood
  134. def enable_some_inputs():
  135.  'allow established and other selected inputs'
  136.  iptables(['--append', 'INPUT', '--match', 'state', '--state',
  137.   'ESTABLISHED,RELATED', '--jump', 'ACCEPT'])
  138.  iptables(['--append', 'INPUT', '--protocol', 'icmp', '--match', 'icmp',
  139.   '--icmp-type', '8', '--jump', 'ACCEPT'])  # ping
  140. def enable_some_outputs():
  141.  iptables(['--append', 'OUTPUT', '--protocol', 'icmp', '--match', 'icmp',
  142.   '--icmp-type', '8', '--jump', 'ACCEPT'])  # ping requests
  143.  iptables(['--append', 'OUTPUT', '--protocol', 'icmp', '--match', 'icmp',
  144.   '--icmp-type', '3', '--jump', 'ACCEPT'])  # report errors
  145. def block_unwanted_outputs():
  146.  iptables(['--append', 'OUTPUT', '--jump', 'LOG',
  147.   '--log-prefix', 'unmatched OUTPUT '])
  148.  iptables(['--append', 'OUTPUT', '--jump', 'REJECT'])
  149.  iptables(['--append', 'FORWARD', '--jump', 'LOG',
  150.   '--log-prefix', 'unmatched FORWARD '])
  151.  iptables(['--append', 'FORWARD', '--jump', 'REJECT'])
  152. if __name__ == '__main__':
  153.  firewall(*sys.argv[1:])
RAW Paste Data

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×