diff --git a/k8s/helmfile/env/local/mediawiki-proxy-nginx.nginx.conf b/k8s/helmfile/env/local/mediawiki-proxy-nginx.nginx.conf new file mode 100644 index 000000000..3cdcd2218 --- /dev/null +++ b/k8s/helmfile/env/local/mediawiki-proxy-nginx.nginx.conf @@ -0,0 +1,109 @@ +# When listing a BUNCH of stuff in a map, this needed bumping.. +map_hash_bucket_size 128; + +map $dbversion $mwversion { + mw1.39-wbs1 139-app; + mw1.43-wbs1 143-app; +} + +# Figure out which group of backends we might want to send the request to based on uri +# TODO add Special:EntityData??? +map $request_uri $mwgroup { + ~^/()(w/load.php.*) "web"; + ~^/()(w/api.php.*) "api"; + ~^/()(w/rest.php.*) "api"; + default "web"; +} + +proxy_cache_path /bitnami/nginx/version_cache levels=1:2 keys_zone=version_cache:10m max_size=50m; + +server { + listen 8080; + server_name _; # This is just an invalid value which will never trigger on a real hostname. + + # Resolver is needed when using variables in proxy_pass directives... + # https://serverfault.com/a/937172 + # https://github.com/kubernetes-sigs/aws-load-balancer-controller/issues/795#issuecomment-451257479 + resolver kube-dns.kube-system.svc.cluster.local valid=10s; + + # IP range matches current kubernetes pod IPs + set_real_ip_from 10.0.0.0/14; + real_ip_header X-Forwarded-For; + proxy_set_header X-Forwarded-For "$proxy_add_x_forwarded_for"; + + client_max_body_size 1m; + + port_in_redirect off; + + proxy_set_header Host $http_host; + + # mitigate HTTPoxy Vulnerability + # https://www.nginx.com/blog/mitigating-the-httpoxy-vulnerability-with-nginx/ + proxy_set_header Proxy ""; + + proxy_redirect off; + proxy_request_buffering on; + proxy_http_version 1.1; + + proxy_cookie_domain off; + proxy_cookie_path off; + + # In case of errors try the next upstream server before returning an error + proxy_next_upstream error timeout; + proxy_next_upstream_timeout 0; + proxy_next_upstream_tries 3; + + # Custom headers to proxied server + proxy_connect_timeout 5s; + proxy_send_timeout 60s; + proxy_read_timeout 60s; + + proxy_buffering off; + proxy_buffer_size 4k; + proxy_buffers 4 4k; + + proxy_max_temp_file_size 1024m; + + # Allowoverriding the group decision using the magic header + if ($http_x_wbstack_alpha) { + set $mwgroup "alpha"; + } + + ############# Locations ############# + + location = /kube-probe { + add_header Content-Type text/plain; + return 200 'gangnam style!'; + } + + location = /version { + internal; + proxy_buffering on; + proxy_pass http://api-app-backend.default.svc.cluster.local/backend/ingress/getWikiVersionForDomain?domain=$host; + proxy_pass_request_body off; + proxy_set_header Content-Length ""; + proxy_set_header X-Original-URI $request_uri; + proxy_cache version_cache; + proxy_cache_key $host; + proxy_cache_valid any 5m; + proxy_ignore_headers Cache-Control; + proxy_ignore_headers Vary; + proxy_set_header Accept-Encoding ""; + add_header X-Cache-Status $upstream_cache_status; + } + + location = /version_error { + internal; + default_type text/html; + return 404 'You have requested the domain: $host. But that wiki can not currently be loaded.
It may never have existed or it might now be deleted.
You can check the platform status at status.wikibase.cloud.'; + } + + location ~* "^/()(.*)" { + auth_request /version; + error_page 401 = /version_error; + auth_request_set $dbversion $upstream_http_x_version; + add_header X-WBSTACK-MW-BACKEND mediawiki-$mwversion-$mwgroup; + proxy_pass http://mediawiki-$mwversion-$mwgroup.default.svc.cluster.local:80; + rewrite "(?i)/()(.*)" /$2 break; + } +} diff --git a/k8s/helmfile/env/local/mediawiki-proxy-nginx.values.yaml.gotmpl b/k8s/helmfile/env/local/mediawiki-proxy-nginx.values.yaml.gotmpl new file mode 100644 index 000000000..0e989cd95 --- /dev/null +++ b/k8s/helmfile/env/local/mediawiki-proxy-nginx.values.yaml.gotmpl @@ -0,0 +1,8 @@ +replicaCount: 1 + +serverBlock: |- +{{ readFile "mediawiki-proxy-nginx.nginx.conf" | indent 2 }} + +resources: + limits: + cpu: 50m diff --git a/k8s/helmfile/env/local/tool-quickstatements.values.yaml.gotmpl b/k8s/helmfile/env/local/tool-quickstatements.values.yaml.gotmpl index 63e61d96a..26b4ab408 100644 --- a/k8s/helmfile/env/local/tool-quickstatements.values.yaml.gotmpl +++ b/k8s/helmfile/env/local/tool-quickstatements.values.yaml.gotmpl @@ -2,7 +2,7 @@ image: tag: sha-30c6090 platform: - mediawikiBackendHost: mediawiki-143-app-backend.default.svc.cluster.local + mediawikiBackendHost: mediawiki-proxy-nginx.default.svc.cluster.local extraCert: secretName: {{ .Values.tlsSecret }} diff --git a/k8s/helmfile/env/local/tool-widar.values.yaml.gotmpl b/k8s/helmfile/env/local/tool-widar.values.yaml.gotmpl index e22f9d0b5..35abd88b5 100644 --- a/k8s/helmfile/env/local/tool-widar.values.yaml.gotmpl +++ b/k8s/helmfile/env/local/tool-widar.values.yaml.gotmpl @@ -2,7 +2,8 @@ image: tag: sha-b67e613 platform: - mediawikiBackendHost: mediawiki-143-app-backend.default.svc.cluster.local + #mediawikiBackendHost: mediawiki-143-app-backend.default.svc.cluster.local + mediawikiBackendHost: mediawiki-proxy-nginx.default.svc.cluster.local extraCert: secretName: {{ .Values.tlsSecret }} diff --git a/k8s/helmfile/env/production/mediawiki-proxy-nginx.nginx.conf b/k8s/helmfile/env/production/mediawiki-proxy-nginx.nginx.conf new file mode 100644 index 000000000..3cdcd2218 --- /dev/null +++ b/k8s/helmfile/env/production/mediawiki-proxy-nginx.nginx.conf @@ -0,0 +1,109 @@ +# When listing a BUNCH of stuff in a map, this needed bumping.. +map_hash_bucket_size 128; + +map $dbversion $mwversion { + mw1.39-wbs1 139-app; + mw1.43-wbs1 143-app; +} + +# Figure out which group of backends we might want to send the request to based on uri +# TODO add Special:EntityData??? +map $request_uri $mwgroup { + ~^/()(w/load.php.*) "web"; + ~^/()(w/api.php.*) "api"; + ~^/()(w/rest.php.*) "api"; + default "web"; +} + +proxy_cache_path /bitnami/nginx/version_cache levels=1:2 keys_zone=version_cache:10m max_size=50m; + +server { + listen 8080; + server_name _; # This is just an invalid value which will never trigger on a real hostname. + + # Resolver is needed when using variables in proxy_pass directives... + # https://serverfault.com/a/937172 + # https://github.com/kubernetes-sigs/aws-load-balancer-controller/issues/795#issuecomment-451257479 + resolver kube-dns.kube-system.svc.cluster.local valid=10s; + + # IP range matches current kubernetes pod IPs + set_real_ip_from 10.0.0.0/14; + real_ip_header X-Forwarded-For; + proxy_set_header X-Forwarded-For "$proxy_add_x_forwarded_for"; + + client_max_body_size 1m; + + port_in_redirect off; + + proxy_set_header Host $http_host; + + # mitigate HTTPoxy Vulnerability + # https://www.nginx.com/blog/mitigating-the-httpoxy-vulnerability-with-nginx/ + proxy_set_header Proxy ""; + + proxy_redirect off; + proxy_request_buffering on; + proxy_http_version 1.1; + + proxy_cookie_domain off; + proxy_cookie_path off; + + # In case of errors try the next upstream server before returning an error + proxy_next_upstream error timeout; + proxy_next_upstream_timeout 0; + proxy_next_upstream_tries 3; + + # Custom headers to proxied server + proxy_connect_timeout 5s; + proxy_send_timeout 60s; + proxy_read_timeout 60s; + + proxy_buffering off; + proxy_buffer_size 4k; + proxy_buffers 4 4k; + + proxy_max_temp_file_size 1024m; + + # Allowoverriding the group decision using the magic header + if ($http_x_wbstack_alpha) { + set $mwgroup "alpha"; + } + + ############# Locations ############# + + location = /kube-probe { + add_header Content-Type text/plain; + return 200 'gangnam style!'; + } + + location = /version { + internal; + proxy_buffering on; + proxy_pass http://api-app-backend.default.svc.cluster.local/backend/ingress/getWikiVersionForDomain?domain=$host; + proxy_pass_request_body off; + proxy_set_header Content-Length ""; + proxy_set_header X-Original-URI $request_uri; + proxy_cache version_cache; + proxy_cache_key $host; + proxy_cache_valid any 5m; + proxy_ignore_headers Cache-Control; + proxy_ignore_headers Vary; + proxy_set_header Accept-Encoding ""; + add_header X-Cache-Status $upstream_cache_status; + } + + location = /version_error { + internal; + default_type text/html; + return 404 'You have requested the domain: $host. But that wiki can not currently be loaded.
It may never have existed or it might now be deleted.
You can check the platform status at status.wikibase.cloud.'; + } + + location ~* "^/()(.*)" { + auth_request /version; + error_page 401 = /version_error; + auth_request_set $dbversion $upstream_http_x_version; + add_header X-WBSTACK-MW-BACKEND mediawiki-$mwversion-$mwgroup; + proxy_pass http://mediawiki-$mwversion-$mwgroup.default.svc.cluster.local:80; + rewrite "(?i)/()(.*)" /$2 break; + } +} diff --git a/k8s/helmfile/env/production/mediawiki-proxy-nginx.values.yaml.gotmpl b/k8s/helmfile/env/production/mediawiki-proxy-nginx.values.yaml.gotmpl new file mode 100644 index 000000000..f332662ae --- /dev/null +++ b/k8s/helmfile/env/production/mediawiki-proxy-nginx.values.yaml.gotmpl @@ -0,0 +1,66 @@ +image: + registry: ghcr.io + repository: wbstack/nginx + tag: 1.17.10-debian-10-r11 + +# see https://github.com/wbstack/bitnami-legacy/blob/nginx/5.2.4/bitnami/nginx/values.yaml#L49 +cloneStaticSiteFromGit: + # Depends on an image which may no longer exist + enabled: false + +# see https://github.com/wbstack/bitnami-legacy/blob/nginx/5.2.4/bitnami/nginx/values.yaml#L251 +metrics: + # Depends on an image which may no longer exist + enabled: false + +replicaCount: 3 + +resources: + limits: + cpu: null + memory: 128Mi + requests: + cpu: 20m + memory: 128Mi + +serverBlock: |- +{{ readFile "mediawiki-proxy-nginx.nginx.conf" | indent 2 }} + +livenessProbe: + httpGet: + path: /kube-probe + port: http + initialDelaySeconds: 30 + timeoutSeconds: 5 + failureThreshold: 6 +readinessProbe: + httpGet: + path: /kube-probe + port: http + initialDelaySeconds: 5 + timeoutSeconds: 3 + periodSeconds: 5 + +service: + type: ClusterIP + port: 8080 + +ingress: + enabled: false +metrics: + enabled: false +cloneStaticSiteFromGit: + enabled: false + +affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 100 + podAffinityTerm: + labelSelector: + matchExpressions: + - key: "app.kubernetes.io/instance" + operator: In + values: + - platform-nginx + topologyKey: "kubernetes.io/hostname" diff --git a/k8s/helmfile/env/production/platform-nginx.nginx.conf b/k8s/helmfile/env/production/platform-nginx.nginx.conf index bd1b6e521..926164e39 100644 --- a/k8s/helmfile/env/production/platform-nginx.nginx.conf +++ b/k8s/helmfile/env/production/platform-nginx.nginx.conf @@ -3,6 +3,7 @@ map_hash_bucket_size 128; map $dbversion $mwversion { mw1.39-wbs1 139-app; + mw1.43-wbs1 143-app; } # Figure out which group of backends we might want to send the request to based on uri diff --git a/k8s/helmfile/helmfile.yaml b/k8s/helmfile/helmfile.yaml index 3eaee2fa4..ccd9cd7f0 100644 --- a/k8s/helmfile/helmfile.yaml +++ b/k8s/helmfile/helmfile.yaml @@ -130,6 +130,11 @@ releases: chart: https://github.com/wbstack/bitnami-legacy/releases/download/nginx%2F5.2.4/nginx-5.2.4.tgz <<: *default_release + - name: mediawiki-proxy-nginx + namespace: default + chart: https://github.com/wbstack/bitnami-legacy/releases/download/nginx%2F5.2.4/nginx-5.2.4.tgz + <<: *default_release + - name: anubis namespace: default chart: wbstack/anubis