Skip to content

Security Hardening Guide

πŸ”’ Production Security Checklist

1. Change Default Passwords

  • Grafana admin password
  • RabbitMQ credentials
  • PostgreSQL password
  • pgAdmin credentials
  • Keycloak admin password
  • Redis authentication
  • Vault root token rotation

2. Enable HTTPS Everywhere

  • Configure Let's Encrypt certificates
  • Force HTTPS redirects
  • Update internal service communication to use HTTPS
  • Verify SSL certificate expiration monitoring

3. Network Security

  • Configure firewall rules
  • Restrict external access to internal services
  • Enable network segmentation
  • Implement VPN access for management

4. Vault Security

  • Initialize Vault with proper key shares
  • Configure Vault policies for least privilege
  • Enable Vault audit logging
  • Set up automatic unsealing (if appropriate)

5. Container Security

  • Scan images for vulnerabilities
  • Run containers as non-root users
  • Implement resource limits
  • Regular image updates

6. Monitoring & Alerting

  • Configure security event alerts
  • Monitor failed authentication attempts
  • Set up log aggregation for security events
  • Implement intrusion detection

πŸ›‘οΈ Security Configuration Examples

Traefik Security Headers

# traefik.yml
http:
  middlewares:
    security-headers:
      headers:
        customRequestHeaders:
          X-Forwarded-Proto: "https"
        customResponseHeaders:
          X-Frame-Options: "DENY"
          X-Content-Type-Options: "nosniff"
          X-XSS-Protection: "1; mode=block"
          Strict-Transport-Security: "max-age=31536000; includeSubDomains"
          Content-Security-Policy: "default-src 'self'"

Vault Policies

# policies/app-policy.hcl
path "secret/data/myapp/*" {
  capabilities = ["read"]
}

path "secret/metadata/myapp/*" {
  capabilities = ["list"]
}

OpenSearch Security (if enabled)

# opensearch/config/opensearch_security.yml
plugins.security.ssl.transport.pemcert_filepath: transport.pem
plugins.security.ssl.transport.pemkey_filepath: transport-key.pem
plugins.security.ssl.transport.pemtrustedcas_filepath: root-ca.pem
plugins.security.ssl.http.enabled: true
plugins.security.ssl.http.pemcert_filepath: http.pem
plugins.security.ssl.http.pemkey_filepath: http-key.pem
plugins.security.ssl.http.pemtrustedcas_filepath: root-ca.pem

Java Spring Security Configuration

@Configuration
@EnableWebSecurity
@EnableMethodSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(authz -> authz
                .requestMatchers("/actuator/health").permitAll()
                .requestMatchers("/api/public/**").permitAll()
                .anyRequest().authenticated()
            )
            .oauth2ResourceServer(oauth2 -> oauth2
                .jwt(jwt -> jwt.jwtAuthenticationConverter(jwtAuthConverter()))
            )
            .sessionManagement(session -> session
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            );
        return http.build();
    }

    @Bean
    public JwtAuthenticationConverter jwtAuthConverter() {
        JwtGrantedAuthoritiesConverter authoritiesConverter = 
            new JwtGrantedAuthoritiesConverter();
        authoritiesConverter.setAuthorityPrefix("ROLE_");
        authoritiesConverter.setAuthoritiesClaimName("roles");

        JwtAuthenticationConverter converter = new JwtAuthenticationConverter();
        converter.setJwtGrantedAuthoritiesConverter(authoritiesConverter);
        return converter;
    }
}

// Audit Configuration
@Configuration
@EnableJpaAuditing
public class AuditConfig {

    @Bean
    public AuditorAware<String> auditorProvider() {
        return () -> {
            Authentication auth = SecurityContextHolder.getContext().getAuthentication();
            return Optional.ofNullable(auth)
                .map(Authentication::getName);
        };
    }
}

// Secure REST Controller
@RestController
@RequestMapping("/api/secure")
@Validated
public class SecureController {

    @GetMapping("/data")
    @PreAuthorize("hasRole('USER')")
    public ResponseEntity<String> getSecureData() {
        return ResponseEntity.ok("Secure data");
    }

    @PostMapping("/admin")
    @PreAuthorize("hasRole('ADMIN')")
    public ResponseEntity<String> adminOnly() {
        return ResponseEntity.ok("Admin only data");
    }
}

πŸ” Password Management

Generate Secure Passwords

# Generate random password
openssl rand -base64 32

# Generate password with specific requirements
openssl rand -base64 32 | tr -d "=+/" | cut -c1-25

Store Secrets in Vault

# Store database password
vault kv put secret/database username=admin password=secure_password

# Retrieve password
vault kv get -field=password secret/database

🚨 Security Monitoring

Log Analysis Queries

Failed Login Attempts

{
  "query": {
    "bool": {
      "must": [
        {"term": {"event.type": "authentication"}},
        {"term": {"event.outcome": "failure"}},
        {"range": {"@timestamp": {"gte": "now-1h"}}}
      ]
    }
  }
}

Privilege Escalation Attempts

{
  "query": {
    "bool": {
      "must": [
        {"terms": {"process.name": ["sudo", "su", "passwd"]}},
        {"range": {"@timestamp": {"gte": "now-24h"}}}
      ]
    }
  }
}

Grafana Security Dashboards

{
  "dashboard": {
    "title": "Security Overview",
    "panels": [
      {
        "title": "Failed Authentication Attempts",
        "type": "graph",
        "targets": [
          {
            "expr": "increase(authentication_failures_total[5m])"
          }
        ]
      }
    ]
  }
}

πŸ”„ Regular Security Tasks

Weekly Tasks

# Update Docker images
docker-compose pull
docker-compose up -d

# Check for security updates
apt list --upgradable
apt upgrade -y

# Review access logs
tail -n 1000 /var/log/auth.log | grep -i failed

Monthly Tasks

# Rotate Vault root token
vault auth -method=userpass username=admin
vault token-create -policy=root

# Review and update firewall rules
ufw status numbered
ufw --dry-run delete 1

# Certificate expiration check
echo | openssl s_client -servername localhost -connect localhost:443 2>/dev/null | openssl x509 -noout -dates

Quarterly Tasks

# Vulnerability assessment
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock aquasec/trivy image opensearch:latest

# Security audit
lynis audit system

# Backup encryption key rotation
gpg --gen-key

🚫 Security Incident Response

Immediate Response Steps

  1. Isolate affected systems
  2. Preserve evidence
  3. Assess impact
  4. Contain the breach
  5. Eradicate threats
  6. Recover operations
  7. Document lessons learned

Emergency Commands

# Block suspicious IP
iptables -A INPUT -s SUSPICIOUS_IP -j DROP

# Disable compromised user
docker exec keycloak /opt/keycloak/bin/kcadm.sh update users/USER_ID -r master -s enabled=false

# Revoke Vault tokens
vault token-revoke -accessor ACCESSOR_ID

# Emergency shutdown
docker-compose down

πŸ“‹ Compliance Considerations

Data Protection

  • Implement data encryption at rest
  • Configure data retention policies
  • Set up data backup and recovery procedures
  • Document data processing activities

Access Control

  • Implement role-based access control (RBAC)
  • Enable multi-factor authentication (MFA)
  • Regular access reviews
  • Principle of least privilege

Audit Trail

  • Enable comprehensive logging
  • Centralized log management
  • Log integrity protection
  • Regular audit log reviews