Sunday, January 19, 2025

Middleware ipwhitelist trong Traefik

-

1. Giới thiệu.

Middleware ipwhitelist trong Traefik là một công cụ được sử dụng để áp dụng chính sách kiểm tra danh sách trắng (whitelist) địa chỉ IP đến các yêu cầu truy cập vào các dịch vụ web. Cụ thể, middleware này cho phép bạn kiểm soát quyền truy cập dựa trên địa chỉ IP, chỉ cho phép những địa chỉ IP được cấu hình trong danh sách trắng truy cập vào dịch vụ.

Khi middleware ipwhitelist được kích hoạt cho một router trong Traefik, nó sẽ kiểm tra địa chỉ IP của người dùng trước khi chuyển tiếp yêu cầu tới dịch vụ. Nếu địa chỉ IP nằm trong danh sách trắng, yêu cầu sẽ được chấp nhận và tiếp tục chuyển tiếp đến dịch vụ. Ngược lại, nếu địa chỉ IP không nằm trong danh sách trắng, yêu cầu sẽ bị từ chối.

Cấu hình cơ bản của middleware ipwhitelist trong Traefik thường bao gồm:

  • traefik.http.middlewares.<middleware_name>.ipwhitelist.sourcerange: Địa chỉ IP hoặc phạm vi địa chỉ IP được phép truy cập. Bạn có thể chỉ định một hoặc nhiều địa chỉ IP, hoặc một phạm vi địa chỉ IP dưới dạng CIDR.

Ví dụ:

traefik.http.middlewares.allowip.ipwhitelist.sourcerange=192.168.1.1/32,10.0.0.0/8

Trong ví dụ này, middleware allowip cho phép truy cập từ địa chỉ IP 192.168.1.1 và bất kỳ địa chỉ nằm trong phạm vi CIDR 10.0.0.0/8.

Middleware ipwhitelist là một cách hữu ích để thêm một lớp bảo mật bổ sung vào các dịch vụ của bạn, giúp kiểm soát và giới hạn quyền truy cập từ các địa chỉ IP cụ thể.

2. Thực hành.

Sử dụng Traefik để thực hiện các yêu cầu sau:

  • Cho phép IP 192.168.12.48 đi tất cả các URL.
  • Cho phép IP 192.168.12.45 đi trang http://hoanghd.com/admin nhưng chặn các trang còn lại.

Bước 1 – Đầu tiên tạo file nginx.conf ở thư mục hiện tại với nội dung như dưới.

cat > nginx.conf << 'OEF'
server {
    listen       9090;
    server_name  _;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
        proxy_set_header X-Real-Ip $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    location /admin/ {
        alias /usr/share/nginx/html/admin/;
        index  index.html index.htm;
        proxy_set_header X-Real-Ip $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}
OEF

File cấu hình trên là một file cấu hình cho máy chủ web Nginx. Nginx là một máy chủ web và proxy ngược (reverse proxy) phổ biến được sử dụng để phục vụ các trang web và ứng dụng web. Dưới đây là một phân tích của nội dung trong file cấu hình:

  • server: Đây là khối cấu hình cho một máy chủ web Nginx. Các yếu tố bên trong này định cấu hình cho máy chủ cụ thể.
    • listen: Xác định cổng mà máy chủ Nginx sẽ lắng nghe các kết nối. Trong trường hợp này, máy chủ sẽ lắng nghe trên cổng 9090.
    • server_name: Định nghĩa tên miền mà máy chủ sẽ phục vụ. Dấu gạch dưới (_) ở đây có nghĩa là máy chủ sẽ phục vụ tất cả các tên miền.
  • location /: Đây là khối cấu hình cho vị trí (location) chính trên máy chủ. Điều này xảy ra khi URL không khớp với bất kỳ vị trí cụ thể nào. Trong trường hợp này:
    • root: Chỉ định thư mục gốc cho các file tài nguyên tĩnh (như HTML, CSS, JS) được phục vụ bởi máy chủ.
    • index: Xác định tên các file mặc định sẽ được tìm kiếm khi truy cập đường dẫn gốc (“/”).
    • proxy_set_header: Đặt các header của proxy để chuyển các thông tin về client và proxy tới máy chủ back-end.
  • location /admin/: Đây là khối cấu hình cho vị trí /admin/ trên máy chủ. Điều này xảy ra khi URL khớp với đường dẫn /admin/.
    • alias: Cho phép bạn đặt một thư mục ảo để phục vụ các tài nguyên tĩnh từ đường dẫn được chỉ định.
  • error_page: Xác định trang lỗi tùy chỉnh cho các mã lỗi 500, 502, 503, và 504.
    • location = /50x.html: Xác định đường dẫn đến trang lỗi cụ thể cho các mã lỗi 500, 502, 503, và 504.

Những điều này giúp cấu hình Nginx để phục vụ các file tĩnh và chuyển hướng các yêu cầu đến các vị trí tương ứng. Header proxy cũng được đặt để truyền thông tin về client và proxy khi chuyển tiếp yêu cầu.

Bước 2 – Tạo file nội dung Website.

  • Nội dung cho trang chủ.
cat > home-website.html << 'OEF'
<!DOCTYPE html>
<html>
<meta charset="UTF-8">
<head>
    <title>Chào mừng đến với website của tôi</title>
</head>
<body>
    <h1>Đây là trang chủ của webtite.</h1>
</body>
</html>
OEF
  • Nội dung cho trang quản trị.
cat > admin-website.html << 'OEF'
<!DOCTYPE html>
<html>
<meta charset="UTF-8">
<head>
    <title>Trang dành cho Admin</title>
</head>
<body>
    <h1>Trang này dành riêng cho người quản trị.</h1>
</body>
</html>
OEF

Bước 3 – Tạo file docker-compose.yml với nộ dung dưới.

cat > docker-compose.yml << 'OEF'
version: "3.8"

services:
  nginx:
    image: nginx:latest
    labels:
      - "traefik.enable=true"

      # Router for "hoanghd.com"
      - "traefik.http.routers.lab.rule=Host(`hoanghd.com`)"
      - "traefik.http.routers.lab.entrypoints=web"
      - "traefik.http.services.lab.loadbalancer.server.port=9090"
      - "traefik.http.routers.lab.middlewares=allowip_lab@docker"

      # Router for "hoanghd.com/admin"
      - "traefik.http.routers.admin.entrypoints=web"
      - "traefik.http.routers.admin.rule=(Host(`hoanghd.com`) && PathPrefix(`/admin/`))"
      - "traefik.http.routers.admin.middlewares=admin@docker"

      # Middleware for IP Whitelisting
      - "traefik.http.middlewares.allowip_lab.ipwhitelist.sourcerange=192.168.12.48/32"
      - "traefik.http.middlewares.admin.ipwhitelist.sourcerange=192.168.12.45/32,192.168.12.48"

    networks:
      - reverse-proxy
    volumes:
      - ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
      - ./home-website.html:/usr/share/nginx/html/index.html:ro
      - ./admin-website.html:/usr/share/nginx/html/admin/index.html:ro

  traefik:
    image: traefik
    command:
      - --log.level=DEBUG
      - --api.insecure=true
      - --providers.docker=true
      - --providers.docker.exposedbydefault=false
      - --providers.docker.network=reverse-proxy
      - --entrypoints.web.address=:80
      - --entrypoints.web.forwardedHeaders.insecure=true
    ports:
      - 80:80
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
    networks:
      - reverse-proxy

networks:
  reverse-proxy:
    external: true
OEF

Đoạn config trên là một file cấu hình cho Docker Compose để triển khai một môi trường sử dụng Traefik làm reverse proxy để quản lý việc định tuyến và bảo mật truy cập cho các dịch vụ nginx khác nhau. Dưới đây là một phân tích chi tiết về từng phần của file cấu hình:

  • Version: Đây là phiên bản của Docker Compose mà file cấu hình này tuân theo, trong trường hợp này là phiên bản 3.8.
  • Services: Phần này định nghĩa các dịch vụ mà bạn muốn triển khai bằng Docker Compose.
    • nginx: Định nghĩa dịch vụ nginx sử dụng hình ảnh “nginx:latest”. Các nhãn (labels) dưới đây được sử dụng để cấu hình Traefik để quản lý dịch vụ này:
      • traefik.enable=true: Bật Traefik cho dịch vụ này.
      • traefik.http.routers.lab.rule: Định nghĩa một quy tắc định tuyến dựa trên tên miền “hoanghd.com”.
      • traefik.http.routers.lab.entrypoints: Sử dụng entrypoint “web”.
      • traefik.http.services.lab.loadbalancer.server.port: Chỉ định cổng 9090 của dịch vụ để định tuyến yêu cầu tới.
      • traefik.http.routers.lab.middlewares: Sử dụng middleware “allowip_lab@docker”.
      • traefik.http.routers.admin: Định nghĩa một router khác cho đường dẫn “/admin” trên tên miền “hoanghd.com”.
      • traefik.http.routers.admin.entrypoints: Sử dụng entrypoint “web”.
      • traefik.http.routers.admin.rule: Quy tắc định tuyến cho đường dẫn “/admin”.
      • traefik.http.routers.admin.middlewares: Sử dụng middleware “admin@docker”.
      • traefik.http.middlewares.allowip_lab.ipwhitelist.sourcerange: Xác định danh sách các địa chỉ IP được phép truy cập dịch vụ “hoanghd.com” thông qua middleware “allowip_lab”.
      • traefik.http.middlewares.admin.ipwhitelist.sourcerange: Xác định danh sách các địa chỉ IP được phép truy cập dịch vụ “hoanghd.com/admin” thông qua middleware “admin”.
    • traefik: Định nghĩa dịch vụ Traefik để làm reverse proxy.
      • Các cờ --log.level, --api.insecure, --providers.docker--providers.docker.exposedbydefault được sử dụng để cấu hình Traefik.
      • --entrypoints.web.address xác định cổng của entrypoint “web”.
      • --entrypoints.web.forwardedHeaders.insecure=true cho phép chuyển tiếp các header từ proxy không an toàn.
  • Ports: Định nghĩa cổng mà dịch vụ Traefik lắng nghe (cổng 80).
  • Volumes: Đối với dịch vụ Traefik, liên kết đến socket Docker để Traefik có thể theo dõi các dịch vụ Docker đang chạy. Đối với dịch vụ nginx, volumes được sử dụng để liên kết các file cấu hình và tài nguyên tĩnh vào dịch vụ.
  • Networks: Định nghĩa mạng có tên “reverse-proxy” được sử dụng cho các dịch vụ. Mạng này được định nghĩa bên ngoài (external) để cho phép Traefik quản lý việc định tuyến cho các dịch vụ trong mạng này.

Chú ý:

Trong Traefik, PathPrefixPath là hai quy tắc định tuyến khác nhau, chúng được sử dụng để xác định cách mà các yêu cầu HTTP sẽ được định tuyến tới các dịch vụ.

  • PathPrefix:
    • PathPrefix được sử dụng để định tuyến các yêu cầu dựa trên một tiền tố đường dẫn cụ thể.
    • Khi bạn sử dụng PathPrefix, Traefik sẽ định tuyến các yêu cầu có đường dẫn bắt đầu bằng tiền tố xác định tới dịch vụ tương ứng.
    • Ví dụ: PathPrefix("/admin/") sẽ định tuyến các yêu cầu có đường dẫn bắt đầu bằng “/admin/” tới dịch vụ tương ứng.
  • Path:
    • Path được sử dụng để định tuyến các yêu cầu dựa trên một đường dẫn cụ thể.
    • Khi bạn sử dụng Path, Traefik sẽ định tuyến các yêu cầu có đường dẫn chính xác trùng khớp với đường dẫn xác định tới dịch vụ tương ứng.
    • Ví dụ: Path("/admin") sẽ định tuyến các yêu cầu có đường dẫn là “/admin” (không bao gồm tiền tố / sau “/admin”) tới dịch vụ tương ứng.

Về ví dụ cụ thể mà bạn đưa ra:

  • PathPrefix("/admin/"): Định tuyến các yêu cầu có đường dẫn bắt đầu bằng “/admin/” tới dịch vụ được cấu hình.
  • Path("/admin"): Định tuyến chỉ yêu cầu có đường dẫn là “/admin” (không bao gồm tiền tố / sau “/admin”) tới dịch vụ được cấu hình.

Ví dụ cụ thể về URL tương ứng với mỗi quy tắc:

  • http://hoanghd.com/admin/abc: Sẽ phù hợp với PathPrefix("/admin/").
  • http://hoanghd.com/admin: Sẽ phù hợp với cả hai PathPrefix("/admin/")Path("/admin").

Lưu ý rằng việc sử dụng Path hoặc PathPrefix phụ thuộc vào cách bạn muốn định tuyến yêu cầu dựa trên đường dẫn.

Bước 4 – Triển khai file docker-compose.yml vừa tạo xong.

docker-compose down && docker-compose up -d && docker logs -f root-traefik-1

Bước 5 – Kiểm tra kết quả.

Đối với client sử dụng IP 192.168.12.45 sẽ bị chặn tất cả và chỉ cho phép vào trang quản trị admin.

Đối với client sử dụng IP 192.168.12.48 sẽ cho phép đi tất cả.

LEAVE A REPLY

Please enter your comment!
Please enter your name here

4,956FansLike
256FollowersFollow
223SubscribersSubscribe
spot_img

Related Stories