]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: log: report SSL ciphers and version in logs using logformat %sslc/%sslv
authorWilly Tarreau <w@1wt.eu>
Fri, 12 Oct 2012 18:17:54 +0000 (20:17 +0200)
committerWilly Tarreau <w@1wt.eu>
Fri, 12 Oct 2012 18:48:51 +0000 (20:48 +0200)
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"

doc/configuration.txt
include/proto/ssl_sock.h
include/types/log.h
src/log.c
src/ssl_sock.c

index aee1d904b0737850666fa8cf86614fa9995e130d..208c43221e9e24400491b032b0b4846231379997 100644 (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
 -----------------------------
index 8246b35630ed3c4eb41495723b2fe51b6b71b478..5f83dbc70d6cce0f5a896c952651e98c98ae6da0 100644 (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 */
 
index 70dc9faf5a2f2fdd46e251afb44d9df1df573e89..8c28310d044c8db39423a91dbf448776dc6a9659 100644 (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 */
index 15ba27bfac7d0d6475b66d7ace312ff427c3a23a..130c378ca7e336f2ed1a8999c3a003332a9e0f2f 100644 (file)
--- a/src/log.c
+++ b/src/log.c
@@ -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);
index 6c9eae4fe6b0c795e08d57a6e9b31ce23303b641..9aed915711b485e3636643e5582cfd22ef93427c 100644 (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 */