Làm cách nào để chạy máy chủ trên cổng 80 như một người dùng bình thường trên Linux?


311

Tôi đã Googled về một giải pháp trong một thời gian khá lâu, nhưng không thể tìm thấy câu trả lời.

Tôi đang dùng Ubuntu Linux và muốn chạy máy chủ trên cổng 80, nhưng do cơ chế bảo mật của Ubuntu, tôi gặp phải lỗi sau:

java.net.BindException: Quyền bị từ chối: 80

Tôi nghĩ rằng nó đủ đơn giản để vô hiệu hóa cơ chế bảo mật này để cổng 80 có sẵn cho tất cả người dùng hoặc gán các đặc quyền cần thiết cho người dùng hiện tại để truy cập cổng 80.


3
Vấn đề để chạy máy chủ trên một cổng khác không được ưu tiên là gì? Bạn đang suy nghĩ về một cái gì đó khắc nghiệt như vô hiệu hóa cơ chế bảo mật mà không cung cấp ít nhất một lý do rất nghiêm trọng để chạy một máy chủ trên cổng đó. Là máy chủ được mã hóa cứng để liên kết với cổng 80? Nếu vậy, hãy ném nó đi.
Ẩn danh


4
Bạn không thể. Các cổng dưới 1024 là đặc quyền và chỉ root mới có thể mở ổ cắm nghe trên chúng. Điều thích hợp để làm là bỏ quyền sau khi mở nó.
Falcon Momot

2
"Ẩn danh" - người dùng trên thế giới đã được đào tạo để tìm kiếm một số dịch vụ tại một số cổng nhất định. Trong một số trường hợp, nó đã được tiêu chuẩn hóa. Ví dụ: HTTP trên cổng 80 và HTTPS trên cổng 443. Thật khó để thay đổi người dùng và tiêu chuẩn của thế giới.

1
@FalconMomot Nếu các cổng dưới 1024 được đặc quyền, tại sao máy chủ Apache không yêu cầu một người nhập mật khẩu để nhận quyền root trên cổng 80 và làm thế nào để họ làm theo cách đó? Tôi nghĩ người hỏi muốn biết làm thế nào để làm mọi thứ theo cách đó (cho dù về mặt kỹ thuật nó có được sử dụng như root hay không). Hãy nói cho tôi biết nếu tôi sai, Deepak Mittal.
Shule

Câu trả lời:


355

Câu trả lời ngắn gọn: bạn không thể. Các cổng dưới 1024 chỉ có thể được mở bằng root. Theo nhận xét - tốt, bạn có thể, sử dụng CAP_NET_BIND_SERVICE , nhưng cách tiếp cận đó, áp dụng cho java bin sẽ khiến bất kỳ chương trình java nào được chạy với cài đặt này, điều không mong muốn, nếu không phải là rủi ro bảo mật.

Câu trả lời dài: bạn có thể chuyển hướng kết nối trên cổng 80 sang một số cổng khác mà bạn có thể mở như người dùng bình thường.

Chạy bằng root:

# iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080

Vì các thiết bị loopback (như localhost) không sử dụng quy tắc phát hành trước, nếu bạn cần sử dụng localhost, v.v., hãy thêm quy tắc này ( cảm ơn @Francesco ):

# iptables -t nat -I OUTPUT -p tcp -d 127.0.0.1 --dport 80 -j REDIRECT --to-ports 8080

GHI CHÚ: Giải pháp trên không phù hợp với hệ thống nhiều người dùng, vì bất kỳ người dùng nào cũng có thể mở cổng 8080 (hoặc bất kỳ cổng cao nào khác mà bạn quyết định sử dụng), do đó chặn lưu lượng. (Tín dụng cho CesarB ).

EDIT: theo câu hỏi bình luận - để xóa quy tắc trên:

# iptables -t nat --line-numbers -n -L

Điều này sẽ tạo ra một cái gì đó như:

Chain PREROUTING (policy ACCEPT)
num  target     prot opt source               destination         
1    REDIRECT   tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:8080 redir ports 8088
2    REDIRECT   tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:80 redir ports 8080

Quy tắc bạn quan tâm là nr. 2, để xóa nó:

# iptables -t nat -D PREROUTING 2

13
@Sunny: upvotes không phải là khẩu súng nhanh nhất ở phía tây, mà là phản hồi tốt nhất. Của bạn là tốt nhất cho đến nay (tôi chỉ đề cập đến iptables; bạn thực sự đã cung cấp dòng lệnh đầy đủ). Điều duy nhất của tôi không có của bạn là sự cảnh báo về những người dùng khác cũng có thể liên kết với cổng 8080.
CesarB

3
Lưu ý rằng điều này không hoạt động với IPv6.
Emmanuel Bourg

3
Bất cứ ai có thể giải thích làm thế nào tôi có thể loại bỏ quy tắc này sau khi tôi muốn? Sau khi chạy nó, nó hoạt động, nhưng dường như nó không phải là "quy tắc" bởi vì nó không hiển thị khi tôi làm sudo iptables --list. Tôi biết iptables là gì và làm gì, nhưng tôi chưa bao giờ thực sự sử dụng nó trước đây.
Bộ mã hóa

4
Cảm ơn câu trả lời của bạn ... bất cứ khi nào tôi khởi động lại Ubuntu, quy tắc này sẽ biến mất và tôi phải chạy lại nó. Có cách nào để cứu nó mãi mãi?
Coderji

4
@Coderji: kiểm tra phần "lưu" trong tài liệu cộng đồng: help.ubfox.com/community/IptablesHowTo
Nắng

79

Sử dụng authbind .

Nó thậm chí hoạt động với Java nếu bạn kích hoạt ngăn xếp chỉ IPv4 của Java. Tôi sử dụng:

authbind --deep $JAVA_HOME/bin/java -Djava.net.preferIPv4Stack=true …

4
Nếu máy chủ là Tomcat, bạn có thể tự động sử dụng authbind bằng cách cài đặt AUTHBIND=yestrong / etc / default / tomcat6
Emmanuel Bourg

Tôi không thể làm điều này hoạt động trên máy chủ Ubuntu với gói Java mặc định ...
Ashley

Tôi cũng không, bất kỳ giải pháp được biết đến?
đánh dấu

10
Lưu ý rằng bạn phải cấu hình authbindđể thực sự cho phép điều này xảy ra. Từ trang man: "/ etc / authbind / byport / port đã được kiểm tra. Nếu tệp này có thể truy cập để thực thi cho người dùng gọi, theo quyền truy cập (2), thì ràng buộc với cổng được ủy quyền." , ví dụ cho cổng 80 , sudo touch /etc/authbind/byport/80 ; sudo chmod 777 /etc/authbind/byport/80. Cài đặt ban đầu authbindthường không có bất kỳ ủy quyền được cấu hình sẵn nào.
Jason C

4
Oh nonononononono, đừng bao giờ chmod 777 bất cứ điều gì!
Julian

57

Nếu hệ thống của bạn hỗ trợ nó, bạn có thể sử dụng các khả năng. Xem các khả năng của con người, thứ bạn cần sẽ là CAP_NET_BIND_SERVICE.

Trên Debian / Ubuntu mới hơn, bạn có thể chạy:

sudo apt-get install libcap2-bin 
sudo setcap 'cap_net_bind_service=+ep' /path/to/program

cái này hoạt động cho nodejs: setcap 'cap_net_bind_service = + ep' / usr / bin / nodejs
JasonS

5
Điều này. Tôi tự hỏi tại sao câu trả lời này không tăng thêm. Dễ dàng hơn nhiều so với tùy chọn iptables imho.
Dominik R

5
Đây là câu trả lời đúng và hiệu quả nhất, tất cả các câu trả lời khác gây ra hiệu quả hoặc chỉ là iffy / không an toàn.
OneOfOne

41

Một giải pháp khác là làm cho ứng dụng của bạn được thiết lập để nó có thể liên kết với cổng 80. Khi root, hãy làm như sau

chown root ./myapp
chmod +S ./myapp

Hãy nhớ rằng làm điều này, trừ khi nó hoàn toàn đúng, sẽ khiến bạn gặp các lỗ hổng bảo mật tiềm ẩn, bởi vì ứng dụng của bạn sẽ nói chuyện với mạng và sẽ được chạy với các quyền riêng tư gốc. Nếu bạn sử dụng giải pháp này, bạn nên xem mã nguồn cho Apache hoặc Lighttpd hoặc một cái gì đó tương tự, nơi họ sử dụng các đặc quyền gốc để mở cổng, nhưng sau đó từ bỏ ngay những quyền riêng tư đó và "trở thành" một người dùng đặc quyền thấp hơn để một tên không tặc không thể chiếm toàn bộ máy tính của bạn.

Cập nhật: Như đã thấy trong câu hỏi này , có vẻ như các nhân Linux kể từ 2.6.24 có một khả năng mới cho phép bạn đánh dấu một tệp thực thi (tất nhiên không phải là tập lệnh) là có CAP_NET_BIND_SERVICEkhả năng "". Nếu bạn cài đặt gói debian "libcap2-bin", bạn có thể làm điều đó bằng cách ban hành lệnh

setcap 'cap_net_bind_service=+ep' /path/to/program

6
Điều đó cũng giống như chạy bằng root, trừ khi ứng dụng biết cách bỏ quyền riêng tư.
CesarB

14
Điều này nguy hiểm. Điều này có nghĩa là bất kỳ yêu cầu sẽ chạy như root. Đó là vì một lý do mà ngay cả apache bắt đầu như root để liên kết, và sau đó giảm các đặc quyền cho người dùng khác.
Nắng

9
Paul: iptables không quá nguy hiểm, bởi vì ngay cả khi ứng dụng bị xâm nhập, nó sẽ không làm lộ hệ thống trên các cuộc tấn công, ít nhất là không có quyền root. Chạy ứng dụng như root là một câu chuyện khác.
Nắng

1
Nguy hiểm cho iptables chỉ là nếu đây là một hệ thống nhiều người dùng, như CesarB nói, vì bất kỳ ai cũng có thể liên kết với 8080 và chặn lưu lượng.
Nắng

1
lol, thích cách câu trả lời được chấp nhận có -15
Evan Teran

40

Tôi chỉ đơn giản là sử dụng Nginx ở phía trước. Nó cũng có thể chạy trên localhost.

  • apt-get install nginx

.. hoặc là ..

  • pkg_add -r nginx

.. hoặc những gì từng phù hợp với hệ điều hành của bạn.

Tất cả những gì bạn cần trong nginx.conf, nếu chạy trên localhost, là:

người phục vụ {
        nghe 80;
        server_name some.domain.org;
        vị trí / {
            proxy_set_header Máy chủ lưu trữ $;
            proxy_set_header X-Real-IP $ remote_addr;
            proxy_set_header X-Forwarded-For $ proxy_add_x_forwarded_for;
            proxy_pass http://127.0.0.1:8081;
        }
}

Tôi thực sự thích giải pháp này.
thomasfedb

1
Đây là (một trong) giải pháp được đề xuất từ ​​chính JFrog
stolsvik

36

Cách tiếp cận được đề xuất bởi Sunny và CesarB:

iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080

hoạt động tốt nhưng nó có một nhược điểm nhỏ - nó không ngăn người dùng kết nối trực tiếp với cổng 8080 thay vì 80.

Hãy xem xét các kịch bản sau đây khi điều này có thể là một vấn đề.

Giả sử chúng ta có một máy chủ chấp nhận kết nối HTTP trên các kết nối cổng 8080 và HTTPS trên cổng 8181.

Chúng tôi sử dụng iptables để thiết lập các chuyển hướng sau:

80  ---> 8080
443 ---> 8181

Bây giờ, giả sử máy chủ của chúng tôi quyết định chuyển hướng người dùng từ trang HTTP sang trang HTTPS. Trừ khi chúng tôi cẩn thận viết lại phản hồi, nó sẽ chuyển hướng đến https://host:8181/. Tại thời điểm này, chúng tôi đang say sưa:

  • Một số người dùng sẽ đánh dấu https://host:8181/URL và chúng tôi sẽ cần duy trì URL này để tránh phá vỡ dấu trang của họ.
  • Những người dùng khác sẽ không thể kết nối vì máy chủ proxy của họ không hỗ trợ các cổng SSL không chuẩn.

Tôi sử dụng cách tiếp cận sau:

iptables -t mangle -A PREROUTING -p tcp --dport 80 -j MARK --set-mark 1
iptables -t mangle -A PREROUTING -p tcp --dport 443 -j MARK --set-mark 1
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080
iptables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-port 8181
iptables -I INPUT -m state --state NEW -m tcp -p tcp --dport 8080 -m mark --mark 1 -j ACCEPT
iptables -I INPUT -m state --state NEW -m tcp -p tcp --dport 8181 -m mark --mark 1 -j ACCEPT

Kết hợp với quy tắc RE DỰA mặc định trên chuỗi INPUT, cách tiếp cận này ngăn người dùng kết nối trực tiếp với các cổng 8080, 8181


1
Điều này là tốt, nhưng tại sao không chỉ liên kết daemon với localhost: 8080 thay vì 0.0.0.0:8080? Tôi muốn làm điều đó, nhưng tôi cần iptables cho điều đó.
Amala

Nó hoạt động, thực sự mát mẻ.
xtian

29

Theo truyền thống trên Unix, chỉ root mới có thể liên kết với các cổng thấp (<1024).

Cách đơn giản nhất để giải quyết vấn đề này là chạy máy chủ của bạn trên một cổng cao (ví dụ: 8080) và sử dụng quy tắc iptables đơn giản để chuyển tiếp các kết nối từ cổng 80 đến cổng 8080. Lưu ý rằng với điều này, bạn sẽ mất bảo vệ thêm từ cảng thấp; bất kỳ người dùng nào trên máy của bạn đều có thể liên kết với cổng 8080.


23

Nếu hệ thống của bạn hỗ trợ nó, bạn có thể sử dụng các khả năng. Hãy xem man capabilities, cái bạn cần sẽ là CAP_NET_BIND_SERVICE. Không, tôi chưa bao giờ sử dụng chúng cho mình và tôi không biết nếu chúng thực sự hoạt động :-)


1
họ làm việc, tôi sử dụng CAP_NET_RAW để chạy các công cụ như tcpdump như một người dùng bình thường.
Justin

12

Sử dụng proxy ngược (nginx, apache + mod_proxy) hoặc proxy đảo ngược bộ đệm (Squid, Varnish) trước các máy chủ ứng dụng của bạn!

Với proxy ngược, bạn có thể đạt được rất nhiều điều thú vị như:

  • Cân bằng tải
  • Khởi động lại máy chủ ứng dụng của bạn với người dùng nhận được trang lỗi ưa thích
  • Tăng tốc mọi thứ với bộ nhớ cache
  • Các cài đặt chi tiết mà bạn thường làm với proxy ngược chứ không phải với máy chủ ứng dụng

6

Bạn có thể sử dụng chương trình chuyển hướng:

sudo redir --lport=80 --laddr=192.168.0.101 --cport 9990 --caddr=127.0.0.1

4

Sử dụng sudo.

Cấu hình sudo để người dùng thông thường có thể chạy các lệnh thích hợp:

/etc/init.d/httpd start

Hoặc là

apachectl stop

Hoặc là

/usr/local/apache2/apachectl restart

Hoặc là

/myapp/myappbin start

(Hoặc bất kỳ lệnh / tập lệnh nào khác mà bạn sử dụng để bắt đầu / dừng bạn máy chủ web / ứng dụng cụ thể)


8
Điều này có cùng một vấn đề - chạy một dịch vụ như root là một thực tiễn xấu.
Kevin Panko

4

câu trả lời của nắng là đúng, nhưng bạn có thể phải đối mặt với các vấn đề khác vì giao diện loopback không sử dụng bảng PREROUTING,

vì vậy các quy tắc iptables cần thêm là hai:

iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080
iptables -t nat -I OUTPUT -p tcp -d 127.0.0.1 --dport 80 -j REDIRECT --to-ports 8080

3

Với Linux, bạn có một số tùy chọn khác:

Cả hai phần mở rộng cho nhân Linux đều cho phép cấp quyền truy cập ở mức độ chi tiết rất tốt. Điều này sẽ cho phép bạn cấp quy trình này để mở cổng 80 nhưng nó sẽ không kế thừa bất kỳ quyền gốc nào khác.

Từ những gì tôi đã nghe, bảo mật đơn giản hơn nhiều để sử dụng nhưng SELinux an toàn hơn.


2

Một giải pháp là sử dụng iptables để thực hiện PAT trên các gói cho cổng 80. Chẳng hạn, bạn có thể sử dụng điều này để định tuyến các gói đến cổng cục bộ 8080. Hãy chắc chắn và điều chỉnh các gói gửi trở lại cổng 80.

Theo kinh nghiệm của tôi, các tính năng cấp phép chi tiết của Linux không được biên dịch thành các hạt nhân tiêu chuẩn vì các vấn đề bảo mật.


2

Nếu bạn đang cố gắng thực hiện điều này để lệnh do người dùng chạy có thể sử dụng cổng 80, thì giải pháp duy nhất của bạn là các thủ thuật iptables hoặc đặt setuid-to-root có thể thực thi được.

Cách mà một thứ như Apache thực hiện điều này (nó liên kết với cổng 80, nhưng đang chạy như một người khác không phải root) là chạy bằng root, liên kết với cổng, sau đó thay đổi quyền sở hữu quy trình thành người dùng không có đặc quyền sau cổng đã thiết lập. Nếu ứng dụng bạn đang viết có thể được chạy bằng root, bạn có thể làm cho nó thay đổi chủ sở hữu thành người dùng không riêng tư sau khi các cổng được thiết lập. Nhưng nếu điều này chỉ dành cho một người dùng trung bình chạy từ dòng lệnh, thì bạn sẽ phải sử dụng một trong những giải pháp khác.


2

Khi tôi có nhiều ứng dụng phục vụ web khác nhau (tập lệnh python, công cụ tomcat, ...) mà tôi không muốn chạy bằng root, tôi thường định cấu hình máy chủ web apache trước chúng. Apache nghe cổng 80 và tomcat nghe 8080.

Trong apache: s config:

ProxyPass /webapp http://localhost:8080/webapp
ProxyPassReverse /webapp http://localhost:8080/webapp

Xem tài liệu mod-proxy để biết thêm thông tin: http://httpd.apache.org/docs/2.2/mod/mod_proxy.html


1
Hạn chế của giải pháp này là mất IP đến trong nhật ký Tomcat.
Emmanuel Bourg

2

Tôi nghĩ rằng giải pháp tốt nhất là sgid ứng dụng của bạn và ngay khi nó có cổng bị ràng buộc, nó sẽ bỏ các đặc quyền bằng cách chuyển sang người dùng khác.


1

Một số hệ thống máy chủ không cho phép sử dụng mô-đun NAT, 'iptables' không giải quyết được vấn đề trong trường hợp này.

Làm thế nào về xinetd?

Trong trường hợp của tôi (ubfox 10.04)

# apt-get install xinetd
# touch /etc/xinetd.d/my_redirect
# vim /etc/xinetd.d/my_redirect

Dán cấu hình:

service my_redirector_80
{
 disable = no
 socket_type = stream
 protocol = tcp
 user = root
 wait = no
 port = 80
 redirect = localhost 8080
 type = UNLISTED
}

Sau đó:

# service xinetd restart

http://docs.codehaus.org/display/JETTY/port80 giải thích rõ hơn.


1
Điều này về cơ bản tương đương với việc đặt proxy ngược trước máy chủ, nhưng nó không hiệu quả so với các giải pháp chuyên dụng như HAproxy, Pound hoặc Varnish hiểu giao thức HTTP và có thể thêm các tiêu đề hữu ích như X-Forwarded-For.
Emmanuel Bourg

-1

Bên cạnh đó, FreeBSD và Solaris (có ai nhớ cái đó không?) Cho phép bạn làm điều này (liên kết với các cổng thấp) mà không cần leo thang đặc quyền (nghĩa là sử dụng các chương trình để chuyển sang root). Vì bạn đã chỉ định Linux, tôi chỉ đăng bài này dưới dạng thông báo cho những người khác có thể tìm thấy câu hỏi này.


-1

Necromance.

Đơn giản. Với một nhân bình thường hoặc cũ, bạn không.
Như được chỉ ra bởi những người khác, iptables có thể chuyển tiếp một cổng.
Như những người khác đã chỉ ra, CAP_NET_BIND_SERVICE cũng có thể thực hiện công việc.
Tất nhiên, CAP_NET_BIND_SERVICE sẽ thất bại nếu bạn khởi chạy chương trình của mình từ một tập lệnh, trừ khi bạn đặt giới hạn trên trình thông dịch shell, điều này là vô nghĩa, bạn cũng có thể chạy dịch vụ của mình dưới dạng root ...
ví dụ: đối với Java, bạn phải áp dụng nó đến JVM JAVA

sudo /sbin/setcap 'cap_net_bind_service=ep' /usr/lib/jvm/java-8-openjdk/jre/bin/java

Rõ ràng, điều đó có nghĩa là bất kỳ chương trình Java nào cũng có thể liên kết các cổng hệ thống.
Dito cho mono / .NET.

Tôi cũng khá chắc chắn xinetd không phải là ý tưởng hay nhất.
Nhưng vì cả hai phương pháp đều là hack, tại sao không nâng giới hạn bằng cách nâng giới hạn?
Không ai nói bạn phải chạy kernel bình thường, vì vậy bạn chỉ có thể chạy kernel của riêng mình.

Bạn chỉ cần tải xuống nguồn cho kernel mới nhất (hoặc giống như bạn hiện có). Sau đó, bạn đi đến:

/usr/src/linux-<version_number>/include/net/sock.h:

Có bạn tìm dòng này

/* Sockets 0-1023 can't be bound to unless you are superuser */
#define PROT_SOCK       1024

và thay đổi nó thành

#define PROT_SOCK 0

nếu bạn không muốn có một tình huống ssh không an toàn, bạn hãy thay đổi nó thành: #define PROT_SOCK 24

Nói chung, tôi sẽ sử dụng cài đặt thấp nhất mà bạn cần, ví dụ 79 cho http hoặc 24 khi sử dụng SMTP trên cổng 25.

Đó là tất cả.
Biên dịch kernel và cài đặt nó.
Khởi động lại.
Đã kết thúc - giới hạn ngu ngốc đó là Gone, và điều đó cũng hoạt động cho các kịch bản.

Đây là cách bạn biên dịch kernel:

https://help.ubfox.com/community/Kernel/Compile

# You can get the kernel-source via package linux-source, no manual download required
apt-get install linux-source fakeroot

mkdir ~/src
cd ~/src
tar xjvf /usr/src/linux-source-<version>.tar.bz2
cd linux-source-<version>

# Apply the changes to PROT_SOCK define in /include/net/sock.h

# Copy the kernel config file you are currently using
cp -vi /boot/config-`uname -r` .config

# Install ncurses libary, if you want to run menuconfig
apt-get install libncurses5 libncurses5-dev

# Run menuconfig (optional)
make menuconfig

# Define the number of threads you wanna use when compiling (should be <number CPU cores> - 1), e.g. for quad-core
export CONCURRENCY_LEVEL=3
# Now compile the custom kernel
fakeroot make-kpkg --initrd --append-to-version=custom kernel-image kernel-headers

# And wait a long long time

cd ..

Tóm lại, hãy sử dụng iptables nếu bạn muốn giữ an toàn, biên dịch kernel nếu bạn muốn chắc chắn rằng hạn chế này không bao giờ làm phiền bạn nữa.


Ai đó vui lòng giải thích các downvote? Biên dịch hạt nhân không hoạt động? Hay chỉ vì sau đó, bạn không thể nâng cấp kernel từ kho lưu trữ thông thường nữa?
Quandary

Tôi đã thử giải pháp này ( sudo setcap cap_net_bind_service=+ep /path-to-java/java) nhưng tôi luôn nhận được java: error while loading shared libraries: libjli.so: cannot open shared object file: No such file or directorynếu java đã đặt mũ. xem thêm phần đầu tiên của unix.stackexchange.com/a/16670/55508
Daniel Alder

1
Giải quyết các lỗi trước đó bằng cách thêm <javahome>/lib/amd64/jli/vào ld.so.confvà chạysudo ldconfig
Daniel Alder
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.