- Add 100 blog posts covering AI, development, and tech topics - Add .env.example for environment configuration - Add accessibility and lighthouse audit scripts - Remove obsolete SEO reports and temporary files - Remove dev-dist build artifacts and backup files - Remove unused portrait images (moved/consolidated elsewhere) - Update contact form and component improvements Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
826 lines
21 KiB
Markdown
826 lines
21 KiB
Markdown
# IoT Security Best Practices
|
||
|
||
**Meta-Description:** IoT Security implementieren. Device Authentication, Verschlüsselung, Secure Boot und Firmware Updates für sichere IoT-Systeme.
|
||
|
||
**Keywords:** IoT Security, Device Authentication, TLS, Encryption, Secure Boot, Firmware Update, MQTT Security
|
||
|
||
---
|
||
|
||
## Einführung
|
||
|
||
IoT-Sicherheit ist kritisch – vernetzte Geräte sind potenzielle Angriffsziele. **Device Authentication, Verschlüsselung, Secure Boot** und sichere **Firmware Updates** sind Pflicht für jedes professionelle IoT-System.
|
||
|
||
---
|
||
|
||
## IoT Security Layers
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────┐
|
||
│ IOT SECURITY ARCHITECTURE │
|
||
├─────────────────────────────────────────────────────────────┤
|
||
│ │
|
||
│ Layer 7 - Application Security: │
|
||
│ ├── Input Validation │
|
||
│ ├── API Security (Rate Limiting, Auth) │
|
||
│ └── Secure Data Handling │
|
||
│ │
|
||
│ Layer 6 - Identity & Access: │
|
||
│ ├── Device Authentication (Certificates, Tokens) │
|
||
│ ├── User Authentication (MFA, Passkeys) │
|
||
│ └── Role-Based Access Control (RBAC) │
|
||
│ │
|
||
│ Layer 5 - Communication Security: │
|
||
│ ├── TLS 1.3 Encryption │
|
||
│ ├── mTLS (Mutual TLS) │
|
||
│ └── VPN / Private Networks │
|
||
│ │
|
||
│ Layer 4 - Network Security: │
|
||
│ ├── Firewalls / Segmentation │
|
||
│ ├── Intrusion Detection (IDS) │
|
||
│ └── Traffic Monitoring │
|
||
│ │
|
||
│ Layer 3 - Device Security: │
|
||
│ ├── Secure Boot │
|
||
│ ├── Hardware Security Module (HSM) │
|
||
│ ├── Firmware Signing │
|
||
│ └── Secure Storage (Encrypted) │
|
||
│ │
|
||
│ Layer 2 - Physical Security: │
|
||
│ ├── Tamper Detection │
|
||
│ ├── Secure Enclosure │
|
||
│ └── Debug Port Disable │
|
||
│ │
|
||
│ Compliance: NIST, ISO 27001, IEC 62443, GDPR │
|
||
│ │
|
||
└─────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
---
|
||
|
||
## Device Authentication
|
||
|
||
```typescript
|
||
// lib/device-auth.ts
|
||
import crypto from 'crypto';
|
||
import jwt from 'jsonwebtoken';
|
||
|
||
interface DeviceCredentials {
|
||
deviceId: string;
|
||
certificate: string;
|
||
privateKey: string;
|
||
}
|
||
|
||
interface DeviceToken {
|
||
deviceId: string;
|
||
iat: number;
|
||
exp: number;
|
||
capabilities: string[];
|
||
}
|
||
|
||
class DeviceAuthenticator {
|
||
private caCertificate: string;
|
||
private jwtSecret: string;
|
||
|
||
constructor(caCertPath: string, jwtSecret: string) {
|
||
this.caCertificate = require('fs').readFileSync(caCertPath, 'utf8');
|
||
this.jwtSecret = jwtSecret;
|
||
}
|
||
|
||
// X.509 Certificate-based Authentication
|
||
verifyCertificate(clientCert: string): boolean {
|
||
try {
|
||
const cert = new crypto.X509Certificate(clientCert);
|
||
const caCert = new crypto.X509Certificate(this.caCertificate);
|
||
|
||
// Verify certificate chain
|
||
if (!cert.verify(caCert.publicKey)) {
|
||
return false;
|
||
}
|
||
|
||
// Check expiration
|
||
const now = new Date();
|
||
if (now < new Date(cert.validFrom) || now > new Date(cert.validTo)) {
|
||
return false;
|
||
}
|
||
|
||
// Check revocation (in production: check CRL/OCSP)
|
||
// ...
|
||
|
||
return true;
|
||
} catch (error) {
|
||
console.error('Certificate verification failed:', error);
|
||
return false;
|
||
}
|
||
}
|
||
|
||
// Extract Device ID from Certificate
|
||
extractDeviceId(clientCert: string): string | null {
|
||
try {
|
||
const cert = new crypto.X509Certificate(clientCert);
|
||
// CN (Common Name) enthält Device ID
|
||
const cnMatch = cert.subject.match(/CN=([^,]+)/);
|
||
return cnMatch ? cnMatch[1] : null;
|
||
} catch {
|
||
return null;
|
||
}
|
||
}
|
||
|
||
// JWT Token Generation für Devices
|
||
generateDeviceToken(deviceId: string, capabilities: string[]): string {
|
||
const payload: Omit<DeviceToken, 'iat' | 'exp'> = {
|
||
deviceId,
|
||
capabilities
|
||
};
|
||
|
||
return jwt.sign(payload, this.jwtSecret, {
|
||
expiresIn: '24h',
|
||
issuer: 'iot-platform',
|
||
audience: 'iot-devices'
|
||
});
|
||
}
|
||
|
||
// Token Verification
|
||
verifyDeviceToken(token: string): DeviceToken | null {
|
||
try {
|
||
return jwt.verify(token, this.jwtSecret, {
|
||
issuer: 'iot-platform',
|
||
audience: 'iot-devices'
|
||
}) as DeviceToken;
|
||
} catch {
|
||
return null;
|
||
}
|
||
}
|
||
|
||
// Challenge-Response Authentication
|
||
generateChallenge(): { challenge: string; expiresAt: Date } {
|
||
const challenge = crypto.randomBytes(32).toString('hex');
|
||
const expiresAt = new Date(Date.now() + 5 * 60 * 1000); // 5 Minuten
|
||
|
||
return { challenge, expiresAt };
|
||
}
|
||
|
||
verifyChallenge(
|
||
challenge: string,
|
||
response: string,
|
||
devicePublicKey: string
|
||
): boolean {
|
||
try {
|
||
const verify = crypto.createVerify('SHA256');
|
||
verify.update(challenge);
|
||
|
||
return verify.verify(devicePublicKey, response, 'base64');
|
||
} catch {
|
||
return false;
|
||
}
|
||
}
|
||
}
|
||
|
||
// API Key Authentication (für einfachere Devices)
|
||
interface APIKeyConfig {
|
||
deviceId: string;
|
||
apiKey: string;
|
||
createdAt: Date;
|
||
lastUsed?: Date;
|
||
rateLimit: number;
|
||
}
|
||
|
||
class APIKeyAuthenticator {
|
||
private keys: Map<string, APIKeyConfig> = new Map();
|
||
|
||
generateKey(deviceId: string, rateLimit: number = 100): string {
|
||
const apiKey = `iot_${crypto.randomBytes(24).toString('hex')}`;
|
||
|
||
this.keys.set(apiKey, {
|
||
deviceId,
|
||
apiKey,
|
||
createdAt: new Date(),
|
||
rateLimit
|
||
});
|
||
|
||
return apiKey;
|
||
}
|
||
|
||
validateKey(apiKey: string): APIKeyConfig | null {
|
||
const config = this.keys.get(apiKey);
|
||
|
||
if (!config) {
|
||
return null;
|
||
}
|
||
|
||
// Update last used
|
||
config.lastUsed = new Date();
|
||
|
||
return config;
|
||
}
|
||
|
||
revokeKey(apiKey: string): void {
|
||
this.keys.delete(apiKey);
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## TLS/mTLS Communication
|
||
|
||
```typescript
|
||
// lib/secure-mqtt.ts
|
||
import mqtt from 'mqtt';
|
||
import fs from 'fs';
|
||
import tls from 'tls';
|
||
|
||
interface SecureMQTTConfig {
|
||
brokerUrl: string;
|
||
caCert: string;
|
||
clientCert: string;
|
||
clientKey: string;
|
||
clientId: string;
|
||
}
|
||
|
||
function createSecureMQTTClient(config: SecureMQTTConfig): mqtt.MqttClient {
|
||
return mqtt.connect(config.brokerUrl, {
|
||
clientId: config.clientId,
|
||
protocol: 'mqtts',
|
||
protocolVersion: 5, // MQTT 5.0
|
||
|
||
// TLS Options
|
||
ca: fs.readFileSync(config.caCert),
|
||
cert: fs.readFileSync(config.clientCert),
|
||
key: fs.readFileSync(config.clientKey),
|
||
|
||
// Strict verification
|
||
rejectUnauthorized: true,
|
||
checkServerIdentity: (hostname, cert) => {
|
||
// Custom hostname verification if needed
|
||
return tls.checkServerIdentity(hostname, cert);
|
||
},
|
||
|
||
// Connection Options
|
||
keepalive: 60,
|
||
reconnectPeriod: 5000,
|
||
connectTimeout: 30000,
|
||
|
||
// Clean Session (MQTT 5.0)
|
||
clean: true,
|
||
properties: {
|
||
sessionExpiryInterval: 0
|
||
}
|
||
});
|
||
}
|
||
|
||
// HTTPS Server mit mTLS
|
||
import https from 'https';
|
||
import express from 'express';
|
||
|
||
function createSecureServer(
|
||
app: express.Application,
|
||
caCert: string,
|
||
serverCert: string,
|
||
serverKey: string
|
||
) {
|
||
return https.createServer({
|
||
ca: fs.readFileSync(caCert),
|
||
cert: fs.readFileSync(serverCert),
|
||
key: fs.readFileSync(serverKey),
|
||
|
||
// Require client certificates (mTLS)
|
||
requestCert: true,
|
||
rejectUnauthorized: true,
|
||
|
||
// Minimum TLS version
|
||
minVersion: 'TLSv1.3',
|
||
|
||
// Cipher Suites (only strong ciphers)
|
||
ciphers: [
|
||
'TLS_AES_256_GCM_SHA384',
|
||
'TLS_CHACHA20_POLY1305_SHA256',
|
||
'TLS_AES_128_GCM_SHA256'
|
||
].join(':')
|
||
}, app);
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## Secure Data Storage
|
||
|
||
```typescript
|
||
// lib/secure-storage.ts
|
||
import crypto from 'crypto';
|
||
import { promisify } from 'util';
|
||
|
||
const scrypt = promisify(crypto.scrypt);
|
||
|
||
interface EncryptedData {
|
||
iv: string;
|
||
data: string;
|
||
tag: string;
|
||
salt: string;
|
||
}
|
||
|
||
class SecureStorage {
|
||
private masterKey: Buffer | null = null;
|
||
|
||
// Key Derivation von Password/PIN
|
||
async deriveKey(password: string, salt: Buffer): Promise<Buffer> {
|
||
return scrypt(password, salt, 32) as Promise<Buffer>;
|
||
}
|
||
|
||
// Initialize mit Master Key
|
||
async initialize(masterPassword: string): Promise<void> {
|
||
const salt = crypto.randomBytes(32);
|
||
this.masterKey = await this.deriveKey(masterPassword, salt);
|
||
}
|
||
|
||
// AES-256-GCM Encryption
|
||
encrypt(plaintext: string): EncryptedData {
|
||
if (!this.masterKey) {
|
||
throw new Error('Storage not initialized');
|
||
}
|
||
|
||
const iv = crypto.randomBytes(16);
|
||
const salt = crypto.randomBytes(32);
|
||
|
||
const cipher = crypto.createCipheriv('aes-256-gcm', this.masterKey, iv);
|
||
|
||
let encrypted = cipher.update(plaintext, 'utf8', 'hex');
|
||
encrypted += cipher.final('hex');
|
||
|
||
const tag = cipher.getAuthTag();
|
||
|
||
return {
|
||
iv: iv.toString('hex'),
|
||
data: encrypted,
|
||
tag: tag.toString('hex'),
|
||
salt: salt.toString('hex')
|
||
};
|
||
}
|
||
|
||
// Decryption
|
||
decrypt(encryptedData: EncryptedData): string {
|
||
if (!this.masterKey) {
|
||
throw new Error('Storage not initialized');
|
||
}
|
||
|
||
const iv = Buffer.from(encryptedData.iv, 'hex');
|
||
const tag = Buffer.from(encryptedData.tag, 'hex');
|
||
|
||
const decipher = crypto.createDecipheriv('aes-256-gcm', this.masterKey, iv);
|
||
decipher.setAuthTag(tag);
|
||
|
||
let decrypted = decipher.update(encryptedData.data, 'hex', 'utf8');
|
||
decrypted += decipher.final('utf8');
|
||
|
||
return decrypted;
|
||
}
|
||
|
||
// Secure Credential Storage
|
||
async storeCredentials(
|
||
deviceId: string,
|
||
credentials: Record<string, string>
|
||
): Promise<EncryptedData> {
|
||
const data = JSON.stringify({ deviceId, credentials, timestamp: Date.now() });
|
||
return this.encrypt(data);
|
||
}
|
||
}
|
||
|
||
// Hardware Security Module (HSM) Integration
|
||
interface HSMConfig {
|
||
slotId: number;
|
||
pin: string;
|
||
modulePath: string;
|
||
}
|
||
|
||
class HSMIntegration {
|
||
// Für echte HSM-Integration: PKCS#11 Library verwenden
|
||
// z.B. graphene-pk11, pkcs11js
|
||
|
||
async sign(data: Buffer, keyLabel: string): Promise<Buffer> {
|
||
// HSM signing operation
|
||
throw new Error('Implement with actual HSM library');
|
||
}
|
||
|
||
async verify(
|
||
data: Buffer,
|
||
signature: Buffer,
|
||
keyLabel: string
|
||
): Promise<boolean> {
|
||
// HSM verification
|
||
throw new Error('Implement with actual HSM library');
|
||
}
|
||
|
||
async generateKeyPair(keyLabel: string): Promise<{ publicKey: string }> {
|
||
// Generate key pair in HSM (private key never leaves HSM)
|
||
throw new Error('Implement with actual HSM library');
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## Secure Firmware Updates
|
||
|
||
```typescript
|
||
// lib/firmware-update.ts
|
||
import crypto from 'crypto';
|
||
import fs from 'fs';
|
||
import { pipeline } from 'stream/promises';
|
||
|
||
interface FirmwareMetadata {
|
||
version: string;
|
||
releaseDate: string;
|
||
sha256: string;
|
||
signature: string;
|
||
size: number;
|
||
minVersion: string;
|
||
deviceModels: string[];
|
||
}
|
||
|
||
class SecureFirmwareUpdater {
|
||
private signingPublicKey: string;
|
||
|
||
constructor(publicKeyPath: string) {
|
||
this.signingPublicKey = fs.readFileSync(publicKeyPath, 'utf8');
|
||
}
|
||
|
||
// Firmware Signatur verifizieren
|
||
verifySignature(firmwarePath: string, signature: string): boolean {
|
||
const firmware = fs.readFileSync(firmwarePath);
|
||
|
||
const verify = crypto.createVerify('SHA256');
|
||
verify.update(firmware);
|
||
|
||
return verify.verify(this.signingPublicKey, signature, 'base64');
|
||
}
|
||
|
||
// Firmware Hash verifizieren
|
||
verifyHash(firmwarePath: string, expectedHash: string): boolean {
|
||
const firmware = fs.readFileSync(firmwarePath);
|
||
const hash = crypto.createHash('sha256').update(firmware).digest('hex');
|
||
|
||
return hash === expectedHash;
|
||
}
|
||
|
||
// Firmware Download mit Verification
|
||
async downloadFirmware(
|
||
url: string,
|
||
metadata: FirmwareMetadata,
|
||
targetPath: string
|
||
): Promise<boolean> {
|
||
const response = await fetch(url);
|
||
|
||
if (!response.ok) {
|
||
throw new Error(`Download failed: ${response.status}`);
|
||
}
|
||
|
||
// Streaming Download mit Hash-Berechnung
|
||
const hash = crypto.createHash('sha256');
|
||
const fileStream = fs.createWriteStream(targetPath);
|
||
|
||
const reader = response.body?.getReader();
|
||
if (!reader) throw new Error('No response body');
|
||
|
||
let downloadedSize = 0;
|
||
|
||
while (true) {
|
||
const { done, value } = await reader.read();
|
||
|
||
if (done) break;
|
||
|
||
hash.update(value);
|
||
fileStream.write(value);
|
||
downloadedSize += value.length;
|
||
}
|
||
|
||
fileStream.end();
|
||
|
||
// Size Check
|
||
if (downloadedSize !== metadata.size) {
|
||
fs.unlinkSync(targetPath);
|
||
throw new Error('Size mismatch');
|
||
}
|
||
|
||
// Hash Check
|
||
const actualHash = hash.digest('hex');
|
||
if (actualHash !== metadata.sha256) {
|
||
fs.unlinkSync(targetPath);
|
||
throw new Error('Hash mismatch');
|
||
}
|
||
|
||
// Signature Check
|
||
if (!this.verifySignature(targetPath, metadata.signature)) {
|
||
fs.unlinkSync(targetPath);
|
||
throw new Error('Signature verification failed');
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
// Version Check
|
||
shouldUpdate(
|
||
currentVersion: string,
|
||
newVersion: string,
|
||
minVersion: string
|
||
): boolean {
|
||
const current = this.parseVersion(currentVersion);
|
||
const target = this.parseVersion(newVersion);
|
||
const min = this.parseVersion(minVersion);
|
||
|
||
// Current version must be >= minVersion for update
|
||
if (this.compareVersions(current, min) < 0) {
|
||
return false;
|
||
}
|
||
|
||
// Only update if target is newer
|
||
return this.compareVersions(target, current) > 0;
|
||
}
|
||
|
||
private parseVersion(version: string): number[] {
|
||
return version.split('.').map(Number);
|
||
}
|
||
|
||
private compareVersions(a: number[], b: number[]): number {
|
||
for (let i = 0; i < Math.max(a.length, b.length); i++) {
|
||
const av = a[i] || 0;
|
||
const bv = b[i] || 0;
|
||
if (av > bv) return 1;
|
||
if (av < bv) return -1;
|
||
}
|
||
return 0;
|
||
}
|
||
}
|
||
|
||
// OTA Update API
|
||
import express from 'express';
|
||
|
||
const firmwareRouter = express.Router();
|
||
|
||
// GET /api/firmware/check?model=xxx&version=1.0.0
|
||
firmwareRouter.get('/check', async (req, res) => {
|
||
const { model, version } = req.query;
|
||
|
||
// Check for available updates
|
||
const latestFirmware = await getLatestFirmware(model as string);
|
||
|
||
if (!latestFirmware) {
|
||
return res.json({ updateAvailable: false });
|
||
}
|
||
|
||
const updater = new SecureFirmwareUpdater('./keys/firmware-signing.pub');
|
||
|
||
const shouldUpdate = updater.shouldUpdate(
|
||
version as string,
|
||
latestFirmware.version,
|
||
latestFirmware.minVersion
|
||
);
|
||
|
||
res.json({
|
||
updateAvailable: shouldUpdate,
|
||
...(shouldUpdate && { firmware: latestFirmware })
|
||
});
|
||
});
|
||
```
|
||
|
||
---
|
||
|
||
## Input Validation & Sanitization
|
||
|
||
```typescript
|
||
// lib/input-validation.ts
|
||
import { z } from 'zod';
|
||
|
||
// Schema für Sensor-Daten
|
||
const SensorDataSchema = z.object({
|
||
device_id: z.string()
|
||
.min(1)
|
||
.max(64)
|
||
.regex(/^[a-zA-Z0-9_-]+$/),
|
||
|
||
timestamp: z.string()
|
||
.datetime()
|
||
.refine(
|
||
(ts) => new Date(ts) <= new Date(),
|
||
'Timestamp cannot be in the future'
|
||
),
|
||
|
||
temperature: z.number()
|
||
.min(-50)
|
||
.max(100)
|
||
.optional(),
|
||
|
||
humidity: z.number()
|
||
.min(0)
|
||
.max(100)
|
||
.optional(),
|
||
|
||
battery: z.number()
|
||
.min(0)
|
||
.max(100)
|
||
.optional()
|
||
});
|
||
|
||
// Schema für Device Commands
|
||
const DeviceCommandSchema = z.object({
|
||
action: z.enum(['restart', 'update', 'configure', 'reset']),
|
||
target: z.string().min(1).max(64),
|
||
payload: z.record(z.unknown()).optional()
|
||
}).refine(
|
||
(data) => {
|
||
// Dangerous actions require additional validation
|
||
if (data.action === 'reset') {
|
||
return data.payload?.confirm === true;
|
||
}
|
||
return true;
|
||
},
|
||
'Reset action requires confirmation'
|
||
);
|
||
|
||
// Middleware für Input Validation
|
||
import { Request, Response, NextFunction } from 'express';
|
||
|
||
function validateInput(schema: z.ZodType<any>) {
|
||
return (req: Request, res: Response, next: NextFunction) => {
|
||
try {
|
||
req.body = schema.parse(req.body);
|
||
next();
|
||
} catch (error) {
|
||
if (error instanceof z.ZodError) {
|
||
return res.status(400).json({
|
||
error: 'Validation failed',
|
||
details: error.errors
|
||
});
|
||
}
|
||
next(error);
|
||
}
|
||
};
|
||
}
|
||
|
||
// Rate Limiting
|
||
import rateLimit from 'express-rate-limit';
|
||
|
||
const deviceRateLimit = rateLimit({
|
||
windowMs: 60 * 1000, // 1 Minute
|
||
max: 60, // 60 Requests pro Minute
|
||
keyGenerator: (req) => req.headers['x-device-id'] as string || req.ip,
|
||
handler: (req, res) => {
|
||
res.status(429).json({
|
||
error: 'Rate limit exceeded',
|
||
retryAfter: 60
|
||
});
|
||
}
|
||
});
|
||
```
|
||
|
||
---
|
||
|
||
## Security Monitoring
|
||
|
||
```typescript
|
||
// lib/security-monitoring.ts
|
||
|
||
interface SecurityEvent {
|
||
timestamp: Date;
|
||
eventType: string;
|
||
severity: 'low' | 'medium' | 'high' | 'critical';
|
||
deviceId?: string;
|
||
sourceIp?: string;
|
||
details: Record<string, any>;
|
||
}
|
||
|
||
class SecurityMonitor {
|
||
private events: SecurityEvent[] = [];
|
||
|
||
// Authentication Failure
|
||
logAuthFailure(deviceId: string, reason: string, sourceIp: string): void {
|
||
this.logEvent({
|
||
eventType: 'auth_failure',
|
||
severity: 'medium',
|
||
deviceId,
|
||
sourceIp,
|
||
details: { reason }
|
||
});
|
||
|
||
// Check for brute force
|
||
this.checkBruteForce(deviceId, sourceIp);
|
||
}
|
||
|
||
// Anomaly Detection
|
||
logAnomaly(deviceId: string, anomalyType: string, value: any): void {
|
||
this.logEvent({
|
||
eventType: 'anomaly',
|
||
severity: 'medium',
|
||
deviceId,
|
||
details: { anomalyType, value }
|
||
});
|
||
}
|
||
|
||
// Firmware Tampering
|
||
logTamperAttempt(deviceId: string, details: Record<string, any>): void {
|
||
this.logEvent({
|
||
eventType: 'tamper_attempt',
|
||
severity: 'critical',
|
||
deviceId,
|
||
details
|
||
});
|
||
|
||
// Immediate alert
|
||
this.sendAlert({
|
||
type: 'tamper_attempt',
|
||
deviceId,
|
||
details
|
||
});
|
||
}
|
||
|
||
private logEvent(event: Omit<SecurityEvent, 'timestamp'>): void {
|
||
const fullEvent: SecurityEvent = {
|
||
...event,
|
||
timestamp: new Date()
|
||
};
|
||
|
||
this.events.push(fullEvent);
|
||
|
||
// In production: send to SIEM
|
||
console.log('Security Event:', JSON.stringify(fullEvent));
|
||
}
|
||
|
||
private checkBruteForce(deviceId: string, sourceIp: string): void {
|
||
const recentFailures = this.events.filter(e =>
|
||
e.eventType === 'auth_failure' &&
|
||
e.timestamp > new Date(Date.now() - 5 * 60 * 1000) &&
|
||
(e.deviceId === deviceId || e.sourceIp === sourceIp)
|
||
);
|
||
|
||
if (recentFailures.length >= 5) {
|
||
this.logEvent({
|
||
eventType: 'brute_force_detected',
|
||
severity: 'high',
|
||
deviceId,
|
||
sourceIp,
|
||
details: { failureCount: recentFailures.length }
|
||
});
|
||
|
||
// Block IP/Device
|
||
this.blockSource(sourceIp, deviceId);
|
||
}
|
||
}
|
||
|
||
private blockSource(ip: string, deviceId: string): void {
|
||
// Implement blocking logic
|
||
console.log(`Blocking IP: ${ip}, Device: ${deviceId}`);
|
||
}
|
||
|
||
private sendAlert(alert: Record<string, any>): void {
|
||
// Send to Slack, PagerDuty, etc.
|
||
console.log('ALERT:', alert);
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## Security Checklist
|
||
|
||
| Category | Requirement | Priority |
|
||
|----------|------------|----------|
|
||
| **Authentication** | Certificate-based device auth | High |
|
||
| **Authentication** | No default credentials | Critical |
|
||
| **Encryption** | TLS 1.3 for all communications | High |
|
||
| **Encryption** | Data at rest encryption | High |
|
||
| **Firmware** | Signed firmware updates | Critical |
|
||
| **Firmware** | Secure boot chain | High |
|
||
| **Network** | Network segmentation | Medium |
|
||
| **Network** | Firewall rules | High |
|
||
| **Monitoring** | Security event logging | High |
|
||
| **Monitoring** | Anomaly detection | Medium |
|
||
| **Compliance** | Regular security audits | High |
|
||
|
||
---
|
||
|
||
## Fazit
|
||
|
||
IoT Security erfordert:
|
||
|
||
1. **Defense in Depth**: Mehrere Sicherheitsebenen
|
||
2. **Strong Authentication**: Zertifikate statt Passwörter
|
||
3. **Encryption**: TLS everywhere
|
||
4. **Secure Updates**: Signierte Firmware
|
||
|
||
Sicherheit ist keine Option – sie ist Pflicht.
|
||
|
||
---
|
||
|
||
## Bildprompts
|
||
|
||
1. "IoT security layers diagram, defense in depth concept"
|
||
2. "Secure device authentication flow, certificate exchange"
|
||
3. "Security monitoring dashboard with alerts and events"
|
||
|
||
---
|
||
|
||
## Quellen
|
||
|
||
- [IoT Device Security Best Practices 2026](https://www.jaycon.com/iot-device-security-best-practices/)
|
||
- [ConnectWise IoT Security Guide](https://www.connectwise.com/blog/how-to-secure-iot-devices)
|
||
- [Fortinet IoT Best Practices](https://www.fortinet.com/resources/cyberglossary/iot-best-practices)
|
||
- [Azure IoT Security](https://learn.microsoft.com/en-us/azure/iot/iot-overview-security)
|