redir гораздо больше подходит для перенаправления портов, чем nc.
Хотя nc более легкий и подходит для одноразовых тестов, для более серьезного использования больше подходит redir; nc также не подходит для обработки повторных подключений или ошибок без поддержки вспомогательных инструментов и более сложных настроек, таких как xinetd.
redir также является очень легким инструментом, который довольно хорошо справляется с перенаправлением одного TCP-порта на другой с присущими ему повторными попытками/обработкой ошибок.
Перенаправление портов Tcp с помощью redir
Предположим, что ip-адрес нашей системы 1.1.1.1 и мы хотим перенаправить весь трафик, который идет с порта 80 на удаленный сервер с ip-адресом 2.2.2.2 и портом 8080. Проще говоря, мы хотим, чтобы утилита redir перенаправить соединения, приходящие на 1.1.1.1 по порту 80, на 2.2.2.2 порт 8080. Для этого нам нужно запустить redir, как показано ниже:
redir --laddr=1.1.1.1 --lport=80 --caddr=2.2.2.2 --cport=8080
Я исхожу из того, что вам строго не требуются монтирования, видимые для процесса инициализации (pid 1 )и что монтирования, видимые для демона docker, достаточно. Обычно они оба должны иметь одно и то же пространство имен монтирования.
(Использование докера 1.13.1 из репозитория CentOS)
Я могу воспроизвести вашу проблему с /proc/1/mounts
. Однако использование файла монтирования демона docker работает :
$ docker run -it -v /proc/$(pidof dockerd-current)/mounts:/tmp/mounts ubuntu:16.04
В док-контейнере /tmp/mounts
затем перечисляются подключения хоста.
(Использование внешнего докера -пакета ce 18.09.5 , как описано здесь)
В дополнение к проблеме, описанной выше, у пакета docker-ce
есть проблема с контекстом SE Linux службы containerd
:
# ps xZ | grep containerd
system_u:system_r:unconfined_service_t:s0 5695 ? Ssl 0:00 /usr/bin/containerd
...
Мы хотим, чтобы containerd
был помечен типом container_runtime_t
вместо unconfined_service_t
. С этой целью маркировка /usr/bin/containerd
должна быть обновлена ( общая ссылка):
# ls -Z /usr/bin/dockerd-ce
-rwxr-xr-x. root root system_u:object_r:container_runtime_exec_t:s0 /usr/bin/dockerd-ce
# ls -Z /usr/bin/containerd
-rwxr-xr-x. root root system_u:object_r:bin_t:s0 /usr/bin/containerd
# semanage fcontext -a -t container_runtime_exec_t /usr/bin/containerd
# restorecon /usr/bin/containerd
# ls -Z /usr/bin/containerd
-rwxr-xr-x. root root system_u:object_r:container_runtime_exec_t:s0 /usr/bin/containerd
Затем перезапустите демон containerd
:
# systemctl daemon-reload
# systemctl restart containerd
# ps xZ | grep containerd
system_u:system_r:container_runtime_t:s0 6557 ? Ssl 0:00 /usr/bin/containerd
Теперь Docker-контейнер можно запустить, используя ту же технику, что и выше (с помощью dockerd
вместоdockerd-current
):
$ docker run -it -v /proc/$(pidof dockerd)/mounts:/tmp/mounts ubuntu:16.04
Я проверил это на CentOS Linux версии 7.6.1810.
Вы можете убедиться, что init и демон docker имеют одинаковое пространство имен монтирования (, т. е. их /proc/[pid]/mounts будут показывать одни и те же монтирования):
# readlink /proc/1/ns/mnt /proc/$(pidof dockerd-current)/ns/mnt
mnt:[4026531840]
mnt:[4026531840]
Я также проверил, что SE Linux включен:
# getenforce
Enforcing
При выполнении вашей команды с пакетом CentOS docker
я получаю это сообщение об ошибке:
$ docker run -it -v /proc/1/mounts:/tmp/mounts ubuntu:16.04
/usr/bin/docker-current: Error response from daemon: oci runtime error: container_linux.go:247: starting container process caused "container init exited prematurely".
Кроме того, в /var/log/audit/audit.log
,Я вижу следующее нарушение AVC:
type=AVC msg=audit(1555530383.707:214): avc: denied { mounton } for pid=5691 comm="runc:[2:INIT]" path="/var/lib/docker/overlay2/8944062749f8ad19c3ff600e1d5286315227378174b95a952e7b0530927f4dcd/merged/tmp/mounts" dev="proc" ino=45422 scontext=system_u:system_r:container_runtime_t:s0 tcontext=system_u:system_r:init_t:s0 tclass=file permissive=0
Это говорит нам о том, что правила SE Linux не позволяют исходному контексту типа container _runtime _t выполнять действие «mounton» для целевого контекста типа «init _t». Вы можете убедиться, что это контекст /proc/1/mounts
, тогда как контекст /proc/$(pidof dockerd-current)/mounts
соответствует :
# ls -Z /proc/1/mounts /proc/$(pidof dockerd-current)/mounts
-r--r--r--. root root system_u:system_r:init_t:s0 /proc/1/mounts
-r--r--r--. root root system_u:system_r:container_runtime_t:s0 /proc/5476/mounts