Advice
며칠간 Rocket Loader를 사용해보니 Content Security Policy를 최적화하는데 손이 많이 간다. 워드프레스에 설치한 다양한 플러그인이 다양한 도메인의 자바스크립트를 불러오다 보니 일이 많더라. 워드프레스에는 Rocket Loader와 똑같은 일을 하는 플러그인이 많고 이런 플러그인을 사용하면 CSP 헤더를 수정하느라 고생할 필요가 없다. Rocket Loader는 개인 블로그에는 과한 듯 싶다.
CloudFlare의 Rocker Loader를 적용했더니 Discourse 포럼 사이트가 제대로 로딩 안 되더라. CloudFlare 측에서 JavaScript를 수정하다 오류가 발생했나 싶었다. 하지만 웹브라우저의 개발자 도구로 살펴보니 Content Security Policy 관련 오류가 발생하더라.
결국 Nginx 쪽에 Content Security Policy 헤더를 넣어주어 문제를 해결했다. CloudFlare의 다른 기능을 쓰다가 또 웹사이트를 깨먹을까봐 공식문서에 있는 directive를 몽땅 넣어줬다. Kubernetes의 Nginx Ingress Controller 기준으로 코드를 짜면 다음과 같다.
apiVersion: v1
data:
Content-Security-Policy: script-src 'self' ajax.cloudflare.com; script-src 'self' 'unsafe-inline'; script-src 'self' static.cloudflareinsights.com; script-src static.cloudflareinsights.com; connect-src cloudflareinsights.co;
kind: ConfigMap
metadata:
name: custom-headers
namespace: ingress-nginx
---
apiVersion: v1
data:
add-headers: "ingress-nginx/custom-headers"
kind: ConfigMap
metadata:
name: ingress-nginx-controller
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
공식 문서에서 언급하듯 ConfigMap을 변경한 후에 Controller를 재배포해야 설정이 적용된다. 재배포를 하기 싫거나 특정 웹 서비스에만 CSP 헤더를 추가하고 싶다면 annotation 에 설정을 달아도 된다.
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: discourse
namespace: discourse
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/configuration-snippet: |
more_set_headers "script-src 'self' ajax.cloudflare.com";
전과 후
워낙 소규모 서버라 성능이 들쭉날쭉해서 성능 테스트는 의미가 없지만 재미 삼아 성능이 얼마나 나아졌나 살펴본다.
참고
- CSP, RocketLoader and Nginx? – Security – Cloudflare Community
- What does Rocket Loader do? – Cloudflare Help Center
- Using Content Security Policy (CSP) with Cloudflare – Cloudflare Help Center
- Custom Headers – NGINX Ingress Controller