def test_intersect_rules():
    r1 = [
        Rule(src=ipset('1.0.0.0/24'),
             dst=ipset('0.0.0.0/0'),
             app='app',
             name='r1'),
    ]
    r2 = [
        Rule(src=ipset('1.0.0.10', '1.0.0.14'),
             dst=ipset('0.0.0.0/0'),
             app='app',
             name='r2'),
    ]
    r3 = [
        Rule(src=ipset('1.0.0.11', '1.0.0.14'),
             dst=ipset('0.0.0.0/0'),
             app='app',
             name='r3'),
    ]
    eq_(
        process.intersect_rules([r1, r2, r3], ipset('0.0.0.0/0'),
                                ipset('2.0.0.0/8')), [
                                    Rule(src=ipset('1.0.0.14'),
                                         dst=ipset('2.0.0.0/8'),
                                         app='app',
                                         name='r1+r2+r3'),
                                ])
def test_rules_from_to_no_match_dst():
    rules = [
        Rule(src=ipset('1.0.0.0/8'),
             dst=ipset('3.0.0.0/24'),
             app='app',
             name='r'),
    ]
    eq_(process.rules_from_to(rules, ipset('1.0.0.0/8'), ipset('2.0.0.0/8')),
        [])
예제 #3
0
def test_limited_by_space():
    lax_rules = {'app': [
    ]}
    lga_rules = {'app': [
        # /7 covers both lax and lga
        Rule(ipset('0.0.0.0/7'), ipset('2.0.0.0/8'), 'app', 'lga'),
    ]}
    ord_rules = {'app': [
        Rule(ipset('0.0.0.0/7'), ipset('2.0.0.0/8'), 'app', 'ord'),
    ]}
    address_spaces = {
        'lax': ipset('0.0.0.0/8'),
        'lga': ipset('1.0.0.0/8'),
        'ord': ipset('2.0.0.0/8'),
    }
    routes = {
        ('lax', 'lax'): ['fw1.lax'],
        ('lax', 'lga'): ['fw1.lga', 'fw1.lax'],
        ('lax', 'ord'): ['fw1.ord', 'fw1.lax'],
        ('lga', 'lax'): ['fw1.lax', 'fw1.lga'],
        ('lga', 'lga'): ['fw1.lga'],
        ('lga', 'ord'): ['fw1.ord', 'fw1.lga'],
        ('ord', 'lax'): ['fw1.ord', 'fw1.lax'],
        ('ord', 'lga'): ['fw1.ord', 'fw1.lga'],
        ('ord', 'ord'): ['fw1.ord'],
    }
    sources = {'fw1.ord': ord_rules, 'fw1.lga': lga_rules, 'fw1.lax': lax_rules}
    with no_simplify():
        result = process.combine(address_spaces, routes, sources)
        eq_(result, {'app': [
            # only lga's address space is allowed
            Rule(ipset('1.0.0.0/8'), ipset('2.0.0.0/8'), 'app', 'lga+ord'),
        ]})
예제 #4
0
def test_one_address_space():
    rules = {'app': [
        Rule(ipset('1.2.3.4'), ipset('1.7.7.7'), 'app', 'p2p'),
        Rule(ipset('1.2.5.0/24'), ipset('1.7.7.7'), 'app', 'net'),
    ]}
    with no_simplify():
        result = process.combine(
            {'nyc': ipset('1.0.0.0/8')},
            {('nyc', 'nyc'): ['fw1.nyc']},
            {'fw1.nyc': rules})
        eq_(sorted(result), sorted(rules))
예제 #5
0
def test_make_diff():
    eq_(sorted(diff.make_diff(FakeSource(LEFT), FakeSource(RIGHT))), sorted([
        # expand stage from /25 to /24
        ('+', 'db', ipset('10.20.20.128/25'), ipset('10.20.30.16')),
        ('+', 'http', ipset('0.0.0.0/0'), ipset('10.20.20.128/25')),
        ('+', 'ssh', ipset('10.2.1.1'), ipset('10.20.20.128/25')),
        # add production db server
        ('+', 'db', ipset('10.20.19.0/24'), ipset('10.20.30.28')),
        # remove ssh access to production
        ('-', 'ssh', ipset('10.2.1.1'), ipset('10.20.19.0/24', '10.20.30.15', '10.20.30.19')),
    ]))
예제 #6
0
def test_identical_rules():
    rules = {'app': [
        Rule(ipset('2.7.7.0/24'), ipset('1.7.7.0/24'), 'app', 'lga-ord'),
    ]}
    address_spaces = {
        'lga': ipset('1.0.0.0/8'),
        'ord': ipset('2.0.0.0/8'),
    }
    sources = {'fw1.ord': rules, 'fw1.lga': rules}
    with no_simplify():
        result = process.combine(address_spaces, routes, sources)
        eq_(result, rules)
def test_one_address_space():
    rules = {
        'app': [
            Rule(ipset('1.2.3.4'), ipset('1.7.7.7'), 'app', 'p2p'),
            Rule(ipset('1.2.5.0/24'), ipset('1.7.7.7'), 'app', 'net'),
        ]
    }
    with no_simplify():
        result = process.combine({'nyc': ipset('1.0.0.0/8')},
                                 {('nyc', 'nyc'): ['fw1.nyc']},
                                 {'fw1.nyc': rules})
        eq_(sorted(result), sorted(rules))
def test_identical_rules():
    rules = {
        'app': [
            Rule(ipset('2.7.7.0/24'), ipset('1.7.7.0/24'), 'app', 'lga-ord'),
        ]
    }
    address_spaces = {
        'lga': ipset('1.0.0.0/8'),
        'ord': ipset('2.0.0.0/8'),
    }
    sources = {'fw1.ord': rules, 'fw1.lga': rules}
    with no_simplify():
        result = process.combine(address_spaces, routes, sources)
        eq_(result, rules)
def test_overlapping_rules():
    lga_rules = {
        'app': [
            Rule(ipset('1.1.0.0/16'), ipset('2.0.0.0/8'), 'app', 'lga'),
        ]
    }
    ord_rules = {
        'app': [
            Rule(ipset('1.0.0.0/8'), ipset('2.1.0.0/16'), 'app', 'ord'),
        ]
    }
    address_spaces = {
        'lga': ipset('1.0.0.0/8'),
        'ord': ipset('2.0.0.0/8'),
    }
    sources = {'fw1.ord': ord_rules, 'fw1.lga': lga_rules}

    with no_simplify():
        result = process.combine(address_spaces, routes, sources)
        eq_(
            result,
            {
                'app': [
                    # takes the intersection of both rules:
                    Rule(ipset('1.1.0.0/16'), ipset('2.1.0.0/16'), 'app',
                         'lga+ord'),
                ]
            })
예제 #10
0
def test_intersect_rules():
    r1 = [
        Rule(src=ipset('1.0.0.0/24'), dst=ipset('0.0.0.0/0'), app='app', name='r1'),
    ]
    r2 = [
        Rule(src=ipset('1.0.0.10', '1.0.0.14'), dst=ipset('0.0.0.0/0'),
             app='app', name='r2'),
    ]
    r3 = [
        Rule(src=ipset('1.0.0.11', '1.0.0.14'), dst=ipset('0.0.0.0/0'),
             app='app', name='r3'),
    ]
    eq_(process.intersect_rules([r1, r2, r3], ipset('0.0.0.0/0'), ipset('2.0.0.0/8')), [
        Rule(src=ipset('1.0.0.14'), dst=ipset('2.0.0.0/8'), app='app', name='r1+r2+r3'),
    ])
예제 #11
0
def test_rules_from_to_intersection():
    rules = [
        Rule(src=ipset('0.0.0.0/7'), dst=ipset('2.0.1.0/24'), app='app', name='r'),
    ]
    eq_(process.rules_from_to(rules, ipset('1.0.0.0/8'), ipset('2.0.0.0/8')), [
        Rule(src=ipset('1.0.0.0/8'), dst=ipset('2.0.1.0/24'), app='app', name='r'),
    ])
def test_limited_by_space():
    lax_rules = {'app': []}
    lga_rules = {
        'app': [
            # /7 covers both lax and lga
            Rule(ipset('0.0.0.0/7'), ipset('2.0.0.0/8'), 'app', 'lga'),
        ]
    }
    ord_rules = {
        'app': [
            Rule(ipset('0.0.0.0/7'), ipset('2.0.0.0/8'), 'app', 'ord'),
        ]
    }
    address_spaces = {
        'lax': ipset('0.0.0.0/8'),
        'lga': ipset('1.0.0.0/8'),
        'ord': ipset('2.0.0.0/8'),
    }
    routes = {
        ('lax', 'lax'): ['fw1.lax'],
        ('lax', 'lga'): ['fw1.lga', 'fw1.lax'],
        ('lax', 'ord'): ['fw1.ord', 'fw1.lax'],
        ('lga', 'lax'): ['fw1.lax', 'fw1.lga'],
        ('lga', 'lga'): ['fw1.lga'],
        ('lga', 'ord'): ['fw1.ord', 'fw1.lga'],
        ('ord', 'lax'): ['fw1.ord', 'fw1.lax'],
        ('ord', 'lga'): ['fw1.ord', 'fw1.lga'],
        ('ord', 'ord'): ['fw1.ord'],
    }
    sources = {
        'fw1.ord': ord_rules,
        'fw1.lga': lga_rules,
        'fw1.lax': lax_rules
    }
    with no_simplify():
        result = process.combine(address_spaces, routes, sources)
        eq_(
            result,
            {
                'app': [
                    # only lga's address space is allowed
                    Rule(ipset('1.0.0.0/8'), ipset('2.0.0.0/8'), 'app',
                         'lga+ord'),
                ]
            })
예제 #13
0
def test_overlapping_rules():
    lga_rules = {'app': [
        Rule(ipset('1.1.0.0/16'), ipset('2.0.0.0/8'), 'app', 'lga'),
    ]}
    ord_rules = {'app': [
        Rule(ipset('1.0.0.0/8'), ipset('2.1.0.0/16'), 'app', 'ord'),
    ]}
    address_spaces = {
        'lga': ipset('1.0.0.0/8'),
        'ord': ipset('2.0.0.0/8'),
    }
    sources = {'fw1.ord': ord_rules, 'fw1.lga': lga_rules}

    with no_simplify():
        result = process.combine(address_spaces, routes, sources)
        eq_(result, {'app': [
            # takes the intersection of both rules:
            Rule(ipset('1.1.0.0/16'), ipset('2.1.0.0/16'), 'app', 'lga+ord'),
        ]})
def test_rules_from_to_intersection():
    rules = [
        Rule(src=ipset('0.0.0.0/7'),
             dst=ipset('2.0.1.0/24'),
             app='app',
             name='r'),
    ]
    eq_(process.rules_from_to(rules, ipset('1.0.0.0/8'), ipset('2.0.0.0/8')), [
        Rule(src=ipset('1.0.0.0/8'),
             dst=ipset('2.0.1.0/24'),
             app='app',
             name='r'),
    ])
예제 #15
0
def test_nonoverlapping_rules():
    lga_rules = {'app': [
        Rule(ipset('1.2.5.0/24'), ipset('2.2.5.0/24'), 'app', 'lga'),
    ]}
    ord_rules = {'app': [
        Rule(ipset('2.7.7.0/24'), ipset('1.7.7.0/24'), 'app', 'ord'),
    ]}
    address_spaces = {
        'ord': ipset('2.0.0.0/8'),
        'lga': ipset('1.0.0.0/8'),
    }
    sources = {'fw1.ord': ord_rules, 'fw1.lga': lga_rules}
    with no_simplify():
        result = process.combine(address_spaces, routes, sources)
        eq_(result, {})
예제 #16
0
def test_process_global_priority():
    # test the relative priority of "regular" (per-zone) and global policies
    policies = [
        mkpol(name='ok', from_zone='pvt', to_zone='pub',
            src_addrs=ipset('192.168.1.2/31'), dst_addrs=ipset('0.0.0.0/0'),
            applications=['junos-ssh'], sequence=100),
        mkpol(name='deny-all-global', from_zone=None, to_zone=None,
            src_addrs=ipset('0.0.0.0/0'), dst_addrs=ipset('0.0.0.0/0'),
            applications=['junos-ssh'], sequence=3, action='deny'),
        mkpol(name='ok-global', from_zone=None, to_zone=None,
            src_addrs=ipset('192.168.1.128/32'), dst_addrs=ipset('128.135.0.0/16'),
            applications=['junos-ssh'], sequence=1),
    ]
    res = call_process_rules(APP_MAP, policies, ZONE_NETS)
    exp = {
        'junos-ssh': [
            Rule(src=ipset('192.168.1.128/32', '192.168.1.2/31'),
                 dst=ipset('128.135.0.0/16'),
                 app='junos-ssh', name='ok+ok-global'),
        ],
    }
    [ruleset.sort() for ruleset in exp.itervalues()]
    eq_(res, exp)
예제 #17
0
def test_process_global_priority():
    # test the relative priority of "regular" (per-zone) and global policies
    policies = [
        mkpol(name='ok',
              from_zone='pvt',
              to_zone='pub',
              src_addrs=ipset('192.168.1.2/31'),
              dst_addrs=ipset('0.0.0.0/0'),
              applications=['junos-ssh'],
              sequence=100),
        mkpol(name='deny-all-global',
              from_zone=None,
              to_zone=None,
              src_addrs=ipset('0.0.0.0/0'),
              dst_addrs=ipset('0.0.0.0/0'),
              applications=['junos-ssh'],
              sequence=3,
              action='deny'),
        mkpol(name='ok-global',
              from_zone=None,
              to_zone=None,
              src_addrs=ipset('192.168.1.128/32'),
              dst_addrs=ipset('128.135.0.0/16'),
              applications=['junos-ssh'],
              sequence=1),
    ]
    res = call_process_rules(APP_MAP, policies, ZONE_NETS)
    exp = {
        'junos-ssh': [
            Rule(src=ipset('192.168.1.128/32', '192.168.1.2/31'),
                 dst=ipset('128.135.0.0/16'),
                 app='junos-ssh',
                 name='ok+ok-global'),
        ],
    }
    [ruleset.sort() for ruleset in exp.itervalues()]
    eq_(res, exp)
def test_nonoverlapping_rules():
    lga_rules = {
        'app': [
            Rule(ipset('1.2.5.0/24'), ipset('2.2.5.0/24'), 'app', 'lga'),
        ]
    }
    ord_rules = {
        'app': [
            Rule(ipset('2.7.7.0/24'), ipset('1.7.7.0/24'), 'app', 'ord'),
        ]
    }
    address_spaces = {
        'ord': ipset('2.0.0.0/8'),
        'lga': ipset('1.0.0.0/8'),
    }
    sources = {'fw1.ord': ord_rules, 'fw1.lga': lga_rules}
    with no_simplify():
        result = process.combine(address_spaces, routes, sources)
        eq_(result, {})
예제 #19
0
def test_process_interface_ips():
    routes = [
        # reth2 is the route to the Internet
        mkroute(destination="0.0.0.0/0", interface='reth2'),
        # reth1 is the gateway to the rest of the private space
        mkroute(destination="10.0.0.0/8", interface='reth1'),
        # reth7 is the peer link to some other private /16's
        mkroute(destination="10.128.0.0/16", interface='reth7'),
        mkroute(destination="10.130.0.0/15", interface='reth7'),
        # 10.129.0.0/16 is ours, but has only one active subnet,
        # with the rest blackholed
        mkroute(destination="10.129.0.0/16", reject=True),
        mkroute(destination="10.129.210.0/24",
                interface='reth0.210', is_local=True),
    ]
    interface_ips = process.process_interface_ips(routes)
    exp = {
        'reth0.210': ipset('10.129.210.0/24'),
        'reth1': ipset('10.0.0.0/8') - ipset('10.128.0.0/14'), # 10.{128-131}
        'reth2': ipset('0.0.0.0/0') - ipset('10.0.0.0/8'),
        'reth7': ipset('10.128.0.0/16') + ipset('10.130.0.0/15'),
    }
    eq_(interface_ips, exp)
예제 #20
0
def test_process_interface_ips():
    routes = [
        # reth2 is the route to the Internet
        mkroute(destination="0.0.0.0/0", interface='reth2'),
        # reth1 is the gateway to the rest of the private space
        mkroute(destination="10.0.0.0/8", interface='reth1'),
        # reth7 is the peer link to some other private /16's
        mkroute(destination="10.128.0.0/16", interface='reth7'),
        mkroute(destination="10.130.0.0/15", interface='reth7'),
        # 10.129.0.0/16 is ours, but has only one active subnet,
        # with the rest blackholed
        mkroute(destination="10.129.0.0/16", reject=True),
        mkroute(destination="10.129.210.0/24",
                interface='reth0.210',
                is_local=True),
    ]
    interface_ips = process.process_interface_ips(routes)
    exp = {
        'reth0.210': ipset('10.129.210.0/24'),
        'reth1': ipset('10.0.0.0/8') - ipset('10.128.0.0/14'),  # 10.{128-131}
        'reth2': ipset('0.0.0.0/0') - ipset('10.0.0.0/8'),
        'reth7': ipset('10.128.0.0/16') + ipset('10.130.0.0/15'),
    }
    eq_(interface_ips, exp)
예제 #21
0
def test_rules_from_to_no_match_dst():
    rules = [
        Rule(src=ipset('1.0.0.0/8'), dst=ipset('3.0.0.0/24'), app='app', name='r'),
    ]
    eq_(process.rules_from_to(rules, ipset('1.0.0.0/8'), ipset('2.0.0.0/8')),
        [])
예제 #22
0
    'fw.nyc': {
        'output': 'fw.nyc.json'
    },
    'enterprise': {
        'address_spaces': {
            'ord': '100.0.0.0/8',
            'lax': '200.0.0.0/8',
            'nyc': '240.0.0.0/8',
        },
        'routes': {},
    },
}

exp_address_spaces = {
    'ord':
    ipset('100.0.0.0/8'),
    'lax':
    ipset('200.0.0.0/8'),
    'nyc':
    ipset('240.0.0.0/8'),
    'unmanaged':
    ipset('0.0.0.0/0') - ipset('100.0.0.0/8') - ipset('200.0.0.0/8') -
    ipset('240.0.0.0/8'),
}

empty_exp_routes = {(s, d): set()
                    for s in exp_address_spaces for d in exp_address_spaces}


def exp_sources(*srcs):
    return {s: "rules for " + s for s in srcs}
def test_sourcesFor_unknown_app():
    eq_(rules.sourcesFor('10.1.1.1', 'somerandomapp'), ipset('1.2.3.4'))
예제 #24
0
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

from nose.tools import eq_
from fwunit.srx import parse
from fwunit.srx import process
from fwunit.common import ApplicationMap
from fwunit.test.util import ipset
from fwunit.types import Rule
from fwunit import IP

APP_MAP = ApplicationMap(dict(application_map={'junos-ssh': 'ssh'}))
ZONE_NETS = {
    'pvt': ipset('192.168.0.0/16'),
    'dmz': ipset('10.0.0.0/8'),
    'pub': ipset('128.135.0.00/16'),
}


def mkpol(**kwargs):
    kwargs.setdefault('action', 'permit')
    kwargs.setdefault('enabled', True)
    kwargs.setdefault('sequence', 1)
    kwargs['source_addresses'] = kwargs.pop('src_addrs')
    kwargs['destination_addresses'] = kwargs.pop('dst_addrs')
    pol = parse.Policy()
    for k, v in kwargs.iteritems():
        setattr(pol, k, v)
    return pol
예제 #25
0
def test_process_rules_any_app():
    # test basic functionality + the "any" app
    policies = [
        mkpol(name='dbssh', from_zone='pvt', to_zone='pvt',
            src_addrs=ipset('192.168.1.2/31'), dst_addrs=ipset('0.0.0.0/0'),
            applications=['junos-ssh', 'junos-ping'], sequence=1),
        mkpol(name='admin', from_zone='pvt', to_zone='pvt',
            src_addrs=ipset('192.168.1.128/32'), dst_addrs=ipset('0.0.0.0/0'),
            applications=['any'], sequence=2),
        mkpol(name='admin', from_zone='pvt', to_zone='dmz',
            src_addrs=ipset('192.168.1.128/32'), dst_addrs=ipset('0.0.0.0/0'),
            applications=['any']),
        mkpol(name='admin', from_zone='pvt', to_zone='pub',
            src_addrs=ipset('192.168.1.128/32'), dst_addrs=ipset('0.0.0.0/0'),
            applications=['any']),
        mkpol(name='http', from_zone='pub', to_zone='dmz',
            src_addrs=ipset('0.0.0.0/0'), dst_addrs=ipset('10.1.10.0/24'),
            applications=['web']),
        mkpol(name='db', from_zone='dmz', to_zone='pvt',
            src_addrs=ipset('10.1.10.0/24'), dst_addrs=ipset('192.168.1.2/31'),
            applications=['db']),
    ]
    res = call_process_rules(APP_MAP, policies, ZONE_NETS)
    exp = {
        'junos-ping': [
            Rule(src=ipset('192.168.1.128'),
                 dst=ipset('10.0.0.0/8', '128.135.0.0/16', '192.168.0.0/16'),
                 app='junos-ping', name='admin'),
            Rule(src=ipset('192.168.1.2/31'), dst=ipset('192.168.0.0/16'), app='junos-ping', name='dbssh'),
        ],
        'web': [
            Rule(src=ipset('192.168.1.128'),
                 dst=ipset('10.0.0.0/8', '128.135.0.0/16', '192.168.0.0/16'),
                 app='web', name='admin'),
            Rule(src=ipset('128.135.0.0/16'), dst=ipset('10.1.10.0/24'), app='web', name='http'),
        ],
        'db': [
            Rule(src=ipset('192.168.1.128'),
                 dst=ipset('10.0.0.0/8', '128.135.0.0/16', '192.168.0.0/16'),
                 app='db', name='admin'),
            Rule(src=ipset('10.1.10.0/24'), dst=ipset('192.168.1.2/31'), app='db', name='db'),
        ],
        'junos-ssh': [
            Rule(src=ipset('192.168.1.128'),
                 dst=ipset('10.0.0.0/8', '128.135.0.0/16', '192.168.0.0/16'),
                 app='junos-ssh', name='admin'),
            Rule(src=ipset('192.168.1.2/31'), dst=ipset('192.168.0.0/16'), app='junos-ssh', name='dbssh'),
        ],
        '@@other': [
            Rule(src=ipset('192.168.1.128'),
                 dst=ipset('10.0.0.0/8', '128.135.0.0/16', '192.168.0.0/16'),
                 app='@@other', name='admin'),
        ],
    }
    [ruleset.sort() for ruleset in exp.itervalues()]
    eq_(res, exp)
예제 #26
0
def test_rules_from_to_empty():
    eq_(process.rules_from_to([], ipset('1.0.0.0/8'), ipset('2.0.0.0/8')),
        [])
예제 #27
0
def test_combine():
    address_spaces = {
        'ten': ipset('10.0.0.0/8'),
        'twenty': ipset('20.0.0.0/8'),
        'unmanaged': ipset('0.0.0.0/0') - ipset('10.0.0.0/8') - ipset('20.0.0.0/8'),
    }
    routes = {
        ('ten', 'ten'): ['fw1.ten'],
        ('ten', 'twenty'): ['fw1.ten', 'fw1.twenty'],
        ('ten', 'unmanaged'): ['fw1.ten'],
        ('twenty', 'ten'): ['fw1.ten', 'fw1.twenty'],
        ('twenty', 'twenty'): ['fw1.twenty'],
        ('twenty', 'unmanaged'): ['fw1.twenty'],
        ('unmanaged', 'ten'): ['fw1.ten'],
        ('unmanaged', 'twenty'): ['fw1.twenty'],
        ('unmanaged', 'unmanaged'): [],
    }
    sources = {
        'fw1.ten': RULES_10,
        'fw1.twenty': RULES_20,
    }
    res = process.combine(address_spaces, routes, sources)
    res['http'].sort()
    eq_(res, {
        'http': sorted([
            Rule(src=ipset('10.10.0.0/16'), dst=ipset('10.20.0.0/16', '30.20.0.0/16'),
                 app='http', name='10->10+10->30'), 
            Rule(src=ipset('20.10.0.0/16'), dst=ipset('20.20.0.0/16', '30.20.0.0/16'),
                 app='http', name='20->20+20->30'), 
            Rule(src=ipset('30.10.0.0/16'), dst=ipset('10.20.0.0/16', '20.20.0.0/16'),
                 app='http', name='30->10+30->20'),
            # note that only the intersection of these flows makes it through
            Rule(src=ipset('10.20.0.0/16'), dst=ipset('20.20.0.0/16'),
                 app='http', name='10->20'), 
            Rule(src=ipset('20.20.0.0/16'), dst=ipset('10.20.0.0/16'),
                 app='http', name='20->10'), 
        ]),
    })
예제 #28
0
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

from nose.tools import eq_
from fwunit.srx import parse
from fwunit.srx import process
from fwunit.common import ApplicationMap
from fwunit.test.util import ipset
from fwunit.types import Rule
from fwunit import IP

APP_MAP = ApplicationMap(dict(application_map={'junos-ssh': 'ssh'}))
ZONE_NETS = {
    'pvt': ipset('192.168.0.0/16'),
    'dmz': ipset('10.0.0.0/8'),
    'pub': ipset('128.135.0.00/16'),
}

def mkpol(**kwargs):
    kwargs.setdefault('action', 'permit')
    kwargs.setdefault('enabled', True)
    kwargs.setdefault('sequence', 1)
    pol = parse.Policy()
    for k, v in kwargs.iteritems():
        setattr(pol, k, v)
    return pol

def call_process_rules(app_map, policies, zone_nets):
    # calculate a few of the extra inputs
    policies_by_zone_pair = {}
예제 #29
0
def test_process_rules_any_app():
    # test basic functionality + the "any" app
    policies = [
        mkpol(name='dbssh',
              from_zone='pvt',
              to_zone='pvt',
              src_addrs=ipset('192.168.1.2/31'),
              dst_addrs=ipset('0.0.0.0/0'),
              applications=['junos-ssh', 'junos-ping'],
              sequence=1),
        mkpol(name='admin',
              from_zone='pvt',
              to_zone='pvt',
              src_addrs=ipset('192.168.1.128/32'),
              dst_addrs=ipset('0.0.0.0/0'),
              applications=['any'],
              sequence=2),
        mkpol(name='admin',
              from_zone='pvt',
              to_zone='dmz',
              src_addrs=ipset('192.168.1.128/32'),
              dst_addrs=ipset('0.0.0.0/0'),
              applications=['any']),
        mkpol(name='admin',
              from_zone='pvt',
              to_zone='pub',
              src_addrs=ipset('192.168.1.128/32'),
              dst_addrs=ipset('0.0.0.0/0'),
              applications=['any']),
        mkpol(name='http',
              from_zone='pub',
              to_zone='dmz',
              src_addrs=ipset('0.0.0.0/0'),
              dst_addrs=ipset('10.1.10.0/24'),
              applications=['web']),
        mkpol(name='db',
              from_zone='dmz',
              to_zone='pvt',
              src_addrs=ipset('10.1.10.0/24'),
              dst_addrs=ipset('192.168.1.2/31'),
              applications=['db']),
    ]
    res = call_process_rules(APP_MAP, policies, ZONE_NETS)
    exp = {
        'junos-ping': [
            Rule(src=ipset('192.168.1.128'),
                 dst=ipset('10.0.0.0/8', '128.135.0.0/16', '192.168.0.0/16'),
                 app='junos-ping',
                 name='admin'),
            Rule(src=ipset('192.168.1.2/31'),
                 dst=ipset('192.168.0.0/16'),
                 app='junos-ping',
                 name='dbssh'),
        ],
        'web': [
            Rule(src=ipset('192.168.1.128'),
                 dst=ipset('10.0.0.0/8', '128.135.0.0/16', '192.168.0.0/16'),
                 app='web',
                 name='admin'),
            Rule(src=ipset('128.135.0.0/16'),
                 dst=ipset('10.1.10.0/24'),
                 app='web',
                 name='http'),
        ],
        'db': [
            Rule(src=ipset('192.168.1.128'),
                 dst=ipset('10.0.0.0/8', '128.135.0.0/16', '192.168.0.0/16'),
                 app='db',
                 name='admin'),
            Rule(src=ipset('10.1.10.0/24'),
                 dst=ipset('192.168.1.2/31'),
                 app='db',
                 name='db'),
        ],
        'junos-ssh': [
            Rule(src=ipset('192.168.1.128'),
                 dst=ipset('10.0.0.0/8', '128.135.0.0/16', '192.168.0.0/16'),
                 app='junos-ssh',
                 name='admin'),
            Rule(src=ipset('192.168.1.2/31'),
                 dst=ipset('192.168.0.0/16'),
                 app='junos-ssh',
                 name='dbssh'),
        ],
        '@@other': [
            Rule(src=ipset('192.168.1.128'),
                 dst=ipset('10.0.0.0/8', '128.135.0.0/16', '192.168.0.0/16'),
                 app='@@other',
                 name='admin'),
        ],
    }
    [ruleset.sort() for ruleset in exp.itervalues()]
    eq_(res, exp)
예제 #30
0
def test_multiple_matches():
    lga_rules = {'app': [
        Rule(ipset('1.1.1.1'), ipset('2.0.0.0/8'), 'app', 'one'),
        Rule(ipset('1.1.1.2'), ipset('2.0.0.0/8'), 'app', 'two'),
        Rule(ipset('1.1.1.3'), ipset('2.0.0.0/8'), 'app', 'three'),
    ]}
    ord_rules = {'app': [
        Rule(ipset('1.0.0.0/8'), ipset('2.7.8.8'), 'app', 'eight'),
        Rule(ipset('1.0.0.0/8'), ipset('2.7.8.9'), 'app', 'nine'),
    ]}
    address_spaces = {
        'lga': ipset('1.0.0.0/8'),
        'ord': ipset('2.0.0.0/8'),
    }
    sources = {'fw1.ord': ord_rules, 'fw1.lga': lga_rules}
    with no_simplify():
        result = process.combine(address_spaces, routes, sources)
        eq_(sorted(result['app']), sorted([
            # takes the intersection of all rules:
            Rule(src=ipset('1.1.1.1'), dst=ipset('2.7.8.8'), app='app', name='eight+one'),
            Rule(src=ipset('1.1.1.1'), dst=ipset('2.7.8.9'), app='app', name='nine+one'),
            Rule(src=ipset('1.1.1.2'), dst=ipset('2.7.8.8'), app='app', name='eight+two'),
            Rule(src=ipset('1.1.1.2'), dst=ipset('2.7.8.9'), app='app', name='nine+two'),
            Rule(src=ipset('1.1.1.3'), dst=ipset('2.7.8.8'), app='app', name='eight+three'),
            Rule(src=ipset('1.1.1.3'), dst=ipset('2.7.8.9'), app='app', name='nine+three')
        ]))
def test_rules_from_to_empty():
    eq_(process.rules_from_to([], ipset('1.0.0.0/8'), ipset('2.0.0.0/8')), [])
def test_multiple_matches():
    lga_rules = {
        'app': [
            Rule(ipset('1.1.1.1'), ipset('2.0.0.0/8'), 'app', 'one'),
            Rule(ipset('1.1.1.2'), ipset('2.0.0.0/8'), 'app', 'two'),
            Rule(ipset('1.1.1.3'), ipset('2.0.0.0/8'), 'app', 'three'),
        ]
    }
    ord_rules = {
        'app': [
            Rule(ipset('1.0.0.0/8'), ipset('2.7.8.8'), 'app', 'eight'),
            Rule(ipset('1.0.0.0/8'), ipset('2.7.8.9'), 'app', 'nine'),
        ]
    }
    address_spaces = {
        'lga': ipset('1.0.0.0/8'),
        'ord': ipset('2.0.0.0/8'),
    }
    sources = {'fw1.ord': ord_rules, 'fw1.lga': lga_rules}
    with no_simplify():
        result = process.combine(address_spaces, routes, sources)
        eq_(
            sorted(result['app']),
            sorted([
                # takes the intersection of all rules:
                Rule(src=ipset('1.1.1.1'),
                     dst=ipset('2.7.8.8'),
                     app='app',
                     name='eight+one'),
                Rule(src=ipset('1.1.1.1'),
                     dst=ipset('2.7.8.9'),
                     app='app',
                     name='nine+one'),
                Rule(src=ipset('1.1.1.2'),
                     dst=ipset('2.7.8.8'),
                     app='app',
                     name='eight+two'),
                Rule(src=ipset('1.1.1.2'),
                     dst=ipset('2.7.8.9'),
                     app='app',
                     name='nine+two'),
                Rule(src=ipset('1.1.1.3'),
                     dst=ipset('2.7.8.8'),
                     app='app',
                     name='eight+three'),
                Rule(src=ipset('1.1.1.3'),
                     dst=ipset('2.7.8.9'),
                     app='app',
                     name='nine+three')
            ]))
예제 #33
0
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

import mock
import re

from nose.tools import eq_
from fwunit.types import Rule
from fwunit.analysis import sources
from fwunit.test.util import ipset
from fwunit import diff

TEN = ipset('10.10.0.0/16')
TEN_0 = ipset('10.10.0.0/17')
TEN_128 = ipset('10.10.128.0/17')
TWENTY = ipset('10.20.0.0/16')
TWENTY_0 = ipset('10.20.0.0/17')
TWENTY_128 = ipset('10.20.128.0/17')

LEFT = {
    'http': [
        Rule(src=ipset('0.0.0.0/0'), dst=ipset('10.20.19.0/24'), app='http', name='web access'),
        Rule(src=ipset('0.0.0.0/0'), dst=ipset('10.20.20.0/25'), app='http', name='stage web access'),
    ],
    'https': [
        Rule(src=ipset('0.0.0.0/0'), dst=ipset('10.20.19.0/24'), app='https', name='https web access'),
    ],
    'db': [
        Rule(src=ipset('10.20.19.0/24'), dst=ipset('10.20.30.15', '10.20.30.19'), app='db', name='db'),
        Rule(src=ipset('10.20.20.0/25'), dst=ipset('10.20.30.16'), app='db', name='stage db'),
예제 #34
0
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

from nose.tools import eq_
from fwunit.types import Rule
from fwunit.combine import process
from fwunit.test.util import ipset

RULES_10 = {
    'http': [
        # within this ip space
        Rule(src=ipset('10.10.0.0/16'), dst=ipset('10.20.0.0/16'), app='http', name='10->10'),
        # from and to "unmanaged" space
        Rule(src=ipset('30.10.0.0/16'), dst=ipset('10.20.0.0/16'), app='http', name='30->10'),
        Rule(src=ipset('10.10.0.0/16'), dst=ipset('30.20.0.0/16'), app='http', name='10->30'),
        # from and to the 20/8 space
        Rule(src=ipset('20.20.0.0/16', '20.30.0.0/16'),
             dst=ipset('10.20.0.0/16', '10.30.0.0/16'),
             app='http', name='20->10'),
        Rule(src=ipset('10.10.0.0/16', '10.20.0.0/16'),
             dst=ipset('20.10.0.0/16', '20.20.0.0/16'),
             app='http', name='10->20'),
    ],
}

RULES_20 = {
    'http': [
        # within this ip space
        Rule(src=ipset('20.10.0.0/16'), dst=ipset('20.20.0.0/16'), app='http', name='20->20'),
        # from and to "unmanaged" space
예제 #35
0
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

from fwunit.types import Rule
from fwunit.test.util import ipset

TEST_RULES = {
    'ping': [
        Rule(src=ipset('0.0.0.0/0') - ipset('10.0.0.0/8'),
             dst=ipset('10.1.0.0/16') - ipset('10.1.99.99'),
             app='ping', name='ping'),
    ],
    'puppet': [
        Rule(src=ipset('10.0.0.0/8'), dst=ipset('10.0.9.2'), app='puppet',
             name='puppet'),
    ],
    'ssh': [
        Rule(src=ipset('9.0.9.2'), dst=ipset('10.0.9.2'), app='ssh',
             name='admin'),
        Rule(src=ipset('10.0.0.0/8'), dst=ipset('0.0.0.0/0'), app='ssh',
             name='ssh--any+ssh-untrust'),
    ],
    '@@other': [
        Rule(src=ipset('1.2.3.4/32'), dst=ipset('0.0.0.0/0'), app='@@other',
             name='admin-access')
    ],
}
from fwunit import TestContext
from fwunit import types
from fwunit import scripts
from fwunit.test.util import ipset

FWUNIT_YAML = {
    'rules': {
        'type': 'anything',
        'output': 'rules.json',
    }
}
RULES = {
    'http': [
        # within this ip space
        types.Rule(src=ipset('10.10.0.0/16'),
                   dst=ipset('10.20.0.0/16'),
                   app='http',
                   name='10->10'),
        # from and to "unmanaged" space
        types.Rule(src=ipset('30.10.0.0/16'),
                   dst=ipset('10.20.0.0/16'),
                   app='http',
                   name='30->10'),
        types.Rule(src=ipset('10.10.0.0/16'),
                   dst=ipset('30.20.0.0/16'),
                   app='http',
                   name='10->30'),
        # from and to the 20/8 space
        types.Rule(src=ipset('20.20.0.0/16', '20.30.0.0/16'),
                   dst=ipset('10.20.0.0/16', '10.30.0.0/16'),
def test_combine():
    address_spaces = {
        'ten':
        ipset('10.0.0.0/8'),
        'twenty':
        ipset('20.0.0.0/8'),
        'unmanaged':
        ipset('0.0.0.0/0') - ipset('10.0.0.0/8') - ipset('20.0.0.0/8'),
    }
    routes = {
        ('ten', 'ten'): ['fw1.ten'],
        ('ten', 'twenty'): ['fw1.ten', 'fw1.twenty'],
        ('ten', 'unmanaged'): ['fw1.ten'],
        ('twenty', 'ten'): ['fw1.ten', 'fw1.twenty'],
        ('twenty', 'twenty'): ['fw1.twenty'],
        ('twenty', 'unmanaged'): ['fw1.twenty'],
        ('unmanaged', 'ten'): ['fw1.ten'],
        ('unmanaged', 'twenty'): ['fw1.twenty'],
        ('unmanaged', 'unmanaged'): [],
    }
    sources = {
        'fw1.ten': RULES_10,
        'fw1.twenty': RULES_20,
    }
    res = process.combine(address_spaces, routes, sources)
    res['http'].sort()
    eq_(
        res,
        {
            'http':
            sorted([
                Rule(src=ipset('10.10.0.0/16'),
                     dst=ipset('10.20.0.0/16', '30.20.0.0/16'),
                     app='http',
                     name='10->10+10->30'),
                Rule(src=ipset('20.10.0.0/16'),
                     dst=ipset('20.20.0.0/16', '30.20.0.0/16'),
                     app='http',
                     name='20->20+20->30'),
                Rule(src=ipset('30.10.0.0/16'),
                     dst=ipset('10.20.0.0/16', '20.20.0.0/16'),
                     app='http',
                     name='30->10+30->20'),
                # note that only the intersection of these flows makes it through
                Rule(src=ipset('10.20.0.0/16'),
                     dst=ipset('20.20.0.0/16'),
                     app='http',
                     name='10->20'),
                Rule(src=ipset('20.20.0.0/16'),
                     dst=ipset('10.20.0.0/16'),
                     app='http',
                     name='20->10'),
            ]),
        })
def test_other_app():
    ord_rules = {
        'ordonly': [
            Rule(ipset('1.1.0.0'), ipset('1.1.9.9'), 'ordonly', 'ordonly'),
        ],
        'inboth': [
            Rule(ipset('1.1.8.8'), ipset('1.1.9.9'), 'inboth', 'inboth_ord'),
        ],
        '@@other': [
            Rule(ipset('1.1.0.0'), ipset('1.1.9.9'), '@@other', 'ordother'),
        ],
    }
    lga_rules = {
        'lgaonly': [
            Rule(ipset('65.1.0.0'), ipset('65.1.9.9'), 'lgaonly', 'lgaonly'),
        ],
        'inboth': [
            Rule(ipset('65.1.8.8'), ipset('65.1.9.9'), 'inboth', 'inboth_lga'),
        ],
        '@@other': [
            Rule(ipset('65.1.0.0'), ipset('65.1.9.9'), '@@other', 'lgaother'),
        ],
    }
    address_spaces = {
        'ord': ipset('0.0.0.0/2'),
        'lga': ipset('64.0.0.0/2'),
    }
    sources = {'fw1.ord': ord_rules, 'fw1.lga': lga_rules}
    with no_simplify():
        result = process.combine(address_spaces, routes, sources)
        for apprules in result.itervalues():
            apprules.sort()
        eq_(
            result, {
                'ordonly':
                sorted([
                    Rule(ipset('1.1.0.0'), ipset('1.1.9.9'), 'ordonly',
                         'ordonly'),
                    Rule(ipset('65.1.0.0'), ipset('65.1.9.9'), 'ordonly',
                         'lgaother'),
                ]),
                'lgaonly':
                sorted([
                    Rule(ipset('65.1.0.0'), ipset('65.1.9.9'), 'lgaonly',
                         'lgaonly'),
                    Rule(ipset('1.1.0.0'), ipset('1.1.9.9'), 'lgaonly',
                         'ordother'),
                ]),
                'inboth':
                sorted([
                    Rule(ipset('1.1.8.8'), ipset('1.1.9.9'), 'inboth',
                         'inboth_ord'),
                    Rule(ipset('65.1.8.8'), ipset('65.1.9.9'), 'inboth',
                         'inboth_lga'),
                ]),
                '@@other':
                sorted([
                    Rule(ipset('1.1.0.0'), ipset('1.1.9.9'), '@@other',
                         'ordother'),
                    Rule(ipset('65.1.0.0'), ipset('65.1.9.9'), '@@other',
                         'lgaother'),
                ]),
            })
def test_sourcesFor():
    eq_(rules.sourcesFor('10.1.1.1', 'ssh'), ipset('10.0.0.0/8'))
예제 #40
0
    'fw.ord': {'output': 'fw.ord.json'},
    'fw.lax': {'output': 'fw.lax.json'},
    'fw.nyc': {'output': 'fw.nyc.json'},
    'enterprise': {
        'address_spaces': {
            'ord': '100.0.0.0/8',
            'lax': '200.0.0.0/8',
            'nyc': '240.0.0.0/8',
        },
        'routes': {
        },
    },
}

exp_address_spaces = {
    'ord': ipset('100.0.0.0/8'),
    'lax': ipset('200.0.0.0/8'),
    'nyc': ipset('240.0.0.0/8'),
    'unmanaged': ipset('0.0.0.0/0')
        - ipset('100.0.0.0/8') - ipset('200.0.0.0/8') - ipset('240.0.0.0/8'),
}

empty_exp_routes = {
    (s, d): set()
    for s in exp_address_spaces
    for d in exp_address_spaces
}

def exp_sources(*srcs):
    return {s: "rules for " + s for s in srcs}
예제 #41
0
def test_other_app():
    ord_rules = {
        'ordonly': [
            Rule(ipset('1.1.0.0'), ipset('1.1.9.9'), 'ordonly', 'ordonly'),
        ],
        'inboth': [
            Rule(ipset('1.1.8.8'), ipset('1.1.9.9'), 'inboth', 'inboth_ord'),
        ],
        '@@other': [
            Rule(ipset('1.1.0.0'), ipset('1.1.9.9'), '@@other', 'ordother'),
        ],
    }
    lga_rules = {
        'lgaonly': [
            Rule(ipset('65.1.0.0'), ipset('65.1.9.9'), 'lgaonly', 'lgaonly'),
        ],
        'inboth': [
            Rule(ipset('65.1.8.8'), ipset('65.1.9.9'), 'inboth', 'inboth_lga'),
        ],
        '@@other': [
            Rule(ipset('65.1.0.0'), ipset('65.1.9.9'), '@@other', 'lgaother'),
        ],
    }
    address_spaces = {
        'ord': ipset('0.0.0.0/2'),
        'lga': ipset('64.0.0.0/2'),
    }
    sources = {'fw1.ord': ord_rules, 'fw1.lga': lga_rules}
    with no_simplify():
        result = process.combine(address_spaces, routes, sources)
        for apprules in result.itervalues():
            apprules.sort()
        eq_(result, {
            'ordonly': sorted([
                Rule(ipset('1.1.0.0'), ipset('1.1.9.9'), 'ordonly', 'ordonly'),
                Rule(ipset('65.1.0.0'), ipset('65.1.9.9'), 'ordonly', 'lgaother'),
            ]),
            'lgaonly': sorted([
                Rule(ipset('65.1.0.0'), ipset('65.1.9.9'), 'lgaonly', 'lgaonly'),
                Rule(ipset('1.1.0.0'), ipset('1.1.9.9'), 'lgaonly', 'ordother'),
            ]),
            'inboth': sorted([
                Rule(ipset('1.1.8.8'), ipset('1.1.9.9'), 'inboth', 'inboth_ord'),
                Rule(ipset('65.1.8.8'), ipset('65.1.9.9'), 'inboth', 'inboth_lga'),
            ]),
            '@@other': sorted([
                Rule(ipset('1.1.0.0'), ipset('1.1.9.9'), '@@other', 'ordother'),
                Rule(ipset('65.1.0.0'), ipset('65.1.9.9'), '@@other', 'lgaother'),
            ]),
        })