ok

Mini Shell

Direktori : /opt/imunify360/venv/share/imunify360/scripts/
Upload File :
Current File : //opt/imunify360/venv/share/imunify360/scripts/remote_iplist.py

#!/opt/imunify360/venv/bin/python3
"""
Usage: /opt/imunify360/venv/bin/python3 remote_iplist.py
"""

import argparse
import asyncio
import json
import sys
import pickle
from logging import getLogger
from pathlib import Path
from typing import Optional

from defence360agent.contracts.config import Model
from defence360agent.internals import logger as lg
from defence360agent.model import instance, tls_check
from defence360agent.utils.benchmark import Benchmark
from im360.contracts.config import IPSET_LISTS_PATH
from im360.files import WHITELISTS, Index
from im360.internals.core import ip_versions
from im360.plugins.resident.remote_iplist import RemoteIPListPlugin

logger = getLogger("remote-iplist")
REMOTE_IPLIST_RESPONSE = Path("/var/imunify360/.remote_iplist.response")


class RemoteIPListResponse:
    def __init__(self, sync_point, delay, responses):
        self.sync_point = sync_point
        self.delay = delay
        self.responses = responses

    def unpack(self):
        return self.sync_point, self.delay, self.responses


def save_state(rips: RemoteIPListResponse):
    """Save RealProtector state."""
    pickle.dump(rips, REMOTE_IPLIST_RESPONSE.open("wb"))


def restore_state() -> Optional[RemoteIPListResponse]:
    """Restore RealProtector state."""
    if REMOTE_IPLIST_RESPONSE.exists():
        try:
            return pickle.load(REMOTE_IPLIST_RESPONSE.open("rb"))
        except Exception as e:
            logger.error("Failed to restore remote-ipslist response: %s", e)
            return None
    return None


def parse_args() -> argparse.Namespace:
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "-j",
        "--json",
        action="store_true",
        help="output more information in JSON format",
    )
    parser.add_argument(
        "-s",
        "--sync-request",
        action="store_true",
        help=(
            "send sync request to the server and save the response to the file"
        ),
    )
    return parser.parse_args()


def setup_environment():
    lg.reconfigure()
    ip_versions.init()
    instance.db.init(Model.PATH)
    instance.db.execute_sql("ATTACH ? AS resident", (Model.RESIDENT_PATH,))
    instance.db.execute_sql("ATTACH ? AS ipsetlists", (IPSET_LISTS_PATH,))
    Index.add_type(WHITELISTS, "whitelist/v2", 0o770, 0o660, all_zip=True)


async def run_sync_request() -> None:
    try:
        # remove previous response file if it exists
        REMOTE_IPLIST_RESPONSE.unlink(missing_ok=True)
        plugin = RemoteIPListPlugin()
        sync_point, delay, responses = await plugin.get_sync_from_server(
            lazy_responses=False
        )
        logger.info(f"Sync point: {sync_point}, delay: {delay}")
        save_state(RemoteIPListResponse(sync_point, delay, responses))
    except Exception as ex:
        logger.error("Failed to get sync from server: %s", ex)


async def run(args: argparse.Namespace) -> None:
    _response = restore_state()
    if _response is None:
        logger.error("response file not found")
        sys.exit(2)
    try:
        sync_point, delay, responses = _response.unpack()
        logger.info(
            "Restored response: %s", (sync_point, delay, len(responses))
        )
        plugin = RemoteIPListPlugin()
        with Benchmark() as bench:
            (
                total_blocked_count,
                total_unblocked_count,
                sync_point,
                delay_s,
            ) = await plugin.do_single_update(
                sync=(sync_point, delay, responses)
            )

        if args.json:
            print(
                json.dumps(
                    {
                        "unblocked": total_unblocked_count,
                        "blocked": total_blocked_count,
                        "sync_point": sync_point,
                        "elapsed": bench.elapsed_time_ms,
                        "delay": delay_s,
                    },
                    indent=True,
                )
            )
        else:
            print(delay_s)

    except Exception as ex:
        print(ex, file=sys.stderr)


def main():
    args = parse_args()
    loop = asyncio.get_event_loop()
    tls_check.reset()
    setup_environment()
    logger.info("Starting remote_iplist with args %s", args)
    if args.sync_request:
        loop.run_until_complete(run_sync_request())
    else:
        loop.run_until_complete(run(args))


if __name__ == "__main__":
    main()

Zerion Mini Shell 1.0