mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-06-11 13:44:56 +03:00
c47eed6a64
- Fix 25 shell=True subprocess calls with list-based commands - Fix 49 verify=False in defensive skills (env-var override) - Add timeout to 231 HTTP/subprocess/socket calls - Fix 6 SQL injection patterns with whitelist validation - Replace 8 __import__() with standard imports - Remove 701 unused imports across 442 files - Add authorized-testing disclaimers to all offensive skills - Complete 11 incomplete skill directories - Expand 10 stub SKILL.md files with full content - Fix 2 YAML parse errors in frontmatter - Fix 5 pre-existing syntax errors - Convert 22 hardcoded paths/ports to environment variables - Back up 21 redundant skill pairs to .bak - Fix 2 global declaration errors - 724/724 skills with full folder anatomy (SKILL.md + agent.py + api-reference.md + LICENSE) - 0 compile errors across all 724 agent.py files
247 lines
8.8 KiB
Python
247 lines
8.8 KiB
Python
#!/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, timeout=120)
|
|
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, timeout=120)
|
|
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, timeout=120)
|
|
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()
|