endlessh_scoreboard.sh 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. #!/bin/bash
  2. ## "A bash and awk script for generating a endless scoreboard web page.
  3. ## written by demure
  4. ## https://notabug.org/demure/scripts/src/master/endlessh_scoreboard.sh
  5. ##
  6. ## 2019-04-03: Initial Version.
  7. ## Dependencies:
  8. ## gawk
  9. ## bc
  10. ## geoiplookup
  11. ## sha512sum
  12. ## Initialize
  13. declare -a ARRAY
  14. declare Last
  15. declare LastHost
  16. declare HostCount
  17. declare MaxTime
  18. declare MinTime
  19. declare SumTime
  20. declare x
  21. declare y
  22. declare Geo
  23. ## Parse endlessh log, keep last 7 days, output host and time spent, sort by host, store in array
  24. #ARRAY=($(TZ=UTC awk -v CUTOFF=$(date --date="-7 days" +%s) '/CLOSE/ {match($0,/^(.*T.*Z).*host=([0-9a-f:\.]+).*time=([0-9\.]+)/,m); command="date -d" m[1] " +%s"; command | getline m[1]; close(command)}{if(m[1]>CUTOFF){print m[2],m[3]}}' /var/log/endlessh.log | sort -k1))
  25. ## Doesn't account for ipv6
  26. ARRAY=($(TZ=UTC awk -v CUTOFF=$(date --date="-7 days" +%s) '/CLOSE/ {match($0,/^(.*T.*Z).*host=::ffff:([0-9a-f:\.]+).*time=([0-9\.]+)/,m); command="date -d" m[1] " +%s"; command | getline m[1]; close(command)}{if(m[1]>CUTOFF){print m[2],m[3]}}' /var/log/endlessh.log 2>/dev/null | sort -k1))
  27. ## Get the last array element position
  28. Last="$(echo "${!ARRAY[@]}" | awk '{print $NF}')"
  29. ## Print HTML Beginning
  30. HTML1=$(cat <<-END
  31. <html><center><body>
  32. <style> table {border-spacing: 0; border: 1px solid black; font-family: monospace;} th {cursor: pointer;} th, td {border: 1px solid black; border-collapse: collapse;}</style>
  33. <h2>Tar Pit Score Board</h2>
  34. <p>Here is a little Score Board of <strike>ssh</strike> player attempts from the last seven days. <BR>To "keep things fair", players who try too many times are given a time out. <BR>All times are in seconds, and hosts are hashed for 'privacy'. <BR> Number colmnus may be sorted by clicking.</p>
  35. <table id="myTable">
  36. <tr><th onclick="sortTable(0)">Host (hashed)</th><th onclick="sortTable(1)">Geo Location</th><th onclick="sortTable(2)">Attempts</th><th onclick="sortTable(3)">Shortest Conn</th><th onclick="sortTable(4)">Longest Conn</th><th onclick="sortTable(5)">Average Conn</th><th onclick="sortTable(6)">Total Conn</th></tr>
  37. END
  38. )
  39. echo "${HTML1}"
  40. ## iterate over array
  41. for i in "${!ARRAY[@]}"; do
  42. x="${ARRAY[i]}" ## Hold current host
  43. y="${ARRAY[$((i+1))]}" ## Hold current time spent
  44. ## Act on even, since the array length is doubled
  45. if [[ $((i%2)) -eq 0 ]]; then
  46. if [ "${x}" == "${LastHost}" ]; then
  47. HostCount=$(($HostCount+1))
  48. #if [ "${y}" > "${MaxTime}" ]; then
  49. if (( $(echo "${y} > ${MaxTime}" | bc) )); then
  50. #echo "$MaxTime -> $y"
  51. MaxTime="${y}"
  52. fi
  53. if (( $(echo "${y} < ${MaxTime}" | bc) )); then
  54. #if [ "${y}" < "${MinTime}" ]; then
  55. MinTime="${y}"
  56. fi
  57. SumTime=$(echo "${SumTime} + ${y}" | bc)
  58. else
  59. if [ ! -z ${LastHost} ]; then
  60. Geo="$(geoiplookup ${LastHost} | awk '/Country/ {match($0, /Geo.*: [A-Z]+, (.*)/, m); print m[1]}')"
  61. #Geo="$(geoiplookup ${LastHost} | awk '/Country/ {match($0, /Geo.*: (.*)/, m); print m[1]}')"
  62. #echo "Host $(echo ${LastHost} | sha512sum | cut -c1-16), Geo ${Geo}, Times ${HostCount}, Min ${MinTime}, Max ${MaxTime}, Average $(echo "${SumTime} / ${HostCount}" | bc), Total ${SumTime}"
  63. echo "<tr><td>$(echo ${LastHost} | sha512sum | cut -c1-16)</td><td>${Geo}</td><td align=right>${HostCount}</td><td align=right>${MinTime}</td><td align=right>${MaxTime}</td><td align=right>$(echo "${SumTime} / ${HostCount}" | bc)</td><td align=right>${SumTime}</td></tr>"
  64. fi
  65. ## Make new tracking
  66. LastHost="${x}"
  67. HostCount=1
  68. MaxTime="${y}"
  69. MinTime="${y}"
  70. SumTime="${y}"
  71. Geo=""
  72. fi
  73. fi
  74. done
  75. ## TODO: Make sure last round printed
  76. ## TODO: Add "banned players" section using f2b jail ban list
  77. ## Print HTML end
  78. HTML3=$(cat <<-END
  79. </table>
  80. <p>This page is brought to you by bash, gawk, and geoiplookup.</p>
  81. <p><b>Last updated $(date -u)</b></p>
  82. <script>
  83. function sortTable(n) {
  84. var table, rows, switching, i, x, y, shouldSwitch, dir, switchcount = 0;
  85. table = document.getElementById("myTable");
  86. switching = true;
  87. // Set the sorting direction to ascending:
  88. dir = "asc";
  89. /* Make a loop that will continue until
  90. no switching has been done: */
  91. while (switching) {
  92. // Start by saying: no switching is done:
  93. switching = false;
  94. rows = table.rows;
  95. /* Loop through all table rows (except the
  96. first, which contains table headers): */
  97. for (i = 1; i < (rows.length - 1); i++) {
  98. // Start by saying there should be no switching:
  99. shouldSwitch = false;
  100. /* Get the two elements you want to compare,
  101. one from current row and one from the next: */
  102. x = rows[i].getElementsByTagName("TD")[n];
  103. y = rows[i + 1].getElementsByTagName("TD")[n];
  104. /* Check if the two rows should switch place,
  105. based on the direction, asc or desc: */
  106. if (dir == "asc") {
  107. if (Number(x.innerHTML) < Number(y.innerHTML)) {
  108. // If so, mark as a switch and break the loop:
  109. shouldSwitch = true;
  110. break;
  111. }
  112. } else if (dir == "desc") {
  113. if (Number(x.innerHTML) > Number(y.innerHTML)) {
  114. // If so, mark as a switch and break the loop:
  115. shouldSwitch = true;
  116. break;
  117. }
  118. }
  119. }
  120. if (shouldSwitch) {
  121. /* If a switch has been marked, make the switch
  122. and mark that a switch has been done: */
  123. rows[i].parentNode.insertBefore(rows[i + 1], rows[i]);
  124. switching = true;
  125. // Each time a switch is done, increase this count by 1:
  126. switchcount ++;
  127. } else {
  128. /* If no switching has been done AND the direction is "asc",
  129. set the direction to "desc" and run the while loop again. */
  130. if (switchcount == 0 && dir == "asc") {
  131. dir = "desc";
  132. switching = true;
  133. }
  134. }
  135. }
  136. }
  137. </script>
  138. </body></center></html>
  139. END
  140. )
  141. echo "${HTML3}"
  142. #echo "--------------------" ## DEBUG