Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
Gelencsér Szabolcs
/
circlestack
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
43391a3d
authored
Sep 04, 2013
by
Őry Máté
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
firewall: merge from network-gui
parent
a8c081dc
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
1295 additions
and
340 deletions
+1295
-340
circle/firewall/admin.py
+29
-17
circle/firewall/fields.py
+28
-3
circle/firewall/fw.py
+99
-106
circle/firewall/locale/hu/LC_MESSAGES/django.po
+572
-0
circle/firewall/models.py
+518
-182
circle/firewall/tasks.py
+10
-4
circle/firewall/tests.py
+5
-1
circle/firewall/views.py
+34
-27
No files found.
circle/firewall/admin.py
View file @
43391a3d
# -*- 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
)
circle/firewall/fields.py
View file @
43391a3d
...
@@ -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
)))
circle/firewall/fw.py
View file @
43391a3d
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
([
'
%03
o'
%
x
for
x
in
octets
])
return
'
\\
'
+
'
\\
'
.
join
([
'
%03
o'
%
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'
%
(
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
:
else
:
return
(
'
%
s.
%
s.
%
s.
%
s.in-addr.arpa'
%
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
):
def
ipv6_to_arpa
(
ipv6
):
while
len
(
ipv6
.
split
(
':'
))
<
8
:
while
len
(
ipv6
.
split
(
':'
))
<
8
:
...
@@ -357,11 +362,11 @@ def ipv6_to_arpa(ipv6):
...
@@ -357,11 +362,11 @@ def ipv6_to_arpa(ipv6):
def
dns
():
def
dns
():
vlans
=
models
.
Vlan
.
objects
.
all
()
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
=
[]
DNS
=
[]
for
i_vlan
in
vlans
:
for
i_vlan
in
vlans
:
m
=
regex
.
search
(
i_vlan
.
net4
)
#
m = regex.search(i_vlan.net4)
rev
=
i_vlan
.
reverse_domain
rev
=
i_vlan
.
reverse_domain
for
i_host
in
i_vlan
.
host_set
.
all
():
for
i_host
in
i_vlan
.
host_set
.
all
():
...
@@ -369,31 +374,32 @@ def dns():
...
@@ -369,31 +374,32 @@ def dns():
not
i_host
.
shared_ip
else
i_host
.
ipv4
)
not
i_host
.
shared_ip
else
i_host
.
ipv4
)
i
=
ipv4
.
split
(
'.'
,
4
)
i
=
ipv4
.
split
(
'.'
,
4
)
reverse
=
(
i_host
.
reverse
if
i_host
.
reverse
and
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
# ipv4
if
i_host
.
ipv4
:
if
i_host
.
ipv4
:
DNS
.
append
(
"^
%
s:
%
s:
%
s"
%
(
DNS
.
append
(
"^
%
s:
%
s:
%
s"
%
(
(
rev
%
{
'a'
:
int
(
i
[
0
]),
'b'
:
int
(
i
[
1
]),
'c'
:
int
(
i
[
2
]),
(
rev
%
{
'a'
:
int
(
i
[
0
]),
'b'
:
int
(
i
[
1
]),
'c'
:
int
(
i
[
2
]),
'd'
:
int
(
i
[
3
])
}),
'd'
:
int
(
i
[
3
])
}),
reverse
,
models
.
settings
[
'dns_ttl'
]))
reverse
,
models
.
settings
[
'dns_ttl'
]))
# ipv6
# ipv6
if
i_host
.
ipv6
:
if
i_host
.
ipv6
:
DNS
.
append
(
"^
%
s:
%
s:
%
s"
%
(
ipv6_to_arpa
(
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
():
for
domain
in
models
.
Domain
.
objects
.
all
():
DNS
.
append
(
"Z
%
s:
%
s:support.ik.bme.hu::::::
%
s"
%
(
domain
.
name
,
DNS
.
append
(
"Z
%
s:
%
s:support.ik.bme.hu::::::
%
s"
%
settings
[
'dns_hostname'
],
models
.
settings
[
'dns_ttl'
]))
(
domain
.
name
,
settings
[
'dns_hostname'
],
models
.
settings
[
'dns_ttl'
]))
for
r
in
models
.
Record
.
objects
.
all
():
for
r
in
models
.
Record
.
objects
.
all
():
d
=
r
.
get_data
()
d
=
r
.
get_data
()
if
d
[
'type'
]
==
'A'
:
if
d
[
'type'
]
==
'A'
:
DNS
.
append
(
"+
%
s:
%
s:
%
s"
%
(
d
[
'name'
],
d
[
'address'
],
d
[
'ttl'
]))
DNS
.
append
(
"+
%
s:
%
s:
%
s"
%
(
d
[
'name'
],
d
[
'address'
],
d
[
'ttl'
]))
elif
d
[
'type'
]
==
'AAAA'
:
elif
d
[
'type'
]
==
'AAAA'
:
DNS
.
append
(
":
%
s:28:
%
s:
%
s"
%
(
d
[
'name'
],
DNS
.
append
(
":
%
s:28:
%
s:
%
s"
%
ipv6_to_octal
(
d
[
'address'
]),
d
[
'ttl'
]))
(
d
[
'name'
],
ipv6_to_octal
(
d
[
'address'
]),
d
[
'ttl'
]))
elif
d
[
'type'
]
==
'NS'
:
elif
d
[
'type'
]
==
'NS'
:
DNS
.
append
(
"&
%
s::
%
s:
%
s"
%
(
d
[
'name'
],
d
[
'address'
],
d
[
'ttl'
]))
DNS
.
append
(
"&
%
s::
%
s:
%
s"
%
(
d
[
'name'
],
d
[
'address'
],
d
[
'ttl'
]))
elif
d
[
'type'
]
==
'CNAME'
:
elif
d
[
'type'
]
==
'CNAME'
:
...
@@ -401,15 +407,16 @@ def dns():
...
@@ -401,15 +407,16 @@ def dns():
elif
d
[
'type'
]
==
'MX'
:
elif
d
[
'type'
]
==
'MX'
:
mx
=
d
[
'address'
]
.
split
(
':'
,
2
)
mx
=
d
[
'address'
]
.
split
(
':'
,
2
)
DNS
.
append
(
"@
%(fqdn)
s::
%(mx)
s:
%(dist)
s:
%(ttl)
s"
%
DNS
.
append
(
"@
%(fqdn)
s::
%(mx)
s:
%(dist)
s:
%(ttl)
s"
%
{
'fqdn'
:
d
[
'name'
],
'mx'
:
mx
[
1
],
'dist'
:
mx
[
0
],
{
'fqdn'
:
d
[
'name'
],
'mx'
:
mx
[
1
],
'dist'
:
mx
[
0
],
'ttl'
:
d
[
'ttl'
]})
'ttl'
:
d
[
'ttl'
]})
elif
d
[
'type'
]
==
'PTR'
:
elif
d
[
'type'
]
==
'PTR'
:
DNS
.
append
(
"^
%
s:
%
s:
%
s"
%
(
d
[
'name'
],
d
[
'address'
],
d
[
'ttl'
]))
DNS
.
append
(
"^
%
s:
%
s:
%
s"
%
(
d
[
'name'
],
d
[
'address'
],
d
[
'ttl'
]))
return
DNS
return
DNS
process
=
subprocess
.
Popen
([
'/usr/bin/ssh'
,
'tinydns@
%
s'
%
process
=
subprocess
.
Popen
([
'/usr/bin/ssh'
,
'tinydns@
%
s'
%
settings
[
'dns_hostname'
]],
shell
=
False
,
stdin
=
subprocess
.
PIPE
)
settings
[
'dns_hostname'
]],
process
.
communicate
(
"
\n
"
.
join
(
DNS
)
+
"
\n
"
)
shell
=
False
,
stdin
=
subprocess
.
PIPE
)
process
.
communicate
(
"
\n
"
.
join
(
DNS
)
+
"
\n
"
)
# print "\n".join(DNS)+"\n"
# print "\n".join(DNS)+"\n"
...
@@ -422,10 +429,11 @@ def prefix_to_mask(prefix):
...
@@ -422,10 +429,11 @@ def prefix_to_mask(prefix):
t
[
i
]
=
256
-
(
2
**
((
i
+
1
)
*
8
-
prefix
))
t
[
i
]
=
256
-
(
2
**
((
i
+
1
)
*
8
-
prefix
))
return
"."
.
join
([
str
(
i
)
for
i
in
t
])
return
"."
.
join
([
str
(
i
)
for
i
in
t
])
def
dhcp
():
def
dhcp
():
vlans
=
models
.
Vlan
.
objects
.
all
()
vlans
=
models
.
Vlan
.
objects
.
all
()
regex
=
re
.
compile
(
r'^([0-9]+)\.([0-9]+)\.[0-9]+\.[0-9]+\s+'
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
=
[]
DHCP
=
[]
# /tools/dhcp3/dhcpd.conf.generated
# /tools/dhcp3/dhcpd.conf.generated
...
@@ -434,7 +442,7 @@ def dhcp():
...
@@ -434,7 +442,7 @@ def dhcp():
if
(
i_vlan
.
dhcp_pool
):
if
(
i_vlan
.
dhcp_pool
):
m
=
regex
.
search
(
i_vlan
.
dhcp_pool
)
m
=
regex
.
search
(
i_vlan
.
dhcp_pool
)
if
(
m
or
i_vlan
.
dhcp_pool
==
"manual"
):
if
(
m
or
i_vlan
.
dhcp_pool
==
"manual"
):
DHCP
.
append
(
'''
DHCP
.
append
(
'''
#
%(name)
s -
%(interface)
s
#
%(name)
s -
%(interface)
s
subnet
%(net)
s netmask
%(netmask)
s {
subnet
%(net)
s netmask
%(netmask)
s {
%(extra)
s;
%(extra)
s;
...
@@ -446,7 +454,7 @@ def dhcp():
...
@@ -446,7 +454,7 @@ def dhcp():
authoritative;
authoritative;
filename
\"
pxelinux.0
\"
;
filename
\"
pxelinux.0
\"
;
allow bootp; allow booting;
allow bootp; allow booting;
}'''
%
{
}'''
%
{
'net'
:
i_vlan
.
net4
,
'net'
:
i_vlan
.
net4
,
'netmask'
:
prefix_to_mask
(
i_vlan
.
prefix4
),
'netmask'
:
prefix_to_mask
(
i_vlan
.
prefix4
),
'domain'
:
i_vlan
.
domain
,
'domain'
:
i_vlan
.
domain
,
...
@@ -454,14 +462,14 @@ def dhcp():
...
@@ -454,14 +462,14 @@ def dhcp():
'ntp'
:
i_vlan
.
ipv4
,
'ntp'
:
i_vlan
.
ipv4
,
'dnsserver'
:
settings
[
'rdns_ip'
],
'dnsserver'
:
settings
[
'rdns_ip'
],
'extra'
:
(
"range
%
s"
%
i_vlan
.
dhcp_pool
'extra'
:
(
"range
%
s"
%
i_vlan
.
dhcp_pool
if
m
else
"deny unknown-clients"
),
if
m
else
"deny unknown-clients"
),
'interface'
:
i_vlan
.
interface
,
'interface'
:
i_vlan
.
interface
,
'name'
:
i_vlan
.
name
,
'name'
:
i_vlan
.
name
,
'tftp'
:
i_vlan
.
ipv4
'tftp'
:
i_vlan
.
ipv4
})
})
for
i_host
in
i_vlan
.
host_set
.
all
():
for
i_host
in
i_vlan
.
host_set
.
all
():
DHCP
.
append
(
'''
DHCP
.
append
(
'''
host
%(hostname)
s {
host
%(hostname)
s {
hardware ethernet
%(mac)
s;
hardware ethernet
%(mac)
s;
fixed-address
%(ipv4)
s;
fixed-address
%(ipv4)
s;
...
@@ -473,23 +481,8 @@ def dhcp():
...
@@ -473,23 +481,8 @@ def dhcp():
return
DHCP
return
DHCP
process
=
subprocess
.
Popen
([
'/usr/bin/ssh'
,
'fw2'
,
process
=
subprocess
.
Popen
([
'/usr/bin/ssh'
,
'fw2'
,
'cat > /tools/dhcp3/dhcpd.conf.generated;'
'cat > /tools/dhcp3/dhcpd.conf.generated;'
'sudo /etc/init.d/isc-dhcp-server restart'
],
shell
=
False
,
'sudo /etc/init.d/isc-dhcp-server restart'
]
,
stdin
=
subprocess
.
PIPE
)
shell
=
False
,
stdin
=
subprocess
.
PIPE
)
# print "\n".join(DHCP)+"\n"
# print "\n".join(DHCP)+"\n"
process
.
communicate
(
"
\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
'''
circle/firewall/locale/hu/LC_MESSAGES/django.po
0 → 100644
View file @
43391a3d
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-08-21 12:29+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
#: fields.py:19
msgid "Enter a valid MAC address."
msgstr ""
#: fields.py:46
#, python-format
msgid "%s - only letters, numbers, underscores and hyphens are allowed!"
msgstr ""
#: fields.py:58
#, python-format
msgid "%s - invalid domain name"
msgstr ""
#: fields.py:80
#, python-format
msgid "%s - not an IPv4 address"
msgstr "%s - nem egy IPv4 cím"
#: fields.py:86
#, python-format
msgid "%s - not an IPv6 address"
msgstr ""
#: fields.py:97
msgid "Bad MX address format. Should be: <priority>:<hostname>"
msgstr ""
#: models.py:33
msgid "direction"
msgstr ""
#: models.py:34
msgid "If the rule matches egress or ingress packets."
msgstr ""
#: models.py:36 models.py:222 models.py:284 models.py:307 models.py:366
#: models.py:591 models.py:615
msgid "description"
msgstr ""
#: models.py:37
msgid "Why is the rule needed, or how does it work."
msgstr ""
#: models.py:40
msgid "foreign network"
msgstr ""
#: models.py:41
msgid ""
"The group of vlans the matching packet goes to (direction out) or from (in)."
msgstr ""
#: models.py:45
msgid "dest. port"
msgstr ""
#: models.py:47
msgid "Destination port number of packets that match."
msgstr ""
#: models.py:49
msgid "source port"
msgstr ""
#: models.py:51
msgid "Source port number of packets that match."
msgstr ""
#: models.py:53
msgid "protocol"
msgstr ""
#: models.py:54
msgid "Protocol of packets that match."
msgstr ""
#: models.py:55
msgid "extra arguments"
msgstr ""
#: models.py:56
msgid "Additional arguments passed literally to the iptables-rule."
msgstr ""
#: models.py:58
msgid "accept"
msgstr ""
#: models.py:59
msgid "Accept the matching packets (or deny if not checked)."
msgstr ""
#: models.py:62 models.py:253 models.py:287 models.py:310 models.py:377
#: models.py:585 models.py:614
msgid "owner"
msgstr ""
#: models.py:63
msgid "The user responsible for this rule."
msgstr ""
#: models.py:65
msgid "Rule type"
msgstr ""
#: models.py:67
msgid "The type of entity the rule belongs to."
msgstr ""
#: models.py:69
msgid "NAT"
msgstr ""
#: models.py:70
msgid "If network address translation shoud be done."
msgstr ""
#: models.py:74
msgid "Rewrite destination port number to."
msgstr ""
#: models.py:79 models.py:251 models.py:289 models.py:312 models.py:385
msgid "created at"
msgstr ""
#: models.py:82 models.py:255 models.py:291 models.py:314 models.py:387
msgid "modified at"
msgstr ""
#: models.py:85 models.py:374
msgid "vlan"
msgstr ""
#: models.py:86
msgid "Vlan the rule applies to (if type is vlan)."
msgstr ""
#: models.py:90
msgid "vlan group"
msgstr ""
#: models.py:91
msgid "Group of vlans the rule applies to (if type is vlan)."
msgstr ""
#: models.py:94 models.py:608 models.py:730
msgid "host"
msgstr ""
#: models.py:95
msgid "Host the rule applies to (if type is host)."
msgstr ""
#: models.py:98
msgid "host group"
msgstr ""
#: models.py:99
msgid "Group of hosts the rule applies to (if type is host)."
msgstr ""
#: models.py:102
msgid "firewall"
msgstr ""
#: models.py:103
msgid "Firewall the rule applies to (if type is firewall)."
msgstr ""
#: models.py:115
msgid "Only one field can be selected."
msgstr ""
#: models.py:136
msgid "rule"
msgstr ""
#: models.py:137
msgid "rules"
msgstr ""
#: models.py:163
msgid "VID"
msgstr ""
#: models.py:164
msgid "The vlan ID of the subnet."
msgstr ""
#: models.py:169
msgid "Name"
msgstr ""
#: models.py:170
msgid "The short name of the subnet."
msgstr ""
#: models.py:173
msgid "IPv4 prefix length"
msgstr ""
#: models.py:174
msgid "The prefix length of the IPv4 subnet."
msgstr ""
#: models.py:176
msgid "IPv6 prefix length"
msgstr ""
#: models.py:177
msgid "The prefix length of the IPv6 subnet."
msgstr ""
#: models.py:179
msgid "interface"
msgstr ""
#: models.py:180
msgid ""
"The name of network interface the gateway should serve this network on. For "
"example vlan0004 or eth2."
msgstr ""
#: models.py:184
msgid "IPv4 network"
msgstr ""
#: models.py:185
msgid "The network address of the IPv4 subnet."
msgstr ""
#: models.py:188
msgid "IPv6 network"
msgstr ""
#: models.py:189
msgid "The network address of the IPv6 subnet."
msgstr ""
#: models.py:192 models.py:346
msgid "IPv4 address"
msgstr ""
#: models.py:194
msgid ""
"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."
msgstr ""
#: models.py:201 models.py:357
msgid "IPv6 address"
msgstr ""
#: models.py:203
msgid "The IPv6 address of the gateway."
msgstr ""
#: models.py:207
msgid "NAT IP address"
msgstr ""
#: models.py:209
msgid ""
"Common IPv4 address used for address translation of connections to the "
"networks selected below (typically to the internet)."
msgstr ""
#: models.py:215
msgid "NAT to"
msgstr ""
#: models.py:217
msgid ""
"Connections to these networks should be network address translated, i.e. "
"their source address is rewritten to the value of NAT IP address."
msgstr ""
#: models.py:224
msgid "Description of the goals and elements of the vlan network."
msgstr ""
#: models.py:226
msgid "comment"
msgstr ""
#: models.py:228
msgid "Notes, comments about the network"
msgstr ""
#: models.py:229
msgid "domain name"
msgstr ""
#: models.py:230
msgid "Domain name of the members of this network."
msgstr ""
#: models.py:234
msgid "reverse domain"
msgstr ""
#: models.py:235
#, python-format
msgid ""
"Template of the IPv4 reverse domain name that should be generated for each "
"host. The template should contain four tokens: \"%(a)d\", \"%(b)d\", \"%(c)d"
"\", and \"%(d)d\", representing the four bytes of the address, respectively, "
"in decimal notation. For example, the template for the standard reverse "
"address is: \"%(d)d.%(c)d.%(b)d.%(a)d.in-addr.arpa\"."
msgstr ""
#: models.py:243
msgid "DHCP pool"
msgstr ""
#: models.py:245
msgid ""
"The address range of the DHCP pool: empty for no DHCP service, \"manual\" "
"for no DHCP pool, or the first and last address of the range separated by a "
"space."
msgstr ""
#: models.py:278 models.py:305 models.py:576 models.py:584 models.py:605
msgid "name"
msgstr ""
#: models.py:279 models.py:306
msgid "The name of the group."
msgstr ""
#: models.py:281
msgid "vlans"
msgstr ""
#: models.py:282
msgid "The vlans which are members of the group."
msgstr ""
#: models.py:285 models.py:308
msgid "Description of the group."
msgstr ""
#: models.py:330
msgid "hostname"
msgstr ""
#: models.py:331
msgid "The alphanumeric hostname of the host, the first part of the FQDN."
msgstr ""
#: models.py:336
msgid "reverse"
msgstr ""
#: models.py:337
msgid ""
"The fully qualified reverse hostname of the host, if different than hostname."
"domain."
msgstr ""
#: models.py:341
msgid "MAC address"
msgstr ""
#: models.py:342
msgid ""
"The MAC (Ethernet) address of the network interface. For example: 99:AA:BB:"
"CC:DD:EE."
msgstr ""
#: models.py:348
msgid "The real IPv4 address of the host, for example 10.5.1.34."
msgstr ""
#: models.py:352
msgid "WAN IPv4 address"
msgstr ""
#: models.py:353
msgid ""
"The public IPv4 address of the host on the wide area network, if different."
msgstr ""
#: models.py:359
msgid "The global IPv6 address of the host, for example 2001:500:88:200::10."
msgstr ""
#: models.py:362
msgid "shared IP"
msgstr ""
#: models.py:364
msgid "If the given WAN IPv4 address is used by multiple hosts."
msgstr ""
#: models.py:367
msgid "What is this host for, what kind of machine is it."
msgstr ""
#: models.py:370
msgid "Notes"
msgstr ""
#: models.py:371
msgid "location"
msgstr ""
#: models.py:373
msgid "The physical location of the machine."
msgstr ""
#: models.py:376
msgid "Vlan network that the host is part of."
msgstr ""
#: models.py:379
msgid "The person responsible for this host."
msgstr ""
#: models.py:381
msgid "groups"
msgstr ""
#: models.py:383
msgid "Host groups the machine is part of."
msgstr ""
#: models.py:398
msgid "If shared_ip has been checked, pub_ipv4 has to be unique."
msgstr ""
#: models.py:401
msgid "You can't use another host's NAT'd address as your own IPv4."
msgstr ""
#: models.py:454
#, python-format
msgid "All %s ports are already in use."
msgstr ""
#: models.py:471
#, python-format
msgid "Port %(proto)s %(public)s is already in use."
msgstr ""
#: models.py:479
msgid "Only ports above 1024 can be used."
msgstr ""
#: models.py:587 models.py:617 models.py:741
msgid "created_at"
msgstr ""
#: models.py:589 models.py:619 models.py:743
msgid "modified_at"
msgstr ""
#: models.py:590 models.py:613
msgid "ttl"
msgstr ""
#: models.py:606
msgid "domain"
msgstr ""
#: models.py:610 models.py:738
msgid "type"
msgstr ""
#: models.py:612
msgid "address"
msgstr ""
#: models.py:627
msgid "(empty)"
msgstr ""
#: models.py:638
msgid "Can't specify address for A or AAAA records if host is set!"
msgstr ""
#: models.py:641
msgid "Can't specify name for A or AAAA records if host is set!"
msgstr ""
#: models.py:645
msgid "Name must be specified for CNAME records if host is set!"
msgstr ""
#: models.py:648
msgid "Can't specify address for CNAME records if host is set!"
msgstr ""
#: models.py:656
msgid "Address must be specified!"
msgstr ""
#: models.py:666
msgid "Unknown record type."
msgstr ""
#: models.py:731
msgid "reason"
msgstr ""
#: models.py:733
msgid "short message"
msgstr ""
#: views.py:26
#, python-format
msgid ""
"Dear %s, you've signed in as administrator!<br />Reloading in 10 seconds..."
msgstr ""
#: views.py:30
#, python-format
msgid "Dear %s, you've signed in!"
msgstr ""
#: views.py:32
msgid "Dear anonymous, you've not signed in yet!"
msgstr ""
#: views.py:43
msgid "Wrong password."
msgstr ""
#: views.py:77 views.py:118
msgid "OK"
msgstr ""
#: views.py:80
msgid "Only vm-net and war can be used."
msgstr ""
#: views.py:111
msgid "Unknown command."
msgstr ""
#: views.py:114
#, python-format
msgid ""
"Something went wrong!\n"
"%s\n"
msgstr ""
#: views.py:116
msgid "Something went wrong!\n"
msgstr ""
circle/firewall/models.py
View file @
43391a3d
# -*- coding: utf8 -*-
# -*- coding: utf
-
8 -*-
from
django.contrib.auth.models
import
User
from
django.contrib.auth.models
import
User
from
django.db
import
models
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
django.utils.translation
import
ugettext_lazy
as
_
from
firewall.fields
import
*
from
firewall.fields
import
(
MACAddressField
,
val_alfanum
,
val_reverse_domain
,
from
south.modelsinspector
import
add_introspection_rules
val_domain
,
val_ipv4
,
val_ipv6
,
val_mx
,
ipv4_2_ipv6
)
from
django.core.validators
import
MinValueValidator
,
MaxValueValidator
from
django.core.validators
import
MinValueValidator
,
MaxValueValidator
import
django.conf
import
django.conf
from
django.db.models.signals
import
post_save
from
django.db.models.signals
import
post_save
import
re
import
random
import
random
settings
=
django
.
conf
.
settings
.
FIREWALL_SETTINGS
settings
=
django
.
conf
.
settings
.
FIREWALL_SETTINGS
class
Rule
(
models
.
Model
):
class
Rule
(
models
.
Model
):
"""
Common firewall rule
Rule can be applied to: Host, Firewall, Vlan
"""
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.
"""
"""
CHOICES_type
=
((
'host'
,
'host'
),
(
'firewall'
,
'firewall'
),
CHOICES_type
=
((
'host'
,
'host'
),
(
'firewall'
,
'firewall'
),
(
'vlan'
,
'vlan'
))
(
'vlan'
,
'vlan'
))
CHOICES_proto
=
((
'tcp'
,
'tcp'
),
(
'udp'
,
'udp'
),
(
'icmp'
,
'icmp'
))
CHOICES_proto
=
((
'tcp'
,
'tcp'
),
(
'udp'
,
'udp'
),
(
'icmp'
,
'icmp'
))
CHOICES_dir
=
((
'0'
,
'out'
),
(
'1'
,
'in'
))
CHOICES_dir
=
((
'0'
,
'out'
),
(
'1'
,
'in'
))
direction
=
models
.
CharField
(
max_length
=
1
,
choices
=
CHOICES_dir
,
direction
=
models
.
CharField
(
max_length
=
1
,
choices
=
CHOICES_dir
,
blank
=
False
)
blank
=
False
,
verbose_name
=
_
(
"direction"
),
description
=
models
.
TextField
(
blank
=
True
)
help_text
=
_
(
"If the rule matches egress "
foreign_network
=
models
.
ForeignKey
(
'VlanGroup'
,
"or ingress packets."
))
related_name
=
"ForeignRules"
)
description
=
models
.
TextField
(
blank
=
True
,
verbose_name
=
_
(
'description'
),
dport
=
models
.
IntegerField
(
blank
=
True
,
null
=
True
,
help_text
=
_
(
"Why is the rule needed, "
validators
=
[
MinValueValidator
(
1
),
MaxValueValidator
(
65535
)])
"or how does it work."
))
sport
=
models
.
IntegerField
(
blank
=
True
,
null
=
True
,
foreign_network
=
models
.
ForeignKey
(
validators
=
[
MinValueValidator
(
1
),
MaxValueValidator
(
65535
)])
'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"
),
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"
),
validators
=
[
MinValueValidator
(
1
),
MaxValueValidator
(
65535
)],
help_text
=
_
(
"Source port number of packets that match."
))
proto
=
models
.
CharField
(
max_length
=
10
,
choices
=
CHOICES_proto
,
proto
=
models
.
CharField
(
max_length
=
10
,
choices
=
CHOICES_proto
,
blank
=
True
,
null
=
True
)
blank
=
True
,
null
=
True
,
verbose_name
=
_
(
"protocol"
),
extra
=
models
.
TextField
(
blank
=
True
)
help_text
=
_
(
"Protocol of packets that match."
))
accept
=
models
.
BooleanField
(
default
=
False
)
extra
=
models
.
TextField
(
blank
=
True
,
verbose_name
=
_
(
"extra arguments"
),
owner
=
models
.
ForeignKey
(
User
,
blank
=
True
,
null
=
True
)
help_text
=
_
(
"Additional arguments passed "
r_type
=
models
.
CharField
(
max_length
=
10
,
choices
=
CHOICES_type
)
"literally to the iptables-rule."
))
nat
=
models
.
BooleanField
(
default
=
False
)
accept
=
models
.
BooleanField
(
default
=
False
,
verbose_name
=
_
(
"accept"
),
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."
))
r_type
=
models
.
CharField
(
max_length
=
10
,
verbose_name
=
_
(
"Rule type"
),
choices
=
CHOICES_type
,
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."
))
nat_dport
=
models
.
IntegerField
(
blank
=
True
,
null
=
True
,
nat_dport
=
models
.
IntegerField
(
blank
=
True
,
null
=
True
,
validators
=
[
MinValueValidator
(
1
),
MaxValueValidator
(
65535
)])
help_text
=
_
(
created_at
=
models
.
DateTimeField
(
auto_now_add
=
True
)
"Rewrite destination port number to."
),
modified_at
=
models
.
DateTimeField
(
auto_now
=
True
)
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"
))
vlan
=
models
.
ForeignKey
(
'Vlan'
,
related_name
=
"rules"
,
blank
=
True
,
vlan
=
models
.
ForeignKey
(
'Vlan'
,
related_name
=
"rules"
,
blank
=
True
,
null
=
True
)
null
=
True
,
verbose_name
=
_
(
"vlan"
),
help_text
=
_
(
"Vlan the rule applies to "
"(if type is vlan)."
))
vlangroup
=
models
.
ForeignKey
(
'VlanGroup'
,
related_name
=
"rules"
,
vlangroup
=
models
.
ForeignKey
(
'VlanGroup'
,
related_name
=
"rules"
,
blank
=
True
,
null
=
True
)
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
,
host
=
models
.
ForeignKey
(
'Host'
,
related_name
=
"rules"
,
blank
=
True
,
null
=
True
)
verbose_name
=
_
(
'host'
),
null
=
True
,
hostgroup
=
models
.
ForeignKey
(
'Group'
,
related_name
=
"rules"
,
help_text
=
_
(
"Host the rule applies to "
blank
=
True
,
null
=
True
)
"(if type is host)."
))
firewall
=
models
.
ForeignKey
(
'Firewall'
,
related_name
=
"rules"
,
hostgroup
=
models
.
ForeignKey
(
blank
=
True
,
null
=
True
)
'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
):
def
__unicode__
(
self
):
return
self
.
desc
()
return
self
.
desc
()
def
clean
(
self
):
def
clean
(
self
):
fields
=
[
self
.
vlan
,
self
.
vlangroup
,
self
.
host
,
self
.
hostgroup
,
fields
=
[
self
.
vlan
,
self
.
vlangroup
,
self
.
host
,
self
.
hostgroup
,
self
.
firewall
]
self
.
firewall
]
selected_fields
=
[
field
for
field
in
fields
if
field
]
selected_fields
=
[
field
for
field
in
fields
if
field
]
if
len
(
selected_fields
)
>
1
:
if
len
(
selected_fields
)
>
1
:
raise
ValidationError
(
_
(
'Only one field can be selected.'
))
raise
ValidationError
(
_
(
'Only one field can be selected.'
))
def
desc
(
self
):
def
desc
(
self
):
"""Return a short string representation of the current rule.
"""
return
u'[
%(type)
s]
%(src)
s ▸
%(dst)
s
%(para)
s
%(desc)
s'
%
{
return
u'[
%(type)
s]
%(src)
s ▸
%(dst)
s
%(para)
s
%(desc)
s'
%
{
'type'
:
self
.
r_type
,
'type'
:
self
.
r_type
,
'src'
:
(
unicode
(
self
.
foreign_network
)
if
self
.
direction
==
'1'
'src'
:
(
unicode
(
self
.
foreign_network
)
if
self
.
direction
==
'1'
else
self
.
r_type
),
else
self
.
r_type
),
'dst'
:
(
self
.
r_type
if
self
.
direction
==
'1'
'dst'
:
(
self
.
r_type
if
self
.
direction
==
'1'
else
unicode
(
self
.
foreign_network
)),
else
unicode
(
self
.
foreign_network
)),
'para'
:
(((
"proto=
%
s "
%
self
.
proto
)
if
self
.
proto
else
''
)
+
'para'
:
(((
"proto=
%
s "
%
self
.
proto
)
if
self
.
proto
else
''
)
+
((
"sport=
%
s "
%
self
.
sport
)
if
self
.
sport
else
''
)
+
((
"sport=
%
s "
%
self
.
sport
)
if
self
.
sport
else
''
)
+
((
"dport=
%
s "
%
self
.
dport
)
if
self
.
dport
else
''
)),
((
"dport=
%
s "
%
self
.
dport
)
if
self
.
dport
else
''
)),
'desc'
:
self
.
description
}
'desc'
:
self
.
description
}
@models.permalink
def
get_absolute_url
(
self
):
return
(
'network.rule'
,
None
,
{
'pk'
:
self
.
pk
})
class
Meta
:
verbose_name
=
_
(
"rule"
)
verbose_name_plural
=
_
(
"rules"
)
ordering
=
(
'r_type'
,
'direction'
,
'proto'
,
'sport'
,
'dport'
,
'nat_dport'
,
'host'
,
)
class
Vlan
(
models
.
Model
):
class
Vlan
(
models
.
Model
):
vid
=
models
.
IntegerField
(
unique
=
True
)
name
=
models
.
CharField
(
max_length
=
20
,
unique
=
True
,
"""
validators
=
[
val_alfanum
])
A vlan of the network,
prefix4
=
models
.
IntegerField
(
default
=
16
)
prefix6
=
models
.
IntegerField
(
default
=
80
)
Networks controlled by this framework are split into separated subnets.
interface
=
models
.
CharField
(
max_length
=
20
,
unique
=
True
)
These networks are izolated by the vlan (virtual lan) technology, which is
net4
=
models
.
GenericIPAddressField
(
protocol
=
'ipv4'
,
unique
=
True
)
commonly used by managed network switches to partition the network.
net6
=
models
.
GenericIPAddressField
(
protocol
=
'ipv6'
,
unique
=
True
)
ipv4
=
models
.
GenericIPAddressField
(
protocol
=
'ipv4'
,
unique
=
True
)
Each vlan network has a unique identifier, a name, a unique IPv4 and IPv6
ipv6
=
models
.
GenericIPAddressField
(
protocol
=
'ipv6'
,
unique
=
True
)
range. The gateway also has an IP address in each range.
"""
vid
=
models
.
IntegerField
(
unique
=
True
,
verbose_name
=
_
(
'VID'
),
help_text
=
_
(
'The vlan ID of the subnet.'
),
validators
=
[
MinValueValidator
(
1
),
MaxValueValidator
(
4095
)])
name
=
models
.
CharField
(
max_length
=
20
,
unique
=
True
,
verbose_name
=
_
(
'Name'
),
help_text
=
_
(
'The short name of the subnet.'
),
validators
=
[
val_alfanum
])
prefix4
=
models
.
IntegerField
(
default
=
16
,
verbose_name
=
_
(
'IPv4 prefix length'
),
help_text
=
_
(
'The prefix length of the IPv4 subnet.'
))
prefix6
=
models
.
IntegerField
(
default
=
80
,
verbose_name
=
_
(
'IPv6 prefix length'
),
help_text
=
_
(
'The prefix length of the IPv6 subnet.'
))
interface
=
models
.
CharField
(
max_length
=
20
,
unique
=
True
,
verbose_name
=
_
(
'interface'
),
help_text
=
_
(
'The name of network interface the '
'gateway should serve this network on. '
'For example vlan0004 or eth2.'
))
net4
=
models
.
GenericIPAddressField
(
protocol
=
'ipv4'
,
unique
=
True
,
verbose_name
=
_
(
'IPv4 network'
),
help_text
=
_
(
'The network address of '
'the IPv4 subnet.'
))
net6
=
models
.
GenericIPAddressField
(
protocol
=
'ipv6'
,
unique
=
True
,
verbose_name
=
_
(
'IPv6 network'
),
help_text
=
_
(
'The network address of '
'the IPv6 subnet.'
))
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.'
))
ipv6
=
models
.
GenericIPAddressField
(
protocol
=
'ipv6'
,
unique
=
True
,
verbose_name
=
_
(
'IPv6 address'
),
help_text
=
_
(
'The IPv6 address of the '
'gateway.'
))
snat_ip
=
models
.
GenericIPAddressField
(
protocol
=
'ipv4'
,
blank
=
True
,
snat_ip
=
models
.
GenericIPAddressField
(
protocol
=
'ipv4'
,
blank
=
True
,
null
=
True
)
null
=
True
,
verbose_name
=
_
(
'NAT IP address'
),
help_text
=
_
(
'Common IPv4 address used for '
'address translation of '
'connections to the networks '
'selected below '
'(typically to the internet).'
))
snat_to
=
models
.
ManyToManyField
(
'self'
,
symmetrical
=
False
,
blank
=
True
,
snat_to
=
models
.
ManyToManyField
(
'self'
,
symmetrical
=
False
,
blank
=
True
,
null
=
True
)
null
=
True
,
verbose_name
=
_
(
'NAT to'
),
description
=
models
.
TextField
(
blank
=
True
)
help_text
=
_
(
comment
=
models
.
TextField
(
blank
=
True
)
'Connections to these networks '
domain
=
models
.
ForeignKey
(
'Domain'
)
'should be network address '
reverse_domain
=
models
.
TextField
(
validators
=
[
val_reverse_domain
])
'translated, i.e. their source '
dhcp_pool
=
models
.
TextField
(
blank
=
True
)
'address is rewritten to the value '
created_at
=
models
.
DateTimeField
(
auto_now_add
=
True
)
'of NAT IP address.'
))
owner
=
models
.
ForeignKey
(
User
,
blank
=
True
,
null
=
True
)
description
=
models
.
TextField
(
blank
=
True
,
verbose_name
=
_
(
'description'
),
modified_at
=
models
.
DateTimeField
(
auto_now
=
True
)
help_text
=
_
(
'Description of the goals and elements '
'of the vlan network.'
))
comment
=
models
.
TextField
(
blank
=
True
,
verbose_name
=
_
(
'comment'
),
help_text
=
_
(
'Notes, comments about the network'
))
domain
=
models
.
ForeignKey
(
'Domain'
,
verbose_name
=
_
(
'domain name'
),
help_text
=
_
(
'Domain name of the members of '
'this network.'
))
reverse_domain
=
models
.
TextField
(
validators
=
[
val_reverse_domain
],
verbose_name
=
_
(
'reverse domain'
),
help_text
=
_
(
'Template of the IPv4 reverse domain name that '
'should be generated for each host. The template '
'should contain four tokens: "
%(a)
d", "
%(b)
d", '
'"
%(c)
d", and "
%(d)
d", representing the four bytes '
'of the address, respectively, in decimal notation. '
'For example, the template for the standard reverse '
'address is: "
%(d)
d.
%(c)
d.
%(b)
d.
%(a)
d.in-addr.arpa".'
),
default
=
"
%(d)
d.
%(c)
d.
%(b)
d.
%(a)
d.in-addr.arpa"
)
dhcp_pool
=
models
.
TextField
(
blank
=
True
,
verbose_name
=
_
(
'DHCP pool'
),
help_text
=
_
(
'The address range of the DHCP pool: '
'empty for no DHCP service, "manual" for '
'no DHCP pool, or the first and last '
'address of the range separated by a '
'space.'
))
created_at
=
models
.
DateTimeField
(
auto_now_add
=
True
,
verbose_name
=
_
(
'created at'
))
owner
=
models
.
ForeignKey
(
User
,
blank
=
True
,
null
=
True
,
verbose_name
=
_
(
'owner'
))
modified_at
=
models
.
DateTimeField
(
auto_now
=
True
,
verbose_name
=
_
(
'modified at'
))
def
__unicode__
(
self
):
def
__unicode__
(
self
):
return
self
.
name
return
self
.
name
def
net_ipv6
(
self
):
def
net_ipv6
(
self
):
"""String representation of selected IPv6 network."""
return
self
.
net6
+
"/"
+
unicode
(
self
.
prefix6
)
return
self
.
net6
+
"/"
+
unicode
(
self
.
prefix6
)
def
net_ipv4
(
self
):
def
net_ipv4
(
self
):
"""String representation of selected IPv4 network."""
return
self
.
net4
+
"/"
+
unicode
(
self
.
prefix4
)
return
self
.
net4
+
"/"
+
unicode
(
self
.
prefix4
)
@models.permalink
def
get_absolute_url
(
self
):
return
(
'network.vlan'
,
None
,
{
'vid'
:
self
.
vid
})
class
VlanGroup
(
models
.
Model
):
class
VlanGroup
(
models
.
Model
):
name
=
models
.
CharField
(
max_length
=
20
,
unique
=
True
)
"""
A group of Vlans.
"""
name
=
models
.
CharField
(
max_length
=
20
,
unique
=
True
,
verbose_name
=
_
(
'name'
),
help_text
=
_
(
'The name of the group.'
))
vlans
=
models
.
ManyToManyField
(
'Vlan'
,
symmetrical
=
False
,
blank
=
True
,
vlans
=
models
.
ManyToManyField
(
'Vlan'
,
symmetrical
=
False
,
blank
=
True
,
null
=
True
)
null
=
True
,
verbose_name
=
_
(
'vlans'
),
description
=
models
.
TextField
(
blank
=
True
)
help_text
=
_
(
'The vlans which are members '
owner
=
models
.
ForeignKey
(
User
,
blank
=
True
,
null
=
True
)
'of the group.'
))
created_at
=
models
.
DateTimeField
(
auto_now_add
=
True
)
description
=
models
.
TextField
(
blank
=
True
,
verbose_name
=
_
(
'description'
),
modified_at
=
models
.
DateTimeField
(
auto_now
=
True
)
help_text
=
_
(
'Description of the group.'
))
owner
=
models
.
ForeignKey
(
User
,
blank
=
True
,
null
=
True
,
verbose_name
=
_
(
'owner'
))
created_at
=
models
.
DateTimeField
(
auto_now_add
=
True
,
verbose_name
=
_
(
'created at'
))
modified_at
=
models
.
DateTimeField
(
auto_now
=
True
,
verbose_name
=
_
(
'modified at'
))
def
__unicode__
(
self
):
def
__unicode__
(
self
):
return
self
.
name
return
self
.
name
@models.permalink
def
get_absolute_url
(
self
):
return
(
'network.vlan_group'
,
None
,
{
'pk'
:
self
.
pk
})
class
Group
(
models
.
Model
):
class
Group
(
models
.
Model
):
name
=
models
.
CharField
(
max_length
=
20
,
unique
=
True
)
"""
description
=
models
.
TextField
(
blank
=
True
)
A group of hosts.
owner
=
models
.
ForeignKey
(
User
,
blank
=
True
,
null
=
True
)
"""
created_at
=
models
.
DateTimeField
(
auto_now_add
=
True
)
name
=
models
.
CharField
(
max_length
=
20
,
unique
=
True
,
verbose_name
=
_
(
'name'
),
modified_at
=
models
.
DateTimeField
(
auto_now
=
True
)
help_text
=
_
(
'The name of the group.'
))
description
=
models
.
TextField
(
blank
=
True
,
verbose_name
=
_
(
'description'
),
help_text
=
_
(
'Description of the group.'
))
owner
=
models
.
ForeignKey
(
User
,
blank
=
True
,
null
=
True
,
verbose_name
=
_
(
'owner'
))
created_at
=
models
.
DateTimeField
(
auto_now_add
=
True
,
verbose_name
=
_
(
'created at'
))
modified_at
=
models
.
DateTimeField
(
auto_now
=
True
,
verbose_name
=
_
(
'modified at'
))
def
__unicode__
(
self
):
def
__unicode__
(
self
):
return
self
.
name
return
self
.
name
@models.permalink
def
get_absolute_url
(
self
):
return
(
'network.group'
,
None
,
{
'pk'
:
self
.
pk
})
class
Host
(
models
.
Model
):
class
Host
(
models
.
Model
):
"""
A host of the network.
"""
hostname
=
models
.
CharField
(
max_length
=
40
,
unique
=
True
,
hostname
=
models
.
CharField
(
max_length
=
40
,
unique
=
True
,
validators
=
[
val_alfanum
])
verbose_name
=
_
(
'hostname'
),
help_text
=
_
(
'The alphanumeric hostname of '
'the host, the first part of '
'the FQDN.'
),
validators
=
[
val_alfanum
])
reverse
=
models
.
CharField
(
max_length
=
40
,
validators
=
[
val_domain
],
reverse
=
models
.
CharField
(
max_length
=
40
,
validators
=
[
val_domain
],
blank
=
True
,
null
=
True
)
verbose_name
=
_
(
'reverse'
),
mac
=
MACAddressField
(
unique
=
True
)
help_text
=
_
(
'The fully qualified reverse '
ipv4
=
models
.
GenericIPAddressField
(
protocol
=
'ipv4'
,
unique
=
True
)
'hostname of the host, if '
pub_ipv4
=
models
.
GenericIPAddressField
(
protocol
=
'ipv4'
,
blank
=
True
,
'different than hostname.domain.'
),
null
=
True
)
blank
=
True
,
null
=
True
)
mac
=
MACAddressField
(
unique
=
True
,
verbose_name
=
_
(
'MAC address'
),
help_text
=
_
(
'The MAC (Ethernet) address of the '
'network interface. For example: '
'99:AA:BB:CC:DD:EE.'
))
ipv4
=
models
.
GenericIPAddressField
(
protocol
=
'ipv4'
,
unique
=
True
,
verbose_name
=
_
(
'IPv4 address'
),
help_text
=
_
(
'The real IPv4 address of the '
'host, for example 10.5.1.34.'
))
pub_ipv4
=
models
.
GenericIPAddressField
(
protocol
=
'ipv4'
,
blank
=
True
,
null
=
True
,
verbose_name
=
_
(
'WAN IPv4 address'
),
help_text
=
_
(
'The public IPv4 address of the host on the wide '
'area network, if different.'
))
ipv6
=
models
.
GenericIPAddressField
(
protocol
=
'ipv6'
,
unique
=
True
,
ipv6
=
models
.
GenericIPAddressField
(
protocol
=
'ipv6'
,
unique
=
True
,
blank
=
True
,
null
=
True
)
blank
=
True
,
null
=
True
,
shared_ip
=
models
.
BooleanField
(
default
=
False
)
verbose_name
=
_
(
'IPv6 address'
),
description
=
models
.
TextField
(
blank
=
True
)
help_text
=
_
(
comment
=
models
.
TextField
(
blank
=
True
)
'The global IPv6 address of the '
location
=
models
.
TextField
(
blank
=
True
)
'host, for example '
vlan
=
models
.
ForeignKey
(
'Vlan'
)
'2001:500:88:200::10.'
))
owner
=
models
.
ForeignKey
(
User
)
shared_ip
=
models
.
BooleanField
(
default
=
False
,
verbose_name
=
_
(
'shared IP'
),
help_text
=
_
(
'If the given WAN IPv4 address is '
'used by multiple hosts.'
))
description
=
models
.
TextField
(
blank
=
True
,
verbose_name
=
_
(
'description'
),
help_text
=
_
(
'What is this host for, what '
'kind of machine is it.'
))
comment
=
models
.
TextField
(
blank
=
True
,
verbose_name
=
_
(
'Notes'
))
location
=
models
.
TextField
(
blank
=
True
,
verbose_name
=
_
(
'location'
),
help_text
=
_
(
'The physical location of the machine.'
))
vlan
=
models
.
ForeignKey
(
'Vlan'
,
verbose_name
=
_
(
'vlan'
),
help_text
=
_
(
'Vlan network that the host is part of.'
))
owner
=
models
.
ForeignKey
(
User
,
verbose_name
=
_
(
'owner'
),
help_text
=
_
(
'The person responsible for this host.'
))
groups
=
models
.
ManyToManyField
(
'Group'
,
symmetrical
=
False
,
blank
=
True
,
groups
=
models
.
ManyToManyField
(
'Group'
,
symmetrical
=
False
,
blank
=
True
,
null
=
True
)
null
=
True
,
verbose_name
=
_
(
'groups'
),
created_at
=
models
.
DateTimeField
(
auto_now_add
=
True
)
help_text
=
_
(
modified_at
=
models
.
DateTimeField
(
auto_now
=
True
)
'Host groups the machine is part of.'
))
created_at
=
models
.
DateTimeField
(
auto_now_add
=
True
,
verbose_name
=
_
(
'created at'
))
modified_at
=
models
.
DateTimeField
(
auto_now
=
True
,
verbose_name
=
_
(
'modified at'
))
def
__unicode__
(
self
):
def
__unicode__
(
self
):
return
self
.
hostname
return
self
.
hostname
...
@@ -166,89 +396,144 @@ class Host(models.Model):
...
@@ -166,89 +396,144 @@ class Host(models.Model):
if
(
not
self
.
shared_ip
and
self
.
pub_ipv4
and
Host
.
objects
.
if
(
not
self
.
shared_ip
and
self
.
pub_ipv4
and
Host
.
objects
.
exclude
(
id
=
self
.
id
)
.
filter
(
pub_ipv4
=
self
.
pub_ipv4
)):
exclude
(
id
=
self
.
id
)
.
filter
(
pub_ipv4
=
self
.
pub_ipv4
)):
raise
ValidationError
(
_
(
"If shared_ip has been checked, "
raise
ValidationError
(
_
(
"If shared_ip has been checked, "
"pub_ipv4 has to be unique."
))
"pub_ipv4 has to be unique."
))
if
Host
.
objects
.
exclude
(
id
=
self
.
id
)
.
filter
(
pub_ipv4
=
self
.
ipv4
):
if
Host
.
objects
.
exclude
(
id
=
self
.
id
)
.
filter
(
pub_ipv4
=
self
.
ipv4
):
raise
ValidationError
(
_
(
"You can't use another host's NAT'd "
raise
ValidationError
(
_
(
"You can't use another host's NAT'd "
"address as your own IPv4."
))
"address as your own IPv4."
))
self
.
full_clean
()
self
.
full_clean
()
super
(
Host
,
self
)
.
save
(
*
args
,
**
kwargs
)
super
(
Host
,
self
)
.
save
(
*
args
,
**
kwargs
)
if
not
id
:
if
not
id
:
Record
(
domain
=
self
.
vlan
.
domain
,
host
=
self
,
type
=
'A'
,
Record
(
domain
=
self
.
vlan
.
domain
,
host
=
self
,
type
=
'A'
,
owner
=
self
.
owner
)
.
save
()
owner
=
self
.
owner
)
.
save
()
if
self
.
ipv6
:
if
self
.
ipv6
:
Record
(
domain
=
self
.
vlan
.
domain
,
host
=
self
,
type
=
'AAAA'
,
Record
(
domain
=
self
.
vlan
.
domain
,
host
=
self
,
type
=
'AAAA'
,
owner
=
self
.
owner
)
.
save
()
owner
=
self
.
owner
)
.
save
()
def
enable_net
(
self
):
def
enable_net
(
self
):
self
.
groups
.
add
(
Group
.
objects
.
get
(
name
=
"netezhet"
))
self
.
groups
.
add
(
Group
.
objects
.
get
(
name
=
"netezhet"
))
def
add_port
(
self
,
proto
,
public
=
None
,
private
=
None
):
def
_get_ports_used
(
self
,
proto
):
proto
=
"tcp"
if
proto
==
"tcp"
else
"udp"
"""
if
self
.
shared_ip
:
Gives a list of port numbers used for the public IP address of current
used_ports
=
Rule
.
objects
.
filter
(
host__pub_ipv4
=
self
.
pub_ipv4
,
host for the given protocol.
nat
=
True
,
proto
=
proto
)
.
values_list
(
'dport'
,
flat
=
True
)
if
public
is
None
:
public
=
random
.
randint
(
1024
,
21000
)
if
public
in
used_ports
:
for
i
in
range
(
1024
,
21000
)
+
range
(
24000
,
65535
):
if
i
not
in
used_ports
:
public
=
i
break
else
:
raise
ValidationError
(
_
(
"Port
%
s
%
s is already in use."
)
%
(
proto
,
public
))
:param proto: The transport protocol of the generated port (tcp|udp).
:type proto: str.
:returns: list -- list of int port numbers used.
"""
if
self
.
shared_ip
:
ports
=
Rule
.
objects
.
filter
(
host__pub_ipv4
=
self
.
pub_ipv4
,
nat
=
True
,
proto
=
proto
)
else
:
ports
=
self
.
rules
.
filter
(
proto
=
proto
,
)
return
ports
.
values_list
(
'dport'
,
flat
=
True
)
def
_get_random_port
(
self
,
proto
,
used_ports
=
None
):
"""
Get a random unused port for given protocol for current host's public
IP address.
:param proto: The transport protocol of the generated port (tcp|udp).
:type proto: str.
:param used_ports: Optional list of used ports returned by
_get_ports_used.
:returns: int -- the generated port number.
:raises: ValidationError
"""
if
used_ports
is
None
:
used_ports
=
self
.
_get_ports_used
(
proto
)
public
=
random
.
randint
(
1024
,
21000
)
# pick a random port
if
public
in
used_ports
:
# if it's in use, select smallest free one
for
i
in
range
(
1024
,
21000
)
+
range
(
24000
,
65535
):
if
i
not
in
used_ports
:
public
=
i
break
else
:
else
:
if
public
<
1024
:
raise
ValidationError
(
raise
ValidationError
(
_
(
"Only ports above 1024 can be used."
))
_
(
"All
%
s ports are already in use."
)
%
proto
)
if
public
in
used_ports
:
raise
ValidationError
(
_
(
"Port
%
s
%
s is already in use."
)
%
def
add_port
(
self
,
proto
,
public
=
None
,
private
=
None
):
(
proto
,
public
))
"""
Allow inbound traffic to a port.
If the host uses a shared IP address, also set up port forwarding.
:param proto: The transport protocol (tcp|udp).
:type proto: str.
:param public: Preferred public port number for forwarding (optional).
:param private: Port number of host in subject.
"""
assert
proto
in
(
'tcp'
,
'udp'
,
)
if
public
:
if
public
in
self
.
_get_ports_used
(
proto
):
raise
ValidationError
(
_
(
"Port
%(proto)
s
%(public)
s is already in use."
)
%
{
'proto'
:
proto
,
'public'
:
public
})
else
:
public
=
self
.
_get_random_port
(
proto
)
vg
=
VlanGroup
.
objects
.
get
(
name
=
settings
[
"default_vlangroup"
])
if
self
.
shared_ip
:
if
public
<
1024
:
raise
ValidationError
(
_
(
"Only ports above 1024 can be used."
))
rule
=
Rule
(
direction
=
'1'
,
owner
=
self
.
owner
,
dport
=
public
,
rule
=
Rule
(
direction
=
'1'
,
owner
=
self
.
owner
,
dport
=
public
,
proto
=
proto
,
nat
=
True
,
accept
=
True
,
r_type
=
"host"
,
proto
=
proto
,
nat
=
True
,
accept
=
True
,
r_type
=
"host"
,
nat_dport
=
private
,
host
=
self
,
foreign_network
=
VlanGroup
.
nat_dport
=
private
,
host
=
self
,
foreign_network
=
vg
)
objects
.
get
(
name
=
settings
[
"default_vlangroup"
]))
else
:
else
:
if
self
.
rules
.
filter
(
proto
=
proto
,
dport
=
public
):
raise
ValidationError
(
_
(
"Port
%
s
%
s is already in use."
)
%
(
proto
,
public
))
rule
=
Rule
(
direction
=
'1'
,
owner
=
self
.
owner
,
dport
=
public
,
rule
=
Rule
(
direction
=
'1'
,
owner
=
self
.
owner
,
dport
=
public
,
proto
=
proto
,
nat
=
False
,
accept
=
True
,
r_type
=
"host"
,
proto
=
proto
,
nat
=
False
,
accept
=
True
,
r_type
=
"host"
,
host
=
self
,
foreign_network
=
VlanGroup
.
objects
host
=
self
,
foreign_network
=
vg
)
.
get
(
name
=
settings
[
"default_vlangroup"
]))
rule
.
full_clean
()
rule
.
full_clean
()
rule
.
save
()
rule
.
save
()
def
del_port
(
self
,
proto
,
private
):
def
del_port
(
self
,
proto
,
private
):
"""
Remove rules about inbound traffic to a given port.
If the host uses a shared IP address, also set up port forwarding.
:param proto: The transport protocol (tcp|udp).
:type proto: str.
:param private: Port number of host in subject.
"""
if
self
.
shared_ip
:
if
self
.
shared_ip
:
self
.
rules
.
filter
(
owner
=
self
.
owner
,
proto
=
proto
,
host
=
self
,
self
.
rules
.
filter
(
owner
=
self
.
owner
,
proto
=
proto
,
host
=
self
,
nat_dport
=
private
)
.
delete
()
nat_dport
=
private
)
.
delete
()
else
:
else
:
self
.
rules
.
filter
(
owner
=
self
.
owner
,
proto
=
proto
,
host
=
self
,
self
.
rules
.
filter
(
owner
=
self
.
owner
,
proto
=
proto
,
host
=
self
,
dport
=
private
)
.
delete
()
dport
=
private
)
.
delete
()
def
get_hostname
(
self
,
proto
):
def
get_hostname
(
self
,
proto
):
"""
Get a hostname for public ip address.
:param proto: The IP version (ipv4|ipv6).
:type proto: str.
"""
assert
proto
in
(
'ipv6'
,
'ipv4'
,
)
try
:
try
:
if
proto
==
'ipv6'
:
if
proto
==
'ipv6'
:
res
=
self
.
record_set
.
filter
(
type
=
'AAAA'
)
res
=
self
.
record_set
.
filter
(
type
=
'AAAA'
)
elif
proto
==
'ipv4'
:
elif
proto
==
'ipv4'
:
if
self
.
shared_ip
:
if
self
.
shared_ip
:
res
=
Record
.
objects
.
filter
(
type
=
'A'
,
res
=
Record
.
objects
.
filter
(
type
=
'A'
,
address
=
self
.
pub_ipv4
)
address
=
self
.
pub_ipv4
)
else
:
else
:
res
=
self
.
record_set
.
filter
(
type
=
'A'
)
res
=
self
.
record_set
.
filter
(
type
=
'A'
)
return
unicode
(
res
[
0
]
.
get_data
()[
'name'
])
return
unicode
(
res
[
0
]
.
get_data
()[
'name'
])
except
:
except
:
# raise
if
self
.
shared_ip
:
if
self
.
shared_ip
:
return
self
.
pub_ipv4
return
self
.
pub_ipv4
else
:
else
:
return
self
.
ipv4
return
self
.
ipv4
def
list_ports
(
self
):
def
list_ports
(
self
):
"""
Return a list of ports with forwarding rules set.
"""
retval
=
[]
retval
=
[]
for
rule
in
self
.
rules
.
filter
(
owner
=
self
.
owner
):
for
rule
in
self
.
rules
.
filter
(
owner
=
self
.
owner
):
private
=
rule
.
nat_dport
if
self
.
shared_ip
else
rule
.
dport
private
=
rule
.
nat_dport
if
self
.
shared_ip
else
rule
.
dport
...
@@ -267,7 +552,7 @@ class Host(models.Model):
...
@@ -267,7 +552,7 @@ class Host(models.Model):
'host'
:
self
.
get_hostname
(
proto
=
'ipv4'
),
'host'
:
self
.
get_hostname
(
proto
=
'ipv4'
),
'port'
:
public4
,
'port'
:
public4
,
}
}
if
self
.
ipv6
:
# ipv6
if
self
.
ipv6
:
# ipv6
forward
[
'ipv6'
]
=
{
forward
[
'ipv6'
]
=
{
'host'
:
self
.
get_hostname
(
proto
=
'ipv6'
),
'host'
:
self
.
get_hostname
(
proto
=
'ipv6'
),
'port'
:
public6
,
'port'
:
public6
,
...
@@ -276,40 +561,62 @@ class Host(models.Model):
...
@@ -276,40 +561,62 @@ class Host(models.Model):
return
retval
return
retval
def
get_fqdn
(
self
):
def
get_fqdn
(
self
):
"""
Get fully qualified host name of host.
"""
return
self
.
hostname
+
u'.'
+
unicode
(
self
.
vlan
.
domain
)
return
self
.
hostname
+
u'.'
+
unicode
(
self
.
vlan
.
domain
)
@models.permalink
def
get_absolute_url
(
self
):
return
(
'network.host'
,
None
,
{
'pk'
:
self
.
pk
})
class
Firewall
(
models
.
Model
):
class
Firewall
(
models
.
Model
):
name
=
models
.
CharField
(
max_length
=
20
,
unique
=
True
)
name
=
models
.
CharField
(
max_length
=
20
,
unique
=
True
,
verbose_name
=
_
(
'name'
))
def
__unicode__
(
self
):
def
__unicode__
(
self
):
return
self
.
name
return
self
.
name
class
Domain
(
models
.
Model
):
class
Domain
(
models
.
Model
):
name
=
models
.
CharField
(
max_length
=
40
,
validators
=
[
val_domain
])
name
=
models
.
CharField
(
max_length
=
40
,
validators
=
[
val_domain
],
owner
=
models
.
ForeignKey
(
User
)
verbose_name
=
_
(
'name'
))
created_at
=
models
.
DateTimeField
(
auto_now_add
=
True
)
owner
=
models
.
ForeignKey
(
User
,
verbose_name
=
_
(
'owner'
))
modified_at
=
models
.
DateTimeField
(
auto_now
=
True
)
created_at
=
models
.
DateTimeField
(
auto_now_add
=
True
,
ttl
=
models
.
IntegerField
(
default
=
600
)
verbose_name
=
_
(
'created_at'
))
description
=
models
.
TextField
(
blank
=
True
)
modified_at
=
models
.
DateTimeField
(
auto_now
=
True
,
verbose_name
=
_
(
'modified_at'
))
ttl
=
models
.
IntegerField
(
default
=
600
,
verbose_name
=
_
(
'ttl'
))
description
=
models
.
TextField
(
blank
=
True
,
verbose_name
=
_
(
'description'
))
def
__unicode__
(
self
):
def
__unicode__
(
self
):
return
self
.
name
return
self
.
name
@models.permalink
def
get_absolute_url
(
self
):
return
(
'network.domain'
,
None
,
{
'pk'
:
self
.
pk
})
class
Record
(
models
.
Model
):
class
Record
(
models
.
Model
):
CHOICES_type
=
((
'A'
,
'A'
),
(
'CNAME'
,
'CNAME'
),
(
'AAAA'
,
'AAAA'
),
CHOICES_type
=
((
'A'
,
'A'
),
(
'CNAME'
,
'CNAME'
),
(
'AAAA'
,
'AAAA'
),
(
'MX'
,
'MX'
),
(
'NS'
,
'NS'
),
(
'PTR'
,
'PTR'
),
(
'TXT'
,
'TXT'
))
(
'MX'
,
'MX'
),
(
'NS'
,
'NS'
),
(
'PTR'
,
'PTR'
),
(
'TXT'
,
'TXT'
))
name
=
models
.
CharField
(
max_length
=
40
,
validators
=
[
val_domain
],
name
=
models
.
CharField
(
max_length
=
40
,
validators
=
[
val_domain
],
blank
=
True
,
null
=
True
)
blank
=
True
,
null
=
True
,
verbose_name
=
_
(
'name'
))
domain
=
models
.
ForeignKey
(
'Domain'
)
domain
=
models
.
ForeignKey
(
'Domain'
,
verbose_name
=
_
(
'domain'
))
host
=
models
.
ForeignKey
(
'Host'
,
blank
=
True
,
null
=
True
)
host
=
models
.
ForeignKey
(
'Host'
,
blank
=
True
,
null
=
True
,
type
=
models
.
CharField
(
max_length
=
6
,
choices
=
CHOICES_type
)
verbose_name
=
_
(
'host'
))
address
=
models
.
CharField
(
max_length
=
40
,
blank
=
True
,
null
=
True
)
type
=
models
.
CharField
(
max_length
=
6
,
choices
=
CHOICES_type
,
ttl
=
models
.
IntegerField
(
default
=
600
)
verbose_name
=
_
(
'type'
))
owner
=
models
.
ForeignKey
(
User
)
address
=
models
.
CharField
(
max_length
=
40
,
blank
=
True
,
null
=
True
,
description
=
models
.
TextField
(
blank
=
True
)
verbose_name
=
_
(
'address'
))
created_at
=
models
.
DateTimeField
(
auto_now_add
=
True
)
ttl
=
models
.
IntegerField
(
default
=
600
,
verbose_name
=
_
(
'ttl'
))
modified_at
=
models
.
DateTimeField
(
auto_now
=
True
)
owner
=
models
.
ForeignKey
(
User
,
verbose_name
=
_
(
'owner'
))
description
=
models
.
TextField
(
blank
=
True
,
verbose_name
=
_
(
'description'
))
created_at
=
models
.
DateTimeField
(
auto_now_add
=
True
,
verbose_name
=
_
(
'created_at'
))
modified_at
=
models
.
DateTimeField
(
auto_now
=
True
,
verbose_name
=
_
(
'modified_at'
))
def
__unicode__
(
self
):
def
__unicode__
(
self
):
return
self
.
desc
()
return
self
.
desc
()
...
@@ -323,46 +630,54 @@ class Record(models.Model):
...
@@ -323,46 +630,54 @@ class Record(models.Model):
self
.
full_clean
()
self
.
full_clean
()
super
(
Record
,
self
)
.
save
(
*
args
,
**
kwargs
)
super
(
Record
,
self
)
.
save
(
*
args
,
**
kwargs
)
def
_validate_w_host
(
self
):
"""Validate a record with host set."""
assert
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!"
))
if
self
.
name
:
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 "
"CNAME records if host is set!"
))
if
self
.
address
:
raise
ValidationError
(
_
(
"Can't specify address for "
"CNAME records if host is set!"
))
def
_validate_wo_host
(
self
):
"""Validate a record without a host set."""
assert
self
.
host
is
None
if
not
self
.
address
:
raise
ValidationError
(
_
(
"Address must be specified!"
))
if
self
.
type
==
'A'
:
val_ipv4
(
self
.
address
)
elif
self
.
type
==
'AAAA'
:
val_ipv6
(
self
.
address
)
elif
self
.
type
in
[
'CNAME'
,
'NS'
,
'PTR'
,
'TXT'
]:
val_domain
(
self
.
address
)
elif
self
.
type
==
'MX'
:
val_mx
(
self
.
address
)
else
:
raise
ValidationError
(
_
(
"Unknown record type."
))
def
clean
(
self
):
def
clean
(
self
):
"""Validate the Record to be saved.
"""
if
self
.
name
:
if
self
.
name
:
self
.
name
=
self
.
name
.
rstrip
(
"."
)
# remove trailing dots
self
.
name
=
self
.
name
.
rstrip
(
"."
)
# remove trailing dots
if
self
.
host
:
if
self
.
host
:
if
self
.
type
in
[
'A'
,
'AAAA'
]:
self
.
_validate_w_host
()
if
self
.
address
:
else
:
raise
ValidationError
(
_
(
"Can't specify address for "
self
.
_validate_wo_host
()
"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!"
))
elif
self
.
type
==
'CNAME'
:
if
not
self
.
name
:
raise
ValidationError
(
_
(
"Name must be specified for "
"CNAME records if host is set!"
))
if
self
.
address
:
raise
ValidationError
(
_
(
"Can't specify address for "
"CNAME records if host is set!"
))
else
:
# if self.host is None
if
not
self
.
address
:
raise
ValidationError
(
_
(
"Address must be specified!"
))
if
self
.
type
==
'A'
:
@property
val_ipv4
(
self
.
address
)
def
fqdn
(
self
):
elif
self
.
type
==
'AAAA'
:
val_ipv6
(
self
.
address
)
elif
self
.
type
in
[
'CNAME'
,
'NS'
,
'PTR'
,
'TXT'
]:
val_domain
(
self
.
address
)
elif
self
.
type
==
'MX'
:
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>"
))
else
:
raise
ValidationError
(
_
(
"Unknown record type."
))
def
get_name
(
self
):
return
self
.
__get_name
()
def
__get_name
(
self
):
if
self
.
host
and
self
.
type
!=
'MX'
:
if
self
.
host
and
self
.
type
!=
'MX'
:
if
self
.
type
in
[
'A'
,
'AAAA'
]:
if
self
.
type
in
[
'A'
,
'AAAA'
]:
return
self
.
host
.
get_fqdn
()
return
self
.
host
.
get_fqdn
()
...
@@ -390,7 +705,7 @@ class Record(models.Model):
...
@@ -390,7 +705,7 @@ class Record(models.Model):
return
self
.
address
return
self
.
address
def
get_data
(
self
):
def
get_data
(
self
):
name
=
self
.
__get_name
()
name
=
self
.
fqdn
address
=
self
.
__get_address
()
address
=
self
.
__get_address
()
if
self
.
host
and
self
.
type
==
'AAAA'
and
not
self
.
host
.
ipv6
:
if
self
.
host
and
self
.
type
==
'AAAA'
and
not
self
.
host
.
ipv6
:
return
None
return
None
...
@@ -402,22 +717,43 @@ class Record(models.Model):
...
@@ -402,22 +717,43 @@ class Record(models.Model):
'ttl'
:
self
.
ttl
,
'ttl'
:
self
.
ttl
,
'address'
:
address
}
'address'
:
address
}
@models.permalink
def
get_absolute_url
(
self
):
return
(
'network.record'
,
None
,
{
'pk'
:
self
.
pk
})
class
Blacklist
(
models
.
Model
):
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
)
ipv4
=
models
.
GenericIPAddressField
(
protocol
=
'ipv4'
,
unique
=
True
)
host
=
models
.
ForeignKey
(
'Host'
,
blank
=
True
,
null
=
True
)
host
=
models
.
ForeignKey
(
'Host'
,
blank
=
True
,
null
=
True
,
reason
=
models
.
TextField
(
blank
=
True
)
verbose_name
=
_
(
'host'
))
snort_message
=
models
.
TextField
(
blank
=
True
)
reason
=
models
.
TextField
(
blank
=
True
,
verbose_name
=
_
(
'reason'
))
type
=
models
.
CharField
(
max_length
=
10
,
choices
=
CHOICES_type
,
default
=
'tempban'
)
snort_message
=
models
.
TextField
(
blank
=
True
,
created_at
=
models
.
DateTimeField
(
auto_now_add
=
True
)
verbose_name
=
_
(
'short message'
))
modified_at
=
models
.
DateTimeField
(
auto_now
=
True
)
type
=
models
.
CharField
(
max_length
=
10
,
choices
=
CHOICES_type
,
default
=
'tempban'
,
verbose_name
=
_
(
'type'
)
)
created_at
=
models
.
DateTimeField
(
auto_now_add
=
True
,
verbose_name
=
_
(
'created_at'
))
modified_at
=
models
.
DateTimeField
(
auto_now
=
True
,
verbose_name
=
_
(
'modified_at'
))
def
save
(
self
,
*
args
,
**
kwargs
):
def
save
(
self
,
*
args
,
**
kwargs
):
self
.
full_clean
()
self
.
full_clean
()
super
(
Blacklist
,
self
)
.
save
(
*
args
,
**
kwargs
)
super
(
Blacklist
,
self
)
.
save
(
*
args
,
**
kwargs
)
def
__unicode__
(
self
):
def
__unicode__
(
self
):
return
self
.
ipv4
return
self
.
ipv4
@models.permalink
def
get_absolute_url
(
self
):
return
(
'network.blacklist'
,
None
,
{
'pk'
:
self
.
pk
})
def
send_task
(
sender
,
instance
,
created
,
**
kwargs
):
def
send_task
(
sender
,
instance
,
created
,
**
kwargs
):
from
firewall.tasks
import
ReloadTask
from
firewall.tasks
import
ReloadTask
ReloadTask
.
apply_async
(
args
=
[
sender
.
__name__
])
ReloadTask
.
apply_async
(
args
=
[
sender
.
__name__
])
...
...
circle/firewall/tasks.py
View file @
43391a3d
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"
,
"Record
s
"
,
"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
circle/firewall/tests.py
View file @
43391a3d
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"
)
circle/firewall/views.py
View file @
43391a3d
...
@@ -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
:
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment