Bläddra i källkod

new vyos2 api class, done #46, #74, #73, #72, #71 at add new rule

Roberto Berto 5 år sedan
förälder
incheckning
50c3482122

+ 1 - 1
vycontrol/firewall/templates/firewall/addressgroup-list.html

@@ -28,7 +28,7 @@
     {% for key, value in firewall_addressgroup.items %}       
         {% for ifkey, ifvalue in value.items %}
             <tr>
-                <td>{{ ifkey }}</a></td>
+                <td><a href="{% url 'firewall:firewall-addressgroup-desc' ifkey %}">{{ ifkey }}</a></td>
                 <td>{{ ifvalue.address }}</td>
                 <td>{{ ifvalue.description }}</td>
                 <td>

+ 90 - 34
vycontrol/firewall/templates/firewall/addrule.html

@@ -60,7 +60,7 @@
             <div class="col">
                 <p>
                     <label for="alias">rule number</label><br>
-                    <input type="text" name="rulenumber" id="rulenumber" value="{{ rulenumber }}" size="5">
+                    <input type="text" name="rulenumber" id="rulenumber" value="{{ rulenumber }}111" size="5">
                 </p>
             </div>
 
@@ -75,9 +75,9 @@
             <div class="col">
                 <p>
                     <label for="action">action</label><br>
-                    <input type="radio" class="fwaction" name="action" id="action" value="accept"> accept
-                    <input type="radio" class="fwaction" name="action" id="action" value="drop"> drop
-                    <input type="radio" class="fwaction" name="action" id="action" value="reject"> reject        
+                    <input type="radio" class="fwaction" name="ruleaction" id="action" value="accept"> accept
+                    <input type="radio" class="fwaction" name="ruleaction" id="action" value="drop"> drop
+                    <input type="radio" class="fwaction" name="ruleaction" id="action" value="reject"> reject        
                 </p>
             </div>
         </div>
@@ -86,7 +86,7 @@
             <div class="col">
                 <p>
                     <label for="alias">description</label><br>
-                    <input type="text" name="description" id="description" value="{{ description }}" size="60">
+                    <input type="text" name="description" id="description" value="{{ description }}xxx" size="60">
                 </p>
             </div>
 
@@ -95,7 +95,7 @@
     </div>
 
 
-    <h3><input type="checkbox" id="criteria_protocol" value="1"> <label for="criteria_protocol" class="label_for_h3">Matching criteria - protocol</label></h3>
+    <h3><input type="checkbox" name="criteria_protocol" value="1" id="criteria_protocol"> <label for="criteria_protocol" class="label_for_h3">Matching criteria - protocol</label></h3>
     <div class="container" id="criteria_protocol_block" style="display: none">
 
         <div class="row">
@@ -132,7 +132,7 @@
         </div>
     </div>
 
-    <h3><input type="checkbox" id="criteria_port" value="1" id="criteria_port"> <label for="criteria_port" class="label_for_h3">Matching criteria - port</label></h3>
+    <h3 id="criteria_port_block_header" style="display: none"><input type="checkbox" name="criteria_port" value="1" id="criteria_port"> <label for="criteria_port" class="label_for_h3">Matching criteria - port</label></h3>
     <div class="container" id="criteria_port_block" style="display: none">
         <div class="row">  
             <div class="col">
@@ -141,13 +141,17 @@
                 <p>
                     <label for="destinationport_common">common destinations ports to add</label><br>
                     <select name="destinationport_common" id="destinationport_common" size="1">
+                        <option value="">select one</option>
                         {% for p in services_common %}
-                        <option>{{ p }} - {{ services|get_item_port:p }} </option>
+                        <option value="{{ services|get_item_port:p }}">{{ p }} - {{ services|get_item_port:p }} </option>
                         {% endfor %}
                     </select>
 
+                    {% comment %}
                     <input type="checkbox" name="destinationport_common_negate" id="destinationport_common_negate" value="1">
                     <label for="destinationport_common_negate">negate </label>
+                    {% endcomment %}
+
                     <input type="button" name="destinationport_common_add" id="destinationport_common_add" value="add" />
                 </p>
 
@@ -155,8 +159,12 @@
                 <p>
                     <label for="destinationport_custom">add custom destination ports (use single 100 or range 100-200)</label><br>
                     <input type="text" name="destinationport_custom" id="destinationport_custom" value="{{ destinationport_custom }}" size="14"> 
+                    
+                    {% comment %}
                     <input type="checkbox" name="destinationport_custom_negate" id="destinationport_custom_negate" value="1"> 
                     <label for="destinationport_custom_negate">negate </label>
+                    {% endcomment %}
+
                     <input type="button" name="destinationport_custom_add" id="destinationport_custom_add" value="add" />
                 </p>                     
                 
@@ -164,6 +172,9 @@
                     <label for="destinationport">destination ports filtered (click to remove)</label><br>
                     <select name="destinationport" id="destinationport" size="10" style="width: 200px;">
                     </select>
+
+
+                    <input type="hidden" name="destinationport_json" id="destinationport_json" value="" >
                 </p>
                 
 
@@ -196,6 +207,10 @@
                     <label for="sourceport">source ports filtered (click to remove)</label><br>
                     <select name="sourceport" size="10" style="width: 200px;" id="sourceport">
                     </select>
+
+                    <input type="hidden" name="sourceport_json" id="sourceport_json" value="" >
+
+
                 </p>
 
 
@@ -224,7 +239,7 @@
     </div>
     -->
 
-    <h3><input type="checkbox" id="criteria_address" value="1" id="criteria_address"> <label for="criteria_address" class="label_for_h3">Matching criteria - address</label></h3>
+    <h3><input type="checkbox" id="criteria_address" value="1" name="criteria_address"> <label for="criteria_address" class="label_for_h3">Matching criteria - address</label></h3>
     <div class="container" id="criteria_address_block" style="display: none">
 
         <div class="row">
@@ -272,7 +287,7 @@
         </div>
     </div>
     
-    <h3><input type="checkbox" id="criteria_addressgroup" value="1" id="criteria_addressgroup"> <label for="criteria_addressgroup" class="label_for_h3">Matching criteria - address-group</label></h3>    
+    <h3><input type="checkbox" id="criteria_addressgroup" value="1" name="criteria_addressgroup"> <label for="criteria_addressgroup" class="label_for_h3">Matching criteria - address-group</label></h3>    
     <div class="container" id="criteria_addressgroup_block" style="display: none">    
 
         <div class="row">
@@ -305,7 +320,7 @@
     </div>
 
 
-    <h3><input type="checkbox" id="criteria_networkgroup" value="1" id="criteria_networkgroup"> <label for="criteria_networkgroup" class="label_for_h3">Matching criteria - network-group</label></h3>    
+    <h3><input type="checkbox" id="criteria_networkgroup" value="1" name="criteria_networkgroup"> <label for="criteria_networkgroup" class="label_for_h3">Matching criteria - network-group</label></h3>    
     <div class="container" id="criteria_networkgroup_block" style="display: none">
         <div class="row">
             <div class="col">
@@ -336,7 +351,7 @@
 
     </div>    
 
-    <h3><input type="checkbox" id="criteria_portgroup" value="1" id="criteria_portgroup"> <label for="criteria_portgroup" class="label_for_h3">Matching criteria - port group</label></h3>    
+    <h3><input type="checkbox" id="criteria_portgroup" value="1" name="criteria_portgroup"> <label for="criteria_portgroup" class="label_for_h3">Matching criteria - port group</label></h3>    
     <div class="container" id="criteria_portgroup_block" style="display: none">
         <div class="row">
             <div class="col">
@@ -367,7 +382,7 @@
 
     </div>    
 
-    <h3><input type="checkbox" id="criteria_sourcemac" value="1" id="criteria_sourcemac"> <label for="criteria_sourcemac" class="label_for_h3">Matching criteria - source mac address</label></h3>    
+    <h3><input type="checkbox" id="criteria_sourcemac" value="1" name="criteria_sourcemac"> <label for="criteria_sourcemac" class="label_for_h3">Matching criteria - source mac address</label></h3>    
     <div class="container" id="criteria_sourcemac_block" style="display: none">
         <div class="row">
             <div class="col">
@@ -385,7 +400,7 @@
 
     </div>
 
-    <h3><input type="checkbox" id="criteria_tcpflags" value="1" id="criteria_tcpflags"> <label for="criteria_tcpflags" class="label_for_h3">Matching criteria - TCP Flags</label></h3>    
+    <h3><input type="checkbox" id="criteria_tcpflags" value="1" name="criteria_tcpflags"> <label for="criteria_tcpflags" class="label_for_h3">Matching criteria - TCP Flags</label></h3>    
     <div class="container" id="criteria_tcpflags_block" style="display: none">
         <div class="row">
             <div class="col">
@@ -428,7 +443,7 @@
         </div>
     </div>
 
-    <h3><input type="checkbox" id="criteria_packetstate" value="1" id="criteria_packetstate"> <label for="criteria_packetstate" class="label_for_h3">Matching criteria - Packet State</label></h3>    
+    <h3><input type="checkbox" id="criteria_packetstate" value="1" name="criteria_packetstate"> <label for="criteria_packetstate" class="label_for_h3">Matching criteria - Packet State</label></h3>    
     <div class="container" id="criteria_packetstate_block" style="display: none">
         <div class="row">
             <div class="col">
@@ -456,6 +471,17 @@
             else if ($("#addresstype_range").not(":checked")) {
                 $('#protocol_custom_block').hide();
             }
+
+            protocol_criteria = $('.protocol_criteria:checked').val();
+
+
+            if (['tcp', 'udp', 'tcp_udp'].includes(protocol_criteria) == false) {
+                $("#criteria_port").prop("checked", false);
+                $("#criteria_port_block_header").hide();
+                $("#criteria_port_block").hide();
+            } else {
+                $("#criteria_port_block_header").show();
+            }
         });
 
         $("#criteria_protocol").change(function () {
@@ -512,7 +538,6 @@
             }
         });                                        
 
-
         $("#criteria_sourcemac").change(function () {
             if ($("#criteria_sourcemac").is(":checked")) {
                 $('#criteria_sourcemac_block').show();
@@ -531,7 +556,6 @@
             }
         });
 
-
         $("#criteria_packetstate").change(function () {
             if ($("#criteria_packetstate").is(":checked")) {
                 $('#criteria_packetstate_block').show();
@@ -541,22 +565,55 @@
             }
         });   
 
+        function isNumeric(n) {
+            return !isNaN(parseFloat(n)) && isFinite(n);
+        }
+
         // form basic validations
         $("#form_addrule").submit(function(e){
-            if ($('#rulenumber').val() < 1){
-                alert('Rule numed must be definied.');
+            rulenumber = $('#rulenumber').val();
+            
+
+            if (rulenumber == "" || isNumeric(rulenumber) == false) {
+                alert('Rule number must be definied and be numeric.');
+                e.preventDefault();
+                return false;
+            } else if (rulenumber < 1 && rulenumber > 9999) {
+                alert('Rule number must be between 1 and 9999.');
                 e.preventDefault();
                 return false;
-            } else if (!$('.fwaction').is(':checked')){
+            }
+            
+            if (!$('.fwaction').is(':checked')){
                 alert('Rule action must be selected.');
                 e.preventDefault();
                 return false;
             } 
+
+            var destinationport_values = []
+            $("#destinationport option").each(function() {
+                destinationport_values.push($(this).val());
+            });
+            var destinationport_json = JSON.stringify(destinationport_values);
+            $("#destinationport_json").val(destinationport_json);
+
+            var sourceport_values = []
+            $("#sourceport option").each(function() {
+                sourceport_values.push($(this).val());
+            });            
+            var sourceport_json = JSON.stringify(sourceport_values);
+            $("#sourceport_json").val(sourceport_json);
+
+            console.log(sourceport_json)
+
+
+            //e.preventDefault();
         });
 
         
         $("#sourceport_common_add").click(function () {
             port = $("#sourceport_common").children("option:selected").val();
+            text = $("#sourceport_common").children("option:selected").text();            
             if (port == "") {
                 return false;
             }
@@ -567,12 +624,13 @@
                 negate = "";
             }
 
-            port_text = negate + port;
+            v = negate + port;
+            t = negate + text;
 
-            if ($("#sourceport option[value='" + port_text + "']").length == 0) {
+            if ($("#sourceport option[value='" + v + "']").length == 0) {
                 $('#sourceport').append($('<option>', {
-                    value: port_text,
-                    text: port_text
+                    value: v,
+                    text: t
                 }));
             }
         });
@@ -599,9 +657,9 @@
             }
         });
 
-
         $("#destinationport_common_add").click(function () {
             port = $("#destinationport_common").children("option:selected").val();
+            text = $("#destinationport_common").children("option:selected").text();
             if (port == "") {
                 return false;
             }
@@ -612,12 +670,13 @@
                 negate = "";
             }
 
-            port_text = negate + port;
+            v = negate + port;
+            t = negate + text;
 
-            if ($("#destinationport option[value='" + port_text + "']").length == 0) {
+            if ($("#destinationport option[value='" + v + "']").length == 0) {
                 $('#destinationport').append($('<option>', {
-                    value: port_text,
-                    text: port_text
+                    value: v,
+                    text: t
                 }));
             }
         });
@@ -644,18 +703,15 @@
             }
         });
 
-        
-
-
         $('#sourceport').click(function() {
             $(this).find('option:selected').remove();
         });
+
         $('#destinationport').click(function() {
             $(this).find('option:selected').remove();
         });        
-                
 
-    });
+ });
 </script>
           
 

+ 158 - 53
vycontrol/firewall/views.py

@@ -5,12 +5,13 @@ from django.shortcuts import redirect
 from django.conf import settings
 from django.urls import reverse
 
-import vyos
+import vyos, vyos2
 from performance import timer
 from perms import is_authenticated
 import perms
 import network
 import json
+import pprint
 
 from filters.vycontrol_filters import get_item
 from filters.vycontrol_filters import get_item_port
@@ -21,6 +22,18 @@ def index(request):
     #interfaces = vyos.get_interfaces()
     all_instances = vyos.instance_getall_by_group(request)
     hostname_default = vyos.get_hostname_prefered(request)
+
+
+    firewall2 = vyos2.api(
+        hostname =      hostname_default,
+        api =           'get',
+        op =            'showConfig',
+        cmd =           {"op": "showConfig", "path": ["firewall"]},
+        description =   "get all firewall",
+    )
+
+
+
     is_superuser = perms.get_is_superuser(request.user)
 
 
@@ -92,78 +105,169 @@ def addrule(request, firewall_name):
     firewall_addressgroup = vyos.get_firewall_addressgroup(hostname_default)
     firewall_networkgroup_js = json.dumps(firewall_networkgroup['network-group'])
     firewall_addressgroup_js = json.dumps(firewall_addressgroup['address-group'])
-    portgroups = vyos.get_firewall_portgroup(hostname_default)
-    portgroups_groups = portgroups['port-group']
-
-
     netservices = network.get_services()
     netservices_js = json.dumps(netservices)
+    portgroups = vyos.get_firewall_portgroup(hostname_default)
+
+    if portgroups != False:
+        portgroups_groups = portgroups['port-group']
+    else:
+        portgroups_groups = []
 
     changed = False
 
-    # verifing basic informations
-    if (request.POST.get('rulenumber',None) != None and 
-        request.POST.get('rulenumber') != "" and 
-        int(request.POST.get('rulenumber')) > 0 and
-        request.POST.get('status',None) != None and
-        request.POST.get('status',None) in ("enabled", "disabled") and
-        request.POST.get('action',None) in ("accept","drop","reject")):
-        
-        cmd = {"op": "set", "path": ["firewall", "name", firewall_name, "rule", request.POST['rulenumber'], "action", request.POST['action']]}
-        result1 = vyos.set_config(hostname_default, cmd)
-        print(result1)
-        #if result1['success'] == True:
-        #    changed = True 
 
-        cmd = {"op": "set", "path": ["firewall", "name", firewall_name, "rule", request.POST['rulenumber'], "status", request.POST['status']]}
-        result1 = vyos.set_config(hostname_default, cmd)
-        print(result1)
-        #if result1['success'] == True:
-        #    changed = True 
+    # verifing basic informations, should have rulenumber, status and ruleaction
+    if (    request.POST.get('rulenumber', None) != None 
+        and int(request.POST.get('rulenumber')) > 0
+        and request.POST.get('status', None) != None
+        and request.POST.get('status') in ["enabled", "disabled"]
+        and request.POST.get('ruleaction', None) != None
+        and request.POST.get('ruleaction') in ["accept", "drop", "reject"]
+    ):
+        vyos2.log("basic pass x")
+
+
+        v = vyos2.api (
+            hostname=   hostname_default,
+            api =       "post",
+            op =        "set",
+            cmd =       ["firewall", "name", firewall_name, "rule", request.POST.get('rulenumber'), "action", request.POST.get('ruleaction')],
+            description = "set rule action",
+        )
+        # rule created, continue to configure firewall rule according his criterias
+        if v.success:
+            changed = True 
+
+            # if status disabled, save it
+            if request.POST.get('status') == "disabled":
+                v = vyos2.api (
+                    hostname=   hostname_default,
+                    api =       "post",
+                    op =        "set",
+                    cmd =       ["firewall", "name", firewall_name, "rule", request.POST.get('rulenumber'), "disable"],
+                    description = "set rule disable",
+                )
+
+            # if status set, save it
+            if request.POST.get('description', None) != None:
+                v = vyos2.api (
+                    hostname=   hostname_default,
+                    api =       "post",
+                    op =        "set",
+                    cmd =       ["firewall", "name", firewall_name, "rule", request.POST.get('rulenumber'), "description", request.POST.get('description')],
+                    description = "set rule description",
+                )     
+
+            # if criteria protocol set, save it
+            if request.POST.get('criteria_protocol', None) == "1":
+                # other protocol - todo validate data
+                if request.POST.get('protocol_criteria', None) == "other":
+                    if request.POST.get('protocol_custom', None) != None:
+                        protocol_criteria = request.POST.get('protocol_custom')
+                # common protocols
+                elif request.POST.get('protocol_criteria', None) in ['all', 'tcp', 'udp', 'tcp_udp', 'icmp']:
+                    protocol_criteria = request.POST.get('protocol_criteria')
+                # other cases did not checked anything
+                else:
+                     protocol_criteria = None   
 
-        cmd = {"op": "set", "path": ["firewall", "name", firewall_name, "rule", request.POST['rulenumber'], "description", request.POST['description']]}
-        result1 = vyos.set_config(hostname_default, cmd)
-        print(result1)
-        #if result1['success'] == True:
-        #    changed = True 
+                # negate protocol
+                if request.POST.get('protocol_negate', None) == "1":
+                    protocol_negate = "!"
+                else:
+                    protocol_negate = ""
 
+                # run vyos command
+                if protocol_criteria != None:
+                    protocol_criteria_txt = protocol_negate + protocol_criteria
 
+                    v = vyos2.api (
+                        hostname=   hostname_default,
+                        api =       "post",
+                        op =        "set",
+                        cmd =       ["firewall", "name", firewall_name, "rule", request.POST.get('rulenumber'), "protocol", protocol_criteria_txt],
+                        description = "set rule protocol",
+                    )                                
 
-        if request.POST.get('protocol_criteria', None) != None:
-            protocol_criteria = None
-            protocol_negate = False
+            # if criteria port set, save it
+            if request.POST.get('criteria_port', None) == "1":
+                destinationport_json =  request.POST.get('destinationport_json', None)
+                sourceport_json =       request.POST.get('sourceport_json', None)
 
-            if request.POST.get('protocol_criteria') == "other":
-                if request.POST.get('protocol_custom', None) != None:
-                    protocol_criteria = request.POST.get('protocol_custom')
-            else:
-                protocol_criteria = request.POST.get('protocol_criteria')
+                if destinationport_json != None:
 
-            if request.POST.get('protocol_negate', None) == "1":
-                protocol_negate = True
+                    try:
+                        destinationport = json.loads(destinationport_json)
+                    except ValueError:
+                        destinationport = {}
 
+                    vyos2.log("destinationport_json", destinationport)
+                    destinationport_text = ','.join(destinationport)
 
+                    
+                    v = vyos2.api (
+                        hostname=   hostname_default,
+                        api =       "post",
+                        op =        "set",
+                        cmd =       ["firewall", "name", firewall_name, "rule", request.POST.get('rulenumber'), "destination", "port", destinationport_text],
+                        description = "set destination port",
+                    ) 
 
-            if protocol_criteria != None:
-                protocol_criteria_txt = ""
-                if protocol_negate == True:
-                    protocol_criteria_txt = "!" + protocol_criteria
-                else:
-                    protocol_criteria_txt = protocol_criteria
+                if sourceport_json != None:
+
+                    try:
+                        sourceport = json.loads(sourceport_json)
+                    except ValueError:
+                        sourceport = {}          
+
+                    vyos2.log("sourceport_json", sourceport)
+                    sourceport_text = ','.join(sourceport)
+
+                    v = vyos2.api (
+                        hostname=   hostname_default,
+                        api =       "post",
+                        op =        "set",
+                        cmd =       ["firewall", "name", firewall_name, "rule", request.POST.get('rulenumber'), "source", "port", sourceport_text],
+                        description = "set sourceport port",
+                    )
 
-                cmd = {"op": "set", "path": ["firewall", "name", firewall_name, "rule", request.POST['rulenumber'], "protocol", protocol_criteria_txt]}
-                result1 = vyos.set_config(hostname_default, cmd)
-                print(result1)
-                #if result1['success'] == True:
-                changed = True 
 
 
-            #set firewall name WAN-IN-v4 rule 11 protocol !tcp_udp
+    """
+  
 
 
+            #  optional matching crieteria criteria_port
+            if request.POST.get('criteria_port', None) == "1":
+                #destinationport_json
+                #sourceport_json
 
+                if request.POST.get('destinationport_json', None) != None:
+                    try:
+                        destinationports = json.loads(request.POST.get('destinationport_json'))
+                    except ValueError:
+                        return redirect('firewall:firewall-list')
 
-        """if 'protocol' in request.POST:
+                    print("###################")
+                    pprint.pprint(destinationports)
+
+                    for destinationport in destinationports:
+                        #cmd = {"op": "set", "path": ["firewall", "name", firewall_name, "rule", request.POST['rulenumber'], "protocol", protocol_criteria_txt]}
+                        #result1 = vyos.set_config(hostname_default, cmd)
+                        #print(result1)
+                        print("###################")
+                        pprint.pprint(destinationport)
+                        #if result1['success'] == True:
+                        changed = True 
+
+            
+
+
+
+
+
+        #""if 'protocol' in request.POST:
             cmd = {"op": "set", "path": ["firewall", "name", firewall_name, "rule", request.POST['rulenumber'], "protocol", request.POST['protocol']]}
             result2 = vyos.set_config(hostname_default, cmd)
             print(result2)
@@ -179,10 +283,11 @@ def addrule(request, firewall_name):
             cmd = {"op": "set", "path": ["firewall", "name", firewall_name, "rule", request.POST['rulenumber'], "source", "port", request.POST['sourceport']]}
             result3 = vyos.set_config(hostname_default, cmd)
             print(result3)        
-            changed = True"""
+            changed = True""#
 
         if changed == True:
-            return redirect('firewall:show', firewall_name)
+            return redirect('firewall:show', firewall_name)"""
+    
 
     template = loader.get_template('firewall/addrule.html')
     context = { 

+ 1 - 0
vycontrol/vycenter/templates/base.html

@@ -5,6 +5,7 @@
     <!-- Required meta tags -->
     <meta charset="utf-8">
     <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+    <link rel="shortcut icon" href="data:image/x-icon;," type="image/x-icon"> 
 
     <!-- Bootstrap CSS -->
     <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">