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 django.contrib import auth
from firewall import models from firewall import models
import os
import django.conf import django.conf
import subprocess import subprocess
import re import re
import json
from datetime import datetime, timedelta from datetime import datetime, timedelta
from django.db.models import Q from django.db.models import Q
settings = django.conf.settings.FIREWALL_SETTINGS settings = django.conf.settings.FIREWALL_SETTINGS
class Firewall: class Firewall:
IPV6=False IPV6 = False
RULES = None RULES = None
RULES_NAT = [] RULES_NAT = []
vlans = None vlans = None
dmz = None
pub = None pub = None
hosts = None hosts = None
fw = None fw = None
...@@ -30,13 +28,12 @@ class Firewall: ...@@ -30,13 +28,12 @@ class Firewall:
retval += ' --sport %s ' % rule.sport retval += ' --sport %s ' % rule.sport
if rule.dport: if rule.dport:
retval += ' --dport %s ' % (rule.nat_dport retval += ' --dport %s ' % (rule.nat_dport
if (repl and rule.nat and rule.direction == '1') if (repl and rule.nat and rule.direction == '1')
else rule.dport) else rule.dport)
elif rule.proto == 'icmp': elif rule.proto == 'icmp':
retval = '-p %s ' % rule.proto retval = '-p %s ' % rule.proto
return retval return retval
def iptables(self, s): def iptables(self, s):
"""Append rule to filter table.""" """Append rule to filter table."""
self.RULES.append(s) self.RULES.append(s)
...@@ -61,8 +58,8 @@ class Firewall: ...@@ -61,8 +58,8 @@ class Firewall:
if rule.direction == '0' and vlan.name == 'PUB': if rule.direction == '0' and vlan.name == 'PUB':
if rule.dport == 25: if rule.dport == 25:
self.iptables('-A PUB_OUT -s %s %s -p tcp ' self.iptables('-A PUB_OUT -s %s %s -p tcp '
'--dport 25 -j LOG_ACC' % '--dport 25 -j LOG_ACC' %
(ipaddr, rule.extra)) (ipaddr, rule.extra))
break break
action = 'PUB_OUT' action = 'PUB_OUT'
else: else:
...@@ -70,13 +67,14 @@ class Firewall: ...@@ -70,13 +67,14 @@ class Firewall:
else: else:
action = 'LOG_DROP' action = 'LOG_DROP'
if rule.direction == '1': # going TO host if rule.direction == '1': # going TO host
self.iptables('-A %s_%s -d %s %s %s -g %s' % (vlan, self.iptables('-A %s_%s -d %s %s %s -g %s' %
host.vlan, ipaddr, dport_sport, rule.extra, action)) (vlan, host.vlan, ipaddr, dport_sport,
rule.extra, action))
else: else:
self.iptables('-A %s_%s -s %s %s %s -g %s' % (host.vlan, self.iptables('-A %s_%s -s %s %s %s -g %s' %
vlan, ipaddr, dport_sport, rule.extra, action)) (host.vlan, vlan, ipaddr, dport_sport,
rule.extra, action))
def fw2vlan(self, rule): def fw2vlan(self, rule):
if not rule.foreign_network: if not rule.foreign_network:
...@@ -85,14 +83,14 @@ class Firewall: ...@@ -85,14 +83,14 @@ class Firewall:
dport_sport = self.dportsport(rule) dport_sport = self.dportsport(rule)
for vlan in rule.foreign_network.vlans.all(): 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' % self.iptables('-A INPUT -i %s %s %s -g %s' %
(vlan.interface, dport_sport, rule.extra, (vlan.interface, dport_sport, rule.extra,
'LOG_ACC' if rule.accept else 'LOG_DROP')) 'LOG_ACC' if rule.accept else 'LOG_DROP'))
else: else:
self.iptables('-A OUTPUT -o %s %s %s -g %s' % self.iptables('-A OUTPUT -o %s %s %s -g %s' %
(vlan.interface, dport_sport, rule.extra, (vlan.interface, dport_sport, rule.extra,
'LOG_ACC' if rule.accept else 'LOG_DROP')) 'LOG_ACC' if rule.accept else 'LOG_DROP'))
def vlan2vlan(self, l_vlan, rule): def vlan2vlan(self, l_vlan, rule):
if not rule.foreign_network: if not rule.foreign_network:
...@@ -109,13 +107,13 @@ class Firewall: ...@@ -109,13 +107,13 @@ class Firewall:
else: else:
action = 'LOG_DROP' action = 'LOG_DROP'
if rule.direction == '1': # going TO host if rule.direction == '1': # going TO host
self.iptables('-A %s_%s %s %s -g %s' % (vlan, l_vlan, self.iptables('-A %s_%s %s %s -g %s' %
dport_sport, rule.extra, action)) (vlan, l_vlan, dport_sport, rule.extra, action))
else: else:
self.iptables('-A %s_%s %s %s -g %s' % (l_vlan, vlan, 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): def prerun(self):
self.iptables('*filter') self.iptables('*filter')
...@@ -129,39 +127,39 @@ class Firewall: ...@@ -129,39 +127,39 @@ class Firewall:
self.iptables('-A LOG_DROP -p tcp --dport 445 -j DROP') 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 -p udp --dport 137 -j DROP')
self.iptables('-A LOG_DROP -j LOG --log-level 7 ' 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('-A LOG_DROP -j DROP')
self.iptables('-N LOG_ACC') self.iptables('-N LOG_ACC')
self.iptables('-A LOG_ACC -j LOG --log-level 7 ' 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('-A LOG_ACC -j ACCEPT')
self.iptables('-N PUB_OUT') 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 INVALID -g LOG_DROP')
self.iptables('-A FORWARD -m state --state ESTABLISHED,RELATED ' self.iptables('-A FORWARD -m state --state ESTABLISHED,RELATED '
'-j ACCEPT') '-j ACCEPT')
self.iptables('-A FORWARD -p icmp --icmp-type echo-request ' 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 set --match-set blacklist src -j DROP')
self.iptables('-A INPUT -m state --state INVALID -g LOG_DROP') self.iptables('-A INPUT -m state --state INVALID -g LOG_DROP')
self.iptables('-A INPUT -i lo -j ACCEPT') self.iptables('-A INPUT -i lo -j ACCEPT')
self.iptables('-A INPUT -m state --state ESTABLISHED,RELATED ' 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 -m state --state INVALID -g LOG_DROP')
self.iptables('-A OUTPUT -o lo -j ACCEPT') self.iptables('-A OUTPUT -o lo -j ACCEPT')
self.iptables('-A OUTPUT -m state --state ESTABLISHED,RELATED ' self.iptables('-A OUTPUT -m state --state ESTABLISHED,RELATED '
'-j ACCEPT') '-j ACCEPT')
def postrun(self): def postrun(self):
self.iptables('-A PUB_OUT -s 152.66.243.160/27 -p tcp --dport 25 ' 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 ' 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 25 -j LOG_DROP')
self.iptables('-A PUB_OUT -p tcp --dport 445 -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') self.iptables('-A PUB_OUT -p udp --dport 445 -j LOG_DROP')
...@@ -172,9 +170,6 @@ class Firewall: ...@@ -172,9 +170,6 @@ class Firewall:
self.iptables('-A OUTPUT -g LOG_DROP') self.iptables('-A OUTPUT -g LOG_DROP')
self.iptables('COMMIT') self.iptables('COMMIT')
def ipt_nat(self): def ipt_nat(self):
self.iptablesnat('*nat') self.iptablesnat('*nat')
self.iptablesnat(':PREROUTING ACCEPT [0:0]') self.iptablesnat(':PREROUTING ACCEPT [0:0]')
...@@ -188,34 +183,37 @@ class Firewall: ...@@ -188,34 +183,37 @@ class Firewall:
dport_sport = self.dportsport(rule, False) dport_sport = self.dportsport(rule, False)
if host.vlan.snat_ip: if host.vlan.snat_ip:
self.iptablesnat('-A PREROUTING -d %s %s %s -j DNAT ' self.iptablesnat('-A PREROUTING -d %s %s %s -j DNAT '
'--to-destination %s:%s' % (host.pub_ipv4, '--to-destination %s:%s' %
dport_sport, rule.extra, host.ipv4, (host.pub_ipv4, dport_sport, rule.extra,
rule.nat_dport)) host.ipv4, rule.nat_dport))
# rules for machines with dedicated public IP # rules for machines with dedicated public IP
for host in self.hosts.exclude(shared_ip=True): for host in self.hosts.exclude(shared_ip=True):
if host.pub_ipv4: if host.pub_ipv4:
self.iptablesnat('-A PREROUTING -d %s -j DNAT ' 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 ' 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 # default NAT rules for VLANs
for s_vlan in self.vlans: for s_vlan in self.vlans:
if s_vlan.snat_ip: if s_vlan.snat_ip:
for d_vlan in s_vlan.snat_to.all(): for d_vlan in s_vlan.snat_to.all():
self.iptablesnat('-A POSTROUTING -s %s -o %s -j SNAT ' self.iptablesnat('-A POSTROUTING -s %s -o %s -j SNAT '
'--to-source %s' % (s_vlan.net_ipv4(), '--to-source %s' %
d_vlan.interface, s_vlan.snat_ip)) (s_vlan.net_ipv4(), d_vlan.interface,
s_vlan.snat_ip))
# hard-wired rules # hard-wired rules
self.iptablesnat('-A POSTROUTING -s 10.5.0.0/16 -o vlan0003 -j SNAT ' 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 -s 10.5.0.0/16 -o vlan0008 -j SNAT ' self.iptablesnat('-A POSTROUTING -o vlan0008 -j SNAT '
'--to-source 10.0.0.247') # wolf network for printing '--to-source 10.0.0.247') # wolf network for printing
self.iptablesnat('-A POSTROUTING -s 10.3.0.0/16 -o vlan0002 -j SNAT ' self.iptablesnat('-A POSTROUTING -s 10.3.0.0/16 -p udp --dport 53 '
'--to-source %s' % self.pub.ipv4) # kulonben nemmegy a du '-o vlan0002 -j SNAT ''--to-source %s' %
self.pub.ipv4) # kulonben nem megy a dns man-ban
self.iptablesnat('COMMIT') self.iptablesnat('COMMIT')
...@@ -235,7 +233,8 @@ class Firewall: ...@@ -235,7 +233,8 @@ class Firewall:
for d_vlan in self.vlans: for d_vlan in self.vlans:
self.iptables('-N %s_%s' % (s_vlan, d_vlan)) self.iptables('-N %s_%s' % (s_vlan, d_vlan))
self.iptables('-A FORWARD -i %s -o %s -g %s_%s' % 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 # hosts' rules
for i_vlan in self.vlans: for i_vlan in self.vlans:
...@@ -264,12 +263,11 @@ class Firewall: ...@@ -264,12 +263,11 @@ class Firewall:
self.RULES = [x.replace('icmp', 'icmpv6') for x in self.RULES] self.RULES = [x.replace('icmp', 'icmpv6') for x in self.RULES]
def __init__(self, IPV6=False): def __init__(self, IPV6=False):
self.RULES=[] self.RULES = []
self.RULES_NAT=[] self.RULES_NAT = []
self.IPV6 = IPV6 self.IPV6 = IPV6
self.vlans = models.Vlan.objects.all() self.vlans = models.Vlan.objects.all()
self.hosts = models.Host.objects.all() self.hosts = models.Host.objects.all()
self.dmz = models.Vlan.objects.get(name='DMZ')
self.pub = models.Vlan.objects.get(name='PUB') self.pub = models.Vlan.objects.get(name='PUB')
self.fw = models.Firewall.objects.all() self.fw = models.Firewall.objects.all()
self.ipt_filter() self.ipt_filter()
...@@ -279,32 +277,37 @@ class Firewall: ...@@ -279,32 +277,37 @@ class Firewall:
def reload(self): def reload(self):
if self.IPV6: if self.IPV6:
process = subprocess.Popen(['/usr/bin/ssh', 'fw2', process = subprocess.Popen(['/usr/bin/ssh', 'fw2',
'/usr/bin/sudo', '/sbin/ip6tables-restore', '-c'], '/usr/bin/sudo',
shell=False, stdin=subprocess.PIPE) '/sbin/ip6tables-restore', '-c'],
shell=False, stdin=subprocess.PIPE)
process.communicate('\n'.join(self.RULES) + '\n') process.communicate('\n'.join(self.RULES) + '\n')
else: else:
process = subprocess.Popen(['/usr/bin/ssh', 'fw2', process = subprocess.Popen(['/usr/bin/ssh', 'fw2',
'/usr/bin/sudo', '/sbin/iptables-restore', '-c'], '/usr/bin/sudo',
shell=False, stdin=subprocess.PIPE) '/sbin/iptables-restore', '-c'],
shell=False, stdin=subprocess.PIPE)
process.communicate('\n'.join(self.RULES) + '\n' + process.communicate('\n'.join(self.RULES) + '\n' +
'\n'.join(self.RULES_NAT) + '\n') '\n'.join(self.RULES_NAT) + '\n')
def get(self): def get(self):
if self.IPV6: if self.IPV6:
return { 'filter': self.RULES, } return {'filter': self.RULES, }
else: else:
return { 'filter': self.RULES, 'nat': self.RULES_NAT } return {'filter': self.RULES, 'nat': self.RULES_NAT}
def show(self): def show(self):
if self.IPV6: if self.IPV6:
return '\n'.join(self.RULES) + '\n' return '\n'.join(self.RULES) + '\n'
else: else:
return ('\n'.join(self.RULES) + '\n' + return ('\n'.join(self.RULES) + '\n' +
'\n'.join(self.RULES_NAT) + '\n') '\n'.join(self.RULES_NAT) + '\n')
def ipset(): def ipset():
week = datetime.now()-timedelta(days=2) week = datetime.now() - timedelta(days=2)
return models.Blacklist.objects.filter(Q(type='tempban', modified_at__gte=week) | Q(type='permban')).values('ipv4', 'reason') 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): def ipv6_to_octal(ipv6):
...@@ -321,14 +324,16 @@ def ipv6_to_octal(ipv6): ...@@ -321,14 +324,16 @@ def ipv6_to_octal(ipv6):
octets.append(int(part[2:], 16)) octets.append(int(part[2:], 16))
return '\\' + '\\'.join(['%03o' % x for x in octets]) return '\\' + '\\'.join(['%03o' % x for x in octets])
def ipv4_to_arpa(ipv4, cname=False): def ipv4_to_arpa(ipv4, cname=False):
m2 = re.search(r'^([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)$', ipv4) m2 = re.search(r'^([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)$', ipv4)
if cname: if cname:
return ('%s.dns1.%s.%s.%s.in-addr.arpa' % return ('%s.dns1.%s.%s.%s.in-addr.arpa' %