Thứ năm, 20/08/2015 | 00:00 GMT+7

Cách chuyển tiếp cổng thông qua cổng Linux với Iptables

NAT , hay bản dịch địa chỉ mạng, là một thuật ngữ chung để chỉ các gói tin nhằm chuyển hướng chúng đến một địa chỉ thay thế. Thông thường, điều này được sử dụng để cho phép lưu lượng vượt qua ranh giới mạng. Một server thực hiện NAT thường có quyền truy cập vào hai hoặc nhiều mạng và được cấu hình để định tuyến lưu lượng giữa chúng.

Chuyển tiếp cổng là quá trình chuyển tiếp các yêu cầu đối với một cổng cụ thể đến server , mạng hoặc cổng khác. Khi quá trình này sửa đổi đích của gói đang bay, nó được coi là một loại hoạt động NAT.

Trong hướng dẫn này, ta sẽ trình bày cách sử dụng iptables để chuyển tiếp các cổng tới các server phía sau firewall bằng cách sử dụng các kỹ thuật NAT. Điều này rất hữu ích nếu bạn đã cấu hình một mạng riêng nhưng vẫn muốn cho phép một số lưu lượng nhất định bên trong thông qua một máy cổng được chỉ định. Ta sẽ sử dụng hai server Ubuntu 14.04 để chứng minh điều này.

Yêu cầu và Mục tiêu

Để làm theo hướng dẫn này, bạn cần hai server Ubuntu 14.04 trong cùng một trung tâm dữ liệu đã bật mạng riêng. Trên mỗi máy này, bạn cần cài đặt account user không phải root với các quyền sudo . Bạn có thể tìm hiểu cách tạo user có quyền sudo theo hướng dẫn cài đặt server ban đầu Ubuntu 14.04 của ta .

Server đầu tiên sẽ hoạt động như firewall và bộ định tuyến của ta cho mạng riêng. Đối với mục đích demo , server thứ hai sẽ được cấu hình với một web server chỉ có thể truy cập bằng giao diện riêng tư của nó. Ta sẽ cấu hình máy firewall để chuyển tiếp các yêu cầu nhận được trên giao diện công khai của nó tới web server , server này sẽ tiếp cận trên giao diện riêng tư của nó.

Chi tiết Server

Trước khi bạn bắt đầu, ta cần biết giao diện và địa chỉ nào đang được sử dụng bởi cả hai server của ta .

Tìm chi tiết mạng của bạn

Để có thông tin chi tiết về hệ thống của bạn , hãy bắt đầu bằng cách tìm các network interface của bạn. Bạn có thể tìm thấy các giao diện trên máy của bạn và địa chỉ được liên kết với chúng bằng lệnh :

  • ip -4 addr show scope global
Sample Output
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 inet 198.51.100.45/18 brd 45.55.191.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.168.1.5/16 brd 10.132.255.255 scope global eth1 valid_lft forever preferred_lft forever

Kết quả được đánh dấu ở trên hiển thị hai giao diện ( eth0eth1 ) và các địa chỉ được gán cho mỗi giao diện ( 192.51.100.45192.168.1.5 tương ứng). Để biết giao diện nào trong số những giao diện này là giao diện công khai của bạn, hãy nhập:

  • ip route show | grep default
Output
default via 111.111.111.111 dev eth0

Giao diện được hiển thị ( eth0 trong ví dụ này) sẽ là giao diện được kết nối với cổng mặc định của bạn. Đây gần như chắc chắn là giao diện công khai của bạn.

Tìm các giá trị này trên mỗi máy của bạn và sử dụng chúng để làm theo đúng hướng dẫn này.

Dữ liệu mẫu cho Hướng dẫn này

Để làm cho việc theo dõi dễ dàng hơn, ta sẽ sử dụng địa chỉ giả và các phép gán giao diện trong suốt hướng dẫn này. Vui lòng thay thế các giá trị của bạn cho những giá trị bạn thấy bên dưới:

Chi tiết mạng web server :

  • Địa chỉ IP công cộng: 203.0.113.2
  • Địa chỉ IP riêng: 192.0.2.2
  • Giao diện công khai: eth0
  • Giao diện riêng tư: eth1

Chi tiết mạng firewall :

  • Địa chỉ IP công cộng: 203.0.113.15
  • Địa chỉ IP riêng: 192.0.2.15
  • Giao diện công khai: eth0
  • Giao diện riêng tư: eth1

Cài đặt web server

Ta sẽ bắt đầu với server lưu trữ web server của ta . Đăng nhập với user sudo của bạn để bắt đầu.

Cài đặt Nginx

Quá trình đầu tiên ta sẽ hoàn thành là cài đặt Nginx trên server lưu trữ web server của ta và khóa nó lại để nó chỉ lắng nghe giao diện riêng tư của nó. Điều này sẽ đảm bảo web server của ta sẽ chỉ khả dụng nếu ta cài đặt chính xác tính năng chuyển tiếp cổng.

Bắt đầu bằng cách cập nhật cache ẩn gói local và sử dụng apt để download và cài đặt phần mềm:

  • sudo apt-get update
  • sudo apt-get install nginx

Hạn chế Nginx đối với Mạng riêng

Sau khi Nginx được cài đặt, ta sẽ mở file cấu hình khối server mặc định đảm bảo rằng nó chỉ lắng nghe giao diện riêng tư. Mở file ngay bây giờ:

  • sudo nano /etc/nginx/sites-enabled/default

Bên trong, tìm chỉ thị listen . Bạn sẽ tìm thấy nó hai lần liên tiếp ở phía trên cùng của cấu hình:

/ etc / nginx / sites-enable / default
server {     listen 80 default_server;     listen [::]:80 default_server ipv6only=on;      . . . } 

Ở chỉ thị listen đầu tiên, hãy thêm địa chỉ IP riêng của web server của bạn và dấu hai chấm ngay trước 80 để yêu cầu Nginx chỉ lắng nghe trên giao diện riêng tư. Ta chỉ trình bày chuyển tiếp IPv4 trong hướng dẫn này, vì vậy ta có thể xóa chỉ thị lắng nghe thứ hai, được cấu hình cho IPv6.

Trong ví dụ của ta , ta sẽ sửa đổi các chỉ thị lắng nghe để trông giống như sau:

/ etc / nginx / sites-enable / default
server {     listen 192.0.2.2:80 default_server;      . . . } 

Lưu file khi bạn hoàn tất. Kiểm tra file để tìm lỗi cú pháp bằng lệnh :

  • sudo nginx -t

Nếu không có lỗi nào được hiển thị, hãy khởi động lại Nginx để kích hoạt cấu hình mới:

  • sudo service nginx restart

Xác minh hạn chế mạng

Đến đây, rất hữu ích để xác minh mức độ truy cập mà ta có vào web server của bạn .

Từ server tường lửa của ta , nếu ta cố gắng truy cập web server của bạn từ giao diện riêng tư, nó sẽ hoạt động:

  • curl --connect-timeout 5 192.0.2.2
Output
<!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx!</h1> . . .

Nếu cố gắng sử dụng giao diện công khai, ta sẽ thấy rằng ta không thể kết nối:

  • curl --connect-timeout 5 203.0.113.2
curl: (7) Failed to connect to 203.0.113.2 port 80: Connection refused 

Đây chính xác là những gì ta mong đợi sẽ xảy ra.

Cấu hình Tường lửa để Chuyển tiếp Cổng 80

Bây giờ, ta có thể thực hiện chuyển tiếp cổng trên máy firewall của bạn .

Bật chuyển tiếp trong nhân

Điều đầu tiên ta cần làm là kích hoạt chuyển tiếp lưu lượng ở cấp kernel . Theo mặc định, hầu hết các hệ thống đã tắt chuyển tiếp.

Để chỉ bật chuyển tiếp cổng cho phiên này, hãy nhập:

  • echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward

Để bật chuyển tiếp cổng vĩnh viễn, bạn sẽ phải chỉnh sửa file /etc/sysctl.conf . Mở file với quyền sudo bằng lệnh :

  • sudo nano /etc/sysctl.conf

Bên trong, tìm và bỏ comment trông như thế này:

/etc/sysctl.conf
net.ipv4.ip_forward=1 

Lưu file khi bạn hoàn tất. Bạn áp dụng cài đặt trong file này bằng lệnh :

  • sudo sysctl -p
  • sudo sysctl --system

Cài đặt firewall cơ bản

Ta sẽ sử dụng firewall trong hướng dẫn này làm khung cơ bản cho các luật trong hướng dẫn này. Chạy qua hướng dẫn ngay bây giờ trên máy firewall của bạn để cài đặt . Sau khi kết thúc, bạn sẽ có:

  • Đã cài đặt iptables-persistent
  • Đã lưu luật mặc định được đặt vào /etc/iptables/rules.v4
  • Đã học cách thêm hoặc điều chỉnh các luật bằng cách chỉnh sửa file luật hoặc bằng cách sử dụng lệnh iptables

Khi bạn đã cài đặt firewall cơ bản, hãy tiếp tục bên dưới để ta có thể điều chỉnh firewall cho chuyển tiếp cổng.

Thêm luật chuyển tiếp

Ta muốn cấu hình firewall của bạn để lưu lượng truy cập vào giao diện công cộng ( eth0 ) trên cổng 80 sẽ được chuyển tiếp đến giao diện riêng tư của ta ( eth1 ).

Tường lửa cơ bản của ta có chuỗi FORWARD được đặt thành DROP lưu lượng truy cập theo mặc định. Ta cần thêm các luật cho phép ta chuyển tiếp kết nối đến web server của ta . Vì lợi ích bảo mật, ta sẽ khóa điều này khá chặt chẽ để chỉ cho phép các kết nối mà ta muốn chuyển tiếp.

Trong chuỗi FORWARD , ta sẽ chấp nhận các kết nối mới dành cho cổng 80 đến từ giao diện công cộng của ta và chuyển sang giao diện riêng tư của ta . Các kết nối mới được xác định bởi phần mở rộng conntrack và cụ thể sẽ được đại diện bởi một gói TCP SYN:

  • sudo iptables -A FORWARD -i eth0 -o eth1 -p tcp --syn --dport 80 -m conntrack --ctstate NEW -j ACCEPT

Điều này sẽ cho phép gói đầu tiên, nghĩa là cài đặt kết nối, thông qua firewall . Ta cũng cần cho phép mọi lưu lượng truy cập tiếp theo theo cả hai hướng là kết quả của kết nối đó. Để cho phép lưu lượng đã ESTABLISHEDRLEATED giữa giao diện công khai và riêng tư của ta , hãy nhập:

  • iptables -A FORWARD -i eth0 -o eth1 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
  • iptables -A FORWARD -i eth1 -o eth0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

Ta có thể kiểm tra kỹ xem policy của ta trên chuỗi FORWARD có được đặt thành DROP bằng lệnh :

  • sudo iptables -P FORWARD DROP

Đến đây, ta đã cho phép một số lưu lượng nhất định giữa các giao diện công khai và riêng tư của ta để tiến hành thông qua firewall của ta . Tuy nhiên, ta vẫn chưa cấu hình các luật sẽ thực sự cho iptables biết cách dịch và hướng lưu lượng truy cập.

Thêm luật NAT vào gói trực tiếp một cách chính xác

Tiếp theo, ta sẽ thêm các luật sẽ cho iptables biết cách định tuyến giao thông của ta . Ta cần thực hiện hai hoạt động riêng biệt để iptables thay đổi chính xác các gói để client có thể giao tiếp với web server .

Hoạt động đầu tiên, được gọi là DNAT , sẽ diễn ra trong chuỗi PREROUTING của bảng nat . DNAT là một hoạt động làm thay đổi địa chỉ đích của gói để cho phép nó được định tuyến chính xác khi nó truyền giữa các mạng. Các client trên mạng công cộng sẽ kết nối với server firewall của ta và sẽ không biết về cấu trúc liên kết mạng riêng của ta . Ta cần thay đổi địa chỉ đích của mỗi gói tin để khi nó được gửi đi trên mạng riêng của ta , nó biết cách truy cập chính xác vào web server của ta .

Vì ta chỉ cấu hình chuyển tiếp cổng và không thực hiện NAT trên mọi gói tin truy cập vào firewall của ta , ta sẽ muốn khớp cổng 80 theo luật của ta . Ta sẽ đối sánh các gói nhắm đến cổng 80 với địa chỉ IP riêng của web server của ta (trong ví dụ của ta là 192.0.2.2 ):

  • sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to-destination 192.0.2.2

Điều này sẽ quan tâm đến một nửa của bức tranh. Gói tin sẽ được định tuyến chính xác đến web server của ta . Tuy nhiên, ngay bây giờ, gói tin sẽ vẫn có địa chỉ ban đầu của khách hàng là địa chỉ nguồn. Server sẽ cố gắng gửi thư trả lời trực tiếp đến địa chỉ đó, điều này sẽ khiến không thể cài đặt kết nối TCP hợp lệ .

Ghi chú
Trên DigitalOcean, các gói rời khỏi Server có địa chỉ nguồn khác sẽ thực sự bị trình giám sát loại bỏ, vì vậy các gói của bạn ở giai đoạn này thậm chí sẽ không bao giờ đến được web server ( ta sẽ khắc phục điều này bằng cách triển khai SNAT trong giây lát). Đây là một biện pháp chống giả mạo được đưa ra để ngăn chặn các cuộc tấn công trong đó một lượng lớn dữ liệu được yêu cầu gửi đến máy tính của nạn nhân bằng cách giả mạo địa chỉ nguồn trong yêu cầu. Để tìm hiểu thêm, hãy xem phản hồi này trong cộng đồng của ta .

Để cấu hình định tuyến thích hợp, ta cũng cần sửa đổi địa chỉ nguồn của gói tin khi nó rời khỏi firewall trên đường đến web server . Ta cần sửa đổi địa chỉ nguồn thành địa chỉ IP riêng của server firewall của ta ( 192.0.2.15 trong ví dụ của ta ). Câu trả lời sau đó sẽ được gửi trở lại firewall , sau đó có thể chuyển tiếp nó trở lại client như mong đợi.

Để kích hoạt chức năng này, ta sẽ thêm một luật vào chuỗi POSTROUTING của bảng nat , được đánh giá ngay trước khi các gói được gửi đi trên mạng. Ta sẽ đối sánh các gói dành cho web server của ta theo địa chỉ IP và cổng:

  • sudo iptables -t nat -A POSTROUTING -o eth1 -p tcp --dport 80 -d 192.0.2.2 -j SNAT --to-source 192.0.2.15

Khi luật này được áp dụng, web server của ta sẽ có thể truy cập được bằng cách trỏ trình duyệt web của ta vào địa chỉ công cộng của máy firewall của ta :

  • curl 203.0.113.15
Output
<!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx!</h1> . . .

Cài đặt chuyển tiếp cổng của ta đã hoàn tất.

Điều chỉnh Bộ luật vĩnh viễn

Bây giờ ta đã cài đặt chuyển tiếp cổng, ta có thể lưu điều này vào bộ luật vĩnh viễn của ta .

Nếu bạn không quan tâm đến việc mất các comment có trong bộ luật hiện tại của bạn , chỉ cần sử dụng dịch vụ iptables-persistent để lưu các luật của bạn:

  • sudo service iptables-persistent save

Nếu bạn muốn giữ các comment trong file của bạn , hãy mở nó lên và chỉnh sửa theo cách thủ công:

  • sudo nano /etc/iptables/rules.v4

Bạn cần điều chỉnh cấu hình trong bảng filter cho các luật chuỗi FORWARD đã được thêm vào. Bạn cũng cần điều chỉnh phần cấu hình bảng nat để bạn có thể thêm các luật PREROUTINGPOSTROUTING . Đối với ví dụ của ta , nó sẽ trông giống như sau:

/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  # Rules to forward port 80 to our web server  # Web server network details:  # * Public IP Address: 203.0.113.2 # * Private IP Address: 192.0.2.2 # * Public Interface: eth0 # * Private Interface: eth1 #  # Firewall network details: #  # * Public IP Address: 203.0.113.15 # * Private IP Address: 192.0.2.15 # * Public Interface: eth0 # * Private Interface: eth1 -A FORWARD -i eth0 -o eth1 -p tcp --syn --dport 80 -m conntrack --ctstate NEW -j ACCEPT -A FORWARD -i eth0 -o eth1 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT -A FORWARD -i eth1 -o eth0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT # End of Forward filtering rules  # 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]  # Rules to translate requests for port 80 of the public interface # so that we can forward correctly to the web server using the # private interface.  # Web server network details:  # * Public IP Address: 203.0.113.2 # * Private IP Address: 192.0.2.2 # * Public Interface: eth0 # * Private Interface: eth1 #  # Firewall network details: #  # * Public IP Address: 203.0.113.15 # * Private IP Address: 192.0.2.15 # * Public Interface: eth0 # * Private Interface: eth1 -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to-destination 192.0.2.2 -A POSTROUTING -d 192.0.2.2 -o eth1 -p tcp --dport 80 -j SNAT --to-source 192.0.2.15 # End of NAT translations for web server traffic 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 file khi bạn đã thêm các thông tin trên và điều chỉnh các giá trị để phản ánh môi trường mạng của bạn .

Kiểm tra cú pháp của file luật của bạn bằng lệnh :

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

Nếu không có lỗi nào được phát hiện, hãy tải bộ luật :

  • sudo service iptables-persistent reload

Kiểm tra xem web server của bạn vẫn có thể truy cập được thông qua địa chỉ IP công cộng của firewall hay không:

  • curl 203.0.113.15

Điều này sẽ hoạt động giống như nó đã làm trước đây.

Kết luận

Bây giờ, bạn đã cảm thấy thoải mái với các cổng chuyển tiếp trên server Linux với iptables . Quá trình này liên quan đến việc cho phép chuyển tiếp ở cấp kernel , cài đặt quyền truy cập để cho phép chuyển tiếp lưu lượng của cổng cụ thể giữa hai giao diện trên hệ thống firewall và cấu hình các luật NAT để các gói có thể được định tuyến chính xác. Đây có vẻ là một quy trình khó sử dụng, nhưng nó cũng thể hiện tính linh hoạt của khung lọc gói netfilter và firewall iptables . Điều này được dùng để ngụy trang cấu trúc liên kết mạng riêng của bạn trong khi cho phép lưu lượng dịch vụ chảy tự do qua máy firewall cổng của bạn.


Tags:

Các tin liên quan

Cách cấu hình dịch vụ Linux để khởi động tự động sau khi gặp sự cố hoặc khởi động lại - Phần 1: Ví dụ thực tế
2015-08-19
Cách sử dụng Hệ thống kiểm toán Linux trên CentOS 7
2015-07-16
Cách sử dụng Hệ thống kiểm toán Linux trên CentOS 7
2015-07-16
Thiết lập ban đầu của server Fedora 22
2015-07-08
Cách thiết lập Shiny Server trên Ubuntu 14.04
2015-06-28
Cách backup server LAMP bằng Bacula trên Ubuntu 14.04
2015-06-11
Cách cấu hình sao chép DNS trên server Slave PowerDNS trên Ubuntu 14.04
2015-06-04
Cách thay đổi mật khẩu tài khoản trên server OpenLDAP
2015-05-29
Cách thay đổi mật khẩu tài khoản trên server OpenLDAP
2015-05-29
Cách chạy mail server và lưu trữ tệp của riêng bạn với PEPS trên Ubuntu 14.04
2015-05-22