Add configuration for geoip2 module

Based on closed PRs #2551, #2755
This commit is contained in:
Maximilian Bode 2018-10-29 21:25:23 +01:00
parent 468872b7e9
commit c27c57dc8b
4 changed files with 133 additions and 0 deletions

View file

@ -86,6 +86,7 @@ The following table shows a configuration option's name, type, and the default v
|[proxy-protocol-header-timeout](#proxy-protocol-header-timeout)|string|"5s"|
|[use-gzip](#use-gzip)|bool|"true"|
|[use-geoip](#use-geoip)|bool|"true"|
|[use-geoip2](#use-geoip2)|bool|"false"|
|[enable-brotli](#enable-brotli)|bool|"false"|
|[brotli-level](#brotli-level)|int|4|
|[brotli-types](#brotli-types)|string|"application/xml+rss application/atom+xml application/javascript application/x-javascript application/json application/rss+xml application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/svg+xml image/x-icon text/css text/plain text/x-component"|
@ -498,6 +499,13 @@ The default mime type list to compress is: `application/atom+xml application/jav
Enables or disables ["geoip" module](http://nginx.org/en/docs/http/ngx_http_geoip_module.html) that creates variables with values depending on the client IP address, using the precompiled MaxMind databases.
_**default:**_ true
> __Note:__ MaxMind legacy databases are discontinued and will not receive updates after 2019-01-02, cf. [discontinuation notice](https://support.maxmind.com/geolite-legacy-discontinuation-notice/). Consider [use-geoip2](#use-geoip2) below.
## use-geoip2
Enables the [geoip2 module](https://github.com/leev/ngx_http_geoip2_module) for NGINX.
_**default:**_ false
## enable-brotli
Enables or disables compression of HTTP responses using the ["brotli" module](https://github.com/google/ngx_brotli).

View file

@ -347,6 +347,10 @@ type Configuration struct {
// http://nginx.org/en/docs/http/ngx_http_geoip_module.html
UseGeoIP bool `json:"use-geoip,omitempty"`
// UseGeoIP2 enables the geoip2 module for NGINX
// By default this is disabled
UseGeoIP2 bool `json:"use-geoip2,omitempty"`
// Enables or disables the use of the NGINX Brotli Module for compression
// https://github.com/google/ngx_brotli
EnableBrotli bool `json:"enable-brotli,omitempty"`
@ -630,6 +634,7 @@ func NewDefault() Configuration {
EnableBrotli: false,
UseGzip: true,
UseGeoIP: true,
UseGeoIP2: false,
WorkerProcesses: strconv.Itoa(runtime.NumCPU()),
WorkerShutdownTimeout: "10s",
LoadBalanceAlgorithm: defaultLoadBalancerAlgorithm,

View file

@ -12,6 +12,10 @@
# setup custom paths that do not require root access
pid /tmp/nginx.pid;
{{ if $cfg.UseGeoIP2 }}
load_module /etc/nginx/modules/ngx_http_geoip2_module.so;
{{ end }}
{{ if $cfg.EnableModsecurity }}
load_module /etc/nginx/modules/ngx_http_modsecurity_module.so;
{{ end }}
@ -123,6 +127,26 @@ http {
geoip_proxy_recursive on;
{{ end }}
{{ if $cfg.UseGeoIP2 }}
# https://github.com/leev/ngx_http_geoip2_module#example-usage
geoip2 /etc/nginx/geoip/GeoLite2-City.mmdb {
$geoip2_city_country_code source=$the_real_ip country iso_code;
$geoip2_city_country_name source=$the_real_ip country names en;
$geoip2_city source=$the_real_ip city names en;
$geoip2_postal_code source=$the_real_ip postal code;
$geoip2_dma_code source=$the_real_ip location metro_code;
$geoip2_latitude source=$the_real_ip location latitude;
$geoip2_longitude source=$the_real_ip location longitude;
$geoip2_region_code source=$the_real_ip subdivisions 0 iso_code;
$geoip2_region_name source=$the_real_ip subdivisions 0 names en;
}
geoip2 /etc/nginx/geoip/GeoLite2-ASN.mmdb {
$geoip2_asn source=$the_real_ip autonomous_system_number;
}
{{ end }}
aio threads;
aio_write on;

View file

@ -0,0 +1,96 @@
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package settings
import (
"strings"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/parnurzeal/gorequest"
"k8s.io/ingress-nginx/test/e2e/framework"
"net/http"
)
var _ = framework.IngressNginxDescribe("Geoip2", func() {
f := framework.NewDefaultFramework("geoip2")
host := "geoip2"
BeforeEach(func() {
err := f.NewEchoDeployment()
Expect(err).NotTo(HaveOccurred())
})
It("should only allow requests from specific countries", func() {
err := f.UpdateNginxConfigMapData("use-geoip2", "true")
Expect(err).NotTo(HaveOccurred())
httpSnippetAllowingOnlyAustralia :=
`map $geoip2_city_country_code $blocked_country {
default 1;
AU 0;
}`
err = f.UpdateNginxConfigMapData("http-snippet", httpSnippetAllowingOnlyAustralia)
Expect(err).NotTo(HaveOccurred())
err = f.WaitForNginxConfiguration(
func(cfg string) bool {
return strings.Contains(cfg, "map $geoip2_city_country_code $blocked_country")
})
Expect(err).NotTo(HaveOccurred())
configSnippet :=
`if ($blocked_country) {
return 403;
}`
annotations := map[string]string{
"nginx.ingress.kubernetes.io/configuration-snippet": configSnippet,
}
ing, err := f.EnsureIngress(framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations))
Expect(err).NotTo(HaveOccurred())
Expect(ing).NotTo(BeNil())
err = f.WaitForNginxConfiguration(
func(cfg string) bool {
return strings.Contains(cfg, "if ($blocked_country)")
})
Expect(err).NotTo(HaveOccurred())
// Should be blocked
usIp := "8.8.8.8"
resp, _, errs := gorequest.New().
Get(f.IngressController.HTTPURL).
Set("Host", host).
Set("X-Forwarded-For", usIp).
End()
Expect(errs).To(BeNil())
Expect(resp.StatusCode).Should(Equal(http.StatusForbidden))
// Shouldn't be blocked
australianIp := "1.1.1.1"
resp, _, errs = gorequest.New().
Get(f.IngressController.HTTPURL).
Set("Host", host).
Set("X-Forwarded-For", australianIp).
End()
Expect(errs).To(BeNil())
Expect(resp.StatusCode).Should(Equal(http.StatusOK))
})
})