nghttpx: Add log variables related to SSL/TLS connection
This commit add following 3 log variables to SSL/TLS connection: $ssl_cipher, $ssl_protocol, $ssl_session_id. If no information is available for them, '-' is produced for each.
This commit is contained in:
parent
b06e339dbb
commit
197493afd4
|
@ -269,27 +269,6 @@ void Client::report_progress() {
|
|||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
const char *get_tls_protocol(SSL *ssl) {
|
||||
auto session = SSL_get_session(ssl);
|
||||
|
||||
switch (session->ssl_version) {
|
||||
case SSL2_VERSION:
|
||||
return "SSLv2";
|
||||
case SSL3_VERSION:
|
||||
return "SSLv3";
|
||||
case TLS1_2_VERSION:
|
||||
return "TLSv1.2";
|
||||
case TLS1_1_VERSION:
|
||||
return "TLSv1.1";
|
||||
case TLS1_VERSION:
|
||||
return "TLSv1";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace {
|
||||
void print_server_tmp_key(SSL *ssl) {
|
||||
// libressl does not have SSL_get_server_tmp_key
|
||||
|
@ -333,7 +312,7 @@ void Client::report_tls_info() {
|
|||
if (worker->id == 0 && !worker->tls_info_report_done) {
|
||||
worker->tls_info_report_done = true;
|
||||
auto cipher = SSL_get_current_cipher(ssl);
|
||||
std::cout << "Protocol: " << get_tls_protocol(ssl) << "\n"
|
||||
std::cout << "Protocol: " << ssl::get_tls_protocol(ssl) << "\n"
|
||||
<< "Cipher: " << SSL_CIPHER_get_name(cipher) << std::endl;
|
||||
print_server_tmp_key(ssl);
|
||||
}
|
||||
|
|
|
@ -1345,6 +1345,9 @@ Logging:
|
|||
* $alpn: ALPN identifier of the protocol which generates
|
||||
the response. For HTTP/1, ALPN is always http/1.1,
|
||||
regardless of minor version.
|
||||
* $ssl_cipher: cipher used for SSL/TLS connection.
|
||||
* $ssl_protocol: protocol for SSL/TLS connection.
|
||||
* $ssl_session_id: session ID for SSL/TLS connection.
|
||||
|
||||
Default: )" << DEFAULT_ACCESSLOG_FORMAT << R"(
|
||||
--errorlog-file=<PATH>
|
||||
|
|
|
@ -733,6 +733,8 @@ std::string construct_absolute_request_uri(Downstream *downstream) {
|
|||
} // namespace
|
||||
|
||||
void ClientHandler::write_accesslog(Downstream *downstream) {
|
||||
nghttp2::ssl::TLSSessionInfo tls_info;
|
||||
|
||||
upstream_accesslog(
|
||||
get_config()->accesslog_format,
|
||||
LogSpec{
|
||||
|
@ -747,6 +749,7 @@ void ClientHandler::write_accesslog(Downstream *downstream) {
|
|||
: downstream->get_request_path().c_str(),
|
||||
|
||||
alpn_.c_str(),
|
||||
nghttp2::ssl::get_tls_session_info(&tls_info, conn_.tls.ssl),
|
||||
|
||||
std::chrono::system_clock::now(), // time_now
|
||||
downstream->get_request_start_time(), // request_start_time
|
||||
|
@ -763,13 +766,16 @@ void ClientHandler::write_accesslog(int major, int minor, unsigned int status,
|
|||
int64_t body_bytes_sent) {
|
||||
auto time_now = std::chrono::system_clock::now();
|
||||
auto highres_now = std::chrono::high_resolution_clock::now();
|
||||
nghttp2::ssl::TLSSessionInfo tls_info;
|
||||
|
||||
upstream_accesslog(get_config()->accesslog_format,
|
||||
LogSpec{
|
||||
nullptr, ipaddr_.c_str(),
|
||||
"-", // method
|
||||
"-", // path,
|
||||
alpn_.c_str(), time_now,
|
||||
alpn_.c_str(), nghttp2::ssl::get_tls_session_info(
|
||||
&tls_info, conn_.tls.ssl),
|
||||
time_now,
|
||||
highres_now, // request_start_time TODO is
|
||||
// there a better value?
|
||||
highres_now, // request_end_time
|
||||
|
|
|
@ -383,6 +383,12 @@ std::vector<LogFragment> parse_log_format(const char *optarg) {
|
|||
type = SHRPX_LOGF_PID;
|
||||
} else if (util::strieq_l("$alpn", var_start, varlen)) {
|
||||
type = SHRPX_LOGF_ALPN;
|
||||
} else if (util::strieq_l("$ssl_cipher", var_start, varlen)) {
|
||||
type = SHRPX_LOGF_SSL_CIPHER;
|
||||
} else if (util::strieq_l("$ssl_protocol", var_start, varlen)) {
|
||||
type = SHRPX_LOGF_SSL_PROTOCOL;
|
||||
} else if (util::strieq_l("$ssl_session_id", var_start, varlen)) {
|
||||
type = SHRPX_LOGF_SSL_SESSION_ID;
|
||||
} else {
|
||||
LOG(WARN) << "Unrecognized log format variable: "
|
||||
<< std::string(var_start, varlen);
|
||||
|
|
|
@ -164,6 +164,24 @@ std::pair<OutputIterator, size_t> copy(const char *src, size_t avail,
|
|||
}
|
||||
} // namespace
|
||||
|
||||
namespace {
|
||||
const char LOWER_XDIGITS[] = "0123456789abcdef";
|
||||
} // namespace
|
||||
|
||||
namespace {
|
||||
template <typename OutputIterator>
|
||||
std::pair<OutputIterator, size_t> copy_hex_low(const uint8_t *src,
|
||||
size_t srclen, size_t avail,
|
||||
OutputIterator oitr) {
|
||||
auto nwrite = std::min(srclen * 2, avail) / 2;
|
||||
for (auto i = 0; i < nwrite; ++i) {
|
||||
*oitr++ = LOWER_XDIGITS[src[i] >> 4];
|
||||
*oitr++ = LOWER_XDIGITS[src[i] & 0xf];
|
||||
}
|
||||
return std::make_pair(oitr, avail - nwrite);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
void upstream_accesslog(const std::vector<LogFragment> &lfv,
|
||||
const LogSpec &lgsp) {
|
||||
auto lgconf = log_config();
|
||||
|
@ -253,6 +271,29 @@ void upstream_accesslog(const std::vector<LogFragment> &lfv,
|
|||
case SHRPX_LOGF_ALPN:
|
||||
std::tie(p, avail) = copy(lgsp.alpn, avail, p);
|
||||
break;
|
||||
case SHRPX_LOGF_SSL_CIPHER:
|
||||
if (!lgsp.tls_info) {
|
||||
std::tie(p, avail) = copy("-", avail, p);
|
||||
break;
|
||||
}
|
||||
std::tie(p, avail) = copy(lgsp.tls_info->cipher, avail, p);
|
||||
break;
|
||||
case SHRPX_LOGF_SSL_PROTOCOL:
|
||||
if (!lgsp.tls_info) {
|
||||
std::tie(p, avail) = copy("-", avail, p);
|
||||
break;
|
||||
}
|
||||
std::tie(p, avail) = copy(lgsp.tls_info->protocol, avail, p);
|
||||
break;
|
||||
case SHRPX_LOGF_SSL_SESSION_ID:
|
||||
if (!lgsp.tls_info || lgsp.tls_info->session_id_length == 0) {
|
||||
std::tie(p, avail) = copy("-", avail, p);
|
||||
break;
|
||||
}
|
||||
std::tie(p, avail) =
|
||||
copy_hex_low(lgsp.tls_info->session_id,
|
||||
lgsp.tls_info->session_id_length, avail, p);
|
||||
break;
|
||||
case SHRPX_LOGF_NONE:
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include <chrono>
|
||||
|
||||
#include "shrpx_log_config.h"
|
||||
#include "ssl.h"
|
||||
|
||||
namespace shrpx {
|
||||
|
||||
|
@ -115,6 +116,9 @@ enum LogFragmentType {
|
|||
SHRPX_LOGF_REQUEST_TIME,
|
||||
SHRPX_LOGF_PID,
|
||||
SHRPX_LOGF_ALPN,
|
||||
SHRPX_LOGF_SSL_CIPHER,
|
||||
SHRPX_LOGF_SSL_PROTOCOL,
|
||||
SHRPX_LOGF_SSL_SESSION_ID,
|
||||
};
|
||||
|
||||
struct LogFragment {
|
||||
|
@ -128,6 +132,7 @@ struct LogSpec {
|
|||
const char *method;
|
||||
const char *path;
|
||||
const char *alpn;
|
||||
const nghttp2::ssl::TLSSessionInfo *tls_info;
|
||||
std::chrono::system_clock::time_point time_now;
|
||||
std::chrono::high_resolution_clock::time_point request_start_time;
|
||||
std::chrono::high_resolution_clock::time_point request_end_time;
|
||||
|
|
40
src/ssl.cc
40
src/ssl.cc
|
@ -78,6 +78,46 @@ LibsslGlobalLock::LibsslGlobalLock() {
|
|||
|
||||
LibsslGlobalLock::~LibsslGlobalLock() { ssl_global_locks.clear(); }
|
||||
|
||||
const char *get_tls_protocol(SSL *ssl) {
|
||||
auto session = SSL_get_session(ssl);
|
||||
if (!session) {
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
switch (session->ssl_version) {
|
||||
case SSL2_VERSION:
|
||||
return "SSLv2";
|
||||
case SSL3_VERSION:
|
||||
return "SSLv3";
|
||||
case TLS1_2_VERSION:
|
||||
return "TLSv1.2";
|
||||
case TLS1_1_VERSION:
|
||||
return "TLSv1.1";
|
||||
case TLS1_VERSION:
|
||||
return "TLSv1";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
TLSSessionInfo *get_tls_session_info(TLSSessionInfo *tls_info, SSL *ssl) {
|
||||
if (!ssl) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto session = SSL_get_session(ssl);
|
||||
if (!session) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
tls_info->cipher = SSL_get_cipher_name(ssl);
|
||||
tls_info->protocol = get_tls_protocol(ssl);
|
||||
tls_info->session_id = session->session_id;
|
||||
tls_info->session_id_length = session->session_id_length;
|
||||
|
||||
return tls_info;
|
||||
}
|
||||
|
||||
} // namespace ssl
|
||||
|
||||
} // namespace nghttp2
|
||||
|
|
20
src/ssl.h
20
src/ssl.h
|
@ -22,8 +22,15 @@
|
|||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef SSL_H
|
||||
#define SSL_H
|
||||
|
||||
#include "nghttp2_config.h"
|
||||
|
||||
#include <cinttypes>
|
||||
|
||||
#include <openssl/ssl.h>
|
||||
|
||||
namespace nghttp2 {
|
||||
|
||||
namespace ssl {
|
||||
|
@ -40,6 +47,19 @@ public:
|
|||
|
||||
extern const char *const DEFAULT_CIPHER_LIST;
|
||||
|
||||
const char *get_tls_protocol(SSL *ssl);
|
||||
|
||||
struct TLSSessionInfo {
|
||||
const char *cipher;
|
||||
const char *protocol;
|
||||
const uint8_t *session_id;
|
||||
size_t session_id_length;
|
||||
};
|
||||
|
||||
TLSSessionInfo *get_tls_session_info(TLSSessionInfo *tls_info, SSL *ssl);
|
||||
|
||||
} // namespace ssl
|
||||
|
||||
} // namespace nghttp2
|
||||
|
||||
#endif // SSL_H
|
||||
|
|
Loading…
Reference in New Issue