Lệnh Openssl s_client luôn nói 400 Yêu cầu xấu


10

Tôi đang cố kiểm tra một máy chủ hoạt động bình thường trong trình duyệt web, với tùy chọn openssl s_client, kết nối trực tiếp với nó bằng openssl trả về 400 Yêu cầu Không hợp lệ:

openssl s_client -servername example.com -connect example.com:443 -tls1
(some information about the certificate)

GET / HTTP/1.1 
(and the error occurs **immediately** - no time to include more headers like Host:)

Quan trọng: Tôi đã cố gắng đặt tiêu đề Host: điều này là khi tôi chạy GET, lỗi xảy ra ngay lập tức khiến tôi không có cơ hội bao gồm nhiều tiêu đề hơn. Thay thế example.com bằng máy chủ của tôi ...


1
Tôi thường echo: echo -e "GET / HTTP/1.1\r\nHost: example.com.br\r\n\r\n" | openssl s_client .... Điều \r\nnày rất quan trọng vì đó là những gì mà tiêu chuẩn HTTP nói phải làm. Hai cặp CRLF ở cuối yêu cầu cũng rất quan trọng vì đó là những gì tiêu chuẩn nói. Ngoài ra, hãy xem Làm thế nào để bạn chuyển đổi tiếng vang tiếng vang vào thành trò chơi opens opens tinh?

Nó nói DONG, nhưng không có phản hồi cho trang web, điều đó có bình thường không? Lưu ý rằng tôi không thể viết tiêu đề Host: theo mẫu mà tôi đã hỏi, nó sẽ báo lỗi cho tôi ở cuối get.
Luciano Andress Martini

Tôi đoán (và chỉ là phỏng đoán), nhưng bạn không cung cấp đúng tên tài liệu; hoặc bạn không cung cấp cookie hoặc mã thông báo truy cập. Máy chủ nhận được yêu cầu của bạn và sau đó lỗi với mã lỗi 4xx để chỉ ra lỗi máy khách. Bạn có thể cần GET /index.html ...hoặc bạn có thể cần đặt cookie. Bạn có thể nên thử với curlhoặc wget, và gửi yêu cầu và phản hồi đầy đủ , bao gồm cả lỗi. Mặt khác, bạn phải cung cấp tên máy chủ và URL thực để chúng tôi có thể chạy thử nghiệm.

Tôi biết đúng tên của URL khi tôi định cấu hình máy chủ và điều lạ là nó đang hoạt động trên trình duyệt web, rất lạ khi không muốn làm việc bằng openssl ngay cả khi tôi chỉ định đúng tên miền trên Máy chủ: tiêu đề. Lỗi 500 rất có thể là tôi đang gửi dữ liệu ở dạng văn bản đơn giản (ví dụ sử dụng telnet), nhưng openssl đã được sử dụng ... Tôi nghĩ rằng tôi sẽ bỏ cuộc .... Không quan trọng lắm, chỉ vì tôi thấy một ví dụ về cách telnet một trang web ssl và muốn thử nó, nhưng nó không hoạt động tốt.
Luciano Andress Martini

"Tôi nghĩ rằng tôi sẽ từ bỏ ..." - Nếu bạn sẽ nghỉ hưu, xin vui lòng xóa câu hỏi. Câu hỏi và trả lời sẽ không hoàn thành và câu hỏi sẽ không bao giờ có câu trả lời được chấp nhận. Ở trạng thái này, nó có thể gây ra vấn đề cho khách truy cập trong tương lai. Nếu bạn cần trợ giúp để xóa câu hỏi, sau đó gắn cờ cho sự chú ý của người điều hành.

Câu trả lời:


19

Theo https://bz.apache.org/ormszilla/show_orms.cgi?id=60695 lệnh của tôi là:

openssl s_client -crlf -connect www.pgxperts.com:443

trong đó -crlf có nghĩa là, theo sự trợ giúp của lệnh openssl,

-crlf - chuyển đổi LF từ thiết bị đầu cuối thành CRLF

Sau đó, tôi có thể nhập các lệnh đa dòng và không có "yêu cầu xấu" nào dưới dạng phản hồi sau dòng lệnh đầu tiên nữa.


Bây giờ thì tốt hơn, nhưng không hoạt động khi tôi cố gắng chỉ định máy chủ, chỉ khi tôi thực hiện một thao tác đơn giản.
Luciano Andress Martini

4

OK đã có điều tương tự bản thân mình và mất một thời gian để tìm ra.

Tôi không thể tìm cách gửi nhiều dòng trong yêu cầu khi sử dụng s_client tương tác. Nó luôn gửi yêu cầu ngay lập tức ngay khi bạn nhập dòng đầu tiên. Nếu ai đó biết cách khắc phục điều này thì xin vui lòng cho tôi biết!

Chỉnh sửa : Tôi thấy Wei Ông đã đăng cách để làm điều này - sử dụng -crlfcờ nhưng để câu trả lời này ở đây như một phương pháp thay thế.

Trong khi đó, như jww đề xuất, bạn phải sử dụng echocho việc này:

echo -e "GET / HTTP/1.1\r\nHost: example.com\r\n\r\n" | openssl s_client ...

Vấn đề tiếp theo là theo mặc định openssl đóng kết nối khi đóng tệp đầu vào. Mà là làm ngay lập tức khi sử dụng echonhư thế này. Vì vậy, bạn không có thời gian để xem phản hồi và thay vào đó chỉ xem đầu ra DONE! :-(

Bạn có thể thêm a sleepvào lệnh echo để giải quyết vấn đề này (lưu ý dấu ngoặc là quan trọng):

(echo -e "GET / HTTP/1.1\r\nHost: example.com\r\n\r\n"; sleep 10) | openssl s_client ...

Hoặc, tốt hơn thế, bạn có thể sử dụng -ign_eoftùy chọn để mở kết nối:

echo -e "GET / HTTP/1.1\r\nHost: example.com\r\n\r\n" | openssl s_client -ign_eof ...

Hoặc tốt hơn nữa, nếu bạn chỉ quan tâm đến các phản hồi HTTP thì hãy sử dụng -quitetùy chọn che giấu phần lớn tiếng ồn TLS và cũng đặt tùy chọn -ign_eof cho bạn:

echo -e "GET / HTTP/1.1\r\nHost: example.com\r\n\r\n" | openssl s_client -quiet ...

3

Từ những gì tôi có thể thấy, 400 Yêu cầu xấu có khả năng liên quan đến việc sử dụng HTTP / 1.1 trong dòng GET của bạn.

Bạn đã thêm tiêu đề "Máy chủ:" sau yêu cầu GET? RFC tuyên bố rằng đối với HTTP / 1.1, cần có tiêu đề Máy chủ:

https://www.ietf.org/rfc/rfc2616.txt

19.6.1.1 Thay đổi để đơn giản hóa máy chủ web đa nhà và bảo tồn địa chỉ IP

Các yêu cầu mà máy khách và máy chủ hỗ trợ tiêu đề yêu cầu Máy chủ, báo cáo lỗi nếu tiêu đề yêu cầu Máy chủ (phần 14,23) bị thiếu trong yêu cầu HTTP / 1.1 và chấp nhận URI tuyệt đối (phần 5.1.2) là một trong những quan trọng nhất thay đổi được xác định bởi đặc điểm kỹ thuật này.


2

Bạn có thể đưa ra yêu cầu GET với OpenSSL:

openssl s_client -quiet -connect cdn.sstatic.net:443 <<eof
GET /stackexchange/js/universal-login.js HTTP/1.1
Connection: close
Host: cdn.sstatic.net

eof

Lưu ý rằng bạn cũng có thể sử dụng "HTTP / 2", nhưng hãy cẩn thận vì một số máy chủ (ví dụ: github.com) không hỗ trợ nó.

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.