diff --git a/.gitignore b/.gitignore index f72c084a0..61e7b17e1 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ .env .nyc_output coverage +/test/fixtures/certs/tmp diff --git a/README.md b/README.md index 30827c99d..ed1b5e794 100644 --- a/README.md +++ b/README.md @@ -208,7 +208,7 @@ Public filters are for requests that a recieved on your broker client and are in - The broker requires at least node@4.latest - Broker clients are *uniquely* identified (i.e. the same ID can't be used twice) -- If your private service is using a self signed https certificate, you will need to add the following environment value when runnning the client: `NODE_TLS_REJECT_UNAUTHORIZED=0` +- If your private service is using an unrecognized certificate, you will need to supply a Certificate Authority file and add the following environment value when runnning the client: `CA_CERT=ca.cert.pem` - Client will load your CA certificate and use it for requests to your internal service ## License diff --git a/lib/relay.js b/lib/relay.js index 6344b5074..6a30e047f 100644 --- a/lib/relay.js +++ b/lib/relay.js @@ -1,3 +1,5 @@ +const fs = require('fs'); +const path = require('path'); const request = require('request'); const undefsafe = require('undefsafe'); const parse = require('url').parse; @@ -112,6 +114,9 @@ function responseHandler(filterRules, config) { headers: headers, method, body, + agentOptions: { + ca: (() => {return config.caCert ? fs.readFileSync(path.resolve(process.cwd(), config.caCert)) : undefined;})(), + }, }, (error, response, body) => { debug('%s %s (%s)', method, result, (response || { statusCode: 500 }).statusCode); diff --git a/test/fixtures/certs/README.md b/test/fixtures/certs/README.md new file mode 100644 index 000000000..508a928a5 --- /dev/null +++ b/test/fixtures/certs/README.md @@ -0,0 +1,9 @@ +Generated using [coolaj86/nodejs-self-signed-certificate-example](https://github.com/coolaj86/nodejs-self-signed-certificate-example) + +Just run in this directory: + +```bash +bash ./generate-certs.sh +``` + +I'm adding these into the repository and not regenerating with say `postinstall` hook, so we don't rely on openssl being installed. diff --git a/test/fixtures/certs/ca/my-root-ca.crt.pem b/test/fixtures/certs/ca/my-root-ca.crt.pem new file mode 100644 index 000000000..9f2994e49 --- /dev/null +++ b/test/fixtures/certs/ca/my-root-ca.crt.pem @@ -0,0 +1,24 @@ +-----BEGIN CERTIFICATE----- +MIIEGDCCAwCgAwIBAgIJAJq8QHkEg5o5MA0GCSqGSIb3DQEBBQUAMGUxCzAJBgNV +BAYTAlVTMQ0wCwYDVQQIEwRVdGFoMQ4wDAYDVQQHEwVQcm92bzEjMCEGA1UEChMa +SW50ZXJuYWwgU2lnbmluZyBBdXRob3JpdHkxEjAQBgNVBAMTCWxvY2FsaG9zdDAe +Fw0xNjEwMTExMjIxNTZaFw0xOTA4MDExMjIxNTZaMGUxCzAJBgNVBAYTAlVTMQ0w +CwYDVQQIEwRVdGFoMQ4wDAYDVQQHEwVQcm92bzEjMCEGA1UEChMaSW50ZXJuYWwg +U2lnbmluZyBBdXRob3JpdHkxEjAQBgNVBAMTCWxvY2FsaG9zdDCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBANI3e2jhyAoQOtenmDgqMaulDbd6LxB54+2H +EBZ94868s563HZfW1i9a322Njl8Z8Zs7Hp6X8NANtJeOjbOdocKV7UZ7mhiCirlE +1TeulfwgPbbDdjQ4QSCengESBdi1ai1Iy+bSxC8RX4xiRP1vEgUlsIEj50rQWjvq +NU9B+k0jwrfSYWSFz4OPL6p2kCKne8A34smpL02yaEcdkgy6d0joV4ggPMqv17cV +0WEr74pO+f/bFZD9IObrHibtp7GPdPmxK4bofNqPaVxXfp5BXp1TaNZhLwRBgVjT +tK7nU46A9TXMZ59vk9g3vv+fCCPy1s1d6/wRMso9yHj6hfResosCAwEAAaOByjCB +xzAdBgNVHQ4EFgQUnX++qBGyUBIpJkfIuYLAkS441rwwgZcGA1UdIwSBjzCBjIAU +nX++qBGyUBIpJkfIuYLAkS441ryhaaRnMGUxCzAJBgNVBAYTAlVTMQ0wCwYDVQQI +EwRVdGFoMQ4wDAYDVQQHEwVQcm92bzEjMCEGA1UEChMaSW50ZXJuYWwgU2lnbmlu +ZyBBdXRob3JpdHkxEjAQBgNVBAMTCWxvY2FsaG9zdIIJAJq8QHkEg5o5MAwGA1Ud +EwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBACzI+LS7z3DJDbwczhT4lW+qsexv +avXT7x/Zt2Wv+szjNYRA4LYFGTQ/JYCx9J2zg9Cc6uPxjWlJNjwTVT4WLKJPnuQf +PEEcYp5gJqpHBULdWIEcH9IROpnVQeZETTzLuFLGY6Ya8pA2j6E44pxE8c8wVYuP +RLL8ihFKlEi7iQFjPX8Y0Jq2Xfjo9puldN6Jes3SMQfMuP1MIwiDaTNXeyD4ZBBO +3wDVN4dQHV2Fcq8ES9c5jBKpTkg8a8tFp60WKz+eEAg3mGYkFQNBLyG+S8ZhZef1 +VAg3jV1MPjlSw7aGrCkadVwXXOJZmOAlQM5D4NvxnuRwLGCzrBv13q+bDqA= +-----END CERTIFICATE----- diff --git a/test/fixtures/certs/ca/my-root-ca.key.pem b/test/fixtures/certs/ca/my-root-ca.key.pem new file mode 100644 index 000000000..6779e29f2 --- /dev/null +++ b/test/fixtures/certs/ca/my-root-ca.key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEA0jd7aOHIChA616eYOCoxq6UNt3ovEHnj7YcQFn3jzryznrcd +l9bWL1rfbY2OXxnxmzsenpfw0A20l46Ns52hwpXtRnuaGIKKuUTVN66V/CA9tsN2 +NDhBIJ6eARIF2LVqLUjL5tLELxFfjGJE/W8SBSWwgSPnStBaO+o1T0H6TSPCt9Jh +ZIXPg48vqnaQIqd7wDfiyakvTbJoRx2SDLp3SOhXiCA8yq/XtxXRYSvvik75/9sV +kP0g5useJu2nsY90+bErhuh82o9pXFd+nkFenVNo1mEvBEGBWNO0rudTjoD1Ncxn +n2+T2De+/58II/LWzV3r/BEyyj3IePqF9F6yiwIDAQABAoIBAHBEISxKKEL3l/VE +FA8quYwpgcHTBv+NmSRpVTYt1VO7g1HoCW3l1k1EAr7HMpmniViVoiygiIMUTrYB +87tRG+qHl0hlCk68qMl48UXjf0Y/EbZhfOc2g9Gf5FI+BdFOUX4NupdzSEK6zIR0 +ltOiVcVZ84GEYymZTBdjZUUGv14iGzfa/GIdubxWyxlLpCcrxjH+6DcUVs/Ux5Nc +alN/z99j480PAllG2cMxp6ZRNi7THvG9hanWsV8vgc4fq5id3P3wDj6Ncnekg+PG +x/r7tREttvpvYqVSuSs6GChMy3ZNnC7IYqQgkgmBM5QREMtOADP5KZ7+nKTGmVwS +grdAgUECgYEA6k+3wouXHGYmYvV0wqUzxhFAavmZBw8yYmTNvgzwe42u3u+IGWZm +cN9+Q/9Tn+a4Jm14Rf5LqFD/dtWFie7tvgGJvFKvyaP3vHHbzNOlSocOaEc8HKMa +zumhXoVurzRFgd2HN8uaiMBHrKUpS4xIqsPgFxv/SEAet59d/5L92H8CgYEA5azQ +Gc6eVNVQ3xRz+5Qn8/V/YWqf4jsFf5e8RaJxbTJGBz848Jlor0SUQTJiMkO7tO7s +Q+dy1ldNxlkPsEcn580M9JF3XIQwmyAfCfWmM3kyZLwJiG1IaYphxFOuroLkTfsG +Chx7w5LpPzH+GRJRyi/O8y889ME31LyAY284//UCgYAO10PFX8APfWzbAb8GgR45 +YmhZHjwSFWVUlBvv+LPWr4+u8S8GpNTCO3Ws6uQqEZwCWxauIEA8hfzYUwflR6vp +SAGoWvhlZixP1Epeu90RTmKcOj7VdYNCLcwZx4vOLxpj8lsZLp04Ii2oAsIN1fHY +VxW/gPd3ZRBNAxwaDv5jEwKBgQCBuCxFFyzX7y9g/7VON2ylXlgWllk9NmaxnOrK +TahQq19gAnZPdeXpcAtoE2Pgzd67n2I0LAnxQ5f62hyBTH8ebfLOQ0auKz8krmy5 +fFPlqKMswAOGWWrXqT/02erER8tYu9m6ZkIEwPoaJktEr9MgJgZ11Y1RE7xL3DeL +cas47QKBgGnV9Oe3Rb0NyWr1w0uM92kHZ3DygIM6WoSF5hH/o3/Q4dDvTeJAjljv +Nix0epAKnpHwiaK2lc/HZ2qPvtOq12IdRNSeBKnKdC++g8ClipcGorAOwzjnyEur +G9xafplj85I0u8Cc1IPHGqtzmjbtA4QUeeu1DtOp5tabuZP/VQGb +-----END RSA PRIVATE KEY----- diff --git a/test/fixtures/certs/client/chain.pem b/test/fixtures/certs/client/chain.pem new file mode 100644 index 000000000..9f2994e49 --- /dev/null +++ b/test/fixtures/certs/client/chain.pem @@ -0,0 +1,24 @@ +-----BEGIN CERTIFICATE----- +MIIEGDCCAwCgAwIBAgIJAJq8QHkEg5o5MA0GCSqGSIb3DQEBBQUAMGUxCzAJBgNV +BAYTAlVTMQ0wCwYDVQQIEwRVdGFoMQ4wDAYDVQQHEwVQcm92bzEjMCEGA1UEChMa +SW50ZXJuYWwgU2lnbmluZyBBdXRob3JpdHkxEjAQBgNVBAMTCWxvY2FsaG9zdDAe +Fw0xNjEwMTExMjIxNTZaFw0xOTA4MDExMjIxNTZaMGUxCzAJBgNVBAYTAlVTMQ0w +CwYDVQQIEwRVdGFoMQ4wDAYDVQQHEwVQcm92bzEjMCEGA1UEChMaSW50ZXJuYWwg +U2lnbmluZyBBdXRob3JpdHkxEjAQBgNVBAMTCWxvY2FsaG9zdDCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBANI3e2jhyAoQOtenmDgqMaulDbd6LxB54+2H +EBZ94868s563HZfW1i9a322Njl8Z8Zs7Hp6X8NANtJeOjbOdocKV7UZ7mhiCirlE +1TeulfwgPbbDdjQ4QSCengESBdi1ai1Iy+bSxC8RX4xiRP1vEgUlsIEj50rQWjvq +NU9B+k0jwrfSYWSFz4OPL6p2kCKne8A34smpL02yaEcdkgy6d0joV4ggPMqv17cV +0WEr74pO+f/bFZD9IObrHibtp7GPdPmxK4bofNqPaVxXfp5BXp1TaNZhLwRBgVjT +tK7nU46A9TXMZ59vk9g3vv+fCCPy1s1d6/wRMso9yHj6hfResosCAwEAAaOByjCB +xzAdBgNVHQ4EFgQUnX++qBGyUBIpJkfIuYLAkS441rwwgZcGA1UdIwSBjzCBjIAU +nX++qBGyUBIpJkfIuYLAkS441ryhaaRnMGUxCzAJBgNVBAYTAlVTMQ0wCwYDVQQI +EwRVdGFoMQ4wDAYDVQQHEwVQcm92bzEjMCEGA1UEChMaSW50ZXJuYWwgU2lnbmlu +ZyBBdXRob3JpdHkxEjAQBgNVBAMTCWxvY2FsaG9zdIIJAJq8QHkEg5o5MAwGA1Ud +EwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBACzI+LS7z3DJDbwczhT4lW+qsexv +avXT7x/Zt2Wv+szjNYRA4LYFGTQ/JYCx9J2zg9Cc6uPxjWlJNjwTVT4WLKJPnuQf +PEEcYp5gJqpHBULdWIEcH9IROpnVQeZETTzLuFLGY6Ya8pA2j6E44pxE8c8wVYuP +RLL8ihFKlEi7iQFjPX8Y0Jq2Xfjo9puldN6Jes3SMQfMuP1MIwiDaTNXeyD4ZBBO +3wDVN4dQHV2Fcq8ES9c5jBKpTkg8a8tFp60WKz+eEAg3mGYkFQNBLyG+S8ZhZef1 +VAg3jV1MPjlSw7aGrCkadVwXXOJZmOAlQM5D4NvxnuRwLGCzrBv13q+bDqA= +-----END CERTIFICATE----- diff --git a/test/fixtures/certs/client/pubkey.pem b/test/fixtures/certs/client/pubkey.pem new file mode 100644 index 000000000..4f3a63a91 --- /dev/null +++ b/test/fixtures/certs/client/pubkey.pem @@ -0,0 +1,9 @@ +-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA77j88dFqCJiXgigrQAYR +2lt2tlRQqmTo+H/YYwFK0epuaAhVF4qzhoN3pcdbhaVL9+FRLl4DTKq3GtQId6lk +Rf927x/QYfA0FFDZWopg8aQUuC7ka30J8F01xG1/fw0wfMYziE8eQ/p+5sP1O18x +0E4stOL+IM+DltC4vFqis6fpirzWU90Fk23oUh9vJF0Yc8PA4pWm24dBnjYxkT2D +Z+uieI2fXvRf8Yurik0UMPDO+WsOTR1xRVScuDKnq9gePAY6nReUcxX6XcShKEjz +lYeMQca9KFOxYIb6B+DqBQ5SVJnFL2rtWmErL2h+QgU4OV56IVv4IDrDSWR5Wftd +hwIDAQAB +-----END PUBLIC KEY----- diff --git a/test/fixtures/certs/generate-certs.sh b/test/fixtures/certs/generate-certs.sh new file mode 100644 index 000000000..b7bde6bf3 --- /dev/null +++ b/test/fixtures/certs/generate-certs.sh @@ -0,0 +1,55 @@ +#!/bin/bash +FQDN='localhost' + +# make directories to work from +mkdir -p {server,client,ca,tmp} + +# Create your very own Root Certificate Authority +openssl genrsa \ + -out ca/my-root-ca.key.pem \ + 2048 + +# Self-sign your Root Certificate Authority +# Since this is private, the details can be as bogus as you like +openssl req \ + -x509 \ + -new \ + -nodes \ + -key ca/my-root-ca.key.pem \ + -days 1024 \ + -out ca/my-root-ca.crt.pem \ + -subj "/C=US/ST=Utah/L=Provo/O=Internal Signing Authority/CN=${FQDN}" + +# Create a Device Certificate for each domain, +# such as example.com, *.example.com, awesome.example.com +# NOTE: You MUST match CN to the domain name or ip address you want to use +openssl genrsa \ + -out server/privkey.pem \ + 2048 + +# Create a request from your Device, which your Root CA will sign +openssl req -new \ + -key server/privkey.pem \ + -out tmp/csr.pem \ + -subj "/C=US/ST=Utah/L=Provo/O=ACME Tech Inc/CN=${FQDN}" + +# Sign the request from Device with your Root CA +# -CAserial ca/my-root-ca.srl +openssl x509 \ + -req -in tmp/csr.pem \ + -CA ca/my-root-ca.crt.pem \ + -CAkey ca/my-root-ca.key.pem \ + -CAcreateserial \ + -out server/cert.pem \ + -days 500 + +# Create a public key, for funzies +# see https://gist.github.com/coolaj86/f6f36efce2821dfb046d +openssl rsa \ + -in server/privkey.pem \ + -pubout -out client/pubkey.pem + +# Put things in their proper place +rsync -a ca/my-root-ca.crt.pem server/chain.pem +rsync -a ca/my-root-ca.crt.pem client/chain.pem +cat server/cert.pem server/chain.pem > server/fullchain.pem diff --git a/test/fixtures/certs/server/cert.pem b/test/fixtures/certs/server/cert.pem new file mode 100644 index 000000000..8ea64bf19 --- /dev/null +++ b/test/fixtures/certs/server/cert.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDOTCCAiECCQDeQUEpn9zznTANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQGEwJV +UzENMAsGA1UECBMEVXRhaDEOMAwGA1UEBxMFUHJvdm8xIzAhBgNVBAoTGkludGVy +bmFsIFNpZ25pbmcgQXV0aG9yaXR5MRIwEAYDVQQDEwlsb2NhbGhvc3QwHhcNMTYx +MDExMTIyMTU2WhcNMTgwMjIzMTIyMTU2WjBYMQswCQYDVQQGEwJVUzENMAsGA1UE +CBMEVXRhaDEOMAwGA1UEBxMFUHJvdm8xFjAUBgNVBAoTDUFDTUUgVGVjaCBJbmMx +EjAQBgNVBAMTCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAO+4/PHRagiYl4IoK0AGEdpbdrZUUKpk6Ph/2GMBStHqbmgIVReKs4aDd6XH +W4WlS/fhUS5eA0yqtxrUCHepZEX/du8f0GHwNBRQ2VqKYPGkFLgu5Gt9CfBdNcRt +f38NMHzGM4hPHkP6fubD9TtfMdBOLLTi/iDPg5bQuLxaorOn6Yq81lPdBZNt6FIf +byRdGHPDwOKVptuHQZ42MZE9g2froniNn170X/GLq4pNFDDwzvlrDk0dcUVUnLgy +p6vYHjwGOp0XlHMV+l3EoShI85WHjEHGvShTsWCG+gfg6gUOUlSZxS9q7VphKy9o +fkIFODleeiFb+CA6w0lkeVn7XYcCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAA307 +asNetk+fAJHwsR3xsrP7vPWdb7wAS72ZHWeM/qvuhGlNe4MexWjqbTycDPaN8cvj +WcrhiNg+QdnMuKDu65lZ9BRZm2W1TdCvMIAq69B+bPssbFm7V2XrFALRzfjSmUrw +YYstqJFsM2RxS4kPl+6s6VTyayWgHURofMee1FrUPeWHMlLqgkeVvTDm6NPViYrT +inh4a++/IYh61vCONJqRpyuAn/wYDJD4uOhU4Xp/J/60ZygHvz9hyxjrbUK1cXLW +X7vRnw2GAKnN/KcVjwKYdfXoOFHQeaWsugOVcb9t7mHm+kFrM8lCxUpI4z15h+FV +um/V2RYmCWkOQCddNA== +-----END CERTIFICATE----- diff --git a/test/fixtures/certs/server/chain.pem b/test/fixtures/certs/server/chain.pem new file mode 100644 index 000000000..9f2994e49 --- /dev/null +++ b/test/fixtures/certs/server/chain.pem @@ -0,0 +1,24 @@ +-----BEGIN CERTIFICATE----- +MIIEGDCCAwCgAwIBAgIJAJq8QHkEg5o5MA0GCSqGSIb3DQEBBQUAMGUxCzAJBgNV +BAYTAlVTMQ0wCwYDVQQIEwRVdGFoMQ4wDAYDVQQHEwVQcm92bzEjMCEGA1UEChMa +SW50ZXJuYWwgU2lnbmluZyBBdXRob3JpdHkxEjAQBgNVBAMTCWxvY2FsaG9zdDAe +Fw0xNjEwMTExMjIxNTZaFw0xOTA4MDExMjIxNTZaMGUxCzAJBgNVBAYTAlVTMQ0w +CwYDVQQIEwRVdGFoMQ4wDAYDVQQHEwVQcm92bzEjMCEGA1UEChMaSW50ZXJuYWwg +U2lnbmluZyBBdXRob3JpdHkxEjAQBgNVBAMTCWxvY2FsaG9zdDCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBANI3e2jhyAoQOtenmDgqMaulDbd6LxB54+2H +EBZ94868s563HZfW1i9a322Njl8Z8Zs7Hp6X8NANtJeOjbOdocKV7UZ7mhiCirlE +1TeulfwgPbbDdjQ4QSCengESBdi1ai1Iy+bSxC8RX4xiRP1vEgUlsIEj50rQWjvq +NU9B+k0jwrfSYWSFz4OPL6p2kCKne8A34smpL02yaEcdkgy6d0joV4ggPMqv17cV +0WEr74pO+f/bFZD9IObrHibtp7GPdPmxK4bofNqPaVxXfp5BXp1TaNZhLwRBgVjT +tK7nU46A9TXMZ59vk9g3vv+fCCPy1s1d6/wRMso9yHj6hfResosCAwEAAaOByjCB +xzAdBgNVHQ4EFgQUnX++qBGyUBIpJkfIuYLAkS441rwwgZcGA1UdIwSBjzCBjIAU +nX++qBGyUBIpJkfIuYLAkS441ryhaaRnMGUxCzAJBgNVBAYTAlVTMQ0wCwYDVQQI +EwRVdGFoMQ4wDAYDVQQHEwVQcm92bzEjMCEGA1UEChMaSW50ZXJuYWwgU2lnbmlu +ZyBBdXRob3JpdHkxEjAQBgNVBAMTCWxvY2FsaG9zdIIJAJq8QHkEg5o5MAwGA1Ud +EwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBACzI+LS7z3DJDbwczhT4lW+qsexv +avXT7x/Zt2Wv+szjNYRA4LYFGTQ/JYCx9J2zg9Cc6uPxjWlJNjwTVT4WLKJPnuQf +PEEcYp5gJqpHBULdWIEcH9IROpnVQeZETTzLuFLGY6Ya8pA2j6E44pxE8c8wVYuP +RLL8ihFKlEi7iQFjPX8Y0Jq2Xfjo9puldN6Jes3SMQfMuP1MIwiDaTNXeyD4ZBBO +3wDVN4dQHV2Fcq8ES9c5jBKpTkg8a8tFp60WKz+eEAg3mGYkFQNBLyG+S8ZhZef1 +VAg3jV1MPjlSw7aGrCkadVwXXOJZmOAlQM5D4NvxnuRwLGCzrBv13q+bDqA= +-----END CERTIFICATE----- diff --git a/test/fixtures/certs/server/fullchain.pem b/test/fixtures/certs/server/fullchain.pem new file mode 100644 index 000000000..5aa4bbcfe --- /dev/null +++ b/test/fixtures/certs/server/fullchain.pem @@ -0,0 +1,44 @@ +-----BEGIN CERTIFICATE----- +MIIDOTCCAiECCQDeQUEpn9zznTANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQGEwJV +UzENMAsGA1UECBMEVXRhaDEOMAwGA1UEBxMFUHJvdm8xIzAhBgNVBAoTGkludGVy +bmFsIFNpZ25pbmcgQXV0aG9yaXR5MRIwEAYDVQQDEwlsb2NhbGhvc3QwHhcNMTYx +MDExMTIyMTU2WhcNMTgwMjIzMTIyMTU2WjBYMQswCQYDVQQGEwJVUzENMAsGA1UE +CBMEVXRhaDEOMAwGA1UEBxMFUHJvdm8xFjAUBgNVBAoTDUFDTUUgVGVjaCBJbmMx +EjAQBgNVBAMTCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAO+4/PHRagiYl4IoK0AGEdpbdrZUUKpk6Ph/2GMBStHqbmgIVReKs4aDd6XH +W4WlS/fhUS5eA0yqtxrUCHepZEX/du8f0GHwNBRQ2VqKYPGkFLgu5Gt9CfBdNcRt +f38NMHzGM4hPHkP6fubD9TtfMdBOLLTi/iDPg5bQuLxaorOn6Yq81lPdBZNt6FIf +byRdGHPDwOKVptuHQZ42MZE9g2froniNn170X/GLq4pNFDDwzvlrDk0dcUVUnLgy +p6vYHjwGOp0XlHMV+l3EoShI85WHjEHGvShTsWCG+gfg6gUOUlSZxS9q7VphKy9o +fkIFODleeiFb+CA6w0lkeVn7XYcCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAA307 +asNetk+fAJHwsR3xsrP7vPWdb7wAS72ZHWeM/qvuhGlNe4MexWjqbTycDPaN8cvj +WcrhiNg+QdnMuKDu65lZ9BRZm2W1TdCvMIAq69B+bPssbFm7V2XrFALRzfjSmUrw +YYstqJFsM2RxS4kPl+6s6VTyayWgHURofMee1FrUPeWHMlLqgkeVvTDm6NPViYrT +inh4a++/IYh61vCONJqRpyuAn/wYDJD4uOhU4Xp/J/60ZygHvz9hyxjrbUK1cXLW +X7vRnw2GAKnN/KcVjwKYdfXoOFHQeaWsugOVcb9t7mHm+kFrM8lCxUpI4z15h+FV +um/V2RYmCWkOQCddNA== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEGDCCAwCgAwIBAgIJAJq8QHkEg5o5MA0GCSqGSIb3DQEBBQUAMGUxCzAJBgNV +BAYTAlVTMQ0wCwYDVQQIEwRVdGFoMQ4wDAYDVQQHEwVQcm92bzEjMCEGA1UEChMa +SW50ZXJuYWwgU2lnbmluZyBBdXRob3JpdHkxEjAQBgNVBAMTCWxvY2FsaG9zdDAe +Fw0xNjEwMTExMjIxNTZaFw0xOTA4MDExMjIxNTZaMGUxCzAJBgNVBAYTAlVTMQ0w +CwYDVQQIEwRVdGFoMQ4wDAYDVQQHEwVQcm92bzEjMCEGA1UEChMaSW50ZXJuYWwg +U2lnbmluZyBBdXRob3JpdHkxEjAQBgNVBAMTCWxvY2FsaG9zdDCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBANI3e2jhyAoQOtenmDgqMaulDbd6LxB54+2H +EBZ94868s563HZfW1i9a322Njl8Z8Zs7Hp6X8NANtJeOjbOdocKV7UZ7mhiCirlE +1TeulfwgPbbDdjQ4QSCengESBdi1ai1Iy+bSxC8RX4xiRP1vEgUlsIEj50rQWjvq +NU9B+k0jwrfSYWSFz4OPL6p2kCKne8A34smpL02yaEcdkgy6d0joV4ggPMqv17cV +0WEr74pO+f/bFZD9IObrHibtp7GPdPmxK4bofNqPaVxXfp5BXp1TaNZhLwRBgVjT +tK7nU46A9TXMZ59vk9g3vv+fCCPy1s1d6/wRMso9yHj6hfResosCAwEAAaOByjCB +xzAdBgNVHQ4EFgQUnX++qBGyUBIpJkfIuYLAkS441rwwgZcGA1UdIwSBjzCBjIAU +nX++qBGyUBIpJkfIuYLAkS441ryhaaRnMGUxCzAJBgNVBAYTAlVTMQ0wCwYDVQQI +EwRVdGFoMQ4wDAYDVQQHEwVQcm92bzEjMCEGA1UEChMaSW50ZXJuYWwgU2lnbmlu +ZyBBdXRob3JpdHkxEjAQBgNVBAMTCWxvY2FsaG9zdIIJAJq8QHkEg5o5MAwGA1Ud +EwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBACzI+LS7z3DJDbwczhT4lW+qsexv +avXT7x/Zt2Wv+szjNYRA4LYFGTQ/JYCx9J2zg9Cc6uPxjWlJNjwTVT4WLKJPnuQf +PEEcYp5gJqpHBULdWIEcH9IROpnVQeZETTzLuFLGY6Ya8pA2j6E44pxE8c8wVYuP +RLL8ihFKlEi7iQFjPX8Y0Jq2Xfjo9puldN6Jes3SMQfMuP1MIwiDaTNXeyD4ZBBO +3wDVN4dQHV2Fcq8ES9c5jBKpTkg8a8tFp60WKz+eEAg3mGYkFQNBLyG+S8ZhZef1 +VAg3jV1MPjlSw7aGrCkadVwXXOJZmOAlQM5D4NvxnuRwLGCzrBv13q+bDqA= +-----END CERTIFICATE----- diff --git a/test/fixtures/certs/server/privkey.pem b/test/fixtures/certs/server/privkey.pem new file mode 100644 index 000000000..e4f5368a9 --- /dev/null +++ b/test/fixtures/certs/server/privkey.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEogIBAAKCAQEA77j88dFqCJiXgigrQAYR2lt2tlRQqmTo+H/YYwFK0epuaAhV +F4qzhoN3pcdbhaVL9+FRLl4DTKq3GtQId6lkRf927x/QYfA0FFDZWopg8aQUuC7k +a30J8F01xG1/fw0wfMYziE8eQ/p+5sP1O18x0E4stOL+IM+DltC4vFqis6fpirzW +U90Fk23oUh9vJF0Yc8PA4pWm24dBnjYxkT2DZ+uieI2fXvRf8Yurik0UMPDO+WsO +TR1xRVScuDKnq9gePAY6nReUcxX6XcShKEjzlYeMQca9KFOxYIb6B+DqBQ5SVJnF +L2rtWmErL2h+QgU4OV56IVv4IDrDSWR5WftdhwIDAQABAoIBAAZ3jxtW8u1YcH3q +Z4BKqaCiZwl0LNjr7/0ENeo11rbjBCd6UhFYhI9UbJ3kSuvIEcyWH4KItr4SvO3U +WoYf47yfr62zxgNeX4lMxRBUO1lJe+WcHj1oGiSJ3zF1YsMir/QtxKYgvEhJMbM4 +Bh2b69Qax8n5dbGc54fiCZnLOChwidafPyJR1vY/WwcMDzCuUTlHDTHuVt53hocT +DLrteBPZNoYDkDSv8OysQ2BMrvcpIadRnFFUUc8fsmjTf8T9HLMx+PDbeh6fHDnm +KBCqsLlNgKRLJAINRvf626otszi5Bp5Fla/kNYZINgajEUNm2gpKJQb/4g/CF1ql +u4O9ZEECgYEA99lasThmkmOa9KQwi+uoxY3N/HzWIL440MhvPmlHaOzw6C3nqXP6 +uDgqg3ChnEj7ik0LA8O0Y2RkAJynwLrAqOyqLFstUUT1L80WyuBOuEUbrXuaNEMd +Ujy8i2iSob3uzX3b/9KfVNa5sI6fL6t+E/CzRI3T8DRt+/b7tziPTSUCgYEA95s3 +nDFUq+8y6XxBYx1Dr6Bq+9tj5ZA3tWG2LoahG3KvFxK+i0+7cu3p1lqHqlFbFkX3 +Qt8JnQShnlk9NHtjqozyC4fvn4vHLzKBiNc3bIvBTuBE0R7x4UZHAioc2U11VXKD +R3cpzEe/Llemkf7Dv1cfJTGEZvWfuw1ULHzNXjsCgYBTilXBamtYaG5wi285mmM2 +w4ds1X8vZi6sYQLuHHpPaZ4CBIcTXN5jfbsGts4iaY8vnKxbxnllDw+ODT+V/Ny3 +k54AeXMa841ZYV2PYG/oOJMNtJ3Tg9O8RnCe5M6X6fc2GHgxEINYC1BnrIsHfFxw +yC8EqnGHg4SW6zcJGO1kaQKBgA/ZZKbf1X6n8gdWB81zWxjL2O1ELtHL+HToy0OR +JJDgN2rvrTi3otUJe5VX+CUjzgPP+LLUGgZt/HZpWeyZFVkeaoPocKMyzE4uGnKK +7CZLj9Ufr+f+5ha4a+Uskuop9h/BE7woWYmU8hziSWxA9YCy7/Buif4ZLN9JTCEI +4BBvAoGAckWRKbnXG7KS4+XkmuHpeHL/+4T6Odp+0FrhSaQqkmhKEc8BR2BMEFU+ +aF5YARrEr++CZloItaVHnNmRLkFgVQfkaKMfDa1fs/0rm4c1htdZsJJQUiBTojh+ +zJu+hlPRqIN57Zrx6n63zJFdECk4fEpfrkdyWV/iBfzsn+/0BWE= +-----END RSA PRIVATE KEY----- diff --git a/test/fixtures/client/filters-https.json b/test/fixtures/client/filters-https.json new file mode 100644 index 000000000..f8e79e254 --- /dev/null +++ b/test/fixtures/client/filters-https.json @@ -0,0 +1,75 @@ +{ + "private": [ + { + "path": "/echo-param/${param}", + "method": "GET", + "origin": "https://localhost:${originPort}" + }, + + { + "path": "/echo-body", + "method": "POST", + "origin": "https://localhost:${originPort}" + }, + + { + "path": "/echo-body/filtered", + "method": "POST", + "origin": "https://localhost:${originPort}", + "valid": [ + { + "//": "accept requests with 'proxy.*: please' in their body", + "path": "proxy.*", + "value": "please" + } + ] + }, + + { + "path": "/echo-headers", + "method": "POST", + "origin": "https://localhost:${originPort}" + }, + + { + "path": "/echo-query", + "method": "GET", + "origin": "https://localhost:${originPort}" + } + + ], + "public": [ + { + "path": "/echo-param/${param}", + "method": "GET" + }, + + { + "path": "/echo-body", + "method": "POST" + }, + + { + "path": "/echo-body/filtered", + "method": "POST", + "valid": [ + { + "//": "accept requests with 'proxy.*: please' in their body", + "path": "proxy.*", + "value": "please" + } + ] + }, + + { + "path": "/echo-headers", + "method": "POST" + }, + + { + "path": "/echo-query", + "method": "GET" + } + + ] +} diff --git a/test/fixtures/client/le-ca.cert.pem b/test/fixtures/client/le-ca.cert.pem new file mode 100644 index 000000000..9548dc1bf --- /dev/null +++ b/test/fixtures/client/le-ca.cert.pem @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw +TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh +cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4 +WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu +ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY +MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc +h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+ +0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U +A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW +T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH +B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC +B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv +KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn +OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn +jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw +qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI +rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq +hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL +ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ +3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK +NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5 +ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur +TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC +jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc +oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq +4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA +mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d +emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc= +-----END CERTIFICATE----- diff --git a/test/functional/client-ca.test.js b/test/functional/client-ca.test.js new file mode 100644 index 000000000..cc8d1b6a3 --- /dev/null +++ b/test/functional/client-ca.test.js @@ -0,0 +1,85 @@ +const tap = require('tap'); +const test = require('tap-only'); +const request = require('request'); +const path = require('path'); +const app = require('../../lib'); +const root = __dirname; + +process.env.TEST_KEY = path.resolve(root, '../fixtures/certs/server/privkey.pem'); +process.env.TEST_CERT = path.resolve(root, '../fixtures/certs/server/fullchain.pem'); + +const { port, echoServerPort } = require('../utils')(tap); + +test('correctly use supplied CA cert on client for connections', t => { + /** + * 1. start broker in server mode + * 2. start broker in client mode + * 3. run local https server with _self-signed_ cert that replicates "private server" + * 4. send request to the server and expect error + * 5. start broker in client mode with supplied CA cert + * 6. send request to the server and expect success + */ + + t.plan(5); + + process.env.ACCEPT = 'filters.json'; + + process.chdir(path.resolve(root, '../fixtures/server')); + process.env.BROKER_TYPE = 'server'; + const serverPort = port(); + const server = app.main({ port: serverPort }); + + process.chdir(path.resolve(root, '../fixtures/client')); + process.env.BROKER_TYPE = 'client'; + process.env.BROKER_TOKEN = '12345'; + process.env.BROKER_SERVER_URL = `http://localhost:${serverPort}`; + process.env.ORIGIN_PORT = echoServerPort; + process.env.ACCEPT = 'filters-https.json'; // We need to connect to the https version of _internal service_ + let client = app.main({ port: port() }); + + // wait for the client to successfully connect to the server and identify itself + server.io.once('connection', socket => { + socket.on('identify', token => { + t.test('get an error trying to connect to a server with unknown CA', t => { + const url = `http://localhost:${serverPort}/broker/${token}/echo-body`; + request({ url, method: 'post', json: true }, (err, res) => { + t.equal(res.statusCode, 500, '500 statusCode'); + t.end(); + }); + }); + + t.test('close', t => { + client.close(); + t.ok('client closed'); + t.end(); + }); + + t.test('launch a new client with CA set', t => { + server.io.on('connection', socket => { + socket.once('identify', t.end); + }); + + // Specify CA file + process.env.CA_CERT = '../certs/ca/my-root-ca.crt.pem'; + client = app.main({ port: port() }); + }); + + t.test('successfully broker POST with CA set', t => { + const url = `http://localhost:${serverPort}/broker/${token}/echo-body`; + request({ url, method: 'post', json: true }, (err, res) => { + t.equal(res.statusCode, 200, '200 statusCode'); + t.end(); + }); + }); + + t.test('clean up', t => { + client.close(); + setTimeout(() => { + server.close(); + t.ok('sockets closed'); + t.end(); + }, 100); + }); + }); + }); +}); diff --git a/test/utils.js b/test/utils.js index b3145e581..b01ea3030 100644 --- a/test/utils.js +++ b/test/utils.js @@ -10,6 +10,8 @@ function port() { const echoServerPort = port(); const { app: echoServer, server } = webserver({ port: echoServerPort, + key: process.env.TEST_KEY, // Optional + cert: process.env.TEST_CERT, // Optional }); echoServer.get('/echo-param/:param', (req, res) => {