как этот скрипт можно сделать с помощью awk one -лайнера?

Есть две проблемы (и на самом деле не -задал 3-й вопрос, который я рассмотрю простым, если не лучшим решением, на всякий случай, чтобы быть тщательным):

Локально инициированные пакеты не пересылаются/маршрутизируются

Локально инициированные пакеты не пересылаются (не маршрутизируются ). Таким образом, эти пакеты никогда не видят цепочку nat/PREROUTING. Взгляните на Поток пакетов в Netfilter и General Networking , чтобы получить представление о том, что происходит во время жизни пакета в ядре. Локальные пакеты приходят из "локального процесса".

Таким образом, в дополнение к правилу nat/PREROUTINGвыполняется DNATдля пакетов, прибывающих "извне", что должно выглядеть как:

iptables -t nat -I PREROUTING -i eno1 -p tcp --dport 8443 -j DNAT --to-destination 172.17.0.2:8443

Вы также должны использовать цепочку nat/OUTPUT. На выходе его синтаксис допускает только исходящие интерфейсы, поэтому он изменен следующим образом:

iptables -t nat -I OUTPUT -o lo -p tcp --dport 8443 -j DNAT --to-destination 172.17.0.2:8443

Исходный пакет, а затем поток будут фактически перенаправлены на другой интерфейс (Я подозреваю, что "проверка перенаправления" на схеме предыдущей ссылки может быть размещена неправильно ).

Это будет работать с любым IP-адресом, принадлежащим хосту (, т.е. :172.16.214.45 и 172.17.0.1 ), кроме...

диапазон IP 127.0.0.0/8 запрещен для просмотра за пределами интерфейса lo

Ядро Linux имеет специальные настройки, запрещающие маршрутизацию любого IP-адреса в диапазоне 127.0.0.0/8 куда-либо, кроме интерфейса lo, и отбрасывает любой такой пакет как марсианский источник при «попытке» использовать другой интерфейс, и правильно :удаленная система (даже если это контейнер )не примет входящий пакет с источником 127.0.0.1 и пунктом назначения 172.17.0.2 хотя бы потому, что не будет знать, куда на него ответить.

Таким образом,SNAT(или простойMASQUERADE)к пакету в дополнение к DNATтакже необходимо сделать, на этот раз в цепочке nat/POSTROUTING, которая проходится (см. предыдущую схему):

iptables -t nat -I POSTROUTING -s 127.0.0.1 -d 172.17.0.2 -j MASQUERADE

Этого еще недостаточно :как следует из названия, nat/POSTROUTINGпроисходит после маршрутизации (на самом деле проверка перемаршрутизации происходит после DNAT), и пакет уже был отброшен как марсианский источник.

В особых случаях, таких как этот, можно переопределить ограничение локальной сети с помощью переключателя интерфейса -route_localnet:

echo 1 > /proc/sys/net/ipv4/conf/docker0/route_localnet

Теперь стек маршрутизации пропускает пакеты с источником 127.0.0.1, а их источник корректируется на 172.17.0.1 по предыдущему правилу перед выходом по виртуальному проводу в контейнер :это работает.

Вам действительно следует избегать всего, что требует этого второго случая, потому что это ненужная сложность :использование IP-адреса, принадлежащего хосту, а не 127.0.0.1, должно быть достаточно для любого теста. Кроме того, если интерфейс docker0будет удален и создан заново, настройка route_localnetбудет потеряна, и было бы неразумно устанавливать ее по умолчанию.

Шпильки

Не задано, но если вы добавите сюда вторую систему (контейнер )в той же локальной сети, возникнут проблемы с локальной сетью -на -хост -на -тот же -перенаправления локальной сети (, если только Docker уже не обрабатывает это на сетевом уровне ).

Правило nat/PREROUTING, которое я написал в начале ответа, обрабатывает только интерфейс eno1. Была причина, по которой я добавил это -i eno1ограничение :без него, если другой контейнер в сети 172.17.0.0/16 попытается подключиться, например, к 172.16.214.45 :8443 (или к 172.17.0.1 :8443 ), пакет будет перенаправлен на 172.17.0.2. Затем 172.17.0.2 ответит напрямую источнику :другому контейнеру и полностью обойдет хост и его правила NAT.Этот контейнер увидит ответный пакет, пришедший из источника, о котором он не знает, и отклонит его (с помощьюTCP RST). Так что лучше не справляться с этим вообще, чем справляться плохо. Docker, вероятно, предоставляет определенные способы прямого разрешения службы на IP/порт другого контейнера без участия хоста.

В любом случае, если это необходимо, существует несколько способов преодолеть это, часто с компромиссом, от простого NAT (, который теряет исходный IP-адрес или должен транслировать его в фиктивную сеть, для целей регистрации )до сложного моста и /или настройки маршрутизатора, способные перехватывать связь по локальной сети.

Вот простое решение, где источником является SNAT -ed, использующий NETMAP, для фиктивной сети 10.17.0.0/16. Простое предварительное условие :10.17.0.0/16, вероятно, должно быть направлено на хост (, даже если он на самом деле не используется ), либо по маршруту по умолчанию (, вероятно, в случае ), определенному маршруту, либо с помощью хост, имеющий IP-адрес в этой фиктивной сети для этой цели. Пакеты с этим IP-адресом будут существовать только внутри сети docker0.

После удаления -i eno1из правила PREROUTINGвыше добавьте это новое правило:

iptables -t nat -I POSTROUTING -s 172.17.0.0/16 -d 172.17.0.0/16 -j NETMAP --to 10.17.0.0/16

Теперь перенаправление из локальной сети в ту же локальную сеть будет работать, а журналы контейнера назначения будут показывать исходные IP-адреса в диапазоне 10.17.0.0/16.

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

0
12.07.2020, 08:22
2 ответа

Вы просто пытаетесь переименовать файлы, чтобы сжать все цепочки пробелов в их именах до 1? Это было бы (непроверенным):

#!/usr/bin/env bash

shopt -s extglob
while IFS= read -rd '' old; do
    new="${old// *( )/ }"
    mv -- "$old" "$new"
done < <(find "$1" -name '*  *.*' -print0)

Нет причин использовать awk или другие команды.

1
18.03.2021, 23:20

Я нашел :здесь

    awk -v FS=' ' 'NR==FNR{  s[$1]=$0; next }  {print "mv "s[$1]" " $0}' l1 l2 
0
18.03.2021, 23:20

Теги

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