Skip to content

Instantly share code, notes, and snippets.

@dindoliboon
Last active April 15, 2021 22:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dindoliboon/553884cfc67cc2672a786e4aee69cd63 to your computer and use it in GitHub Desktop.
Save dindoliboon/553884cfc67cc2672a786e4aee69cd63 to your computer and use it in GitHub Desktop.
Deploy basic install of Shibboleth IdP on Windows Server 2019.
#
# Moved code to shibidp-deploy.psm1.
#
# Must call function now, but this allows customization using parameters.
#
# Perform default install.
# iex (iwr 'https://gist.githubusercontent.com/dindoliboon/553884cfc67cc2672a786e4aee69cd63/raw/shibidp-deploy.ps1').Content
#
# Example on customizing non-HTTPS port and Java heap size.
# iex (iwr 'https://gist.githubusercontent.com/dindoliboon/553884cfc67cc2672a786e4aee69cd63/raw/shibidp-deploy.psm1').Content; Install-App -JettyNonHttpsPort 8081 -JavaMinimumHeapSize '4g' -JavaMaximumHeapSize '4g'
#
iex (iwr 'https://gist.githubusercontent.com/dindoliboon/553884cfc67cc2672a786e4aee69cd63/raw/shibidp-deploy.psm1').Content; Install-App
<#
This is a basic install of Shibboleth IdP 4.1.0 on Windows Server 2019.
The following applications are used:
7-Zip 16.04
Jetty 9.4.39.v20210325
Shibboleth Identity Provider 4.1.0
Amazon Corretto JDK 11.0.10.9.1
NSSM 2.24
# You will need an active PowerShell or PowerShell Direct connection to the server.
# GUI prompt.
Enter-PSSession -VMName IDP_DEV
# Insecure hard-coded credential.
$password = ConvertTo-SecureString 'P@ssw0rd' -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential ('administrator', $password)
Enter-PSSession -VMName IDP_DEV -Credential $cred
Adding metadata, service providers, etc are beyond the scope of this install.
#>
New-Module -Name DeployApp -ScriptBlock {
function Install-App {
param(
[string]$TemporaryPath = 'C:\tmp',
[string]$AppPath = 'C:\opt',
[string]$JettyBrowserPassword = 'changeit',
[string]$JettyBackchannelPassword = 'changeit', # idp.keystore.password
[string]$JettyCookiePassword = 'changeit', # idp.sealer.password, idp.sealer.storePassword, idp.sealer.keyPassword
[string]$IdpScope = 'localhost',
[string]$IdpHostname = 'localhost',
[int]$JettyStopPort = 8963,
[string]$JettyStopKey = [Guid]::NewGuid().Guid,
[string]$JavaMinimumHeapSize = '256m',
[string]$JavaMaximumHeapSize = '512m',
[int]$JettyHttpsPort = 443,
[int]$JettyBackchannelPort = 8443,
[int]$JettyNonHttpsPort = 8080,
[string]$JettyHost = '0.0.0.0',
[string]$JettyNonHttpsHost = '0.0.0.0',
[ValidateSet('all', 'idp', 'jdk', 'jetty', 'nssm', 'firewall', 'custom-packages')]
[string[]]$Components = @('all')
)
# Set environment variables.
[Environment]::SetEnvironmentVariable('JDK_HOME', $AppPath + '\java\jdk11.0.10_9')
[Environment]::SetEnvironmentVariable('JAVA_HOME', $ENV:JDK_HOME)
[Environment]::SetEnvironmentVariable('JETTY_HOME', $AppPath + '\jetty')
[Environment]::SetEnvironmentVariable('IDP_HOME', $AppPath + '\shibboleth-idp')
[Environment]::SetEnvironmentVariable('IDP_SRC', $AppPath + '\shibboleth-identity-provider-4.1.0')
[Environment]::SetEnvironmentVariable('JETTY_BASE', $ENV:IDP_HOME + '\jetty-base')
# Prepare files for download.
cd \
if (Test-Path -Path "$TemporaryPath\tmp") {
rm -Recurse -Force -Path "$TemporaryPath\tmp"
}
mkdir -Force "$TemporaryPath\install"
mkdir -Force "$TemporaryPath\tmp"
Get-WebFile -Uri 'https://raw.githubusercontent.com/dindoliboon/live-tools/master/windows/7z/16.04/x64/7z.exe' -OutFile "$TemporaryPath\install\7z.exe" -Hash 'C7245E21A7553D9E52D434002A401C77A7CA7D0F245F2311B0DDF16F8F946C6F'
Get-WebFile -Uri 'https://raw.githubusercontent.com/dindoliboon/live-tools/master/windows/7z/16.04/x64/7z.dll' -OutFile "$TemporaryPath\install\7z.dll" -Hash '9ED007AA82E440CEB39A6E105BB1D602A9BC59A4946267BA8DE2F220AA15BC06'
# Clean-up prior installs.
Uninstall-App -TemporaryPath $TemporaryPath -AppPath $AppPath
# Install JDK.
if (($Components -contains 'all' -or $Components -contains 'jdk') -and $Components -notcontains '-jdk') {
Get-WebFile -Uri 'https://corretto.aws/downloads/resources/11.0.10.9.1/amazon-corretto-11.0.10.9.1-windows-x64-jdk.zip' -OutFile "$TemporaryPath\install\amazon-corretto-11.0.10.9.1-windows-x64-jdk.zip" -Hash 'B0405CC115CFF2334B9C5A7CBBAC56DFBB831B2E363B9E901D8F8473CFE2BF3C'
. "$TemporaryPath\install\7z.exe" x "$TemporaryPath\install\amazon-corretto-11.0.10.9.1-windows-x64-jdk.zip" -o"$AppPath\java" * -r -y
}
# Install Jetty.
if (($Components -contains 'all' -or $Components -contains 'jetty') -and $Components -notcontains '-jetty') {
Get-WebFile -Uri 'https://repo1.maven.org/maven2/org/eclipse/jetty/jetty-distribution/9.4.39.v20210325/jetty-distribution-9.4.39.v20210325.zip' -OutFile "$TemporaryPath\install\jetty-distribution-9.4.39.v20210325.zip" -Hash 'C3BE9CCB42963D276B279169ABE28C8EF6FF2E7E0850120A8F92E1D57802F45B'
. "$TemporaryPath\install\7z.exe" x "$TemporaryPath\install\jetty-distribution-9.4.39.v20210325.zip" -o"$AppPath" * -r -y
mv "$AppPath\jetty-distribution-9.4.39.v20210325" "$($ENV:JETTY_HOME)"
}
# Install Shibboleth IdP.
if (($Components -contains 'all' -or $Components -contains 'idp') -and $Components -notcontains '-idp') {
Get-WebFile -Uri 'https://shibboleth.net/downloads/identity-provider/4.1.0/shibboleth-identity-provider-4.1.0.zip' -OutFile "$TemporaryPath\install\shibboleth-identity-provider-4.1.0.zip" -Hash 'E17BAA5DFB62EB726CB17AAE67157AEF93DD208DB7E7752EF8E8A60D5AA477B1'
. "$TemporaryPath\install\7z.exe" x "$TemporaryPath\install\shibboleth-identity-provider-4.1.0.zip" -o"$AppPath" * -r -y
if (Test-Path -Path "$($ENV:IDP_SRC)\merge.txt") {
rm -Force -Path "$($ENV:IDP_SRC)\merge.txt"
}
Add-Content -Path "$($ENV:IDP_SRC)\merge.txt" -Encoding Ascii -Value ('idp.entityID=https://' + $IdpHostname + '/idp/shibboleth')
Add-Content -Path "$($ENV:IDP_SRC)\merge.txt" -Encoding Ascii -Value ('idp.scope=' + $IdpScope)
. "$($ENV:IDP_SRC)\bin\install.bat" ('-Didp.merge.properties="' + $ENV:IDP_SRC + '\merge.txt"') ('-Didp.src.dir="' + $ENV:IDP_SRC + '"') ('-Didp.target.dir="' + $ENV:IDP_HOME + '"') ('-Didp.host.name=' + $IdpHostname) ('-Didp.scope=' + $IdpScope) ('-Didp.sealer.password=' + $JettyCookiePassword) ('-Didp.keystore.password=' + $JettyBackchannelPassword)
rm -Recurse -Force -Path "$($ENV:IDP_SRC)"
rm -Recurse -Force -Path "$($ENV:IDP_HOME)\old-*"
}
# Install Shibboleth IdP Jetty base.
if (($Components -contains 'all' -or $Components -contains 'jetty') -and $Components -notcontains '-jetty') {
Write-Verbose -Verbose -Message "Looking for latest IdP Jetty Base"
$package = Invoke-RestMethod -Uri 'https://build.shibboleth.net/nexus/content/repositories/snapshots/net/shibboleth/idp/idp-jetty-base/9.4.1-SNAPSHOT/maven-metadata.xml'
$snapshot = $package.metadata.versioning.snapshotVersions.snapshotVersion |? { $_.extension -eq 'zip' }
if ($null -eq $snapshot) {
throw 'Unable to get metadata for latest IdP Jetty Base'
}
Write-Verbose -Verbose -Message "Found version $($snapshot.value)"
$zipUrl = "https://build.shibboleth.net/nexus/content/repositories/snapshots/net/shibboleth/idp/idp-jetty-base/9.4.1-SNAPSHOT/idp-jetty-base-$($snapshot.value).zip"
$zipMd5Url = $zipUrl + '.md5'
$zipFile = "idp-jetty-base-$($snapshot.value).zip"
$zipMd5 = Invoke-RestMethod -Uri $zipMd5Url
if ($null -eq $zipMd5) {
throw 'Unable to get MD5 for latest IdP Jetty Base'
}
Get-WebFile -Uri $zipUrl -OutFile "$TemporaryPath\install\$zipFile" -Hash $zipMd5 -Algorithm 'MD5'
. "$TemporaryPath\install\7z.exe" x "$TemporaryPath\install\$zipFile" -o"$($ENV:IDP_HOME)" * -r -y
# Add temporary public-facing certificate.
. "$ENV:JAVA_HOME\bin\keytool.exe" -genkey -alias "secret" -keystore "$ENV:IDP_HOME/credentials/idp-userfacing.p12" -storepass $JettyBrowserPassword -dname "CN=$($IdpHostname), OU=IT Division, O=My Company, L=Any Town, ST=Any State, C=US" -validity 365 -keyalg RSA -keysize 4096 -storetype pkcs12
if ($JettyHost -ne '0.0.0.0') {
Set-PropertyValue -Path "$($ENV:JETTY_BASE)\start.d\idp.ini" -Key 'jetty.ssl.host' -Value $JettyHost -Backup $false
}
Set-PropertyValue -Path "$($ENV:JETTY_BASE)\start.d\idp.ini" -Key 'jetty.ssl.port' -Value $JettyHttpsPort -Backup $false
# Add http module if port is specified.
if ($null -ne $JettyNonHttpsPort -or $JettyNonHttpsPort -gt 0) {
Set-PropertyValue -Path "$($ENV:JETTY_BASE)\start.d\idp.ini" -Key 'jetty.http.port' -Value $JettyNonHttpsPort -Backup $false
Set-PropertyValue -Path "$($ENV:JETTY_BASE)\start.d\idp.ini" -Key 'jetty.http.host' -Value $JettyNonHttpsHost -Backup $false
$idpMod = Get-Content -Path "$($ENV:JETTY_BASE)\modules\idp.mod" -Raw
$idpMod -replace "https`n", "https`nhttp`n" | Out-File -FilePath "$($ENV:JETTY_BASE)\modules\idp.mod" -Encoding ascii -NoNewline
}
if ($JettyBackchannelPort -ne 8443) {
Set-PropertyValue -Path "$($ENV:JETTY_BASE)\start.d\idp-backchannel.ini" -Key 'idp.backchannel.port' -Value $JettyBackchannelPort -Backup $false
}
}
# Create firewall rules.
if (($Components -contains 'all' -or $Components -contains 'firewall') -and $Components -notcontains '-firewall') {
New-NetFirewallRule -Group 'Shibboleth Identity Provider' -DisplayName 'Shibboleth IdP jetty.https.port' -Program "$($ENV:JAVA_HOME)\bin\java.exe" -Direction Inbound -Action Allow -LocalPort $JettyHttpsPort -Protocol TCP
New-NetFirewallRule -Group 'Shibboleth Identity Provider' -DisplayName 'Shibboleth IdP jetty.backchannel.port' -Program "$($ENV:JAVA_HOME)\bin\java.exe" -Direction Inbound -Action Allow -LocalPort $JettyBackchannelPort -Protocol TCP
New-NetFirewallRule -Group 'Shibboleth Identity Provider' -DisplayName 'Shibboleth IdP jetty.nonhttps.port' -Program "$($ENV:JAVA_HOME)\bin\java.exe" -Direction Inbound -Action Allow -LocalPort $JettyNonHttpsPort -Protocol TCP
# Enable ping.
Set-NetFirewallRule -DisplayName 'File and Printer Sharing (Echo Request - ICMPv4-In)' -Enabled True
Set-NetFirewallRule -DisplayName 'File and Printer Sharing (Echo Request - ICMPv6-In)' -Enabled True
}
# Create Windows service.
if (($Components -contains 'all' -or $Components -contains 'nssm') -and $Components -notcontains '-nssm') {
Get-WebFile -Uri 'http://nssm.cc/release/nssm-2.24.zip' -OutFile "$TemporaryPath\install\nssm-2.24.zip" -Hash '727D1E42275C605E0F04ABA98095C38A8E1E46DEF453CDFFCE42869428AA6743'
. "$TemporaryPath\install\7z.exe" x "$TemporaryPath\install\nssm-2.24.zip" -o"$AppPath" * -r -y
. "$AppPath\nssm-2.24\win64\nssm.exe" install shibbolethidp "$($ENV:JAVA_HOME)\bin\java.exe" "-XX:+UseG1GC -Xms$JavaMinimumHeapSize -Xmx$JavaMaximumHeapSize -classpath """"""$($ENV:JETTY_HOME)\start.jar"""""" org.eclipse.jetty.start.Main -Djava.io.tmpdir=""""""$($ENV:JETTY_BASE -replace '\\', '/')/tmp"""""" -Didp.home=""""""$($ENV:IDP_HOME -replace '\\', '/')"""""" jetty.base=""""""$($ENV:JETTY_BASE)"""""" jetty.console-capture.dir=""""""$($ENV:JETTY_BASE)\logs"""""" STOP.PORT=$JettyStopPort STOP.Key={$JettyStopKey}"
. "$AppPath\nssm-2.24\win64\nssm.exe" set shibbolethidp AppEnvironmentExtra JAVA_HOME=$($ENV:JAVA_HOME) IDP_HOME=$($ENV:IDP_HOME) JETTY_HOME=$($ENV:JETTY_HOME) JETTY_BASE=$($ENV:JETTY_BASE) JDK_HOME=$($ENV:JDK_HOME)
. "$AppPath\nssm-2.24\win64\nssm.exe" set shibbolethidp DisplayName "Shibboleth Identity Provider (IdP)"
. "$AppPath\nssm-2.24\win64\nssm.exe" set shibbolethidp Description "Provides Single Sign-On services and extends reach into other organizations and new services through authentication of users and securely providing appropriate data to requesting services."
. "$AppPath\nssm-2.24\win64\nssm.exe" set shibbolethidp AppDirectory $($ENV:JETTY_BASE)
. "$AppPath\nssm-2.24\win64\nssm.exe" status shibbolethidp
. "$AppPath\nssm-2.24\win64\nssm.exe" get shibbolethidp AppEnvironmentExtra
}
# Install custom packages.
if (($Components -contains 'all' -or $Components -contains 'custom-packages') -and $Components -notcontains '-custom-packages') {
if ((Test-Path -Path "$TemporaryPath\install\resources\app-deploy\_app_deploy_.ps1") -eq $true) {
$passedArgs = @{}
$MyInvocation.MyCommand.Parameters.GetEnumerator() |% {
$passedArgs[$_.Key] = Get-Variable -Name $_.Key -ValueOnly
}
. "$TemporaryPath\install\resources\app-deploy\_app_deploy_.ps1" -InstallAppArgs $passedArgs
}
}
# Start service.
if (($Components -contains 'all' -or $Components -contains 'nssm') -and $Components -notcontains '-nssm') {
Start-Service -Name 'shibbolethidp'
}
# Cleanup.
rm -Recurse -Force -Path "$($ENV:WINDIR)\Temp\*" -ErrorAction SilentlyContinue
rm -Recurse -Force -Path "$TemporaryPath\tmp" -ErrorAction SilentlyContinue
# Status check.
Write-Host 'Waiting for IdP to load.'
Write-Host "https://localhost:$($JettyHttpsPort)/idp/profile/status"
Write-Host "http://localhost:$($JettyNonHttpsPort)/idp/profile/status"
$IdpStatusCode = 0
Do {
Try {
$IdpStatusCode = (Invoke-WebRequest -Uri "https://localhost:$($JettyHttpsPort)/idp/profile/status" -SkipCertificateCheck).StatusCode
} Catch {
}
Write-Host -NoNewline -Object '.'
Start-Sleep -Seconds 3
} While ($IdpStatusCode -ne 200)
Write-Host 'IdP is loaded, you are ready to go.'
}
function Uninstall-App {
param(
[string]$TemporaryPath = 'C:\tmp',
[string]$AppPath = 'C:\opt'
)
# Remove Windows service.
Get-Service -Name 'ShibbolethIdp' -ErrorAction SilentlyContinue | Stop-Service
Get-CimInstance -ClassName Win32_Service -Filter "Name='ShibbolethIdp'" | Remove-CimInstance
# Remove application files.
rm -Recurse -Force -Path $AppPath -ErrorAction SilentlyContinue
# Remove firewall rules.
Get-NetFirewallRule -DisplayName 'Shibboleth IdP jetty.https.port' -ErrorAction SilentlyContinue | Remove-NetFirewallRule
Get-NetFirewallRule -DisplayName 'Shibboleth IdP jetty.backchannel.port' -ErrorAction SilentlyContinue | Remove-NetFirewallRule
Get-NetFirewallRule -DisplayName 'Shibboleth IdP jetty.nonhttps.port' -ErrorAction SilentlyContinue | Remove-NetFirewallRule
}
$script:ErrorActionPreference = 'Stop'
# Import Get-WebFile.ps1 and Set-PropertyValue.ps1.
Invoke-Expression -Command (Invoke-WebRequest -Uri 'https://gist.githubusercontent.com/dindoliboon/f378b41ed09a820d10407466a503161e/raw/Get-WebFile.ps1').Content
Invoke-Expression -Command (Invoke-WebRequest -Uri 'https://gist.githubusercontent.com/dindoliboon/b42d793101492b8cb4c0c52edb0497dd/raw/Set-PropertyValue.ps1').Content
Export-ModuleMember -Function 'Install-App', 'Uninstall-App'
}
@dindoliboon
Copy link
Author

To start the install, run in PowerShell:

iex (iwr 'https://gist.githubusercontent.com/dindoliboon/553884cfc67cc2672a786e4aee69cd63/raw/shibidp-deploy.ps1').Content

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment