Updated on 2024-12-17 GMT+08:00

WAF Dashboard Templates

WAF keeps web services stable and secure. It examines all HTTP and HTTPS requests to detect and block the following attacks: Structured Query Language (SQL) injection, cross-site scripting (XSS), web shells, command and code injections, file inclusion, sensitive file access, third-party vulnerability exploits, Challenge Collapsar (CC) attacks, malicious crawlers, and cross-site request forgery (CSRF).

For Log Search and Analysis, the corresponding WAF dashboard templates are those for Viewing WAF Security Log Center and Viewing WAF Access Log Center.

Prerequisites

Viewing WAF Security Log Center

  1. Log in to the LTS console. In the navigation pane, choose Dashboards.
  2. Choose WAF dashboard templates under Dashboard Templates and click WAF security log center to view the chart details.

    • Attacked Websites. The associated query and analysis statement is:
      SELECT diff [ 1 ] AS  "VALUE", COALESCE ( diff [ 1 ]- diff [ 2 ], 0 ) AS "BEFORE" FROM
            (
            SELECT
            compare ( "DATA", 86400 ) AS diff 
            FROM
            ( SELECT count( DISTINCT "host" ) AS "DATA" FROM log 
            WHERE action != ''
            ))
    • Originating Countries. The associated query and analysis statement is:
      SELECT
            diff [ 1 ] AS 
            "VALUE"
            ,
            COALESCE ( diff [ 1 ]- diff [ 2 ], 0 ) AS "BEFORE" 
            FROM
            (
            SELECT
            compare ( "DATA", 86400 ) AS diff 
            FROM
            ( SELECT count( DISTINCT ip_to_country ( CASE WHEN sip = '-' THEN remote_ip ELSE sip END) ) AS "DATA" FROM log 
            WHERE action != ''
            ) 
            )
    • Web Attacks Intercepted. The associated query and analysis statement is:
      SELECT
            CASE
      
            WHEN
            diff [ 1 ] < 1000 THEN
            concat( cast( diff [ 1 ] AS VARCHAR ), ' attacks' ) 
            WHEN diff [ 1 ] < 1000 * 1000 THEN
            concat( cast( round( diff [ 1 ]/ 1000, 1 ) AS VARCHAR ), ' thousand attacks' ) 
            WHEN diff [ 1 ] < 1000000000 THEN
            concat( cast( round( diff [ 1 ]/ 1000000.0, 1 ) AS VARCHAR ), ' million attacks' ) 
            WHEN diff [ 1 ]/ 1000.0 < 1000000000 THEN
            concat( cast( round( diff [ 1 ]/ 1000.0 / 1000000, 1 ) AS VARCHAR ), ' billion attacks' ) ELSE concat( cast( round( diff [ 1 ]/ 1000.0 / 1000 / 1000 / 1000, 1 ) AS VARCHAR ), ' trillion attacks' ) 
            END AS 
            "value"
            ,
            CASE WHEN diff [ 2 ]= 0 THEN 0 ELSE round( diff [ 3 ]- 1, 2 ) END AS ratio 
            FROM
            ( SELECT compare ( "data", 86400 ) AS diff FROM ( SELECT count( 1 ) AS "data" FROM log WHERE action = '' ) )
    • CC Attacks Intercepted. The associated query and analysis statement is:
      SELECT
            CASE
      
            WHEN
            diff [ 1 ] < 1000 THEN
            concat( cast( diff [ 1 ] AS VARCHAR ), ' attacks' ) 
            WHEN diff [ 1 ] < 1000 * 1000 THEN
            concat( cast( round( diff [ 1 ]/ 1000, 1 ) AS VARCHAR ), ' thousand attacks' ) 
            WHEN diff [ 1 ] < 1000000000 THEN
            concat( cast( round( diff [ 1 ]/ 1000000.0, 1 ) AS VARCHAR ), ' million attacks' ) 
            WHEN diff [ 1 ]/ 1000.0 < 1000000000 THEN
            concat( cast( round( diff [ 1 ]/ 1000.0 / 1000000, 1 ) AS VARCHAR ), ' billion attacks' ) ELSE concat( cast( round( diff [ 1 ]/ 1000.0 / 1000 / 1000 / 1000, 1 ) AS VARCHAR ), ' trillion attacks' ) 
            END AS 
            "value"
            ,
            CASE WHEN diff [ 2 ]= 0 THEN 0 ELSE round( diff [ 3 ]- 1, 2 ) END AS ratio 
            FROM
            ( SELECT compare ( "data", 86400 ) AS diff FROM ( SELECT count( 1 ) AS "data" FROM log WHERE attack != 'default') )
    • Attacker UV. The associated query and analysis statement is:
      SELECT
            CASE
            WHEN
            diff [ 1 ] < 1000 THEN
            concat( cast( cast ( diff [ 1 ] AS INTEGER ) AS VARCHAR ), ' attackers' ) 
            WHEN diff [ 1 ] < 1000 * 1000 THEN
            concat( cast( round( diff [ 1 ]/ 1000, 1 ) AS VARCHAR ), ' thousand attackers' ) 
            WHEN diff [ 1 ] < 1000000000 THEN
            concat( cast( round( diff [ 1 ]/ 1000000.0, 1 ) AS VARCHAR ), ' million attackers' ) 
            WHEN diff [ 1 ]/ 1000.0 < 1000000000 THEN
            concat( cast( round( diff [ 1 ]/ 1000.0 / 1000000, 1 ) AS VARCHAR ), ' billion attackers' ) ELSE concat( cast( round( diff [ 1 ]/ 1000.0 / 1000 / 1000 / 1000, 1 ) AS VARCHAR ), ' trillion attackers' ) 
            END AS "value",
            CASE WHEN diff [ 2 ]= 0 THEN 0 ELSE round( diff [ 3 ]- 1, 2 ) END AS ratio 
            FROM
            (
            SELECT
            compare ( "data", 86400 ) AS diff 
            FROM
            ( SELECT count( DISTINCT CASE WHEN sip = '-' THEN remote_ip ELSE sip END ) AS "data" 
            FROM log
            ))
    • Total Attacks Intercepted. The associated query and analysis statement is:
      SELECT
            CASE
            WHEN
            diff [ 1 ] < 1000 THEN
            concat( cast( diff [ 1 ] AS VARCHAR ), ' attacks' ) 
            WHEN diff [ 1 ] < 1000 * 1000 THEN
            concat( cast( round( diff [ 1 ]/ 1000, 1 ) AS VARCHAR ), ' thousand attacks' ) 
            WHEN diff [ 1 ] < 1000000000 THEN
            concat( cast( round( diff [ 1 ]/ 1000000.0, 1 ) AS VARCHAR ), ' million attacks' ) 
            WHEN diff [ 1 ]/ 1000.0 < 1000000000 THEN
            concat( cast( round( diff [ 1 ]/ 1000.0 / 1000000, 1 ) AS VARCHAR ), ' billion attacks' ) ELSE concat( cast( round( diff [ 1 ]/ 1000.0 / 1000 / 1000 / 1000, 1 ) AS VARCHAR ), ' trillion attacks' ) 
            END AS 
            "value",
            CASE WHEN diff [ 2 ]= 0 THEN 0 ELSE round( diff [ 3 ]- 1, 2 ) END AS "ratio" 
            FROM
            (
            SELECT
            compare ( "data", 86400 ) AS diff 
            FROM
            ( SELECT count( 1 ) AS "data" FROM log WHERE action != '') 
            )
    • CC Attacks. The associated query and analysis statement is:
      SELECT
            ip_to_province (CASE WHEN sip = '-' THEN remote_ip ELSE sip END) AS province,
            count( 1 ) AS " attacks" 
            WHERE attack != 'default' and ip_to_country(CASE WHEN sip = '-' THEN remote_ip ELSE sip END) = 'China'
            GROUP BY
            province
    • Attack Types. The associated query and analysis statement is:
      SELECT time_format( MILLIS_TO_TIMESTAMP( TIMESTAMP_TO_MILLIS(__time) - MOD(TIMESTAMP_TO_MILLIS(__time), 3600)), 'HH:mm' ) AS dt, count( 1 ) AS cnt, CASE WHEN action = 'block' THEN 'Intercepted'  WHEN action = 'log' THEN 'Log only'  WHEN action = 'captcha' THEN 'Verification code' END AS attack FROM log WHERE action != '' GROUP BY TIMESTAMP_TO_MILLIS(__time) - MOD(TIMESTAMP_TO_MILLIS(__time), 3600), attack ORDER BY cnt DESC
    • Web Attacks. The associated query and analysis statement is:
      SELECT
            ip_to_province (
            CASE WHEN sip = '-' THEN remote_ip ELSE sip END) AS province,
            count( 1 ) AS " attacks" 
            WHERE action = 'block' and ip_to_country(CASE WHEN sip = '-' THEN remote_ip ELSE sip END) = 'China'
            GROUP BY
            province
    • CC Attacks(World). The associated query and analysis statement is:
      SELECT
            ip_to_country (CASE WHEN sip = '-' THEN remote_ip ELSE sip END) AS country,
            count( 1 ) AS " attacks" 
            WHERE attack != 'default'
            GROUP BY
            country
    • Web Attacks(World). The associated query and analysis statement is:
      SELECT
            ip_to_country (CASE WHEN sip = '-' THEN remote_ip ELSE sip END) AS country,
            count( 1 ) AS " attacks" 
            WHERE action = 'block'
            GROUP BY
            country

Viewing WAF Access Log Center

  1. Log in to the LTS console. In the navigation pane, choose Dashboards.
  2. Choose WAF dashboard templates under Dashboard Templates and click WAF access log center to view the chart details.

    • PV. The associated query and analysis statement is:
      SELECT       CASE               WHEN       diff [ 1 ] < 1000 THEN       concat( cast( diff [ 1 ] AS VARCHAR ), '' )        WHEN diff [ 1 ] < 1000 * 1000 THEN       concat( cast( round( diff [ 1 ]/ 1000, 1 ) AS VARCHAR ), ' thousand' )        WHEN diff [ 1 ] < 1000000000 THEN       concat( cast( round( diff [ 1 ]/ 1000000.0, 1 ) AS VARCHAR ), ' million' )        WHEN diff [ 1 ]/ 1000.0 < 1000000000 THEN       concat( cast( round( diff [ 1 ]/ 1000 / 1000000.0, 1 ) AS VARCHAR ), ' billion' ) ELSE concat( cast( round( diff [ 1 ]/ 1000.0 / 1000 / 1000 / 1000, 1 ) AS VARCHAR ), ' trillion' )        END AS        "VALUE"       ,       CASE WHEN diff [ 2 ]= 0 THEN 0 ELSE round( diff [ 3 ]- 1, 2 ) END AS ratio        FROM       (       SELECT       compare ( DATA, 86400 ) AS diff        FROM       ( SELECT count( 1 ) AS DATA FROM log )        )
    • UV. The associated query and analysis statement is:
      SELECT       CASE               WHEN       diff [ 1 ] < 1000 THEN       concat( cast( diff [ 1 ] AS VARCHAR ), '' )        WHEN diff [ 1 ] < 1000 * 1000 THEN       concat( cast( round( diff [ 1 ]/ 1000, 1 ) AS VARCHAR ), ' thousand' )        WHEN diff [ 1 ] < 1000000000 THEN       concat( cast( round( diff [ 1 ]/ 1000000.0, 1 ) AS VARCHAR ), ' million' )        WHEN diff [ 1 ]/ 1000.0 < 1000000000 THEN       concat( cast( round( diff [ 1 ]/ 1000 / 1000000.0, 1 ) AS VARCHAR ), ' billion' ) ELSE concat( cast( round( diff [ 1 ]/ 1000.0 / 1000 / 1000 / 1000, 1 ) AS VARCHAR ), ' trillion' )        END AS        "VALUE"       ,       CASE               WHEN diff [ 2 ]= 0 THEN       0 ELSE round( diff [ 3 ]- 1, 2 )       END AS ratio        FROM       (       SELECT       compare ( DATA, 86400 ) AS diff        FROM       ( SELECT count( DISTINCT CASE WHEN sip = '-' THEN remote_ip ELSE sip END ) AS "DATA" FROM log )        )
    • Incoming Traffic. The associated query and analysis statement is:
      SELECT       CASE               WHEN       diff [ 1 ] < 102 THEN       concat( cast( diff [ 1 ] AS VARCHAR ), ' B' )        WHEN diff [ 1 ] < 1024 * 1024 THEN       concat( cast( round( diff [ 1 ]/ 1024, 1 ) AS VARCHAR ), ' KB' )        WHEN diff [ 1 ] < 1024 * 1024 * 1024 THEN       concat( cast( round( diff [ 1 ]/ 1024.0 / 1024, 1 ) AS VARCHAR ), ' MB' )        WHEN diff [ 1 ]/ 1024.0 < 1024 * 1024 * 1024 THEN       concat( cast( round( diff [ 1 ]/ 1024.0 / 1024 / 1024, 1 ) AS VARCHAR ), ' GB' ) ELSE concat( cast( round( diff [ 1 ]/ 1024.0 / 1024 / 1024 / 1024, 1 ) AS VARCHAR ), ' TB' )        END AS        "VALUE"       ,       CASE               WHEN diff [ 2 ]= 0 THEN       0 ELSE round( diff [ 3 ]- 1, 2 )       END AS ratio        FROM       (       SELECT       compare ( "DATA", 86400 ) AS diff        FROM       ( SELECT COALESCE ( sum( request_length ), 0 ) AS "DATA" FROM log )        )
    • Peak In-Bandwidth. The associated query and analysis statement is:
      SELECT       CASE               WHEN       diff [ 1 ] < 102 THEN       concat( cast( round( diff [ 1 ], 2 ) AS VARCHAR ), ' B/s' )        WHEN diff [ 1 ] < 1024 * 1024  THEN       concat( cast( round( diff [ 1 ]/ 1024, 1 ) AS VARCHAR ), ' KB/s' )         WHEN diff [ 1 ] < 1024 * 1024 * 1024  THEN       concat( cast( round( diff [ 1 ]/ 1024.0 / 1024, 1 ) AS VARCHAR ), ' MB/s' )          WHEN diff [ 1 ]/ 1024.0 < 1024 * 1024 * 1024  THEN       concat( cast( round( diff [ 1 ]/ 1024.0 / 1024 / 1024, 1 ) AS VARCHAR ), ' GB/s' )  ELSE concat( cast( round( diff [ 1 ]/ 1024.0 / 1024 / 1024 / 1024, 1 ) AS VARCHAR ), ' TB/s' )        END AS        "VALUE"       ,       CASE               WHEN diff [ 2 ]= 0 THEN       0 ELSE round( diff [ 3 ]- 1, 2 )       END AS ratio        FROM       (       SELECT       compare ( "DATA", 86400 ) AS diff        FROM       (       SELECT COALESCE       ( max( "DATA" ), 0 ) AS "DATA"        FROM       ( SELECT TIME_FLOOR(__time,'PT1M') AS dt, sum( request_length )/ 60.0 AS "DATA" FROM log GROUP BY dt  LIMIT 10000 ))        )
    • Peak Out-Bandwidth. The associated query and analysis statement is:
      SELECT CASE WHEN diff [ 1 ] < 102 THEN concat( cast( round( diff [ 1 ], 2 ) AS VARCHAR ), ' B/s' )  WHEN diff [ 1 ] < 1024 * 1024 THEN concat( cast( round( diff [ 1 ]/ 1024, 1 ) AS VARCHAR ), ' KB/s' ) WHEN diff [ 1 ] < 1024 * 1024 * 1024 THEN concat( cast( round( diff [ 1 ]/ 1024.0 / 1024, 1 ) AS VARCHAR ), ' MB/s' ) WHEN diff [ 1 ]/ 1024.0 < 1024 * 1024 * 1024 THEN concat( cast( round( diff [ 1 ]/ 1024.0 / 1024 / 1024, 1 ) AS VARCHAR ), ' GB/s' ) ELSE concat( cast( round( diff [ 1 ]/ 1024.0 / 1024 / 1024 / 1024, 1 ) AS VARCHAR ), ' TB/s' ) END AS "value", case when diff [ 2 ]= 0 then 0 else round( diff [ 3 ]- 1, 2 ) END AS "ratio" FROM ( SELECT compare ( "DATA", 86400 ) AS diff FROM ( SELECT COALESCE ( max( bytes_out ), 0 ) AS "DATA" FROM ( SELECT time_ceil( __time,'PT1M') AS dt, sum( body_bytes_sent )/ 60.0 AS bytes_out FROM log GROUP BY dt LIMIT 10000 )))
    • Traffic Bandwidth Trend. The associated query and analysis statement is:
      SELECT       TIME_FORMAT( MILLIS_TO_TIMESTAMP( TIMESTAMP_TO_MILLIS(__time) - MOD(TIMESTAMP_TO_MILLIS(__time) , 600000)), 'HH:mm' ) AS dt,       round( sum( request_length )/ 1024.0 / 600, 2 ) AS "Incoming (KB/s)",       round( sum( body_bytes_sent )/ 1024.0 / 600, 2 ) AS "Outgoing (KB/s)"    where   request_length is not null    GROUP BY       TIMESTAMP_TO_MILLIS(__time) - MOD(TIMESTAMP_TO_MILLIS(__time) , 600000)       ORDER BY       dt        LIMIT 1000
    • PV/UV Trend. The associated query and analysis statement is:
      SELECT       TIME_FORMAT(MILLIS_TO_TIMESTAMP( TIMESTAMP_TO_MILLIS(__time) - MOD(TIMESTAMP_TO_MILLIS(__time) , 3600000)) , 'HH:mm' ) AS dt,       count( 1 ) AS PV,       APPROX_COUNT_DISTINCT (CASE WHEN sip = '-' THEN remote_ip ELSE sip       END) AS UV       FROM log       GROUP BY       TIMESTAMP_TO_MILLIS(__time) - MOD(TIMESTAMP_TO_MILLIS(__time) , 3600000)        ORDER BY       dt        LIMIT 1000
    • Visit Statuses. The associated query and analysis statement is:
      SELECT       TIME_FORMAT(MILLIS_TO_TIMESTAMP( TIMESTAMP_TO_MILLIS(__time) - MOD(TIMESTAMP_TO_MILLIS(__time) , 3600000)) , 'HH:mm' ) AS dt,       count( 1 ) AS cnt,       concat( cast( "response_code" / 100 AS VARCHAR ), 'XX' ) AS "status"        GROUP BY       TIMESTAMP_TO_MILLIS(__time) - MOD(TIMESTAMP_TO_MILLIS(__time) , 3600000) ,       "response_code" / 100        ORDER BY       dt DESC        LIMIT 10000
    • Source. The associated query and analysis statement is:
      SELECT       ip_to_province (CASE WHEN sip = '-' THEN remote_ip ELSE sip END) AS country,       count( 1 ) AS "Visits"    where ip_to_country(CASE WHEN sip = '-' THEN remote_ip ELSE sip END) = 'China'    GROUP BY       country
    • Incoming Traffic Source (China). The associated query and analysis statement is:
      SELECT       ip_to_province (CASE WHEN sip = '-' THEN remote_ip ELSE sip END) AS region,       round( sum( request_length )/ 1024.0 / 1024, 4 ) AS "Incoming (MB)"  where ip_to_country(CASE WHEN sip = '-' THEN remote_ip ELSE sip END) = 'China'     GROUP BY       region
    • Incoming Traffic Source (World). The associated query and analysis statement is:
      SELECT       ip_to_country (CASE WHEN sip = '-' THEN remote_ip ELSE sip END) AS region,       round( sum( request_length )/ 1024.0 / 1024, 4 ) AS "Incoming (MB)"   where   request_length is not null     GROUP BY       region 
    • Source Network Providers. The associated query and analysis statement is:
      SELECT       ip_to_provider (CASE WHEN sip = '-' THEN remote_ip ELSE sip END) AS provider,       round( sum( request_length )/ 1024.0 / 1024.0, 3 ) AS mb_in       GROUP BY       provider        HAVING       ip_to_provider (CASE WHEN sip = '-' THEN remote_ip ELSE sip END) != '*'        ORDER BY       mb_in DESC        LIMIT 10
    • Domain Names. The associated query and analysis statement is:
      SELECT        http_host,       count( 1 ) AS "Visits"        GROUP BY       http_host        ORDER BY       "Visits" DESC        LIMIT 30
    • URLs with the Slowest Response. The associated query and analysis statement is:
      SELECT http_host AS "Website",url_extract_path (COALESCE ( url, '/' )) AS URL,sum( request_time )/ count( 1 ) AS "Response Duration (ms)",count( 1 ) AS "Visits" GROUP BY http_host, url ORDER BY "Response Duration (ms)" DESC  LIMIT 100
    • Clients with the Most Visits. The associated query and analysis statement is:
      SELECT  ip AS "Client",  client AS "Network",  concat(  cast( (CASE WHEN pv IS NULL THEN 0 ELSE pv END) AS VARCHAR ),  ' (',  cast( case when  head_pv  = 'null'  then 0 else (case when head_pv > 0 then head_pv else 0 end) end AS VARCHAR ),  '/',  cast( case when  get_pv  = 'null'  then 0 else (case when get_pv > 0 then get_pv else 0 end) end AS VARCHAR ),  '/',  cast( case when  put_pv  = 'null'  then 0 else (case when put_pv > 0 then put_pv else 0 end) end AS VARCHAR ),  '/',  cast( case when  post_pv  = 'null'  then 0 else (case when post_pv > 0 then post_pv else 0 end) end AS VARCHAR ),  '/',  cast( case when  delete_pv  = 'null'  then 0 else (case when delete_pv > 0 then delete_pv else 0 end) end AS VARCHAR ),  '/',  ')'   ) AS "PV(Head, Get, Put, Post, Delete)",  error_count AS "Wrong Visits"   FROM  (  SELECT  ip,  client,  sum( CASE WHEN "method" = 'PUT' AND "status" < 400 THEN pv ELSE 0 END ) AS put_pv,  sum( CASE WHEN "method" = 'GET' AND "status" < 400 THEN pv ELSE 0 END ) AS get_pv,  sum( CASE WHEN "method" = 'POST' AND "status" < 400 THEN pv ELSE 0 END ) AS post_pv,  sum( CASE WHEN "method" = 'DELETE' AND "status" < 400 THEN pv ELSE 0 END ) AS delete_pv,  sum( CASE WHEN "method" = 'HEAD' AND "status" < 400 THEN pv ELSE 0 END ) AS head_pv,  sum( throughput ) AS throughput,  sum( pv ) AS pv,  sum( CASE WHEN "status" < 400 THEN 1 ELSE 0 END ) AS error_count   FROM  (  SELECT  CASE     WHEN  sip = '-' THEN  remote_ip ELSE sip   END AS ip,  "method",  CASE     WHEN ip_to_country ( CASE WHEN sip = '-' THEN remote_ip ELSE sip END )= 'Shanghai' THEN  'Shanghai, China'   WHEN ip_to_province ( CASE WHEN sip = '-' THEN remote_ip ELSE sip END )= '*' THEN  'Unknown IP'   WHEN ip_to_provider ( CASE WHEN sip = '-' THEN remote_ip ELSE sip END )= 'Private IP' THEN  'Private IP' ELSE concat(  ip_to_country ( CASE WHEN sip = '-' THEN remote_ip ELSE sip END ),  '/',  ip_to_province ( CASE WHEN sip = '-' THEN remote_ip ELSE sip END ),  '/',  CASE     WHEN ip_to_city ( CASE WHEN sip = '-' THEN remote_ip ELSE sip END )= '*' THEN  ' ' ELSE ip_to_city ( CASE WHEN sip = '-' THEN remote_ip ELSE sip END )   END,  ' ',  ip_to_provider ( CASE WHEN sip = '-' THEN remote_ip ELSE sip END ))   END AS client,  sum( CASE WHEN "response_code" < 400 THEN 1 ELSE 0 END ) AS pv,  round( sum( request_length )/ 1024.0 / 1024, 1 ) AS throughput,  "response_code" AS "status"   FROM     log  GROUP BY  ip,  client,  "method",  "response_code"   ORDER BY  pv DESC,  client,  "method"   LIMIT 1000  )   GROUP BY  ip,  client   ORDER BY  pv DESC   )   LIMIT 100