Commit 9fa75044 by Őry Máté

firewall: cleanup models

parent de7816ad
......@@ -2,21 +2,22 @@
from django.contrib.auth.models import User
from django.db import models
from django.forms import fields, ValidationError
from django.forms import ValidationError
from django.utils.translation import ugettext_lazy as _
from firewall.fields import *
from south.modelsinspector import add_introspection_rules
from django.core.validators import MinValueValidator, MaxValueValidator
import django.conf
from django.db.models.signals import post_save
import re
import random
settings = django.conf.settings.FIREWALL_SETTINGS
class Rule(models.Model):
"""
A rule of a packet filter, changing the behavior of a host, vlan or firewall.
A rule of a packet filter, changing the behavior of a host, vlan or
firewall.
Some rules accept or deny packets matching some criteria.
Others set address translation or other free-form iptables parameters.
......@@ -28,52 +29,77 @@ class Rule(models.Model):
direction = models.CharField(max_length=1, choices=CHOICES_dir,
blank=False, verbose_name=_("direction"),
help_text=_("If the rule matches egress or ingress packets."))
help_text=_("If the rule matches egress "
"or ingress packets."))
description = models.TextField(blank=True,
help_text=_("Why is the rule needed, or how does it work."))
foreign_network = models.ForeignKey('VlanGroup', verbose_name=_("foreign network"),
help_text=_("The group of vlans the matching packet goes to (direction out) or from (in)."),
help_text=_("Why is the rule needed, "
"or how does it work."))
foreign_network = models.ForeignKey(
'VlanGroup', verbose_name=_("foreign network"),
help_text=_("The group of vlans the matching packet goes to "
"(direction out) or from (in)."),
related_name="ForeignRules")
dport = models.IntegerField(blank=True, null=True, verbose_name=_("dest. port"),
dport = models.IntegerField(
blank=True, null=True, verbose_name=_("dest. port"),
validators=[MinValueValidator(1), MaxValueValidator(65535)],
help_text=_("Destination port number of packets that match."))
sport = models.IntegerField(blank=True, null=True, verbose_name=_("source port"),
sport = models.IntegerField(
blank=True, null=True, verbose_name=_("source port"),
validators=[MinValueValidator(1), MaxValueValidator(65535)],
help_text=_("Source port number of packets that match."))
proto = models.CharField(max_length=10, choices=CHOICES_proto,
blank=True, null=True, verbose_name=_("protocol"),
help_text=_("Protocol of packets that match."))
extra = models.TextField(blank=True, verbose_name=_("extra arguments"),
help_text=_("Additional arguments passed literally to the iptables-rule."))
help_text=_("Additional arguments passed "
"literally to the iptables-rule."))
accept = models.BooleanField(default=False, verbose_name=_("accept"),
help_text=_("Accept the matching packets (or deny if not checked)."))
help_text=_("Accept the matching packets "
"(or deny if not checked)."))
owner = models.ForeignKey(User, blank=True, null=True,
verbose_name=_("owner"),
help_text=_("The user responsible for this rule."))
help_text=_("The user responsible for "
"this rule."))
r_type = models.CharField(max_length=10, verbose_name=_("Rule type"),
choices=CHOICES_type,
help_text=_("The type of entity the rule belongs to."))
help_text=_("The type of entity the rule "
"belongs to."))
nat = models.BooleanField(default=False, verbose_name=_("NAT"),
help_text=_("If network address translation shoud be done."))
help_text=_("If network address translation "
"shoud be done."))
nat_dport = models.IntegerField(blank=True, null=True,
help_text=_("Rewrite destination port number to."),
help_text=_(
"Rewrite destination port number to."),
validators=[MinValueValidator(1),
MaxValueValidator(65535)])
created_at = models.DateTimeField(auto_now_add=True, verbose_name=_("created at"))
modified_at = models.DateTimeField(auto_now=True, verbose_name=_("modified at"))
created_at = models.DateTimeField(
auto_now_add=True,
verbose_name=_("created at"))
modified_at = models.DateTimeField(
auto_now=True,
verbose_name=_("modified at"))
vlan = models.ForeignKey('Vlan', related_name="rules", blank=True,
null=True, verbose_name=_("vlan"),
help_text=_("Vlan the rule applies to (if type is vlan)."))
help_text=_("Vlan the rule applies to "
"(if type is vlan)."))
vlangroup = models.ForeignKey('VlanGroup', related_name="rules",
blank=True, null=True, verbose_name=_("vlan group"),
help_text=_("Group of vlans the rule applies to (if type is vlan)."))
blank=True, null=True, verbose_name=_(
"vlan group"),
help_text=_("Group of vlans the rule "
"applies to (if type is vlan)."))
host = models.ForeignKey('Host', related_name="rules", blank=True,
verbose_name=_('host'), null=True, help_text=_("Host the rule applies to (if type is host)."))
hostgroup = models.ForeignKey('Group', related_name="rules", verbose_name=_("host group"),
blank=True, null=True, help_text=_("Group of hosts the rule applies to (if type is host)."))
firewall = models.ForeignKey('Firewall', related_name="rules", verbose_name=_("firewall"),
help_text=_("Firewall the rule applies to (if type is firewall)."),
verbose_name=_('host'), null=True,
help_text=_("Host the rule applies to "
"(if type is host)."))
hostgroup = models.ForeignKey(
'Group', related_name="rules", verbose_name=_("host group"),
blank=True, null=True, help_text=_("Group of hosts the rule applies "
"to (if type is host)."))
firewall = models.ForeignKey(
'Firewall', related_name="rules", verbose_name=_("firewall"),
help_text=_("Firewall the rule applies to "
"(if type is firewall)."),
blank=True, null=True)
def __unicode__(self):
......@@ -101,7 +127,16 @@ class Rule(models.Model):
class Meta:
verbose_name = _("rule")
verbose_name_plural = _("rules")
ordering = ('r_type', 'direction', 'proto', 'sport', 'dport', 'nat_dport', 'host', )
ordering = (
'r_type',
'direction',
'proto',
'sport',
'dport',
'nat_dport',
'host',
)
class Vlan(models.Model):
vid = models.IntegerField(unique=True)
......@@ -136,6 +171,7 @@ class Vlan(models.Model):
def net_ipv4(self):
return self.net4 + "/" + unicode(self.prefix4)
class VlanGroup(models.Model):
name = models.CharField(max_length=20, unique=True)
vlans = models.ManyToManyField('Vlan', symmetrical=False, blank=True,
......@@ -148,6 +184,7 @@ class VlanGroup(models.Model):
def __unicode__(self):
return self.name
class Group(models.Model):
name = models.CharField(max_length=20, unique=True)
description = models.TextField(blank=True)
......@@ -158,6 +195,7 @@ class Group(models.Model):
def __unicode__(self):
return self.name
class Host(models.Model):
hostname = models.CharField(max_length=40, unique=True,
validators=[val_alfanum])
......@@ -210,7 +248,8 @@ class Host(models.Model):
proto = "tcp" if proto == "tcp" else "udp"
if self.shared_ip:
used_ports = Rule.objects.filter(host__pub_ipv4=self.pub_ipv4,
nat=True, proto=proto).values_list('dport', flat=True)
nat=True, proto=proto
).values_list('dport', flat=True)
if public is None:
public = random.randint(1024, 21000)
......@@ -220,20 +259,21 @@ class Host(models.Model):
public = i
break
else:
raise ValidationError(_("Port %s %s is already in use.") %
raise ValidationError(
_("Port %s %s is already in use.") %
(proto, public))
else:
if public < 1024:
raise ValidationError(_("Only ports above 1024 can be used."))
raise ValidationError(
_("Only ports above 1024 can be used."))
if public in used_ports:
raise ValidationError(_("Port %s %s is already in use.") %
(proto, public))
vg = VlanGroup.objects.get(name=settings["default_vlangroup"])
rule = Rule(direction='1', owner=self.owner, dport=public,
proto=proto, nat=True, accept=True, r_type="host",
nat_dport=private, host=self, foreign_network=VlanGroup.
objects.get(name=settings["default_vlangroup"]))
nat_dport=private, host=self, foreign_network=vg)
else:
if self.rules.filter(proto=proto, dport=public):
raise ValidationError(_("Port %s %s is already in use.") %
......@@ -309,6 +349,7 @@ class Firewall(models.Model):
def __unicode__(self):
return self.name
class Domain(models.Model):
name = models.CharField(max_length=40, validators=[val_domain])
owner = models.ForeignKey(User)
......@@ -320,6 +361,7 @@ class Domain(models.Model):
def __unicode__(self):
return self.name
class Record(models.Model):
CHOICES_type = (('A', 'A'), ('CNAME', 'CNAME'), ('AAAA', 'AAAA'),
('MX', 'MX'), ('NS', 'NS'), ('PTR', 'PTR'), ('TXT', 'TXT'))
......@@ -354,11 +396,11 @@ class Record(models.Model):
if self.host:
if self.type in ['A', 'AAAA']:
if self.address:
raise ValidationError(_("Can't specify address for "
"A or AAAA records if host is set!"))
raise ValidationError(_("Can't specify address for A "
"or AAAA records if host is set!"))
if self.name:
raise ValidationError(_("Can't specify name for "
"A or AAAA records if host is set!"))
raise ValidationError(_("Can't specify name for A "
"or AAAA records if host is set!"))
elif self.type == 'CNAME':
if not self.name:
raise ValidationError(_("Name must be specified for "
......@@ -380,8 +422,8 @@ class Record(models.Model):
mx = self.address.split(':', 1)
if not (len(mx) == 2 and mx[0].isdigit() and
domain_re.match(mx[1])):
raise ValidationError(_("Bad address format. "
"Should be: <priority>:<hostname>"))
raise ValidationError(_("Bad MX address format. "
"Should be: <priority>:<name>"))
else:
raise ValidationError(_("Unknown record type."))
......@@ -425,22 +467,29 @@ class Record(models.Model):
'ttl': self.ttl,
'address': address}
class Blacklist(models.Model):
CHOICES_type = (('permban', 'permanent ban'), ('tempban', 'temporary ban'), ('whitelist', 'whitelist'), ('tempwhite', 'tempwhite'))
CHOICES_type = (('permban', 'permanent ban'), ('tempban', 'temporary ban'),
('whitelist', 'whitelist'), ('tempwhite', 'tempwhite'))
ipv4 = models.GenericIPAddressField(protocol='ipv4', unique=True)
host = models.ForeignKey('Host', blank=True, null=True)
reason = models.TextField(blank=True)
snort_message = models.TextField(blank=True)
type = models.CharField(max_length=10, choices=CHOICES_type, default='tempban')
type = models.CharField(
max_length=10,
choices=CHOICES_type,
default='tempban')
created_at = models.DateTimeField(auto_now_add=True)
modified_at = models.DateTimeField(auto_now=True)
def save(self, *args, **kwargs):
self.full_clean()
super(Blacklist, self).save(*args, **kwargs)
def __unicode__(self):
return self.ipv4
def send_task(sender, instance, created, **kwargs):
from firewall.tasks import ReloadTask
ReloadTask.apply_async(args=[sender.__name__])
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment