Commit 43391a3d by Őry Máté

firewall: merge from network-gui

parent a8c081dc
# -*- coding: utf8 -*- # -*- coding: utf-8 -*-
from django.contrib import admin 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 from django import contrib
class RuleInline(contrib.admin.TabularInline): class RuleInline(contrib.admin.TabularInline):
model = Rule model = Rule
class RecordInline(contrib.admin.TabularInline): class RecordInline(contrib.admin.TabularInline):
model = Record model = Record
class HostAdmin(admin.ModelAdmin): class HostAdmin(admin.ModelAdmin):
list_display = ('hostname', 'vlan', 'ipv4', 'ipv6', 'pub_ipv4', 'mac', 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', ) ordering = ('hostname', )
list_filter = ('owner', 'vlan', 'groups') list_filter = ('owner', 'vlan', 'groups')
search_fields = ('hostname', 'description', 'ipv4', 'ipv6', 'mac') search_fields = ('hostname', 'description', 'ipv4', 'ipv6', 'mac')
...@@ -26,42 +30,46 @@ class HostAdmin(admin.ModelAdmin): ...@@ -26,42 +30,46 @@ class HostAdmin(admin.ModelAdmin):
names = [group.name for group in instance.groups.all()] names = [group.name for group in instance.groups.all()]
return u', '.join(names) return u', '.join(names)
class HostInline(contrib.admin.TabularInline): class HostInline(contrib.admin.TabularInline):
model = Host model = Host
fields = ('hostname', 'ipv4', 'ipv6', 'pub_ipv4', 'mac', 'shared_ip', fields = ('hostname', 'ipv4', 'ipv6', 'pub_ipv4', 'mac', 'shared_ip',
'owner', 'reverse') 'owner', 'reverse')
class VlanAdmin(admin.ModelAdmin): class VlanAdmin(admin.ModelAdmin):
list_display = ('vid', 'name', 'ipv4', 'net_ipv4', 'ipv6', 'net_ipv6', list_display = ('vid', 'name', 'ipv4', 'net_ipv4', 'ipv6', 'net_ipv6',
'description', 'domain', 'snat_ip', ) 'description', 'domain', 'snat_ip', )
ordering = ('vid', ) ordering = ('vid', )
inlines = (RuleInline, ) inlines = (RuleInline, )
class RuleAdmin(admin.ModelAdmin): class RuleAdmin(admin.ModelAdmin):
list_display = ('r_type', 'color_desc', 'owner', 'extra', 'direction', 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', list_filter = ('r_type', 'vlan', 'owner', 'direction', 'accept',
'proto', 'nat') 'proto', 'nat')
def color_desc(self, instance): def color_desc(self, instance):
"""Returns a colorful description of the instance.""" """Returns a colorful description of the instance."""
return (u'<span style="color: #FF0000;">[%(type)s]</span> ' return (u'<span style="color: #FF0000;">[%(type)s]</span> '
u'%(src)s<span style="color: #0000FF;"> ▸ </span>%(dst)s ' u'%(src)s<span style="color: #0000FF;"> ▸ </span>%(dst)s '
u'%(para)s %(desc)s') % { u'%(para)s %(desc)s') % {
'type': instance.r_type, 'type': instance.r_type,
'src': (instance.foreign_network.name 'src': (instance.foreign_network.name
if instance.direction == '1' else instance.r_type), if instance.direction == '1' else instance.r_type),
'dst': (instance.r_type if instance.direction == '1' 'dst': (instance.r_type if instance.direction == '1'
else instance.foreign_network.name), else instance.foreign_network.name),
'para': (u'<span style="color: #00FF00;">' + 'para': (u'<span style="color: #00FF00;">' +
(('proto=%s ' % instance.proto) (('proto=%s ' % instance.proto)
if instance.proto else '') + if instance.proto else '') +
(('sport=%s ' % instance.sport) (('sport=%s ' % instance.sport)
if instance.sport else '') + if instance.sport else '') +
(('dport=%s ' % instance.dport) (('dport=%s ' % instance.dport)
if instance.dport else '') + if instance.dport else '') +
'</span>'), '</span>'),
'desc': instance.description} 'desc': instance.description}
color_desc.allow_tags = True color_desc.allow_tags = True
@staticmethod @staticmethod
...@@ -73,7 +81,7 @@ class RuleAdmin(admin.ModelAdmin): ...@@ -73,7 +81,7 @@ class RuleAdmin(admin.ModelAdmin):
@staticmethod @staticmethod
def used_in(instance): def used_in(instance):
for field in [instance.vlan, instance.vlangroup, instance.host, for field in [instance.vlan, instance.vlangroup, instance.host,
instance.hostgroup, instance.firewall]: instance.hostgroup, instance.firewall]:
if field: if field:
return unicode(field) + ' ' + field._meta.object_name return unicode(field) + ' ' + field._meta.object_name
...@@ -81,16 +89,20 @@ class RuleAdmin(admin.ModelAdmin): ...@@ -81,16 +89,20 @@ class RuleAdmin(admin.ModelAdmin):
class AliasAdmin(admin.ModelAdmin): class AliasAdmin(admin.ModelAdmin):
list_display = ('alias', 'host') list_display = ('alias', 'host')
class GroupAdmin(admin.ModelAdmin): class GroupAdmin(admin.ModelAdmin):
list_display = ('name', 'owner', 'description') list_display = ('name', 'owner', 'description')
inlines = (RuleInline, ) inlines = (RuleInline, )
class FirewallAdmin(admin.ModelAdmin): class FirewallAdmin(admin.ModelAdmin):
inlines = (RuleInline, ) inlines = (RuleInline, )
class DomainAdmin(admin.ModelAdmin): class DomainAdmin(admin.ModelAdmin):
list_display = ('name', 'owner') list_display = ('name', 'owner')
class RecordAdmin(admin.ModelAdmin): class RecordAdmin(admin.ModelAdmin):
list_display = ('name_', 'type', 'address_', 'ttl', 'host', 'owner') list_display = ('name_', 'type', 'address_', 'ttl', 'host', 'owner')
...@@ -104,6 +116,7 @@ class RecordAdmin(admin.ModelAdmin): ...@@ -104,6 +116,7 @@ class RecordAdmin(admin.ModelAdmin):
a = instance.get_data() a = instance.get_data()
return a['name'] if a else None return a['name'] if a else None
class BlacklistAdmin(admin.ModelAdmin): class BlacklistAdmin(admin.ModelAdmin):
list_display = ('ipv4', 'reason', 'created_at', 'modified_at') list_display = ('ipv4', 'reason', 'created_at', 'modified_at')
...@@ -116,4 +129,3 @@ admin.site.register(Firewall, FirewallAdmin) ...@@ -116,4 +129,3 @@ admin.site.register(Firewall, FirewallAdmin)
admin.site.register(Domain, DomainAdmin) admin.site.register(Domain, DomainAdmin)
admin.site.register(Record, RecordAdmin) admin.site.register(Record, RecordAdmin)
admin.site.register(Blacklist, BlacklistAdmin) admin.site.register(Blacklist, BlacklistAdmin)
...@@ -6,12 +6,14 @@ from django.utils.ipv6 import is_valid_ipv6_address ...@@ -6,12 +6,14 @@ from django.utils.ipv6 import is_valid_ipv6_address
from south.modelsinspector import add_introspection_rules from south.modelsinspector import add_introspection_rules
import re import re
mac_re = re.compile(r'^([0-9a-fA-F]{2}([:-]?|$)){6}$')
mac_re = re.compile(r'^([0-9a-fA-F]{2}(:|$)){6}$')
alfanum_re = re.compile(r'^[A-Za-z0-9_-]+$') alfanum_re = re.compile(r'^[A-Za-z0-9_-]+$')
domain_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]+)$') ipv4_re = re.compile('^[0-9]+\.([0-9]+)\.([0-9]+)\.([0-9]+)$')
reverse_domain_re = re.compile(r'^(%\([abcd]\)d|[a-z0-9.-])+$') reverse_domain_re = re.compile(r'^(%\([abcd]\)d|[a-z0-9.-])+$')
class MACAddressFormField(fields.RegexField): class MACAddressFormField(fields.RegexField):
default_error_messages = { default_error_messages = {
'invalid': _(u'Enter a valid MAC address.'), 'invalid': _(u'Enter a valid MAC address.'),
...@@ -20,8 +22,10 @@ class MACAddressFormField(fields.RegexField): ...@@ -20,8 +22,10 @@ class MACAddressFormField(fields.RegexField):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super(MACAddressFormField, self).__init__(mac_re, *args, **kwargs) super(MACAddressFormField, self).__init__(mac_re, *args, **kwargs)
class MACAddressField(models.Field): class MACAddressField(models.Field):
empty_strings_allowed = False empty_strings_allowed = False
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
kwargs['max_length'] = 17 kwargs['max_length'] = 17
super(MACAddressField, self).__init__(*args, **kwargs) super(MACAddressField, self).__init__(*args, **kwargs)
...@@ -35,47 +39,68 @@ class MACAddressField(models.Field): ...@@ -35,47 +39,68 @@ class MACAddressField(models.Field):
return super(MACAddressField, self).formfield(**defaults) return super(MACAddressField, self).formfield(**defaults)
add_introspection_rules([], ["firewall\.fields\.MACAddressField"]) add_introspection_rules([], ["firewall\.fields\.MACAddressField"])
def val_alfanum(value): def val_alfanum(value):
"""Validate whether the parameter is a valid alphanumeric value.""" """Validate whether the parameter is a valid alphanumeric value."""
if not alfanum_re.match(value): if not alfanum_re.match(value):
raise ValidationError(_(u'%s - only letters, numbers, underscores ' raise ValidationError(_(u'%s - only letters, numbers, underscores '
'and hyphens are allowed!') % value) 'and hyphens are allowed!') % value)
def is_valid_domain(value): def is_valid_domain(value):
"""Check whether the parameter is a valid domain name.""" """Check whether the parameter is a valid domain name."""
return domain_re.match(value) is not None return domain_re.match(value) is not None
def val_domain(value): def val_domain(value):
"""Validate whether the parameter is a valid domin name.""" """Validate whether the parameter is a valid domin name."""
if not is_valid_domain(value): if not is_valid_domain(value):
raise ValidationError(_(u'%s - invalid domain name') % value) raise ValidationError(_(u'%s - invalid domain name') % value)
def is_valid_reverse_domain(value): def is_valid_reverse_domain(value):
"""Check whether the parameter is a valid reverse domain name.""" """Check whether the parameter is a valid reverse domain name."""
return reverse_domain_re.match(value) is not None return reverse_domain_re.match(value) is not None
def val_reverse_domain(value): def val_reverse_domain(value):
"""Validate whether the parameter is a valid reverse domain name.""" """Validate whether the parameter is a valid reverse domain name."""
if not is_valid_reverse_domain(value): if not is_valid_reverse_domain(value):
raise ValidationError(u'%s - invalid reverse domain name' % value) raise ValidationError(u'%s - invalid reverse domain name' % value)
def is_valid_ipv4_address(value): def is_valid_ipv4_address(value):
"""Check whether the parameter is a valid IPv4 address.""" """Check whether the parameter is a valid IPv4 address."""
return ipv4_re.match(value) is not None return ipv4_re.match(value) is not None
def val_ipv4(value): def val_ipv4(value):
"""Validate whether the parameter is a valid IPv4 address.""" """Validate whether the parameter is a valid IPv4 address."""
if not is_valid_ipv4_address(value): if not is_valid_ipv4_address(value):
raise ValidationError(_(u'%s - not an IPv4 address') % value) raise ValidationError(_(u'%s - not an IPv4 address') % value)
def val_ipv6(value): def val_ipv6(value):
"""Validate whether the parameter is a valid IPv6 address.""" """Validate whether the parameter is a valid IPv6 address."""
if not is_valid_ipv6_address(value): if not is_valid_ipv6_address(value):
raise ValidationError(_(u'%s - not an 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.
Expected form is <priority>:<hostname>.
"""
mx = value.split(':', 1)
if not (len(mx) == 2 and mx[0].isdigit() and
domain_re.match(mx[1])):
raise ValidationError(_("Bad MX address format. "
"Should be: <priority>:<hostname>"))
def ipv4_2_ipv6(ipv4): def ipv4_2_ipv6(ipv4):
"""Convert IPv4 address string to IPv6 address string.""" """Convert IPv4 address string to IPv6 address string."""
val_ipv4(ipv4) val_ipv4(ipv4)
m = ipv4_re.match(ipv4) m = ipv4_re.match(ipv4)
return ("2001:738:2001:4031:%s:%s:%s:0" % 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)))
from celery.task import Task, PeriodicTask from celery.task import Task, PeriodicTask
import celery import celery
from django.core.cache import cache from django.core.cache import cache
import os
import time
from firewall.fw import * from firewall.fw import *
import django.conf import django.conf
settings = django.conf.settings.FIREWALL_SETTINGS settings = django.conf.settings.FIREWALL_SETTINGS
@celery.task @celery.task
def reload_dns_task(data): def reload_dns_task(data):
pass pass
@celery.task @celery.task
def reload_firewall_task(data4, data6): def reload_firewall_task(data4, data6):
pass pass
@celery.task @celery.task
def reload_dhcp_task(data): def reload_dhcp_task(data):
pass pass
@celery.task @celery.task
def reload_blacklist_task(data): def reload_blacklist_task(data):
pass pass
class Periodic(PeriodicTask): class Periodic(PeriodicTask):
run_every = timedelta(seconds=10) run_every = timedelta(seconds=10)
...@@ -48,10 +54,11 @@ class Periodic(PeriodicTask): ...@@ -48,10 +54,11 @@ class Periodic(PeriodicTask):
reload_blacklist_task.delay(list(ipset())) reload_blacklist_task.delay(list(ipset()))
print "blacklist ujratoltese kesz" print "blacklist ujratoltese kesz"
class ReloadTask(Task): class ReloadTask(Task):
def run(self, type='Host'): def run(self, type='Host'):
if type in ["Host", "Records", "Domain", "Vlan"]: if type in ["Host", "Record", "Domain", "Vlan"]:
cache.add("dns_lock", "true", 30) cache.add("dns_lock", "true", 30)
if type == "Host": if type == "Host":
...@@ -64,4 +71,3 @@ class ReloadTask(Task): ...@@ -64,4 +71,3 @@ class ReloadTask(Task):
cache.add("blacklist_lock", "true", 30) cache.add("blacklist_lock", "true", 30)
print type print type
from django.test import TestCase from django.test import TestCase
from admin import HostAdmin from admin import HostAdmin
class MockInstance: class MockInstance:
def __init__(self, groups): def __init__(self, groups):
self.groups = MockGroups(groups) self.groups = MockGroups(groups)
class MockGroup: class MockGroup:
def __init__(self, name): def __init__(self, name):
self.name = name self.name = name
class MockGroups: class MockGroups:
def __init__(self, groups): def __init__(self, groups):
self.groups = groups self.groups = groups
...@@ -16,6 +19,7 @@ class MockGroups: ...@@ -16,6 +19,7 @@ class MockGroups:
def all(self): def all(self):
return self.groups return self.groups
class HostAdminTestCase(TestCase): class HostAdminTestCase(TestCase):
def test_no_groups(self): def test_no_groups(self):
instance = MockInstance([]) instance = MockInstance([])
...@@ -29,6 +33,6 @@ class HostAdminTestCase(TestCase): ...@@ -29,6 +33,6 @@ class HostAdminTestCase(TestCase):
def test_multiple_groups(self): def test_multiple_groups(self):
instance = MockInstance([MockGroup("alma"), instance = MockInstance([MockGroup("alma"),
MockGroup("korte"), MockGroup("szilva")]) MockGroup("korte"), MockGroup("szilva")])
l = HostAdmin.list_groups(instance) l = HostAdmin.list_groups(instance)
self.assertEqual(l, "alma, korte, szilva") self.assertEqual(l, "alma, korte, szilva")
...@@ -2,12 +2,10 @@ import base64 ...@@ -2,12 +2,10 @@ import base64
import datetime import datetime
import json import json
import re import re
import sys
from django.conf import settings from django.conf import settings
from django.db import IntegrityError from django.db import IntegrityError
from django.http import HttpResponse from django.http import HttpResponse
from django.shortcuts import render_to_response
from django.template.loader import render_to_string from django.template.loader import render_to_string
from django.utils import translation from django.utils import translation
from django.utils.timezone import utc from django.utils.timezone import utc
...@@ -15,13 +13,13 @@ from django.utils.translation import ugettext_lazy as _ ...@@ -15,13 +13,13 @@ from django.utils.translation import ugettext_lazy as _
from django.views.decorators.csrf import csrf_exempt from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_POST from django.views.decorators.http import require_POST
from celery.task.control import inspect
from tasks import * from tasks import *
from firewall.fw import * from firewall.fw import *
from firewall.models import * from firewall.models import *
from one.tasks import SendMailTask from one.tasks import SendMailTask
def reload_firewall(request): def reload_firewall(request):
if request.user.is_authenticated(): if request.user.is_authenticated():
if request.user.is_superuser: if request.user.is_superuser:
...@@ -34,36 +32,46 @@ def reload_firewall(request): ...@@ -34,36 +32,46 @@ def reload_firewall(request):
html = _("Dear anonymous, you've not signed in yet!") html = _("Dear anonymous, you've not signed in yet!")
return HttpResponse(html) return HttpResponse(html)
@csrf_exempt @csrf_exempt
@require_POST @require_POST
def firewall_api(request): def firewall_api(request):
try: try:
data=json.loads(base64.b64decode(request.POST["data"])) data = json.loads(base64.b64decode(request.POST["data"]))
command = request.POST["command"] command = request.POST["command"]
if data["password"] != "bdmegintelrontottaanetet": if data["password"] != "bdmegintelrontottaanetet":
raise Exception(_("Wrong password.")) raise Exception(_("Wrong password."))
if command == "blacklist": if command == "blacklist":
obj, created = Blacklist.objects.get_or_create(ipv4=data["ip"]) obj, created = Blacklist.objects.get_or_create(ipv4=data["ip"])
obj.reason=data["reason"] obj.reason = data["reason"]
obj.snort_message=data["snort_message"] obj.snort_message = data["snort_message"]
if created: if created:
try: try:
obj.host = models.Host.objects.get(ipv4=data["ip"]) obj.host = Host.objects.get(ipv4=data["ip"])
user = obj.host.owner user = obj.host.owner
lang = user.person_set.all()[0].language lang = user.person_set.all()[0].language
translation.activate(lang) translation.activate(lang)
msg = render_to_string('mails/notification-ban-now.txt', msg = render_to_string(
{ 'user': user, 'mails/notification-ban-now.txt',
'bl': obj, {
'instance:': obj.host.instance_set.get(), 'user': user,
'url': settings.CLOUD_URL} ) 'bl': obj,
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') 'instance:': obj.host.instance_set.get(),
except (Host.DoesNotExist, ValidationError, IntegrityError, AttributeError): '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 pass
print obj.modified_at + datetime.timedelta(minutes=5)
print datetime.datetime.utcnow().replace(tzinfo=utc) modified = obj.modified_at + datetime.timedelta(minutes=1)
if obj.type == 'tempwhite' and obj.modified_at + datetime.timedelta(minutes=1) < datetime.datetime.utcnow().replace(tzinfo=utc): now = datetime.dateime.utcnow().replace(tzinfo=utc)
if obj.type == 'tempwhite' and modified < now:
obj.type = 'tempban' obj.type = 'tempban'
obj.save() obj.save()
return HttpResponse(unicode(_("OK"))) return HttpResponse(unicode(_("OK")))
...@@ -76,28 +84,27 @@ def firewall_api(request): ...@@ -76,28 +84,27 @@ def firewall_api(request):
if command == "create": if command == "create":
data["owner"] = "opennebula" data["owner"] = "opennebula"
owner = auth.models.User.objects.get(username=data["owner"]) owner = auth.models.User.objects.get(username=data["owner"])
host = models.Host(hostname=data["hostname"], host = Host(hostname=data["hostname"],
vlan=models.Vlan.objects.get(name=data["vlan"]), vlan=Vlan.objects.get(name=data["vlan"]),
mac=data["mac"], ipv4=data["ip"], owner=owner, mac=data["mac"], ipv4=data["ip"], owner=owner,
description=data["description"], pub_ipv4=models. description=data["description"], pub_ipv4=
Vlan.objects.get(name=data["vlan"]).snat_ip, Vlan.objects.get(name=data["vlan"]).snat_ip,
shared_ip=True) shared_ip=True)
host.full_clean() host.full_clean()
host.save() host.save()
host.enable_net() host.enable_net()
for p in data["portforward"]: for p in data["portforward"]:
host.add_port(proto=p["proto"], host.add_port(proto=p["proto"], public=int(p["public_port"]),
public=int(p["public_port"]), private=int(p["private_port"]))
private=int(p["private_port"]))
elif command == "destroy": elif command == "destroy":
data["owner"] = "opennebula" data["owner"] = "opennebula"
print data["hostname"] print data["hostname"]
owner = auth.models.User.objects.get(username=data["owner"]) owner = auth.models.User.objects.get(username=data["owner"])
host = models.Host.objects.get(hostname=data["hostname"], host = Host.objects.get(hostname=data["hostname"],
owner=owner) owner=owner)
host.delete() host.delete()
else: else:
......
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