Skip to content

Commit

Permalink
feat: add nginx, robots.txt, HTTP headers (#7683)
Browse files Browse the repository at this point in the history
* feat: nginx + robots.txt

* feat: minimal /health/ endpoint

* ci: startupProbe for datatracker pod

* ci: probe auth pod; set timeoutSeconds

* feat: add CSP and other headers to nginx

* fix: typo in nginx.conf

* feat: split auth/dt nginx confs

* test: test health endpoint

* ci: auth service on port 80

We'll remove http-old (8080) in the future.

* ci: rename auth container/nginx cfg
  • Loading branch information
jennifer-richards authored Jul 15, 2024
1 parent 17e0f57 commit 18bb793
Show file tree
Hide file tree
Showing 7 changed files with 141 additions and 9 deletions.
2 changes: 2 additions & 0 deletions ietf/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from django.contrib import admin
from django.contrib.sitemaps import views as sitemap_views
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
from django.http import HttpResponse
from django.urls import include, path
from django.views import static as static_view
from django.views.generic import TemplateView
Expand Down Expand Up @@ -35,6 +36,7 @@

urlpatterns = [
url(r'^$', views_search.frontpage),
url(r'^health/', lambda _: HttpResponse()),
url(r'^accounts/', include('ietf.ietfauth.urls')),
url(r'^admin/', admin.site.urls),
url(r'^admin/docs/', include('django.contrib.admindocs.urls')),
Expand Down
9 changes: 9 additions & 0 deletions ietf/utils/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -679,3 +679,12 @@ class TestForm(Form):
self.assertTrue(changed_form.has_changed())
unchanged_form = TestForm(initial={'test_field': [1]}, data={'test_field': [1]})
self.assertFalse(unchanged_form.has_changed())


class HealthTests(TestCase):
def test_health(self):
self.assertEqual(
self.client.get("/health/").status_code,
200,
)

43 changes: 38 additions & 5 deletions k8s/auth.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,6 @@ spec:
- name: auth
image: "ghcr.io/ietf-tools/datatracker:$APP_IMAGE_TAG"
imagePullPolicy: Always
ports:
- containerPort: 8000
name: http
protocol: TCP
volumeMounts:
- name: dt-vol
mountPath: /a
Expand All @@ -49,6 +45,14 @@ spec:
envFrom:
- secretRef:
name: dt-secrets-env
startupProbe:
httpGet:
port: 8000
path: /health/
initialDelaySeconds: 10
periodSeconds: 5
failureThreshold: 30
timeoutSeconds: 3
securityContext:
allowPrivilegeEscalation: false
capabilities:
Expand All @@ -58,6 +62,28 @@ spec:
runAsUser: 1000
runAsGroup: 1000
# -----------------------------------------------------
# Nginx Container
# -----------------------------------------------------
- name: nginx
image: "ghcr.io/nginxinc/nginx-unprivileged:1.27"
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
name: http
protocol: TCP
livenessProbe:
httpGet:
port: 8080
path: /health/nginx
securityContext:
readOnlyRootFilesystem: true
volumeMounts:
- name: nginx-tmp
mountPath: /tmp
- name: dt-cfg
mountPath: /etc/nginx/conf.d/auth.conf
subPath: nginx-auth.conf
# -----------------------------------------------------
# ScoutAPM Container
# -----------------------------------------------------
- name: scoutapm
Expand Down Expand Up @@ -97,6 +123,9 @@ spec:
- name: dt-cfg
configMap:
name: files-cfgmap
- name: nginx-tmp
emptyDir:
sizeLimit: "500Mi"
dnsPolicy: ClusterFirst
restartPolicy: Always
terminationGracePeriodSeconds: 60
Expand All @@ -108,9 +137,13 @@ metadata:
spec:
type: ClusterIP
ports:
- port: 8080
- port: 80
targetPort: http
protocol: TCP
name: http
- port: 8080
targetPort: http
protocol: TCP
name: http-old
selector:
app: auth
37 changes: 33 additions & 4 deletions k8s/datatracker.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,6 @@ spec:
- name: datatracker
image: "ghcr.io/ietf-tools/datatracker:$APP_IMAGE_TAG"
imagePullPolicy: Always
ports:
- containerPort: 8000
name: http
protocol: TCP
volumeMounts:
- name: dt-vol
mountPath: /a
Expand All @@ -49,6 +45,14 @@ spec:
envFrom:
- secretRef:
name: dt-secrets-env
startupProbe:
httpGet:
port: 8000
path: /health/
initialDelaySeconds: 10
periodSeconds: 5
failureThreshold: 30
timeoutSeconds: 3
securityContext:
allowPrivilegeEscalation: false
capabilities:
Expand All @@ -58,6 +62,28 @@ spec:
runAsUser: 1000
runAsGroup: 1000
# -----------------------------------------------------
# Nginx Container
# -----------------------------------------------------
- name: nginx
image: "ghcr.io/nginxinc/nginx-unprivileged:1.27"
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
name: http
protocol: TCP
livenessProbe:
httpGet:
port: 8080
path: /health/nginx
securityContext:
readOnlyRootFilesystem: true
volumeMounts:
- name: nginx-tmp
mountPath: /tmp
- name: dt-cfg
mountPath: /etc/nginx/conf.d/datatracker.conf
subPath: nginx-datatracker.conf
# -----------------------------------------------------
# ScoutAPM Container
# -----------------------------------------------------
- name: scoutapm
Expand Down Expand Up @@ -126,6 +152,9 @@ spec:
- name: dt-cfg
configMap:
name: files-cfgmap
- name: nginx-tmp
emptyDir:
sizeLimit: "500Mi"
dnsPolicy: ClusterFirst
restartPolicy: Always
terminationGracePeriodSeconds: 60
Expand Down
2 changes: 2 additions & 0 deletions k8s/kustomization.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ namePrefix: dt-
configMapGenerator:
- name: files-cfgmap
files:
- nginx-auth.conf
- nginx-datatracker.conf
- settings_local.py
resources:
- auth.yaml
Expand Down
34 changes: 34 additions & 0 deletions k8s/nginx-auth.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
server {
listen 8080 default_server;
server_name _;

# Note that regex location matches take priority over non-regex "prefix" matches. Use regexes so that
# our deny all rule does not squelch the other locations.
location ~ ^/health/nginx$ {
return 200;
}

location ~ ^/robots.txt$ {
add_header Content-Type text/plain;
return 200 "User-agent: *\nDisallow: /\n";
}

location ~ ^/accounts/create.* {
return 302 https://datatracker.ietf.org/accounts/create;
}

# n.b. (?!...) is a negative lookahead group
location ~ ^(/(?!(api/openid/|accounts/login/|accounts/logout/|accounts/reset/|person/.*/photo|group/groupmenu.json)).*) {
deny all;
}

location / {
add_header Content-Security-Policy "default-src 'self' 'unsafe-inline' data: https://datatracker.ietf.org/ https://www.ietf.org/ http://ietf.org/ https://analytics.ietf.org https://static.ietf.org; frame-ancestors 'self' ietf.org *.ietf.org meetecho.com *.meetecho.com gather.town *.gather.town";
proxy_set_header Host $${keepempty}host;
proxy_set_header Connection close;
proxy_set_header X-Request-Start "t=${msec}";
proxy_set_header X-Forwarded-For $${keepempty}proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $${keepempty}remote_addr;
proxy_pass http://localhost:8000;
}
}
23 changes: 23 additions & 0 deletions k8s/nginx-datatracker.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
server {
listen 8080 default_server;
server_name _;

location /health/nginx {
return 200;
}

location /robots.txt {
add_header Content-Type text/plain;
return 200 "User-agent: *\nDisallow: /doc/pdf/\n";
}

location / {
add_header Content-Security-Policy "default-src 'self' 'unsafe-inline' data: https://datatracker.ietf.org/ https://www.ietf.org/ http://ietf.org/ https://analytics.ietf.org https://static.ietf.org; frame-ancestors 'self' ietf.org *.ietf.org meetecho.com *.meetecho.com";
proxy_set_header Host $${keepempty}host;
proxy_set_header Connection close;
proxy_set_header X-Request-Start "t=${msec}";
proxy_set_header X-Forwarded-For $${keepempty}proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $${keepempty}remote_addr;
proxy_pass http://localhost:8000;
}
}

0 comments on commit 18bb793

Please sign in to comment.