Skip to content

Commit 8354d4e

Browse files
author
Julian Strobl
committed
Add SSL services annotation
If an application in a container requires HTTPS, one needs to set the 'proxy_path https://...' instead of 'proxy_pass http://...'. With this patch one can use the annotation: 'nginx.org/ssl-services: "service1[,service2,...]"' to specify, which services require HTTPS. Fixes #61
1 parent ea9571b commit 8354d4e

File tree

7 files changed

+80
-8
lines changed

7 files changed

+80
-8
lines changed

examples/ssl-services/README.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# SSL Services Support
2+
3+
To load balance an application that requires HTTPS with NGINX Ingress controllers, you need to add the **nginx.org/ssl-services** annotation to your Ingress resource definition. The annotation specifies which services are SSL services. The annotation syntax is as follows:
4+
```
5+
nginx.org/ssl-services: "service1[,service2,...]"
6+
```
7+
8+
In the following example we load balance three applications, one of which requires HTTPS:
9+
```yaml
10+
apiVersion: extensions/v1beta1
11+
kind: Ingress
12+
metadata:
13+
name: cafe-ingress
14+
annotations:
15+
nginx.org/ssl-services: "ssl-svc"
16+
spec:
17+
rules:
18+
- host: cafe.example.com
19+
http:
20+
paths:
21+
- path: /tea
22+
backend:
23+
serviceName: tea-svc
24+
servicePort: 80
25+
- path: /coffee
26+
backend:
27+
serviceName: coffee-svc
28+
servicePort: 80
29+
- path: /ssl
30+
backend:
31+
serviceName: ssl-svc
32+
servicePort: 443
33+
```
34+
*ssl-svc* is a service for an HTTPS application. The service becomes available at the `/ssl` path. Note how we used the **nginx.org/ssl-services** annotation.

nginx-controller/nginx/configurator.go

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ func (cnf *Configurator) generateNginxCfg(ingEx *IngressEx, pems map[string]stri
8080
upstreams := make(map[string]Upstream)
8181

8282
wsServices := getWebsocketServices(ingEx)
83+
sslServices := getSSLServices(ingEx)
8384

8485
if ingEx.Ingress.Spec.Backend != nil {
8586
name := getNameForUpstream(ingEx.Ingress, emptyHost, ingEx.Ingress.Spec.Backend.ServiceName)
@@ -119,7 +120,7 @@ func (cnf *Configurator) generateNginxCfg(ingEx *IngressEx, pems map[string]stri
119120
upstreams[upsName] = upstream
120121
}
121122

122-
loc := createLocation(pathOrDefault(path.Path), upstreams[upsName], &ingCfg, wsServices[path.Backend.ServiceName])
123+
loc := createLocation(pathOrDefault(path.Path), upstreams[upsName], &ingCfg, wsServices[path.Backend.ServiceName], sslServices[path.Backend.ServiceName])
123124
locations = append(locations, loc)
124125

125126
if loc.Path == "/" {
@@ -129,7 +130,7 @@ func (cnf *Configurator) generateNginxCfg(ingEx *IngressEx, pems map[string]stri
129130

130131
if rootLocation == false && ingEx.Ingress.Spec.Backend != nil {
131132
upsName := getNameForUpstream(ingEx.Ingress, emptyHost, ingEx.Ingress.Spec.Backend.ServiceName)
132-
loc := createLocation(pathOrDefault("/"), upstreams[upsName], &ingCfg, wsServices[ingEx.Ingress.Spec.Backend.ServiceName])
133+
loc := createLocation(pathOrDefault("/"), upstreams[upsName], &ingCfg, wsServices[ingEx.Ingress.Spec.Backend.ServiceName], sslServices[ingEx.Ingress.Spec.Backend.ServiceName])
133134
locations = append(locations, loc)
134135
}
135136

@@ -150,7 +151,7 @@ func (cnf *Configurator) generateNginxCfg(ingEx *IngressEx, pems map[string]stri
150151

151152
upsName := getNameForUpstream(ingEx.Ingress, emptyHost, ingEx.Ingress.Spec.Backend.ServiceName)
152153

153-
loc := createLocation(pathOrDefault("/"), upstreams[upsName], &ingCfg, wsServices[ingEx.Ingress.Spec.Backend.ServiceName])
154+
loc := createLocation(pathOrDefault("/"), upstreams[upsName], &ingCfg, wsServices[ingEx.Ingress.Spec.Backend.ServiceName], sslServices[ingEx.Ingress.Spec.Backend.ServiceName])
154155
locations = append(locations, loc)
155156

156157
server.Locations = locations
@@ -187,14 +188,27 @@ func getWebsocketServices(ingEx *IngressEx) map[string]bool {
187188
return wsServices
188189
}
189190

190-
func createLocation(path string, upstream Upstream, cfg *Config, websocket bool) Location {
191+
func getSSLServices(ingEx *IngressEx) map[string]bool {
192+
sslServices := make(map[string]bool)
193+
194+
if services, exists := ingEx.Ingress.Annotations["nginx.org/ssl-services"]; exists {
195+
for _, svc := range strings.Split(services, ",") {
196+
sslServices[svc] = true
197+
}
198+
}
199+
200+
return sslServices
201+
}
202+
203+
func createLocation(path string, upstream Upstream, cfg *Config, websocket bool, ssl bool) Location {
191204
loc := Location{
192205
Path: path,
193206
Upstream: upstream,
194207
ProxyConnectTimeout: cfg.ProxyConnectTimeout,
195208
ProxyReadTimeout: cfg.ProxyReadTimeout,
196209
ClientMaxBodySize: cfg.ClientMaxBodySize,
197210
Websocket: websocket,
211+
SSL: ssl,
198212
}
199213

200214
return loc

nginx-controller/nginx/ingress.tmpl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ server {
3939
proxy_set_header X-Forwarded-Host $host;
4040
proxy_set_header X-Forwarded-Port $server_port;
4141
proxy_set_header X-Forwarded-Proto $scheme;
42+
{{if $location.SSL}}
43+
proxy_pass https://{{$location.Upstream.Name}};
44+
{{else}}
4245
proxy_pass http://{{$location.Upstream.Name}};
46+
{{end}}
4347
}{{end}}
4448
}{{end}}

nginx-controller/nginx/nginx.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ type Location struct {
5353
ProxyReadTimeout string
5454
ClientMaxBodySize string
5555
Websocket bool
56+
SSL bool
5657
}
5758

5859
// NginxMainConfig describe the main NGINX configuration file

nginx-plus-controller/nginx/configurator.go

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ func (cnf *Configurator) generateNginxCfg(ingEx *IngressEx, pems map[string]stri
8787

8888
wsServices := getWebsocketServices(ingEx)
8989
spServices := getSessionPersistenceServices(ingEx)
90+
sslServices := getSSLServices(ingEx)
9091

9192
if ingEx.Ingress.Spec.Backend != nil {
9293
name := getNameForUpstream(ingEx.Ingress, emptyHost, ingEx.Ingress.Spec.Backend.ServiceName)
@@ -128,7 +129,7 @@ func (cnf *Configurator) generateNginxCfg(ingEx *IngressEx, pems map[string]stri
128129
upstreams[upsName] = upstream
129130
}
130131

131-
loc := createLocation(pathOrDefault(path.Path), upstreams[upsName], &ingCfg, wsServices[path.Backend.ServiceName])
132+
loc := createLocation(pathOrDefault(path.Path), upstreams[upsName], &ingCfg, wsServices[path.Backend.ServiceName], sslServices[path.Backend.ServiceName])
132133
locations = append(locations, loc)
133134

134135
if loc.Path == "/" {
@@ -138,7 +139,7 @@ func (cnf *Configurator) generateNginxCfg(ingEx *IngressEx, pems map[string]stri
138139

139140
if rootLocation == false && ingEx.Ingress.Spec.Backend != nil {
140141
upsName := getNameForUpstream(ingEx.Ingress, emptyHost, ingEx.Ingress.Spec.Backend.ServiceName)
141-
loc := createLocation(pathOrDefault("/"), upstreams[upsName], &ingCfg, wsServices[ingEx.Ingress.Spec.Backend.ServiceName])
142+
loc := createLocation(pathOrDefault("/"), upstreams[upsName], &ingCfg, wsServices[ingEx.Ingress.Spec.Backend.ServiceName], sslServices[ingEx.Ingress.Spec.Backend.ServiceName])
142143
locations = append(locations, loc)
143144
}
144145

@@ -163,7 +164,7 @@ func (cnf *Configurator) generateNginxCfg(ingEx *IngressEx, pems map[string]stri
163164

164165
upsName := getNameForUpstream(ingEx.Ingress, emptyHost, ingEx.Ingress.Spec.Backend.ServiceName)
165166

166-
loc := createLocation(pathOrDefault("/"), upstreams[upsName], &ingCfg, wsServices[ingEx.Ingress.Spec.Backend.ServiceName])
167+
loc := createLocation(pathOrDefault("/"), upstreams[upsName], &ingCfg, wsServices[ingEx.Ingress.Spec.Backend.ServiceName], sslServices[ingEx.Ingress.Spec.Backend.ServiceName])
167168
locations = append(locations, loc)
168169

169170
server.Locations = locations
@@ -200,6 +201,18 @@ func getWebsocketServices(ingEx *IngressEx) map[string]bool {
200201
return wsServices
201202
}
202203

204+
func getSSLServices(ingEx *IngressEx) map[string]bool {
205+
sslServices := make(map[string]bool)
206+
207+
if services, exists := ingEx.Ingress.Annotations["nginx.org/ssl-services"]; exists {
208+
for _, svc := range strings.Split(services, ",") {
209+
sslServices[svc] = true
210+
}
211+
}
212+
213+
return sslServices
214+
}
215+
203216
func getSessionPersistenceServices(ingEx *IngressEx) map[string]string {
204217
spServices := make(map[string]string)
205218

@@ -231,14 +244,15 @@ func parseStickyService(service string) (serviceName string, stickyCookie string
231244
return svcNameParts[1], parts[1], nil
232245
}
233246

234-
func createLocation(path string, upstream Upstream, cfg *Config, websocket bool) Location {
247+
func createLocation(path string, upstream Upstream, cfg *Config, websocket bool, ssl bool) Location {
235248
loc := Location{
236249
Path: path,
237250
Upstream: upstream,
238251
ProxyConnectTimeout: cfg.ProxyConnectTimeout,
239252
ProxyReadTimeout: cfg.ProxyReadTimeout,
240253
ClientMaxBodySize: cfg.ClientMaxBodySize,
241254
Websocket: websocket,
255+
SSL: ssl,
242256
}
243257

244258
return loc

nginx-plus-controller/nginx/ingress.tmpl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ server {
4444
proxy_set_header X-Forwarded-Host $host;
4545
proxy_set_header X-Forwarded-Port $server_port;
4646
proxy_set_header X-Forwarded-Proto $scheme;
47+
{{if $location.SSL}}
48+
proxy_pass https://{{$location.Upstream.Name}};
49+
{{else}}
4750
proxy_pass http://{{$location.Upstream.Name}};
51+
{{end}}
4852
}{{end}}
4953
}{{end}}

nginx-plus-controller/nginx/nginx.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ type Location struct {
7676
ProxyReadTimeout string
7777
ClientMaxBodySize string
7878
Websocket bool
79+
SSL bool
7980
}
8081

8182
// NginxMainConfig describe the main NGINX configuration file

0 commit comments

Comments
 (0)