From 29bbf837b960205d0a1c7f9bbea59091d3142fe1 Mon Sep 17 00:00:00 2001 From: Kálmán Viktor <viktorvector@gmail.com> Date: Thu, 4 Jul 2013 12:34:48 +0200 Subject: [PATCH] firewall: fixing trivial pep8 errors --- firewall/admin.py | 44 ++++++++++++++++++++++++++++---------------- firewall/fields.py | 18 ++++++++++++++++-- firewall/fw.py | 201 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------------------------------------------------------------------------------------- firewall/models.py | 18 +++++++++++------- firewall/tasks.py | 12 +++++++++--- firewall/views.py | 51 +++++++++++++++++++++++++++++---------------------- 6 files changed, 191 insertions(+), 153 deletions(-) diff --git a/firewall/admin.py b/firewall/admin.py index 448f619..c1b9dd6 100644 --- a/firewall/admin.py +++ b/firewall/admin.py @@ -1,19 +1,23 @@ # -*- coding: utf8 -*- from django.contrib import admin -from firewall.models import * +from firewall.models import (Rule, Host, Vlan, Group, VlanGroup, Firewall, + Domain, Record, Blacklist) from django import contrib class RuleInline(contrib.admin.TabularInline): model = Rule + class RecordInline(contrib.admin.TabularInline): model = Record + class HostAdmin(admin.ModelAdmin): list_display = ('hostname', 'vlan', 'ipv4', 'ipv6', 'pub_ipv4', 'mac', - 'shared_ip', 'owner', 'description', 'reverse', 'list_groups') + 'shared_ip', 'owner', 'description', 'reverse', + 'list_groups') ordering = ('hostname', ) list_filter = ('owner', 'vlan', 'groups') search_fields = ('hostname', 'description', 'ipv4', 'ipv6', 'mac') @@ -26,42 +30,46 @@ class HostAdmin(admin.ModelAdmin): names = [group.name for group in instance.groups.all()] return u', '.join(names) + class HostInline(contrib.admin.TabularInline): model = Host fields = ('hostname', 'ipv4', 'ipv6', 'pub_ipv4', 'mac', 'shared_ip', - 'owner', 'reverse') + 'owner', 'reverse') + class VlanAdmin(admin.ModelAdmin): list_display = ('vid', 'name', 'ipv4', 'net_ipv4', 'ipv6', 'net_ipv6', - 'description', 'domain', 'snat_ip', ) + 'description', 'domain', 'snat_ip', ) ordering = ('vid', ) inlines = (RuleInline, ) + class RuleAdmin(admin.ModelAdmin): list_display = ('r_type', 'color_desc', 'owner', 'extra', 'direction', - 'accept', 'proto', 'sport', 'dport', 'nat', 'nat_dport', 'used_in') + 'accept', 'proto', 'sport', 'dport', 'nat', + 'nat_dport', 'used_in') list_filter = ('r_type', 'vlan', 'owner', 'direction', 'accept', - 'proto', 'nat') + 'proto', 'nat') def color_desc(self, instance): """Returns a colorful description of the instance.""" return (u'<span style="color: #FF0000;">[%(type)s]</span> ' u'%(src)s<span style="color: #0000FF;"> ▸ </span>%(dst)s ' u'%(para)s %(desc)s') % { - 'type': instance.r_type, - 'src': (instance.foreign_network.name - if instance.direction == '1' else instance.r_type), - 'dst': (instance.r_type if instance.direction == '1' - else instance.foreign_network.name), - 'para': (u'<span style="color: #00FF00;">' + + 'type': instance.r_type, + 'src': (instance.foreign_network.name + if instance.direction == '1' else instance.r_type), + 'dst': (instance.r_type if instance.direction == '1' + else instance.foreign_network.name), + 'para': (u'<span style="color: #00FF00;">' + (('proto=%s ' % instance.proto) if instance.proto else '') + (('sport=%s ' % instance.sport) if instance.sport else '') + (('dport=%s ' % instance.dport) if instance.dport else '') + - '</span>'), - 'desc': instance.description} + '</span>'), + 'desc': instance.description} color_desc.allow_tags = True @staticmethod @@ -73,7 +81,7 @@ class RuleAdmin(admin.ModelAdmin): @staticmethod def used_in(instance): for field in [instance.vlan, instance.vlangroup, instance.host, - instance.hostgroup, instance.firewall]: + instance.hostgroup, instance.firewall]: if field: return unicode(field) + ' ' + field._meta.object_name @@ -81,16 +89,20 @@ class RuleAdmin(admin.ModelAdmin): class AliasAdmin(admin.ModelAdmin): list_display = ('alias', 'host') + class GroupAdmin(admin.ModelAdmin): list_display = ('name', 'owner', 'description') inlines = (RuleInline, ) + class FirewallAdmin(admin.ModelAdmin): inlines = (RuleInline, ) + class DomainAdmin(admin.ModelAdmin): list_display = ('name', 'owner') + class RecordAdmin(admin.ModelAdmin): list_display = ('name_', 'type', 'address_', 'ttl', 'host', 'owner') @@ -104,6 +116,7 @@ class RecordAdmin(admin.ModelAdmin): a = instance.get_data() return a['name'] if a else None + class BlacklistAdmin(admin.ModelAdmin): list_display = ('ipv4', 'reason', 'created_at', 'modified_at') @@ -116,4 +129,3 @@ admin.site.register(Firewall, FirewallAdmin) admin.site.register(Domain, DomainAdmin) admin.site.register(Record, RecordAdmin) admin.site.register(Blacklist, BlacklistAdmin) - diff --git a/firewall/fields.py b/firewall/fields.py index fba5d00..f0bca9c 100644 --- a/firewall/fields.py +++ b/firewall/fields.py @@ -6,12 +6,14 @@ from django.utils.ipv6 import is_valid_ipv6_address from south.modelsinspector import add_introspection_rules import re + mac_re = re.compile(r'^([0-9a-fA-F]{2}(:|$)){6}$') alfanum_re = re.compile(r'^[A-Za-z0-9_-]+$') domain_re = re.compile(r'^([A-Za-z0-9_-]\.?)+$') ipv4_re = re.compile('^[0-9]+\.([0-9]+)\.([0-9]+)\.([0-9]+)$') reverse_domain_re = re.compile(r'^(%\([abcd]\)d|[a-z0-9.-])+$') + class MACAddressFormField(fields.RegexField): default_error_messages = { 'invalid': _(u'Enter a valid MAC address.'), @@ -20,8 +22,10 @@ class MACAddressFormField(fields.RegexField): def __init__(self, *args, **kwargs): super(MACAddressFormField, self).__init__(mac_re, *args, **kwargs) + class MACAddressField(models.Field): empty_strings_allowed = False + def __init__(self, *args, **kwargs): kwargs['max_length'] = 17 super(MACAddressField, self).__init__(*args, **kwargs) @@ -35,44 +39,53 @@ class MACAddressField(models.Field): return super(MACAddressField, self).formfield(**defaults) add_introspection_rules([], ["firewall\.fields\.MACAddressField"]) + def val_alfanum(value): """Validate whether the parameter is a valid alphanumeric value.""" if not alfanum_re.match(value): raise ValidationError(_(u'%s - only letters, numbers, underscores ' - 'and hyphens are allowed!') % value) + 'and hyphens are allowed!') % value) + def is_valid_domain(value): """Check whether the parameter is a valid domain name.""" return domain_re.match(value) is not None + def val_domain(value): """Validate whether the parameter is a valid domin name.""" if not is_valid_domain(value): raise ValidationError(_(u'%s - invalid domain name') % value) + def is_valid_reverse_domain(value): """Check whether the parameter is a valid reverse domain name.""" return reverse_domain_re.match(value) is not None + def val_reverse_domain(value): """Validate whether the parameter is a valid reverse domain name.""" if not is_valid_reverse_domain(value): raise ValidationError(u'%s - invalid reverse domain name' % value) + def is_valid_ipv4_address(value): """Check whether the parameter is a valid IPv4 address.""" return ipv4_re.match(value) is not None + def val_ipv4(value): """Validate whether the parameter is a valid IPv4 address.""" if not is_valid_ipv4_address(value): raise ValidationError(_(u'%s - not an IPv4 address') % value) + def val_ipv6(value): """Validate whether the parameter is a valid IPv6 address.""" if not is_valid_ipv6_address(value): raise ValidationError(_(u'%s - not an IPv6 address') % value) + def val_mx(value): """Validate whether the parameter is a valid MX address definition. @@ -84,9 +97,10 @@ def val_mx(value): raise ValidationError(_("Bad MX address format. " "Should be: <priority>:<hostname>")) + def ipv4_2_ipv6(ipv4): """Convert IPv4 address string to IPv6 address string.""" val_ipv4(ipv4) m = ipv4_re.match(ipv4) return ("2001:738:2001:4031:%s:%s:%s:0" % - (m.group(1), m.group(2), m.group(3))) + (m.group(1), m.group(2), m.group(3))) diff --git a/firewall/fw.py b/firewall/fw.py index 4c45c63..138c9aa 100644 --- a/firewall/fw.py +++ b/firewall/fw.py @@ -1,19 +1,18 @@ -from django.contrib import auth from firewall import models -import os import django.conf import subprocess import re -import json from datetime import datetime, timedelta from django.db.models import Q settings = django.conf.settings.FIREWALL_SETTINGS + + class Firewall: - IPV6=False + IPV6 = False RULES = None RULES_NAT = [] vlans = None @@ -29,13 +28,12 @@ class Firewall: retval += ' --sport %s ' % rule.sport if rule.dport: retval += ' --dport %s ' % (rule.nat_dport - if (repl and rule.nat and rule.direction == '1') - else rule.dport) + if (repl and rule.nat and rule.direction == '1') + else rule.dport) elif rule.proto == 'icmp': retval = '-p %s ' % rule.proto return retval - def iptables(self, s): """Append rule to filter table.""" self.RULES.append(s) @@ -60,8 +58,8 @@ class Firewall: if rule.direction == '0' and vlan.name == 'PUB': if rule.dport == 25: self.iptables('-A PUB_OUT -s %s %s -p tcp ' - '--dport 25 -j LOG_ACC' % - (ipaddr, rule.extra)) + '--dport 25 -j LOG_ACC' % + (ipaddr, rule.extra)) break action = 'PUB_OUT' else: @@ -69,13 +67,14 @@ class Firewall: else: action = 'LOG_DROP' - if rule.direction == '1': # going TO host - self.iptables('-A %s_%s -d %s %s %s -g %s' % (vlan, - host.vlan, ipaddr, dport_sport, rule.extra, action)) + if rule.direction == '1': # going TO host + self.iptables('-A %s_%s -d %s %s %s -g %s' % + (vlan, host.vlan, ipaddr, dport_sport, + rule.extra, action)) else: - self.iptables('-A %s_%s -s %s %s %s -g %s' % (host.vlan, - vlan, ipaddr, dport_sport, rule.extra, action)) - + self.iptables('-A %s_%s -s %s %s %s -g %s' % + (host.vlan, vlan, ipaddr, dport_sport, + rule.extra, action)) def fw2vlan(self, rule): if not rule.foreign_network: @@ -84,14 +83,14 @@ class Firewall: dport_sport = self.dportsport(rule) for vlan in rule.foreign_network.vlans.all(): - if rule.direction == '1': # going TO host + if rule.direction == '1': # going TO host self.iptables('-A INPUT -i %s %s %s -g %s' % - (vlan.interface, dport_sport, rule.extra, - 'LOG_ACC' if rule.accept else 'LOG_DROP')) + (vlan.interface, dport_sport, rule.extra, + 'LOG_ACC' if rule.accept else 'LOG_DROP')) else: self.iptables('-A OUTPUT -o %s %s %s -g %s' % - (vlan.interface, dport_sport, rule.extra, - 'LOG_ACC' if rule.accept else 'LOG_DROP')) + (vlan.interface, dport_sport, rule.extra, + 'LOG_ACC' if rule.accept else 'LOG_DROP')) def vlan2vlan(self, l_vlan, rule): if not rule.foreign_network: @@ -108,13 +107,13 @@ class Firewall: else: action = 'LOG_DROP' - if rule.direction == '1': # going TO host - self.iptables('-A %s_%s %s %s -g %s' % (vlan, l_vlan, - dport_sport, rule.extra, action)) + if rule.direction == '1': # going TO host + self.iptables('-A %s_%s %s %s -g %s' % + (vlan, l_vlan, dport_sport, rule.extra, action)) else: self.iptables('-A %s_%s %s %s -g %s' % (l_vlan, vlan, - dport_sport, rule.extra, action)) - + dport_sport, + rule.extra, action)) def prerun(self): self.iptables('*filter') @@ -128,39 +127,39 @@ class Firewall: self.iptables('-A LOG_DROP -p tcp --dport 445 -j DROP') self.iptables('-A LOG_DROP -p udp --dport 137 -j DROP') self.iptables('-A LOG_DROP -j LOG --log-level 7 ' - '--log-prefix "[ipt][drop]"') + '--log-prefix "[ipt][drop]"') self.iptables('-A LOG_DROP -j DROP') self.iptables('-N LOG_ACC') self.iptables('-A LOG_ACC -j LOG --log-level 7 ' - '--log-prefix "[ipt][isok]"') + '--log-prefix "[ipt][isok]"') self.iptables('-A LOG_ACC -j ACCEPT') self.iptables('-N PUB_OUT') - self.iptables('-A FORWARD -m set --match-set blacklist src,dst -j DROP') + self.iptables('-A FORWARD -m set --match-set blacklist src,dst' + '-j DROP') self.iptables('-A FORWARD -m state --state INVALID -g LOG_DROP') self.iptables('-A FORWARD -m state --state ESTABLISHED,RELATED ' - '-j ACCEPT') + '-j ACCEPT') self.iptables('-A FORWARD -p icmp --icmp-type echo-request ' - '-g LOG_ACC') + '-g LOG_ACC') self.iptables('-A INPUT -m set --match-set blacklist src -j DROP') self.iptables('-A INPUT -m state --state INVALID -g LOG_DROP') self.iptables('-A INPUT -i lo -j ACCEPT') self.iptables('-A INPUT -m state --state ESTABLISHED,RELATED ' - '-j ACCEPT') + '-j ACCEPT') self.iptables('-A OUTPUT -m state --state INVALID -g LOG_DROP') self.iptables('-A OUTPUT -o lo -j ACCEPT') self.iptables('-A OUTPUT -m state --state ESTABLISHED,RELATED ' - '-j ACCEPT') - + '-j ACCEPT') def postrun(self): self.iptables('-A PUB_OUT -s 152.66.243.160/27 -p tcp --dport 25 ' - '-j LOG_ACC') + '-j LOG_ACC') self.iptables('-A PUB_OUT -s 152.66.243.160/27 -p tcp --dport 445 ' - '-j LOG_ACC') + '-j LOG_ACC') self.iptables('-A PUB_OUT -p tcp --dport 25 -j LOG_DROP') self.iptables('-A PUB_OUT -p tcp --dport 445 -j LOG_DROP') self.iptables('-A PUB_OUT -p udp --dport 445 -j LOG_DROP') @@ -171,9 +170,6 @@ class Firewall: self.iptables('-A OUTPUT -g LOG_DROP') self.iptables('COMMIT') - - - def ipt_nat(self): self.iptablesnat('*nat') self.iptablesnat(':PREROUTING ACCEPT [0:0]') @@ -187,34 +183,37 @@ class Firewall: dport_sport = self.dportsport(rule, False) if host.vlan.snat_ip: self.iptablesnat('-A PREROUTING -d %s %s %s -j DNAT ' - '--to-destination %s:%s' % (host.pub_ipv4, - dport_sport, rule.extra, host.ipv4, - rule.nat_dport)) + '--to-destination %s:%s' % + (host.pub_ipv4, dport_sport, rule.extra, + host.ipv4, rule.nat_dport)) # rules for machines with dedicated public IP for host in self.hosts.exclude(shared_ip=True): if host.pub_ipv4: self.iptablesnat('-A PREROUTING -d %s -j DNAT ' - '--to-destination %s' % (host.pub_ipv4, host.ipv4)) + '--to-destination %s' % + (host.pub_ipv4, host.ipv4)) self.iptablesnat('-A POSTROUTING -s %s -j SNAT ' - '--to-source %s' % (host.ipv4, host.pub_ipv4)) + '--to-source %s' % + (host.ipv4, host.pub_ipv4)) # default NAT rules for VLANs for s_vlan in self.vlans: if s_vlan.snat_ip: for d_vlan in s_vlan.snat_to.all(): self.iptablesnat('-A POSTROUTING -s %s -o %s -j SNAT ' - '--to-source %s' % (s_vlan.net_ipv4(), - d_vlan.interface, s_vlan.snat_ip)) - + '--to-source %s' % + (s_vlan.net_ipv4(), d_vlan.interface, + s_vlan.snat_ip)) # hard-wired rules self.iptablesnat('-A POSTROUTING -s 10.5.0.0/16 -o vlan0003 -j SNAT ' - '--to-source 10.3.255.254') # man elerheto legyen + '--to-source 10.3.255.254') # man elerheto legyen self.iptablesnat('-A POSTROUTING -o vlan0008 -j SNAT ' - '--to-source 10.0.0.247') # wolf network for printing - self.iptablesnat('-A POSTROUTING -s 10.3.0.0/16 -p udp --dport 53 -o vlan0002 -j SNAT ' - '--to-source %s' % self.pub.ipv4) # kulonben nem megy a dns man-ban + '--to-source 10.0.0.247') # wolf network for printing + self.iptablesnat('-A POSTROUTING -s 10.3.0.0/16 -p udp --dport 53' + '-o vlan0002 -j SNAT ''--to-source %s' % + self.pub.ipv4) # kulonben nem megy a dns man-ban self.iptablesnat('COMMIT') @@ -234,7 +233,8 @@ class Firewall: for d_vlan in self.vlans: self.iptables('-N %s_%s' % (s_vlan, d_vlan)) self.iptables('-A FORWARD -i %s -o %s -g %s_%s' % - (s_vlan.interface, d_vlan.interface, s_vlan, d_vlan)) + (s_vlan.interface, d_vlan.interface, s_vlan, + d_vlan)) # hosts' rules for i_vlan in self.vlans: @@ -263,8 +263,8 @@ class Firewall: self.RULES = [x.replace('icmp', 'icmpv6') for x in self.RULES] def __init__(self, IPV6=False): - self.RULES=[] - self.RULES_NAT=[] + self.RULES = [] + self.RULES_NAT = [] self.IPV6 = IPV6 self.vlans = models.Vlan.objects.all() self.hosts = models.Host.objects.all() @@ -277,32 +277,37 @@ class Firewall: def reload(self): if self.IPV6: process = subprocess.Popen(['/usr/bin/ssh', 'fw2', - '/usr/bin/sudo', '/sbin/ip6tables-restore', '-c'], - shell=False, stdin=subprocess.PIPE) + '/usr/bin/sudo', + '/sbin/ip6tables-restore', '-c'], + shell=False, stdin=subprocess.PIPE) process.communicate('\n'.join(self.RULES) + '\n') else: process = subprocess.Popen(['/usr/bin/ssh', 'fw2', - '/usr/bin/sudo', '/sbin/iptables-restore', '-c'], - shell=False, stdin=subprocess.PIPE) + '/usr/bin/sudo', + '/sbin/iptables-restore', '-c'], + shell=False, stdin=subprocess.PIPE) process.communicate('\n'.join(self.RULES) + '\n' + - '\n'.join(self.RULES_NAT) + '\n') + '\n'.join(self.RULES_NAT) + '\n') def get(self): if self.IPV6: - return { 'filter': self.RULES, } + return {'filter': self.RULES, } else: - return { 'filter': self.RULES, 'nat': self.RULES_NAT } + return {'filter': self.RULES, 'nat': self.RULES_NAT} def show(self): if self.IPV6: return '\n'.join(self.RULES) + '\n' else: return ('\n'.join(self.RULES) + '\n' + - '\n'.join(self.RULES_NAT) + '\n') + '\n'.join(self.RULES_NAT) + '\n') + def ipset(): - week = datetime.now()-timedelta(days=2) - return models.Blacklist.objects.filter(Q(type='tempban', modified_at__gte=week) | Q(type='permban')).values('ipv4', 'reason') + week = datetime.now() - timedelta(days=2) + filter_ban = (Q(type='tempban', modified_at__gte=week) | + Q(type='permban')).values('ipv4', 'reason') + return models.Blacklist.objects.filter(filter_ban) def ipv6_to_octal(ipv6): @@ -319,14 +324,16 @@ def ipv6_to_octal(ipv6): octets.append(int(part[2:], 16)) return '\\' + '\\'.join(['%03o' % x for x in octets]) + def ipv4_to_arpa(ipv4, cname=False): m2 = re.search(r'^([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)$', ipv4) if cname: return ('%s.dns1.%s.%s.%s.in-addr.arpa' % - (m2.group(4), m2.group(3), m2.group(2), m2.group(1))) + (m2.group(4), m2.group(3), m2.group(2), m2.group(1))) else: return ('%s.%s.%s.%s.in-addr.arpa' % - (m2.group(4), m2.group(3), m2.group(2), m2.group(1))) + (m2.group(4), m2.group(3), m2.group(2), m2.group(1))) + def ipv6_to_arpa(ipv6): while len(ipv6.split(':')) < 8: @@ -355,11 +362,11 @@ def ipv6_to_arpa(ipv6): def dns(): vlans = models.Vlan.objects.all() - regex = re.compile(r'^([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)$') + # regex = re.compile(r'^([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)$') DNS = [] for i_vlan in vlans: - m = regex.search(i_vlan.net4) + # m = regex.search(i_vlan.net4) rev = i_vlan.reverse_domain for i_host in i_vlan.host_set.all(): @@ -367,31 +374,32 @@ def dns(): not i_host.shared_ip else i_host.ipv4) i = ipv4.split('.', 4) reverse = (i_host.reverse if i_host.reverse and - len(i_host.reverse) else i_host.get_fqdn()) + len(i_host.reverse) else i_host.get_fqdn()) # ipv4 if i_host.ipv4: DNS.append("^%s:%s:%s" % ( - (rev % { 'a': int(i[0]), 'b': int(i[1]), 'c': int(i[2]), - 'd': int(i[3]) }), + (rev % {'a': int(i[0]), 'b': int(i[1]), 'c': int(i[2]), + 'd': int(i[3])}), reverse, models.settings['dns_ttl'])) # ipv6 if i_host.ipv6: DNS.append("^%s:%s:%s" % (ipv6_to_arpa(i_host.ipv6), - reverse, models.settings['dns_ttl'])) + reverse, models.settings['dns_ttl'])) for domain in models.Domain.objects.all(): - DNS.append("Z%s:%s:support.ik.bme.hu::::::%s" % (domain.name, - settings['dns_hostname'], models.settings['dns_ttl'])) + DNS.append("Z%s:%s:support.ik.bme.hu::::::%s" % + (domain.name, settings['dns_hostname'], + models.settings['dns_ttl'])) for r in models.Record.objects.all(): d = r.get_data() if d['type'] == 'A': DNS.append("+%s:%s:%s" % (d['name'], d['address'], d['ttl'])) elif d['type'] == 'AAAA': - DNS.append(":%s:28:%s:%s" % (d['name'], - ipv6_to_octal(d['address']), d['ttl'])) + DNS.append(":%s:28:%s:%s" % + (d['name'], ipv6_to_octal(d['address']), d['ttl'])) elif d['type'] == 'NS': DNS.append("&%s::%s:%s" % (d['name'], d['address'], d['ttl'])) elif d['type'] == 'CNAME': @@ -399,15 +407,16 @@ def dns(): elif d['type'] == 'MX': mx = d['address'].split(':', 2) DNS.append("@%(fqdn)s::%(mx)s:%(dist)s:%(ttl)s" % - {'fqdn': d['name'], 'mx': mx[1], 'dist': mx[0], - 'ttl': d['ttl']}) + {'fqdn': d['name'], 'mx': mx[1], 'dist': mx[0], + 'ttl': d['ttl']}) elif d['type'] == 'PTR': DNS.append("^%s:%s:%s" % (d['name'], d['address'], d['ttl'])) return DNS process = subprocess.Popen(['/usr/bin/ssh', 'tinydns@%s' % - settings['dns_hostname']], shell=False, stdin=subprocess.PIPE) - process.communicate("\n".join(DNS)+"\n") + settings['dns_hostname']], + shell=False, stdin=subprocess.PIPE) + process.communicate("\n".join(DNS) + "\n") # print "\n".join(DNS)+"\n" @@ -420,10 +429,11 @@ def prefix_to_mask(prefix): t[i] = 256 - (2 ** ((i + 1) * 8 - prefix)) return ".".join([str(i) for i in t]) + def dhcp(): vlans = models.Vlan.objects.all() regex = re.compile(r'^([0-9]+)\.([0-9]+)\.[0-9]+\.[0-9]+\s+' - r'([0-9]+)\.([0-9]+)\.[0-9]+\.[0-9]+$') + r'([0-9]+)\.([0-9]+)\.[0-9]+\.[0-9]+$') DHCP = [] # /tools/dhcp3/dhcpd.conf.generated @@ -432,7 +442,7 @@ def dhcp(): if(i_vlan.dhcp_pool): m = regex.search(i_vlan.dhcp_pool) if(m or i_vlan.dhcp_pool == "manual"): - DHCP.append (''' + DHCP.append(''' # %(name)s - %(interface)s subnet %(net)s netmask %(netmask)s { %(extra)s; @@ -444,7 +454,7 @@ def dhcp(): authoritative; filename \"pxelinux.0\"; allow bootp; allow booting; - }''' % { + }''' % { 'net': i_vlan.net4, 'netmask': prefix_to_mask(i_vlan.prefix4), 'domain': i_vlan.domain, @@ -452,14 +462,14 @@ def dhcp(): 'ntp': i_vlan.ipv4, 'dnsserver': settings['rdns_ip'], 'extra': ("range %s" % i_vlan.dhcp_pool - if m else "deny unknown-clients"), + if m else "deny unknown-clients"), 'interface': i_vlan.interface, 'name': i_vlan.name, 'tftp': i_vlan.ipv4 }) for i_host in i_vlan.host_set.all(): - DHCP.append (''' + DHCP.append(''' host %(hostname)s { hardware ethernet %(mac)s; fixed-address %(ipv4)s; @@ -471,23 +481,8 @@ def dhcp(): return DHCP process = subprocess.Popen(['/usr/bin/ssh', 'fw2', - 'cat > /tools/dhcp3/dhcpd.conf.generated;' - 'sudo /etc/init.d/isc-dhcp-server restart'], shell=False, - stdin=subprocess.PIPE) + 'cat > /tools/dhcp3/dhcpd.conf.generated;' + 'sudo /etc/init.d/isc-dhcp-server restart'], + shell=False, stdin=subprocess.PIPE) # print "\n".join(DHCP)+"\n" - process.communicate("\n".join(DHCP)+"\n") - - -''' -i=2 -for mac, name, ipend in [("18:a9:05:64:19:aa", "mega6", 16), ("00:1e:0b:e9:79:1e", "blade1", 21), ("00:22:64:9c:fd:34", "blade2", 22), ("00:1e:0b:ec:65:46", "blade3", 23), ("b4:b5:2f:61:d2:5a", "cloud-man", 1)]: - h1 = models.Host(hostname= name, vlan=models.Vlan.objects.get(vid=3), mac=mac, ipv4="10.3.1.%d" % ipend, ipv6="2001:738:2001:4031:3:1:%d:0" % ipend, owner=auth.models.User.objects.get(username="bd")) - try: - h1.save() - h1.groups.add(models.Group.objects.get(name="netezhet manbol")) - h1.save() -# i = i + 1 - except: - print "nemok %s" % name -''' - + process.communicate("\n".join(DHCP) + "\n") diff --git a/firewall/models.py b/firewall/models.py index 4a34386..fa45696 100644 --- a/firewall/models.py +++ b/firewall/models.py @@ -4,7 +4,9 @@ from django.contrib.auth.models import User from django.db import models from django.forms import ValidationError from django.utils.translation import ugettext_lazy as _ -from firewall.fields import * +from firewall.fields import (MACAddressField, val_alfanum, val_reverse_domain, + val_domain, val_ipv4, val_ipv6, val_mx, + ipv4_2_ipv6) from django.core.validators import MinValueValidator, MaxValueValidator import django.conf from django.db.models.signals import post_save @@ -85,7 +87,7 @@ class Rule(models.Model): "(if type is vlan).")) vlangroup = models.ForeignKey('VlanGroup', related_name="rules", blank=True, null=True, verbose_name=_( - "vlan group"), + "vlan group"), help_text=_("Group of vlans the rule " "applies to (if type is vlan).")) host = models.ForeignKey('Host', related_name="rules", blank=True, @@ -185,15 +187,17 @@ class Vlan(models.Model): ipv4 = models.GenericIPAddressField(protocol='ipv4', unique=True, verbose_name=_('IPv4 address'), help_text=_( - 'The IPv4 address of the gateway. ' - 'Recommended value is the last valid ' - 'address of the subnet, for example ' - '10.4.255.254 for 10.4.0.0/16.')) + 'The IPv4 address of the gateway. ' + 'Recommended value is the last ' + 'valid address of the subnet, ' + 'for example ' + '10.4.255.254 for 10.4.0.0/16.')) ipv6 = models.GenericIPAddressField(protocol='ipv6', unique=True, verbose_name=_('IPv6 address'), help_text=_( - 'The IPv6 address of the gateway.')) + 'The IPv6 address of the ' + 'gateway.')) snat_ip = models.GenericIPAddressField(protocol='ipv4', blank=True, null=True, verbose_name=_('NAT IP address'), diff --git a/firewall/tasks.py b/firewall/tasks.py index 7d35e20..fbfd879 100644 --- a/firewall/tasks.py +++ b/firewall/tasks.py @@ -1,26 +1,32 @@ from celery.task import Task, PeriodicTask import celery from django.core.cache import cache -import os -import time from firewall.fw import * import django.conf settings = django.conf.settings.FIREWALL_SETTINGS + @celery.task def reload_dns_task(data): pass + + @celery.task def reload_firewall_task(data4, data6): pass + + @celery.task def reload_dhcp_task(data): pass + + @celery.task def reload_blacklist_task(data): pass + class Periodic(PeriodicTask): run_every = timedelta(seconds=10) @@ -48,6 +54,7 @@ class Periodic(PeriodicTask): reload_blacklist_task.delay(list(ipset())) print "blacklist ujratoltese kesz" + class ReloadTask(Task): def run(self, type='Host'): @@ -64,4 +71,3 @@ class ReloadTask(Task): cache.add("blacklist_lock", "true", 30) print type - diff --git a/firewall/views.py b/firewall/views.py index 266d338..fe95550 100644 --- a/firewall/views.py +++ b/firewall/views.py @@ -2,12 +2,10 @@ import base64 import datetime import json import re -import sys from django.conf import settings from django.db import IntegrityError from django.http import HttpResponse -from django.shortcuts import render_to_response from django.template.loader import render_to_string from django.utils import translation from django.utils.timezone import utc @@ -15,13 +13,13 @@ from django.utils.translation import ugettext_lazy as _ from django.views.decorators.csrf import csrf_exempt from django.views.decorators.http import require_POST -from celery.task.control import inspect from tasks import * from firewall.fw import * from firewall.models import * from one.tasks import SendMailTask + def reload_firewall(request): if request.user.is_authenticated(): if request.user.is_superuser: @@ -34,34 +32,44 @@ def reload_firewall(request): html = _("Dear anonymous, you've not signed in yet!") return HttpResponse(html) + @csrf_exempt @require_POST def firewall_api(request): try: - data=json.loads(base64.b64decode(request.POST["data"])) + data = json.loads(base64.b64decode(request.POST["data"])) command = request.POST["command"] if data["password"] != "bdmegintelrontottaanetet": raise Exception(_("Wrong password.")) if command == "blacklist": obj, created = Blacklist.objects.get_or_create(ipv4=data["ip"]) - obj.reason=data["reason"] - obj.snort_message=data["snort_message"] + obj.reason = data["reason"] + obj.snort_message = data["snort_message"] if created: try: obj.host = Host.objects.get(ipv4=data["ip"]) user = obj.host.owner lang = user.person_set.all()[0].language translation.activate(lang) - msg = render_to_string('mails/notification-ban-now.txt', - { 'user': user, - 'bl': obj, - 'instance:': obj.host.instance_set.get(), - 'url': settings.CLOUD_URL} ) - SendMailTask.delay(to=obj.host.owner.email, subject='[IK Cloud] %s' % obj.host.instance_set.get().name, msg=msg, sender=u'cloud@ik.bme.hu') - except (Host.DoesNotExist, ValidationError, IntegrityError, AttributeError): + msg = render_to_string( + 'mails/notification-ban-now.txt', + {'user': user, + 'bl': obj, + 'instance:': obj.host.instance_set.get(), + 'url': settings.CLOUD_URL}) + SendMailTask.delay( + to=obj.host.owner.email, + subject='[IK Cloud] %s' % + obj.host.instance_set.get().name, + msg=msg, sender=u'cloud@ik.bme.hu') + except (Host.DoesNotExist, ValidationError, + IntegrityError, AttributeError): pass - if obj.type == 'tempwhite' and obj.modified_at + datetime.timedelta(minutes=1) < datetime.datetime.utcnow().replace(tzinfo=utc): + + modified = obj.modified_at + datetime.timedelta(minutes=1) + now = datetime.dateime.utcnow().replace(tzinfo=utc) + if obj.type == 'tempwhite' and modified < now: obj.type = 'tempban' obj.save() return HttpResponse(unicode(_("OK"))) @@ -75,27 +83,26 @@ def firewall_api(request): data["owner"] = "opennebula" owner = auth.models.User.objects.get(username=data["owner"]) host = Host(hostname=data["hostname"], - vlan=Vlan.objects.get(name=data["vlan"]), - mac=data["mac"], ipv4=data["ip"], owner=owner, - description=data["description"], pub_ipv4= + vlan=Vlan.objects.get(name=data["vlan"]), + mac=data["mac"], ipv4=data["ip"], owner=owner, + description=data["description"], pub_ipv4= Vlan.objects.get(name=data["vlan"]).snat_ip, - shared_ip=True) + shared_ip=True) host.full_clean() host.save() host.enable_net() for p in data["portforward"]: - host.add_port(proto=p["proto"], - public=int(p["public_port"]), - private=int(p["private_port"])) + host.add_port(proto=p["proto"], public=int(p["public_port"]), + private=int(p["private_port"])) elif command == "destroy": data["owner"] = "opennebula" print data["hostname"] owner = auth.models.User.objects.get(username=data["owner"]) host = Host.objects.get(hostname=data["hostname"], - owner=owner) + owner=owner) host.delete() else: -- libgit2 0.26.0