google-site-verification: google61fe8ba583a51912.html
Sysdig Secure for Containers in Java

Introduction

Sysdig Secure is a container security platform that provides runtime security, vulnerability management, and compliance for containerized applications. It uses eBPF technology to provide deep visibility and security for Java applications running in containers.

Architecture Overview

Sysdig Secure Architecture for Java Containers

┌─────────────────────────────────────────────────────────────┐ │ Java Application Container │ ├─────────────────────────────────────────────────────────────┤ │ Sysdig Agent (eBPF-based) │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │ │ │ System │ │ Network │ │ Security │ │ │ │ Calls │ │ Activity │ │ Policies │ │ │ └─────────────┘ └─────────────┘ └─────────────────────┘ │ ├─────────────────────────────────────────────────────────────┤ │ Container Runtime │ └─────────────────────────────────────────────────────────────┘

Installation and Setup

1. Sysdig Agent Installation

Kubernetes Deployment

# k8s/sysdig-agent.yaml apiVersion: v1 kind: ConfigMap metadata: name: sysdig-agent-config data: dragent.yaml: | sysdig: access_key: ${ACCESS_KEY} url: https://us2.app.sysdig.com security: enabled: true falco_rules_filename: ["falco_rules.yaml", "java_rules.yaml"] new_k8s: true k8s_cluster_name: production-cluster --- apiVersion: apps/v1 kind: DaemonSet metadata: name: sysdig-agent labels: app: sysdig-agent spec: selector: matchLabels: app: sysdig-agent template: metadata: labels: app: sysdig-agent spec: hostNetwork: true hostPID: true containers: - name: sysdig-agent image: sysdig/agent:latest imagePullPolicy: Always env: - name: ACCESS_KEY valueFrom: secretKeyRef: name: sysdig-access-key key: access-key - name: NODE_NAME valueFrom: fieldRef: fieldPath: spec.nodeName securityContext: privileged: true volumeMounts: - mountPath: /host/var/run/docker.sock name: docker-sock - mountPath: /host/dev name: dev-vol - mountPath: /host/proc name: proc-vol readOnly: true - mountPath: /host/boot name: boot-vol readOnly: true - mountPath: /host/lib/modules name: lib-modules-vol readOnly: true - mountPath: /host/usr name: usr-vol readOnly: true - mountPath: /etc/sysdig name: sysdig-agent-config volumes: - name: docker-sock hostPath: path: /var/run/docker.sock - name: dev-vol hostPath: path: /dev - name: proc-vol hostPath: path: /proc - name: boot-vol hostPath: path: /boot - name: lib-modules-vol hostPath: path: /lib/modules - name: usr-vol hostPath: path: /usr - name: sysdig-agent-config configMap: name: sysdig-agent-config tolerations: - effect: NoSchedule operator: Exists

Installation Script

#!/bin/bash # install-sysdig-agent.sh set -euo pipefail CLUSTER_NAME="production-cluster" ACCESS_KEY="${SYSFIG_ACCESS_KEY}" # Create namespace kubectl create namespace sysdig-agent # Create secret kubectl create secret generic sysdig-access-key \ --from-literal=access-key=$ACCESS_KEY \ -n sysdig-agent # Deploy agent kubectl apply -f k8s/sysdig-agent.yaml # Verify installation kubectl get pods -n sysdig-agent kubectl logs -f daemonset/sysdig-agent -n sysdig-agent

Java Application Security

2. Secure Java Container Configuration

Security-Hardened Dockerfile

# Dockerfile for Secure Java Application FROM eclipse-temurin:17-jre-jammy as runtime # Security: Use non-root user RUN groupadd -r javaapp && useradd -r -g javaapp javaapp # Security: Create app directory with proper permissions RUN mkdir -p /app && chown javaapp:javaapp /app WORKDIR /app # Security: Copy application with correct ownership COPY --chown=javaapp:javaapp target/*.jar app.jar # Security: Use signed base images only # Security: Minimal base image with no shell # Security: Read-only root filesystem RUN chmod 755 /app && \ chmod 644 app.jar # Security: Drop capabilities # Security: No new privileges # Security: Read-only root filesystem # Security: Disable ptrace # Switch to non-root user USER javaapp # Security: Use secure JVM options ENV JAVA_OPTS="-Djava.security.egd=file:/dev/./urandom \ -Djava.awt.headless=true \ -Dspring.profiles.active=production \ -Dlog4j2.formatMsgNoLookups=true" # Health check HEALTHCHECK --interval=30s --timeout=3s --start-period=60s --retries=3 \ CMD curl -f http://localhost:8080/actuator/health || exit 1 # Security: Expose non-privileged port EXPOSE 8080 # Security: Use exec form for proper signal handling ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]

Security Context in Kubernetes

# k8s/secure-deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: user-service labels: app: user-service spec: replicas: 3 selector: matchLabels: app: user-service template: metadata: labels: app: user-service annotations: # Sysdig annotations for enhanced monitoring sysdig.com/monitoring: "true" sysdig.com/secure: "enabled" spec: securityContext: # Pod security context runAsNonRoot: true runAsUser: 1000 runAsGroup: 3000 fsGroup: 2000 seccompProfile: type: RuntimeDefault containers: - name: user-service image: company/user-service:1.0.0 securityContext: # Container security context allowPrivilegeEscalation: false runAsNonRoot: true runAsUser: 1000 privileged: false readOnlyRootFilesystem: true capabilities: drop: - ALL seccompProfile: type: RuntimeDefault ports: - containerPort: 8080 env: - name: JAVA_OPTS value: "-Djava.security.egd=file:/dev/./urandom -Xmx512m -Xms256m" - name: SYSFIG_CAPTURE_ENABLED value: "true" livenessProbe: httpGet: path: /actuator/health port: 8080 initialDelaySeconds: 30 periodSeconds: 10 readinessProbe: httpGet: path: /actuator/health port: 8080 initialDelaySeconds: 5 periodSeconds: 5 resources: requests: memory: "512Mi" cpu: "250m" limits: memory: "1Gi" cpu: "500m" volumeMounts: - name: tmp mountPath: /tmp - name: logs mountPath: /app/logs volumes: - name: tmp emptyDir: {} - name: logs emptyDir: {}

3. Custom Security Rules for Java Applications

Java-Specific Falco Rules

# java-security-rules.yaml - rule: Java Process Spawned Shell desc: Detect Java process spawning shell commands condition: > proc.name = "java" and (spawned_process and (proc.name in (bash, sh, zsh, ksh, csh, tcsh))) output: > Java process spawned shell (user=%user.name command=%proc.cmdline container=%container.info shell=%proc.name parent=%proc.pname) priority: WARNING tags: [java, process, container] - rule: Java File System Write in Sensitive Location desc: Detect Java writing to sensitive file system locations condition: > proc.name = "java" and (write and (fd.name startswith /etc or fd.name startswith /bin or fd.name startswith /sbin or fd.name startswith /usr/bin)) output: > Java process wrote to sensitive location (user=%user.name command=%proc.cmdline container=%container.info file=%fd.name) priority: CRITICAL tags: [java, filesystem, container] - rule: Java Network Connection to Suspicious Ports desc: Detect Java making network connections to suspicious ports condition: > proc.name = "java" and (evt.type = connect and (server_port < 1024 and server_port != 80 and server_port != 443 and server_port != 8080 and server_port != 8443)) output: > Java process connected to suspicious port (user=%user.name command=%proc.cmdline container=%container.info port=%server_port) priority: WARNING tags: [java, network, container] - rule: Java Process Memory Execution desc: Detect Java process executing from memory condition: > proc.name = "java" and (evt.type = execve and evt.dir=> and (proc.exe != /usr/lib/jvm/java-17-openjdk/bin/java)) output: > Java process executed from memory (user=%user.name command=%proc.cmdline container=%container.info) priority: CRITICAL tags: [java, process, container] - rule: Java Deserialization Attack Detection desc: Detect potential Java deserialization attacks condition: > proc.name = "java" and (evt.type in (open, openat) and (fd.name contains ".ser" or fd.name contains ".serialized")) output: > Java process accessed serialized file (user=%user.name command=%proc.cmdline container=%container.info file=%fd.name) priority: WARNING tags: [java, deserialization, container] - rule: Java Classpath Manipulation desc: Detect Java process modifying classpath or loading external classes condition: > proc.name = "java" and (evt.type in (open, openat, execve) and (proc.cmdline contains "-cp" or proc.cmdline contains "-classpath" or proc.cmdline contains "javaagent:")) output: > Java process with classpath manipulation (user=%user.name command=%proc.cmdline container=%container.info) priority: WARNING tags: [java, classpath, container]

Runtime Security Monitoring

4. Java Application Security Integration

Security Event Monitoring Service

@Service public class SecurityEventMonitor { private static final Logger logger = LoggerFactory.getLogger(SecurityEventMonitor.class); private final MeterRegistry meterRegistry; private final Counter securityEventCounter; public SecurityEventMonitor(MeterRegistry meterRegistry) { this.meterRegistry = meterRegistry; this.securityEventCounter = Counter.builder("security_events") .description("Security events detected in the application") .register(meterRegistry); } @EventListener public void handleSecurityEvent(SecurityEvent event) { logger.warn("Security event detected: {}", event.getDescription()); securityEventCounter.increment(); // Tag the event with severity and type Tags tags = Tags.of( Tag.of("severity", event.getSeverity().name()), Tag.of("type", event.getType()), Tag.of("source", event.getSource()) ); meterRegistry.counter("security_events_detailed", tags).increment(); // Log to security audit log auditSecurityEvent(event); } public void monitorSuspiciousActivity(String activity, String details) { logger.warn("Suspicious activity detected: {} - {}", activity, details); Tags tags = Tags.of( Tag.of("activity", activity), Tag.of("details", details) ); meterRegistry.counter("suspicious_activities", tags).increment(); } public void monitorFileAccess(String filePath, String operation) { if (isSensitiveFile(filePath)) { logger.warn("Sensitive file accessed: {} - {}", filePath, operation); Tags tags = Tags.of( Tag.of("file", filePath), Tag.of("operation", operation) ); meterRegistry.counter("sensitive_file_access", tags).increment(); } } public void monitorNetworkConnection(String host, int port, String protocol) { if (isSuspiciousDestination(host, port)) { logger.warn("Suspicious network connection: {}:{} via {}", host, port, protocol); Tags tags = Tags.of( Tag.of("host", host), Tag.of("port", String.valueOf(port)), Tag.of("protocol", protocol) ); meterRegistry.counter("suspicious_connections", tags).increment(); } } private boolean isSensitiveFile(String filePath) { return filePath.contains("/etc/") || filePath.contains("/bin/") || filePath.contains("/sys/") || filePath.contains("/proc/") || filePath.endsWith(".key") || filePath.endsWith(".pem") || filePath.endsWith(".jks"); } private boolean isSuspiciousDestination(String host, int port) { // Define suspicious destinations return port < 1024 && port != 80 && port != 443 && port != 8080 && port != 8443; } private void auditSecurityEvent(SecurityEvent event) { // Send to security information and event management (SIEM) system // Integrate with Sysdig Secure API logger.info("SECURITY_AUDIT: {}", event); } } // Security Event Classes @Data class SecurityEvent { private final String type; private final String description; private final Severity severity; private final String source; private final Instant timestamp; private final Map<String, Object> details; public SecurityEvent(String type, String description, Severity severity, String source) { this.type = type; this.description = description; this.severity = severity; this.source = source; this.timestamp = Instant.now(); this.details = new HashMap<>(); } public SecurityEvent withDetail(String key, Object value) { this.details.put(key, value); return this; } } enum Severity { LOW, MEDIUM, HIGH, CRITICAL }

5. Security Aspect for Method Monitoring

@Aspect @Component public class SecurityMonitoringAspect { private final SecurityEventMonitor securityMonitor; public SecurityMonitoringAspect(SecurityEventMonitor securityMonitor) { this.securityMonitor = securityMonitor; } @Around("execution(* com.company..*(..)) && " + "@annotation(monitorSecurity)") public Object monitorSecuritySensitiveMethods(ProceedingJoinPoint joinPoint, MonitorSecurity monitorSecurity) throws Throwable { String methodName = joinPoint.getSignature().getName(); String className = joinPoint.getTarget().getClass().getSimpleName(); long startTime = System.currentTimeMillis(); try { Object result = joinPoint.proceed(); long duration = System.currentTimeMillis() - startTime; // Log successful execution if (monitorSecurity.logSuccess()) { logger.debug("Security-sensitive method executed: {}.{} in {}ms", className, methodName, duration); } return result; } catch (Exception e) { long duration = System.currentTimeMillis() - startTime; // Create security event for exceptions in security-sensitive methods SecurityEvent event = new SecurityEvent( "METHOD_EXCEPTION", String.format("Exception in security-sensitive method %s.%s: %s", className, methodName, e.getMessage()), Severity.MEDIUM, "SecurityAspect" ).withDetail("method", methodName) .withDetail("class", className) .withDetail("exception", e.getClass().getSimpleName()) .withDetail("duration", duration); securityMonitor.handleSecurityEvent(event); throw e; } } @AfterReturning(pointcut = "execution(* java.io.*.*(..)) || " + "execution(* java.nio.file.*.*(..))", returning = "result") public void monitorFileOperations(JoinPoint joinPoint, Object result) { String methodName = joinPoint.getSignature().getName(); Object[] args = joinPoint.getArgs(); // Monitor file operations for (Object arg : args) { if (arg instanceof String) { String path = (String) arg; securityMonitor.monitorFileAccess(path, methodName); } else if (arg instanceof Path) { Path path = (Path) arg; securityMonitor.monitorFileAccess(path.toString(), methodName); } } } } // Annotation for security-sensitive methods @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface MonitorSecurity { boolean logSuccess() default false; Severity severity() default Severity.MEDIUM; }

Vulnerability Management

6. Vulnerability Scanning Integration

Pre-commit Security Scanning

@Component public class VulnerabilityScanner { private final RestTemplate restTemplate; private final SysdigSecureClient sysdigClient; public VulnerabilityScanner(RestTemplate restTemplate, SysdigSecureClient sysdigClient) { this.restTemplate = restTemplate; this.sysdigClient = sysdigClient; } public VulnerabilityReport scanImage(String imageName, String imageTag) { try { // Trigger Sysdig Secure vulnerability scan ScanRequest request = new ScanRequest(imageName, imageTag); ScanResponse response = sysdigClient.scanImage(request); return analyzeVulnerabilities(response); } catch (Exception e) { logger.error("Failed to scan image {}:{}", imageName, imageTag, e); throw new SecurityScanException("Vulnerability scan failed", e); } } public ComplianceReport checkCompliance(String imageName, String imageTag) { try { // Check compliance against standards ComplianceRequest request = new ComplianceRequest(imageName, imageTag); ComplianceResponse response = sysdigClient.checkCompliance(request); return analyzeCompliance(response); } catch (Exception e) { logger.error("Failed to check compliance for {}:{}", imageName, imageTag, e); throw new SecurityScanException("Compliance check failed", e); } } public boolean isImageApproved(String imageName, String imageTag) { VulnerabilityReport vulnerabilityReport = scanImage(imageName, imageTag); ComplianceReport complianceReport = checkCompliance(imageName, imageTag); return vulnerabilityReport.isApproved() && complianceReport.isCompliant(); } private VulnerabilityReport analyzeVulnerabilities(ScanResponse response) { List<Vulnerability> criticalVulns = response.getVulnerabilities().stream() .filter(v -> v.getSeverity() == Severity.CRITICAL) .collect(Collectors.toList()); List<Vulnerability> highVulns = response.getVulnerabilities().stream() .filter(v -> v.getSeverity() == Severity.HIGH) .collect(Collectors.toList()); boolean approved = criticalVulns.isEmpty() && highVulns.size() <= 3; return new VulnerabilityReport(response.getVulnerabilities(), approved); } private ComplianceReport analyzeCompliance(ComplianceResponse response) { List<ComplianceCheck> failedChecks = response.getChecks().stream() .filter(check -> !check.isPassed()) .collect(Collectors.toList()); boolean compliant = failedChecks.size() <= response.getAllowedFailures(); return new ComplianceReport(response.getChecks(), compliant); } } // Report Classes @Data class VulnerabilityReport { private final List<Vulnerability> vulnerabilities; private final boolean approved; private final Instant scanTime; public VulnerabilityReport(List<Vulnerability> vulnerabilities, boolean approved) { this.vulnerabilities = vulnerabilities; this.approved = approved; this.scanTime = Instant.now(); } public long getCriticalCount() { return vulnerabilities.stream() .filter(v -> v.getSeverity() == Severity.CRITICAL) .count(); } public long getHighCount() { return vulnerabilities.stream() .filter(v -> v.getSeverity() == Severity.HIGH) .count(); } } @Data class ComplianceReport { private final List<ComplianceCheck> checks; private final boolean compliant; private final Instant checkTime; public ComplianceReport(List<ComplianceCheck> checks, boolean compliant) { this.checks = checks; this.compliant = compliant; this.checkTime = Instant.now(); } public List<ComplianceCheck> getFailedChecks() { return checks.stream() .filter(check -> !check.isPassed()) .collect(Collectors.toList()); } }

7. Admission Controller for Security

Kubernetes Validating Webhook

@RestController @RequestMapping("/admission") public class SecurityAdmissionController { private final VulnerabilityScanner vulnerabilityScanner; private final ObjectMapper objectMapper; public SecurityAdmissionController(VulnerabilityScanner vulnerabilityScanner) { this.vulnerabilityScanner = vulnerabilityScanner; this.objectMapper = new ObjectMapper(); } @PostMapping("/validate") public AdmissionReview validateDeployment(@RequestBody AdmissionReview review) { try { AdmissionRequest request = review.getRequest(); // Extract deployment information DeploymentInfo deploymentInfo = extractDeploymentInfo(request); // Check image security boolean approved = validateImageSecurity(deploymentInfo); // Create response AdmissionResponse response = new AdmissionResponse(); response.setUid(request.getUid()); response.setAllowed(approved); if (!approved) { response.setStatus(new AdmissionResponseStatus("Failure", "Image security validation failed. Check vulnerabilities and compliance.")); } return new AdmissionReview(response); } catch (Exception e) { logger.error("Admission validation failed", e); return createErrorResponse(review.getRequest().getUid(), "Admission validation error: " + e.getMessage()); } } private DeploymentInfo extractDeploymentInfo(AdmissionRequest request) { try { String deploymentJson = objectMapper.writeValueAsString(request.getObject()); JsonNode deploymentNode = objectMapper.readTree(deploymentJson); String image = deploymentNode.path("spec") .path("template") .path("spec") .path("containers") .get(0) .path("image") .asText(); String[] imageParts = image.split(":"); String imageName = imageParts[0]; String imageTag = imageParts.length > 1 ? imageParts[1] : "latest"; return new DeploymentInfo(imageName, imageTag, request.getNamespace()); } catch (Exception e) { throw new AdmissionException("Failed to extract deployment info", e); } } private boolean validateImageSecurity(DeploymentInfo deploymentInfo) { try { // Check if image is approved boolean imageApproved = vulnerabilityScanner.isImageApproved( deploymentInfo.getImageName(), deploymentInfo.getImageTag()); if (!imageApproved) { logger.warn("Image security validation failed for {}:{} in namespace {}", deploymentInfo.getImageName(), deploymentInfo.getImageTag(), deploymentInfo.getNamespace()); return false; } // Additional security checks boolean securityContextValid = validateSecurityContext(deploymentInfo); return securityContextValid; } catch (Exception e) { logger.error("Image security validation error for {}:{}", deploymentInfo.getImageName(), deploymentInfo.getImageTag(), e); return false; } } private boolean validateSecurityContext(DeploymentInfo deploymentInfo) { // Validate security context requirements // - Non-root user // - Read-only root filesystem // - No privilege escalation // - etc. return true; // Simplified for example } private AdmissionReview createErrorResponse(String uid, String message) { AdmissionResponse response = new AdmissionResponse(); response.setUid(uid); response.setAllowed(false); response.setStatus(new AdmissionResponseStatus("Failure", message)); return new AdmissionReview(response); } } @Data class DeploymentInfo { private final String imageName; private final String imageTag; private final String namespace; }

Runtime Policy Enforcement

8. Security Policy Configuration

Sysdig Secure Policies

# java-security-policies.yaml apiVersion: security.sysdig.com/v1 kind: Policy metadata: name: java-container-security spec: rules: - name: "Java Container Security" description: "Security policies for Java containers" scope: - container: image: "company/*" actions: - containerExec: block - containerTerminal: block - networkDetection: alert condition: and: - proc.name = java - not: k8s.pod.label.app in (user-service, profile-service, api-gateway) --- apiVersion: security.sysdig.com/v1 kind: Policy metadata: name: java-file-integrity spec: rules: - name: "Java File Integrity Monitoring" description: "Monitor file system changes in Java containers" scope: - container: image: "company/java-*" actions: - fileModification: alert condition: and: - proc.name = java - fd.name contains "/app/" - not: fd.name endswith ".log" --- apiVersion: security.sysdig.com/v1 kind: Policy metadata: name: java-network-policy spec: rules: - name: "Java Network Policy" description: "Network security policies for Java applications" scope: - container: image: "company/*" actions: - networkConnection: alert condition: and: - proc.name = java - server_port not in (80, 443, 8080, 8443, 9092, 5432)

9. Real-time Security Monitoring

Security Dashboard Integration

@Service public class SecurityDashboardService { private final SysdigSecureClient sysdigClient; private final MeterRegistry meterRegistry; public SecurityDashboardService(SysdigSecureClient sysdigClient, MeterRegistry meterRegistry) { this.sysdigClient = sysdigClient; this.meterRegistry = meterRegistry; } @Scheduled(fixedRate = 30000) // Every 30 seconds public void updateSecurityMetrics() { try { SecurityMetrics metrics = sysdigClient.getSecurityMetrics(); updateMetrics(metrics); } catch (Exception e) { logger.error("Failed to update security metrics", e); } } @Scheduled(fixedRate = 60000) // Every minute public void checkRuntimeThreats() { try { List<SecurityEvent> threats = sysdigClient.getRecentThreats(); processThreats(threats); } catch (Exception e) { logger.error("Failed to check runtime threats", e); } } public SecurityStatus getSecurityStatus() { try { RuntimeSecurityStatus status = sysdigClient.getRuntimeSecurityStatus(); return mapToSecurityStatus(status); } catch (Exception e) { logger.error("Failed to get security status", e); return SecurityStatus.ERROR; } } private void updateMetrics(SecurityMetrics metrics) { // Update Micrometer metrics Gauge.builder("security.vulnerabilities.critical") .description("Critical vulnerabilities count") .register(meterRegistry, metrics::getCriticalVulnerabilities); Gauge.builder("security.vulnerabilities.high") .description("High vulnerabilities count") .register(meterRegistry, metrics::getHighVulnerabilities); Gauge.builder("security.runtime.threats") .description("Active runtime threats") .register(meterRegistry, metrics::getActiveThreats); Gauge.builder("security.compliance.score") .description("Compliance score percentage") .register(meterRegistry, metrics::getComplianceScore); } private void processThreats(List<SecurityEvent> threats) { for (SecurityEvent threat : threats) { logger.warn("Runtime threat detected: {}", threat.getDescription()); // Alert based on severity if (threat.getSeverity() == Severity.CRITICAL) { sendCriticalAlert(threat); } } } private void sendCriticalAlert(SecurityEvent threat) { // Integrate with alerting system (PagerDuty, Slack, etc.) logger.error("CRITICAL SECURITY ALERT: {}", threat); } private SecurityStatus mapToSecurityStatus(RuntimeSecurityStatus status) { if (status.getCriticalThreats() > 0) { return SecurityStatus.CRITICAL; } else if (status.getHighThreats() > 5) { return SecurityStatus.WARNING; } else { return SecurityStatus.HEALTHY; } } } enum SecurityStatus { HEALTHY, WARNING, CRITICAL, ERROR }

Incident Response

10. Automated Incident Response

Security Incident Handler

@Service public class SecurityIncidentHandler { private final SecurityEventMonitor securityMonitor; private final KubernetesClient kubernetesClient; private final SysdigSecureClient sysdigClient; public SecurityIncidentHandler(SecurityEventMonitor securityMonitor, KubernetesClient kubernetesClient, SysdigSecureClient sysdigClient) { this.securityMonitor = securityMonitor; this.kubernetesClient = kubernetesClient; this.sysdigClient = sysdigClient; } @EventListener public void handleCriticalSecurityEvent(SecurityEvent event) { if (event.getSeverity() == Severity.CRITICAL) { logger.error("Handling critical security event: {}", event.getDescription()); // Automated response actions switch (event.getType()) { case "CONTAINER_BREACH": handleContainerBreach(event); break; case "MALICIOUS_PROCESS": handleMaliciousProcess(event); break; case "UNAUTHORIZED_ACCESS": handleUnauthorizedAccess(event); break; default: logger.warn("No specific handler for event type: {}", event.getType()); } } } private void handleContainerBreach(SecurityEvent event) { String containerId = (String) event.getDetails().get("containerId"); String podName = (String) event.getDetails().get("podName"); String namespace = (String) event.getDetails().get("namespace"); logger.warn("Container breach detected in pod {}/{}", namespace, podName); try { // Isolate the pod by adding network policies isolatePod(podName, namespace); // Capture forensic data captureForensicData(podName, namespace); // Scale down the deployment scaleDownDeployment(podName, namespace); // Notify security team notifySecurityTeam(event); } catch (Exception e) { logger.error("Failed to handle container breach for pod {}/{}", namespace, podName, e); } } private void handleMaliciousProcess(SecurityEvent event) { String containerId = (String) event.getDetails().get("containerId"); String processName = (String) event.getDetails().get("processName"); logger.warn("Malicious process detected: {} in container {}", processName, containerId); // Kill the malicious process killProcess(containerId, processName); // Create security policy to block similar processes createBlockingPolicy(processName); } private void handleUnauthorizedAccess(SecurityEvent event) { String sourceIp = (String) event.getDetails().get("sourceIp"); String user = (String) event.getDetails().get("user"); logger.warn("Unauthorized access detected from IP: {} by user: {}", sourceIp, user); // Block the source IP blockSourceIp(sourceIp); // Revoke user access if applicable revokeUserAccess(user); } private void isolatePod(String podName, String namespace) { // Create network policy to isolate the pod NetworkPolicy policy = new NetworkPolicyBuilder() .withNewMetadata() .withName("isolate-" + podName) .withNamespace(namespace) .endMetadata() .withNewSpec() .withNewPodSelector() .addToMatchLabels("pod-name", podName) .endPodSelector() .withPolicyTypes("Ingress", "Egress") .withNewIngress() .addNewFrom() .withNewPodSelector() .addToMatchLabels("app", "security-scanner") .endPodSelector() .endFrom() .endIngress() .endSpec() .build(); kubernetesClient.network().networkPolicies() .inNamespace(namespace) .createOrReplace(policy); } private void captureForensicData(String podName, String namespace) { // Use Sysdig Secure to capture forensic data sysdigClient.captureContainerData(podName, namespace); } private void scaleDownDeployment(String podName, String namespace) { // Find deployment for the pod and scale to 0 kubernetesClient.apps().deployments() .inNamespace(namespace) .withName(getDeploymentName(podName)) .scale(0); } private void killProcess(String containerId, String processName) { // Use Sysdig Secure to kill the process sysdigClient.killProcess(containerId, processName); } private String getDeploymentName(String podName) { // Extract deployment name from pod name return podName.substring(0, podName.lastIndexOf('-')); } }

Best Practices and Compliance

11. Security Compliance Reporting

Compliance Service

@Service public class ComplianceService { private final SysdigSecureClient sysdigClient; private final VulnerabilityScanner vulnerabilityScanner; public ComplianceService(SysdigSecureClient sysdigClient, VulnerabilityScanner vulnerabilityScanner) { this.sysdigClient = sysdigClient; this.vulnerabilityScanner = vulnerabilityScanner; } public ComplianceReport generateComplianceReport(String namespace) { try { List<PodSecurityReport> podReports = getPodSecurityReports(namespace); List<ImageSecurityReport> imageReports = getImageSecurityReports(namespace); RuntimeSecurityReport runtimeReport = getRuntimeSecurityReport(namespace); return compileComplianceReport(podReports, imageReports, runtimeReport); } catch (Exception e) { logger.error("Failed to generate compliance report for namespace {}", namespace, e); throw new ComplianceException("Compliance report generation failed", e); } } public boolean checkCISCompliance(String namespace) { try { CISComplianceReport cisReport = sysdigClient.getCISCompliance(namespace); return cisReport.isCompliant() && cisReport.getScore() >= 90; } catch (Exception e) { logger.error("Failed to check CIS compliance for namespace {}", namespace, e); return false; } } public void enforceCompliancePolicies(String namespace) { List<ComplianceViolation> violations = sysdigClient.getComplianceViolations(namespace); for (ComplianceViolation violation : violations) { if (violation.getSeverity() == Severity.CRITICAL) { enforceCriticalViolation(violation); } } } private List<PodSecurityReport> getPodSecurityReports(String namespace) { // Get pod security context compliance return kubernetesClient.pods() .inNamespace(namespace) .list() .getItems() .stream() .map(this::analyzePodSecurity) .collect(Collectors.toList()); } private PodSecurityReport analyzePodSecurity(Pod pod) { PodSecurityReport report = new PodSecurityReport(pod.getMetadata().getName()); // Check security context if (pod.getSpec().getSecurityContext() == null) { report.addViolation("Missing pod security context"); } // Check container security contexts pod.getSpec().getContainers().forEach(container -> { if (container.getSecurityContext() == null) { report.addViolation( String.format("Container %s missing security context", container.getName())); } else { checkContainerSecurityContext(container, report); } }); return report; } private void checkContainerSecurityContext(Container container, PodSecurityReport report) { SecurityContext sc = container.getSecurityContext(); if (sc.getRunAsNonRoot() == null || !sc.getRunAsNonRoot()) { report.addViolation( String.format("Container %s not running as non-root", container.getName())); } if (sc.getReadOnlyRootFilesystem() == null || !sc.getReadOnlyRootFilesystem()) { report.addViolation( String.format("Container %s has writable root filesystem", container.getName())); } if (sc.getAllowPrivilegeEscalation() != null && sc.getAllowPrivilegeEscalation()) { report.addViolation( String.format("Container %s allows privilege escalation", container.getName())); } } }

Conclusion

Sysdig Secure provides comprehensive security for Java containerized applications:

  1. Runtime Security: Real-time threat detection using eBPF
  2. Vulnerability Management: Container image scanning and compliance
  3. Network Security: Micro-segmentation and network policies
  4. Compliance: CIS benchmarks and custom compliance checks
  5. Incident Response: Automated response to security events

Key benefits for Java applications:

  • Deep Visibility: System call monitoring for Java processes
  • Zero Configuration: Automatic detection of Java applications
  • Performance: eBPF-based monitoring with minimal overhead
  • Integration: Seamless integration with Java ecosystem and frameworks
  • Compliance: Out-of-the-box compliance for Java containers

By implementing Sysdig Secure with these patterns, organizations can achieve enterprise-grade security for their Java microservices while maintaining development velocity and operational efficiency.

Leave a Reply

Your email address will not be published. Required fields are marked *


Macro Nepal Helper