8
0
Fork 0
mirror of https://gitlab2.federez.net/re2o/re2o synced 2024-12-26 08:53:46 +00:00

Merge branch 'ouverture_des_ports' into 'master'

Ouverture des ports

See merge request rezo/re2o!19
This commit is contained in:
Gabriel Detraz 2017-10-15 20:06:00 +02:00
commit d9d4c1fd8c
10 changed files with 187 additions and 17 deletions

BIN
docs_utils/re2o-archi.dia Normal file

Binary file not shown.

View file

@ -156,7 +156,7 @@ class DelMachineTypeForm(Form):
class IpTypeForm(ModelForm): class IpTypeForm(ModelForm):
class Meta: class Meta:
model = IpType model = IpType
fields = ['type','extension','need_infra','domaine_ip_start','domaine_ip_stop', 'prefix_v6', 'vlan'] fields = ['type','extension','need_infra','domaine_ip_start','domaine_ip_stop', 'prefix_v6', 'vlan', 'ouverture_ports']
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
prefix = kwargs.pop('prefix', self.Meta.model.__name__) prefix = kwargs.pop('prefix', self.Meta.model.__name__)
@ -165,7 +165,7 @@ class IpTypeForm(ModelForm):
class EditIpTypeForm(IpTypeForm): class EditIpTypeForm(IpTypeForm):
class Meta(IpTypeForm.Meta): class Meta(IpTypeForm.Meta):
fields = ['extension','type','need_infra', 'prefix_v6', 'vlan'] fields = ['extension','type','need_infra', 'prefix_v6', 'vlan', 'ouverture_ports']
class DelIpTypeForm(Form): class DelIpTypeForm(Form):
iptypes = forms.ModelMultipleChoiceField(queryset=IpType.objects.all(), label="Types d'ip actuelles", widget=forms.CheckboxSelectMultiple) iptypes = forms.ModelMultipleChoiceField(queryset=IpType.objects.all(), label="Types d'ip actuelles", widget=forms.CheckboxSelectMultiple)

View file

@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2017-10-03 16:08
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('machines', '0059_iptype_prefix_v6'),
]
operations = [
migrations.AddField(
model_name='iptype',
name='ouverture_ports',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='machines.OuverturePortList'),
),
]

View file

@ -73,6 +73,7 @@ class IpType(models.Model):
domaine_ip_stop = models.GenericIPAddressField(protocol='IPv4') domaine_ip_stop = models.GenericIPAddressField(protocol='IPv4')
prefix_v6 = models.GenericIPAddressField(protocol='IPv6', null=True, blank=True) prefix_v6 = models.GenericIPAddressField(protocol='IPv6', null=True, blank=True)
vlan = models.ForeignKey('Vlan', on_delete=models.PROTECT, blank=True, null=True) vlan = models.ForeignKey('Vlan', on_delete=models.PROTECT, blank=True, null=True)
ouverture_ports = models.ForeignKey('OuverturePortList', blank=True, null=True)
@cached_property @cached_property
def ip_range(self): def ip_range(self):

View file

@ -24,7 +24,7 @@
#Augustin Lemesle #Augustin Lemesle
from rest_framework import serializers from rest_framework import serializers
from machines.models import Interface, IpType, Extension, IpList, MachineType, Domain, Text, Mx, Service_link, Ns from machines.models import Interface, IpType, Extension, IpList, MachineType, Domain, Text, Mx, Service_link, Ns, OuverturePortList, OuverturePort
class IpTypeField(serializers.RelatedField): class IpTypeField(serializers.RelatedField):
def to_representation(self, value): def to_representation(self, value):
@ -81,10 +81,31 @@ class ExtensionNameField(serializers.RelatedField):
class TypeSerializer(serializers.ModelSerializer): class TypeSerializer(serializers.ModelSerializer):
extension = ExtensionNameField(read_only=True) extension = ExtensionNameField(read_only=True)
ouverture_ports_tcp_in = serializers.SerializerMethodField('get_port_policy_input_tcp')
ouverture_ports_tcp_out = serializers.SerializerMethodField('get_port_policy_output_tcp')
ouverture_ports_udp_in = serializers.SerializerMethodField('get_port_policy_input_udp')
ouverture_ports_udp_out = serializers.SerializerMethodField('get_port_policy_output_udp')
class Meta: class Meta:
model = IpType model = IpType
fields = ('type', 'extension', 'domaine_ip_start', 'domaine_ip_stop') fields = ('type', 'extension', 'domaine_ip_start', 'domaine_ip_stop', 'ouverture_ports_tcp_in', 'ouverture_ports_tcp_out', 'ouverture_ports_udp_in', 'ouverture_ports_udp_out', )
def get_port_policy(self, obj, protocole, io):
if obj.ouverture_ports is None:
return []
return map(str, obj.ouverture_ports.ouvertureport_set.filter(protocole=protocole).filter(io=io))
def get_port_policy_input_tcp(self, obj):
return self.get_port_policy(obj, OuverturePort.TCP, OuverturePort.IN)
def get_port_policy_output_tcp(self, obj):
return self.get_port_policy(obj, OuverturePort.TCP, OuverturePort.OUT)
def get_port_policy_input_udp(self, obj):
return self.get_port_policy(obj, OuverturePort.UDP, OuverturePort.IN)
def get_port_policy_output_udp(self, obj):
return self.get_port_policy(obj, OuverturePort.UDP, OuverturePort.OUT)
class ExtensionSerializer(serializers.ModelSerializer): class ExtensionSerializer(serializers.ModelSerializer):
origin = serializers.SerializerMethodField('get_origin_ip') origin = serializers.SerializerMethodField('get_origin_ip')
@ -185,3 +206,29 @@ class ServiceServersSerializer(serializers.ModelSerializer):
def get_regen_status(self, obj): def get_regen_status(self, obj):
return obj.need_regen() return obj.need_regen()
class OuverturePortsSerializer(serializers.Serializer):
ipv4 = serializers.SerializerMethodField()
ipv6 = serializers.SerializerMethodField()
def get_ipv4():
return {i.ipv4.ipv4:
{
"tcp_in":[j.tcp_ports_in() for j in i.port_lists.all()],
"tcp_out":[j.tcp_ports_out()for j in i.port_lists.all()],
"udp_in":[j.udp_ports_in() for j in i.port_lists.all()],
"udp_out":[j.udp_ports_out() for j in i.port_lists.all()],
}
for i in Interface.objects.all() if i.ipv4
}
def get_ipv6():
return {i.ipv6:
{
"tcp_in":[j.tcp_ports_in() for j in i.port_lists.all()],
"tcp_out":[j.tcp_ports_out()for j in i.port_lists.all()],
"udp_in":[j.udp_ports_in() for j in i.port_lists.all()],
"udp_out":[j.udp_ports_out() for j in i.port_lists.all()],
}
for i in Interface.objects.all() if i.ipv6
}

View file

@ -32,6 +32,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<th>Fin</th> <th>Fin</th>
<th>Préfixe v6</th> <th>Préfixe v6</th>
<th>Sur vlan</th> <th>Sur vlan</th>
<th>Ouverture ports par défault</th>
<th></th> <th></th>
<th></th> <th></th>
</tr> </tr>
@ -45,6 +46,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<td>{{ type.domaine_ip_stop }}</td> <td>{{ type.domaine_ip_stop }}</td>
<td>{{ type.prefix_v6 }}</td> <td>{{ type.prefix_v6 }}</td>
<td>{{ type.vlan }}</td> <td>{{ type.vlan }}</td>
<td>{{ type.ouverture_ports }}</td>
<td class="text-right"> <td class="text-right">
{% if is_infra %} {% if is_infra %}
{% include 'buttons/edit.html' with href='machines:edit-iptype' id=type.id %} {% include 'buttons/edit.html' with href='machines:edit-iptype' id=type.id %}

View file

@ -58,7 +58,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% if is_cableur %} {% if is_cableur %}
<a class="list-group-item list-group-item-info" href="{% url "machines:index-portlist" %}"> <a class="list-group-item list-group-item-info" href="{% url "machines:index-portlist" %}">
<i class="glyphicon glyphicon-list"></i> <i class="glyphicon glyphicon-list"></i>
Configuration de ports Ouverture de ports
</a> </a>
{%endif%} {%endif%}
{% endblock %} {% endblock %}

View file

@ -93,6 +93,7 @@ urlpatterns = [
url(r'^rest/text/$', views.text, name='text'), url(r'^rest/text/$', views.text, name='text'),
url(r'^rest/zones/$', views.zones, name='zones'), url(r'^rest/zones/$', views.zones, name='zones'),
url(r'^rest/service_servers/$', views.service_servers, name='service-servers'), url(r'^rest/service_servers/$', views.service_servers, name='service-servers'),
url(r'^rest/ouverture_ports/$', views.ouverture_ports, name='ouverture-ports'),
url(r'index_portlist/$', views.index_portlist, name='index-portlist'), url(r'index_portlist/$', views.index_portlist, name='index-portlist'),
url(r'^edit_portlist/(?P<pk>[0-9]+)$', views.edit_portlist, name='edit-portlist'), url(r'^edit_portlist/(?P<pk>[0-9]+)$', views.edit_portlist, name='edit-portlist'),
url(r'^del_portlist/(?P<pk>[0-9]+)$', views.del_portlist, name='del-portlist'), url(r'^del_portlist/(?P<pk>[0-9]+)$', views.del_portlist, name='del-portlist'),

View file

@ -43,19 +43,81 @@ from django.contrib.auth import authenticate, login
from django.views.decorators.csrf import csrf_exempt from django.views.decorators.csrf import csrf_exempt
from rest_framework.renderers import JSONRenderer from rest_framework.renderers import JSONRenderer
from machines.serializers import FullInterfaceSerializer, InterfaceSerializer, TypeSerializer, DomainSerializer, TextSerializer, MxSerializer, ExtensionSerializer, ServiceServersSerializer, NsSerializer from machines.serializers import ( FullInterfaceSerializer,
InterfaceSerializer,
TypeSerializer,
DomainSerializer,
TextSerializer,
MxSerializer,
ExtensionSerializer,
ServiceServersSerializer,
NsSerializer,
OuverturePortsSerializer
)
from reversion import revisions as reversion from reversion import revisions as reversion
from reversion.models import Version from reversion.models import Version
import re import re
from .forms import NewMachineForm, EditMachineForm, EditInterfaceForm, AddInterfaceForm, MachineTypeForm, DelMachineTypeForm, ExtensionForm, DelExtensionForm, BaseEditInterfaceForm, BaseEditMachineForm from .forms import (
from .forms import EditIpTypeForm, IpTypeForm, DelIpTypeForm, DomainForm, AliasForm, DelAliasForm, NsForm, DelNsForm, TxtForm, DelTxtForm, MxForm, DelMxForm, VlanForm, DelVlanForm, ServiceForm, DelServiceForm, NasForm, DelNasForm NewMachineForm,
EditMachineForm,
EditInterfaceForm,
AddInterfaceForm,
MachineTypeForm,
DelMachineTypeForm,
ExtensionForm,
DelExtensionForm,
BaseEditInterfaceForm,
BaseEditMachineForm
)
from .forms import (
EditIpTypeForm,
IpTypeForm,
DelIpTypeForm,
DomainForm,
AliasForm,
DelAliasForm,
NsForm,
DelNsForm,
TxtForm,
DelTxtForm,
MxForm,
DelMxForm,
VlanForm,
DelVlanForm,
ServiceForm,
DelServiceForm,
NasForm,
DelNasForm
)
from .forms import EditOuverturePortListForm, EditOuverturePortConfigForm from .forms import EditOuverturePortListForm, EditOuverturePortConfigForm
from .models import IpType, Machine, Interface, IpList, MachineType, Extension, Mx, Ns, Domain, Service, Service_link, Vlan, Nas, Text, OuverturePortList, OuverturePort from .models import (
IpType,
Machine,
Interface,
IpList,
MachineType,
Extension,
Mx,
Ns,
Domain,
Service,
Service_link,
Vlan,
Nas,
Text,
OuverturePortList,
OuverturePort
)
from users.models import User from users.models import User
from preferences.models import GeneralOption, OptionalMachine from preferences.models import GeneralOption, OptionalMachine
from re2o.templatetags.massive_bootstrap_form import hidden_id, input_id from re2o.templatetags.massive_bootstrap_form import hidden_id, input_id
from re2o.utils import all_active_assigned_interfaces, all_has_access from re2o.utils import (
all_active_assigned_interfaces,
all_has_access,
filter_active_interfaces
)
from re2o.views import form from re2o.views import form
def f_type_id( is_type_tt ): def f_type_id( is_type_tt ):
@ -72,7 +134,8 @@ def generate_ipv4_choices( form ) :
choices = '{"":[{key:"",value:"Choisissez d\'abord un type de machine"},' choices = '{"":[{key:"",value:"Choisissez d\'abord un type de machine"},'
mtype_id = -1 mtype_id = -1
for ip in f_ipv4.queryset.annotate(mtype_id=F('ip_type__machinetype__id')).order_by('mtype_id', 'id') : for ip in f_ipv4.queryset.annotate(mtype_id=F('ip_type__machinetype__id'))\
.order_by('mtype_id', 'id') :
if mtype_id != ip.mtype_id : if mtype_id != ip.mtype_id :
mtype_id = ip.mtype_id mtype_id = ip.mtype_id
used_mtype_id.append(mtype_id) used_mtype_id.append(mtype_id)
@ -139,8 +202,8 @@ def generate_ipv4_mbf_param( form, is_type_tt ):
@login_required @login_required
def new_machine(request, userid): def new_machine(request, userid):
""" Fonction de creation d'une machine. Cree l'objet machine, le sous objet interface et l'objet domain """ Fonction de creation d'une machine. Cree l'objet machine,
à partir de model forms. le sous objet interface et l'objet domain à partir de model forms.
Trop complexe, devrait être simplifié""" Trop complexe, devrait être simplifié"""
try: try:
user = User.objects.get(pk=userid) user = User.objects.get(pk=userid)
@ -151,7 +214,9 @@ def new_machine(request, userid):
max_lambdauser_interfaces = options.max_lambdauser_interfaces max_lambdauser_interfaces = options.max_lambdauser_interfaces
if not request.user.has_perms(('cableur',)): if not request.user.has_perms(('cableur',)):
if user != request.user: if user != request.user:
messages.error(request, "Vous ne pouvez pas ajouter une machine à un autre user que vous sans droit") messages.error(
request,
"Vous ne pouvez pas ajouter une machine à un autre user que vous sans droit")
return redirect("/users/profil/" + str(request.user.id)) return redirect("/users/profil/" + str(request.user.id))
if user.user_interfaces().count() >= max_lambdauser_interfaces: if user.user_interfaces().count() >= max_lambdauser_interfaces:
messages.error(request, "Vous avez atteint le maximum d'interfaces autorisées que vous pouvez créer vous même (%s) " % max_lambdauser_interfaces) messages.error(request, "Vous avez atteint le maximum d'interfaces autorisées que vous pouvez créer vous même (%s) " % max_lambdauser_interfaces)
@ -1183,6 +1248,34 @@ def service_servers(request):
@csrf_exempt @csrf_exempt
@login_required @login_required
@permission_required('serveur') @permission_required('serveur')
def ouverture_ports(request):
r = {'ipv4':{}, 'ipv6':{}}
for o in OuverturePortList.objects.all().prefetch_related('ouvertureport_set').prefetch_related('interface_set', 'interface_set__ipv4'):
pl = {
"tcp_in":set(map(str,o.ouvertureport_set.filter(protocole=OuverturePort.TCP, io=OuverturePort.IN))),
"tcp_out":set(map(str,o.ouvertureport_set.filter(protocole=OuverturePort.TCP, io=OuverturePort.OUT))),
"udp_in":set(map(str,o.ouvertureport_set.filter(protocole=OuverturePort.UDP, io=OuverturePort.IN))),
"udp_out":set(map(str,o.ouvertureport_set.filter(protocole=OuverturePort.UDP, io=OuverturePort.OUT))),
}
for i in filter_active_interfaces(o.interface_set):
if i.may_have_port_open():
d = r['ipv4'].get(i.ipv4.ipv4, {})
d["tcp_in"] = d.get("tcp_in",set()).union(pl["tcp_in"])
d["tcp_out"] = d.get("tcp_out",set()).union(pl["tcp_out"])
d["udp_in"] = d.get("udp_in",set()).union(pl["udp_in"])
d["udp_out"] = d.get("udp_out",set()).union(pl["udp_out"])
r['ipv4'][i.ipv4.ipv4] = d
if i.ipv6_object:
d = r['ipv6'].get(i.ipv6, {})
d["tcp_in"] = d.get("tcp_in",set()).union(pl["tcp_in"])
d["tcp_out"] = d.get("tcp_out",set()).union(pl["tcp_out"])
d["udp_in"] = d.get("udp_in",set()).union(pl["udp_in"])
d["udp_out"] = d.get("udp_out",set()).union(pl["udp_out"])
r['ipv6'][i.ipv6] = d
return JSONResponse(r)
@csrf_exempt
@login_required
@permission_required('serveur')
def regen_achieved(request): def regen_achieved(request):
obj = Service_link.objects.filter(service__in=Service.objects.filter(service_type=request.POST['service']), server__in=Interface.objects.filter(domain__in=Domain.objects.filter(name=request.POST['server']))) obj = Service_link.objects.filter(service__in=Service.objects.filter(service_type=request.POST['service']), server__in=Interface.objects.filter(domain__in=Domain.objects.filter(name=request.POST['server'])))
if obj: if obj:

View file

@ -104,9 +104,9 @@ def all_has_access(search_time=DT_NOW):
).distinct() ).distinct()
def all_active_interfaces(): def filter_active_interfaces(interface_set):
"""Renvoie l'ensemble des machines autorisées à sortir sur internet """ """Filtre les machines autorisées à sortir sur internet dans une requête"""
return Interface.objects.filter( return interface_set.filter(
machine__in=Machine.objects.filter( machine__in=Machine.objects.filter(
user__in=all_has_access() user__in=all_has_access()
).filter(active=True) ).filter(active=True)
@ -116,6 +116,11 @@ def all_active_interfaces():
.distinct() .distinct()
def all_active_interfaces():
"""Renvoie l'ensemble des machines autorisées à sortir sur internet """
return filter_active_interfaces(Interface.objects)
def all_active_assigned_interfaces(): def all_active_assigned_interfaces():
""" Renvoie l'ensemble des machines qui ont une ipv4 assignées et """ Renvoie l'ensemble des machines qui ont une ipv4 assignées et
disposant de l'accès internet""" disposant de l'accès internet"""