Пример #1
0
def grant_access(address, port):
    """Grant TCP access to address and port via UFW

    :side effect: calls ufw.grant_access
    :return: None
    """
    log('granting access: {}:{}'.format(address, port), level='DEBUG')
    ufw.grant_access(address, port=str(port), proto='tcp',
                     index=FIRST)
Пример #2
0
    def test_grant_access_with_index(self, popen, log, is_enabled):
        is_enabled.return_value = True
        p = mock.Mock()
        p.configure_mock(**{'communicate.return_value': ('stdout', 'stderr'),
                            'returncode': 0})
        popen.return_value = p

        ufw.grant_access('127.0.0.1', dst='127.0.0.1', port='80', index=1)
        popen.assert_any_call(['ufw', 'insert', '1', 'allow', 'from',
                               '127.0.0.1', 'to', '127.0.0.1', 'port', '80'],
                              stdout=subprocess.PIPE)
        log.assert_any_call(('ufw allow: ufw insert 1 allow from 127.0.0.1 '
                             'to 127.0.0.1 port 80'), level='DEBUG')
        log.assert_any_call('stdout', level='INFO')
Пример #3
0
def configure_firewall():
    '''Configure firewall rules using ufw.

    This is primarily to block access to the replication and JMX ports,
    as juju's default port access controls are not strict enough and
    allow access to the entire environment.
    '''
    config = hookenv.config()
    ufw.enable(soft_fail=True)

    # Enable SSH from anywhere, relying on Juju and external firewalls
    # to control access.
    ufw.service('ssh', 'open')
    ufw.service('nrpe', 'open')  # Also NRPE for nagios checks.

    # Clients need client access. These protocols are configured to
    # require authentication.
    client_keys = ['native_transport_port', 'rpc_port']
    client_ports = [config[key] for key in client_keys]

    # Peers need replication access. This protocols does not
    # require authentication, so firewall it from other nodes.
    peer_ports = [config['storage_port'], config['ssl_storage_port']]

    # Enable client access from anywhere. Juju and external firewalls
    # can still restrict this further of course (ie. 'juju expose').
    for key in client_keys:
        if config.changed(key) and config.previous(key) is not None:
            # First close old ports. We use this order in the unlikely case
            # someone is trying to swap the native and Thrift ports.
            ufw.service(config.previous(key), 'close')
    for port in client_ports:
        # Then open or close the configured ports.
        ufw.service(port, 'open')

    desired_rules = set()  # ufw.grant_access/remove_access commands.

    # Rules for peers
    for relinfo in hookenv.relations_of_type('cluster'):
        if relinfo['private-address']:
            for port in peer_ports:
                desired_rules.add((relinfo['private-address'], 'any', port))
    # Rules for admin connections. We allow database-admin relations access
    # to the cluster communication ports so that tools like sstableloader
    # can run.
    for relinfo in hookenv.relations_of_type('database-admin'):
        if relinfo['private-address']:
            for port in peer_ports:
                desired_rules.add((relinfo['private-address'], 'any', port))

    previous_rules = set(tuple(rule) for rule in config.get('ufw_rules', []))

    # Close any rules previously opened that are no longer desired.
    for rule in sorted(list(previous_rules - desired_rules)):
        ufw.revoke_access(*rule)

    # Open all the desired rules.
    for rule in sorted(list(desired_rules)):
        ufw.grant_access(*rule)

    # Store our rules for next time. Note that this is inherantly racy -
    # this value is only persisted if the hook exits cleanly. If the
    # hook fails, then someone changes port configuration or IP
    # addresses change, then the failed hook retried, we can lose track
    # of previously granted rules and they will never be revoked. It is
    # impossible to remove this race entirely, so we stick with this
    # simple approach.
    config['ufw_rules'] = list(desired_rules)  # A list because JSON.
Пример #4
0
def configure_firewall():
    '''Configure firewall rules using ufw.

    This is primarily to block access to the replication and JMX ports,
    as juju's default port access controls are not strict enough and
    allow access to the entire environment.
    '''
    config = hookenv.config()
    ufw.enable(soft_fail=True)

    # Enable SSH from anywhere, relying on Juju and external firewalls
    # to control access.
    ufw.service('ssh', 'open')
    ufw.service('nrpe', 'open')  # Also NRPE for nagios checks.

    # Clients need client access. These protocols are configured to
    # require authentication.
    client_keys = ['native_transport_port', 'rpc_port']
    client_ports = [config[key] for key in client_keys]

    # Peers need replication access. This protocols does not
    # require authentication, so firewall it from other nodes.
    peer_ports = [config['storage_port'], config['ssl_storage_port']]

    # Enable client access from anywhere. Juju and external firewalls
    # can still restrict this further of course (ie. 'juju expose').
    for key in client_keys:
        if config.changed(key) and config.previous(key) is not None:
            # First close old ports. We use this order in the unlikely case
            # someone is trying to swap the native and Thrift ports.
            ufw.service(config.previous(key), 'close')
    for port in client_ports:
        # Then open or close the configured ports.
        ufw.service(port, 'open')

    desired_rules = set()  # ufw.grant_access/remove_access commands.

    # Rules for peers
    for relinfo in hookenv.relations_of_type('cluster'):
        if relinfo['private-address']:
            for port in peer_ports:
                desired_rules.add((relinfo['private-address'], 'any', port))
    # Rules for admin connections. We allow database-admin relations access
    # to the cluster communication ports so that tools like sstableloader
    # can run.
    for relinfo in hookenv.relations_of_type('database-admin'):
        if relinfo['private-address']:
            for port in peer_ports:
                desired_rules.add((relinfo['private-address'], 'any', port))

    previous_rules = set(tuple(rule) for rule in config.get('ufw_rules', []))

    # Close any rules previously opened that are no longer desired.
    for rule in sorted(list(previous_rules - desired_rules)):
        ufw.revoke_access(*rule)

    # Open all the desired rules.
    for rule in sorted(list(desired_rules)):
        ufw.grant_access(*rule)

    # Store our rules for next time. Note that this is inherantly racy -
    # this value is only persisted if the hook exits cleanly. If the
    # hook fails, then someone changes port configuration or IP
    # addresses change, then the failed hook retried, we can lose track
    # of previously granted rules and they will never be revoked. It is
    # impossible to remove this race entirely, so we stick with this
    # simple approach.
    config['ufw_rules'] = list(desired_rules)  # A list because JSON.