GithubHelp home page GithubHelp logo

sap-cf-proxy's Introduction

sap-cf-proxy - proxy to all destinations in SAP BTP Cloud Foundry subaccount

Why?

You might ask why do I need this project? The answer is whenever you want to work with on-premise destinations or a system connected through a Cloud Connector and you don't have a VPN connection which would allow you to connect directly. But please note that you don't need this project when you're working with SAP Business Application Studio and you have a Cloud Connector connected to the subaccount BAS is running in.

Limitations

The authentication of the SAP BTP Cloud Foundry subaccount must be configured to use SAP ID or SAP Identity Authentication. For SAP Identity Authentication you must have the credentials of a local user.

How does it work

sap-cf-proxy Architecture

This proxy makes use of the possibility to connect via ssh into an app (sshenabler) that is running inside the SAP BTP Cloud Foundry environment. From there the so-called connectivity proxy is reachable. This proxy is provided by an instance of the Connectivity Service. On your development computer you have to start two programs:

  • the script that establishes the ssh tunnel and forwards requests from the local port 20003 and 20004 to connectivityproxy.internal.cf.eu10.hana.ondemand.com:20003 / 20004
  • the reverse proxy that by default listens on port 5050 and acts as your local endpoint for calls that should be forwarded to the on premise system

When your local app that you develop e.g. a CAP Application using an external service, a SAPUI5 App or a REST Client Script sends a request to the proxy, it will either use the username / password provided as an basic authentication header or via the environment variables USERNAME / PASSWORD and use that to authenticate on the XSUAA service using the password grant type. In return a JWT is retrieved. This token is sent in the backend request and is translated to the X.509 certificate used for principal propagation in the Cloud Connector. The local reverse proxy sends request for an on premise destination to local port that are forwarded via the ssh tunnel to the proxy in the BTP.

When you want to directly connect to e.g. a database running on-premise (Sybase ASE, Postgres, HANA) then this repository provides a proxy that tunnels TCP requests through to the database.

Prerequisites

You are logged into your SAP BTP Cloud Foundry subaccount via the cf CLI and you have the Multitarget Build Tool installed (mbt).

Installation

Clone the repository to a directory of your choice:

git clone [email protected]:jowavp/sap-cf-proxy.git

Setup

Run the following commands in a terminal window in the sap-cf-proxy directory :

npm install
npm run build:mta
npm run deploy:cf
npm run enable-ssh

Now check the SAP BAP Cockpit for the correct setting for the connectivity proxy.

The start-sshtunnel command is currently forwarding the requests to: 'connectivityproxy.internal.cf.eu10.hana.ondemand.com:20003' .

Connectivity Proxy

Go to the SAP BTP Cockpit and open the details of the deployed app sshenabler. Navigate there to the Environment Variables.

This is found by opening the cloud foundry space in the correct sub-account. Click on the deployed application sshenabler and click on the Environment Variables in the left-hand menu.

Application menu

Copy the content of the textbox System Provided to a local file. Only the "VCAP_SERVICES" section is required. Do not add the "VCAP_APPLICATION" section.

The host you are looking for is in the credentials.onpremise_proxy_port of the sshenabler Environment Variables.

This is set in configuration in package.json so update this config section to the setting in the Environment Variables

  "config":{
    "proxy": "connectivityproxy.internal.cf.eu10.hana.ondemand.com"
  },

Once this configuration is complete you can now run:

npm run start:sshtunnel

The result should be something like:

> [email protected] start:sshtunnel
> cf ssh sshenabler -L 20003:$npm_package_config_proxy:20003 -L 20004:$npm_package_config_proxy:20004

vcap@<guid>:~$

and you will be able to enter commands on the server if you wish.

Forward HTTP requests (CAP, UI5)

Once you have created the local default-env.json as described above, in another terminal window of the sap-cf-proxy app run:

npm start

Forward TCP data (Database connection)

Go to the SAP BTP Cockpit and open the details of the deployed app sshenabler. Navigate there to the Environment Variables. Copy the content of the textbox System Provided to a local file called default-env.json in the directory socks-proxy.

Then run the following commands in another terminal window. Make sure to change ON_PREMISE_HOST and ON_PREMISE_PORT to values that you see in the Cloud Connector configuration.

cd socks-proxy
mvn compile
ON_PREMISE_HOST=hostnameOfOnPremiseSystem ON_PREMISE_PORT=portOfOnPremiseSystem VCAP_SERVICES=$(jq '.VCAP_SERVICES' default-env.json|jq -c .) mvn compile exec:java -Dexec.mainClass="StartSocksProxy"

Now you can open your preferred database tool or also your application that uses JDBC to connect and just point it to localhost:5050.

Proxy Configuration (valid for HTTP request forwarding)

Following properties can be configured in a .env file in the root folder of the project.

Property Description Defaul value
PORT Proxy port 5050
DESTINATION_PROPERTY_NAME Header property to define the target destination X-SAP-BTP-destination
DEFAULT_DESTINATION If no target destination is set in the request to the proxy we use this destination nama. SAP_ABAP_BACKEND
CFPROXY_HOST Host where the port-forwarding is running to the CF proxy 127.0.0.1
CFPROXY_POST Port that is forwarded to the CF proxy 20003
USERNAME Username in cloud foundry, if no user is set you have to send an authorization header.
PASSWORD Password in cloud foundry, if no password is set you have to send an authorization header.

Testing

Using the VS Code Extension REST Client you can execute the test in test/ping.http. Before you can run the test you have to create a .env file in the test folder with the following (of course adjusted) content:

sapcpproxy=http://localhost:5050
sapid_username="<user-email>"
sapid_password="<password>"

Connect a Cloud Connector to your Subaccount and create the following destinations:

  • SAP_ABAP_BACKEND_NO_AUTH
  • SAP_ABAP_BACKEND_BASIC_AUTH

Then run the test. The result should be:

<html><body>Server reached.</body></html>

in both cases.

Troubleshooting

If you start the sshtunnel with npm run start:sshtunnel and get the following error:

Error opening SSH connection: You are not authorized to perform the requested action.

then you need to:

cf enable-ssh sshenabler;
cf restart sshenabler;

Other troubleshooting is available

update modules @todo

Currently the following warning are emmited on npm i

The deprecated libraries need to be updated.

npm WARN deprecated @types/[email protected]: This is a stub types definition. pino provides its own type definitions, so you do not need this installed.
npm WARN deprecated [email protected]: ๐Ÿ™Œ  Thanks for using Babel: we recommend using babel-preset-env now: please read https://babeljs.io/env to update!
npm WARN deprecated @sap-cloud-sdk/[email protected]: 1.x is no longer maintained.
npm WARN deprecated @sap-cloud-sdk/[email protected]: 1.x is no longer maintained.
npm WARN deprecated @sap-cloud-sdk/[email protected]: Version 1 of SAP Cloud SDK is no longer maintained. Check the upgrade guide for switching to version 2: https://sap.github.io/cloud-sdk/docs/js/guides/upgrade-to-version-2.
npm WARN deprecated [email protected]: core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.


sap-cf-proxy's People

Contributors

gregorwolf avatar jowavp avatar njames avatar spamsch avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

sap-cf-proxy's Issues

Cache destination information

Also JWT issued for the Proxy-Authorization is valid for 12 hours. So we can cache it to speed up the 2nd request.

First time user: MTA build fails

First had to npm -g i npm-run-all, that was a quick fix, I have no clue how to continue here:

โฏ npm run build:mta

> [email protected] build:mta
> mbt build

[2021-11-30 14:55:18]  INFO Cloud MTA Build Tool version 1.2.7
[2021-11-30 14:55:18]  INFO generating the "Makefile_20211130145518.mta" file...
[2021-11-30 14:55:18]  INFO done
[2021-11-30 14:55:18]  INFO executing the "make -f Makefile_20211130145518.mta p=cf mtar= strict=true mode=" command...
[2021-11-30 14:55:18]  INFO validating the MTA project
[2021-11-30 14:55:18]  INFO running the "before-all" build...
[2021-11-30 14:55:18]  INFO executing the "npm install --production" command...
.
up to date, audited 178 packages in 1s

34 packages are looking for funding
  run `npm fund` for details

2 vulnerabilities (1 moderate, 1 high)

To address all issues, run:
  npm audit fix

Run `npm audit` for details.
[2021-11-30 14:55:19]  INFO executing the "npm run build" command...

> [email protected] build
> run-s build:tsc build:sshenabler


> [email protected] build:tsc
> tsc

.ts/proxy/authentication.ts(1,24): error TS7016: Could not find a declaration file for module '@sap/xsenv'. '/home/pieter/projects/sap-cf-proxy/node_modules/@sap/xsenv/index.js' implicitly has an 'any' type.
  Try `npm i --save-dev @types/sap__xsenv` if it exists or add a new declaration (.d.ts) file containing `declare module '@sap/xsenv';`
ts/proxy/index.ts(2,23): error TS7016: Could not find a declaration file for module 'http-proxy'. '/home/pieter/projects/sap-cf-proxy/node_modules/http-proxy/index.js' implicitly has an 'any' type.
  Try `npm i --save-dev @types/http-proxy` if it exists or add a new declaration (.d.ts) file containing `declare module 'http-proxy';`
ts/proxy/index.ts(3,18): error TS7016: Could not find a declaration file for module 'pino'. '/home/pieter/projects/sap-cf-proxy/node_modules/pino/pino.js' implicitly has an 'any' type.
  Try `npm i --save-dev @types/pino` if it exists or add a new declaration (.d.ts) file containing `declare module 'pino';`
ts/proxy/index.ts(6,24): error TS7016: Could not find a declaration file for module '@sap/xsenv'. '/home/pieter/projects/sap-cf-proxy/node_modules/@sap/xsenv/index.js' implicitly has an 'any' type.
  Try `npm i --save-dev @types/sap__xsenv` if it exists or add a new declaration (.d.ts) file containing `declare module '@sap/xsenv';`
ts/proxy/index.ts(60,32): error TS7006: Parameter 'proxyReq' implicitly has an 'any' type.
ts/proxy/index.ts(60,42): error TS7006: Parameter 'req' implicitly has an 'any' type.
ts/proxy/index.ts(60,47): error TS7006: Parameter 'res' implicitly has an 'any' type.
ts/proxy/index.ts(60,52): error TS7006: Parameter 'options' implicitly has an 'any' type.
ERROR: "build:tsc" exited with 2.
[2021-11-30 14:55:21] ERROR the "before-all"" build failed: could not execute the "npm run build" command: exit status 1
make: *** [Makefile_20211130145518.mta:28: pre_build] Error 1
Error: could not build the MTA project: could not execute the "make -f Makefile_20211130145518.mta p=cf mtar= strict=true mode=" command: exit status 2

Suggestion: Use the @sap-cloud-sdk/core for Destination / Connectivity details

As the SAP Cloud SDK Javascript / Typescript is Open Source, I would highly suggest to leverage that for retrieving destination and connectivity information.
For example:
{ getDestinationFromDestinationService } = require('@sap-cloud-sdk/core')
And if Destination has the Proxy type OnPremise, retrieve the Connectivity related headers with:
addProxyConfigurationOnPrem
or if you want the full flow which also accounts for subscriber/provider tenants and all:
{ getDestination } = require('@sap-cloud-sdk/core')

For more see:
https://sap.github.io/cloud-sdk/api/1.39.0/modules/sap_cloud_sdk_core

upgrade Readme documentation

Dear contributers ,

this project seems to solve a big issue for developers willing to consume on-premise systems locally, but I have a hard time understanding the architecture with the ssh tunnel .

if you can provide more details that would help a lot. i can also blog on it on https://blogs.sap.com once I understand how it works.

thank you

401 Unauthorized while testing /sap/bc/ping

Hi Gregor,

Per your advice, I am creating an issue here.

Issue Description: ping test to service /sap/bc/ping returns 401 Unauthorized.

Landscape: On premise system is connected to BTP via cloud connector. A destination is created of type On premise as screenshot below. The backend user exists and password is working.
image

Deployed sshenabler to BTP and it works fine. Copied the system variables into local file default-env.json under root of sap-cf-proxy project.

No environment variables set (destination, http_proxy, etc)

SSH into SSHEnabler app
image

In another terminal, npm is listening to 5050
image

Maintained a .env file under Test directory with BTP login email and password with sapcpproxy=http://localhost:5050
In ping.http the below URL is called via VS Code rest client extension
image

Output:
image

Api call to /sap/public/ping works fine. I am not sure what authorization am I missing. We confirmed that we added / in cloud connector under resources.

What is working:
From postman, I could call an api successfully with below URL but does not work if I dont mention the "sap-client" field.
http://localhost:5050/sap/opu/odata/sap/API_BUSINESS_PARTNER/A_BusinessPartner?sap-client=102&$format=json&$select=BusinessPartner

Thank you for the great tool. Any help would be greatly appreciated!

Thanks
Rajkumar Elango

It must be possible to specify the value SAP-Connectivity-SCC-Location_ID header

Multiple Cloud Connectors can be connected to one SAP BTP Cloud Foundry Subaccount. To distinguish this connectors they get a Location ID. When using the Connectivity Service service this Location ID can be set via the header:

SAP-Connectivity-SCC-Location_ID

This is documented in Specify a Cloud Connector Location ID. I think that adding a variable like for DEFAULT_DESTINATION i.e. defining DEFAULT_LOCATION_ID is the way to go.

Cache JWT retrieved by basicToJWT

The JWT issued by BTP is valid for 12 hours. So we should cache the token to get a quicker response for the second request by the same user.

Remove dependency to jq

The socks-proxy which is implemented in Java currently needs jq to be installed. jq parses the default-env.json and fills the VCAP_SERVICES environment variable. Maybe there is a way to get rid of this dependency.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.