diff --git a/Setup-ByteTrail-AD.ps1 b/Setup-ByteTrail-AD.ps1 new file mode 100644 index 0000000..8dd74fd --- /dev/null +++ b/Setup-ByteTrail-AD.ps1 @@ -0,0 +1,238 @@ +# ============================================================ +# ByteTrail GmbH – Active Directory Setup Script +# Domäne: bytetrail.local +# Erstellt: Team 3 VZ | FH Burgenland | SS 2026 +# Ausführen auf: SRV-DC01 als Domain Admin +# ============================================================ + +#region KONFIGURATION +$Domain = "bytetrail.local" +$DomainDN = "DC=bytetrail,DC=local" +$MailDomain = "byte.trail" +$DefaultPW = ConvertTo-SecureString "ByteTrail2026!" -AsPlainText -Force +#endregion + +Write-Host "`n=== ByteTrail AD Setup gestartet ===" -ForegroundColor Cyan + +# ============================================================ +# 1. OU-STRUKTUR +# ============================================================ +Write-Host "`n[1/3] Erstelle OU-Struktur..." -ForegroundColor Yellow + +$OUs = @( + "OU=Geschaeftsfuehrung,$DomainDN", + "OU=Sales,$DomainDN", + "OU=Marketing,$DomainDN", + "OU=Service,$DomainDN", + "OU=Server,$DomainDN", + "OU=Gruppen,$DomainDN" +) + +foreach ($OU in $OUs) { + $OUName = ($OU -split ",")[0] -replace "OU=", "" + if (-not (Get-ADOrganizationalUnit -Filter "DistinguishedName -eq '$OU'" -ErrorAction SilentlyContinue)) { + New-ADOrganizationalUnit -Name $OUName -Path $DomainDN -ProtectedFromAccidentalDeletion $true + Write-Host " [+] OU erstellt: $OUName" -ForegroundColor Green + } else { + Write-Host " [~] OU existiert bereits: $OUName" -ForegroundColor Gray + } +} + +# ============================================================ +# 2. AD-GRUPPEN +# ============================================================ +Write-Host "`n[2/3] Erstelle AD-Gruppen..." -ForegroundColor Yellow + +$Groups = @( + # Name Beschreibung + @("GRP-GF-VOLLZUGRIFF", "Geschäftsführung – Vollzugriff"), + @("GRP-GF-VPN", "Geschäftsführung – VPN-Zugang"), + @("GRP-GF-ERP", "Geschäftsführung – ERP-Zugriff"), + @("GRP-SALES-ERP", "Sales – ERP-Zugriff"), + @("GRP-SALES-VPN", "Sales – VPN-Zugang"), + @("GRP-SALES-FILES", "Sales – Dateifreigabe"), + @("GRP-MKT-FILES", "Marketing – Dateifreigabe"), + @("GRP-SVC-FILES", "Service/Technik – Dateifreigabe"), + @("GRP-SVC-ERP", "Service/Technik – ERP-Zugriff (tlw.)"), + @("GRP-ALL-EMAIL", "Alle Mitarbeiter – E-Mail"), + @("GRP-ADMINS", "IT-Administratoren") +) + +foreach ($Group in $Groups) { + if (-not (Get-ADGroup -Filter "Name -eq '$($Group[0])'" -ErrorAction SilentlyContinue)) { + New-ADGroup ` + -Name $Group[0] ` + -SamAccountName $Group[0] ` + -GroupScope Global ` + -GroupCategory Security ` + -Description $Group[1] ` + -Path "OU=Gruppen,$DomainDN" + Write-Host " [+] Gruppe erstellt: $($Group[0])" -ForegroundColor Green + } else { + Write-Host " [~] Gruppe existiert bereits: $($Group[0])" -ForegroundColor Gray + } +} + +# ============================================================ +# 3. BENUTZER +# ============================================================ +Write-Host "`n[3/3] Erstelle Benutzer..." -ForegroundColor Yellow + +# Schema: Vorname, Nachname, Abteilung, OU, Gruppen[] +$Users = @( + + # --- Geschäftsführung (1 MA) --- + @{ + Vorname = "Thomas" + Nachname = "Maier" + Abt = "Geschaeftsfuehrung" + OU = "OU=Geschaeftsfuehrung,$DomainDN" + Gruppen = @("GRP-GF-VOLLZUGRIFF","GRP-GF-VPN","GRP-GF-ERP","GRP-ALL-EMAIL") + Title = "Geschäftsführer" + }, + + # --- Sales / Vertrieb (2 MA) --- + @{ + Vorname = "Anna" + Nachname = "Huber" + Abt = "Sales" + OU = "OU=Sales,$DomainDN" + Gruppen = @("GRP-SALES-ERP","GRP-SALES-VPN","GRP-SALES-FILES","GRP-ALL-EMAIL") + Title = "Vertriebsmitarbeiterin" + }, + @{ + Vorname = "Markus" + Nachname = "Reiter" + Abt = "Sales" + OU = "OU=Sales,$DomainDN" + Gruppen = @("GRP-SALES-ERP","GRP-SALES-VPN","GRP-SALES-FILES","GRP-ALL-EMAIL") + Title = "Vertriebsmitarbeiter" + }, + + # --- Marketing (2 MA) --- + @{ + Vorname = "Julia" + Nachname = "Wagner" + Abt = "Marketing" + OU = "OU=Marketing,$DomainDN" + Gruppen = @("GRP-MKT-FILES","GRP-ALL-EMAIL") + Title = "Marketingmitarbeiterin" + }, + @{ + Vorname = "Stefan" + Nachname = "Bauer" + Abt = "Marketing" + OU = "OU=Marketing,$DomainDN" + Gruppen = @("GRP-MKT-FILES","GRP-ALL-EMAIL") + Title = "Marketingmitarbeiter" + }, + + # --- Service / Technik (25 MA) --- + # Techniker mit ERP-Zugriff (5 MA) + @{ Vorname="Klaus"; Nachname="Schneider"; Abt="Service"; OU="OU=Service,$DomainDN"; Gruppen=@("GRP-SVC-FILES","GRP-SVC-ERP","GRP-ALL-EMAIL"); Title="Techniker" }, + @{ Vorname="Peter"; Nachname="Fischer"; Abt="Service"; OU="OU=Service,$DomainDN"; Gruppen=@("GRP-SVC-FILES","GRP-SVC-ERP","GRP-ALL-EMAIL"); Title="Techniker" }, + @{ Vorname="Michael"; Nachname="Weber"; Abt="Service"; OU="OU=Service,$DomainDN"; Gruppen=@("GRP-SVC-FILES","GRP-SVC-ERP","GRP-ALL-EMAIL"); Title="Techniker" }, + @{ Vorname="Andreas"; Nachname="Müller"; Abt="Service"; OU="OU=Service,$DomainDN"; Gruppen=@("GRP-SVC-FILES","GRP-SVC-ERP","GRP-ALL-EMAIL"); Title="Techniker" }, + @{ Vorname="Christian";Nachname="Schmidt"; Abt="Service"; OU="OU=Service,$DomainDN"; Gruppen=@("GRP-SVC-FILES","GRP-SVC-ERP","GRP-ALL-EMAIL"); Title="Techniker" }, + + # Techniker ohne ERP (20 MA) + @{ Vorname="David"; Nachname="Hoffmann"; Abt="Service"; OU="OU=Service,$DomainDN"; Gruppen=@("GRP-SVC-FILES","GRP-ALL-EMAIL"); Title="Servicemitarbeiter" }, + @{ Vorname="Felix"; Nachname="Schäfer"; Abt="Service"; OU="OU=Service,$DomainDN"; Gruppen=@("GRP-SVC-FILES","GRP-ALL-EMAIL"); Title="Servicemitarbeiter" }, + @{ Vorname="Georg"; Nachname="Koch"; Abt="Service"; OU="OU=Service,$DomainDN"; Gruppen=@("GRP-SVC-FILES","GRP-ALL-EMAIL"); Title="Servicemitarbeiter" }, + @{ Vorname="Hans"; Nachname="Becker"; Abt="Service"; OU="OU=Service,$DomainDN"; Gruppen=@("GRP-SVC-FILES","GRP-ALL-EMAIL"); Title="Servicemitarbeiter" }, + @{ Vorname="Josef"; Nachname="Wolf"; Abt="Service"; OU="OU=Service,$DomainDN"; Gruppen=@("GRP-SVC-FILES","GRP-ALL-EMAIL"); Title="Servicemitarbeiter" }, + @{ Vorname="Karl"; Nachname="Braun"; Abt="Service"; OU="OU=Service,$DomainDN"; Gruppen=@("GRP-SVC-FILES","GRP-ALL-EMAIL"); Title="Servicemitarbeiter" }, + @{ Vorname="Leon"; Nachname="Schwarz"; Abt="Service"; OU="OU=Service,$DomainDN"; Gruppen=@("GRP-SVC-FILES","GRP-ALL-EMAIL"); Title="Servicemitarbeiter" }, + @{ Vorname="Martin"; Nachname="Zimmermann";Abt="Service"; OU="OU=Service,$DomainDN"; Gruppen=@("GRP-SVC-FILES","GRP-ALL-EMAIL"); Title="Servicemitarbeiter" }, + @{ Vorname="Nico"; Nachname="Krause"; Abt="Service"; OU="OU=Service,$DomainDN"; Gruppen=@("GRP-SVC-FILES","GRP-ALL-EMAIL"); Title="Servicemitarbeiter" }, + @{ Vorname="Oliver"; Nachname="Richter"; Abt="Service"; OU="OU=Service,$DomainDN"; Gruppen=@("GRP-SVC-FILES","GRP-ALL-EMAIL"); Title="Servicemitarbeiter" }, + @{ Vorname="Paul"; Nachname="Klein"; Abt="Service"; OU="OU=Service,$DomainDN"; Gruppen=@("GRP-SVC-FILES","GRP-ALL-EMAIL"); Title="Servicemitarbeiter" }, + @{ Vorname="Robert"; Nachname="Werner"; Abt="Service"; OU="OU=Service,$DomainDN"; Gruppen=@("GRP-SVC-FILES","GRP-ALL-EMAIL"); Title="Servicemitarbeiter" }, + @{ Vorname="Simon"; Nachname="Neumann"; Abt="Service"; OU="OU=Service,$DomainDN"; Gruppen=@("GRP-SVC-FILES","GRP-ALL-EMAIL"); Title="Servicemitarbeiter" }, + @{ Vorname="Thomas"; Nachname="Lange"; Abt="Service"; OU="OU=Service,$DomainDN"; Gruppen=@("GRP-SVC-FILES","GRP-ALL-EMAIL"); Title="Servicemitarbeiter" }, + @{ Vorname="Ulrich"; Nachname="Scholz"; Abt="Service"; OU="OU=Service,$DomainDN"; Gruppen=@("GRP-SVC-FILES","GRP-ALL-EMAIL"); Title="Servicemitarbeiter" }, + @{ Vorname="Viktor"; Nachname="Peters"; Abt="Service"; OU="OU=Service,$DomainDN"; Gruppen=@("GRP-SVC-FILES","GRP-ALL-EMAIL"); Title="Servicemitarbeiter" }, + @{ Vorname="Walter"; Nachname="Vogel"; Abt="Service"; OU="OU=Service,$DomainDN"; Gruppen=@("GRP-SVC-FILES","GRP-ALL-EMAIL"); Title="Servicemitarbeiter" }, + @{ Vorname="Xaver"; Nachname="Keller"; Abt="Service"; OU="OU=Service,$DomainDN"; Gruppen=@("GRP-SVC-FILES","GRP-ALL-EMAIL"); Title="Servicemitarbeiter" }, + @{ Vorname="Yannick"; Nachname="Frank"; Abt="Service"; OU="OU=Service,$DomainDN"; Gruppen=@("GRP-SVC-FILES","GRP-ALL-EMAIL"); Title="Servicemitarbeiter" } +) + +foreach ($User in $Users) { + # Benutzername: vorname.nachname (Umlaute ersetzen) + $Sam = ($User.Vorname + "." + $User.Nachname).ToLower() + $Sam = $Sam -replace "ä","ae" -replace "ö","oe" -replace "ü","ue" -replace "ß","ss" + + $UPN = "$Sam@$Domain" + $EmailAddr = "$Sam@$MailDomain" + + if (-not (Get-ADUser -Filter "SamAccountName -eq '$Sam'" -ErrorAction SilentlyContinue)) { + New-ADUser ` + -SamAccountName $Sam ` + -UserPrincipalName $UPN ` + -GivenName $User.Vorname ` + -Surname $User.Nachname ` + -Name "$($User.Vorname) $($User.Nachname)" ` + -DisplayName "$($User.Vorname) $($User.Nachname)" ` + -Department $User.Abt ` + -Title $User.Title ` + -EmailAddress $EmailAddr ` + -Path $User.OU ` + -AccountPassword $DefaultPW ` + -PasswordNeverExpires $false ` + -ChangePasswordAtLogon $true ` + -Enabled $true + + Write-Host " [+] User erstellt: $Sam ($($User.Abt))" -ForegroundColor Green + } else { + Write-Host " [~] User existiert bereits: $Sam" -ForegroundColor Gray + } + + # Gruppen zuweisen + foreach ($Gruppe in $User.Gruppen) { + try { + Add-ADGroupMember -Identity $Gruppe -Members $Sam -ErrorAction Stop + } catch { + Write-Warning " Gruppe '$Gruppe' konnte nicht zugewiesen werden: $_" + } + } +} + +# ============================================================ +# 4. SERVICE-ACCOUNT FÜR MAILSERVER (LDAP-Bind) +# ============================================================ +Write-Host "`n[4/4] Erstelle Service-Account für Mailserver..." -ForegroundColor Yellow + +$SvcSam = "svc-mailserver" +$SvcUPN = "$SvcSam@$Domain" +$SvcPW = ConvertTo-SecureString "Mail$3rv!ceAcc2026" -AsPlainText -Force + +if (-not (Get-ADUser -Filter "SamAccountName -eq '$SvcSam'" -ErrorAction SilentlyContinue)) { + New-ADUser ` + -SamAccountName $SvcSam ` + -UserPrincipalName $SvcUPN ` + -Name "Mailserver Service Account" ` + -DisplayName "Mailserver Service Account" ` + -Description "Service-Account fuer Docker-Mailserver LDAP-Bind" ` + -Path "OU=Server,$DomainDN" ` + -AccountPassword $SvcPW ` + -PasswordNeverExpires $true ` + -ChangePasswordAtLogon $false ` + -CannotChangePassword $true ` + -Enabled $true + Write-Host " [+] Service-Account erstellt: $SvcSam" -ForegroundColor Green +} else { + Write-Host " [~] Service-Account existiert bereits: $SvcSam" -ForegroundColor Gray +} + +# ============================================================ +# ZUSAMMENFASSUNG +# ============================================================ +Write-Host "`n=== Setup abgeschlossen ===" -ForegroundColor Cyan +Write-Host "OUs: $($OUs.Count) erstellt" -ForegroundColor White +Write-Host "Gruppen: $($Groups.Count) erstellt" -ForegroundColor White +Write-Host "User: $($Users.Count) erstellt (+ 1 Service-Account)" -ForegroundColor White +Write-Host "`nStandard-Passwort User: ByteTrail2026! (Benutzer muessen es beim ersten Login aendern)" -ForegroundColor Yellow +Write-Host "Service-Account Mailserver: $SvcSam / Mail`$3rv!ceAcc2026" -ForegroundColor Yellow +Write-Host "Mail-Domain: $MailDomain" -ForegroundColor White +Write-Host "AD-Domaene: $Domain" -ForegroundColor White +Write-Host "" diff --git a/docker-compose.yml b/docker-compose.yml index 64bd492..4d479cd 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -3,7 +3,7 @@ services: image: ghcr.io/docker-mailserver/docker-mailserver:latest container_name: mailserver # Provide the FQDN of your mail server here (Your DNS MX record should point to this value) - hostname: mail.example.com + hostname: mail.byte.trail env_file: mailserver.env # More information about the mail-server ports: # https://docker-mailserver.github.io/docker-mailserver/latest/config/security/understanding-the-ports/ @@ -37,7 +37,7 @@ services: environment: ACCEPT_EULA: "Y" - MSSQL_SA_PASSWORD: "YourStrongPassword123!" + MSSQL_SA_PASSWORD: "ByteTrail123456!" MSSQL_PID: "Developer" ports: diff --git a/mailserver.env b/mailserver.env index bd76504..11a7e26 100644 --- a/mailserver.env +++ b/mailserver.env @@ -44,7 +44,7 @@ ACCOUNT_PROVISIONER=LDAP # empty => postmaster@domain.com # => Specify the postmaster address -POSTMASTER_ADDRESS= +POSTMASTER_ADDRESS=postmaster@byte.trail # Check for updates on container start and then once a day # If an update is available, a mail is sent to POSTMASTER_ADDRESS @@ -240,7 +240,7 @@ SMTP_ONLY= # custom => Enables custom certificates # manual => Let's you manually specify locations of your SSL certificates for non-standard cases # self-signed => Enables self-signed certificates -SSL_TYPE= +SSL_TYPE=letsencrypt # These are only supported with `SSL_TYPE=manual`. # Provide the path to your cert and key files that you've mounted access to within the container. @@ -460,19 +460,19 @@ LDAP_START_TLS=yes # empty => mail.example.com # Specify the `` / `` where the LDAP server is reachable via a URI like: `ldaps://mail.example.com`. # Note: You must include the desired URI scheme (`ldap://`, `ldaps://`, `ldapi://`). -LDAP_SERVER_HOST=10.10.10.10 +LDAP_SERVER_HOST=ldap://10.10.10.10 # empty => ou=people,dc=domain,dc=com # => e.g. LDAP_SEARCH_BASE=dc=mydomain,dc=local -LDAP_SEARCH_BASE= +LDAP_SEARCH_BASE=DC=bytetrail,DC=local # empty => cn=admin,dc=domain,dc=com # => take a look at examples of SASL_LDAP_BIND_DN -LDAP_BIND_DN= +LDAP_BIND_DN=CN=Mailserver Service Account,OU=Server,DC=bytetrail,DC=local # empty** => admin # => Specify the password to bind against ldap -LDAP_BIND_PW= +LDAP_BIND_PW=ByteTrail123456! # e.g. `"(&(mail=%s)(mailEnabled=TRUE))"` # => Specify how ldap should be asked for users @@ -496,13 +496,13 @@ LDAP_QUERY_FILTER_DOMAIN=(mail=*@%s) # empty => no # yes => LDAP over TLS enabled for Dovecot -DOVECOT_TLS= +DOVECOT_TLS=yes # e.g. `"(&(objectClass=PostfixBookMailAccount)(uniqueIdentifier=%n))"` -DOVECOT_USER_FILTER= +DOVECOT_USER_FILTER=(&(objectClass=person)(mail=%u)) # e.g. `"(&(objectClass=PostfixBookMailAccount)(uniqueIdentifier=%n))"` -DOVECOT_PASS_FILTER= +DOVECOT_PASS_FILTER=(&(objectClass=person)(mail=%u)) # Define the mailbox format to be used # default is maildir, supported values are: sdbox, mdbox, maildir @@ -511,7 +511,7 @@ DOVECOT_MAILBOX_FORMAT=maildir # empty => no # yes => Allow bind authentication for LDAP # https://doc.dovecot.org/2.4.0/core/config/auth/databases/ldap.html#authentication-bind -DOVECOT_AUTH_BIND= +DOVECOT_AUTH_BIND=yes # ----------------------------------------------- # --- Postgrey Section --------------------------