https
The https is very similar to the http protocol, except for the fact that it uses
a certificate key pair. If you use the built-in self-signed certificate, you may have to
configure your code to disable certificate validation (e.g. use the -k
switch in curl
). Alternatively, you may pass in the key pair yourself.
Imposter Creation Parameters
Parameter | Options | Required? | Default | Description |
---|---|---|---|---|
protocol |
https |
Yes | N/A | |
port |
Any valid port number | No | A randomly assigned port. mountebank will return the actual value
in the POST response. |
The port to run the imposter on. |
key |
A PEM-formatted string | No | A built in private key | The SSL server private key |
cert |
A PEM-formatted string | No | A built in self-signed certificate | The SSL server certificate |
mutualAuth |
true or false |
No | false |
If true , the server will request a client certificate.
Since the goal is simply to virtualize a server requiring mutual auth,
invalid certificates will not be rejected. |
ciphers |
See here | No | Here | For older (and insecure) https servers, this field allows you to override the cipher used to communicate |
name |
Any string | No | empty string | Included in the logs, useful when multiple imposters are set up. |
recordRequests |
true or false |
No | false | Adds mock verification support by remembering the requests
made to this imposter. Note that this represents a memory leak for any long running
mb process, as requests are never forgotten. |
stubs |
Valid stubs | No | An empty array | The list of stubs responsible for matching a request and returning a response |
defaultResponse |
A valid response, see the http page for response fields | No |
|
The default response to send if no predicate matches. Also represents the default values that get merged into a response that doesn't specify every field |
allowCORS |
boolean | No | false | If true, mountebank will allow all CORS preflight requests on the imposter. |
rejectUnauthorized |
boolean | No | false | If true, mountebank will validate the certificate against the list of supplied CAs. |
ca |
Array of PEM-formatted certificates | No | null | Use when setting rejectUnauthorized to true to provide a list of certificates to validate against.
When rejectUnauthorized is true and mutualAuth is true, mountebank will request a client certificate. |
See the http page for examples. Just be sure
to change the protocol
parameter to https
during imposter
creation!
Handling trust
By default, mountebank will use an internal self-signed certificate. While this allows you to explore the API in a simple zero-config manner, it also means that you need to configure your system under test to ignore trust errors. This is A Very Bad Idea. It puts you at risk of accidentally leaving that configuration in production, exposing your network to unnecessary risk.
There are at least three solutions that are safe for testing and remove the possibility of your test strategy causing trust violations in production:
- Test against an http imposter, and trust that the SSL/TLS libraries your system under test is using just work.
- Create your own self-signed certificate for testing and add it to your local trust store only. Have a look at mkcert for a simple way of doing this.
- Use a real trusted certificate for testing. If you can't have your organization create one for you, Let's Encrypt offers a free service to create trusted certificates.
The mutual authentication example below shows including them in your imposter setup.
Mutual Authentication
mountebank supports mutual authentication involving client certificates both for the
server itself and through proxies. The following example demonstrates this capability,
as well as setting up your own certificate for the server. First we'll set up a server
that expects client certificates by using the mutualAuth
field:
POST /imposters HTTP/1.1
Host: localhost:35553
Accept: application/json
Content-Type: application/json
{
"port": 4545,
"protocol": "https",
"name": "origin server",
"mutualAuth": true,
"key": "-----BEGIN RSA PRIVATE KEY-----\nMIICXAIBAAKBgQCrvse04YkxtVGagyvGJCsvv7LTfLK5uR/ZIJKDYCnuF+BqBzM4\nlko8O39vx+Lz9FfF11Xl+CN1aY37YurLYOle3dC/qslSbQDe2TJN7lcVHVssePvc\nO5IExpvNFV5LYtmyCMKJHxpnIprv/trUso5obqzzXhFVPV9SQbFH/snInwIDAQAB\nAoGARywlqLD6YO4qJiULw+4DM6N2oSwBCPRN3XYhIW59kdy1NFtNf7rQgsuJUTJ9\nu+lbYnKNd2LwltyqaS4h7Sx5KRhpFNmMpyVsBf5J2q3fbfmrsXt+emY7XhVTc1NV\nizUWYyxCoTTeMWvN/6NYpPV0lSxq7jMTFVZrWQUMqJclxpECQQDTlGwALtAX1Y8u\nGKsEHPkoq9bhHA5N9WAboQ4LQCZVC8eBf/XH//2iosYTXRNgII2JLmHmmxJHo5iN\nJPFMbnoHAkEAz81osJf+yHm7PBBJP4zEWZCV25c+iJiPDpj5UoUXEbq47qVfy1mV\nDqy2zoDynAWitU7PeHyZ8ozfyribPoR2qQJAVmvMhXKZmvKnLivzRpXTC9LMzVwZ\nV6x/Wim5w8yrG5fZIMM0kEG2xwR3pZch/+SsCzl/0aLLn6lp+VT6nr6NZwJBAMxs\nHrvymoLvNeDtiJFK0nHliXafP7YyljDfDg4+vSYE0R57c1RhSQBJqgBV29TeumSw\nJes6cFuqeBE+MAJ9XxkCQDdUdhnA8HHQRNetqK7lygUep7EcHHCB6u/0FypoLw7o\nEUVo5KSEFq93UeMr3B7DDPIz3LOrFXlm7clCh1HFZhQ=\n-----END RSA PRIVATE KEY-----",
"cert": "-----BEGIN CERTIFICATE-----\nMIIB6TCCAVICCQCZgxbBD0CG4zANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJV\nUzETMBEGA1UECBMKU29tZS1TdGF0ZTEVMBMGA1UEChMMVGhvdWdodFdvcmtzMB4X\nDTEzMTIyOTE2NDAzN1oXDTE0MDEyODE2NDAzN1owOTELMAkGA1UEBhMCVVMxEzAR\nBgNVBAgTClNvbWUtU3RhdGUxFTATBgNVBAoTDFRob3VnaHRXb3JrczCBnzANBgkq\nhkiG9w0BAQEFAAOBjQAwgYkCgYEAq77HtOGJMbVRmoMrxiQrL7+y03yyubkf2SCS\ng2Ap7hfgagczOJZKPDt/b8fi8/RXxddV5fgjdWmN+2Lqy2DpXt3Qv6rJUm0A3tky\nTe5XFR1bLHj73DuSBMabzRVeS2LZsgjCiR8aZyKa7/7a1LKOaG6s814RVT1fUkGx\nR/7JyJ8CAwEAATANBgkqhkiG9w0BAQUFAAOBgQCPhixeKxIy+ftrfPikwjYo1uxp\ngQ18FdVN1pbI//IIx1o8kJuX8yZzO95PsCOU0GbIRCkFMhBlqHiD9H0/W/GvWzjf\n7WFW15lL61y/kH1J0wqEgoaMrUDjHZvKVr0HrN+vSxHlNQcSNFJ2KdvZ5a9dhpGf\nXOdprCdUUXzSoJWCCg==\n-----END CERTIFICATE-----",
"stubs": [{
"responses": [{ "is": { "body": "It worked!" } }]
}]
}
If we try and connect to this server without providing a client certificate, it will immediately terminate the connection. Let's create an imposter that will proxy to it, providing the necessary credentials:
POST /imposters HTTP/1.1
Host: localhost:35553
Accept: application/json
Content-Type: application/json
{
"port": 5555,
"protocol": "http",
"name": "proxy",
"stubs": [
{
"responses": [
{
"proxy": {
"to": "https://localhost:4545",
"key": "-----BEGIN RSA PRIVATE KEY-----\nMIICXAIBAAKBgQCrvse04YkxtVGagyvGJCsvv7LTfLK5uR/ZIJKDYCnuF+BqBzM4\nlko8O39vx+Lz9FfF11Xl+CN1aY37YurLYOle3dC/qslSbQDe2TJN7lcVHVssePvc\nO5IExpvNFV5LYtmyCMKJHxpnIprv/trUso5obqzzXhFVPV9SQbFH/snInwIDAQAB\nAoGARywlqLD6YO4qJiULw+4DM6N2oSwBCPRN3XYhIW59kdy1NFtNf7rQgsuJUTJ9\nu+lbYnKNd2LwltyqaS4h7Sx5KRhpFNmMpyVsBf5J2q3fbfmrsXt+emY7XhVTc1NV\nizUWYyxCoTTeMWvN/6NYpPV0lSxq7jMTFVZrWQUMqJclxpECQQDTlGwALtAX1Y8u\nGKsEHPkoq9bhHA5N9WAboQ4LQCZVC8eBf/XH//2iosYTXRNgII2JLmHmmxJHo5iN\nJPFMbnoHAkEAz81osJf+yHm7PBBJP4zEWZCV25c+iJiPDpj5UoUXEbq47qVfy1mV\nDqy2zoDynAWitU7PeHyZ8ozfyribPoR2qQJAVmvMhXKZmvKnLivzRpXTC9LMzVwZ\nV6x/Wim5w8yrG5fZIMM0kEG2xwR3pZch/+SsCzl/0aLLn6lp+VT6nr6NZwJBAMxs\nHrvymoLvNeDtiJFK0nHliXafP7YyljDfDg4+vSYE0R57c1RhSQBJqgBV29TeumSw\nJes6cFuqeBE+MAJ9XxkCQDdUdhnA8HHQRNetqK7lygUep7EcHHCB6u/0FypoLw7o\nEUVo5KSEFq93UeMr3B7DDPIz3LOrFXlm7clCh1HFZhQ=\n-----END RSA PRIVATE KEY-----",
"cert": "-----BEGIN CERTIFICATE-----\nMIIB6TCCAVICCQCZgxbBD0CG4zANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJV\nUzETMBEGA1UECBMKU29tZS1TdGF0ZTEVMBMGA1UEChMMVGhvdWdodFdvcmtzMB4X\nDTEzMTIyOTE2NDAzN1oXDTE0MDEyODE2NDAzN1owOTELMAkGA1UEBhMCVVMxEzAR\nBgNVBAgTClNvbWUtU3RhdGUxFTATBgNVBAoTDFRob3VnaHRXb3JrczCBnzANBgkq\nhkiG9w0BAQEFAAOBjQAwgYkCgYEAq77HtOGJMbVRmoMrxiQrL7+y03yyubkf2SCS\ng2Ap7hfgagczOJZKPDt/b8fi8/RXxddV5fgjdWmN+2Lqy2DpXt3Qv6rJUm0A3tky\nTe5XFR1bLHj73DuSBMabzRVeS2LZsgjCiR8aZyKa7/7a1LKOaG6s814RVT1fUkGx\nR/7JyJ8CAwEAATANBgkqhkiG9w0BAQUFAAOBgQCPhixeKxIy+ftrfPikwjYo1uxp\ngQ18FdVN1pbI//IIx1o8kJuX8yZzO95PsCOU0GbIRCkFMhBlqHiD9H0/W/GvWzjf\n7WFW15lL61y/kH1J0wqEgoaMrUDjHZvKVr0HrN+vSxHlNQcSNFJ2KdvZ5a9dhpGf\nXOdprCdUUXzSoJWCCg==\n-----END CERTIFICATE-----"
}
}
]
}
]
}
With the client certificate specified, we should now be able to successfully proxy:
GET / HTTP/1.1
Host: localhost:5555
HTTP/1.1 200 OK
Connection: close
Date: Thu, 09 Jan 2014 02:30:31 GMT
Transfer-Encoding: chunked
It worked!
DELETE /imposters/5555 HTTP/1.1
Host: localhost:35553
Accept: application/json
DELETE /imposters/4545 HTTP/1.1
Host: localhost:35553
Accept: application/json