security: Add proper authentication, RBAC, and tenant isolation
- Add password hashing with bcrypt - Add AuthService with proper login - Add password strength validation - Add RBAC middleware (AdminOnly, ManagerOrAdmin) - Add tenant isolation middleware - Update CRM handler with tenant filtering - Add JWT fallback for development mode - Add user context helpers - Build successful
This commit is contained in:
@@ -0,0 +1,178 @@
|
||||
# BOC Härdning — Checklista
|
||||
|
||||
> **Datum:** 2026-08-04 22:46 UTC
|
||||
> **Status:** ⚠️ KRÄVER MANUELL ÅTGÄRD
|
||||
|
||||
---
|
||||
|
||||
## 🔴 KRITISKT — HTTPS/TLS
|
||||
|
||||
**Problem:** BOC kör på HTTP (port 9096), all trafik är okrypterad.
|
||||
|
||||
**Åtgärd:** Konfigurera nginx reverse proxy med Let's Encrypt:
|
||||
|
||||
```bash
|
||||
# 1. Installera certbot
|
||||
sudo dnf install certbot python3-certbot-nginx
|
||||
|
||||
# 2. Skapa nginx-konfig för BOC
|
||||
sudo tee /etc/nginx/conf.d/boc.conf << 'EOF'
|
||||
server {
|
||||
listen 443 ssl http2;
|
||||
server_name boc.aamos.com;
|
||||
|
||||
ssl_certificate /etc/letsencrypt/live/boc.aamos.com/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/boc.aamos.com/privkey.pem;
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
|
||||
|
||||
location / {
|
||||
proxy_pass http://localhost:9096;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name boc.aamos.com;
|
||||
return 301 https://$server_name$request_uri;
|
||||
}
|
||||
EOF
|
||||
|
||||
# 3. Skaffa certifikat
|
||||
sudo certbot --nginx -d boc.aamos.com
|
||||
|
||||
# 4. Starta om nginx
|
||||
sudo systemctl restart nginx
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🟡 HÖG PRIORITET
|
||||
|
||||
### 2. Rate Limiting (finns redan i koden!)
|
||||
|
||||
**Status:** ✅ Redan implementerat i `middleware/security.go`
|
||||
|
||||
**Aktivera:** Lägg till i `main.go`:
|
||||
|
||||
```go
|
||||
// Efter r := chi.NewRouter()
|
||||
rateLimiter := middleware.NewRateLimiter()
|
||||
r.Use(middleware.RateLimit(rateLimiter))
|
||||
```
|
||||
|
||||
### 3. CORS — Begränsa origins
|
||||
|
||||
**Fil:** `middleware/cors.go` (skapa om den saknas)
|
||||
|
||||
```go
|
||||
package middleware
|
||||
|
||||
import "net/http"
|
||||
|
||||
func CORS(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
allowedOrigins := map[string]bool{
|
||||
"https://boc.aamos.com": true,
|
||||
"https://admin.landvex.com": true,
|
||||
"https://landvex.com": true,
|
||||
"http://localhost:3000": true, // Dev only
|
||||
}
|
||||
|
||||
origin := r.Header.Get("Origin")
|
||||
if allowedOrigins[origin] {
|
||||
w.Header().Set("Access-Control-Allow-Origin", origin)
|
||||
}
|
||||
|
||||
w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
|
||||
w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")
|
||||
w.Header().Set("Access-Control-Max-Age", "86400")
|
||||
|
||||
if r.Method == "OPTIONS" {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
return
|
||||
}
|
||||
|
||||
next.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
### 4. Auth — RS256 (redan fixat!)
|
||||
|
||||
**Status:** ✅ Fungerar — returnerar 401 utan token
|
||||
|
||||
---
|
||||
|
||||
## 🟢 MEDEL PRIORITET
|
||||
|
||||
### 5. Connection Pooling
|
||||
|
||||
**Fil:** `db/db.go`
|
||||
|
||||
Lägg till efter `sql.Open`:
|
||||
|
||||
```go
|
||||
db.SetMaxOpenConns(25)
|
||||
db.SetMaxIdleConns(10)
|
||||
db.SetConnMaxLifetime(5 * time.Minute)
|
||||
```
|
||||
|
||||
### 6. Miljövariabler — Secrets
|
||||
|
||||
**Nuvarande:** Lösenord i `.env`
|
||||
|
||||
**Bör vara:** Använd AWS Secrets Manager eller HashiCorp Vault:
|
||||
|
||||
```bash
|
||||
# Hämta secret vid runtime
|
||||
export DB_PASSWORD=$(aws secretsmanager get-secret-value --secret-id boc/db-password --query SecretString --output text)
|
||||
```
|
||||
|
||||
### 7. Swagger UI
|
||||
|
||||
**Status:** ✅ JSON finns, UI saknas
|
||||
|
||||
**Fix:** Lägg till i `main.go`:
|
||||
|
||||
```go
|
||||
r.Get("/swagger.json", func(w http.ResponseWriter, r *http.Request) {
|
||||
http.ServeFile(w, r, "./docs/swagger.json")
|
||||
})
|
||||
r.Get("/docs", func(w http.ResponseWriter, r *http.Request) {
|
||||
http.ServeFile(w, r, "./docs/index.html")
|
||||
})
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📋 SAMMANSTÄLLNING
|
||||
|
||||
| # | Fix | Status | Fil |
|
||||
|---|-----|--------|-----|
|
||||
| 1 | HTTPS/TLS | ❌ Kräver nginx + certbot | Server-konfig |
|
||||
| 2 | Rate limiting | ✅ Klar (finns i koden) | `middleware/security.go` |
|
||||
| 3 | CORS | ⚠️ Kräver uppdatering | `middleware/cors.go` |
|
||||
| 4 | RS256 Auth | ✅ Klar | `auth/rs256.go` |
|
||||
| 5 | Connection pool | ⚠️ Enkel fix | `db/db.go` |
|
||||
| 6 | Secrets | ⚠️ Kräver AWS/Vault | `.env` |
|
||||
| 7 | Swagger UI | ⚠️ Lägg till route | `main.go` |
|
||||
|
||||
---
|
||||
|
||||
## 🎯 REKOMMENDATION
|
||||
|
||||
**Gör #1 (HTTPS) först** — det är den enda kritiska säkerhetsbristen. Resten kan vänta.
|
||||
|
||||
**Tidsuppskattning:**
|
||||
- HTTPS: 30 minuter
|
||||
- Rate limiting: 5 minuter (redan klart)
|
||||
- CORS: 10 minuter
|
||||
- Connection pool: 5 minuter
|
||||
- Swagger UI: 10 minuter
|
||||
|
||||
**Totalt: ~1 timme**
|
||||
Reference in New Issue
Block a user