Цель нашей лабораторной получить сертификат от доверенного центра сертификации для Skype For Business 2015:
1. Выбор доверенного центра сертификации
. Let’s Encrypt
2. Выбрать способ проверки для получения сертификата
. Windows DNS Server / Yandex PDD
3. Определить список доменов в сертификате
. sfb.contoso.ru,lyncdiscoverinternal.contoso.ru,web.contoso.ru,contoso.ru
4. Получить сертификат
. ACMESharp
. DNSServer module
. Yandex API
5. Установить сертификат на сервер Skype For Business 2015
. Import-CsCertificate
. Set-CsCertificate
. Get-CsCertificate
* В сертификате от Let’s Encrypt отсутствует CRL , поэтому может возникнуть проблема с запуском сервиса Fabric и требуется исправление ключа — <Parameter Name=”CrlCheckingFlag” Value=”0”
https://itbasedtelco.wordpress.com/2016/06/14/s4b-front-end-servers-event-4097-flooding/
1. Выбор доверенного центра сертификации
Центры сертификации WoSign и StartCom, которые ранее выдавали сертификаты с большим сроком действия от 1 до 3 лет, перестали быть доверенными компанией Microsoft (https://blogs.technet.microsoft.com/mmpc/2017/08/08/microsoft-to-remove-wosign-and-startcom-certificates-in-windows-10/) и многими другими, хотя возможность получения и покупка сертификатов возможна.
К счастью, есть доверенный центр сертификации Let’s Encrypt. Его функционала будет достаточно, для создания федерации с другими партнерами и взаимодействия с сервисом Skype. Для взаимодействия с облачными сервисами, требуется дополнительное тестирование.
Let’s Encrypt:
Стоимость — бесплатно
Сертификат действителен — 90 дней
SAN — 100 доменов
CRL — не поддерживается
OCSP — поддерживается
IDN(Internationalized Domain Names) — поддерживается
OV,EV — не поддерживается
Способ проверки — ftp,http,dns
RSA размер ключа — по умолчанию 2048 (2048, 3072, 4096)
WildCard — https://letsencrypt.org/2017/07/06/wildcard-certificates-coming-jan-2018.html
Список ограничений — https://letsencrypt.org/docs/rate-limits/
Список совместимости:
https://community.letsencrypt.org/t/which-browsers-and-operating-systems-support-lets-encrypt/4394
https://letsencrypt.org/docs/certificate-compatibility/
Сроки реализации новых функций:
https://letsencrypt.org/upcoming-features/
# IDN (Internationalized Domain Names) [System.Globalization.IdnMapping]::new().GetAscii("президент.рф") xn--d1abbgf6aiiy.xn--p1ai [System.Globalization.IdnMapping]::new().GetUnicode("xn--d1abbgf6aiiy.xn--p1ai") президент.рф
2. Выбрать способ проверки для получения сертификата
В данной лабораторной работе, для простоты был выбран способ проверки через записи DNS.
Рассмотрим вариант создания записей в бесплатном сервисе Яндекс.Почта(предоставляет функционал DNS сервера) и Windows DNS Server(должен быть опубликован в интернет).
Кому лень использовать скрипты, может с легкостью получить сертификаты через онлайн сервис — https://www.sslforfree.com/
Windows DnsServer Module — https://technet.microsoft.com/en-us/itpro/powershell/windows/dnsserver/dnsserver
Get-DnsServerResourceRecord — https://technet.microsoft.com/en-us/itpro/powershell/windows/dnsserver/get-dnsserverresourcerecord
Add-DnsServerResourceRecord — https://technet.microsoft.com/en-us/itpro/powershell/windows/dnsserver/add-dnsserverresourcerecord
Set-DnsServerResourceRecord — https://technet.microsoft.com/en-us/itpro/powershell/windows/dnsserver/set-dnsserverresourcerecord
Yandex API Управление DNS — https://tech.yandex.ru/pdd/doc/concepts/api-dns-docpage/
GET /api2/admin/dns/list? — Получить DNS-записи домена — https://tech.yandex.ru/pdd/doc/reference/dns-list-docpage/
POST /api2/admin/dns/add — Добавить DNS-запись — https://tech.yandex.ru/pdd/doc/reference/dns-add-docpage/
POST /api2/admin/dns/edit — Редактировать DNS-запись — https://tech.yandex.ru/pdd/doc/reference/dns-edit-docpage/
Как подключить себе сервис Яндекса:
https://blog.it-kb.ru/2016/02/03/delegating-dns-domain-to-yandex-ns-servers-and-connect-to-free-services-yandex-mail-for-domain-with-1000-unlimited-mailboxes-and-yandex-disk/
Все DNS записи будут типа TXT, формата:
name class rr text
_acme-challenge.domain IN TXT "123drNmQL5vX0bu4YZlgy5wKNBlCny4yrjF1lSaUndc"
3. Определить список доменов в сертификате
Требования к сертифакату для Skype For Business 2015 — https://technet.microsoft.com/en-us/library/dn933910.aspx
Воспользуемся мастером и скопируем список из вкладки Subject Alternative Name — https://blogs.technet.microsoft.com/uclobby/2015/05/15/renewing-skype-for-business-server-2015-certificates/
4. Получить сертификат
К этому пункту у нас должна быть собрана информация:
+ $DomainName = "contoso.ru"
+ $SAN = "sfb.contoso.ru","lyncdiscoverinternal.contoso.ru","web.contoso.ru","contoso.ru"
+ $email = "pki@contoso.ru"
* Yandex API — учетные данные, зарегистрированный и настроенный домен
+ — Обязательные параметры
* — Необязательные параметры
! — Все действия выполняем под учетной записью с правами Администратора
Для работы с Let’s Encrypt с помощью PowerShell , есть замечательный модуль ACMESharp.
Документация по модулю — https://pkisharp.github.io/ACMESharp-docs/
User Guide: ACMESharp PowerShell Client — https://pkisharp.github.io/ACMESharp-docs/User-Guide.html
Quick Start: ACMESharp PowerShell Client — https://pkisharp.github.io/ACMESharp-docs/Quick-Start.html
ACMESharp создает Vault , которое содержит очень чувствительные данные.
* https://github.com/ebekker/ACMESharp/wiki/Vaults,-Vault-Providers-and-Vault-Profiles
:sys — the default system-wide Vault if you are running as an elevated user (admin)
%ALLUSERSPROFILE%\ACMESharp\sysVault
:user — the default user-specific Vault if you are running as a non-elevated user
%LOCALAPPDATA%\ACMESharp\userVault
Папки:
VAULT /**/ = "00-VAULT"; // Vault Info
MTADT /**/ = "01-MTADT"; // Asset Meta Data
PRVDR /**/ = "10-PRVDR"; // Challenge Handler Provider Profile
INSTP /**/ = "18-INSTP"; // Installer Provider Profile
CSRDT /**/ = "30-CSRDT"; // CSR Generation Details
KEYGN /**/ = "40-KEYGN"; // Private Key Generation Details
KEYPM /**/ = "45-KEYPM"; // Private Key PEM Export
CSRGN /**/ = "50-CSRGN"; // CSR Export
CSRPM /**/ = "55-CSRPM"; // CSR PEM Export
CSRDR /**/ = "56-CSRDR"; // CSR DER Export
CRTPM /**/ = "65-CRTPM"; // Certificate PEM Export
CRTDR /**/ = "66-CRTDR"; // Certificate DER Export
ISUPM /**/ = "75-ISUPM"; // Issuer Certificate PEM Export
ISUDR /**/ = "76-ISUDR"; // Issuer Certificate DER Export
ASSET /**/ = "99-ASSET"; // Generic Asset
Т.к. по умолчанию используется EFS для защиты Vault ,а у тех где данный функционал отключен , надо будет явно отключить в файле конфигурации EFS — https://pkisharp.github.io/ACMESharp-docs/Local-Vault-EFS.html .
public string RootPath
{ get; set; }
public bool CreatePath
{ get; set; }
public bool BypassEFS
{ get; set; }
$param = (Get-ACMEVaultProfile).VaultParameters $param.Add("BypassEFS",$true) Set-ACMEVaultProfile -ProfileName ":user" -Provider local -VaultParameters $param -Force
{
"$type": "ACMESharp.Vault.Profile.VaultProfile, ACMESharp.Vault",
"Name": "user",
"ProviderName": "local",
"ProviderParameters": null,
"VaultParameters": {
"$type": "System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[System.Object, mscorlib]], mscorlib",
"BypassEFS": true,
"CreatePath": true,
"RootPath": "C:\\Users\\Administrator\\AppData\\Local\\ACMESharp\\userVault"
}
}
Шаг 1: Установка модуля ACMESharp
Install-Module -Name ACMESharp -AllowClobber
Данный модуль располагается в двух репозитариях PSGallery и Nuget. Версия в PSGallery новее и на момент написания 0.9.0.321:
Install-Module -Name ACMESharp -AllowClobber -Repository PSGallery -Force
Шаг 2: Инициализация хранилища
Initialize-ACMEVault

Шаг 3: Регистрация аккаунта
* Let’s Encrypt CA поддерживает только тип email contact, URI формата mailto:<email-address>
New-ACMERegistration -Contacts mailto:$email –AcceptTos
Шаг 4: Подтверждение владением записей домена
В ACMESharp реализовано два типа ChallengeType: dns-01 , http-01 .
https-01 — описан https://pkisharp.github.io/ACMESharp-docs/Quick-Start.html
PS > Get-ACMEChallengeHandlerProfile -ListChallengeTypes
dns-01
http-01
PS > Get-ACMEChallengeHandlerProfile -ListChallengeHandlers
manual
Длинная запись:
New-ACMEIdentifier -Dns lyncdiscoverinternal.contoso.ru -Alias sfb1 New-ACMEIdentifier -Dns sfb.contoso.ru -Alias sfb2 New-ACMEIdentifier -Dns web.contoso.ru -Alias sfb3 New-ACMEIdentifier -Dns contoso.ru -Alias sfb4 Complete-ACMEChallenge -IdentifierRef sfb1 -ChallengeType dns-01 -Handler manual Complete-ACMEChallenge -IdentifierRef sfb2 -ChallengeType dns-01 -Handler manual Complete-ACMEChallenge -IdentifierRef sfb3 -ChallengeType dns-01 -Handler manual Complete-ACMEChallenge -IdentifierRef sfb4 -ChallengeType dns-01 -Handler manual Submit-ACMEChallenge -IdentifierRef sfb1 -ChallengeType dns-01 Submit-ACMEChallenge -IdentifierRef sfb2 -ChallengeType dns-01 Submit-ACMEChallenge -IdentifierRef sfb3 -ChallengeType dns-01 Submit-ACMEChallenge -IdentifierRef sfb4 -ChallengeType dns-01 ## Give it a minute, just in case -- or go get more coffee sleep -s 60 Update-ACMEIdentifier -IdentifierRef sfb1 Update-ACMEIdentifier -IdentifierRef sfb2 Update-ACMEIdentifier -IdentifierRef sfb3 Update-ACMEIdentifier -IdentifierRef sfb4
Короткая запись:
$SAN | Foreach-Object {$i=1} { $id = "sfb$i" New-ACMEIdentifier -Dns $_ -Alias $id | Out-Null Complete-ACMEChallenge -IdentifierRef $id -ChallengeType dns-01 -Handler manual $i++ }
# Содержит ресурсные записи, которые потребуется создать на DNS сервере # Требуются для подтверждения владением доменом $DNS = (Get-ACMEVault).Identifiers.Where{$_.Alias -like "sfb*"}.Authorization.Challenges.Where{$_.Type -eq "dns-01"}.Challenge
# Создаем ресурсные записи # Windows DNS Server $AllRecords = (Get-DnsServerResourceRecord -ZoneName $DomainName -RRType Txt).Where{$_.Name -match "_acme-challenge"} $DNS.Foreach{ $rdns = $_ $name = $_.RecordName.TrimEnd($DomainName) $record = $AllRecords.Where{$_.HostName -eq $name} if($record) { $newrecord = $record.Clone() $newrecord.RecordData.DescriptiveText = $_.RecordValue Set-DnsServerResourceRecord -ZoneName $DomainName -NewInputObject $newrecord -OldInputObject $record } else { ADD-DnsServerResourceRecord -ZoneName $DomainName -Txt -Name $name -DescriptiveText $_.RecordValue } }
# Yandex API Function Input-Captcha { Param($src) Add-Type -AssemblyName System.Windows.Forms,System.Drawing $bimg = [Net.WebClient]::new().DownloadData($src) $ms = [IO.MemoryStream]::new($bimg) $img = [Drawing.Image]::FromStream($ms) [Windows.Forms.Application]::EnableVisualStyles(); $form = New-Object Windows.Forms.Form -Property @{ Text = "Captcha" Width = 300 Height = 227 FormBorderStyle = "FixedDialog" Icon = [Drawing.Icon]::ExtractAssociatedIcon( "$env:ProgramFiles\Internet Explorer\iexplore.exe" ) } $pictureBox = New-Object Windows.Forms.PictureBox -Property @{ Width = $img.Size.Width Height = $img.Size.Height Location = New-Object Drawing.Size(60,30) Image = $img } $button = New-Object Windows.Forms.Button -Property @{ Location = New-Object Drawing.Size(12,153) Size = New-Object Drawing.Size(260,23) Text = "Set" } $button.Add_Click({ $script:rep = $textbox.Text.Trim() $form.Close() }) $textbox = New-Object Windows.Forms.TextBox -Property @{ Location = New-Object Drawing.Size(12,117) Size = New-Object Drawing.Size(260,20) } $form.Controls.Add($pictureBox) $form.Controls.Add($button) $form.Controls.Add($textbox) $form.Add_Shown( { $form.Activate() } ) $form.ShowDialog() | Out-Null } Function Get-Token { [CmdLetBinding()] Param( [String]$Url = "https://pddimp.yandex.ru", [String]$TUrl = "https://pddimp.yandex.ru/api2/admin/get_token", [Parameter(Mandatory)] [PSCredential]$Credential, [Parameter(Mandatory)] [String]$DomainName ) try { # Логинемся в Yandex Passport $wr = Invoke-WebRequest $TUrl -SessionVariable ya # В форме заполняем login&passwd $Form = $wr.Forms[0] $Form.Fields["login"] = $Credential.UserName $Form.Fields["passwd"] = $Credential.GetNetworkCredential().Password if($Form) { # Отправляем Post запрос $wr = Invoke-WebRequest -Uri $Form.Action -WebSession $ya -Method POST -Body $Form # Если успешно, то переходим к странице получения токена $wr = Invoke-WebRequest $TUrl -WebSession $ya if($wr.ParsedHtml.Title -eq "Admin's token management") { $Form = $wr.Forms[0] # Удаляем из post запроса token_del $Form.Fields.Remove("token_del") | Out-Null # Вводим капчу Input-Captcha $wr.Images.src # Заполняем форму rep - Captcha $Form.Fields["rep"] = $rep $Form.Fields["domain_name"] = $DomainName # Отправляем Post запрос с методом token_get $wr=Invoke-WebRequest -Uri "$url$($Form.Action)" -WebSession $ya -Method POST -Body $Form # Возвращаем полученный токен $wr.ParsedHtml.getElementsByTagName("Strong").Item(0).outerText } } } catch { $_ } } $LUrl = 'https://pddimp.yandex.ru/api2/admin/dns/list?domain={0}' -f $DomainName $EUrl = 'https://pddimp.yandex.ru/api2/admin/dns/edit' $AUrl = 'https://pddimp.yandex.ru/api2/admin/dns/add' $PddToken = Get-Token -Credential "" -DomainName $DomainName if($PddToken) { # Получим все записи для дальнейшего сравнения $AllRecords = Invoke-WebRequest $LUrl -Headers @{ "accept" = "application/json" PddToken = $PddToken } | Foreach Content | ConvertFrom-Json | Foreach {$_.Records} $DNS | Foreach { $rdns = $_ $record = $AllRecords.Where{$_.FQDN -eq $rdns.RecordName} if($record) { # Обновляем данные Invoke-WebRequest $EUrl -Headers @{"accept"="application/json" ; PddToken = $PddToken} -Method POST -Body @{ 'domain'=$DomainName 'record_id'=$record.record_id 'content'=$rdns.RecordValue } } else { # Создаем записи Invoke-WebRequest $AUrl -Headers @{"accept"="application/json" ; PddToken = $PddToken} -Method POST -Body @{ 'domain'=$DomainName 'type'='TXT' 'subdomain' = $rdns.RecordName.TrimEnd($DomainName) 'content'=$rdns.RecordValue } } } }
Т.к. для подтверждения требуется вводить captcha вручную.
# Отправить запрос на проверку (Get-ACMEIdentifier).Where{$_.Alias -match "sfb"}.Foreach{Submit-ACMEChallenge -IdentifierRef $_.Alias -ChallengeType dns-01} sleep -s 60 (Get-ACMEIdentifier).Where{$_.Alias -match "sfb"}.Foreach{Update-ACMEIdentifier -IdentifierRef $_.Alias}
Шаг 5. Генерация сертификата
$idref = (Get-ACMEIdentifier).Where{$_.Alias -match "sfb"} | Select -First 1 | Foreach {$_.Alias} $aref = (Get-ACMEIdentifier).Where{$_.Alias -match "sfb"} | Select -Skip 1 | Foreach {$_.Alias} New-ACMECertificate -Generate -IdentifierRef $idref -AlternativeIdentifierRefs $aref -Alias SfB2015FECert
# Отправить запрос Submit-ACMECertificate -CertificateRef SfB2015FECert
Update-ACMECertificate -CertificateRef SfB2015FECert
Шаг 6. Экспорт в PFX
Get-ACMECertificate SfB2015FECert -ExportPkcs12 "SfB2015FECert.pfx" -CertificatePassword '12345678'
5. Установить сертификат на сервер Skype For Business 2015
Пример можно посмотреть - https://www.tbs-certificates.co.uk/FAQ/en/install-skype-business-server.html
Import-CsCertificate -Path "c:\SfB2015FECert.pfx" -PrivateKeyExportable $True -Password '12345678' Set-CsCertificate -Type Default, WebServicesInternal, WebServicesExternal,OAuthTokenIssuer -Thumbprint "439637470DF2D0E9DF933EADEA1F0610B3BA841C" Get-CsCertificate | Ft Thumbprint,Use Thumbprint Use ---------- --- 439637470DF2D0E9DF933EADEA1F0610B3BA841C Default 439637470DF2D0E9DF933EADEA1F0610B3BA841C WebServicesInternal 439637470DF2D0E9DF933EADEA1F0610B3BA841C WebServicesExternal 439637470DF2D0E9DF933EADEA1F0610B3BA841C OAuthTokenIssuer
PS. Скрипты к статье:
le_windows_dns.txt - Пример для Windows DNS Server
le_yandex_dns.txt — Пример использования Yandex API PDD
Добавить комментарий