Как перебирать переменную, пропуская одно из значений?

Убедитесь, что вы выполняете установку как root (также убедитесь, что root имеет доступ к SSH самому себе на машине. Проверьте, набрав «ssh root @ localhost "). Убедитесь, что у вас есть доступ к порту 3000 в устанавливаемой системе. Поэтому, если вы устанавливаете на локальную виртуальную машину, убедитесь, что порт 3000 открыт, или убедитесь, что вы используете SSH-туннелирование и туннелирование порта 3000 обратно на локальный компьютер через порт 22.

Убедитесь, что вы следуете всем инструкциям здесь:

https://docs.puppet.com/puppet/3.8/reference/pre_install.html

2
19.09.2017, 23:48
3 ответа

Основная проблема заключается в том, что у вас отношение 1 :1 между именами интерфейсов (eth1, eth2,... )и связанными сетями (10.x, 20.x,... ), но в вашем коде нет ничего, что бы явно устанавливало эту связь 1 :1.

Вы должны где-то привязать ethNк 192.168.N.x. Вы можете сделать это с помощью одной переменной NETS, которая будет содержать список пар interface:N. Смотрите мой код ниже:

#!/bin/sh
NETS="eth1:10 eth2:20 eth3:30"

for net in $NETS; do
    k="${net%:*}"          # Yields the name of the interface
    i="${net#*:}"          # Yields the number bound to the interface
    sarg="192.168.$i.0/24"

    for net in $NETS; do
        j="${net#*:}"      # Yields the number bound to the interface
        [ "$i" -eq "$j" ] && continue
        darg="192.168.$j.0/24"
        echo "iptables -I FORWARD -i $k -s $sarg -d $darg -j DROP"
    done
done

Примечания:

  • Я полностью удалил цикл for k in $NAME, так как он противоречит тому, чего вы хотите достичь.
  • Вы даже можете поместить сеть в определение NETSи прочитать sargи dargпрямо из него. Что-то вроде:

    NETS="eth1:192.168.10.0/24 eth2:192.168.20.0/24 eth3:192.168.30.0/24"
    

[обновление] В сочетании с моим ответом на ваш другой вопрос это дало бы этот скрипт:

#!/bin/sh
NETID="10 20 30"
NAME="eth1 eth2 eth3"
NETS=$(set -- $NETID; for iface in $NAME; do echo "$iface:192.168.$1.0/24"; shift; done)

for net in $NETS; do
    iface="${net%:*}"
    sarg="${net#*:}"

    for net in $NETS; do
        darg="${net#*:}"
        [ "$sarg" != "$darg" ] && echo "iptables -I FORWARD -i $k -s $sarg -d $darg -j DROP"
    done
done
1
27.01.2020, 21:53

Версия POSIX sh:

for n in 1 2 3; do
  src="$n"0
  interface="eth$n"
  for dest in 10 20 30; do
    [ "$dest" = "$src" ] && continue
    printf 'iptables -I FORWARD -i %s -src %s -dst %s -j DROP\n' "$interface" "192.168.$src.0/24" "192.168.$dest.0/24"
  done
done

Я сделал несколько предположений о том, как вы связываете интерфейс с исходным кодом для ваших правил. Но это дает желаемый результат, который вы показали.

2
27.01.2020, 21:53

Используя POSIX Awk и не беспокоясь о последовательности строк вывода:

echo | awk -v 'netids=10 20 30' -v 'names=eth1 eth2 eth3' '
  BEGIN {
    netidcount = split(netids, netid)
    namecount = split(names, name)
    if (netidcount != namecount) {
      print "Error: You must pass the same number of names and netids."
      exit 1
    }
    for (i in name) {
      for (j in name) {
        if (i == j) {
          continue
        }
        printf "iptables -I FORWARD -i %s -src 192.168.%s.0/24 -dst 192.168.%s.0/24 -j DROP\n", name[i], netid[i], netid[j]
      }
    }
  }'

Конечно, вы можете изменить это; например, вы можете поместить приведенный выше awk-скрипт в файл и вызвать его с помощью:

echo | awk -v... -v... -f script.awk

Или вы можете поместить сетевые идентификаторы и имена в data.txt, возможно, в таком формате:

eth1 10
eth2 20
eth3 30

И напишите файл сценария Awk script.awkвот так:

#!/bin/awk
NF != 2 {
  error = 1
  print "Error: Each line of input must contain one interface name and one number."
  exit
}
(($1 in nameseen) || ($2 in netidseen)) {
  error = 1
  print "Error: Each interface name and network id in input must be unique."
  exit
}
{
  name[NR] = $1
  netid[NR] = $2
  nameseen[$1]
  netidseen[$2]
}
END {
  if (error) {
    exit error
  }
  for (i in name) {
    for (j in name) {
      if (i == j) {
        continue
      }
      printf "iptables -I FORWARD -i %s -src 192.168.%s.0/24 -dst 192.168.%s.0/24 -j DROP\n", name[i], netid[i], netid[j]
    }
  }
}

А потом так и назови:

awk -f script.awk data.txt

Большой выбор.

Я бы, наверное, data.txtвыглядел как:

eth1 192.168.10.0/24
eth2 192.168.20.0/24
eth3 192.168.30.0/24

Изменение сценария для работы с этим форматом данных оставлено читателю в качестве упражнения. ;)


(Примечание. :Если вы используете этот код, не забудьте указать ссылку на этот ответ в качестве авторства.)

3
27.01.2020, 21:53

Теги

Похожие вопросы