This post is part 7 of a series sharing service implementation experience and possible applications of BTP Private Link Service on Azure. Find the introduction in part 1 of the series. Part 2 discusses the integration with Integration Suite. Part 4 focusses on how to debug and test your private-link-enabled app. Part 5 describes SAP Principal Propagation – cf user mapping to SAP backend users. Part 6 describes how to restrict access to your SAP backend endpoints to keep your auditor happy.
Continuing with the implementation journey of BTP Private Link Service (PLS) we will have a closer look at the new host name feature and finally close the loop on the end-to-end SSL setup.
Fig.1 pinkies being secured by SSL
Even though PLS is a private tunnel, it is a common practice to utilize transport layer encryption on all levels. Also keep in mind that the source of your communication in BTP originates from a shared environment.
Back to the issue at hand: Remember part 1, where the pinkie broke his swear and SSL peer verification failed for my private IP from BTP?
Back then I gave a short lookout how the different approaches to solve this look like. Quick recap:
- http instead of https
- Override SSL verifier in your CF app
- Configure TrustAll on your BTP Destination
Or setup a dedicated SSL handler. Another alternative is Server Name Indication. However, both options require host names. The workaround, while we were still using private IPs on BTP, was resolving through nip.io. Luckily as of Nov 24th we got upgraded to host names for PLS 😊
Once you create a new PLS and bind it to your app, you see the new fields. The property “additionalHostname” is a less stable but a shorter property (less than 63 characters) that may change for every new instance that you create. It considers that some cert providers have a domain name length limit.
The property “hostname” is considerably longer because it includes a subdomain consisting of a hash of the resource id from your own Azure subscription. That aspect makes it stable for that part of the name and allows the creation of wildcard certificates. So, even if you clean up the link on BTP or create multiple links to the same PLS on Azure, you can keep the same certificate. That reduces your maintenance overhead.
Fig.2 Screenshot of PLS hostname config
Using the new hostname value, you need to adjust all your destinations. Let’s start with the Basic Authentication scenario. Register the new host name from BTP on your SAP backend and import the certificate from your target into the trust store of the BTP destination service.
Fig.3 BTP Destination config without custom trust store
So, where do we get that certificate? That depends on if you are using an SAP WebDispatcher (WDisp) in front of our SAP backend or if you like to hit it directly. We will look at the WDisp option first because it offers access restrictions too. Given that it is currently the best option to design the communication channel. Have a look at part 6 for more details.
Configuring SSL with SAP WDisp
Continuing our setup journey, you need to either adjust your existing Personal Security Environment (PSE) “SAPSSLS” or create a new one using the WDisp Admin UI. Anticipating that you have existing trust setups and the desire to stay flexible going forward, I recommend creating an additional PSE for the purpose of handling PLS connections.
The Admin UI is reachable on “https://your -domain:<your ssl-port>/sap/wdisp/admin/public/default.html”.
Next, you navigate to PSE Management and hit “Create New PSE”.
Fig.4 Screenshot of SAP WebDispatcher Admin UI to create new PSEs
Give it a meaningful file name following the SAP naming conventions. Have a look at the SAP docs for more details.
Fig.5 Create new PSE screen
Under “Distinguished Name” you put your hostname collected from BTP earlier on using this pattern:
DNS=PLS-HOSTNAME, CN=PLS-HOSTNAME or
To reduce maintenance, I recommend creating a wild card certificate. However, you can’t combine with SNI now. WDisp accepts such configuration but ignores the SSL request.
That means you need to either configure a dedicated PSE per private link without SNI or re-use your existing setup with SNI but create certificates without wildcards. Refer to note 2527968 SSL WildCard Certificates for SNI for further details.
Let’s look at SNI first as shown in fig.5. As a result of that create process, you get a new environment including the trusted certificate. Next, you need to export the certificate for the BTP Destination trust store.
Fig.6 Screenshot of newly created PSE setup for PLS
I copied the encoded text and created a new file called “wdisp-pls-cert.cer” locally. Move back to the Destination config on BTP and upload your new certificate to the trust store.
Fig.7 Destination config including certificate for PLS host name created through PSE
But how does the SAP WDisp know, which PSE to check for incoming traffic? I will describe two options:
1. Use SNI without wild card certitifcate
That challenge is addressed with the parameter option SNI_CREDS.
Fig.8 SAP Wdisp parameter config for SNI
For every incoming connection the WDisp evaluates the server’s name (in our case the PLS host name) and picks the certificate from the associated PSE.
2. Without SNI including wild card certificate
This approach requires enhancement of the server port (SSL listener) and its corresponding SSL config. The approach to adding a value and storing it is the same as shown in fig.8.
Fig.9 SAP WDisp config without SNI and wildcard certificate
I maintained an additional port with value 44310 and assigned the PSE that holds the wildcard certificate.
Fig.10 SAP WDisp config for PSE with wildcard certificate
Once you are done with either of the described options, trigger a restart of the WDisp (Core System >> Monitor >> Status >> Shutdown SAP Web Dispatcher). It comes up again by itself.
As mentioned before, you could also configure both options on the target ABAP server directly.
Configuration approaches for SSL with SAP NetWeaver directly
Given that the foundation for ICM, SNI etc. is identical between the WDisp and ABAP NetWeaver, you can re-use the files created by your WDisp.
The PSE needs to be stored in folder /usr/sap/<SID>/<instance>/sec on your ABAP system.
Using SAP GUI navigate to transaction SMICM >> GoTo >> Parameters >> Change. Identify your ICM setting “icm/ssl_config_0” and add SNI_CREDS accordingly. Note single spaces on ABAP config compared to WDisp config before. Find the official SAP docs for the param section here.
The same can be applied for the settings without SNI.
In case you are not going down the copy route from SAP WDisp, you will need to use the SAP CLI tool “sapgenpse”. Find the official docs and examples by SAP here. Of course, you also need a restart of the app server to load the new PSEs.
After that configuration marathon, we are ready for some testing 😊 as usual open the approuter target and navigate to the Java servlet associated with your Destination. As promised before, I am hitting the SAP Products with Basic Authentication, just as we did on the very first post of the series.
Et voilà ssl established end-to-end. Hurray!
Fig.11 Screenshot of OData result using end-to-end SSL config
Uhh, that was quite the ride. I showed you today how you can finally enable end-to-end SSL encryption for your communication from BTP via PLS to your SAP backends. This approach was enabled by the hostname feature upgrade of PLS. In addition to that I explained the different approaches with the SAP WebDispatcher as a proxy and alternatively the ABAP backend directly.
I favour the SAP WebDispatcher, because of its URL filtering and access control capabilities. Furthermore, introducing wild card certificates is desirable to avoid certificate re-creation on PLS deletes, moves within subaccounts etc. or pointing multiple links at the same PLS on Azure.
You learned how you can apply Server Name Indication and SSL ports to enable a flexible and secure setup with BTP and PLS.
Any further inputs from you @Developers and Security Experts?
Find the related GitHub repos here.