Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support HTTPS and introduce ssl_certificate policy phase #622

Merged
merged 6 commits into from
Jun 6, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- Default credentials policy [PR #741](https://github.com/3scale/apicast/pull/741), [THREESCALE-586](https://issues.jboss.org/browse/THREESCALE-586)
- Configurable caching for the token introspection policy [PR #656](https://github.com/3scale/apicast/pull/656)
- `APICAST_ACCESS_LOG_FILE` env to make the access log location configurable [THREESCALE-743](https://github.com/3scale/apicast/pull/743)
- ENV variables to make APIcast listen on HTTPS port [PR #622](https://github.com/3scale/apicast/pull/622)
- New `ssl_certificate` phase allows policies to provide certificate to terminate HTTPS connection [PR #622](https://github.com/3scale/apicast/pull/622).

### Changed

Expand Down
18 changes: 18 additions & 0 deletions doc/parameters.md
Original file line number Diff line number Diff line change
Expand Up @@ -285,3 +285,21 @@ You can choose to mount a different configuration than the provided by default b

This environment variable controls the HTTP header used for forwarding opentracing information, this HTTP header will be forwarded to upstream servers.


### `APICAST_HTTPS_PORT`

**Default:** no value

Controls on which port APIcast should start listening for HTTPS connections. If this clashes with HTTP port it will be used only for HTTPS.

### `APICAST_HTTPS_CERTIFICATE`

**Default:** no value

Path to a file with X.509 certificate in the PEM format for HTTPS.

### `APICAST_HTTPS_CERTIFICATE_KEY`

**Default:** no value

Path to a file with the X.509 certificate secret key in the PEM format.
7 changes: 5 additions & 2 deletions doc/policies.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ APIcast.
## Policies

A policy tells APIcast what it should do in each of the nginx phases: `init`,
`init_worker`, `rewrite`, `access`,`content`, `balancer`, `header_filter`, `body_filter`,
`init_worker`, `ssl_certificate`, `rewrite`, `access`,`content`, `balancer`, `header_filter`, `body_filter`,
`post_action`, `log`, and `metrics`.

Policies can share data between them. They do that through what we call the
Expand All @@ -35,7 +35,7 @@ The way policy chains work is as follows: suppose that we have a policy A that
describes what to do in the `rewrite` and `header_filter` phases and a policy B
that describes what to run in `access` and `header_filter`. Assume also that
when describing the chain, we indicate that policy A should be run before
policy B. When APIcast receives a request, it will check the policy chain
policy B. When APIcast receives an HTTP request, it will check the policy chain
described to see what it should run on each phase:
- rewrite: execute the function policy A provides for this phase.
- access: execute the function policy B provides for this phase.
Expand All @@ -53,6 +53,9 @@ Notice that we did not indicate what APIcast does in the `init` and the
request. `init` is executed when APIcast boots, and `init_worker` when each
of each of its workers start.

Another phase that is not executed for every request is `ssl_certificate` because
it is called only when APIcast terminates the HTTPS connection.

The order in which policies actions are applied depend on two factors:
- Position of the policy within the policy chain.
- The phase in which the policies act.
Expand Down
33 changes: 16 additions & 17 deletions examples/add-ssl/cert/server.crt
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
-----BEGIN CERTIFICATE-----
MIIDBjCCAe4CCQDF1mZcWyPgwTANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJB
VTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0
cyBQdHkgTHRkMB4XDTE2MTExNzA4NDcxOVoXDTE3MTExNzA4NDcxOVowRTELMAkG
A1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNVBAoTGEludGVybmV0
IFdpZGdpdHMgUHR5IEx0ZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
AKvwk7TsVwW/0KSpZMU4LU7PE5rJGGyy0EJY/Y22uAuqzAYDyyuShW3IfUqS0hr5
nOLZWSMjntcHbbLsYy6J6ZcmxfwlpS8FGOq2zhQvHZCmxMTRSTK+5EfgLe0al556
k2RoEcsGgK4jTH09+Fig3dMBL/1ly+s/z7JBzFkCX03y6BA26CjrHl2aVJjyJWRs
Z1/9qndjCzZzVCsdJ7NJi/km3ugAJFRPggxucBeyCToHkQQacXYL4X8S8fS6oP7w
XNMttBdENl1iGT1uD4mxjy1i8L3v8OhK6qxE+dxGLcakECbuGDGBGi/Cyn4sPKfs
fghFfboSPm60OfeXcyS1n+sCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAWcctiXNI
Je80bzdvDNgRegdnZHI5xg+TrrVMQ9DFeCPOCpcesqkypdV2HZKRhtKsosu6O7MR
g7o2C2RnMPuL+8J94FW4V+nDZoUcksOzNERZXMUHctSGkzGkoWBtdCx44dfCcLmQ
gAyQ6+I4pT1Ks6Ri3IJdaj+JFK9C9thibzXXsviW8S6CuqArAIp4jssIO39moFGQ
2dry9O0suQ23YaMAF6Uy0V5Ds9+FyZPNFWn/JPkdQKGuLjeOnOr4LH2JZAyYJxyk
k8M1Dl2TrS/QaqOrpHQ3a/6J6BVvYiLih2tjO6spqWc7rlum8L+qpd9T2m0kukzg
cPK994E90uBW8Q==
MIIC6jCCAdICCQDyqR3mvsRZyDANBgkqhkiG9w0BAQsFADA3MRAwDgYDVQQKDAdS
ZWQgSGF0MQ8wDQYDVQQLDAYzc2NhbGUxEjAQBgNVBAMMCWxvY2FsaG9zdDAeFw0x
ODAyMjMwNzQ3MDBaFw0yODAyMjEwNzQ3MDBaMDcxEDAOBgNVBAoMB1JlZCBIYXQx
DzANBgNVBAsMBjNzY2FsZTESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvD63witlrnDVdHPTV6wrajNh9F3WXsiwFKuZ
OM/2uGrzdeKd2dsMNUfYD/X9sLN8OUe+IbLdVvwGy9cx6nuKR3XTWhzjm2yHUCO9
eT1svPUWGkZNMkyftcG4RG6ArYzf8GUciZ8tm8sMtp6RJ3UhJOETsoo+HXaPbMr2
YICDvPGV5QOJK3mdvHFb5Os19WHkB8zcm/iA8b+0dlTF8cOCuHaTx0ncGDf6Q1zx
A22hQyBFQUcW2MWQBIGkXe2sJMK5P9QS+0kVS8miSuud2qxohKWkuK9WtVsGaJj3
XTdvvZxpu/H+FyMjvoQhd3iaFYRfHrVR91L7G2jY+CzYS4Q7KwIDAQABMA0GCSqG
SIb3DQEBCwUAA4IBAQBkyiygZOJKkxSuMQ9pQ5CldPIloCd+LV0MLmzMztH5NF0/
Zr4hiUB4vMPIt5a2Ay5Og3C04wVoFBbNuMs/70nwBkxqQ0+7c8qmlgLk9OTvjkOC
MEN4bd4MK2WNRw6340bm13nOaBcqsQW//0jhJaWFKEIBddXNwawP1Ua8/B1hXJKz
vSmCWM7XZ2A/LoB69eSwyse1D75BpYOZ5WdBRBKnZO45cc0eRcbGYvK0KOeXXjNw
LCqdMZav74dfB4LM/b6CnHyrZC6FFtJbsBLLJ7UCcRNeR6UF0tTdUel95LdscA5j
sMqFt3bnE9U+IIy3BoxorviPdlbInLXBzynqqyl3
-----END CERTIFICATE-----
50 changes: 25 additions & 25 deletions examples/add-ssl/cert/server.key
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
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
-----END RSA PRIVATE KEY-----
27 changes: 26 additions & 1 deletion gateway/conf/nginx.conf.liquid
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,32 @@ http {

access_log {{ access_log_file | default: "/dev/stdout" }} time;

listen {{ port.apicast | default: 8080 }};
{%- assign http_port = port.apicast | default: 8080 %}
{%- assign https_port = env.APICAST_HTTPS_PORT %}

{% if http_port != https_port -%}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you tried this with https_port = nil ?
I remember problems when comparing nils in Liquid, but maybe it was a different issue.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd add a new test case in t/listen-https.t just to be sure.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So like the variable not set at all? That works - normal blackbox tests run with https_port not set.

The issue was that {% if env.somevar %} would be true even if it is empty.
This works just fine because http_port always has value.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right 👍

listen {{ http_port }};
{% endif %}

{% if https_port -%}
listen {{ https_port }} ssl;

{%- assign https_certificate = env.APICAST_HTTPS_CERTIFICATE -%}
ssl_certificate {% if https_certificate -%}
{{ https_certificate }}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one does not need | filesystem | first ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is path that was given by user in ENV, so we should not need to do any transformations.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, it does not really work. The | filesystem filter does not really work with absolute paths (yet).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

{%- else -%}
{{ "conf/server.crt" | filesystem | first }}
{%- endif %};

{%- assign https_certificate_key = env.APICAST_HTTPS_CERTIFICATE_KEY -%}
ssl_certificate_key {% if https_certificate_key -%}
{{ https_certificate_key }}
{%- else -%}
{{ "conf/server.key" | filesystem | first }}
{%- endif %};

ssl_certificate_by_lua_block { require('apicast.executor'):ssl_certificate() }
{%- endif %}

server_name _;

Expand Down
10 changes: 10 additions & 0 deletions gateway/conf/server.crt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
-----BEGIN CERTIFICATE-----
MIIBTzCB9gIJAJ/Hbl7Rg8UpMAoGCCqGSM49BAMCMDAxEDAOBgNVBAoMB0FQSWNh
c3QxHDAaBgNVBAsME0RlZmF1bHQgY2VydGlmaWNhdGUwHhcNMTgwNjA1MTAxNjAx
WhcNMjgwNjAyMTAxNjAxWjAwMRAwDgYDVQQKDAdBUEljYXN0MRwwGgYDVQQLDBNE
ZWZhdWx0IGNlcnRpZmljYXRlMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEVUiV
WRQcAve1ssYN0qaFWP33pYRLSV4SM6G0BB3SLiYnQKan8K0I7DtvOAoT8HOm0UyM
+6vNyedReg5PXHOuPjAKBggqhkjOPQQDAgNIADBFAiEAoSKLhFHcwFGSu1N4NxSq
p0bGI5J8WYfrdvWVZgWsV9MCIBeJzCEsegLdVBf/mn+4m7GNitMNzLj4CxTCnpqq
S1m1
-----END CERTIFICATE-----
8 changes: 8 additions & 0 deletions gateway/conf/server.key
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
-----BEGIN EC PARAMETERS-----
BggqhkjOPQMBBw==
-----END EC PARAMETERS-----
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIK9vyuYjAXWiI6QwoBwMs2BPKyY/46Qdd8ZFgTCA2YNRoAoGCCqGSM49
AwEHoUQDQgAEVUiVWRQcAve1ssYN0qaFWP33pYRLSV4SM6G0BB3SLiYnQKan8K0I
7DtvOAoT8HOm0UyM+6vNyedReg5PXHOuPg==
-----END EC PRIVATE KEY-----
2 changes: 1 addition & 1 deletion gateway/cpanfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
requires 'Test::APIcast', '0.12';
requires 'Test::APIcast', '0.14';
requires 'Crypt::JWT';
requires 'Test::Deep';
requires 'File::Slurp';
Expand Down
6 changes: 3 additions & 3 deletions gateway/cpanfile.snapshot
Original file line number Diff line number Diff line change
Expand Up @@ -383,10 +383,10 @@ DISTRIBUTIONS
Spiffy::mixin undef
requirements:
ExtUtils::MakeMaker 6.30
Test-APIcast-0.12
pathname: M/MC/MCICHRA/Test-APIcast-0.12.tar.gz
Test-APIcast-0.14
pathname: M/MC/MCICHRA/Test-APIcast-0.14.tar.gz
provides:
Test::APIcast 0.12
Test::APIcast 0.14
Test::APIcast::Blackbox undef
requirements:
File::Slurp 0
Expand Down
1 change: 1 addition & 0 deletions gateway/src/apicast/cli/template.lua
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ function _M:new(config, dir, strict)

for name,value in pairs(resty_env.list()) do
insert(env, { name = name, value = value })
env[name] = value
end

local context = setmetatable({
Expand Down
2 changes: 2 additions & 0 deletions gateway/src/apicast/policy.lua
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ local PHASES = {
'content', 'balancer',
'header_filter', 'body_filter',
'post_action', 'log', 'metrics',

'ssl_certificate',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add this new phase to the list that we have in policies.md ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep.

}

local setmetatable = setmetatable
Expand Down
9 changes: 8 additions & 1 deletion gateway/src/apicast/policy/echo/echo.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
-- the whole processing of the request.

local _M = require('apicast.policy').new('Echo Policy')
local cjson = require('cjson')

local tonumber = tonumber
local new = _M.new
Expand All @@ -20,7 +21,13 @@ function _M.new(configuration)
end

function _M.content()
ngx.say(ngx.var.request)
local accept = ngx.var.http_accept

if accept == 'application/json' then
ngx.say(cjson.encode({ request = ngx.var.request }))
else
ngx.say(ngx.var.request)
end
end

function _M:rewrite()
Expand Down
14 changes: 10 additions & 4 deletions gateway/src/apicast/policy/find_service/find_service.lua
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
local policy = require('apicast.policy')
local _M = policy.new('Find Service Policy')
local Policy = require('apicast.policy')
local _M = Policy.new('Find Service Policy')
local configuration_store = require 'apicast.configuration_store'
local mapping_rules_matcher = require 'apicast.mapping_rules_matcher'
local new = _M.new
Expand Down Expand Up @@ -70,8 +70,14 @@ function _M.new(...)
return self
end

function _M:rewrite(context)
context.service = self.find_service(context.configuration, context.host)
local function find_service(policy, context)
context.service = context.service or policy.find_service(context.configuration, context.host)
end

_M.rewrite = find_service

-- ssl_certiticate is the first phase executed when request arrives on HTTPS
-- therefore it needs to find a service to build a policy chain
_M.ssl_certificate = find_service

return _M
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
local _M = require('apicast.policy').new('Load Configuration')
local ssl = require('ngx.ssl')

local configuration_loader = require('apicast.configuration_loader').new()
local configuration_store = require('apicast.configuration_store')
Expand Down Expand Up @@ -30,4 +31,16 @@ function _M:rewrite(context)
context.configuration = configuration_loader.rewrite(self.configuration, context.host)
end

function _M.ssl_certificate(_, context)
if not context.host then
local server_name, err = ssl.server_name()

if server_name then
context.host = server_name
elseif err then
ngx.log(ngx.DEBUG, 'could not get TLS SNI server name: ', err)
end
end
end

return _M
3 changes: 2 additions & 1 deletion spec/policy_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ describe('policy', function()
'rewrite', 'access',
'content', 'balancer',
'header_filter', 'body_filter',
'post_action', 'log', 'metrics'
'post_action', 'log', 'metrics',
'ssl_certificate',
}

describe('.new', function()
Expand Down
23 changes: 23 additions & 0 deletions t/fixtures/policies/https/builtin/init.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
local _M = require('apicast.policy').new('HTTPS', '1.0.0')
local ssl = require('ngx.ssl')
local new = _M.new

function _M.new(configuration)
local policy = new(configuration)

if configuration then
policy.certificate_chain = assert(ssl.parse_pem_cert(configuration.certificate))
policy.priv_key = assert(ssl.parse_pem_priv_key(configuration.key))
end

return policy
end

function _M:ssl_certificate()
assert(ssl.clear_certs())

assert(ssl.set_cert(self.certificate_chain))
assert(ssl.set_priv_key(self.priv_key))
end

return _M
Loading