Shibboleth IdP 5.2.3 para Debian 13 - Integração com Azure AD

Nesta página vamos explicar como instalar um IdP Shibboleth 5.2.3 em Debian 13 integrado com Azure AD. Para esta instalação é utilizado um Playbook Ansible que automatiza a instalação e configuração do Apache2, Java 17.0.18, Tomcat 11.0.6, PostgreSQL e Shibboleth IdP 5.2.3.

A integração com Azure AD utiliza o Shibboleth IdP como um proxy SAML que assume simultaneamente o perfil de Identity Provider perante os serviços RCTSaai e o perfil de Service Provider perante a Azure AD:

  • SAML PROXY - Shibboleth Perfil Service Provider: responsável por delegar a autenticação e recolha de atributos na Azure AD
  • SAML PROXY - Shibboleth Perfil Identity Provider: responsável pelo mapeamento e filtragem de atributos para os serviços RCTSaai e eduGAIN

Este playbook permite fazer vários tipos de configuração. Permite:

  • Instalar e configurar um IdP para ser possível fazer autenticação com Azure AD.
  • Configurar um layout de acordo com a instituição.
  • Atualizar um IdP existente para a versão 5.2.3.
Playbook
Pode transferir o playbook através do link seguinte: Shibboleth IdP 5.2.3 para Debian 13 - Integração com Azure AD.

1. Flow de autenticação do IdP com Azure AD

O utilizador acede ao serviço e é redirecionado para o IdP para se autenticar. O IdP, por estar a funcionar como SAML Proxy, delega a autenticação na Azure AD e por esta razão redireciona o utilizador para o tenant Azure AD.

Após uma autenticação com sucesso, a Azure AD recolhe os dados/atributos do utilizador e redireciona novamente o utilizador para o IdP, enviando-lhe os respetivos atributos.

O IdP é responsável por mapear e filtrar os atributos recebidos antes de os enviar para os serviços. Por fim, o utilizador consente o envio dos atributos ao serviço e tem acesso ao mesmo. A salientar que este utilizador terá uma sessão ativa na Azure AD e outra no Shibboleth IdP.


azure0.png

Fig 1. Flow de autenticação com Azure AD


2. Configuração do Tenant Azure AD

Nesta secção vamos demonstrar como configurar o tenant Azure AD. Esta configuração deve ser realizada antes da instalação do playbook Ansible.

2.1 Criar Aplicação

É necessário criar uma Azure AD Enterprise Application do tipo Non-Gallery Application.

Aceda ao portal Azure AD e siga as seguintes indicações:

Escolha Enterprise Applications
  • Carregue em "New Application"
  • Escolha a opção "Non Gallery Application" e adicione o nome da aplicação (ex.: SAML IDP)
  • Após criar a aplicação siga para a opção "Set up single sign on"
  • Selecione a opção SAML

Na opção SAML deve adicionar a seguinte informação do IdP:

  1. Adicione o EntityID do IdP: https://idp.dominio-da-instituicao.pt/idp/shibboleth
  2. Adicione o Assertion Consumer Service (ACS) do IdP: https://idp.dominio-da-instituicao.pt/idp/profile/Authn/SAML2/POST/SSO
Nota

O IdP ainda não se encontra instalado, no entanto deve colocar os links de acordo com o URL que o seu IdP irá obter.

Em https://idp.dominio-da-instituicao.pt substitua de acordo com o domínio da sua instituição.

2.2 Metadados do Azure AD

Metadados Tenant
Para o Shibboleth confiar na informação recebida do Azure AD, o IdP necessita de ter acesso aos metadados do tenant.

Transfira os metadados do tenant na Secção 3 da informação de Relying Party do Azure AD, carregando no link de Download referente à opção Federation Metadata XML. Guarde o ficheiro transferido com o nome AzureAD-idp.xml.

azure1.png

Fig 2 - Secção 3 da informação da Relying Party do Azure AD


O ficheiro AzureAD-idp.xml necessita de duas alterações no elemento IDPSSODescriptor:

  1. Adicione a opção xmlns:shibmd="urn:mace:shibboleth:metadata:1.0":
<IDPSSODescriptor
    protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol"
    xmlns:shibmd="urn:mace:shibboleth:metadata:1.0">
  1. Dentro do elemento IDPSSODescriptor adicione o seguinte bloco:
<Extensions>
    <shibmd:Scope regexp="false">dominio_da_instituicao.pt</shibmd:Scope>
</Extensions>
Altere dominio_da_instituicao.pt

Altere o "dominio_da_instituicao.pt" de acordo com o domínio da sua instituição.

Para o exemplo FCCN seria substituído por fccn.pt.

O elemento shibmd:Scope permite realizar o filtro do azureName tendo em conta o domínio inserido — para o exemplo FCCN apenas seriam aceites os utilizadores cujo azureName contenha fccn.pt (ex.: authmonit@fccn.pt).

Após editar o ficheiro, copie-o para a pasta files/ORG/idp-azure-ad/ antes de executar o playbook. O playbook irá automaticamente colocá-lo na pasta de metadados do IdP e adicioná-lo como MetadataProvider.

2.3 Atributos Azure AD

Ainda no modo de edição da Relying Party é necessário configurar o Azure AD para libertar os atributos para o Shibboleth IdP.

Os utilizadores necessitam de ter os seguintes atributos preenchidos:

  • name
  • givenName
  • surname
  • emailaddress
  • Unique User Identifier
  • displayName

azure2.png

Fig 3 - Atribuição dos atributos e respetivas claims no Azure AD


O atributo user.principalname corresponde ao identificador único e permanente do utilizador na instituição para todos os serviços. Este será utilizado como canonicalNameToUseForJoin para identificar o utilizador no IdP.


3. Pré-requisitos

O primeiro passo a efectuar é instalar o pacote ansible e unzip.

shell> apt install ansible unzip

Crie a pasta Shibboleth_IDP_5.2.3, entre na nova diretoria e descomprima o código para dentro da mesma:

shell> mv shibboleth-idp-5-2-3-debian-ORG.zip Shibboleth_IDP_5.2.3
shell> cd Shibboleth_IDP_5.2.3
shell> unzip shibboleth-idp-5-2-3-debian-ORG.zip

4. Configuração do playbook

Edite o ficheiro de definições gerais sobre a instituição e da instalação em curso no seguinte ficheiro:

shell> vi group_vars/all.yml

Descrição dos parâmetros a definir

A instalação do Shibboleth IdP depende das parametrizações efectuadas no ficheiro all.yml. Em baixo encontram-se descritas as parametrizações necessárias de preencher relativas à sua instituição:

4.1 Configurações Gerais do Apache

  • fqdn: hostname do idp a ser instalado (ex.: idp.fccn.pt)
  • server_admin: contacto de admin do servidor (ex.: idp-admin@fccn.pt)

4.2 Configuração SSL - Certificados

Tradicional ACME
configure_SSL_certificates: "Tradicional" configure_SSL_certificates: "ACME"

4.2.1 Configuração SSL Tradicional

  • configure_SSL_certificates: "Tradicional"
  • path_ssl_cert_apache: Localização dos certificados/chaves públicas usadas pelo apache (ex.: /etc/ssl/certs)
  • path_ssl_cert_apache_private: Localização dos certificados/chaves privadas usadas pelo apache (ex.: /etc/ssl/private)

Copiar ficheiros de certificados SSL do IdP para files/ORG/ssl-certs/

  • ssl_cert_key_file_name: Nome do ficheiro que contém o certificado privado usado pelo apache (ex.: idp_fccn_pt.key)
  • ssl_cert_file_name: Nome do ficheiro que contém o certificado público usado pelo apache (ex.: idp_fccn_pt_cert.cer)
  • ssl_cert_chain_file_name: Nome do ficheiro que contém os certificados da cadeia de confiança usada pelo apache (ex.: idp_fccn_pt_interm.cer)

4.2.2 Configuração SSL ACME

O cliente de ACME (certbot) necessita de credenciais de uma conta ACME (mac_id e mac_key), pelo que antes da execução Ansible, o Administrador da Instituição responsável pelos certificados SSL deve criar/configurar uma conta ACME no portal da HARICA associada aos domínios desejados.

  • configure_SSL_certificates: "ACME"
  • path_ssl_cert_apache: /etc/letsencrypt/live/{{ fqdn }} Não alterar
  • path_ssl_cert_apache_private: /etc/letsencrypt/live/{{ fqdn }} Não alterar
  • ssl_cert_key_file_name: Nome do ficheiro que contém o certificado privado usado pelo apache (ex.: privkey.pem)
  • ssl_cert_file_name: Nome do ficheiro que contém o certificado público e da cadeia de confiança usada pelo apache (ex.: fullchain.pem)
  • option_multi_domain: "single-domain" Não alterar
  • option_encryption_algorithm: ecdsa Não alterar
  • option_acme_account_name: IDP Não alterar
  • option_common_names_list: "{{ fqdn }}" Não alterar
  • contact_email: Contacto de email do responsável por esta configuração
  • acme_accounts:
    • name: IDP Não alterar
    • ca: acme-v02.harica.gr Não alterar
    • server: URL do diretório do servidor da HARICA associado à conta ACME (ex.: https://acme-v02.harica.gr/acme//directory)
    • mac_id: Adicionar a EAB Key ID da conta ACME previamente criada
    • mac_key: Adicionar o EAB HMAC Key da conta ACME previamente criada

4.3. Configurações Fail2Ban

  • destemail: endereço de e-mail para onde serão enviadas as notificações do Fail2Ban (ex.: admin@org.pt)
  • sender: endereço de e-mail que aparecerá como remetente nas notificações do Fail2Ban (ex.: admin@org.pt)

4.4. Configurações Tomcat

  • tomcat_major_version: 11 — versão do tomcat a utilizar. Não alterar
  • tomcat_version: 11.0.6 — versão do tomcat a utilizar. Não alterar
  • tomcat_xms: tamanho de heap size inicial em memória no arranque do Tomcat (ex.: 1024M)
  • tomcat_xmx: tamanho de heap size máximo em memória do Tomcat (ex.: 4096M)

4.5. Configurações Shibboleth

  • idp_version: versão do Fornecedor de Identidade. Não alterar
  • source_directory: diretoria onde são colocados os ficheiros de instalação do Shibboleth IdP. Por defeito: /usr/local/dist/shibboleth-identity-provider-5.2.3. Não alterar
  • installation_directory: diretoria de instalação do Shibboleth IdP. Por defeito: /opt/shibboleth-idp. Não alterar
  • update_idp: indica se pretende atualizar ou instalar o IdP de raiz. Para atualizar coloque true, para instalar de raiz coloque false
  • ip_range_access_control: Intervalo de IPs que podem aceder a endpoints sensíveis (ex.: https://HOSTNAME/idp/status). A rede deve estar obrigatoriamente entre plicas (ex.: "'133.16.11.0/24', '133.16.10.0/24'")
  • attribute_scope: Domínio da organização utilizado nos metadados e atributos (schacHomeOrganization, eduPersonScopedAffiliation) (ex.: fccn.pt)
  • organization_name: nome da instituição (ex.: Fundação para a Computação Científica Nacional)
  • ou_organization_name: nome da unidade orgânica da instituição, caso se aplique (ex.: FCCN, Serviços Digitais FCT)
  • user_test: username da conta de monitorização fornecida à FCCN. O nome de utilizador padrão é monitidp

Configuração de Armazenamento de sessões do IdP

  • idp_session_storage: Define como deve ser armazenada a informação de sessão do utilizador. "Server-Side" armazena as sessões no servidor na BD PostgreSQL ou "Client-Side" armazena as sessões no cliente (Recomendado)

Configuração de Armazenamento de Termos e Condições e Consentimento

  • idp_consent_storage: Define como deve ser armazenada a informação de consentimento. "Server-Side" armazena os pedidos de consentimento e termos e condições no servidor na BD PostgreSQL ou "Client-Side" armazena os pedidos de consentimento e termos e condições no cliente.

Configuração de Identificadores Antigos (Transient + eduPersonTargetId)

  • idp_old_persistentId_salt: se for atualizar o IdP a partir de uma versão antiga, coloque o valor antigo do salt. Caso contrário pode manter este campo vazio.
  • idp_old_persistentId_sourceAttribute: Identifique o atributo que seja único para cada utilizador, que permaneça inalterado durante todo o ciclo de vida na instituição e que não seja reutilizado após a sua saída.
  • idp_old_persistenteId_generator: Define como deve ser armazenado o persistentId. "Stored" armazena o persistentId na base de dados PostgreSQL (recomendado) ou "Computed" calcula o persistentId dinamicamente sem armazenamento em BD.

Configuração de Identificadores Novos (samlPairwiseID + samlSubjectID)
Nota: É de extrema importância que o persistentId_sourceAttribute seja preenchido com um atributo único para cada utilizador, que permaneça inalterado durante todo o ciclo de vida na instituição e que não seja reutilizado após a sua saída.

  • idp_persistentId_salt: se for atualizar o IdP a partir de uma versão antiga e já tenha definido estes novos identificadores, coloque o valor antigo do salt. Caso contrário pode manter este campo vazio.
  • idp_persistentId_sourceAttribute: Identifique o atributo que seja único para cada utilizador, que permaneça inalterado durante todo o ciclo de vida na instituição e que não seja reutilizado após a sua saída.
  • idp_persistenteId_generator: Define como deve ser armazenado o persistentId. "Stored" armazena o persistentId na base de dados PostgreSQL (recomendado) ou "Computed" calcula o persistentId dinamicamente sem armazenamento em BD.

Configuração da BD PostgreSQL

  • postgresql_version: versão do PostgreSQL a instalar. Não alterar
  • postgresql_host: endereço do servidor PostgreSQL. Por defeito: localhost. Não alterar
  • backup_bd_shib: Indica se deseja utilizar o backup do IdP de produção em caso de atualização (update_idp: true). Defina true para utilizar o backup ou false para não utilizar.

Comando a utilizar para realizar o PostgreSQL dump:

sudo pg_dump -U shibboleth -F c -f shibboleth

Copiar ficheiro para a seguinte localização files/ORG/idp-postgres-backup/

  • bd_backup_file_name: nome do ficheiro de backup da base de dados PostgreSQL (ex.: bd.sql)
  • postgresql_database: shibboleth Não alterar
  • postgresql_username: shibboleth Não alterar
  • postgresql_password: password de acesso à base de dados PostgreSQL — adicionar entre pelicas
  • postgresql_backup_dest: caminho para a pasta onde ficarão alojados os backups da base de dados. /var/lib/postgresql/backups Não alterar

Configuração de Metadados do IdP

  • idp_entityID: Identificador único do IdP. Em caso de atualização (update_idp: true), mantenha o valor igual ao entityID do IdP atualmente em produção (ex.: https://idp.fccn.pt/idp/shibboleth)
  • idp_metadata_name: idp-metadata Não alterar

Nota: Em caso de atualização (update_idp: true) deve copiar os ficheiros dos certificados na pasta files/ORG/idp-metadata-certs/

  • idp_sign_cert_name: nome do ficheiro que contém o certificado utilizado para assinar asserções do IdP (ex.: idp-signing.crt)
  • idp_sign_key_name: nome do ficheiro que contém a chave privada utilizada para assinar asserções do IdP (ex.: idp-signing.key)
  • idp_encryption_cert_name: nome do ficheiro que contém o certificado utilizado para cifrar asserções do IdP (ex.: idp-encryption.crt)
  • idp_encryption_key_name: nome do ficheiro que contém a chave privada utilizada para cifrar asserções do IdP (ex.: idp-encryption.key)
  • idp_backchannel_cert_name: nome do ficheiro que contém o certificado utilizado para comunicação em backchannel com o IdP (ex.: idp-backchannel.crt)
  • idp_backchannel_key_name: nome do ficheiro que contém a chave privada utilizada para comunicação em backchannel (ex.: idp-backchannel.p12)

Configuração de Ligação ao Azure AD

  • type_of_idp: definir como azure para integração com Azure AD
  • azure_url: URL do tenant Azure AD da organização (ex.: https://sts.windows.net//)

O playbook configura automaticamente o fluxo de autenticação SAML Proxy com os seguintes parâmetros:

  • idp.authn.flows = SAML — ativa o fluxo de autenticação via SAML Proxy
  • idp.authn.SAML.proxyEntityID — definido automaticamente com o valor de azure_url
  • idp.authn.SAML.discoveryRequired = true — ativa a descoberta automática do IdP Azure

O atributo canonicalNameToUseForJoin é utilizado internamente para identificar o utilizador com base no user.principalname recebido da Azure AD.

Configuração do Sealer (sincronização de chaves)

O Sealer é responsável por cifrar tokens de sessão do IdP. O script updateSealerKeys.sh é executado diariamente via cron e, após gerar novas chaves com o seckeygen.sh, sincroniza os ficheiros resultantes (storefile e versionfile) para os restantes IdPs via SCP.

  • Um único IdP: não é necessário configurar estas variáveis. O script gera as chaves localmente e não executa qualquer SCP.

  • Múltiplos IdPs: é obrigatório configurar ambas as variáveis para garantir que as chaves são sincronizadas entre todos os IdPs.

  • idp_sealer_cron_host: hostname do IdP onde a cron será ativada pelo playbook. Apenas um IdP deve executar o script — o que irá gerar as chaves e sincronizá-las para os restantes via SCP (ex.: idp1.fccn.pt)

  • idp_sealer_sync_hosts: lista de hostnames de todos os IdPs separados por espaço. Deve incluir também o hostname do IdP onde o script corre, uma vez que o script o deteta automaticamente e ignora-o, ativando o SCP apenas para os restantes (ex.: idp1.fccn.pt idp2.fccn.pt)

  • idp_sealer_sync_user: utilizador com permissões SSH/SCP nos IdPs de destino, utilizado para transferir os ficheiros de chaves. Por defeito: root

Pré-requisitos para ambientes multi-IdP:

  1. Gerar o par de chaves SSH no IdP que executa o script (se não existir):
    ssh-keygen -t rsa -b 4096 -f /opt/tomcat/.ssh/id_rsa -N ""
  2. Copiar a chave pública para cada um dos IdPs de destino:
    ssh-copy-id -i /opt/tomcat/.ssh/id_rsa.pub <idp_sealer_sync_user>@<hostname_idp_destino>

    Ou manualmente, adicionar o conteúdo de /opt/tomcat/.ssh/id_rsa.pub ao ficheiro /home/tomcat/.ssh/authorized_keys em cada um dos IdPs de destino.

Configuração de Metadata Providers

  • idp_metadata_providers: Nesta secção podem ser adicionados vários "Metadata Providers". No ficheiro all.yml já se encontram os providers necessários (RCTSaai, RCTSaai Engine PRD, RCTSaai Engine QUA e Interfederação). O playbook adiciona automaticamente o MetadataProvider do Azure AD a partir do ficheiro AzureAD-idp.xml. Caso pretenda adicionar um novo provider é necessário preencher a seguinte secção:

    • id: Identificador do Provider (ex.: "RCTSaaiMD")
      file: Nome do ficheiro onde deve ser armazenado (ex.: "metadata.rctsaai.xml")
      url: URL onde se pode realizar o download (ex.: "https://registry.rctsaai.pt/rr/signedmetadata/federation/rctsaai/metadata.xml")
      maxValidInterval: "P7D" Não alterar
      disregardTLSCertificate: "false" Não alterar
      pubKey: adicionar o certificado de verificação de assinatura. Para obter a chave pública a partir de um certificado PEM executar: openssl x509 -pubkey -noout -in <certificado>.pem

Configuração de Layout

Se for necessário atualizar o logótipo ou a imagem de fundo do IdP, siga as seguintes instruções:

  • Logótipo: adicione o ficheiro na pasta /files/ORG/idp-layout/NomeDaInstituicao/images/ e indique o seu nome na variável idp_logo_img_name
  • Background: adicione o ficheiro na pasta /files/ORG/idp-layout/NomeDaInstituicao/images/ e indique o seu nome na variável idp_bg_img_name

Altere o nome da pasta NomeDaInstituicao para um nome apropriado no contexto da instituição e coloque-o na variável org_layout.

  • org_layout: nome da pasta do layout da organização (ex.: FCCN)
  • organization_domain: domínio da organização (ex.: fccn.pt)
  • idp_logo_img_name: nome da imagem com o logotipo da instituição
  • idp_logo_url: URL para o qual o utilizador será redirecionado ao clicar no logotipo
  • idp_bg_img_name: nome da imagem de fundo da instituição
  • link_suporte: URL para uma página de suporte da organização
  • link_rctsaai: URL para a página com informação sobre a RCTSaai
  • link_seguranca: URL para uma página com informação sobre segurança relevante para o utilizador
  • link_ajuda: URL para uma página com informação que possa ajudar o utilizador (ex.: FAQ)
  • link_esqueceu_palavra_chave: URL para uma página onde é possível redefinir a palavra-chave

5. Instalação e Configuração Base do IdP

Após o preenchimento do ficheiro de configurações (all.yml), o IdP pode ser instalado executando o playbook.

Para realizar a instalação base do Shibboleth IdP 5.2.3 utilize o seguinte comando:

shell> ansible-playbook -vv -i "localhost," --connection=local main.yml --tags=base