+1

Nâng cao bảo mật cho n8n: Hướng dẫn cài đặt HTTPS với Docker, Traefik và Letsencrypt

Bài viết hướng dẫn cách thiết lập chứng chỉ SSL cho n8n bằng Traefik và LetsEncrypt, giúp nâng cao tính bảo mật khi sử dụng nền tảng tự động hóa này. Việc sử dụng HTTPS không chỉ đảm bảo an toàn dữ liệu mà còn là điều kiện tiên quyết cho một số kết nối quan trọng, chẳng hạn như OAuth2 với Google Drive.

Việc thiết lập n8n trên Docker mà không có HTTPS tương đối đơn giản. Tuy nhiên, một số tính năng (ví dụ như kết nối OAuth2 với Google Drive) sẽ khó hoặc không thể thực hiện được trong n8n trừ khi nó được truy cập bằng HTTPS (SSL). Có nhiều cách để thực hiện việc này, bao gồm cấu hình n8n với chứng chỉ máy chủ chuyên dụng, nhưng chạy Traefik như một reverse proxy, trước n8n, cung cấp tích hợp tự động với LetsEncrypt để lấy và gia hạn chứng chỉ máy chủ "được tin cậy theo mặc định", và chỉ cần để n8n chạy mà không cần HTTPS.

Điều kiện tiên quyết trước khi thực hiện

  • n8n đang chạy trong Docker, tốt nhất là bắt đầu bằng docker-compose
  • Quyền truy cập để khởi động vùng chứa Traefik trong Docker
  • Tên miền đã đăng ký (cấp cao nhất) với quyền truy cập vào cấu hình DNS.

Mục tiêu sau khi thực hiện

Thiết lập Traefik, trong Docker, sao cho nó xử lý các yêu cầu cho một tên miền phụ, như myn8n.example.com và chuyển tiếp (reverse-proxy) lưu lượng truy cập đó đến n8n, cũng chạy trong Docker.

Các bước triển khai chính

1. Đăng ký/kích hoạt quyền truy cập API vào nhà đăng ký tên miền

  • Cách thực hiện việc này khác nhau tùy thuộc vào nhà đăng ký nào được sử dụng.
  • Danh sách các nhà đăng ký được hỗ trợ và liên kết đến các hướng dẫn cụ thể có thể được tìm thấy ở đây

2. Khởi động Traefik trong một vùng chứa

  • Điều này được ghi lại tại đây.
  • Một phần của thiết lập ví dụ này cấu hình Traefik để tự động tìm nạp chứng chỉ máy chủ, cho HTTPS, từ LetsEncrypt
  • Lưu ý: Docker compose ví dụ hiển thị các biến môi trường cho nhà cung cấp DNS/nhà đăng ký có tên ovh. Phần này sẽ khác nhau với mỗi nhà cung cấp đăng ký khác nhau. Thông tin chi tiết về plugin Traefik cho mỗi nhà đăng ký (chẳng hạn như biến ENV nào được yêu cầu) có thể được tìm thấy cùng với các hướng dẫn truy cập API từ bước trước đó.
  • Trừ khi bạn đang thực sự sử dụng ovh làm nhà đăng ký của mình, hãy thay đổi điều này: - "--certificatesresolvers.myresolver.acme.dnschallenge.provider=ovh" từ ovh thành tên khớp với nhà đăng ký thực tế của bạn, ví dụ: ionos, godaddy, namecheap, v.v.
  • Các biến môi trường cũng sẽ khác nhau. Ví dụ: nếu bạn đang sử dụng GoDaddy, bạn sẽ bao gồm các biến môi trường GODADDY_API_KEY và GODADDY_API_SECRET thay vì tất cả các biến bắt đầu bằng OVH_

3. Định cấu hình DNS để tên miền/tên miền phụ ánh xạ tới máy chủ Traefik (từ góc độ của trình duyệt web)

  • Nếu điều này không thể được thực hiện trong DNS công khai, nó sẽ vẫn hoạt động với các mục nhập máy chủ trong tệp /etc/hosts trên một máy, tính năng tên máy chủ/DNS trên bộ định tuyến hoặc DNS "mạng nội bộ" như pihole.
  • Lưu ý rằng có lẽ không nên định cấu hình DNS công khai tại nhà đăng ký của bạn để phân giải địa chỉ IP máy chủ Traefik chỉ nội bộ (tức là riêng tư/LAN). Ngoài ra, việc bảo mật Traefik để truy cập công khai nằm ngoài phạm vi của bài viết này.

4. Thêm cấu hình (nhãn) vào vùng chứa n8n để yêu cầu Traefik xử lý quyền truy cập HTTPS

  • Dịch vụ whoami ví dụ được hiển thị trong tài liệu Traefik là ổn để kiểm tra xem reverse proxy có hoạt động hay không, nhưng nó không làm rõ chính xác tầm quan trọng của phần "nhãn".
  • Trong vùng chứa n8n, sẽ có các nhãn tương ứng như sau:
labels:
      - "traefik.enable=true"
      - "traefik.http.routers.n8n.rule=Host(`n8n.example.com`)"
      - "traefik.http.routers.n8n.entrypoints=websecure"
      - "traefik.http.routers.n8n.tls.certresolver=myresolver"

Thông tin cơ bản và cách thức hoạt động

1. Ghi chú bổ sung về Docker Networks

Khi tôi thiết lập n8n và Postgres trong Docker, tôi đã đặt cả hai vùng chứa vào mạng docker riêng của chúng để cách ly với những thứ khác đang chạy trong docker, vì vậy có một mạng được xác định trong docker-compose.yaml của n8n như:

networks:
    n8nstack:

Và mỗi vùng chứa "đã tham gia" mạng như:

services:
      n8n:
        # ...
        networks:
          - "n8nstack"
      postgres:
        # ...
        networks:
          - "n8nstack"

Traefik đang chạy trên mạng docker mặc định, không phải mạng n8nstack, vì vậy reverse-proxy không hoạt động. Để khắc phục điều này, Traefik đã được cấu hình tương tự với mạng docker (bên ngoài) của riêng nó, được tạo bởi lệnh docker như...

docker network create traefikproxy

và trong docker-compose.yaml của Traefik...

networks:
    traefikproxy:
      external: true

với mỗi vùng chứa tham chiếu đến mạng như:

 services:
    traefik:
      # ...
      networks:
        - "traefikproxy"
    whoami:
      # ...
      networks:
        - "traefikproxy"

Rõ ràng là, docker-compose của n8n sẽ cần được cập nhật để dịch vụ n8n CŨNG tham gia mạng traefikproxy với:

 networks:
    n8nstack:
    traefikproxy:
      external: true

và dịch vụ n8n (không phải dịch vụ khác) CŨNG tham gia mạng traefik với:

services:
      n8n:
        # ...
        networks:
          - "n8nstack"
          - "traefikproxy"

Phần không rõ ràng là các nhãn liên quan đến Traefik trong vùng chứa/dịch vụ n8n giờ đây sẽ cần thêm một nhãn để cho Traefik biết sử dụng mạng docker nào, như

labels:
  - "traefik.enable=true"
  - "traefik.docker.network=traefikproxy"
  # ...

Lưu ý: Tôi nghĩ rằng điều này cũng có thể đã bị đảo ngược sao cho dịch vụ traefik tham gia mạng n8nstack và mạng của bất kỳ ngăn xếp nào khác, nhưng đối với tôi, có vẻ tốt hơn (được đóng gói nhiều hơn) để đi theo hướng khác.

Trường hợp nào nên sử dụng các hướng dẫn bảo mật trong bài viết này?

Lý do tôi có động lực thiết lập n8n phía sau reverse proxy, với HTTPS/SSL được bật, là dường như không có cách nào khác để vượt qua chuỗi OAuth2 để truy cập Google API, điều này được yêu cầu cho nút Google Drive.

Google muốn có URL chuyển hướng trên thông tin đăng nhập OAuth2 ánh xạ tới tên miền công khai, thực và sử dụng HTTPS. Có thể có nhiều cách để định cấu hình n8n sao cho nó tạo ra URL chuyển hướng HTTPS (có thể sử dụng WEBHOOK_URL) nhưng nếu không thực sự tải giao diện người dùng n8n bằng điểm cuối HTTPS, thì có vẻ như một phần nào đó của toàn bộ chuỗi OAuth2 sẽ luôn bỏ qua theo dõi và không hoạt động bình thường.

Việc thiết lập Traefik để giải quyết các rắc rối về chứng chỉ SSL cuối cùng là lựa chọn tốt nhất.

Tổng quan nhanh về Traefik

Traefik (chủ yếu) là dịch vụ reverse proxy chấp nhận và định tuyến lưu lượng truy cập web (từ trình duyệt và các máy khách HTTP(S) khác) đến một hoặc nhiều "dịch vụ phụ trợ". Trong ngữ cảnh này, n8n là một "dịch vụ phụ trợ".

Lưu ý: Nếu khái niệm về reverse proxy không quen thuộc, thì việc đọc thêm về điều đó có thể sẽ hữu ích.

Traefik + LetsEncrypt - Tự động hóa chứng chỉ

Đây là tổng quan đơn giản về cách thức hoạt động của nó:

  • Traefik được định cấu hình bằng khóa API cho nhà đăng ký kiểm soát DNS cho miền cấp cao nhất và các miền phụ của nó.
  • Traefik được định cấu hình để chấp nhận các yêu cầu HTTPS/443 trên miền, một hoặc nhiều miền phụ của nó hoặc cả hai.
  • Khi được yêu cầu (tức là khi chứng chỉ máy chủ SSL cho một tên máy chủ nhất định bị thiếu hoặc hết hạn), Traefik sẽ tự động gửi yêu cầu đến LetsEncrypt để tìm nạp chứng chỉ máy chủ.
  • LetsEncrypt phản hồi Traefik bằng "Thử thách DNS", về cơ bản là yêu cầu tạo bản ghi DNS tùy ý, tạm thời, để chứng minh "quyền sở hữu" đối với miền.
  • Traefik sử dụng khóa API của nhà đăng ký (và plugin "nhà cung cấp" tương ứng) để thực hiện thay đổi DNS, sau đó gửi lại thông báo cho LetsEncrypt với nội dung "Hãy kiểm tra lại DNS ngay bây giờ".
  • LetsEncrypt kiểm tra DNS và, giả sử tìm thấy mục nhập/bản ghi "thử thách", trả về chứng chỉ máy chủ cho miền/miền phụ được yêu cầu.
  • Traefik lưu trữ chứng chỉ (để sử dụng trên máy chủ proxy) và dọn dẹp các bản ghi DNS tạm thời (một lần nữa bằng cách sử dụng các hàm API của nhà đăng ký).

Một số chi tiết liên quan đến n8n

1. N8N_EDITOR_BASE_URL

Khi n8n được truy cập thông qua reverse-proxy như Traefik (hoặc bộ cân bằng tải Kubernetes hoặc quy tắc trên máy chủ web nginx chuyên dụng hoặc bất kỳ số lượng thứ nào khác như vậy), thì có một biến môi trường (hoặc cấu hình n8n) có tên N8N_EDITOR_BASE_URL để cho n8n biết, nội bộ, những gì cần sử dụng (trong giao diện người dùng và ở những nơi khác) làm URL cơ sở "bên ngoài" (ngữ cảnh trình duyệt). Có thể cần thiết lập điều này trong cấu hình n8n khi sử dụng Traefik.

Hiện tại, (khoảng n8n v1.59.0), hộp thoại thông tin đăng nhập cho thông tin đăng nhập liên quan đến Google API và do đó, URL chuyển hướng được gửi đến Google cho OAuth2, dường như tạo thành URL chuyển hướng dựa trên một trong hai cách:

  • Giao diện người dùng tự tải vào trình duyệt.
  • Hoặc là N8N_EDITOR_BASE_URL, nếu nó được chỉ định trong môi trường hoặc cấu hình.

2. WEBHOOK_URL

Một ghi đè khác có thể cần thiết khi n8n được bảo vệ phía sau Traefik là cấu hình/biến môi trường WEBHOOK_URL.

  • Điều này được sử dụng cho... không ngạc nhiên lắm... những thứ liên quan đến webhook như $execution.resumeUrl
  • Dường như WEBHOOK_URL không ảnh hưởng đến URL chuyển hướng OAuth2, mặc dù tôi nghĩ rằng điều đó có thể đã được đề xuất ở một vài nơi. Có lẽ WEBHOOK_URL cũng phục vụ mục đích của N8N_EDITOR_BASE_URL trong phiên bản n8n trước đó.

All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí