Thứ ba, 06/05/2014 | 00:00 GMT+7

Cách thiết lập firewall bằng Iptables trên Ubuntu 14.04

Cài đặt một firewall tốt là một bước cần thiết để bảo mật bất kỳ hệ điều hành hiện đại nào. Hầu hết các bản phân phối Linux đều có một vài công cụ firewall khác nhau mà ta có thể sử dụng để cấu hình firewall của bạn . Trong hướng dẫn này, ta sẽ trình bày về firewall iptables.

Iptables là một firewall tiêu chuẩn có trong hầu hết các bản phân phối Linux theo mặc định (một biến thể hiện đại được gọi là nftables là mộtversion tiếp theo ). Nó thực sự là một giao diện user cho các netfilter hooks cấp kernel có thể thao tác với mạng Linux. Nó hoạt động bằng cách khớp từng gói đi qua network interface với một bộ luật để quyết định việc cần làm.

Trong hướng dẫn trước, ta đã tìm hiểu cách hoạt động của các luật iptables để chặn lưu lượng truy cập không mong muốn . Trong hướng dẫn này, ta sẽ chuyển sang một ví dụ thực tế để trình bày cách tạo bộ luật cơ bản cho server Ubuntu 14.04. Tường lửa kết quả sẽ cho phép lưu lượng SSH và HTTP.

Lưu ý: Hướng dẫn này bao gồm bảo mật IPv4. Trong Linux, bảo mật IPv6 được duy trì riêng biệt với IPv4. Ví dụ: “iptables” chỉ duy trì các luật firewall cho địa chỉ IPv4 nhưng nó có một đối tác IPv6 được gọi là “ip6tables”, được dùng để duy trì các luật firewall cho địa chỉ mạng IPv6.

Nếu VPS của bạn được cấu hình cho IPv6, hãy nhớ bảo mật cả network interface IPv4 và IPv6 của bạn bằng các công cụ thích hợp. Để biết thêm thông tin về các công cụ IPv6, hãy tham khảo hướng dẫn này: Cách Cấu hình Công cụ để Sử dụng IPv6 trên VPS Linux

Yêu cầu

Trước khi bắt đầu sử dụng hướng dẫn này, bạn nên có một account superuser riêng biệt, không phải root — user có quyền sudo — được cài đặt trên server của bạn. Nếu bạn cần cài đặt điều này, hãy làm theo hướng dẫn sau: Cài đặt server ban đầu với Ubuntu 14.04 .

Các lệnh iptables cơ bản

Đến đây bạn đã hiểu rõ về các khái niệm iptables, ta sẽ trình bày các lệnh cơ bản sẽ được sử dụng để tạo các bộ luật phức tạp và để quản lý giao diện iptables nói chung.

Trước tiên, bạn nên biết rằng các lệnh iptables phải được chạy với quyền root. Điều này nghĩa là bạn cần đăng nhập với quyền root, sử dụng su hoặc sudo -i để đạt được root shell hoặc đặt trước tất cả các lệnh với sudo . Ta sẽ sử dụng sudo trong hướng dẫn này vì đó là phương pháp được ưu tiên trên hệ thống Ubuntu.

Một điểm khởi đầu tốt là liệt kê các luật hiện tại được cấu hình cho iptables. Bạn có thể làm điều đó với cờ -L :

  • sudo iptables -L
Output:
Chain INPUT (policy ACCEPT) target prot opt source destination Chain FORWARD (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination

Như bạn thấy , ta có ba chuỗi mặc định (INPUT, OUTPUT và FORWARD). Ta cũng có thể thấy policy mặc định của mỗi chuỗi (mỗi chuỗi có CHẤP NHẬN làm policy mặc định của nó). Ta cũng thấy một số tiêu đề cột, nhưng ta không thấy bất kỳ luật thực tế nào. Điều này là do Ubuntu không cung cấp bộ luật mặc định.

Ta có thể thấy kết quả ở định dạng phản ánh các lệnh cần thiết để bật từng luật và policy bằng cách sử dụng cờ -S :

  • sudo iptables -S
Output:
-P INPUT ACCEPT -P FORWARD ACCEPT -P OUTPUT ACCEPT

Để sao chép cấu hình, ta chỉ cần nhập sudo iptables theo sau là từng dòng trong kết quả . (Tùy thuộc vào cấu hình, nó có thể phức tạp hơn một chút nếu ta được kết nối từ xa để ta không cài đặt policy thả mặc định trước khi các luật có sẵn để bắt và cho phép kết nối hiện tại của ta .)

Nếu bạn không có luật tại chỗ và mong muốn loại bỏ chúng và bắt đầu lại, bạn có thể làm sạch các luật hiện tại bằng lệnh :

  • sudo iptables -F

, policy mặc định rất quan trọng ở đây, bởi vì, trong khi tất cả các luật bị xóa khỏi chuỗi của bạn, policy mặc định sẽ không thay đổi với lệnh này. Điều đó nghĩa là nếu bạn được kết nối từ xa, bạn nên đảm bảo policy mặc định trên chuỗi INPUT và OUTPUT của bạn được đặt thành CHẤP NHẬN trước khi thực hiện các luật của bạn. Bạn có thể thực hiện việc này bằng lệnh :

  • sudo iptables -P INPUT ACCEPT
  • sudo iptables -P OUTPUT ACCEPT
  • sudo iptables -F

Sau đó, bạn có thể thay đổi policy thả mặc định trở lại DROP sau khi bạn đã cài đặt các luật cho phép rõ ràng kết nối của bạn. Ta sẽ xem xét cách thực hiện điều đó trong giây lát.

Thực hiện luật đầu tiên của bạn

Ta sẽ bắt đầu xây dựng các policy firewall của bạn . Như ta đã nói ở trên, ta sẽ làm việc với chuỗi INPUT vì đó là kênh mà lưu lượng đến sẽ được gửi qua. Ta sẽ bắt đầu với luật mà ta đã nói ở trên: luật chấp nhận rõ ràng kết nối SSH hiện tại của bạn.

Luật đầy đủ ta cần là:

  • sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

Điều này có thể trông cực kỳ phức tạp, nhưng hầu hết nó sẽ có ý nghĩa khi ta xem qua các thành phần:

  • -A INPUT : Cờ -A gắn luật vào cuối chuỗi. Đây là phần của lệnh cho iptables biết rằng ta muốn thêm luật mới, rằng ta muốn luật đó được thêm vào cuối chuỗi và chuỗi mà ta muốn hoạt động là chuỗi INPUT.
  • -m conntrack : iptables có một tập hợp các chức năng cốt lõi, nhưng cũng có một tập hợp các phần mở rộng hoặc module cung cấp các khả năng bổ sung.

Trong phần này của lệnh, ta nói rằng ta muốn có quyền truy cập vào chức năng được cung cấp bởi module conntrack . Mô-đun này cung cấp quyền truy cập vào các lệnh được dùng để đưa ra quyết định dựa trên mối quan hệ của gói tin với các kết nối trước đó.

  • –Ctstate : Đây là một trong những lệnh được tạo sẵn bằng cách gọi module conntrack . Lệnh này cho phép ta so khớp các gói dựa trên cách chúng liên quan đến các gói mà ta đã thấy trước đây.

Ta chuyển nó giá trị ESTABLISHED để cho phép các gói là một phần của kết nối hiện có. Ta chuyển cho nó giá trị RELATED để cho phép các gói được liên kết với một kết nối đã cài đặt . Đây là một phần của luật phù hợp với phiên SSH hiện tại của ta .

  • -j CHẤP NHẬN : Điều này chỉ định mục tiêu của các gói phù hợp. Ở đây, ta nói với iptables rằng các gói phù hợp với tiêu chí trước đó sẽ được chấp nhận và cho phép thông qua.

Ta đặt luật này ngay từ đầu vì ta muốn đảm bảo các kết nối ta đang sử dụng được khớp, được chấp nhận và được rút ra khỏi chuỗi trước khi đạt được bất kỳ luật DROP nào.

Ta có thể thấy những thay đổi nếu ta liệt kê các luật :

  • sudo iptables -L
Output:
Chain INPUT (policy ACCEPT) target prot opt source destination ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED Chain FORWARD (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination

Đến đây bạn đã biết cú pháp chung, hãy tiếp tục bằng cách thêm một số trường hợp khác mà ta muốn chấp nhận kết nối.

Chấp nhận các kết nối cần thiết khác

Ta đã yêu cầu iptables luôn mở bất kỳ kết nối nào đã mở và cho phép các kết nối mới liên quan đến các kết nối đó. Tuy nhiên, ta cần tạo một số luật để cài đặt khi ta muốn chấp nhận các kết nối mới không đáp ứng các tiêu chí đó.

Ta muốn giữ hai cổng mở đặc biệt. Ta muốn giữ cho cổng SSH của ta mở ( ta sẽ giả định trong hướng dẫn này đây là mặc định 22. Nếu bạn đã thay đổi điều này trong cấu hình SSH của bạn , hãy sửa đổi giá trị của bạn tại đây). Ta cũng sẽ giả định máy tính này đang chạy web server trên cổng mặc định 80. Nếu đây không phải là trường hợp của bạn, bạn không phải thêm luật đó.

Hai dòng ta sẽ sử dụng để thêm các luật này là:

  • sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
  • sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT

Như bạn thấy , những điều này rất giống với luật đầu tiên của ta , nhưng có lẽ đơn giản hơn. Các tùy chọn mới là:

  • -p tcp : Tùy chọn này trùng với các gói nếu giao thức đang được sử dụng là TCP. Đây là một giao thức dựa trên kết nối sẽ được hầu hết các ứng dụng sử dụng vì nó cho phép giao tiếp tin cậy .
  • –Dport : Tùy chọn này khả dụng nếu cờ -p tcp được đưa ra. Nó đưa ra một yêu cầu khác về việc khớp cổng đích cho gói phù hợp. Luật đầu tiên phù hợp với các gói TCP dành cho cổng 22, trong khi luật thứ hai trùng với lưu lượng TCP hướng tới cổng 80.

Có một luật chấp nhận nữa mà ta cần đảm bảo server của ta có thể hoạt động chính xác. Thông thường, các dịch vụ trên máy tính giao tiếp với nhau bằng cách gửi các gói mạng cho nhau. Họ làm điều này bằng cách sử dụng một network interface giả được gọi là loopback device , hướng lưu lượng truy cập trở lại chính nó thay vì đến các máy tính khác.

Vì vậy, nếu một dịch vụ muốn giao tiếp với một dịch vụ khác đang lắng nghe các kết nối trên cổng 4555, nó có thể gửi một gói đến cổng 4555 của loopback devide . Ta muốn loại hành vi này được cho phép, vì nó cần thiết cho hoạt động chính xác của nhiều chương trình.

Luật ta cần thêm là:

  • sudo iptables -I INPUT 1 -i lo -j ACCEPT

Điều này trông hơi khác so với các lệnh khác của ta . Hãy xem qua những gì nó đang làm:

  • I INPUT 1 : Cờ -I cho iptables chèn một luật . Điều này khác với cờ -A gắn một luật vào cuối. Cờ -I lấy một chuỗi và vị trí luật mà bạn muốn chèn luật mới.

Trong trường hợp này, ta đang thêm luật này làm luật đầu tiên của chuỗi INPUT. Điều này sẽ làm giảm phần còn lại của các luật . Ta muốn điều này ở đầu vì nó là cơ bản và không bị ảnh hưởng bởi các luật tiếp theo.

  • -i lo : Thành phần này của luật phù hợp nếu giao diện mà gói tin đang sử dụng là giao diện “lo”. Giao diện “lo” là một tên khác của loopback devide . Điều này nghĩa là bất kỳ gói nào sử dụng giao diện đó để giao tiếp (các gói được tạo trên server của ta , cho server của ta ) đều phải được chấp nhận.

Để xem các luật hiện tại của ta , ta nên sử dụng cờ -S . Điều này là do cờ -L không bao gồm một số thông tin, chẳng hạn như giao diện mà luật được liên kết, đây là một phần quan trọng của luật mà ta vừa thêm:

  • sudo iptables -S
Output:
-P INPUT ACCEPT -P FORWARD ACCEPT -P OUTPUT ACCEPT -A INPUT -i lo -j ACCEPT -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT

Thực hiện luật thả

Bây giờ ta có bốn luật riêng biệt chấp nhận các gói tin một cách rõ ràng dựa trên các tiêu chí nhất định. Tuy nhiên, firewall của ta hiện không chặn bất cứ thứ gì .

Nếu một gói đi vào chuỗi INPUT và không phù hợp với một trong bốn luật mà ta đã thực hiện, thì nó sẽ được chuyển đến policy mặc định của ta , đó là chấp nhận gói đó. Ta cần thay đổi điều này.

Có hai cách khác nhau để ta có thể làm điều này, với một số khác biệt khá quan trọng.

Cách đầu tiên ta có thể làm là sửa đổi policy mặc định của chuỗi INPUT. Ta có thể làm điều này bằng lệnh :

  • sudo iptables -P INPUT DROP

Thao tác này sẽ bắt bất kỳ gói nào lọt qua chuỗi INPUT của ta và thả chúng. Đây là những gì ta gọi là policy giảm mặc định. Một trong những tác động của kiểu thiết kế này là nó sẽ rơi trở lại việc giảm các gói tin nếu các luật được tuôn ra.

Điều này có thể an toàn hơn, nhưng cũng có thể gây ra hậu quả nghiêm trọng nếu bạn không có cách khác để truy cập vào server của bạn . Với DigitalOcean, bạn có thể đăng nhập thông qua console web của ta để có quyền truy cập vào server của bạn nếu điều này xảy ra. Control panel web hoạt động như một kết nối local ảo, vì vậy các luật iptables sẽ không ảnh hưởng đến nó.

Bạn có thể cần server của bạn tự động ngắt tất cả các kết nối trong trường hợp các luật bị hủy. Điều này sẽ ngăn không cho server của bạn bị bỏ ngỏ. Điều này cũng nghĩa là bạn có thể dễ dàng nối các luật vào cuối chuỗi một cách dễ dàng trong khi vẫn thả các gói theo ý muốn.

Cách tiếp cận thay thế là giữ policy mặc định cho chuỗi là chấp nhận và thêm luật đưa mọi gói tin còn lại xuống cuối chuỗi.

Nếu bạn đã thay đổi policy mặc định cho chuỗi INPUT ở trên, bạn có thể đặt lại policy này để làm theo bằng lệnh :

  • sudo iptables -P INPUT ACCEPT

Bây giờ, bạn có thể thêm một luật vào cuối chuỗi sẽ loại bỏ bất kỳ gói nào còn lại:

  • sudo iptables -A INPUT -j DROP

Kết quả trong điều kiện hoạt động bình thường hoàn toàn giống với policy thả mặc định. Luật này hoạt động bằng cách khớp mọi gói tin còn lại đến nó. Điều này ngăn một gói không bao giờ bị rơi trong suốt chuỗi để đạt được policy mặc định.

Về cơ bản, điều này được sử dụng để giữ policy mặc định để chấp nhận lưu lượng truy cập. Bằng cách đó, nếu có sự cố nào và các luật được xóa, bạn sẽ vẫn có thể truy cập máy qua mạng. Đây là cách triển khai một hành động mặc định mà không thay đổi policy sẽ được áp dụng cho một chuỗi trống.

Tất nhiên, điều này cũng nghĩa là bất kỳ luật nào mà bất kỳ luật bổ sung nào mà bạn muốn thêm vào cuối chuỗi sẽ phải được thêm vào trước luật thả. Bạn có thể làm điều này bằng cách tạm thời xóa luật thả:

  • sudo iptables -D INPUT -j DROP
  • sudo iptables -A INPUT new_rule_here
  • sudo iptables -A INPUT -j DROP

Hoặc, bạn có thể chèn các luật mà bạn cần vào cuối chuỗi (nhưng trước khi thả) bằng cách chỉ định số dòng. Để chèn luật ở dòng số 4, có thể chạy lệnh:

  • sudo iptables -I INPUT 4 new_rule_here

Nếu bạn gặp khó khăn khi biết số dòng của mỗi luật , bạn có thể yêu cầu iptables đánh số các luật bằng lệnh :

  • sudo iptables -L --line-numbers
Output:
Chain INPUT (policy DROP) num target prot opt source destination 1 ACCEPT all -- anywhere anywhere 2 ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED 3 ACCEPT tcp -- anywhere anywhere tcp dpt:ssh 4 ACCEPT tcp -- anywhere anywhere tcp dpt:http Chain FORWARD (policy ACCEPT) num target prot opt source destination Chain OUTPUT (policy ACCEPT) num target prot opt source destination

Điều này có thể hữu ích đảm bảo bạn đang thêm luật của bạn ở vị trí thích hợp.

Luật liệt kê và xóa Iptables

Nếu bạn muốn tìm hiểu chi tiết về việc liệt kê và xóa các luật iptables, hãy xem hướng dẫn này: Cách Liệt kê và Xóa Luật Tường lửa Iptables .

Lưu cấu hình Iptables của bạn

Theo mặc định, các luật mà bạn thêm vào iptables là tạm thời. Điều này nghĩa là khi bạn khởi động lại server của bạn , các luật iptables của bạn sẽ không còn nữa.

Đây thực sự là một tính năng dành cho một số user vì nó mang lại cho họ một con đường để quay lại nếu họ vô tình tự khóa mình khỏi server . Tuy nhiên, hầu hết user sẽ muốn một cách tự động lưu các luật bạn đã tạo và tải chúng khi server khởi động.

Có một số cách để thực hiện việc này, nhưng cách dễ nhất là với gói iptables-persistent . Bạn có thể download phần mềm này từ repository mặc định của Ubuntu:

  • sudo apt-get update
  • sudo apt-get install iptables-persistent

Trong quá trình cài đặt, bạn sẽ được hỏi liệu bạn có muốn lưu các luật hiện tại của bạn để được tải tự động hay không. Nếu bạn hài lòng với cấu hình hiện tại của bạn (và bạn đã kiểm tra khả năng tạo kết nối SSH độc lập, bạn có thể chọn lưu các luật hiện tại của bạn .

Nó cũng sẽ hỏi bạn xem bạn có muốn lưu các luật IPv6 mà bạn đã cấu hình hay không. Chúng được cấu hình thông qua một tiện ích riêng biệt có tên là ip6tables điều khiển stream các gói IPv6 theo cách gần như giống nhau.

Sau khi cài đặt xong, bạn sẽ có một dịch vụ mới gọi là iptables-persistent được cấu hình để chạy khi khởi động. Dịch vụ này sẽ tải trong các luật của bạn và áp dụng chúng khi server được khởi động.

Lưu cập nhật

Nếu bạn đã từng cập nhật firewall của bạn và muốn duy trì các thay đổi, bạn phải lưu các luật iptables của bạn để chúng được duy trì lâu dài.

Lưu các luật firewall của bạn bằng lệnh này:

  • sudo invoke-rc.d iptables-persistent save

Kết luận

Đến đây bạn sẽ có một điểm khởi đầu tốt để phát triển một bức firewall đáp ứng nhu cầu của bạn. Có nhiều tiện ích firewall khác và một số tiện ích có thể dễ dàng hơn, nhưng iptables là một công cụ học tập tốt, nếu chỉ vì nó tiết lộ một số cấu trúc netfilter bên dưới và vì nó có mặt trong rất nhiều hệ thống.

Để tìm hiểu thêm về cách bảo mật mạng của bạn với iptables, hãy xem các hướng dẫn sau:


Tags:

Các tin trước

Cách thức hoạt động của firewall Iptables 2014-05-02
Cách thiết lập firewall Iptables cơ bản trên Centos 6 2013-04-16
Cách thiết lập firewall Iptables cơ bản trên Centos 6 2013-04-16