mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-06-15 15:34:56 +03:00
Add folder anatomy (scripts/agent.py + references/api-reference.md) for 648 cybersecurity skills
Complete skill folder anatomy across all cybersecurity skills: - scripts/agent.py: 80-150 line Python agents using real libraries (impacket, boto3, azure-mgmt-*, kubernetes, pefile, yara, scapy, shodan, stix2, etc.) - references/api-reference.md: real API documentation with method signatures - LICENSE: MIT license for all skill folders
This commit is contained in:
@@ -0,0 +1,246 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Rsyslog Centralization Agent - Generates and deploys TLS-secured rsyslog configurations."""
|
||||
|
||||
import json
|
||||
import logging
|
||||
import argparse
|
||||
import subprocess
|
||||
from datetime import datetime
|
||||
|
||||
from jinja2 import Template
|
||||
|
||||
logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s")
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
SERVER_TEMPLATE = Template("""\
|
||||
# Rsyslog Server Configuration - TLS Centralized Logging
|
||||
# Generated by Syslog Centralization Agent
|
||||
|
||||
# Load modules
|
||||
module(load="imuxsock")
|
||||
module(load="imklog")
|
||||
module(load="imtcp"
|
||||
StreamDriver.Name="gtls"
|
||||
StreamDriver.Mode="1"
|
||||
StreamDriver.Authmode="x509/name"
|
||||
PermittedPeer=["{{ permitted_peers | join('","') }}"]
|
||||
)
|
||||
|
||||
# TLS Certificate Configuration
|
||||
global(
|
||||
DefaultNetstreamDriver="gtls"
|
||||
DefaultNetstreamDriverCAFile="{{ ca_cert }}"
|
||||
DefaultNetstreamDriverCertFile="{{ server_cert }}"
|
||||
DefaultNetstreamDriverKeyFile="{{ server_key }}"
|
||||
)
|
||||
|
||||
# TLS Listener
|
||||
input(type="imtcp" port="{{ tls_port }}")
|
||||
|
||||
# Templates
|
||||
template(name="PerHostDir" type="string"
|
||||
string="/var/log/remote/%HOSTNAME%/%PROGRAMNAME%.log")
|
||||
|
||||
template(name="JSONFormat" type="string"
|
||||
string='{"timestamp":"%TIMESTAMP:::date-rfc3339%","host":"%HOSTNAME%","facility":"%syslogfacility-text%","severity":"%syslogseverity-text%","program":"%PROGRAMNAME%","msg":"%msg:::json%"}\\n')
|
||||
|
||||
template(name="PerHostJSON" type="string"
|
||||
string="/var/log/remote/%HOSTNAME%/json/%PROGRAMNAME%.json")
|
||||
|
||||
# Rules - Store per-host with standard format
|
||||
*.* ?PerHostDir
|
||||
|
||||
# Also store in JSON format for SIEM ingestion
|
||||
*.* ?PerHostJSON;JSONFormat
|
||||
|
||||
# High-severity alerts to dedicated file
|
||||
*.err /var/log/remote/errors.log
|
||||
""")
|
||||
|
||||
CLIENT_TEMPLATE = Template("""\
|
||||
# Rsyslog Client Configuration - TLS Forwarding
|
||||
# Generated by Syslog Centralization Agent
|
||||
|
||||
# TLS Certificate Configuration
|
||||
global(
|
||||
DefaultNetstreamDriver="gtls"
|
||||
DefaultNetstreamDriverCAFile="{{ ca_cert }}"
|
||||
DefaultNetstreamDriverCertFile="{{ client_cert }}"
|
||||
DefaultNetstreamDriverKeyFile="{{ client_key }}"
|
||||
)
|
||||
|
||||
# Forward all logs to central server with TLS and reliable queue
|
||||
action(
|
||||
type="omfwd"
|
||||
target="{{ server_ip }}"
|
||||
port="{{ tls_port }}"
|
||||
protocol="tcp"
|
||||
StreamDriver="gtls"
|
||||
StreamDriverMode="1"
|
||||
StreamDriverAuthMode="x509/name"
|
||||
StreamDriverPermittedPeers="{{ server_ip }}"
|
||||
queue.type="LinkedList"
|
||||
queue.filename="fwdRule1"
|
||||
queue.maxdiskspace="{{ queue_disk_space }}"
|
||||
queue.saveonshutdown="on"
|
||||
queue.size="{{ queue_size }}"
|
||||
action.resumeRetryCount="-1"
|
||||
action.resumeInterval="30"
|
||||
)
|
||||
""")
|
||||
|
||||
|
||||
def generate_server_config(server_ip, clients, ca_cert, server_cert, server_key, tls_port=6514):
|
||||
"""Generate rsyslog server configuration with TLS."""
|
||||
config = SERVER_TEMPLATE.render(
|
||||
permitted_peers=clients + [server_ip],
|
||||
ca_cert=ca_cert,
|
||||
server_cert=server_cert,
|
||||
server_key=server_key,
|
||||
tls_port=tls_port,
|
||||
)
|
||||
logger.info("Generated server config for %s with %d permitted peers", server_ip, len(clients))
|
||||
return config
|
||||
|
||||
|
||||
def generate_client_config(server_ip, ca_cert, client_cert, client_key, tls_port=6514):
|
||||
"""Generate rsyslog client configuration with TLS forwarding."""
|
||||
config = CLIENT_TEMPLATE.render(
|
||||
server_ip=server_ip,
|
||||
ca_cert=ca_cert,
|
||||
client_cert=client_cert,
|
||||
client_key=client_key,
|
||||
tls_port=tls_port,
|
||||
queue_disk_space="1g",
|
||||
queue_size="50000",
|
||||
)
|
||||
logger.info("Generated client config forwarding to %s:%d", server_ip, tls_port)
|
||||
return config
|
||||
|
||||
|
||||
def generate_tls_certificates(output_dir, server_cn, client_cns):
|
||||
"""Generate CA, server, and client TLS certificates using OpenSSL."""
|
||||
ca_key = f"{output_dir}/ca-key.pem"
|
||||
ca_cert = f"{output_dir}/ca.pem"
|
||||
subprocess.run([
|
||||
"openssl", "req", "-x509", "-newkey", "rsa:4096", "-keyout", ca_key,
|
||||
"-out", ca_cert, "-days", "3650", "-nodes",
|
||||
"-subj", f"/CN=Syslog CA/O=SOC/C=US",
|
||||
], capture_output=True, check=True)
|
||||
logger.info("Generated CA certificate: %s", ca_cert)
|
||||
|
||||
for cn in [server_cn] + client_cns:
|
||||
key_file = f"{output_dir}/{cn}-key.pem"
|
||||
cert_file = f"{output_dir}/{cn}-cert.pem"
|
||||
csr_file = f"{output_dir}/{cn}.csr"
|
||||
subprocess.run([
|
||||
"openssl", "req", "-newkey", "rsa:2048", "-keyout", key_file,
|
||||
"-out", csr_file, "-nodes", "-subj", f"/CN={cn}/O=SOC/C=US",
|
||||
], capture_output=True, check=True)
|
||||
subprocess.run([
|
||||
"openssl", "x509", "-req", "-in", csr_file, "-CA", ca_cert,
|
||||
"-CAkey", ca_key, "-CAcreateserial", "-out", cert_file, "-days", "365",
|
||||
], capture_output=True, check=True)
|
||||
logger.info("Generated certificate for %s", cn)
|
||||
return ca_cert
|
||||
|
||||
|
||||
def deploy_config_ssh(host, config_content, remote_path, username="root", key_file=None):
|
||||
"""Deploy rsyslog configuration to a remote host via SSH."""
|
||||
import paramiko
|
||||
client = paramiko.SSHClient()
|
||||
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||
connect_kwargs = {"hostname": host, "username": username}
|
||||
if key_file:
|
||||
connect_kwargs["key_filename"] = key_file
|
||||
client.connect(**connect_kwargs)
|
||||
sftp = client.open_sftp()
|
||||
with sftp.file(remote_path, "w") as f:
|
||||
f.write(config_content)
|
||||
sftp.close()
|
||||
_, stdout, stderr = client.exec_command("systemctl restart rsyslog")
|
||||
exit_status = stdout.channel.recv_exit_status()
|
||||
client.close()
|
||||
logger.info("Deployed config to %s:%s (restart exit: %d)", host, remote_path, exit_status)
|
||||
return exit_status == 0
|
||||
|
||||
|
||||
def validate_tls_connection(server_ip, tls_port=6514, ca_cert=None):
|
||||
"""Validate TLS connectivity to the rsyslog server."""
|
||||
cmd = [
|
||||
"openssl", "s_client", "-connect", f"{server_ip}:{tls_port}",
|
||||
"-CAfile", ca_cert or "/etc/ssl/certs/ca-certificates.crt",
|
||||
]
|
||||
try:
|
||||
result = subprocess.run(cmd, capture_output=True, text=True, timeout=10, input="")
|
||||
connected = "Verify return code: 0" in result.stdout
|
||||
logger.info("TLS validation to %s:%d: %s", server_ip, tls_port, "OK" if connected else "FAILED")
|
||||
return connected
|
||||
except subprocess.TimeoutExpired:
|
||||
return False
|
||||
|
||||
|
||||
def generate_report(server_config, client_configs, deployments, tls_valid):
|
||||
"""Generate syslog centralization deployment report."""
|
||||
report = {
|
||||
"timestamp": datetime.utcnow().isoformat(),
|
||||
"server_config_generated": bool(server_config),
|
||||
"client_configs_generated": len(client_configs),
|
||||
"deployments": deployments,
|
||||
"tls_validated": tls_valid,
|
||||
}
|
||||
print(f"SYSLOG REPORT: {len(client_configs)} client configs, TLS: {'OK' if tls_valid else 'PENDING'}")
|
||||
return report
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="Rsyslog Centralization Agent")
|
||||
parser.add_argument("--server-ip", required=True, help="Syslog server IP")
|
||||
parser.add_argument("--clients", required=True, help="Comma-separated client IPs")
|
||||
parser.add_argument("--ca-cert", default="/etc/rsyslog.d/ca.pem")
|
||||
parser.add_argument("--server-cert", default="/etc/rsyslog.d/server-cert.pem")
|
||||
parser.add_argument("--server-key", default="/etc/rsyslog.d/server-key.pem")
|
||||
parser.add_argument("--tls-port", type=int, default=6514)
|
||||
parser.add_argument("--deploy", action="store_true", help="Deploy configs via SSH")
|
||||
parser.add_argument("--config-dir", default="./rsyslog_configs")
|
||||
parser.add_argument("--output", default="syslog_report.json")
|
||||
args = parser.parse_args()
|
||||
|
||||
clients = [c.strip() for c in args.clients.split(",")]
|
||||
import os
|
||||
os.makedirs(args.config_dir, exist_ok=True)
|
||||
|
||||
server_config = generate_server_config(
|
||||
args.server_ip, clients, args.ca_cert, args.server_cert, args.server_key, args.tls_port
|
||||
)
|
||||
with open(f"{args.config_dir}/server.conf", "w") as f:
|
||||
f.write(server_config)
|
||||
|
||||
client_configs = {}
|
||||
for client_ip in clients:
|
||||
config = generate_client_config(
|
||||
args.server_ip, args.ca_cert,
|
||||
f"/etc/rsyslog.d/{client_ip}-cert.pem",
|
||||
f"/etc/rsyslog.d/{client_ip}-key.pem",
|
||||
args.tls_port,
|
||||
)
|
||||
with open(f"{args.config_dir}/client-{client_ip}.conf", "w") as f:
|
||||
f.write(config)
|
||||
client_configs[client_ip] = config
|
||||
|
||||
deployments = []
|
||||
if args.deploy:
|
||||
for client_ip, config in client_configs.items():
|
||||
ok = deploy_config_ssh(client_ip, config, "/etc/rsyslog.d/99-central.conf")
|
||||
deployments.append({"host": client_ip, "success": ok})
|
||||
|
||||
tls_valid = validate_tls_connection(args.server_ip, args.tls_port, args.ca_cert)
|
||||
report = generate_report(server_config, client_configs, deployments, tls_valid)
|
||||
|
||||
with open(args.output, "w") as f:
|
||||
json.dump(report, f, indent=2)
|
||||
logger.info("Report saved to %s", args.output)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user