Advertisement
banbooo

Untitled

May 5th, 2020
501
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 14.03 KB | None | 0 0
  1. from firewall import *
  2. import os
  3. import subprocess
  4. import sys
  5.  
  6. from netfilter.rule import Rule,Match,Target
  7. import netfilter.table
  8.  
  9. def main():
  10.     ########################################
  11.     # Test
  12.     ########################################
  13.     test = Firewall()
  14.     test.flush()
  15.     test.policy()
  16.     test.policy(test.INPUT,test.DROP)
  17.     test.chain('INPUT').accept()
  18.     test.interface('-i',"eth0").accept('# error test')
  19.     test.chain('INPUT').interface('-i',"eth0").accept('# ok test')
  20.     test.chain('OUTPUT').interface('-o',"eth0").protocol('icmp').accept()
  21.     test.output().interface('-i',"eth0").protocol('tcp').accept('')
  22.     test.chain('OUTPUT').inbound("eth0").protocol('tcp').source('172.16.1.0/24').accept('')
  23.     test.chain('OUTPUT').outbound("eth0").protocol('tcp').destination('172.16.1.1').accept('')
  24.     test.chain('FORWARD').inbound("eth0").outbound("eth0").protocol('tcp').source('172.16.1.0/24').destination('172.16.1.1').accept()
  25.     test.input().interface('-i',"eth0").protocol('tcp').state('NEW').accept()
  26.     test.chain('INPUT').interface('-i',"eth0").protocol('tcp').state('NEW').dport('21').accept()
  27.     test.chain('INPUT').inbound("eth0").protocol('tcp').state('NEW').dport(('3306','1152','5432')).accept('multiport test')
  28.  
  29.     test.forward().source("172.16.0.1/24").protocol('tcp').string('sex').accept()
  30.     test.forward().dport("53").protocol('udp').time('8:00','18:00','Mon,Tue,Wed,Thu,Fri,Sat').accept()
  31.     test.forward().proto('udp').dport("53").string('movie').time('8:00','18:00','Mon,Tue,Wed,Thu,Fri,Sat').accept()
  32.     test.input().inbound('ppp0').connlimit(20).drop()
  33.     test.forward().reject('--reject-with icmp-host-prohibited')
  34.  
  35.     test.show()
  36.     #test.save('/tmp/firewall.txt')
  37.     print()
  38.  
  39.     ########################################
  40.     # Demo Desktop PC
  41.     ########################################
  42.     single = Firewall()
  43.     single.policy(single.INPUT,single.DROP)
  44.     single.policy(single.OUTPUT,single.ACCEPT)
  45.     single.policy(single.FORWARD,single.DROP)
  46.     single.input().protocol('icmp').drop()
  47.     single.input().protocol('tcp').dport(('3389','5900')).accept()
  48.     single.input().protocol('tcp').dport(('137','138','139','145')).accept()
  49.     single.show()
  50.     #single.run()
  51.     #single.list()
  52.     print()
  53.  
  54.     ########################################
  55.     # Demo Office Server
  56.     ########################################
  57.     office = Firewall()
  58.     office.flush()
  59.     office.policy(office.INPUT,office.DROP)
  60.     office.policy(office.OUTPUT,office.ACCEPT)
  61.     office.policy(office.FORWARD,office.DROP)
  62.     office.input().state(('RELATED','ESTABLISHED')).accept()
  63.     office.input().protocol('icmp').accept()
  64.     office.input().inbound('eth0').protocol('udp').dport(('53','1194')).accept()
  65.     office.input().inbound('eth0').protocol('udp').dport(('68','68')).accept()
  66.     office.input().protocol('tcp').dport(('20','21','22','80')).accept()
  67.     office.input().protocol('tcp').dport(('5800','5900')).accept()
  68.     office.input().protocol('tcp').dport(('137','138','139','145')).accept()
  69.  
  70.     office.show()
  71.     #office.run()
  72.     #office.list()
  73.     print()
  74.    
  75.     ########################################
  76.     # Demo IDC Server
  77.     ########################################
  78.     server = Firewall()
  79.     server.flush()
  80.     server.policy(server.INPUT,server.DROP)
  81.     server.policy(server.OUTPUT,server.DROP)
  82.     server.policy(server.FORWARD,server.DROP)
  83.     server.input().state(('RELATED','ESTABLISHED')).accept()
  84.     server.input().protocol('icmp').accept()
  85.     #server.input().destination('192.168.0.0/24').accept()
  86.     server.input().protocol('tcp').dport(('21','22','80')).state('NEW').accept()
  87.     server.input().protocol('udp').dport(('53','1194')).accept()
  88.     server.input().protocol('tcp').source('172.16.1.0/24').dport('3306').accept()
  89.     server.output().protocol('icmp').accept()
  90.     server.output().destination('192.168.0.0/24').accept()
  91.     server.output().destination('172.16.0.5').reject()
  92.     server.output().destination('172.16.0.0/24').accept()
  93.     server.output().protocol('udp').dport('53').accept()
  94.     server.output().protocol('tcp').dport(('80','21','20','22','8000')).accept()
  95.     server.chain('PREROUTING').inbound('eth0').proto('tcp').dport('80').dnat('--to-destination 192.168.0.1:3128')
  96.     server.output().destination('172.16.0.10').proto('tcp').dport('3306').accept()
  97.     #server.show()
  98.     #server.run()
  99.     #server.list()
  100.     print()
  101.  
  102.     www = Firewall()
  103.     #www.flush()
  104.     www.policy(www.INPUT,www.ACCEPT)
  105.     www.policy(www.OUTPUT,www.ACCEPT)
  106.     www.policy(www.FORWARD,www.DROP)
  107.     www.input().state(('RELATED','ESTABLISHED')).accept()
  108.     www.input().protocol('icmp').accept()
  109.     www.input().source('172.16.1.0/24').accept()
  110.     www.input().protocol('tcp').dport(('21','22','80')).state('NEW').accept()
  111.     www.input().protocol('udp').source('113.106.63.1').dport(('53','1194')).accept()
  112.     www.input().protocol('tcp').source('172.16.1.0/24').dport('22').recent('SSH',60,5).reject('--reject-with tcp-reset')
  113.     www.output().protocol('icmp').accept()
  114.     www.output().protocol('tcp').accept()
  115.     www.output().destination('172.16.1.0/24').accept()
  116.     www.output().destination('172.16.3.0/24').reject()
  117.     www.output().destination('172.16.1.5').proto('tcp').dport('3306').accept()
  118.     #www.output().destination('172.16.1.5').accept()
  119.     www.output().protocol('udp').dport('53').accept()
  120.     www.output().protocol('tcp').dport(('80','3306')).accept()
  121.     www.output().protocol('tcp').dport('2049').reject()
  122.     www.output().protocol('tcp').dport('22').reject()
  123.     www.output().protocol('tcp').dport(('20','21')).reject()
  124.     www.chain('PREROUTING').inbound('eth0').proto('tcp').dport('80').dnat('--to-destination 192.168.0.1:3128')
  125.     # HTTP CC 攻击
  126.     www.input().protocol('tcp').inbound('eth0').dport('80').recent('HTTP',2,20).drop()
  127.     www.input().protocol('tcp').inbound('eth0').dport('80').connlimit(30).drop()
  128.     www.input().protocol('tcp').inbound('eth0').dport('80').recent('HTTP').accept()
  129.     # DDOS
  130.     www.input().proto('tcp').dport("80").string('XXDD0S').drop()
  131.     www.show()
  132.     #server.run()
  133.     #server.list()
  134.     print()
  135.    
  136.     """
  137.     #iptables -A INPUT -p tcp --dport 80 -m recent --name CC --update --seconds 2 --hitcount 20 -j DROP
  138.     #iptables -A INPUT -p tcp --dport 80 -m connlimit --connlimit-above 30 -j DROP
  139.     #iptables -A INPUT -p tcp --dport 80 -m recent --name CC --set -j ACCEPT
  140.     """
  141.     db = Firewall()
  142.     db.flush()
  143.     db.policy(db.INPUT,db.DROP)
  144.     db.policy(db.OUTPUT,db.DROP)
  145.     db.policy(db.FORWARD,db.DROP)
  146.     db.input().state(('RELATED','ESTABLISHED')).accept()
  147.     db.input().protocol('icmp').accept()
  148.     db.input().protocol('tcp').source('172.16.1.10').dport('22').state('NEW').accept()
  149.     db.input().protocol('tcp').source('172.16.1.0/24').dport('3306').state('NEW').accept()
  150.     db.output().protocol('icmp').accept()
  151.     db.output().protocol('udp').dport('53').accept()
  152.     db.output().destination('172.16.1.0/24').accept()
  153.     db.output().destination('172.16.3.0/24').reject()
  154.     db.output().destination('172.16.1.5').proto('tcp').dport('3306').accept()
  155.     db.output().destination('172.16.1.6').proto('tcp').dport('3306').accept()
  156.     db.show()
  157.     #server.run()
  158.     #server.list()
  159.     print()
  160.  
  161.     ########################################
  162.     # Linux Gateway via pppoe
  163.     ########################################
  164.     gateway = Firewall()
  165.     gateway.input().drop()
  166.     gateway.output().accept()
  167.     gateway.inside().state(('RELATED','ESTABLISHED')).accept('# match test')
  168.     gateway.forward().destination('127.16.0.0/24').accept()
  169.     gateway.chain('POSTROUTING').inbound("ppp0").source('172.16.0.0/24').masquerade()
  170.     gateway.show()
  171.     print()
  172.  
  173.     ########################################
  174.     # Cisco ASA Style
  175.     ########################################
  176.     gateway = Firewall()
  177.     gateway.inside().accept()
  178.     gateway.inside().state(('RELATED','ESTABLISHED')).accept('# match test')
  179.     gateway.outside().drop()
  180.     gateway.show()
  181.     print()
  182.  
  183.     ########################################
  184.     # Juniper JunOS Style
  185.     ########################################
  186.     gateway = Firewall()
  187.     gateway.trust().accept()
  188.     gateway.untrust().drop()
  189.     gateway.show()
  190.     print()
  191.    
  192.     return( 0 )
  193.  
  194. if __name__ == '__main__':
  195.     main()
  196.  
  197.  
  198. class Firewall:
  199.     """The Firewall class represents a simple netfilter-based firewall.
  200.    It support 'start', 'stop' and 'restart' operations.
  201.    WARNING: THIS API IS NOT FROZEN!
  202.    """
  203.     def __init__(self, auto_commit = True, ipv6 = False):
  204.         self.filter = netfilter.table.Table(
  205.             name='filter',
  206.             auto_commit=auto_commit,
  207.             ipv6=ipv6)
  208.         self.__ipv6 = ipv6
  209.         self.__tables = [ self.filter ]
  210.         if not ipv6:
  211.             self.nat = netfilter.table.Table(
  212.                 name='nat',
  213.                 auto_commit=auto_commit,
  214.                 ipv6=ipv6)
  215.             self.__tables.append(self.nat)
  216.      
  217.     def clear(self):
  218.         """Clear tables."""
  219.         for table in self.__tables:
  220.             table.flush_chain()
  221.             table.delete_chain()
  222.        
  223.     def commit(self):
  224.         """Commit changes to the tables."""
  225.         for table in self.__tables:
  226.             table.commit()
  227.    
  228.     def get_buffer(self):
  229.         """Get the change buffers."""
  230.         buffer = []
  231.         for table in self.__tables:
  232.             buffer.extend(table.get_buffer())
  233.         return buffer
  234.    
  235.     def run(self, args):
  236.         """
  237.        Process command line arguments and run the given command command
  238.        (start, stop, restart).
  239.        """
  240.         prog = args[0]
  241.         if len(args) < 2:
  242.             self.usage(prog)
  243.             return 1
  244.  
  245.         command = args[1]
  246.         if command == "start":
  247.             self.start()
  248.         elif command == "stop":
  249.             self.stop()
  250.         elif command == "restart":
  251.             self.stop()
  252.             self.start()
  253.         else:
  254.             self.usage(prog)
  255.             return 1
  256.         return 0
  257.    
  258.     def start(self):
  259.         """Start the firewall."""
  260.         self.clear()
  261.         self.setDefaultPolicy()
  262.         self.acceptIcmp()
  263.         self.acceptInput('lo')
  264.    
  265.     def stop(self):
  266.         """Stop the firewall."""
  267.         self.clear()
  268.         self.setOpenPolicy()
  269.    
  270.     def usage(self, prog):
  271.         """Print program usage."""
  272.         sys.stderr.write("Usage: %s {start|stop|restart}\n" % prog)
  273.  
  274.     def acceptForward(self, in_interface=None, out_interface=None):
  275.         self.printMessage("allow FORWARD", in_interface)
  276.         self.filter.append_rule('FORWARD', Rule(
  277.             in_interface=in_interface,
  278.             out_interface=out_interface,
  279.             jump='ACCEPT'))
  280.  
  281.     def acceptIcmp(self, interface=None):
  282.         self.printMessage("allow selected icmp INPUT", interface)
  283.         if self.__ipv6:
  284.             self.filter.append_rule('INPUT', Rule(
  285.                 in_interface=interface,
  286.                 protocol='icmpv6',
  287.                 jump='ACCEPT'))
  288.         else:
  289.             types = ['echo-request',
  290.                 'network-unreachable',
  291.                 'host-unreachable',
  292.                 'port-unreachable',
  293.                 'fragmentation-needed',
  294.                 'time-exceeded']
  295.  
  296.             for type in types:
  297.                 self.filter.append_rule('INPUT', Rule(
  298.                     in_interface=interface,
  299.                     protocol='icmp',
  300.                     matches=[Match('icmp', "--icmp-type %s" % (type))],
  301.                     jump='ACCEPT'))
  302.  
  303.     def acceptInput(self, interface=None):
  304.         self.printMessage("allow INPUT", interface)
  305.         self.filter.append_rule('INPUT', Rule(
  306.             in_interface=interface,
  307.             jump='ACCEPT'))
  308.  
  309.     def acceptProtocol(self, interface, protocol, ports, destination=None, source=None):
  310.         port_str = ','.join(ports)
  311.         self.printMessage("allow selected %s INPUT (ports: %s)" % (protocol, port_str), interface)
  312.         self.filter.append_rule('INPUT', Rule(
  313.             in_interface=interface,
  314.             destination=destination,
  315.             source=source,
  316.             protocol=protocol,
  317.             matches=[Match('state', '--state NEW'),
  318.                 Match('multiport', "--destination-port %s" % port_str)],
  319.             jump='ACCEPT'))
  320.  
  321.     def getNode(self):
  322.         p = subprocess.Popen(["uname", "-n"],
  323.             stdout=subprocess.PIPE,
  324.             stderr=subprocess.PIPE,
  325.             close_fds=True)
  326.         out, err = p.communicate()
  327.         status = p.wait()
  328.         # check exit status
  329.         if not os.WIFEXITED(status) or os.WEXITSTATUS(status):
  330.             raise Exception("uname failed : %s" % ''.join(err))
  331.         node = out.strip()
  332.         return node
  333.  
  334.     def printMessage(self, msg, interface=None):
  335.         if self.__ipv6:
  336.             version = 'IPv6'
  337.         else:
  338.             version = 'IPv4'
  339.         if interface:
  340.             prefix = "interface %s" % interface
  341.         else:
  342.             prefix = "global"
  343.         sys.stderr.write(" * %s %s: %s\n" % (version, prefix, msg))
  344.  
  345.     def redirectHttp(self, interface, proxy_port):
  346.         if self.__ipv6: return
  347.         self.printMessage("redirect HTTP to port %s" % proxy_port, interface)
  348.         self.nat.append_rule('PREROUTING', Rule(
  349.             in_interface=interface,
  350.             protocol='tcp',
  351.             matches=[Match('tcp', '--dport 80')],
  352.             jump=Target('REDIRECT', '--to-port %s' % proxy_port)))
  353.    
  354.     def setDefaultPolicy(self):
  355.         self.printMessage("set default policy", None)
  356.         self.filter.set_policy('INPUT', 'DROP')
  357.         self.filter.append_rule('INPUT', Rule(
  358.             matches=[Match('state', '--state ESTABLISHED,RELATED')],
  359.             jump='ACCEPT'))
  360.         self.filter.set_policy('OUTPUT', 'ACCEPT')
  361.         self.filter.set_policy('FORWARD', 'DROP')
  362.         self.filter.append_rule('FORWARD', Rule(
  363.             matches=[Match('state', '--state ESTABLISHED,RELATED')],
  364.             jump='ACCEPT'))
  365.    
  366.     def setOpenPolicy(self):
  367.         self.printMessage("set open policy", None)
  368.         self.filter.set_policy('INPUT', 'ACCEPT')
  369.         self.filter.set_policy('OUTPUT', 'ACCEPT')
  370.         self.filter.set_policy('FORWARD', 'ACCEPT')
  371.    
  372.     def sourceNAT(self, interface):
  373.         if self.__ipv6: return
  374.         self.printMessage("enable SNAT", interface)
  375.         self.nat.append_rule('POSTROUTING', Rule(
  376.             out_interface=interface,
  377.             jump='MASQUERADE'))
  378.  
  379. if __name__ == "__main__":
  380.     sys.exit(Firewall().run(sys.argv))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement