Thiết Lập Tường Lửa Iptables Để Bảo Vệ Lưu Lượng Giữa Các Máy Chủ của Bạn

iptables firewall 2

Việc triển khai các thành phần rời rạc trong kiến trúc ứng dụng trên các nút (node) khác nhau là cách phổ biến để giảm tải và bắt đầu mở rộng theo chiều ngang. Một ví dụ điển hình là cấu hình cơ sở dữ liệu trên một máy chủ riêng biệt so với máy chủ ứng dụng. Mặc dù có nhiều ưu điểm với thiết lập này, việc kết nối qua mạng cũng mang đến một tập hợp các mối quan tâm về bảo mật mới.

Trong hướng dẫn này, chúng ta sẽ trình bày cách thiết lập tường lửa trên từng máy chủ trong một kiến trúc phân tán. Chúng ta sẽ cấu hình chính sách để cho phép lưu lượng được định hướng giữa các thành phần của ứng dụng, đồng thời từ chối các lưu lượng khác.

Bạn cũng có thể cấu hình DataOnline Cloud Firewalls (tường lửa DataOnline ” Cloud Firewalls”) chạy như một lớp bảo vệ bên ngoài bổ sung cho các máy chủ trên hạ tầng DataOnline. Theo cách này, bạn không cần phải cấu hình tường lửa trên chính các máy chủ.

Trong hướng dẫn này, chúng ta sẽ sử dụng ví dụ với hai máy chủ Ubuntu 22.04. Một máy chủ sẽ chạy ứng dụng web với Nginx và máy chủ kia sẽ là nơi lưu trữ cơ sở dữ liệu MySQL cho ứng dụng. Mặc dù ví dụ này được sử dụng để minh họa, bạn có thể áp dụng các kỹ thuật này cho yêu cầu máy chủ riêng của mình.

Yêu Cầu

Để bắt đầu, bạn cần có hai máy chủ Ubuntu 22.04 mới. Hãy tạo một tài khoản người dùng thường có quyền sudo trên mỗi máy. Để thực hiện, hãy tham khảo hướng dẫn Thiết Lập Máy Chủ Ban Đầu Với Ubuntu 22.04.

Hướng dẫn cấu hình ứng dụng mà chúng ta sẽ bảo mật được dựa trên bài hướng dẫn này. Nếu bạn muốn theo sát ví dụ, hãy cấu hình máy chủ ứng dụng và cơ sở dữ liệu theo chỉ dẫn trong bài hướng dẫn đó. Nếu không, bạn có thể sử dụng bài viết này như một tài liệu tham khảo chung.

Bước 1 — Thiết Lập Tường Lửa

Bạn sẽ bắt đầu bằng cách triển khai một cấu hình tường lửa cơ bản cho từng máy chủ của bạn. Chính sách mà chúng ta sẽ triển khai theo hướng an toàn hàng đầu: chúng ta sẽ khóa hầu hết lưu lượng trừ lưu lượng SSH, và sau đó mở ra các lỗ (hole) cho ứng dụng cụ thể của bạn.

Hướng dẫn này sử dụng cú pháp của iptables. Iptables được cài đặt tự động trên Ubuntu 22.04 sử dụng backend nftables, vì vậy bạn không cần phải cài đặt thêm gói nào.

Mở File Cấu Hình

Sử dụng nano hoặc trình soạn thảo ưa thích, mở file cấu hình iptables tại /etc/iptables/rules.v4:

sudo nano /etc/iptables/rules.v4

Dán cấu hình từ hướng dẫn mẫu tường lửa (firewall template guide):

/etc/iptables/rules.v4

*filter
# Allow all outgoing, but drop incoming and forwarding packets by default
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]

# Custom per-protocol chains
:UDP - [0:0]
:TCP - [0:0]
:ICMP - [0:0]

# Acceptable UDP traffic

# Acceptable TCP traffic
-A TCP -p tcp --dport 22 -j ACCEPT

# Acceptable ICMP traffic

# Boilerplate acceptance policy
-A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
-A INPUT -i lo -j ACCEPT

# Drop invalid packets
-A INPUT -m conntrack --ctstate INVALID -j DROP

# Pass traffic to protocol-specific chains
## Only allow new connections (established and related should already be handled)
## For TCP, additionally only allow new SYN packets since that is the only valid
## method for establishing a new TCP connection
-A INPUT -p udp -m conntrack --ctstate NEW -j UDP
-A INPUT -p tcp --syn -m conntrack --ctstate NEW -j TCP
-A INPUT -p icmp -m conntrack --ctstate NEW -j ICMP

# Reject anything that's fallen through to this point
## Try to be protocol-specific w/ rejection message
-A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable
-A INPUT -p tcp -j REJECT --reject-with tcp-reset
-A INPUT -j REJECT --reject-with icmp-proto-unreachable

# Commit the changes
COMMIT

*raw
:PREROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
COMMIT

*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
COMMIT

*security
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
COMMIT

*mangle
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
COMMIT

Lưu và đóng file. (Với nano: nhấn Ctrl+X, sau đó nhấn Y và Enter).

Lưu ý: Nếu bạn đang thực hiện trong môi trường trực tiếp, đừng reload các quy tắc tường lửa ngay vì việc tải tập quy tắc này sẽ ngay lập tức cắt đứt kết nối giữa máy chủ ứng dụng và máy chủ cơ sở dữ liệu. Bạn cần điều chỉnh quy tắc phù hợp với nhu cầu hoạt động của mình trước khi reload.

Bước 2 — Tìm Hiểu Các Cổng Đang Được Sử Dụng Bởi Các Dịch Vụ

Để cho phép giao tiếp giữa các thành phần, bạn cần biết các cổng mạng đang được sử dụng. Bạn có thể xem các cổng đúng bằng cách kiểm tra dịch vụ đang lắng nghe kết nối trên từng máy.

Sử dụng công cụ netstat để xác định dịch vụ đang chạy. Vì ứng dụng của bạn chỉ giao tiếp qua IPv4, ta thêm tham số -4 (bạn có thể bỏ nếu dùng IPv6). Các tham số cần thiết là -p, -l, -u, -n, -t, được kết hợp thành -plunt.

Giải thích các tham số:

  • p: Hiển thị PID và tên chương trình sở hữu mỗi socket.
  • l: Chỉ hiển thị các socket đang lắng nghe.
  • u: Hiển thị lưu lượng UDP.
  • n: Hiển thị kết quả dưới dạng số thay vì tên dịch vụ.
  • t: Hiển thị lưu lượng TCP.

Chạy lệnh:

sudo netstat -4plunt

Trên máy chủ web, output có thể trông như sau:

Output

Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1058/sshd
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      4187/nginx

Cột đầu tiên cho biết địa chỉ IP và cổng mà dịch vụ đang lắng nghe. Địa chỉ đặc biệt 0.0.0.0 có nghĩa là dịch vụ đang lắng nghe trên tất cả các địa chỉ có sẵn.

Trên máy chủ cơ sở dữ liệu, output có thể như sau:

sudo netstat -4plunt

Output

Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1097/sshd
tcp        0      0 192.0.2.30:3306     0.0.0.0:*               LISTEN      3112/mysqld

Trong ví dụ này, địa chỉ 192.0.2.30 đại diện cho địa chỉ IP riêng của máy chủ cơ sở dữ liệu. Theo hướng dẫn cài đặt ban đầu, MySQL được giới hạn chỉ trên giao diện riêng vì lý do bảo mật.

Ghi nhớ các giá trị tìm được, vì chúng sẽ cần thiết để điều chỉnh cấu hình tường lửa.

Trên máy chủ web, bạn cần đảm bảo các cổng sau được mở:

  • Cổng 80 trên tất cả địa chỉ.
  • Cổng 22 trên tất cả địa chỉ (đã được cấu hình trong quy tắc tường lửa).

Máy chủ cơ sở dữ liệu cần đảm bảo:

  • Cổng 3306 trên địa chỉ 192.0.2.30 (hoặc giao diện tương ứng).
  • Cổng 22 trên tất cả địa chỉ (đã được cấu hình trong quy tắc tường lửa).

Bước 3 — Điều Chỉnh Các Quy Tắc Tường Lửa Trên Máy Chủ Web

Sau khi có thông tin cổng cần thiết, bạn sẽ điều chỉnh tập quy tắc tường lửa trên máy chủ web. Mở file cấu hình:

sudo nano /etc/iptables/rules.v4

Trên máy chủ web, bạn cần thêm cổng 80 vào danh sách lưu lượng được chấp nhận. Vì máy chủ đang lắng nghe trên tất cả các địa chỉ (web server thường mong đợi có thể truy cập từ bất cứ đâu), bạn không cần giới hạn theo giao diện hay địa chỉ đích.

Do lưu lượng truy cập web sử dụng giao thức TCP và đã có một chain tùy chỉnh tên là TCP cho ngoại lệ ứng dụng TCP, bạn chỉ cần thêm quy tắc cho cổng 80 ngay dưới ngoại lệ của cổng SSH. Ví dụ, trong file
/etc/iptables/rules.v4

*filter
. . .

# Acceptable TCP traffic
-A TCP -p tcp --dport 22 -j ACCEPT
-A TCP -p tcp --dport 80 -j ACCEPT

. . .

Máy chủ web sẽ khởi tạo kết nối với máy chủ cơ sở dữ liệu. Lưu lượng đi của bạn không bị hạn chế trong tường lửa, và lưu lượng đến liên quan đến các kết nối đã thiết lập được phép, vì vậy bạn không cần mở thêm cổng nào khác trên máy chủ này để cho phép kết nối.

Lưu và đóng file. Máy chủ web của bạn bây giờ có một chính sách tường lửa cho phép lưu lượng hợp lệ trong khi chặn tất cả các lưu lượng khác.

Kiểm tra file quy tắc để phát hiện lỗi cú pháp:

sudo iptables-restore -t < /etc/iptables/rules.v4

Nếu không có lỗi cú pháp nào được hiển thị, reload tường lửa để áp dụng tập quy tắc mới:

sudo service iptables-persistent reload

Bước 4 — Điều Chỉnh Các Quy Tắc Tường Lửa Trên Máy Chủ Cơ Sở Dữ Liệu

Trên máy chủ cơ sở dữ liệu, bạn cần cho phép truy cập vào cổng 3306 trên địa chỉ IP riêng của máy chủ (ví dụ: 192.0.2.30). Bạn có thể hạn chế truy cập dựa trên địa chỉ này hoặc dựa trên giao diện chứa địa chỉ đó.

Để tìm giao diện mạng chứa địa chỉ đó, chạy:

ip -4 addr show scope global

Output

2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    inet 203.0.113.5/24 brd 104.236.113.255 scope global eth0
       valid_lft forever preferred_lft forever
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    inet 192.0.2.30/24 brd 192.0.2.255 scope global eth1
       valid_lft forever preferred_lft forever

Phần được đánh dấu cho thấy giao diện eth1 gắn với địa chỉ 192.0.2.30.

Tiếp theo, điều chỉnh quy tắc tường lửa trên máy chủ cơ sở dữ liệu. Mở file cấu hình:

sudo nano /etc/iptables/rules.v4

Thêm quy tắc vào chain TCP để tạo ngoại lệ cho kết nối giữa máy chủ web và máy chủ cơ sở dữ liệu.

Nếu bạn muốn hạn chế theo địa chỉ cụ thể, thêm quy tắc như sau:

*filter
. . .

# Acceptable TCP traffic
-A TCP -p tcp --dport 22 -j ACCEPT
-A TCP -p tcp --dport 3306 -d 192.0.2.30 -j ACCEPT

. . .

Nếu bạn muốn hạn chế dựa trên giao diện chứa địa chỉ đó, thêm quy tắc thay thế:

*filter
. . .

# Acceptable TCP traffic
-A TCP -p tcp --dport 22 -j ACCEPT
-A TCP -p tcp --dport 3306 -i eth1 -j ACCEPT

. . .

Lưu và đóng file.

Kiểm tra lỗi cú pháp:

sudo iptables-restore -t < /etc/iptables/rules.v4

Khi sẵn sàng, reload quy tắc tường lửa:

sudo service iptables-persistent reload

Bây giờ, cả hai máy chủ của bạn đều được bảo vệ mà không làm cản trở luồng dữ liệu cần thiết giữa chúng.

Kết Luận

Việc triển khai một tường lửa phù hợp luôn nên là một phần trong kế hoạch triển khai khi thiết lập một ứng dụng. Mặc dù chúng tôi đã trình bày cấu hình này bằng cách sử dụng hai máy chủ chạy Nginx và MySQL, nhưng các kỹ thuật được trình bày ở trên có thể áp dụng bất kể lựa chọn công nghệ cụ thể của bạn.

Để tìm hiểu thêm về tường lửa và iptables, hãy xem các hướng dẫn sau:

Để lại một bình luận

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *