From 8a04d1709df376d3e4c634e80ff04298274a2f00 Mon Sep 17 00:00:00 2001 From: Lars Kiesow Date: Thu, 13 Apr 2023 23:58:38 +0200 Subject: [PATCH] DETERRERS command line client --- MANIFEST.in | 1 + README.md | 77 ++++++++++++++++++++++++++++- deterrerscli/__main__.py | 102 +++++++++++++++++++++++++++++++++++++++ requirements.txt | 3 ++ setup.py | 27 +++++++++++ 5 files changed, 208 insertions(+), 2 deletions(-) create mode 100644 MANIFEST.in create mode 100644 deterrerscli/__main__.py create mode 100644 requirements.txt create mode 100644 setup.py diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000..a62182e --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1 @@ +include LICENSE README.md requirements.txt diff --git a/README.md b/README.md index ae223db..a92eca4 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,75 @@ -# deterrers-cli -Command line client for DETERRERS +# Command line client for DETERRERS + +A command line client making it easy to interact with the DETERRERS perimeter +firewall portal to registr and configuration IP addresses and firewall +profiles. + +**Warning:** The API of DETERRERS used by this tool is still experimental and somewhat fragile. +Most notably, this often leads to unexpected errors returned by the API. + + +## Installation + +Use pip to install the latest version: + +``` +pip install deterrers-cli +``` + +## Configuration + +To configure the client, create a file `~/.deterrers.yml` with the following content: + +```yaml +url: https://deterrers.example.com +token: +``` + +## Usane + +Use the context based help to get information about available commands: + +``` +❯ deterrers-cli --help +Usage: python -m deterrerscli [OPTIONS] COMMAND [ARGS]... + +Options: + --help Show this message and exit. + +Commands: + action Activate firewall profile or block IP address in perimeter... + add Add IP address to DETERRERS. + delete Delete IP address from DETERRERS. + get Get information about an IP address in DETERRERS. + hosts List all IPs added to DETERRERS. + update Update IP address in DETERRERS. +``` + +Help about adding new IP addresses: + +``` +❯ deterrers-cli add --help +Usage: python -m deterrerscli add [OPTIONS] IPV4 + + Add IP address to DETERRERS. + +Options: + -a, --admin TEXT [required] + --help Show this message and exit. +``` + +## Example + +```sh +# Delete IP 192.0.0.1 from DETERRERS +❯ deterrers-cli delete 192.0.0.1 + +# Add IP 192.0.0.1 with group `virtUOS` as admins +❯ deterrers-cli add --admin virtUOS 192.0.0.1 + +# Set firewall profile `SSH` +❯ deterrers-cli update --profile ssh 192.0.0.1 + +# Activate firewall profile +❯ deterrers-cli action register 192.0.0.1 +``` diff --git a/deterrerscli/__main__.py b/deterrerscli/__main__.py new file mode 100644 index 0000000..b671177 --- /dev/null +++ b/deterrerscli/__main__.py @@ -0,0 +1,102 @@ +import click +import deterrersapi +import pathlib +import json +import yaml + +deterrers = None + +profiles = click.Choice( + ('', 'HTTP', 'SSH', 'HTTP+SSH', 'Multipurpose'), + case_sensitive=False) +host_firewalls = click.Choice( + ('', 'UFW', 'FirewallD', 'nftables'), + case_sensitive=False) + + +def print_format(data, format: str): + if format == 'yaml': + print(yaml.dump(data)) + else: + print(json.dumps(data, indent=4)) + + +@click.group() +def cli(): + global deterrers + with open(pathlib.Path().home() / '.deterrers.yml', 'r') as f: + config = yaml.safe_load(f) + deterrers = deterrersapi.Deterrers(config['url'], config['token']) + + +@cli.command() +@click.option('--format', default='json', help='Output format (json or yaml)') +def hosts(format): + '''List all IPs added to DETERRERS. + ''' + data = deterrers.hosts() + print_format(data, format) + + +@cli.command() +@click.option('--format', default='json', help='Output format (json or yaml)') +@click.argument('ipv4') +def get(format, ipv4): + '''Get information about an IP address in DETERRERS. + ''' + data = deterrers.get(ipv4) + print_format(data, format) + + +@cli.command() +@click.argument('ipv4') +def delete(ipv4): + '''Delete IP address from DETERRERS. + ''' + deterrers.delete(ipv4) + + +@cli.command() +@click.option('--admin', '-a', multiple=True, required=True) +@click.argument('ipv4') +def add(ipv4, admin): + '''Add IP address to DETERRERS. + ''' + deterrers.add(ipv4, admin) + + +@cli.command() +@click.option('--profile', '-p', default='', type=profiles) +@click.option('--firewall', '-f', default='', type=host_firewalls) +@click.argument('ipv4') +def update(ipv4, profile, firewall): + '''Update IP address in DETERRERS. + ''' + deterrers.update(ipv4, profile, firewall) + + +@cli.group() +def action(): + '''Activate firewall profile or block IP address in perimeter firewall. + ''' + pass + + +@action.command() +@click.argument('ipv4') +def register(ipv4): + '''Activate profile in perimeter firewall. + ''' + deterrers.action(ipv4, 'register') + + +@action.command() +@click.argument('ipv4') +def block(ipv4): + '''Block IP address perimeter firewall. + ''' + deterrers.action(ipv4, 'block') + + +if __name__ == '__main__': + cli() diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..bf3a284 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +deterrers-api +PyYAML +Click diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..7c974bf --- /dev/null +++ b/setup.py @@ -0,0 +1,27 @@ +from setuptools import setup +import os + + +def read(filename): + path = os.path.abspath(os.path.dirname(__file__)) + with open(os.path.join(path, filename), encoding='utf-8') as f: + return f.read() + + +setup( + name='deterrers-cli', + version='0.2', + description='Command line client for DETERRERS', + url='https://github.com/virtUOS/proteuscmd', + author='Lars Kiesow', + author_email='lkiesow@uos.de', + license='MIT', + packages=['deterrerscli'], + license_files=('LICENSE'), + include_package_data=True, + install_requires=read('requirements.txt').split(), + long_description=read('README.md'), + long_description_content_type='text/markdown', + entry_points={ + 'console_scripts': ['deterrers-cli = deterrerscli.__main__:cli'], + })