Build [v1.9.12] (Secure Seal & LDAP Sync: Custom Caddy & Config Volume)

This commit is contained in:
Daniel Bedeleanu
2026-04-13 22:25:19 +03:00
parent 9d7e4f0ca3
commit ee7e7b7bd7
6 changed files with 78 additions and 29 deletions

View File

@@ -73,6 +73,11 @@ def authenticate_ldap(username, password):
return None
real_user_dn = conn.entries[0].entry_dn
user_groups = []
if hasattr(conn.entries[0], 'memberOf'):
user_groups = [str(g).lower() for g in conn.entries[0].memberOf.values]
log.debug(f"LDAP: Found memberOf groups on user: {user_groups}")
log.debug(f"LDAP: Canonical DN found: {real_user_dn}")
# Check roles based on group membership
@@ -87,27 +92,39 @@ def authenticate_ldap(username, password):
groups_dn = config.get("groups_dn", "ou=groups")
# Iterate through mappings to find the highest role
# Priority: admin > user
potential_roles = []
for mapping in role_mappings:
group_name = mapping["group"]
target_role = mapping["role"]
# Construct group DN if it's just a common name, else use as is
# Construct group DN if it's just a common name
if "=" not in group_name:
full_group_dn = f"cn={group_name},{groups_dn},{base_dn}"
else:
full_group_dn = group_name
log.debug(f"LDAP: Checking membership in group: {full_group_dn}")
conn.search(full_group_dn, '(objectClass=*)', attributes=['member'])
full_group_dn_lower = full_group_dn.lower()
log.debug(f"LDAP: Checking membership in group: {full_group_dn}")
# Method 1: Check memberOf if available (AD/LLDAP)
if full_group_dn_lower in user_groups:
log.debug(f"LDAP: Match found via memberOf for {target_role}")
potential_roles.append(target_role)
continue
# Method 2: Search group's member attribute (Standard LDAP)
conn.search(full_group_dn, '(objectClass=*)', attributes=['member', 'uniqueMember'])
if conn.entries:
members = conn.entries[0].member.values
if real_user_dn in members or user_dn in members or \
any(m.lower().replace(" ", "") == real_user_dn.lower().replace(" ", "") for m in members):
log.debug(f"LDAP: User is in group {group_name}, assigning role: {target_role}")
members = []
if hasattr(conn.entries[0], 'member'):
members = [str(m).lower() for m in conn.entries[0].member.values]
elif hasattr(conn.entries[0], 'uniqueMember'):
members = [str(m).lower() for m in conn.entries[0].uniqueMember.values]
if real_user_dn.lower() in members or user_dn.lower() in members:
log.debug(f"LDAP: Match found via group search for {target_role}")
potential_roles.append(target_role)
if "admin" in potential_roles:

View File

@@ -1,21 +1,35 @@
# TFM aInventory - Caddy Explicit IP Configuration
# Version 1.9.10 - Focused on resolving Protocol Errors on private IPs.
# TFM aInventory - Caddy Patched IP Configuration
# Version 1.9.12 - Secure Seal & IP Stability
{
admin off
admin off
auto_https disable_redirects
auto_https disable_redirects
# Trust local CA for internal certificate issuance
local_certs
}
# Frontend SSL Proxy (8919 -> 443)
https://{$SERVER_IP:192.168.84.113}:443 {
https://{$SERVER_IP:192.168.84.113}:443 {
tls internal {
reverse_proxy frontend:3000
on_demand
}
reverse_proxy frontend:3000
# Security Headers for PWA
header {
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
X-XSS-Protection "1; mode=block"
X-Content-Type-Options "nosniff"
X-Frame-Options "SAMEORIGIN"
Referrer-Policy "strict-origin-when-cross-origin"
}
}
# Backend SSL Proxy (8918 -> 444)
https://{$SERVER_IP:192.168.84.113}:444 {
https://{$SERVER_IP:192.168.84.113}:444 {
tls internal {
reverse_proxy backend:8000
on_demand
}
reverse_proxy backend:8000
}
}

8
config/proxy/Dockerfile Normal file
View File

@@ -0,0 +1,8 @@
FROM caddy:2-alpine
# Install nss-tools to allow Caddy to manage its internal trust store (fixes certutil warning)
# Install ca-certificates to ensure Caddy can trust external sites if needed
RUN apk add --no-cache nss-tools ca-certificates
# Expose the internal proxy ports
EXPOSE 80 443 444

View File

@@ -1,6 +1,6 @@
#!/bin/bash
# =============================================================================
# TFM aInventory - Bulletproof Deployment Script (v1.9.10)
# TFM aInventory - Bulletproof Deployment Script (v1.9.12)
# =============================================================================
set -e
@@ -30,7 +30,7 @@ for arg in "$@"; do
--help)
echo "Usage: ./deploy.sh [options]"
echo "Options:"
echo " --reset-ssl Clear Caddy storage and reset certificates"
echo " --reset-ssl Clear Caddy storage and reset certificates (Aggressive)"
echo " --reset-admin Force reset Admin password to 'Admin123!'"
echo " --help Show this help message"
exit 0
@@ -39,19 +39,25 @@ for arg in "$@"; do
done
if [ "$RESET_SSL" = true ]; then
echo "🧹 Resetting SSL certificates..."
echo "🧹 Aggressive SSL Reset in progress..."
docker compose down
# Clear internal docker volumes
docker volume rm -f inventory_caddy_data 2>/dev/null || true
echo "✅ SSL data cleared."
docker volume rm -f inventory_caddy_config 2>/dev/null || true
# Clear persistent host volumes if they exist
rm -rf ./data/caddy_data/* 2>/dev/null || true
rm -rf ./data/caddy_config/* 2>/dev/null || true
echo "✅ SSL storage completely cleared."
fi
echo "🚀 Starting TFM aInventory Services..."
# Use --build to ensure the custom Caddy image is built
docker compose --env-file inventory.env up -d --build --remove-orphans
if [ "$RESET_ADMIN" = true ]; then
echo "🔐 Resetting Admin credentials..."
# Wait for container to be ready
sleep 2
sleep 3
docker compose exec backend python3 -m backend.scripts.reset_admin
fi
@@ -60,17 +66,18 @@ echo "🔍 Verifying port mapping..."
docker compose ps --format "table {{.Name}}\t{{.Status}}\t{{.Ports}}"
echo ""
echo "🚀 DIAGNOSTIC LOGS (Proxy SSL Handshake):"
echo "🚀 DIAGNOSTIC LOGS (Proxy Status):"
docker compose logs proxy --tail 20
echo ""
echo "✅ Deployment complete."
echo "✅ Deployment complete (v1.9.12)."
echo " ------------------------------------------------------------"
echo " DEFAULT CREDENTIALS:"
echo " ACCESS COORDINATES:"
echo " 1. SECURE: https://${SERVER_IP:-localhost}:${FRONTEND_SSL_PORT:-8919}"
echo " 2. DIRECT: http://${SERVER_IP:-localhost}:${FRONTEND_PORT:-8917}"
echo " ------------------------------------------------------------"
echo " CREDENTIALS (if first run or reset):"
echo " User: Admin"
echo " Pass: Admin123!"
echo " ------------------------------------------------------------"
echo " 1. SECURE ACCESS: https://${SERVER_IP:-localhost}:${FRONTEND_SSL_PORT:-8919}"
echo " 2. DIRECT ACCESS: http://${SERVER_IP:-localhost}:${FRONTEND_PORT:-8917}"
echo " ------------------------------------------------------------"
echo ""

View File

@@ -12,6 +12,7 @@ services:
volumes:
- ./data:/app/data
- ./logs:/app/logs
- ./config:/app/config
- ./scripts:/app/scripts:ro
environment:
- DATA_DIR=/app/data
@@ -36,7 +37,9 @@ services:
restart: unless-stopped
proxy:
image: caddy:alpine
build:
context: .
dockerfile: config/proxy/Dockerfile
networks:
- inventory_net
ports:

View File

@@ -1 +1 @@
{"version": "1.9.10", "last_build": "2026-04-13-2207", "codename": "AccessRecovery", "commit": "bdf6d605"}
{"version": "1.9.11", "last_build": "2026-04-13-2215", "codename": "Convergence", "commit": "9d7e4f0c"}