Цель

Мы собираемся изменить этот вывод (сгенерированный из сценария на основе iptables(8) ниже, работающего в Ubuntu 18.04, который анализирует оригинальный, необработанный, анонимный вывод iptables -nvL с одного из наших серверов):

Chain INPUT (policy DROP 2525 packets, 130K bytes)
target                      prot        opt      in           out   source          destination
ufw-before-logging-input    all         --       *            *     0.0.0.0/0       0.0.0.0/0
ufw-before-input            all         --       *            *     0.0.0.0/0       0.0.0.0/0
ufw-after-input             all         --       *            *     0.0.0.0/0       0.0.0.0/0
ufw-after-logging-input     all         --       *            *     0.0.0.0/0       0.0.0.0/0
ufw-reject-input            all         --       *            *     0.0.0.0/0       0.0.0.0/0
ufw-track-input             all         --       *            *     0.0.0.0/0       0.0.0.0/0

... чтобы быть более узким, с меньшим количеством ненужных пробелов между столбцами:

Chain INPUT (policy DROP 2525 packets, 130K bytes)
target                      prot   opt   in   out   source          destination
ufw-before-logging-input    all    --    *    *     0.0.0.0/0       0.0.0.0/0
ufw-before-input            all    --    *    *     0.0.0.0/0       0.0.0.0/0
ufw-after-input             all    --    *    *     0.0.0.0/0       0.0.0.0/0
ufw-after-logging-input     all    --    *    *     0.0.0.0/0       0.0.0.0/0
ufw-reject-input            all    --    *    *     0.0.0.0/0       0.0.0.0/0
ufw-track-input             all    --    *    *     0.0.0.0/0       0.0.0.0/0

Мы бы предпочли bash сценарий, где мы можем более легко (чем в сценарий ниже), со временем настройте ширину интервала каждого столбца на для каждого столбца . Мы еще не смогли получить awk основанные на таких вещах, как sprintf, gsub или это механизм делать то, что мы хотим.

Не - bash решения, которые выполняют аналогичные / одинаковые действия, также могут работать.

Более сложный ввод

Этот раздел iptables -nvL вывода (не разбирается сценарием, приведенным ниже) более сложный, из-за самого правого столбца свободной формы, единственный столбец с пробелами в содержимом:

Chain ufw-after-input (1 references)
 pkts bytes target     prot opt in     out     source               destination         
    1    78 ufw-skip-to-policy-input  udp  --  *      *       0.0.0.0/0            0.0.0.0/0            udp dpt:137
    0     0 ufw-skip-to-policy-input  udp  --  *      *       0.0.0.0/0            0.0.0.0/0            udp dpt:138
    0     0 ufw-skip-to-policy-input  tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:139
    5   260 ufw-skip-to-policy-input  tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:445
    0     0 ufw-skip-to-policy-input  udp  --  *      *       0.0.0.0/0            0.0.0.0/0            udp dpt:67
    0     0 ufw-skip-to-policy-input  udp  --  *      *       0.0.0.0/0            0.0.0.0/0            udp dpt:68
    0     0 ufw-skip-to-policy-input  all  --  *      *       xxx.xxx.xxx.xxx/yy   xxx.xxx.xxx.xxx/yy   ADDRTYPE match dst-type BROADCAST

Chain ufw-after-logging-forward (1 references)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 LOG        all  --  *      *       xxx.xxx.xxx.xxx/yy   xxx.xxx.xxx.xxx/yy   limit: avg 3/min burst 10 LOG flags 0 level 4 prefix "[UFW BLOCK] "

Хорошее преобразование вышеупомянутого выглядит следующим образом:

Chain ufw-after-input (1 references)
target                    prot opt in  out  source              destination
ufw-skip-to-policy-input  udp  --  *   *    0.0.0.0/0           0.0.0.0/0           udp dpt:137
ufw-skip-to-policy-input  udp  --  *   *    0.0.0.0/0           0.0.0.0/0           udp dpt:138
ufw-skip-to-policy-input  tcp  --  *   *    0.0.0.0/0           0.0.0.0/0           tcp dpt:139
ufw-skip-to-policy-input  tcp  --  *   *    0.0.0.0/0           0.0.0.0/0           tcp dpt:445
ufw-skip-to-policy-input  udp  --  *   *    0.0.0.0/0           0.0.0.0/0           udp dpt:67
ufw-skip-to-policy-input  udp  --  *   *    0.0.0.0/0           0.0.0.0/0           udp dpt:68
ufw-skip-to-policy-input  all  --  *   *    xxx.xxx.xxx.xxx/yy  xxx.xxx.xxx.xxx/yy  ADDRTYPE match dst-type BROADCAST

Chain ufw-after-logging-forward (1 references)
target                    prot opt in  out  source              destination         
LOG                       all  --  *   *    xxx.xxx.xxx.xxx/yy  xxx.xxx.xxx.xxx/yy  limit: avg 3/min burst 10 LOG flags 0 level 4 prefix "[UFW BLOCK] "

Оригинальный iptables скрипт bash

Скрипт, который генерирует первую версию вывода выше; это возможно не элегантный хак

#!/usr/bin/env bash
#
# Pretty-print 'iptables -nvL' output.
# 1. remove the 'pkts' and 'bytes' columns
# 2. make column-aligned, table-based output per
#    https://gist.github.com/Airdawg5571/1a8c49ca5dd97af55ab9
# 3. attempt to make narrower, removing unnecessary whitespace
#    between columns, to save previous display-screen realestate
#
iptables -nvL                                                      | \
    # remove the 'pkts' and 'bytes' columns
    awk '{ if ($1 != "Chain") { $1=""; $2=""; print } else print}' | \
    # make tabular (table) output
    column -t                                                      | \
    sed 's/^Chain/\n&/g'                                           | \
    sed '/^Chain/ s/[ \t]\{1,\}/ /g'                               | \
    sed '/^[0-9]/ s/[ \t]\{1,\}/ /10g'                             | \
    # reduce the unnecessary whitespace after 'prot' column
    perl -pe 's|^(?!Chain)([^\s]+\s+\w+)\s+|\1  \t|'               | \
    # arbitrarily truncate line length
    cut -c -120
1
Johnny Utahh 17 Май 2020 в 03:38

3 ответа

Учитывая ваш обновленный вопрос и комментарии (и использование cat file вместо iptables -nvL, которого у меня нет в моей системе) ::

$ cat tst.awk
BEGIN { nf = split("0 0 27 7 6 5 5 20 20",w) }
NF && !/^Chain/ {
    for (i=3; i<=nf; i++) {
        printf "%-*s", w[i], $i
    }
    sub("^([[:space:]]*[^[:space:]]+){"nf"}[[:space:]]*","")
}
{ print }

.

$ cat file | awk -f tst.awk
Chain ufw-after-input (1 references)
target                     prot   opt   in   out  source              destination
ufw-skip-to-policy-input   udp    --    *    *    0.0.0.0/0           0.0.0.0/0           udp dpt:137
ufw-skip-to-policy-input   udp    --    *    *    0.0.0.0/0           0.0.0.0/0           udp dpt:138
ufw-skip-to-policy-input   tcp    --    *    *    0.0.0.0/0           0.0.0.0/0           tcp dpt:139
ufw-skip-to-policy-input   tcp    --    *    *    0.0.0.0/0           0.0.0.0/0           tcp dpt:445
ufw-skip-to-policy-input   udp    --    *    *    0.0.0.0/0           0.0.0.0/0           udp dpt:67
ufw-skip-to-policy-input   udp    --    *    *    0.0.0.0/0           0.0.0.0/0           udp dpt:68
ufw-skip-to-policy-input   all    --    *    *    xxx.xxx.xxx.xxx/yy  xxx.xxx.xxx.xxx/yy  ADDRTYPE match dst-type BROADCAST

Chain ufw-after-logging-forward (1 references)
target                     prot   opt   in   out  source              destination
LOG                        all    --    *    *    xxx.xxx.xxx.xxx/yy  xxx.xxx.xxx.xxx/yy  limit: avg 3/min burst 10 LOG flags 0 level 4 prefix "[UFW BLOCK] "

При работе с образцом входных данных, предоставленным на https://gist.githubusercontent.com/johnf65/17/2622529181818fh18htx18 raw Я получаю следующее, в котором я не вижу никаких проблем, поэтому, если, как вы говорите, этот вывод не верен, вы должны указать, где проблема:

$ awk -f tst.awk file
Chain INPUT (policy DROP 35 packets, 1771 bytes)
target                     prot   opt   in   out  source              destination
ufw-before-logging-input   all    --    *    *    0.0.0.0/0           0.0.0.0/0
ufw-before-input           all    --    *    *    0.0.0.0/0           0.0.0.0/0
ufw-after-input            all    --    *    *    0.0.0.0/0           0.0.0.0/0
ufw-after-logging-input    all    --    *    *    0.0.0.0/0           0.0.0.0/0
ufw-reject-input           all    --    *    *    0.0.0.0/0           0.0.0.0/0
ufw-track-input            all    --    *    *    0.0.0.0/0           0.0.0.0/0

Chain FORWARD (policy DROP 0 packets, 0 bytes)
target                     prot   opt   in   out  source              destination
ufw-before-logging-forward all    --    *    *    0.0.0.0/0           0.0.0.0/0
ufw-before-forward         all    --    *    *    0.0.0.0/0           0.0.0.0/0
ufw-after-forward          all    --    *    *    0.0.0.0/0           0.0.0.0/0
ufw-after-logging-forward  all    --    *    *    0.0.0.0/0           0.0.0.0/0
ufw-reject-forward         all    --    *    *    0.0.0.0/0           0.0.0.0/0
ufw-track-forward          all    --    *    *    0.0.0.0/0           0.0.0.0/0

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
target                     prot   opt   in   out  source              destination
ufw-before-logging-output  all    --    *    *    0.0.0.0/0           0.0.0.0/0
ufw-before-output          all    --    *    *    0.0.0.0/0           0.0.0.0/0
ufw-after-output           all    --    *    *    0.0.0.0/0           0.0.0.0/0
ufw-after-logging-output   all    --    *    *    0.0.0.0/0           0.0.0.0/0
ufw-reject-output          all    --    *    *    0.0.0.0/0           0.0.0.0/0
ufw-track-output           all    --    *    *    0.0.0.0/0           0.0.0.0/0

Chain ufw-after-forward (1 references)
target                     prot   opt   in   out  source              destination

Chain ufw-after-input (1 references)
target                     prot   opt   in   out  source              destination
ufw-skip-to-policy-input   udp    --    *    *    0.0.0.0/0           0.0.0.0/0           udp dpt:137
ufw-skip-to-policy-input   udp    --    *    *    0.0.0.0/0           0.0.0.0/0           udp dpt:138
ufw-skip-to-policy-input   tcp    --    *    *    0.0.0.0/0           0.0.0.0/0           tcp dpt:139
ufw-skip-to-policy-input   tcp    --    *    *    0.0.0.0/0           0.0.0.0/0           tcp dpt:445
ufw-skip-to-policy-input   udp    --    *    *    0.0.0.0/0           0.0.0.0/0           udp dpt:67
ufw-skip-to-policy-input   udp    --    *    *    0.0.0.0/0           0.0.0.0/0           udp dpt:68
ufw-skip-to-policy-input   all    --    *    *    0.0.0.0/0           0.0.0.0/0           ADDRTYPE match dst-type BROADCAST

Chain ufw-after-logging-forward (1 references)
target                     prot   opt   in   out  source              destination
LOG                        all    --    *    *    0.0.0.0/0           0.0.0.0/0           limit: avg 3/min burst 10 LOG flags 0 level 4 prefix "[UFW BLOCK] "

Chain ufw-after-logging-input (1 references)
target                     prot   opt   in   out  source              destination
LOG                        all    --    *    *    0.0.0.0/0           0.0.0.0/0           limit: avg 3/min burst 10 LOG flags 0 level 4 prefix "[UFW BLOCK] "

Chain ufw-after-logging-output (1 references)
target                     prot   opt   in   out  source              destination

Chain ufw-after-output (1 references)
target                     prot   opt   in   out  source              destination

Chain ufw-before-forward (1 references)
target                     prot   opt   in   out  source              destination
ACCEPT                     all    --    *    *    0.0.0.0/0           0.0.0.0/0           ctstate RELATED,ESTABLISHED
ACCEPT                     all    --    wg0  *    0.0.0.0/0           0.0.0.0/0
ACCEPT                     icmp   --    *    *    0.0.0.0/0           0.0.0.0/0           icmptype 3
ACCEPT                     icmp   --    *    *    0.0.0.0/0           0.0.0.0/0           icmptype 11
ACCEPT                     icmp   --    *    *    0.0.0.0/0           0.0.0.0/0           icmptype 12
ACCEPT                     icmp   --    *    *    0.0.0.0/0           0.0.0.0/0           icmptype 8
ufw-user-forward           all    --    *    *    0.0.0.0/0           0.0.0.0/0

Chain ufw-before-input (1 references)
target                     prot   opt   in   out  source              destination
ACCEPT                     all    --    lo   *    0.0.0.0/0           0.0.0.0/0
ACCEPT                     all    --    *    *    0.0.0.0/0           0.0.0.0/0           ctstate RELATED,ESTABLISHED
ufw-logging-deny           all    --    *    *    0.0.0.0/0           0.0.0.0/0           ctstate INVALID
DROP                       all    --    *    *    0.0.0.0/0           0.0.0.0/0           ctstate INVALID
ACCEPT                     icmp   --    *    *    xxx.xxx.xxx.xxx/yy  0.0.0.0/0           icmptype 8
ACCEPT                     icmp   --    *    *    xxx.xxx.xxx.xxx/yy  0.0.0.0/0           icmptype 8
ACCEPT                     icmp   --    *    *    xxx.xxx.xxx.xxx/yy  0.0.0.0/0           icmptype 8
DROP                       icmp   --    *    *    0.0.0.0/0           0.0.0.0/0           icmptype 3
DROP                       icmp   --    *    *    0.0.0.0/0           0.0.0.0/0           icmptype 11
DROP                       icmp   --    *    *    0.0.0.0/0           0.0.0.0/0           icmptype 12
DROP                       icmp   --    *    *    0.0.0.0/0           0.0.0.0/0           icmptype 8
DROP                       udp    --    *    *    0.0.0.0/0           0.0.0.0/0           udp spt:67 dpt:68
ufw-not-local              all    --    *    *    0.0.0.0/0           0.0.0.0/0
DROP                       udp    --    *    *    0.0.0.0/0           224.0.0.251         udp dpt:5353
DROP                       udp    --    *    *    0.0.0.0/0           239.255.255.250     udp dpt:1900
ufw-user-input             all    --    *    *    0.0.0.0/0           0.0.0.0/0

Chain ufw-before-logging-forward (1 references)
target                     prot   opt   in   out  source              destination

Chain ufw-before-logging-input (1 references)
target                     prot   opt   in   out  source              destination

Chain ufw-before-logging-output (1 references)
target                     prot   opt   in   out  source              destination

Chain ufw-before-output (1 references)
target                     prot   opt   in   out  source              destination
ACCEPT                     all    --    *    lo   0.0.0.0/0           0.0.0.0/0
ACCEPT                     all    --    *    *    0.0.0.0/0           0.0.0.0/0           ctstate RELATED,ESTABLISHED
1
Ed Morton 17 Май 2020 в 19:38

Использование утилиты Стива Кинцлера align util :

align -e '!/^Chain/' -g 4 < file.txt

Вывод (-e не позволяет выровнять первую строку, а -g устанавливает минимум желоб до 4 мест):

Chain INPUT (policy DROP 2525 packets, 130K bytes)
target                      prot    opt    in    out    source       destination
ufw-before-logging-input    all     --     *     *      0.0.0.0/0    0.0.0.0/0
ufw-before-input            all     --     *     *      0.0.0.0/0    0.0.0.0/0
ufw-after-input             all     --     *     *      0.0.0.0/0    0.0.0.0/0
ufw-after-logging-input     all     --     *     *      0.0.0.0/0    0.0.0.0/0
ufw-reject-input            all     --     *     *      0.0.0.0/0    0.0.0.0/0
ufw-track-input             all     --     *     *      0.0.0.0/0    0.0.0.0/0

Для каждого столбца форматирование : переключатель -a контролирует стиль формата, но не может устанавливать ширину отдельных столбцов. Пример - r, возможно, выровняйте первый столбец, используйте выравнивание efault d для следующих четырех, затем r, выровняйте остальные:

align -e '!/^Chain/' -a r4dr < file.txt 

Выход:

Chain INPUT (policy DROP 2525 packets, 130K bytes)
                  target prot opt in out    source destination
ufw-before-logging-input all  --  *  *   0.0.0.0/0   0.0.0.0/0
        ufw-before-input all  --  *  *   0.0.0.0/0   0.0.0.0/0
         ufw-after-input all  --  *  *   0.0.0.0/0   0.0.0.0/0
 ufw-after-logging-input all  --  *  *   0.0.0.0/0   0.0.0.0/0
        ufw-reject-input all  --  *  *   0.0.0.0/0   0.0.0.0/0
         ufw-track-input all  --  *  *   0.0.0.0/0   0.0.0.0/0
1
Johnny Utahh 17 Май 2020 в 20:02

Это работает:

#!/usr/bin/env bash

#
# Pretty-print iptables(8) output.
#
# source:
# https://gitlab.com/johnnyutahh/swmisc/-/blob/master/sysadmin/networking/iptables/iptables-list-pretty.sh
#
# (The following script was Ubuntu-18.04 tested on 2020-05-17.)
#

# Derivered from
# https://www.reddit.com/r/bash/comments/gl61yb/selectively_remove_unnecessary_column_whitespace/fqw19tv

# Adjust these values to resize column widths
column_widths=(0 0 27 5 4 8 8 17 17)

iptables_align()
{
  while read line; do
    if [[ $line =~ Chain ]]; then
      echo "$line"
    else
      line=${line//\*/\\\*}
      array=($line)
      for n in {2..8}; do
        w=${column_widths[$n]}
         printf "%-${w}s" "${array[$n]}"
      done
      lastcol_with_spaces_in_content=("${array[@]:9}")
      printf "%s" "${lastcol_with_spaces_in_content[*]}"
      echo
    fi
  done
}

iptables -nvL | iptables_align | sed -s 's|\\\*|* |g' | less

Источник:

https://gitlab.com/johnnyutahh/swmisc/-/blob/master/sysadmin/networking/iptables/iptables-list-pretty.sh

1
Johnny Utahh 17 Май 2020 в 18:36