AS4 Outbound Sender Dokumentation

Der AS4 Outbound Sender empfängt signierte und verschlüsselte AS4-Nachrichten vom Crypto Operations Service via Message Broker und versendet diese per HTTP(S) an den Marktpartner. Die versendete Nachricht wird zur Persistierung an den AS4 Message Service weitergeleitet. Die empfangene Empfangsbestätigung (Receipt) des Marktpartners wird zur Signaturprüfung an den Crypto Operations Service übergeben.

Features

Feature Property Default Beschreibung
Kryptografie überspringen skipCrypt false Deaktiviert die Anbindung an Crypto Operations (nur für Entwicklung)
mTLS client.ssl.enabled false Aktiviert mutual TLS für ausgehende AS4-Verbindungen
SSL Startup-Check startupSslCheck false Prüft beim Start ob die SSL-Konfiguration erfolgreich ist (Health-Endpoint)
SSL Trust-Info ssl.trust-info false Aktiviert die Abfrage von Trust-Informationen für TLS
Proxy proxyEnable false Aktiviert einen HTTP-Proxy für ausgehende Verbindungen
Zertifikat-Cache-Aktualisierung clear-certificate-cache 0 0 6 * * * Cron-Ausdruck für die automatische Cache-Aktualisierung
Keystore-Dateien löschen deleteKeystoreFiles false Löscht temporäre Keystore-Dateien nach Verwendung
Revocation-Status-Cache revocation.status.cache.enabled false Aktiviert einen Cache für den Sperrstatus von Zertifikaten
Trust-Info-Cache ssl.trust-info.cache.enabled true Aktiviert einen Cache für Trust-Informationen
Alle Content-Types akzeptieren acceptResponseAllContentTypes true Akzeptiert beliebige Content-Types in Partner-SOAP-Antworten
Delay-Queue delayExchangeName as4.outbound.delay Verzögerte Wiederholung bei temporären Fehlern
Max Verbindungen pro Partner as4.outbound.max-connections-per-mpid 200 Begrenzt parallele HTTP-Verbindungen je Marktpartner

Hardware Anforderungen

Eine Service-Instanz erfordert mindestens 512 MB RAM.

Wir empfehlen 0,4 CPU-Kerne je Instanz.

Logs werden auf die Festplatte geschrieben, entsprechend muss genügend Speicherplatz vorhanden sein.

Abhängigkeiten

Der Service greift auf einen Message-Broker zu, um Nachrichten zu empfangen und zu versenden.

Der Service nutzt die REST API des Security Server FSS. Der FSS muss im Hintergrund auf ein HSM zugreifen können.

Der Service verbindet sich per AS4 mit zahlreichen anderen AS4 Endpunkten. Dies beinhaltet auch externe AS4-Endpunkte.

Einfache Konfiguration der as4-outbound-sender.properties

Der AS4 Outbound Sender versendet die Edifact Nachricht als AS4 Nachricht an den Marktpartner. Anschließend wird diese AS4 Nachricht als Business Message an den AS4 Message Service und die erhaltene Bestätigung als Receipt an den Crypto Operations übergeben.

Dazu benötigt der AS4 Outbound Sender die Angaben zum Message-Broker.

rabbitmq.host=localhost
rabbitmq.port=5672
rabbitmq.username=guest
rabbitmq.password=guest

Mit skipCrypt lässt sich die Anbindung zum Crypt Operation für Entwicklungszwecke ausschalten.

skipCrypt=false

AMQP Konfiguration

Falls Sie das Standard Routing nutzen, muss das Routing nicht weiter konfiguriert werden. Wenn Sie Ihr Routing anpassen möchten, lesen Sie die folgende Dokumentation.

Die Property consumer.max.attempts verhindert das mehrfache Versenden der Nachricht, wenn die Versendung fehlgeschlagen oder ein anderer Fehler aufgetreten ist.

consumer.max.attempts=1

Default: 3

Das Intervall zwischen den einzelnen Versuchen kann konfiguriert werden. Der Wert ist in Millisekunden angegeben

consumer.retry.interval=2000

Default: 1000

Empfang der AS4 Nachricht

Der Consumer empfängt die signierte AS4 Nachricht über die Queue as4.outbound.default vom Crypto Operations. Siehe AMQP Routing Konfiguration weiter unten.

AMQP Routing Konfiguration

Im Standard-Routing ist keine weitere Konfiguration nötig. Die folgende Tabelle gibt eine Übersicht über alle vom Service genutzten Exchanges und ihre Gegenstellen. Die Default-Queue ergibt sich aus <exchange>.default.

Richtung Property Exchange Default-Queue Gegenstelle Zweck
Consumer cryptoConsumerExchangeName as4.outbound as4.outbound.default Crypto Operations Empfang der signierten/verschlüsselten AS4-Nachricht zum Versand
Consumer delayExchangeName as4.outbound.delay as4.outbound.delay.default self (Delay-Queue) Verzögerte Wiederholung bei temporären Sendefehlern
Producer businessMessageExchangeName as4.messages as4.messages.default AS4 Message Service Versand der AS4 Business Message (auch Fallback bei Crypto-Fehlern)
Producer receiptCryptoExchangeName as4.verify as4.verify.default Crypto Operations Weiterleiten der Empfangsbestätigung des Marktpartners zur Verifizierung
Producer receiptExchangeName as4.receipt as4.receipt.default AS4 Message Service “Leeres” Receipt bei Crypto-Fehler oder fehlgeschlagener Quittungs-Verifikation

Begrenzung der Sendeversuche pro Nachricht:

consumer.max.attempts=1

Consumer-Gruppen anpassen

Für die Consumer-Exchanges können Gruppe und Binding-Routing-Key geändert werden. Bei deaktiviertem Routing muss bindingRoutingKey zwingend auf default gesetzt werden. Über max-concurrency lässt sich die Anzahl gleichzeitiger Verarbeitungsthreads einstellen.

cryptoConsumerGroup=default
cryptoConsumerMaxConcurrency=50
delayConsumerGroup=default
delayConsumerMaxConcurrency=20
spring.cloud.stream.rabbit.bindings.consumeSignedEncryptedMessage-in-0.consumer.bindingRoutingKey=default

Producer-Routing nach Header

Für Producer-Exchanges lässt sich das Routing über <exchangeProperty>HeaderName und <exchangeProperty>HeaderValues aktivieren. Nachrichten mit Werten, die nicht in HeaderValues aufgelistet sind, laufen weiterhin über die Default-Route. Die Gegenstelle muss entsprechend eingerichtet werden.

Mögliche HeaderName-Werte:

  • tenant: ILN Nummer des Senders
  • partner: ILN Nummer des Empfängers
  • sector: GAS, ELECTRICITY

Beispiel für businessMessageExchangeName:

businessMessageExchangeName=as4.messages
businessMessageHeaderName=tenant
businessMessageHeaderValues=9907647000008,9903111000003

Mindestens verfügbare Consumer

Es ist möglich dem Outbound-Sender vorzugeben, wie viele Consumer er mindestens vorhalten soll – unabhängig von der aktuellen Last. Somit werden Verzögerungen bei schwankenden Nachrichtenvolumen verhindert. Default: 1.

spring.cloud.stream.bindings.consumeSignedEncryptedMessage-in-0.consumer.concurrency=5

Delay Queue

Der Outbound Sender verschiebt bei bestimmten temporären Fehlern (z.B. nicht erreichbarer Marktpartner) Nachrichten in eine Delay-Queue. Nach dem konfigurierten Intervall wird die Nachricht erneut verarbeitet (siehe AMQP Routing Konfiguration).

Maximale Verbindungen pro Partner

Um eine Überlastung einzelner Marktpartner-Endpunkte zu verhindern, kann die maximale Anzahl paralleler HTTP-Verbindungen pro Marktpartner-MPID begrenzt werden. Default: 200.

as4.outbound.max-connections-per-mpid=200

Connection Timeout

Der Timeout für die Verbindung zum Marktpartner (in Sekunden). Default: 300.

connectionTimeout=300

REST API

Die API bietet Server-Health Informationen an.

Der Port lässt sich über folgende Property konfigurieren: server.port=8080

Multi-Mandantenfähigkeit

Falls das AS4-System für mehrere Mandanten betrieben wird, kann der AS4 Outbound Sender für jeden Mandanten mindestens eine eigene Instanz haben. Bei einer solchen Konfiguration muss für jeden Mandanten eine eigene Queue eingerichtet werden. Über die Exchange muss entsprechend dem Mandanten in die jeweilige Queue geroutet werden.

Multi-Tenancy

Der AS4-Outbound-Sender arbeitet außerdem als AMQP Producer. Hier müssen keine weiteren Anpassungen vorgenommen werden.

Ausfallsicherheit

Wie üblich für Microservices können mehrere Instanzen des AS4-Outbound-Senders parallel betrieben werden, um die Last zu verteilen und Ausfallsicherheit zu gewährleisten.

In einem solchen Szenario konsumieren mehrere Instanzen die gleiche Queue und verteilen so die Nachrichten.

Redundancy

Der AS4-Outbound-Sender arbeitet außerdem als AMQP Producer. Hier müssen keine weiteren Anpassungen vorgenommen werden.

mTLS

Der AS4-Outbound-Sender fungiert als AS4-Client, der die Geschäftsnachricht an einen AS4-Server sendet.

Um mTLS auf der Seite des AS4-Outbound-Senders zu aktivieren, müssen zum einen JDK_JAVA_OPTIONS gesetzt und zum anderen in der application.properties gewissen Eigenschaften gesetzt werden:

JDK_JAVA_OPTIONS: "-Djdk.tls.cipherSuites=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_ECDSA_WITH_BRAINPOOLP384R1,TLS_ECDHE_ECDSA_WITH_BRAINPOOLP256R1,TLS_ECDHE_ECDSA_WITH_SECP384R1,TLS_ECDHE_ECDSA_WITH_SECP256R1 -Djdk.tls.namedGroups=brainpoolP384r1,brainpoolP256r1,secp384r1,secp256r1"

In der application.properties sind folgende Properties zu setzen:

client.ssl.enabled=true

addressServiceUrl=http://localhost:8089/aep-as4-address-service
#ssl.tenant.id=9907647000008,9903111000003

fss.server.api.url=http://localhost:2222/fss/api/v1
ssl.partner.client=shared-client

Die TLS-Funktionalität kann über die Eigenschaft client.ssl.enabled ein-/ausgeschaltet werden (entweder durch Setzen auf true oder false). Der Standardwert für client.ssl.enabled ist false. Wenn die Eigenschaft nicht konfiguriert ist, wird sie daher standardmäßig auf „false“ gesetzt.

Der Service unterstützt parallel mehrere Mandanten. Wenn wir die Liste der Mandanten aus dem AS4-Address-Service automatisch abrufen möchten, müssen die Mandanten im AS4-Address-Service konfiguriert werden. Für diese Verbindung müssen wir die Eigenschaft addressServiceUrl in der Konfigurationsdatei definieren. (Alternativ kann die Liste der Mandanten, für die wir TLS konfigurieren möchten, wie gezeigt explizit in der Eigenschaft ssl.tenant.id mithilfe durch Kommas getrennter Werte angegeben werden.)

Hinweis: Konfigurieren Sie entweder die Eigenschaft addressServiceUrl oder ssl.tenant.id – konfigurieren Sie nicht beide Eigenschaften gleichzeitig.

Hinweis: Falls die addressServiceUrl genutzt wird, gilt: Der AS4-Address-Service muss ausgeführt und vom AS4-Outbound-Sender aus aufrufbar sein. Alle benötigten Mandanten müssen zur Bootzeit des AS4-Outbound-Senders verfügbar sein. Falls sich Mandanten zur Laufzeit ändern, müssen Sie den AS4-Outbound-Sender neu starten.

Für jeden Mandanten muss ein Marktpartner-TLS-Zertifikat/-Schlüssel im FSS/HSM vorhanden sein. Für jeden Marktpartner müssen alle Zertifikate der Aussteller-Zertifikatskette im FSS shared-client verfügbar sein. Die FSS-URL wird über die Property fss.server.api.url konfiguriert. Der shared-client wird über die Property ssl.partner.client angegeben. Wenn die Eigenschaft von ssl.partner.client nicht festgelegt ist, lautet der Standardwert shared-client.

Hinweis: Der FSS muss ausgeführt und vom AS4-Outbound-Sender aus aufrufbar sein. Alle benötigten Zertifikate müssen zur Bootzeit des AS4-Outbound-Senders verfügbar sein. Falls sich Zertifikate zur Laufzeit ändern, müssen Sie den AS4-Outbound-Sender neu starten.

Zertifikat Cache

Zertifikate werden intern gecached. Dieser Cache muss regelmäßig aktualisiert werden. Dies ist notwendig um z.B. den änderbaren Sperrlistenstatus aktuell zu halten.

Der Cache wird automatisch auf zeitlicher Basis aktualisiert, per Default alle 6 Stunden.

Das Zeitinterval der automatischen Aktualisierung für Zertifikat-Caches kann über die Eigenschaft clear-certificate-cache konfiguriert werden. Hierbei handelt es sich um einen Cron-Ausdruck. Beispiel:

#         day of week ------------+
#               month ----------+ |
#        day of month --------+ | |
#                hour ------+ | | |
#              minute ----+ | | | |
#              second --+ | | | | |
#                       | | | | | |
clear-certificate-cache=0 0 6 * * *

Weitere Details zur Cron-Konfiguration finden Sie in der Spring-Doku.

Widerrufstatus von Zertifikaten cachen

Um den Widerrufstatus von Zertifikaten zu cachen und nicht für jede Nachricht erneut abzurufen, muss folgender Wert in der application.properties gesetzt werden:

revocation.status.cache.enabled=true

Dann wird der Widerrufstatus der Marktpartnerzertifikate maximal einmal pro Stunde geprüft. Falls Probleme beim Abrufen des Widerrufstatus auftreten, wird der gecachte Status für maximal 6 Stunden verwendet. Diese Zeiträume können mit folgenden Konfigurationseinstellungen angepasst werden:

revocation.status.cache.max.usage=T6H
revocation.status.cache.refresh.after=T1H

Syntax: 1H für eine Stunde, 30M für 30 Minuten, 1D für einen Tag, oder Kombinationen wie 1d4H or 1H30M

Zwischenspeicherung des Ergebnisses der Partnerzertifikatsvertrauensprüfung

Folgende Eigenschaften können eingestellt werden. Nachfolgend sind die Standardwerte aufgeführt.

ssl.trust-info.cache.enabled=true
ssl.trust-info.cache.refresh.after=T1H

Logging der AS4 Verbindungen

Durch die Konfiguration des Bouncycastle Loggings auf DEBUG Level in der application.properties, können die AS4 Verbindungen geloggt werden.

logging.level.org.bouncycastle=DEBUG

Der Standard ist derzeit wie folgt konfiguriert:

logging.level.org.bouncycastle=WARN

Prüfung von nicht gespeicherten Partnerzertifikaten während des TLS-Handshakes

Während des TLS-Handshakes kann die Vertrauensprüfung des Partnerzertifikats nun auch durchgeführt werden, wenn das Zertifikat nicht im FSS gespeichert ist. Diese Prüfung findet im FSS statt. Wenn das Zertifikat im FSS gespeichert ist, werden diese Informationen für die Prüfung herangezogen. Wenn das Zertifikat nicht gespeichert ist, werden die Informationen aus dem Zertifikat verwendet und die Sperrliste von der Sub-CA heruntergeladen. Folgenden Prüfungen werden durchgeführt, um zu prüfen, ob das Zertifikat vertrauenswürdig ist:

  • Zertifikatskette ist im FSS vorhanden und vertrauenswürdig
  • Wenn das Zertifikat vorhanden ist: Aktiv oder inaktiv
  • Validity/time slice
  • Sperrlistenstatus
  • Purpose ist TLS

Um diese Funktion zu aktivieren (FSS-URL ist ebenfalls konfiguriert):

ssl.trust-info=true

Wichtig ist zu beachten, dass für dieses Feature mindestens die FSS Version 2025-02-27-01 verwendet werden muss.

AS4-Outbound Delay Queue

Beim Senden von AS4-Nachrichten können während eines Sendeversuchs Fehler wie Timeouts oder Ausnahmen auftreten. Ohne einen dedizierten Verzögerungsmechanismus würden fehlgeschlagene Nachrichten direkt wieder in die Standard-Queue as4-outbound zurückveröffentlicht und sofort erneut verarbeitet. In Szenarien mit hohem Durchsatz entsteht dadurch eine enge Rückkopplungsschleife, bei der eine große Anzahl fehlgeschlagener Nachrichten für denselben Marktpartner kontinuierlich durch die Queue kreist, die verfügbaren Consumer blockiert und verhindert, dass fehlerfreie Nachrichten anderer Partner verarbeitet werden.

Um dies zu lösen, landen verzögerungsverursachende Nachrichten in as4-outbound-delay anstatt in as4-outbound. Dies dient zwei Zwecken: Es unterbricht die enge Wiederverarbeitungsschleife, die entstehen würde, wenn fehlgeschlagene Nachrichten sofort wieder an den Anfang der Standard-Queue zurückgegeben würden, und es stellt eine dedizierte Queue bereit, die unabhängig überwacht werden kann, um Backpressure und Fehlerraten pro Partner zu beobachten.

Sending the business message via delay queue

Der Service veröffentlicht die zu sendende Nachricht an den Partner und verarbeitet diese auch über die Queue as4.outbound.delay.default

delayExchangeName=as4.outbound.delay

The concurrency can be controlled by:

spring.cloud.stream.bindings.consumeDelayOutboundMessage-in-0.consumer.concurrency=5

Um dies zu beheben, wird die Eigenschaft as4.outbound.max-connections-per-mpid eingeführt, um die maximale Anzahl paralleler Verbindungen zu einem einzelnen Marktpartner zu einem bestimmten Zeitpunkt zu steuern. Wenn die Anzahl der aktiven Verbindungen für eine bestimmte MPID dieses Limit erreicht oder ein Fehler bei der Verarbeitung einer Nachricht auftritt, wird die Nachricht nicht erneut in die Standard-Queue as4-outbound veröffentlicht, sondern stattdessen in die dedizierte Queue as4-outbound-delay geleitet, wo sie wartet, bevor sie erneut versucht wird.

# Maximum parallel connections per partner
as4.outbound.max-connections-per-mpid=200

Der Standardwert (200) ist auf eine sehr hohe Zahl gesetzt, um das bestehende Normalverhalten beizubehalten. Es wird empfohlen, dieses Verhalten zu überschreiben, um es an die Anforderungen des Systems anzupassen.

Anhang: Gesamtkonfiguration

Proxy-Konfiguration

Falls ausgehende Verbindungen über einen HTTP-Proxy laufen müssen:

proxyEnable=true
proxyAddress=proxy.example.com
proxyPort=8080
proxyUser=
proxyPassword=

Default: proxyEnable=false. Proxy-Benutzer und -Passwort sind optional.

Keycloak

Falls der Outbound Sender auf geschützte Services (z.B. FSS) zugreifen muss, kann die Keycloak-Authentifizierung aktiviert werden:

keycloak.rest-client=true
keycloak.auth-server-url=http://host.docker.internal:9000/auth
keycloak.realm=as4
keycloak.resource=as4-backend
keycloak.credentials.secret=
keycloak.scope=
keycloak.username=
keycloak.password=

Default für keycloak.rest-client ist false.

Folgende Konfiguration reicht in einem Standard-System mit TLS aus: application.properties:

rabbitmq.host=rabbitmq3
rabbitmq.port=5672
rabbitmq.username=guest
rabbitmq.password=${RABBITMQ_PASSWORD}

# Timeout default to 300 second
connectionTimeout=300

# Die automatische Aktualisierung für Zertifikat-Caches kann über die Eigenschaft konfiguriert werden: Standard ist 0 0 6 * * *
clear-certificate-cache=0 0 6 * * *
# Keystore-Dateien können während der Cache-Aktualisierung durch die Eigenschaft standardmäßig false gelöscht werden
deleteKeystoreFiles=false

#=== FSS ===#
fss.server.api.url=http://fss:2222/fss/api/v1
## Page size for fss requests
fss.page.size.value=100

#=== SSL Properties ===#
client.ssl.enabled=true
ssl.partner.client=shared-client
addressServiceUrl=http://localhost:8089/aep-as4-address-service

JDK_JAVA_OPTIONS:

JDK_JAVA_OPTIONS: "-Djdk.tls.cipherSuites=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_ECDSA_WITH_BRAINPOOLP384R1,TLS_ECDHE_ECDSA_WITH_BRAINPOOLP256R1,TLS_ECDHE_ECDSA_WITH_SECP384R1,TLS_ECDHE_ECDSA_WITH_SECP256R1 -Djdk.tls.namedGroups=brainpoolP384r1,brainpoolP256r1,secp384r1,secp256r1"

Optionale Proxy Configuration

Es ist möglich den Outbound-Sender mit einem Proxy zu verbinden. Falls Basic-Authentifizierung mit User und Passwort nowendig sind, kann dies ebenfalls konfiguriert werden.

#=== Proxy Properties ===#
proxyEnable=false
proxyAddress=
proxyPort=
proxyUser=
proxyPassword=

Falls der Proxy benötigt wird, muss die Eigenschaft proxyEnable auf true gesetzt werden. Die proxyAddress gibt die Addresse (Host) an, unter welcher der Proxy verfügbar ist. Wenn der Proxy beispielsweise unter localhost läuft, wird 127.0.0.1 eingetragen. Sollte keine Authentifizierung mit User und Passwort erforderlich sein, können diese Eigenschaften leer bleiben.

Allgemeine Hinweise zur Konfiguration finden Sie hier.

View Me   Edit Me