使用 Podman 连接到 ***

     2023-03-17     74

关键词:

【中文标题】使用 Podman 连接到 ***【英文标题】:Connect to *** with Podman 【发布时间】:2019-11-28 14:50:21 【问题描述】:

有这个Dockerfile:

FROM fedora:30

ENV LANG C.UTF-8

RUN dnf upgrade -y \
    && dnf install -y \
        openssh-clients \
        open*** \
        slirp4netns \
    && dnf clean all

CMD ["open***", "--config", "/***/o***.config", "--auth-user-pass", "/***/o***.auth"]

使用以下方法构建图像:

podman build -t peque/*** .

如果我尝试使用它运行它(注意 $(pwd),*** 配置和凭据的存储位置):

podman run -v $(pwd):/***:Z --cap-add=NET_ADMIN --device=/dev/net/tun -it peque/***

我收到以下错误:

ERROR: Cannot open TUN/TAP dev /dev/net/tun: Permission denied (errno=13)

关于如何解决此问题的任何想法?如果有帮助,我不介意更改基本图像(即:到 Alpine 或其他任何东西,只要它允许我使用 open*** 进行连接)。

系统信息

使用 Podman 1.4.4(无根)和带有内核 5.1.19 的 Fedora 30 发行版。

/dev/net/tun 权限

运行容器:

podman run -v $(pwd):/***:Z --cap-add=NET_ADMIN --device=/dev/net/tun -it peque/***

然后,从容器中,我可以:

# ls -l /dev/ | grep net
drwxr-xr-x. 2 root   root       60 Jul 23 07:31 net

我也可以列出/dev/net,但会得到“权限被拒绝错误”:

# ls -l /dev/net
ls: cannot access '/dev/net/tun': Permission denied
total 0
-????????? ? ? ? ?            ? tun

正在尝试--privileged

如果我尝试使用--privileged

podman run -v $(pwd):/***:Z --privileged --cap-add=NET_ADMIN --device=/dev/net/tun -it peque/***

然后我得到一个 no-such-file-or-directory 错误 (errno=2),而不是权限被拒绝错误 (errno=13):

ERROR: Cannot open TUN/TAP dev /dev/net/tun: No such file or directory (errno=2)

使用--privileged时可以有效验证不存在/dev/net/目录,即使我传递了--cap-add=NET_ADMIN --device=/dev/net/tun参数。

详细日志

这是我用verb 3配置客户端时得到的日志:

Open*** 2.4.7 x86_64-redhat-linux-gnu [SSL (OpenSSL)] [LZO] [LZ4] [EPOLL] [PKCS11] [MH/PKTINFO] [AEAD] built on Feb 20 2019
library versions: OpenSSL 1.1.1c FIPS  28 May 2019, LZO 2.08
Outgoing Control Channel Authentication: Using 160 bit message hash 'SHA1' for HMAC authentication
Incoming Control Channel Authentication: Using 160 bit message hash 'SHA1' for HMAC authentication
TCP/UDP: Preserving recently used remote address: [AF_INET]xx.xx.xx.xx:1194
Socket Buffers: R=[212992->212992] S=[212992->212992]
UDP link local (bound): [AF_INET][undef]:0
UDP link remote: [AF_INET]xx.xx.xx.xx:1194
TLS: Initial packet from [AF_INET]xx.xx.xx.xx:1194, sid=3ebc16fc 8cb6d6b1
WARNING: this configuration may cache passwords in memory -- use the auth-nocache option to prevent this
VERIFY OK: depth=1, C=ES, ST=XXX, L=XXX, O=XXXXX, emailAddress=email@domain.com, CN=internal-ca
VERIFY KU OK
Validating certificate extended key usage
++ Certificate has EKU (str) TLS Web Server Authentication, expects TLS Web Server Authentication
VERIFY EKU OK
VERIFY OK: depth=0, C=ES, ST=XXX, L=XXX, O=XXXXX, emailAddress=email@domain.com, CN=o***.server.address
Control Channel: TLSv1.2, cipher TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 2048 bit RSA
[o***.server.address] Peer Connection Initiated with [AF_INET]xx.xx.xx.xx:1194
SENT CONTROL [o***.server.address]: 'PUSH_REQUEST' (status=1)
PUSH: Received control message: 'PUSH_REPLY,route xx.xx.xx.xx 255.255.255.0,route xx.xx.xx.0 255.255.255.0,dhcp-option DOMAIN server.net,dhcp-option DNS xx.xx.xx.254,dhcp-option DNS xx.xx.xx.1,dhcp-option DNS xx.xx.xx.1,route-gateway xx.xx.xx.1,topology subnet,ping 10,ping-restart 60,ifconfig xx.xx.xx.24 255.255.255.0,peer-id 1'
OPTIONS IMPORT: timers and/or timeouts modified
OPTIONS IMPORT: --ifconfig/up options modified
OPTIONS IMPORT: route options modified
OPTIONS IMPORT: route-related options modified
OPTIONS IMPORT: --ip-win32 and/or --dhcp-option options modified
OPTIONS IMPORT: peer-id set
OPTIONS IMPORT: adjusting link_mtu to 1624
Outgoing Data Channel: Cipher 'AES-128-CBC' initialized with 128 bit key
Outgoing Data Channel: Using 160 bit message hash 'SHA1' for HMAC authentication
Incoming Data Channel: Cipher 'AES-128-CBC' initialized with 128 bit key
Incoming Data Channel: Using 160 bit message hash 'SHA1' for HMAC authentication
ROUTE_GATEWAY xx.xx.xx.xx/255.255.255.0 IFACE=tap0 HWADDR=0a:38:ba:e6:4b:5f
ERROR: Cannot open TUN/TAP dev /dev/net/tun: No such file or directory (errno=2)
Exiting due to fatal error

错误编号可能会根据我是否使用--privileged 运行命令而改变。

【问题讨论】:

无法重现 - 客户端容器在 CAP_NET_ADMIN 设置和 /dev/net/tun 允许的情况下运行良好。我使用了 podman 1.4.4(无根)、内核 5.2.1、来自官方 open*** 示例的密钥和证书、配置 - 也来自示例,但删除了一些(可能)不需要的东西。 也许向问题添加更具体的信息是有意义的——版本、服务器/客户端的最小配置等。 @DanilaKiver 我在我的问题中附加了更多信息。更完整的日志,关于我如何从容器中看到/dev/net/tun 的信息以及尝试--privileged 的结果(这没有帮助,或者因为/dev/net/ 不存在而变得更糟)。有什么想法吗? 谢谢,这个更新现在更有意义了——Fedora 有 SELinux(在 VM 上检查——如果是非特权容器,SELinux 会阻止对/dev/net/tun 的访问)。此外,即使在 Fedora 和没有 SELinux 的情况下,似乎在特权容器的情况下缺少 /dev/net/tun 也是可以重现的——这很有趣。打算再深入一点。 我认为这里的好方法是扩展现有的 SELinux 策略,以允许此特定容器与 tun_tap_device_t 一起工作 - 让我试验一下 :) 【参考方案1】:

原来你被 SELinux 阻止了:在运行客户端容器并尝试访问其中的/dev/net/tun 之后,你会在审计日志中得到以下 AVC 拒绝:

type=AVC msg=audit(1563869264.270:833): avc:  denied   getattr  for  pid=11429 comm="ls" path="/dev/net/tun" dev="devtmpfs" ino=15236 scontext=system_u:system_r:container_t:s0:c502,c803 tcontext=system_u:object_r:tun_tap_device_t:s0 tclass=chr_file permissive=0

要允许您的容器在不完全享有特权并强制执行 SELinux 的情况下配置隧道,您需要稍微自定义 SELinux 策略。但是,我没有找到一个简单的方法来正确地做到这一点。

幸运的是,有一个名为 udica 的工具,它可以从容器配置中生成 SELinux 策略。它本身不提供所需的策略,并且需要一些人工干预,因此我将逐步描述我如何让 open*** 容器工作。

首先,安装所需工具:

$ sudo dnf install policycoreutils-python-utils policycoreutils udica

创建具有所需权限的容器,然后为该容器生成策略:

$ podman run -it --cap-add NET_ADMIN --device /dev/net/tun -v $PWD:/***:Z --name o*** peque/***
$ podman inspect o*** | sudo udica -j - o***_container

Policy o***_container created!

Please load these modules using: 
# semodule -i o***_container.cil /usr/share/udica/templates/base_container.cil

Restart the container with: "--security-opt label=type:o***_container.process" parameter

这是udica生成的策略:

$ cat o***_container.cil 
(block o***_container
    (blockinherit container)
    (allow process process ( capability ( chown dac_override fsetid fowner mknod net_raw setgid setuid setfcap setpcap net_bind_service sys_chroot kill audit_write net_admin ))) 

    (allow process default_t ( dir ( open read getattr lock search ioctl add_name remove_name write ))) 
    (allow process default_t ( file ( getattr read write append ioctl lock map open create  ))) 
    (allow process default_t ( sock_file ( getattr read write append open  ))) 
)

让我们试试这个策略(注意--security-opt 选项,它告诉podman 在新创建的域中运行容器):

$ sudo semodule -i o***_container.cil /usr/share/udica/templates/base_container.cil
$ podman run -it --cap-add NET_ADMIN --device /dev/net/tun -v $PWD:/***:Z --security-opt label=type:o***_container.process peque/***
<...>
ERROR: Cannot open TUN/TAP dev /dev/net/tun: Permission denied (errno=13)

呃。这就是问题所在:udica 生成的策略仍然不知道我们容器的具体要求,因为它们没有反映在它的配置中(嗯,很可能,可以推断您希望允许对 @987654334 进行操作@ 基于您请求 --device /dev/net/tun 的事实,但是...)。因此,我们需要通过添加更多语句来自定义策略。

让我们暂时禁用 SELinux 并运行容器以收集预期的拒绝:

$ sudo setenforce 0
$ podman run -it --cap-add NET_ADMIN --device /dev/net/tun -v $PWD:/***:Z --security-opt label=type:o***_container.process peque/***

这些是:

$ sudo grep denied /var/log/audit/audit.log
type=AVC msg=audit(1563889218.937:839): avc:  denied   read write  for  pid=3272 comm="open***" name="tun" dev="devtmpfs" ino=15178 scontext=system_u:system_r:o***_container.process:s0:c138,c149 tcontext=system_u:object_r:tun_tap_device_t:s0 tclass=chr_file permissive=1
type=AVC msg=audit(1563889218.937:840): avc:  denied   open  for  pid=3272 comm="open***" path="/dev/net/tun" dev="devtmpfs" ino=15178 scontext=system_u:system_r:o***_container.process:s0:c138,c149 tcontext=system_u:object_r:tun_tap_device_t:s0 tclass=chr_file permissive=1
type=AVC msg=audit(1563889218.937:841): avc:  denied   ioctl  for  pid=3272 comm="open***" path="/dev/net/tun" dev="devtmpfs" ino=15178 ioctlcmd=0x54ca scontext=system_u:system_r:o***_container.process:s0:c138,c149 tcontext=system_u:object_r:tun_tap_device_t:s0 tclass=chr_file permissive=1
type=AVC msg=audit(1563889218.947:842): avc:  denied   nlmsg_write  for  pid=3273 comm="ip" scontext=system_u:system_r:o***_container.process:s0:c138,c149 tcontext=system_u:system_r:o***_container.process:s0:c138,c149 tclass=netlink_route_socket permissive=1

或者更易于阅读:

$ sudo grep denied /var/log/audit/audit.log | audit2allow


#============= o***_container.process ==============
allow o***_container.process self:netlink_route_socket nlmsg_write;
allow o***_container.process tun_tap_device_t:chr_file  ioctl open read write ;

好的,让我们修改udica-生成的策略,添加建议的allows(注意,这里我手动将语法转换为CIL):

(block o***_container
    (blockinherit container)
    (allow process process ( capability ( chown dac_override fsetid fowner mknod net_raw setgid setuid setfcap setpcap net_bind_service sys_chroot kill audit_write net_admin )))

    (allow process default_t ( dir ( open read getattr lock search ioctl add_name remove_name write )))
    (allow process default_t ( file ( getattr read write append ioctl lock map open create  )))
    (allow process default_t ( sock_file ( getattr read write append open  )))

    ; This is our new stuff.
    (allow process tun_tap_device_t ( chr_file ( ioctl open read write )))
    (allow process self ( netlink_route_socket ( nlmsg_write )))
)

现在我们重新启用 SELinux,重新加载模块并在我们指定自定义域时检查容器是否正常工作:

$ sudo setenforce 1
$ sudo semodule -r o***_container
$ sudo semodule -i o***_container.cil /usr/share/udica/templates/base_container.cil
$ podman run -it --cap-add NET_ADMIN --device /dev/net/tun -v $PWD:/***:Z --security-opt label=type:o***_container.process peque/***
<...>
Initialization Sequence Completed

最后,检查其他容器是否仍然没有这些权限:

$ podman run -it --cap-add NET_ADMIN --device /dev/net/tun -v $PWD:/***:Z peque/***
<...>
ERROR: Cannot open TUN/TAP dev /dev/net/tun: Permission denied (errno=13)

耶!我们继续使用 SELinux,只允许对我们的特定容器进行隧道配置。

【讨论】:

感谢您的详细解答!我目前无法访问可以尝试此操作的机器。我明天试试,但看起来很有希望。 ^^ 我收到了TCP/UDP: Socket bind failed on local address [AF_INET][undef]:0: Permission denied (errno=13)。审核日志显示type=AVC msg=audit(1563968192.672:465): avc: denied node_bind for pid=19626 comm="open***" scontext=system_u:system_r:o***_container.process:s0:c582,c694 tcontext=system_u:object_r:node_t:s0 tclass=udp_socket permissive=0。我尝试将(allow process open***_port_t ( udp_socket ( name_bind )))(allow process node_t ( udp_socket ( name_bind ))) 添加到策略中,但没有成功。有任何想法吗?也许我使用了错误的语法。 :-/ 我认为应该是(allow process node_t ( udp_socket ( node_bind ))) - 拒绝操作是node_bind,而不是name_bind 感谢您的帮助。我仍然没有设法让它工作...... :-(但你的回答肯定解决了我的第一个问题。现在我可以ssh到不需要***的服务器,但仍然不能ssh到那些需要***的服务器***。ssh 命令被“卡住”。没有明显的错误,也没有 SELinux 警告。ping 也无法正常工作,所以也许我仍然有一些连接问题。 其实,如果我等得够久,我会得到以下错误:ssh: connect to host server.domain.com port 22: Connection refused \n kex_exchange_identification: Connection closed by remote host.

centos7安装podman

参考技术Apodman目前只支持linux版本,windows和mac可以用RemoteClient连接到远程的Podman上问题1:解决办法问题2:解决办法:问题3:解决办法:官方文档说明:http://docs.podman.io/en/latest/markdown/podman.1.html?highlight=65536#rootless-mode修改镜像... 查看详情

podman容器技术的日常使用

Podman容器技术的日常使用一、podman介绍1.podman介绍2.podman官网3.podman最新版本介绍二、podman安装1.检查系统版本2.安装podman3.查看podman版本三、docker与podman区别四、podman基本命令五、镜像的基本操作1.配置加速器2.搜索镜像3.拉取镜像... 查看详情

如何使用 impyla 连接到 impala 或使用 pyhive 连接到 hive?

】如何使用impyla连接到impala或使用pyhive连接到hive?【英文标题】:Howtoconnecttoimpalausingimpylaortohiveusingpyhive?【发布时间】:2019-09-1613:49:36【问题描述】:我正在尝试通过以下代码使用impyla连接到impala:fromimpala.dbapiimportconnectconn=conn... 查看详情

使用podman

#使用Podman使用Podman非常的简单,Podman的指令跟Docker大多数都是相同的。下面我们来看几个常用的例子:运行一个容器[root@localhost~]#podmanrun-dit--nameb1centosb4ab9b6e8fc5e00f82b3 查看详情

无法使用php连接错误连接到mysql:无法连接到'localhost'(10061)上的MySQL服务器[重复]

】无法使用php连接错误连接到mysql:无法连接到\\\'localhost\\\'(10061)上的MySQL服务器[重复]【英文标题】:unabletoconnecttomysqlusingphpconnectionerror:Can\'tconnecttoMySQLserveron\'localhost\'(10061)[duplicate]无法使用php连接错误连接到mysql:无法连接... 查看详情

msSQL jdbc .. 我连接到服务器但如何连接到使用特定的 databaseName

】msSQLjdbc..我连接到服务器但如何连接到使用特定的databaseName【英文标题】:msSQLjdbc..IconnectedtotheserverbuthowtoconnecttouseaspecificdatabaseName【发布时间】:2013-06-1814:21:17【问题描述】:上次我在Java/Eclipse中使用SQL时,我有一个链接到项... 查看详情

podman的使用(代码片段)

podman的使用设置别名[root@hzy~]#aliasaliascp='cp-i'aliasdocker='podman'拉取镜像[root@hzy~]#dockerpullnginxResolving"nginx"usingunqualified-searchregistries(/etc/containers 查看详情

podman的使用(代码片段)

podman的使用设置别名[root@hzy~]#aliasaliascp='cp-i'aliasdocker='podman'拉取镜像[root@hzy~]#dockerpullnginxResolving"nginx"usingunqualified-searchregistries(/etc/containers 查看详情

使用 Databricks 连接到 AWS Postgres

】使用Databricks连接到AWSPostgres【英文标题】:ConnecttoAWSPostgresusingDatabricks【发布时间】:2019-05-0215:35:00【问题描述】:从AzureDatabricks连接到AWSPostgres时遇到问题,我是Azure的新手,下面是我用来连接到Postgres的代码,但不知何故它... 查看详情

如何使用 python 连接到 lightstreamer?

】如何使用python连接到lightstreamer?【英文标题】:howconnecttolightstreamerwithpython?【发布时间】:2020-08-0300:19:02【问题描述】:我想用python连接到lightstramerlightstreamerexample我试试importasyncioimportwebsocketsaswebsocketsheader=\'Accept-Encoding\':\' 查看详情

使用 qdbus 连接到信号

】使用qdbus连接到信号【英文标题】:connectingtoasignalwithqdbus【发布时间】:2012-12-0709:25:27【问题描述】:qdbus在调用方法时相当简单,但是可以用它连接到信号吗?签名:signalvoidorg.kde.kwin.Scripting.printError(QStringtext)【问题讨论】... 查看详情

使用直线连接到 Hive

】使用直线连接到Hive【英文标题】:ConnectingtoHiveusingBeeline【发布时间】:2015-03-1802:50:07【问题描述】:我正在尝试通过Beeline客户端连接到我的机器中安装的配置单元。当我给出“直线”命令并连接到Hive时,客户端要求输入用... 查看详情

如何使用 FluentDocker 连接到 mongodb

】如何使用FluentDocker连接到mongodb【英文标题】:HowtoconnecttomongodbusingFluentDocker【发布时间】:2021-11-2903:48:12【问题描述】:我正在尝试使用FluentDocker对MongoDB运行测试,但我无法连接到它,请参阅下面的代码。[Fact]publicasyncTaskTestM... 查看详情

podman使用指南(代码片段)

原文链接:Podman使用指南Podman原来是CRI-O项目的一部分,后来被分离成一个单独的项目叫libpod。Podman的使用体验和Docker类似,不同的是Podman没有daemon。以前使用DockerCLI的时候,DockerCLI会通过gRPCAPI去跟DockerEngine说「我要启动一个容... 查看详情

无法使用 Sqitch 连接到 Snowflake

】无法使用Sqitch连接到Snowflake【英文标题】:UnabletoconnecttoSnowflakeusingSqitch【发布时间】:2019-10-0419:37:07【问题描述】:我正在使用私钥身份验证连接到Snowflake,但无法使用Sqitch进行连接。直接使用snowsql连接时,此功能成功。我... 查看详情

使用 pyODBC 连接到 ODBC

】使用pyODBC连接到ODBC【英文标题】:ConnectingtoODBCusingpyODBC【发布时间】:2015-06-1515:14:42【问题描述】:我已阅读pythonodbc库中的所有常见问题解答页面以及其他示例,并使用以下代码设法连接到DSN:cnxn=pyodbc.connect("DSN=DSNNAME")cursor... 查看详情

使用 Alexa Skill 连接到 Postgresql

】使用AlexaSkill连接到Postgresql【英文标题】:ConnecttoPostgresqlwithAlexaSkill【发布时间】:2018-04-0915:38:31【问题描述】:我正在尝试开发一个简单的AlexaSkill,它使用node.js连接到postgresql数据库并返回结果。我可以使用本地机器上的node... 查看详情

如何在 python 上使用 presto 连接到 Azure 数据湖存储?

】如何在python上使用presto连接到Azure数据湖存储?【英文标题】:HowtoconnecttoAzuredatalakestorageusingprestoonpython?【发布时间】:2022-01-1615:58:03【问题描述】:所以我需要使用presto连接到ADLS,现在我已经阅读了hive可以连接到adls并且pres... 查看详情