Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在我的Docker容器中,为什么我仍然可以绑定端口1而没有“NET\u bind\u SERVICE”功能?_Python_Docker_Sockets_Port_Linux Capabilities - Fatal编程技术网

Python 在我的Docker容器中,为什么我仍然可以绑定端口1而没有“NET\u bind\u SERVICE”功能?

Python 在我的Docker容器中,为什么我仍然可以绑定端口1而没有“NET\u bind\u SERVICE”功能?,python,docker,sockets,port,linux-capabilities,Python,Docker,Sockets,Port,Linux Capabilities,我正在使用ubuntu18.04桌面。以下是关于我的问题的更多细节 最近,我正在编写一些测试代码来实现这一点:当它作为非特权用户运行时,测试代码尝试绑定特权端口(在我的例子中是端口1),并期望绑定失败 在我的主机上,我当前的非特权用户具有以下capsh--print输出: Current: = Bounding set =cap_chown,cap_dac_override,cap_dac_read_search,cap_fowner,cap_fsetid,cap_kill,cap_setgid

我正在使用
ubuntu18.04桌面
。以下是关于我的问题的更多细节

最近,我正在编写一些测试代码来实现这一点:当它作为非特权用户运行时,测试代码尝试绑定特权端口(在我的例子中是端口1),并期望绑定失败

在我的主机上,我当前的非特权用户具有以下
capsh--print
输出:

Current: =
Bounding set =cap_chown,cap_dac_override,cap_dac_read_search,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_linux_immutable,cap_net_bind_service,cap_net_broadcast,cap_net_admin,cap_net_raw,cap_ipc_lock,cap_ipc_owner,cap_sys_module,cap_sys_rawio,cap_sys_chroot,cap_sys_ptrace,cap_sys_pacct,cap_sys_admin,cap_sys_boot,cap_sys_nice,cap_sys_resource,cap_sys_time,cap_sys_tty_config,cap_mknod,cap_lease,cap_audit_write,cap_audit_control,cap_setfcap,cap_mac_override,cap_mac_admin,cap_syslog,cap_wake_alarm,cap_block_suspend,cap_audit_read
Securebits: 00/0x0/1'b0
 secure-noroot: no (unlocked)
 secure-no-suid-fixup: no (unlocked)
 secure-keep-caps: no (unlocked)
uid=1000(ywen)
gid=1000(ywen)
groups=4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),116(lpadmin),126(sambashare),999(docker),1000(ywen)
因此,在尝试使用当前非特权用户绑定端口1时,我可以获得预期的权限拒绝错误:

Python 3.6.9(默认,2020年10月8日12:12:24)
linux上的[GCC 8.4.0]
有关详细信息,请键入“帮助”、“版权”、“信用证”或“许可证”。
>>>将套接字作为
>>>o=s.socket(s.AF_INET)
>>>o.bind(((“127.0.0.1”,1))
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
PermissionError:[Errno 13]权限被拒绝
>>>退出()
因为我的测试代码最终将在Docker容器中运行,所以我使用以下
Dockerfile
构建了一个映像:

ARG UBUNTU_VERSION=18.04
FROM ubuntu:${UBUNTU_VERSION}
ARG USER_NAME=ywen
ARG USER_ID=1000
ARG GROUP_ID=1000

RUN apt-get update

# Install the needed packages.
RUN DEBIAN_FRONTEND=noninteractive apt-get -y install \
    bash-completion \
    libcap2-bin \
    openssh-server \
    openssh-client \
    sudo \
    tree \
    vim

# Add a non-privileged user.
RUN groupadd -g ${GROUP_ID} ${USER_NAME} && \
    useradd -r --create-home -u ${USER_ID} -g ${USER_NAME} ${USER_NAME}

# Give the non-privileged user the privilege to run `sudo` without a password.
RUN echo "${USER_NAME} ALL=(ALL:ALL) NOPASSWD: ALL" > /etc/sudoers.d/${USER_NAME}

# Switch to the non-root user.
USER ${USER_NAME}

# The default command when the container is run.
CMD ["/bin/sleep", "infinity"]

通过运行以下
docker build
命令:

docker build -f ./Dockerfile.ubuntu --tag port-binding .
生成的映像被称为
端口绑定:latest

然后我运行它,首先:

然后我登录到容器并运行
capsh--print
。我得到:

Current: = cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcap+i
Bounding set =cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcap
Securebits: 00/0x0/1'b0
 secure-noroot: no (unlocked)
 secure-no-suid-fixup: no (unlocked)
 secure-keep-caps: no (unlocked)
uid=1000(ywen)
gid=1000(ywen)
groups=
目前,我拥有
cap\u net\u bind\u服务
功能。因此,当我在本文开头运行测试代码时,端口绑定可能会成功,我没有收到任何错误:

Python 3.6.9(默认,2020年10月8日12:12:24)
linux上的[GCC 8.4.0]
有关详细信息,请键入“帮助”、“版权”、“信用证”或“许可证”。
>>>将套接字作为
>>>o=s.socket(s.AF_INET)
>>>o.bind(((“127.0.0.1”,1))#在这里成功了。
>>>
我认为预期会成功,因为容器具有
cap\u net\u bind\u服务
功能。因此,我停止了容器并启动了一个新的容器,该容器丢弃了
cap\u net\u bind\u服务

docker run --rm -it --cap-drop=NET_BIND_SERVICE --name binding port-binding /bin/bash
Current: = cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_raw,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcap+i
Bounding set =cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_raw,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcap
Securebits: 00/0x0/1'b0
 secure-noroot: no (unlocked)
 secure-no-suid-fixup: no (unlocked)
 secure-keep-caps: no (unlocked)
uid=1000(ywen)
gid=1000(ywen)
groups=
在新容器中,
capsh--print
未显示
cap\u net\u bind\u服务

docker run --rm -it --cap-drop=NET_BIND_SERVICE --name binding port-binding /bin/bash
Current: = cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_raw,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcap+i
Bounding set =cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_raw,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcap
Securebits: 00/0x0/1'b0
 secure-noroot: no (unlocked)
 secure-no-suid-fixup: no (unlocked)
 secure-keep-caps: no (unlocked)
uid=1000(ywen)
gid=1000(ywen)
groups=
但是当我运行测试代码时,我发现仍然可以成功绑定端口1:

Python 3.6.9(默认,2020年10月8日12:12:24)
linux上的[GCC 8.4.0]
有关详细信息,请键入“帮助”、“版权”、“信用证”或“许可证”。
>>>将套接字作为
>>>o=s.socket(s.AF_INET)
>>>o.bind(((“127.0.0.1”,1))#未引发错误。在这里仍然成功。
>>>
然而,通过阅读以下文章,我认为删除
NET\u BIND\u服务
应该是正确的做法。显然,我在某个地方犯了个错误有人能告诉我我做错了什么吗?


我遇到了相反的问题-想要绑定到端口80,但无法。由于docker 20.03.0,容器的默认sysctl net.ipv4.ip_unprivileged_port_start设置为0,这与cap_net_bind_服务具有相同的效果-容器内的所有进程现在都可以绑定到(容器的)任何端口,即使是作为非特权用户。它可以通过
docker运行--sysctl net.ipv4.ip_unprivileged_port_start=0…
或docker-compose.yml设置进行外部设置

  sysctls:
    - net.ipv4.ip_unprivileged_port_start=0
将其设置为1024以获得与docker 20.03.0之前版本相同的行为