Skip to content

Commit

Permalink
Merge pull request #33 from stratosphereips/develop
Browse files Browse the repository at this point in the history
Merging:
- Refactor CLI: aivpn.py
- Refactor and bugfixes on Slips module
- Refactor Comms Receiving module
- Fulfill community standards (contributions guidelines, templates,etc)
  • Loading branch information
verovaleros authored Nov 14, 2022
2 parents 6889a1b + ad4121b commit 13c8259
Show file tree
Hide file tree
Showing 10 changed files with 642 additions and 491 deletions.
17 changes: 9 additions & 8 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,6 @@

All contributions are welcomed, thank you for taking the time to contribute to this project!

## How can you contribute?

* Report bugs
* Suggest features and ideas
* Pull requests with a solved GitHub issue and new feature
* Pull request with a new content.

## Persistent Git Branches

The following git branches permanent in the Slips repository:
Expand All @@ -24,7 +17,7 @@ to follow when contributing:

- bugfix-<>: pull request branch, contains one bugfix,
- docs-<>: pull request branch, contains documentation work,
- feat-<>: pull request branch, contains a new feature,
- feat-<>: pull request branch, contains a new feature,
- refactor-<>: pull request branch, contains code refactoring,

## What branch should you base your contribution?
Expand All @@ -41,3 +34,11 @@ Pull Requests:
- If you have developed multiple features and/or bugfixes, create separate
branches for each one of them, and request merges for each branch;
- The cleaner you code/change/changeset is, the faster it will be merged.

## How can you contribute?

* Report bugs
* Suggest features and ideas
* Pull requests with a solved GitHub issue and new feature
* Pull request with a new content.

182 changes: 93 additions & 89 deletions aivpn.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,16 @@

import re
import sys
import json
import datetime
import argparse
import logging
import configparser
from common.database import *


def manage_info(REDIS_CLIENT,profile_name):
"""
Retrieve information about an AI VPN profile_name
"""
profile_information = {}
try:
logging.debug('Manage info: {profile_name}')
vpn_type = get_profile_vpn_type(profile_name,REDIS_CLIENT)
Expand Down Expand Up @@ -59,156 +57,155 @@ def manage_info(REDIS_CLIENT,profile_name):
except Exception as err:
print(f'Exception in manage_info: {err}')

def manage_expire(REDIS_CLIENT,profile_name):
def manage_expire(REDIS_CLIENT, profile_name):
"""
Add a profile to the force expire queue to deprovision
"""
try:
logging.debug(f'Manage expire: {profile_name}')
if exists_active_profile(profile_name,REDIS_CLIENT):
status = add_profile_to_force_expire(REDIS_CLIENT,profile_name)
if exists_active_profile(profile_name, REDIS_CLIENT):
status = add_profile_to_force_expire(REDIS_CLIENT, profile_name)
redis_client.publish('services_status', 'MOD_CLI:FORCE_EXPIRE')
print(f"[+] Forced expiration on profile '{profile_name}' was '{status}'")
else:
print(f'[+] Profile already expired and processed')
except Exception as err:
print(f'Exception in manage_expire: {err}')

def manage_extend(REDIS_CLIENT,profile_name):
"""
"""

def manage_extend(profile_name):
try:
logging.debug(f'Manage extend: {profile_name}')
pass
except Exception as err:
print(f'Exception in manage_extend: {err}')

def manage_whois(REDIS_CLIENT,profile_name):

def manage_whois(REDIS_CLIENT, profile_name):
"""
Retrieve identity associated with a profile
"""
try:
identity=get_profile_name_address(profile_name,REDIS_CLIENT)
identity = get_profile_name_address(profile_name, REDIS_CLIENT)
logging.debug(f'Manage whois: {profile_name}')
print(f"[+] User identity for {profile_name} is {identity}")
except Exception as err:
print(f'Exception in manage_whois: {err}')


def validate_identity(identity):
"""
Verify the provided identity matches an email or telegram ID
"""
try:
email_regex = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b'
telegram_regex = r'\b[0-9]{8,}\b'
if(re.fullmatch(email_regex, identity)):
msg_type = "email"
elif (re.fullmatch(telegram_regex, identity)):
msg_type = "telegram"
if re.fullmatch(email_regex, identity):
return "email"
elif re.fullmatch(telegram_regex, identity):
return "telegram"
else:
print(f"Identity must be a valid format (email or telegram ID): {identity}")
logging.debug(f"Identity must be a valid format (email or telegram ID): {identity}")
return False
return msg_type
except Exception as err:
print(f'Exception in validate_identity: {err}')


def get_validated_data(identity):
try:
valid_identity = validate_identity(identity)
return {
"msg_id": 1,
"msg_type": valid_identity,
"msg_addr ": identity,
"msg_request": ["openvpn", "wireguard", "novpn"]
}

except Exception as err:
logging.debug(f"Identity {identity} is not valid")
return f'Exception occurred in data validation for provision {err}'


def provision_openvpn(REDIS_CLIENT, identity):
"""
Trigger the provisioning of a new OpenVPN profile for a client
"""
try:
logging.debug(f'Provision OpenVPN: {identity}')

msg_id = 1
msg_request = "openvpn"
msg_addr = identity
msg_type = validate_identity(identity)

if msg_id and msg_request and msg_addr and msg_type:
# Add to privisioning queue
logging.debug(f"Adding item to provisioning queue. Msg ID: {msg_id}, msg_type: {msg_type}, msg_addr: {msg_addr}, msg_request: {msg_request}")
status = add_item_provisioning_queue(REDIS_CLIENT,msg_id,msg_type,msg_addr,msg_request)
redis_client.publish('services_status', 'MOD_CLI:NEW_REQUEST')
print(f"Provisioning triggered: {status}. Number of items in the queue: {list_items_provisioning_queue(REDIS_CLIENT)}")
else:
print('Provisioning process failed, try again')
identity_valid_data = get_validated_data(identity)
logging.debug(f'Provision OpenVPN: {identity}')
if identity_valid_data["msg_request"][0] and identity_valid_data["msg_type"]:
# Add to provisioning queue
status = add_item_provisioning_queue(REDIS_CLIENT, identity_valid_data["msg_id"], identity_valid_data["msg_type"],
identity_valid_data["msg_addr"], identity_valid_data["msg_request"][0])
redis_client.publish('services_status', 'MOD_COMM_RECV:NEW_REQUEST')
print(
f"Provisioning triggered: {status}. Number of items in the queue: {list_items_provisioning_queue(REDIS_CLIENT)}")
else:
print('Provisioning process failed, try again')

except Exception as err:
print(f'Exception in provision_new_openvpn: {err}')

def provision_wireguard(REDIS_CLIENT,identity):
def provision_wireguard(REDIS_CLIENT, identity):
"""
Trigger the provisioning of a new Wireguard profile for a client
"""
try:
logging.debug(f'Provision Wireguard: {identity}')
msg_id = 1
msg_request = "wireguard"
msg_addr = identity
msg_type = validate_identity(identity)

if msg_id and msg_request and msg_addr and msg_type:
# Add to privisioning queue
logging.debug(f"Adding item to provisioning queue. Msg ID: {msg_id}, msg_type: {msg_type}, msg_addr: {msg_addr}, msg_request: {msg_request}")
status = add_item_provisioning_queue(REDIS_CLIENT,msg_id,msg_type,msg_addr,msg_request)
redis_client.publish('services_status', 'MOD_COMM_RECV:NEW_REQUEST')
print(f"Provisioning triggered: {status}. Number of items in the queue: {list_items_provisioning_queue(REDIS_CLIENT)}")
else:
print('Provisioning process failed, try again')
except Exception as err:
print(f'Exception in provision_new_wireguard: {err}')
valid_data = get_validated_data(identity)
logging.debug(f'Provision Wireguard: {identity}')
if valid_data["msg_request"][1] and valid_data["msg_type"]:
# Add to provisioning queue
status = add_item_provisioning_queue(REDIS_CLIENT, valid_data["msg_id"], valid_data["msg_type"],
valid_data["msg_addr"], valid_data["msg_request"][1])
redis_client.publish('services_status', 'MOD_COMM_RECV:NEW_REQUEST')
print(
f"Provisioning triggered: {status}. Number of items in the queue: {list_items_provisioning_queue(REDIS_CLIENT)}")
else:
print('Provisioning process failed, try again')


def provision_novpn(REDIS_CLIENT,identity):
def provision_novpn(REDIS_CLIENT, identity):
"""
Trigger the provisioning of a new not encrypted vpn profile for a client
"""
try:
logging.debug(f'Provision No VPN: {identity}')
msg_id = 1
msg_request = "novpn"
msg_addr = identity
msg_type = validate_identity(identity)

if msg_id and msg_request and msg_addr and msg_type:
# Add to privisioning queue
logging.debug(f"Adding item to provisioning queue. Msg ID: {msg_id}, msg_type: {msg_type}, msg_addr: {msg_addr}, msg_request: {msg_request}")
status = add_item_provisioning_queue(REDIS_CLIENT,msg_id,msg_type,msg_addr,msg_request)
redis_client.publish('services_status', 'MOD_COMM_RECV:NEW_REQUEST')
print(f"Provisioning triggered: {status}. Number of items in the queue: {list_items_provisioning_queue(REDIS_CLIENT)}")
else:
print('Provisioning process failed, try again')
except Exception as err:
print(f'Exception in provision_new_novpn: {err}')
valid_data = get_validated_data(identity)
logging.debug(f'Provision No VPN: {identity}')
if valid_data["msg_request"][2] and valid_data["msg_type"]:
status = add_item_provisioning_queue(REDIS_CLIENT, valid_data["msg_id"], valid_data["msg_type"],
valid_data["msg_addr"], valid_data["msg_request"][2])
redis_client.publish('services_status', 'MOD_COMM_RECV:NEW_REQUEST')
print(
f"Provisioning triggered: {status}. Number of items in the queue: {list_items_provisioning_queue(REDIS_CLIENT)}")
else:
print('Provisioning process failed, try again')

def audit_active_profiles(REDIS_CLIENT,action):

def audit_active_profiles(REDIS_CLIENT, action):
"""
Retrieve a list of active VPN profiles
"""
try:
logging.debug('Audit active profiles')
active_profiles = get_active_profiles_keys(REDIS_CLIENT)
print(f"[+] Number of active profiles: {len(active_profiles)}")
if len(active_profiles)>0:
if len(active_profiles) > 0:
for profile in active_profiles:
print(f" [-] {profile}")
except Exception as err:
print(f'Exception in audit_active_profiles: {err}')

def audit_expired_profiles(REDIS_CLIENT,action):

def audit_expired_profiles(REDIS_CLIENT, action):
"""
Retrieve a list of expired profiles
"""
try:
logging.debug('Audit expired profiles')
expired_profiles = get_expired_profiles_keys(REDIS_CLIENT)
print(f"[+] Number of expired profiles: {len(expired_profiles)}")
if len(expired_profiles)>0:
if len(expired_profiles) > 0:
for profile in expired_profiles:
print(f" [-] {profile}")
except Exception as err:
print(f'Exception in audit_expired_profiles: {err}')

def audit_queued_profiles(REDIS_CLIENT,action):

def audit_queued_profiles(REDIS_CLIENT, action):
"""
Retrieve a list of profiles in provisioning queue
"""
Expand All @@ -228,8 +225,8 @@ def audit_queued_profiles(REDIS_CLIENT,action):
MOD_CHANNELS = json.loads(config['REDIS']['REDIS_MODULES'])
LOG_FILE = config['LOGS']['LOG_CLI']

parser = argparse.ArgumentParser(description = "AI VPN Command Line Tool")
parser.add_argument( "-v", "--verbose", help="increase output verbosity", action="store_true")
parser = argparse.ArgumentParser(description="AI VPN Command Line Tool")
parser.add_argument("-v", "--verbose", help="increase output verbosity", action="store_true")
parser.add_argument('--redis', help="AI VPN redis module IP address", required=True)

# Configure commands
Expand All @@ -239,28 +236,35 @@ def audit_queued_profiles(REDIS_CLIENT,action):
audit = subparser.add_parser('audit', help=f'Audit AI VPN activities')

# manage actions
manage.add_argument('--info', help='retrieve information of a profile', type=str, required=False, metavar='<profile_name>')
manage.add_argument('--info', help='retrieve information of a profile', type=str, required=False,
metavar='<profile_name>')
manage.add_argument('--expire', help='expire a profile', type=str, required=False, metavar='<profile_name>')
manage.add_argument('--extend', help='extend the expiration of a profile (add default expiration on top of current date)', type=str, required=False, metavar='<profile_name>')
manage.add_argument('--whois', help='retrieve identity associated with a profile', type=str, required=False, metavar='<profile_name>')
manage.add_argument('--extend',
help='extend the expiration of a profile (add default expiration on top of current date)',
type=str, required=False, metavar='<profile_name>')
manage.add_argument('--whois', help='retrieve identity associated with a profile', type=str, required=False,
metavar='<profile_name>')

# provision actions
provision.add_argument('--openvpn', help='create a new openvpn profile for a given identity', type=str, required=False, metavar='<user email | user telegram>')
provision.add_argument('--wireguard', help='create a new wireguard profile for a given identity', type=str, required=False, metavar='<user email | user telegram>')
provision.add_argument('--novpn', help='create a new novpn profile for a given identity', type=str, required=False, metavar='<user email | user telegram>')
provision.add_argument('--openvpn', help='create a new openvpn profile for a given identity', type=str,
required=False, metavar='<user email | user telegram>')
provision.add_argument('--wireguard', help='create a new wireguard profile for a given identity', type=str,
required=False, metavar='<user email | user telegram>')
provision.add_argument('--novpn', help='create a new novpn profile for a given identity', type=str, required=False,
metavar='<user email | user telegram>')

# audit actions
audit.add_argument('--profiles', choices=['active','expired','queued'], help='Audit profiles by type')
audit.add_argument('--profiles', choices=['active', 'expired', 'queued'], help='Audit profiles by type')

args = parser.parse_args()

# Setup logging
if args.verbose:
log_level=logging.DEBUG
log_level = logging.DEBUG
else:
log_level=logging.INFO
log_level = logging.INFO

logging.basicConfig(filename=LOG_FILE, level=log_level,format='%(asctime)s, AIVPN_CLI, %(message)s')
logging.basicConfig(filename=LOG_FILE, level=log_level, format='%(asctime)s, AIVPN_CLI, %(message)s')

# parsing commands
if args.command == 'manage':
Expand Down
3 changes: 3 additions & 0 deletions docker-compose_EXAMPLE.yml
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ services:
volumes:
- ./logs:/logs/
- ./data:/data/
- ./mod_slips/slips_configuration.conf:/StratosphereLinuxIPS/aivpn_slips.conf
- ./mod_slips/slips_whitelist.conf:/StratosphereLinuxIPS/aivpn_whitelist.conf
- ./mod_slips/slips_slack_bot_token_secret:/StratosphereLinuxIPS/modules/exporting_alerts/slack_bot_token_secret
- ./config:/code/config/:ro
- ./common:/code/common/:ro
deploy:
Expand Down
Loading

0 comments on commit 13c8259

Please sign in to comment.