diff --git a/distribution/examples/ssl/README.md b/distribution/examples/ssl/README.md index d4f13bd419..a87b0bd4ce 100644 --- a/distribution/examples/ssl/README.md +++ b/distribution/examples/ssl/README.md @@ -1,6 +1,7 @@ # SSL/TLS Examples -|Example|Description| -|---|---| -|[to-backend](to-backend)|How to secure communication from the API Gateway to a backend server.| -|[api-with-tls](api-with-tls)|How to protect APIs deployed on the Gateway| \ No newline at end of file +| Example | Description | +|--------------------------------------------|--------------------------------------------------------------------------| +| [to-backend](to-backend) | How to secure communication from the API Gateway to a backend server. | +| [api-with-tls-pkcs12](api-with-tls-pkcs12) | How to protect APIs deployed on the Gateway with PKCS12 TLS certificates | +| [api-with-tls-pem](api-with-tls-pem) | How to protect APIs deployed on the Gateway with PEM TLS certificates | \ No newline at end of file diff --git a/distribution/examples/ssl/api-with-tls-pem/README.md b/distribution/examples/ssl/api-with-tls-pem/README.md new file mode 100644 index 0000000000..4374bd2a50 --- /dev/null +++ b/distribution/examples/ssl/api-with-tls-pem/README.md @@ -0,0 +1,75 @@ +# Protecting APIs with SSL/TLS + +This example describes how to secure an API with SSL/TLS. + + +## Running the Example + +1. Run `service-proxy.bat` or `service-proxy.sh` +2. Open the following URL in your browser. Please do not forget to use `https` instead of `http`. + + `https://localhost/` + + You should get a warning that the certificate is not trustworthy. Here you can ignore the warning. In production, you should use your own certificates. + +3. You can also access the API using `curl`. The option `-k` suppresses the check for self-signed certificates. + +``` +curl -k -v https://localhost/ +``` + +The output should look like this: + +``` +* Trying 127.0.0.1:443... +* Connected to localhost (127.0.0.1) port 443 (#0) +* ALPN, offering h2 +* ALPN, offering http/1.1 +* successfully set certificate verify locations: +* CAfile: /etc/ssl/cert.pem +* CApath: none +* (304) (OUT), TLS handshake, Client hello (1): +* (304) (IN), TLS handshake, Server hello (2): +* (304) (IN), TLS handshake, Unknown (8): +* (304) (IN), TLS handshake, Certificate (11): +* (304) (IN), TLS handshake, CERT verify (15): +* (304) (IN), TLS handshake, Finished (20): +* (304) (OUT), TLS handshake, Finished (20): +* SSL connection using TLSv1.3 / AEAD-CHACHA20-POLY1305-SHA256 +* ALPN, server did not agree to a protocol +* Server certificate: +* subject: CN=membrane +* start date: Aug 5 10:41:09 2015 GMT +* expire date: Aug 2 10:41:09 2025 GMT +* issuer: CN=membrane +* SSL certificate verify result: self signed certificate (18), continuing anyway. +> GET / HTTP/1.1 +> Host: localhost +> +< HTTP/1.1 200 Ok +< Content-Type: application/json +< +{ +"success" : true +} +``` + +## Configuration + +Just put an SSL element into a proxy. See the [documentation](https://www.membrane-soa.org/service-proxy-doc/4.4/configuration/reference/ssl.htm). + +```xml + + + + + + + + + +``` + +--- +See: +- [ssl](https://membrane-soa.org/api-gateway-doc/current/configuration/reference/ssl.htm) reference \ No newline at end of file diff --git a/distribution/examples/ssl/api-with-tls-pem/membrane-key.pem b/distribution/examples/ssl/api-with-tls-pem/membrane-key.pem new file mode 100644 index 0000000000..8a512cca98 --- /dev/null +++ b/distribution/examples/ssl/api-with-tls-pem/membrane-key.pem @@ -0,0 +1,52 @@ +-----BEGIN PRIVATE KEY----- +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 +zalYKwYqE5Kl/6y9wIwHl261JvurgbY= +-----END PRIVATE KEY----- diff --git a/distribution/examples/ssl/api-with-tls-pem/membrane.pem b/distribution/examples/ssl/api-with-tls-pem/membrane.pem new file mode 100644 index 0000000000..943acbfa37 --- /dev/null +++ b/distribution/examples/ssl/api-with-tls-pem/membrane.pem @@ -0,0 +1,28 @@ +-----BEGIN CERTIFICATE----- +MIIExTCCAq2gAwIBAgIEd3OJmTANBgkqhkiG9w0BAQsFADATMREwDwYDVQQDEwht +ZW1icmFuZTAeFw0xNTA4MDUxMDQxMDlaFw0yNTA4MDIxMDQxMDlaMBMxETAPBgNV +BAMTCG1lbWJyYW5lMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAqSsz +wxZRZp/Wa+qxQ2VDOnnCVPjBtoAlWkjgpyA6ytOPh7mnNPPcA1WSj3J0bfdpJR86 +SzsIuDaeFMB+HNI3i+eXWrzn0zGkD73NXfKP1d9HADcXxYvuOBqqdrFYDxW6AY7R +CLu+Vf3/jdsfIoR4qPJyNhFiocedE2+5BEUURxb02ieyQi81cIQ+PFBVoxUwUn7t +v7Rj8nXHWm6I/6CCLOZR4G28lSrzWQGTWDgC8iSr/c19ha1KAg/afiJ63I3bzbIY +lMDK6TIKqLyK3IRhY8FVKg633IL3QxQkakuCssT4sMIGhsgHbVqbmVyfy8rOUGeq +sJSHO2l2cTLHkt84dL1Vvf4BB9sHSpY5y3IymvCQ4/DsCa8082PO3TpFc7IqKDey +IJohK1gFiUqtLB5LAbPghFMs2ceVBDkymSfsT5sIIdh9bAnocWkh4bKIzokmbUnZ +/nx4wsqTpY2yWc9yCZyD+eP3jq4PDxrs3WKBIy2fwBGweyP+Qi0IdJght+x+HMMm +S/YsXQEuW2RKzkwPOEt+AIvsKCKke3dcedq1msrDktf8xMa2U8/fcjwmiD1No/Kl +55h8fNICuseaXHrA8nRBqxZO7WsOv13lq0OObRszY6JCeNSmFMTOVJt/WLLiLlbL +NGF0GLjL2Vmdcg2v66aGLy+pwgwkZeiOoDwncHECAwEAAaMhMB8wHQYDVR0OBBYE +FE8JEAm4kPj2CQLM+lJ9YwDsyICXMA0GCSqGSIb3DQEBCwUAA4ICAQAlaRpG0SNi +wy+PR4yQOlwgCM6OTb5eG8UqIzaqU20odRJm3vtMupI3NPiENR5iZfnY9YPC3+HC +vaTAWCcX02Ic0ad6rKVE4AGYgjDlW/Phe86Gykg/IyEwXMTEpcDENFIYE/3QltfZ +b9DUbUsJtQbZxSIko0xvnvCqMwWU6kLqHUwigzxboDoXiIN4fGpUUzrOxqVj2HxF +/0B8yDBEYk1iI+JQRH5O3KC9W8AgweUBKFjTprUKvcM3AA4zGTCsv8KBrAB9xdxW +AXiBU6SOmSM0RWpLY/5NUnRnxRtSYH/xCk4gbiH4ZtT0FiGxpWD1VWp2WXHziPjT +wwxMYb2q1bnZt4IbnFShVFQd/oR7fVZRyvmVBKRargoUwXxQYvK0e9ptWdZr959R +TQsmTIpP5BLqWiX9tntvNPFAvz6BL7XP+oztrqob23JfI8HTH8wfj/RVR6472mQq +JXXq38C/HGbfrK60SGuwjQ6nTHn6RiSQ+ynbRnr8S6QlzwNd1mGoGKdwckATxTsk +zdqfCgCcE4u6L2JX4Hx4n2aoudsh/TzPovszxiNEVmQTADY4I+gs7BGBFN8lzv+K +VFoJUfPX2srbV1wDXJHydJgHcOBXJrd8hD0AvnVUvuclt6qWle1cePbp1UNncx2B +GGH5p3GIokdCasDetqjiGRPa3Xn1393qbw== +-----END CERTIFICATE----- diff --git a/distribution/examples/ssl/api-with-tls-pem/proxies.xml b/distribution/examples/ssl/api-with-tls-pem/proxies.xml new file mode 100644 index 0000000000..fef3852abf --- /dev/null +++ b/distribution/examples/ssl/api-with-tls-pem/proxies.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/distribution/examples/ssl/api-with-tls/service-proxy.bat b/distribution/examples/ssl/api-with-tls-pem/service-proxy.bat similarity index 100% rename from distribution/examples/ssl/api-with-tls/service-proxy.bat rename to distribution/examples/ssl/api-with-tls-pem/service-proxy.bat diff --git a/distribution/examples/ssl/api-with-tls/service-proxy.sh b/distribution/examples/ssl/api-with-tls-pem/service-proxy.sh similarity index 100% rename from distribution/examples/ssl/api-with-tls/service-proxy.sh rename to distribution/examples/ssl/api-with-tls-pem/service-proxy.sh diff --git a/distribution/examples/ssl/api-with-tls/README.md b/distribution/examples/ssl/api-with-tls-pkcs12/README.md similarity index 100% rename from distribution/examples/ssl/api-with-tls/README.md rename to distribution/examples/ssl/api-with-tls-pkcs12/README.md diff --git a/distribution/examples/ssl/api-with-tls/proxies.xml b/distribution/examples/ssl/api-with-tls-pkcs12/proxies.xml similarity index 100% rename from distribution/examples/ssl/api-with-tls/proxies.xml rename to distribution/examples/ssl/api-with-tls-pkcs12/proxies.xml diff --git a/distribution/examples/ssl/api-with-tls-pkcs12/service-proxy.bat b/distribution/examples/ssl/api-with-tls-pkcs12/service-proxy.bat new file mode 100644 index 0000000000..6742f74b41 --- /dev/null +++ b/distribution/examples/ssl/api-with-tls-pkcs12/service-proxy.bat @@ -0,0 +1,18 @@ +@echo off +if not "%MEMBRANE_HOME%" == "" goto homeSet +set "MEMBRANE_HOME=%cd%\..\..\.." +echo "%MEMBRANE_HOME%" +if exist "%MEMBRANE_HOME%\service-proxy.bat" goto homeOk + +:homeSet +if exist "%MEMBRANE_HOME%\service-proxy.bat" goto homeOk +echo Please set the MEMBRANE_HOME environment variable to point to +echo the directory where you have extracted the Membrane software. +exit + +:homeOk +set "CLASSPATH=%MEMBRANE_HOME%" +set "CLASSPATH=%MEMBRANE_HOME%/conf" +set "CLASSPATH=%CLASSPATH%;%MEMBRANE_HOME%/starter.jar" +echo Membrane Router running... +java -classpath "%CLASSPATH%" com.predic8.membrane.core.Starter -c proxies.xml \ No newline at end of file diff --git a/distribution/examples/ssl/api-with-tls-pkcs12/service-proxy.sh b/distribution/examples/ssl/api-with-tls-pkcs12/service-proxy.sh new file mode 100644 index 0000000000..2c6c5d0d66 --- /dev/null +++ b/distribution/examples/ssl/api-with-tls-pkcs12/service-proxy.sh @@ -0,0 +1,35 @@ +#!/bin/bash +homeSet() { + echo "MEMBRANE_HOME variable is now set" + CLASSPATH="$MEMBRANE_HOME/conf" + CLASSPATH="$CLASSPATH:$MEMBRANE_HOME/starter.jar" + export CLASSPATH + echo Membrane Router running... + java -classpath "$CLASSPATH" com.predic8.membrane.core.Starter -c proxies.xml + +} + +terminate() { + echo "Starting of Membrane Router failed." + echo "Please execute this script from the appropriate subfolder of MEMBRANE_HOME/examples/" + +} + +homeNotSet() { + echo "MEMBRANE_HOME variable is not set" + + if [ -f "`pwd`/../../../starter.jar" ] + then + export MEMBRANE_HOME="`pwd`/../../.." + homeSet + else + terminate + fi +} + + +if [ "$MEMBRANE_HOME" ] + then homeSet + else homeNotSet +fi + diff --git a/distribution/src/test/java/com/predic8/membrane/examples/ExampleTestsWithInternet.java b/distribution/src/test/java/com/predic8/membrane/examples/ExampleTestsWithInternet.java index 632fa4cb63..e2d35e028b 100644 --- a/distribution/src/test/java/com/predic8/membrane/examples/ExampleTestsWithInternet.java +++ b/distribution/src/test/java/com/predic8/membrane/examples/ExampleTestsWithInternet.java @@ -19,7 +19,8 @@ import com.predic8.membrane.examples.tests.*; import com.predic8.membrane.examples.tests.loadbalancing.Loadbalancing4XmlSessionTest; import com.predic8.membrane.examples.tests.openapi.APIProxyTest; -import com.predic8.membrane.examples.tests.ssl.SSLServerApiWithTlsTest; +import com.predic8.membrane.examples.tests.ssl.SSLServerApiWithTlsPemTest; +import com.predic8.membrane.examples.tests.ssl.SSLServerApiWithTlsPkcs12Test; import com.predic8.membrane.examples.tests.ssl.ToBackendTest; import com.predic8.membrane.examples.tests.validation.FormValidationTest; import com.predic8.membrane.examples.tests.versioning.RoutingTest; @@ -43,7 +44,8 @@ LoggingTest.class, LoginTest.class, RewriterTest.class, - SSLServerApiWithTlsTest.class, + SSLServerApiWithTlsPkcs12Test.class, + SSLServerApiWithTlsPemTest.class, ToBackendTest.class, ThrottleTest.class, XSLTTest.class, diff --git a/distribution/src/test/java/com/predic8/membrane/examples/tests/ssl/SSLServerApiWithTlsPemTest.java b/distribution/src/test/java/com/predic8/membrane/examples/tests/ssl/SSLServerApiWithTlsPemTest.java new file mode 100644 index 0000000000..d7ee98b8dd --- /dev/null +++ b/distribution/src/test/java/com/predic8/membrane/examples/tests/ssl/SSLServerApiWithTlsPemTest.java @@ -0,0 +1,26 @@ +package com.predic8.membrane.examples.tests.ssl; + +import com.predic8.membrane.examples.util.DistributionExtractingTestcase; +import com.predic8.membrane.examples.util.Process2; +import org.junit.jupiter.api.Test; + +import static com.predic8.membrane.test.AssertUtils.*; + +public class SSLServerApiWithTlsPemTest extends DistributionExtractingTestcase { + + @Override + protected String getExampleDirName() { + return "ssl/api-with-tls-pem"; + } + + @Test + void test() throws Exception { + replaceInFile2("proxies.xml", "443", "3023"); + + try(Process2 ignored = startServiceProxyScript()) { + trustAnyHTTPSServer(3023); + assertContains("success", getAndAssert200("https://localhost:3023")); + } + } + +} diff --git a/distribution/src/test/java/com/predic8/membrane/examples/tests/ssl/SSLServerApiWithTlsTest.java b/distribution/src/test/java/com/predic8/membrane/examples/tests/ssl/SSLServerApiWithTlsPkcs12Test.java similarity index 88% rename from distribution/src/test/java/com/predic8/membrane/examples/tests/ssl/SSLServerApiWithTlsTest.java rename to distribution/src/test/java/com/predic8/membrane/examples/tests/ssl/SSLServerApiWithTlsPkcs12Test.java index 57b4525eea..66d6cd1593 100644 --- a/distribution/src/test/java/com/predic8/membrane/examples/tests/ssl/SSLServerApiWithTlsTest.java +++ b/distribution/src/test/java/com/predic8/membrane/examples/tests/ssl/SSLServerApiWithTlsPkcs12Test.java @@ -21,15 +21,15 @@ import static com.predic8.membrane.test.AssertUtils.*; -public class SSLServerApiWithTlsTest extends DistributionExtractingTestcase { +public class SSLServerApiWithTlsPkcs12Test extends DistributionExtractingTestcase { @Override protected String getExampleDirName() { - return "ssl/api-with-tls"; + return "ssl/api-with-tls-pkcs12"; } @Test - public void test() throws Exception { + void test() throws Exception { replaceInFile2("proxies.xml", "443", "3023"); try(Process2 ignored = startServiceProxyScript()) {