В связи с уходом Microsoft из России у многих возник вопрос о переносе службы каталогов на open-source или решения из реестра отечественного ПО. Одним из доступных решений является FreeIPA. Проект живет при поддержке RedHat и доступен в репозиториях отечественных операционных систем.

В этой статье мы рассмотрим перенос учетных записей с нужными нам атрибутами из Active Directory в FreeIPA 4.10.1. В качестве инструмента мы будем использовать PowerShell 5.1, так как кроме него и установленного модуля для работы с AD нам по сути ничего и не потребуется.

Для начала потребуется создать шаблон вызова метода API в формате json. В данной статье мы будем создавать staged учетные записи. Все методы для API описаны: IPA Server‑API Browser. В шаблоне нам необходимо сопоставить соответствующие атрибуты объектов.

{
  "method": "stageuser_add",
  "params": [
    [
      "$($ADUser.SamAccountName)"
    ],
    {
      "givenname": "$($ADUser.GivenName)",
      "sn": "$($ADUser.Surname)",
      "cn": "$($ADUser.Name)",
      "mail": "$($ADUser.mail)",
      "title": "$($ADUser.title)",
      "employeenumber": "$($ADUser.employeeNumber)",
      "telephonenumber": "$($ADUser.telephoneNumber)",
      "mobile": "$($ADUser.mobile)",
      "ou": "$($ADUser.department)"
    }
  ]
}

При использовании PowerShell в качестве REST клиента могут возникнуть проблемы с недоверенным сертификатом сервера FreeIPA. В данной статье мы не будем устанавливать сертификаты на машину с PowerShell, нам будет достаточно игнорировать недоверенный сертификат. Начиная c PowerShell 6 при вызове REST запроса, достаточно добавить параметр -SkipCertificateCheck. Для более младших версий, применим политику:

# Apply policy to trust all certificates
add-type @"
 using System.Net;
 using System.Security.Cryptography.X509Certificates;
 public class TrustAllCertsPolicy : ICertificatePolicy {
 public bool CheckValidationResult(
 ServicePoint srvPoint, X509Certificate certificate,
 WebRequest request, int certificateProblem) {
 return true;
 }
 }
"@
[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]'Ssl3,Tls,Tls11,Tls12'

Занесем в переменные: Base DN с учетными записями Active Directory, FQDN сервера FreeIPA и путь к json файлу c шаблоном метода API FreeIPA. Так же создадим новую сессию.

$BaseDN = "OU=Users,DC=local,DC=example,DC=domain"
$FreeIPAFqdn ="freeipa.example.domain"
$Json = ".\stageuser_add.json"

# New web session
$RestSession = New-Object Microsoft.PowerShell.Commands.WebRequestSession

Выгружаем пользователей из Active Directory с нужными нам атрибутами

# Get Active Directory users
$OrganizationalUnit = Get-ADOrganizationalUnit -Identity $BaseDN
$ADUsers = Get-ADUser -Filter * -SearchBase $OrganizationalUnit -Properties employeeNumber,
    title,mail,department,telephoneNumber,mobile

Заносим в переменную учетные данные администратора FreeIPA

# Get FreeIPA credentials
$FreeIPACredentials = Get-Credential -Message "FreeIPA log in with username and password"

Создадим функцию авторизации в API

function Invoke-FreeIPALogin {
    param(
        [parameter(Mandatory = $True)]$Session,
        [parameter(Mandatory = $True)][string]$Fqdn,
        [parameter(Mandatory = $True)][PSCredential]$Credentials
    )
    process {
        $Credentials.Password | ConvertFrom-SecureString 
        $User = $Credentials.UserName
        $Password = $Credentials.GetNetworkCredential().Password
        $Body = @{"user" = "$($User)"; "password" = "$($Password)"}
        $Header = @{"Content-Type" = "application/x-www-form-urlencoded"; "Accept" = "application/json"}
        Invoke-RestMethod -Uri "https://$($Fqdn)/ipa/session/login_password" -Method POST -Body $Body `
            -WebSession $Session -Headers $Header
    }
}

Далее нам потребуется функция вызова метода API

function Invoke-FreeIPARequest {
    param(
        [parameter(Mandatory = $True)]$Session,
        [parameter(Mandatory = $True)][string]$Fqdn,
        [parameter(Mandatory = $True)][string]$Body
    )
    process {
        $Header = @{"Referer" = "https://$($Fqdn)/ipa"; "Accept" = "application/json"}
        $Type = "application/json; charset=utf-8"
        $Request = Invoke-RestMethod -Uri "https://$($Fqdn)/ipa/session/json" -WebSession $Session `
            -Method POST -Body $Body -Headers $Header -ContentType $Type
        return $Request
    }
}

Теперь можно авторизоваться в API и создать новых пользователей FreeIPA по шаблону созданному ранее

# Login to FreeIPA
try {
    Invoke-FreeIPALogin -Session $RestSession -Fqdn $FreeIPAFqdn -Credentials $FreeIPACredentials
}
catch {
    Write-Host $_ -BackgroundColor Red
    exit 1
}

# Transfer users to FreeIPA
foreach ($ADUser in $ADUsers) {
	Invoke-Expression ('$Body = @"' + "`n" + (Get-Content $Json -Encoding UTF8 | ForEach-Object {$_ + "`n"}) + "`n" + '"@')
    try {
        $Request = Invoke-FreeIPARequest -Session $RestSession -Fqdn $FreeIPAFqdn -Body $Body
        Write-Host ($Request.Result)
    }
    catch {
        Write-Host $_ -BackgroundColor Red
        continue 
    }
}

На этом наша работа завершена. По аналогии можно выгружать любые данные из Active Directory и, используя методы API, создавать объекты в службе каталогов FreeIPA.

Комментарии (3)


  1. nnstepan
    06.09.2023 14:54
    +2

    А чем FreeIPA лучше samba 4?


  1. wertex15
    06.09.2023 14:54

    А когда ипа стала реестровой?


    1. Johan_Palych
      06.09.2023 14:54

      Тут в составе.