MEDIUM: log: report SSL ciphers and version in logs using logformat %sslc/%sslv

These two new log-format tags report the SSL protocol version (%sslv) and the
SSL ciphers (%sslc) used for the connection with the client. For instance, to
append these information just after the client's IP/port address information
on an HTTP log line, use the following configuration :

    log-format %Ci:%Cp\ %sslv:%sslc\ [%t]\ %ft\ %b/%s\ %Tq/%Tw/%Tc/%Tr/%Tt\ %st\ %B\ %cc\ \ %cs\ %tsc\ %ac/%fc/%bc/%sc/%rc\ %sq/%bq\ %hr\ %hs\ %{+Q}r

It will report a line such as the following one :

    Oct 12 20:47:30 haproxy[9643]: 127.0.0.1:43602 TLSv1:AES-SHA [12/Oct/2012:20:47:30.303] stick2~ stick2/s1 7/0/12/0/19 200 145 - - ---- 0/0/0/0/0 0/0 "GET /?t=0 HTTP/1.0"
This commit is contained in:
Willy Tarreau 2012-10-12 20:17:54 +02:00
parent 4f65356a22
commit ffc3fcd6da
5 changed files with 60 additions and 14 deletions

View File

@ -9716,7 +9716,7 @@ and the default TCP format is defined this way :
Please refer to the table below for currently defined variables :
+---+------+-----------------------------------------------+-------------+
| H | var | field name (8.2.2 and 8.2.3 for description) | type |
| R | var | field name (8.2.2 and 8.2.3 for description) | type |
+---+------+-----------------------------------------------+-------------+
| | %o | special variable, apply flags on all next var | |
+---+------+-----------------------------------------------+-------------+
@ -9733,8 +9733,8 @@ Please refer to the table below for currently defined variables :
| | %Sp | server_port | numeric |
| | %T | gmt_date_time | date |
| | %Tc | Tc | numeric |
| * | %Tq | Tq | numeric |
| * | %Tr | Tr | numeric |
| H | %Tq | Tq | numeric |
| H | %Tr | Tr | numeric |
| | %Ts | timestamp | numeric |
| | %Tt | Tt | numeric |
| | %Tw | Tw | numeric |
@ -9742,30 +9742,32 @@ Please refer to the table below for currently defined variables :
| | %b | backend_name | string |
| | %bc | beconn | numeric |
| | %bq | backend_queue | numeric |
| * | %cc | captured_request_cookie | string |
| * | %rt | http_request_counter | numeric |
| * | %cs | captured_response_cookie | string |
| H | %cc | captured_request_cookie | string |
| H | %rt | http_request_counter | numeric |
| H | %cs | captured_response_cookie | string |
| | %f | frontend_name | string |
| | %ft | frontend_name_transport ('~' suffix for SSL) | string |
| | %fc | feconn | numeric |
| * | %hr | captured_request_headers default style | string |
| * | %hrl | captured_request_headers CLF style | string list |
| * | %hs | captured_response_headers default style | string |
| * | %hsl | captured_response_headers CLF style | string list |
| H | %hr | captured_request_headers default style | string |
| H | %hrl | captured_request_headers CLF style | string list |
| H | %hs | captured_response_headers default style | string |
| H | %hsl | captured_response_headers CLF style | string list |
| | %ms | accept date milliseconds | numeric |
| | %pid | PID | numeric |
| * | %r | http_request | string |
| H | %r | http_request | string |
| | %rc | retries | numeric |
| | %s | server_name | string |
| | %sc | srv_conn | numeric |
| | %sq | srv_queue | numeric |
| * | %st | status_code | numeric |
| S | %sslc| ssl_ciphers (ex: AES-SHA) | string |
| S | %sslv| ssl_version (ex: TLSv1) | string |
| H | %st | status_code | numeric |
| | %t | date_time | date |
| | %ts | termination_state | string |
| * | %tsc | termination_state with cookie status | string |
| H | %tsc | termination_state with cookie status | string |
+---+------+-----------------------------------------------+-------------+
*: mode http only
R = Restrictions : H = mode http only ; S = SSL only
8.3. Advanced logging options
-----------------------------

View File

@ -35,6 +35,8 @@ void ssl_sock_free_certs(struct bind_conf *bind_conf);
int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf, struct proxy *px);
int ssl_sock_prepare_srv_ctx(struct server *srv, struct proxy *px);
void ssl_sock_free_all_ctx(struct bind_conf *bind_conf);
const char *ssl_sock_get_cipher_name(struct connection *conn);
const char *ssl_sock_get_proto_version(struct connection *conn);
#endif /* _PROTO_SSL_SOCK_H */

View File

@ -91,6 +91,8 @@ enum {
LOG_FMT_REQ,
LOG_FMT_HOSTNAME,
LOG_FMT_UNIQUEID,
LOG_FMT_SSL_CIPHER,
LOG_FMT_SSL_VERSION,
};
/* enum for parse_logformat */

View File

@ -113,6 +113,8 @@ static const struct logformat_type logformat_keywords[] = {
{ "rt", LOG_FMT_COUNTER, PR_MODE_HTTP, LW_REQ, NULL }, /* HTTP request counter */
{ "H", LOG_FMT_HOSTNAME, PR_MODE_TCP, LW_INIT, NULL }, /* Hostname */
{ "ID", LOG_FMT_UNIQUEID, PR_MODE_HTTP, LW_BYTES, NULL }, /* Unique ID */
{ "sslc", LOG_FMT_SSL_CIPHER, PR_MODE_TCP, LW_XPRT, NULL }, /* client-side SSL ciphers */
{ "sslv", LOG_FMT_SSL_VERSION, PR_MODE_TCP, LW_XPRT, NULL }, /* client-side SSL protocol version */
{ 0, 0, 0, 0, NULL }
};
@ -1001,7 +1003,29 @@ int build_logline(struct session *s, char *dst, size_t maxsize, struct list *lis
LOGCHAR('"');
last_isspace = 0;
break;
#ifdef USE_OPENSSL
case LOG_FMT_SSL_CIPHER: // %sslc
src = NULL;
if (s->listener->xprt == &ssl_sock)
src = ssl_sock_get_cipher_name(&s->si[0].conn);
ret = lf_text(tmplog, src, dst + maxsize - tmplog, tmp);
if (ret == NULL)
goto out;
tmplog = ret;
last_isspace = 0;
break;
case LOG_FMT_SSL_VERSION: // %sslv
src = NULL;
if (s->listener->xprt == &ssl_sock)
src = ssl_sock_get_proto_version(&s->si[0].conn);
ret = lf_text(tmplog, src, dst + maxsize - tmplog, tmp);
if (ret == NULL)
goto out;
tmplog = ret;
last_isspace = 0;
break;
#endif
case LOG_FMT_BACKEND: // %b
src = be->id;
ret = lf_text(tmplog, src, dst + maxsize - tmplog, tmp);

View File

@ -1053,6 +1053,22 @@ static void ssl_sock_shutw(struct connection *conn, int clean)
SSL_set_shutdown(conn->xprt_ctx, SSL_SENT_SHUTDOWN);
}
/* used for logging, may be changed for a sample fetch later */
const char *ssl_sock_get_cipher_name(struct connection *conn)
{
if (!conn->xprt && !conn->xprt_ctx)
return NULL;
return SSL_get_cipher_name(conn->xprt_ctx);
}
/* used for logging, may be changed for a sample fetch later */
const char *ssl_sock_get_proto_version(struct connection *conn)
{
if (!conn->xprt && !conn->xprt_ctx)
return NULL;
return SSL_get_version(conn->xprt_ctx);
}
/***** Below are some sample fetching functions for ACL/patterns *****/
/* boolean, returns true if client cert was present */