콘텐츠로 건너뛰기

Platform (플랫폼)

2 토픽 2 게시물

하위 카테고리


  • 1 토픽
    1 게시물
    navystackN

    클라우드플레어 터널은 참 편리합니다.
    별도의 포트를 노출할 필요도 없고, 클라우드 플레이어의 빠른 망을 통해서 빠르게 로딩할 수 있습니다.

    다만, 관련된 문서가 적어서 정보 찾기가 조금 힘들다는 것이 단점이지만, 시간이 해결해 줄 것이라고 믿습니다 ^^

    아래는 제가 온몸비틀기를 한 결과물 입니다.

    모든 구간에서의 통신 암호화는 중요하다. 클라우드플레어 역시 신뢰할 수 있지만, 별개의 문제다. 자체 서명 인증서는 Revoke등 관리하기가 까다롭다. 자체 서명 인증서는 또한 권위의 문제도 존재한다.

    위와 같은 필요성으로 Traefik과 Cloudflare Tunnel을 사용해서

    Traefik 리버스 프록시로 ACME 프로토콜을 통해서 인증서를 발급하고 Cloudflared로 연결한다.

    현재, Traefik에서 SNI를 사용중입니다.
    따라서 IP로 접속하면 HOST에 관한 정보를 전달해야하는데, 이 부분이 가장 힘들었습니다.

    정답은

    'Origin Server Name': 'Hostname that cloudflared should expect from your origin server certificate.'

    이 부분 이었습니다.

    번역 하자면,

    '원본 서버 이름': '클라우드플레어가 원본 서버 인증서에서 예상하는 호스트 이름입니다.'

    인건데, 뭘 기대하나 싶었는데 이게 HOST를 전달하는 것이었습니다.

    { "ingress": [ { "hostname": "askfront.com", "id": "1", "originRequest": { "originServerName": "askfront.com" }, "service": "https://traefik" } ], "warp-routing": { "enabled": false } }

    이렇게 잡아주면 됩니다.

    0e438807-fad3-4e36-957d-3d8ac75a09e1-image.png

    Cloudflared도 docker-compose로 올렸고, Traefik도 docker-compose로 올렸습니다.

    당연히, 같은 네트워크에 있고, Traefik에는 2개의 네트워크를 할당해서 분리했습니다.
    같은 네트워크에 속한 부분이 있으니, 서비스 이름( 컨테이너 이름을 설정했다면, 컨테이너 이름) 과 포트로 통신할 수 있습니다.

    결과는 잘 됩니다. :)
    어떻게 해결할 방법이 없어서 사설 인증서라도 적용하고 No TLS Verify 옵션을 주었는데, 이제 정석대로 할수 있게 되어 마음이 편해졌네요.

    클라우드플레어는 정말... 잘 만들었는데 가끔씩 CLI로 확인해야 하는 것들이 있거나, API로만 접근 가능한 것이 있어서 불편할 때도 많네요...

    혹시 Traefik 리버스 프록시를 사용하고, Cloudflare의 프록시와 방화벽을 사용하고 싶으나, 그냥 프록시를 걸면 오버헤드 때문에 망설이셨다면 한번 도전해 보세요 :)

    혹시 클라우드 플레어 원본 IP를 복원해야 한다면, Traefik에 신뢰할 수 있는 프록시를 선언 하면 됩니다.

    저는 가독성 때문에 toml을 사용합니다.

    [entryPoints.websecure] address = ":443" [entryPoints.websecure.http3] advertisedPort = 443 [entryPoints.websecure.forwardedHeaders] trustedIPs = [ "173.245.48.0/20", "103.21.244.0/22", "103.22.200.0/22", "103.31.4.0/22", "141.101.64.0/18", "108.162.192.0/18", "190.93.240.0/20", "188.114.96.0/20", "197.234.240.0/22", "198.41.128.0/17", "162.158.0.0/15", "104.16.0.0/13", "104.24.0.0/14", "172.64.0.0/13", "131.0.72.0/22", "172.17.0.0/16", "172.18.0.0/16", "172.19.0.0/16", "172.20.0.0/16", "172.21.0.0/16", "172.22.0.0/16", "172.23.0.0/16", "172.24.0.0/16", "172.25.0.0/16", "172.26.0.0/16", "172.27.0.0/16", "172.28.0.0/16", "172.29.0.0/16", "172.30.0.0/16", "172.31.0.0/16" ]

    저는 80포트로 들어오면 전부 443으로 308 리다이렉트 합니다.
    따라서 제가 443 포트에 선언한 websecure에 대해서만 설정합니다.

    "172.17.0.0/16", "172.18.0.0/16", "172.19.0.0/16", "172.20.0.0/16", "172.21.0.0/16", "172.22.0.0/16", "172.23.0.0/16", "172.24.0.0/16", "172.25.0.0/16", "172.26.0.0/16", "172.27.0.0/16", "172.28.0.0/16", "172.29.0.0/16", "172.30.0.0/16", "172.31.0.0/16"

    이 부분은 도커 네트워크 대역입니다. 참고하세요.

    혹시 Traefik에 대해 관심있으시면 제 깃허브에 코드를 전부 올려두었습니다.
    확인 한번 해보실래요? github.com/navystack

    참고 문서

    Traefik forwarded-headers 문서 클라우드플레어 공식문서 - 원본 IP 복원 관련 프로젝트로 IPranges 라는 프로젝트도 진행하고 있습니다.
  • 0 토픽
    0 게시물
    새로운 게시물이 없습니다.
  • 1 토픽
    1 게시물
    navystackN

    Nodebb 성능 최적화를 위한 빠른 요약

    Nginx는 정적 파일을 직접 제공하고, 동적 요청은 Node.js 서버로 프록시

    location /socket.io/ { proxy_pass http://nodes; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; add_header pushed "wss"; } location @nodebb { proxy_pass http://nodes; } location ~ ^/assets/(.*) { root /usr/src/app/; try_files /build/public/$1 /public/$1 @nodebb; add_header pushed "assets"; add_header Cache-Control "max-age=86400"; # 1 day } location /plugins/ { root /usr/src/app/build/public; add_header pushed "plugins"; try_files $uri @nodebb; add_header Cache-Control "max-age=86400"; # 1 day } location / { proxy_pass http://nodes; add_header pushed "main"; } nginx: container_name: nginx-nodebb image: nginx:latest logging: driver: json-file options: tag: '{{.ImageName}}|{{.Name}}|{{.ImageFullID}}|{{.FullID}}' max-size: '10m' max-file: 100 restart: unless-stopped volumes: - nodebb-build:/usr/src/app/build:ro - nodebb-uploads:/usr/src/app/public/uploads:ro - nodebb-modules:/usr/src/app/node_modules:ro - ./nginx:/etc/nginx/conf.d/ networks: - internal - traefik-network depends_on: - nodebb

    default.conf

    upstream nodes { ip_hash; server nodebb-askfront:4567; keepalive 32; } server { listen 80; server_name _; set_real_ip_from 0.0.0.0/0; real_ip_header X-Forwarded-For; real_ip_recursive on; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_set_header X-Forwarded-Proto https; proxy_set_header Content-Disposition "attachment"; proxy_redirect off; proxy_http_version 1.1; proxy_hide_header X-Powered-By; proxy_hide_header X-Dns-Prefetch-Control; proxy_hide_header X-Download-Options; location /socket.io/ { proxy_pass http://nodes; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; add_header pushed "wss"; } location @nodebb { proxy_pass http://nodes; } location ~ ^/assets/(.*) { root /usr/src/app/; try_files /build/public/$1 /public/$1 @nodebb; add_header pushed "assets"; add_header Cache-Control "max-age=86400"; # 1 day } location /plugins/ { root /usr/src/app/build/public; add_header pushed "plugins"; try_files $uri @nodebb; add_header Cache-Control "max-age=86400"; # 1 day } location / { proxy_pass http://nodes; add_header pushed "main"; } }

    upstream nodes: Node.js 서버의 업스트림을 정의.
    ip_hash는 세션 퍼시스턴스를 제공하기 위해 클라이언트 IP를 기반으로 한 서버로 트래픽을 라우팅

    server: HTTP 서버 블록을 정의. 포트 80에서 리스닝하며, 모든 도메인을 허용.
    (상황에 맞게 적절하게 수정)

    proxy_set_header: 프록시로 전달되는 요청 헤더를 설정. 실제 IP 주소와 포트, 프로토콜 등을 설정.

    proxy_hide_header: 프록시 응답에서 특정 헤더를 숨김.

    proxy_redirect: 프록시 리디렉션을 비활성화.

    gzip 및 brotli: Gzip 및 Brotli 압축을 사용하여 지정된 MIME 타입의 응답을 압축합니다. (nodebb 자체가 요청 횟수가 많으므로 최대한 적정한 크기만 압축)

    location 블록들: URL 경로에 따라 요청을 처리.

    location @nodebb: @nodebb라는 이름의 location 블록으로 요청을 전달.
    프록시 패스를 사용하여 Node.js 서버로 요청을 전달.

    location ~ ^/assets/(.*): 정규 표현식을 사용하여 URL 경로가 /assets/로 시작하는 요청을 처리.
    이 경우에는 정적 파일을 제공하기 위해 지정된 디렉토리에서 파일을 찾고, 없으면 Node.js 서버로 요청을 전달.

    location /plugins/: /plugins/의 요청을 처리.
    이 경우에는 정적 파일을 제공하기 위해 지정된 디렉토리에서 파일을 찾고, 없으면 Node.js 서버로 요청을 전달.

    location /: 기본적으로 모든 요청은 Node.js 서버로 전달.