将 Samba 共享挂载到 Docker 容器

将 Samba 共享挂载到 Docker 容器

目标

在我的服务器上,我运行着各种 Docker 容器,特别是 syncthing 容器。此外,我还将我的服务器用于不同的 Samba 共享。

我的目标是将主机目录挂载/mnt/basis/software/backups/syncthing到 syncthing 容器,以便所有同步的文件都可以在 Samba 共享“备份”下访问。请注意,父目录backups用于 Samba 共享。该syncthing目录具有以下权限和标签设置:

drwxrwx---. 4 myuser applications system_u:object_r:samba_share_t:s0     11 12. Jan 00:06 syncthing

配置

我的 Samba 共享“备份”的配置如下:

[backups]
path = /mnt/basis/software/backups
writeable = yes
browseable = yes
read only = no
valid users = @applications
public = no
guest ok = no
force group = applications
directory mask = 0770
force directory mode = 0770
create mask = 0770
force create mode = 0770
inherit acls = yes

用于同步的docker-compose文件如下:

version: "3.9"

services:
  syncthing:
    image: lscr.io/linuxserver/syncthing:1.27.2
    container_name: syncthing
    hostname: syncthing-docker
    environment:
      - PUID=1000
      - PGID=1006
      - TZ=Europe/Berlin
    volumes:
      - /mnt/basis/software/docker/syncthing:/config:z
    ports:
      - 8384:8384
      - 22000:22000/tcp
      - 22000:22000/udp
      - 21027:21027/udp
    restart: always

在 docker-compose 文件中,我指定了挂载卷的后缀:z,以确保目录的标签正确。此外,我确保分配了正确的用户 ID 和组 ID。在我的例子中,这是1006引用组的组 ID applications(如我的 Samba 共享配置中所述)。

问题

目前,当前设置无法正常工作。我可以成功启动 syncthing 容器,并且可以在端口 8384 上访问 Web 应用程序。我还能够在一个小测试中确认文件已成功同步。但是,不再能够访问/syncthingSamba 共享中的目录,因为使用后缀重新标记会从目录中:z删除标签并添加标签,从而使目录无法访问。问题似乎出在已挂载目录的重新标记上。samba_share_tcontainer_file_t

但是如果我省略后缀:z并且目录未重新绑定,则容器无法正确启动。我查看了容器日志,发现权限显然被拒绝,如下所示。

[start] 2024/01/12 01:24:04 INFO: syncthing v1.27.2 "Gold Grasshopper" (go1.20.11 linux-amd64) root@buildkitsandbox 2024-01-02 08:15:35 UTC [noupgrade]
[start] 2024/01/12 01:24:04 INFO: Generating ECDSA key and certificate for syncthing...
[start] 2024/01/12 01:24:04 WARNING: Failed to load/generate certificate: save cert: open /config/cert.pem: permission denied

看来我在设置syncthing目录的权限时做错了什么。

问题

根据前面的解释,我想问一下是否可以将目录挂载/mnt/basis/software/backups/syncthing到 syncthing 容器中,以便我可以通过 Samba 共享从远程机器访问同步文件?

如果您能提供任何关于如何进行的想法或建议,我将不胜感激。

答案1

事实证明,问题实际上源于 SELinux 策略。具体来说,podman 容器进程(标记为container_t)无法访问 samba 共享目录(标记为samba_share_t)。

经过一番研究,我发现了这篇文章:

如那里所述,我们可以使用ausearch检查 SELinux 的拒绝决定,并为拒绝创建例外规则audit2allow。然而,经过反复测试,我提出了这个 SELinux 模块规范:

module docker-samba 1.0;

require {
    type container_t;
    type samba_share_t;
    type mnt_t;
    class dir { read write setattr getattr create rename open add_name rmdir remove_name lock watch};
    class file { read write setattr getattr create rename open lock unlink append};
}

#============= container_t ==============
allow container_t samba_share_t:dir { read write setattr getattr create rename open add_name rmdir remove_name lock watch};
allow container_t samba_share_t:file { read write setattr getattr create rename open lock unlink append};
allow container_t mnt_t:dir { setattr };

它基于官方 SELinux 规范政策声明对象类别权限

然后可以按如下方式安装该模块:

sudo checkmodule -M -m -o docker-samba.mod docker-samba.te
sudo semodule_package -m docker-samba.mod -o docker-samba.pp
sudo semodule -i docker-samba.pp

要检查您的模块规范是否确实正确,您可以再次使用ausearch之前描述的方法检查 SELinux 拒绝消息。

答案2

看起来你正在使用基于 Linux 的 docker 容器,因此无法识别 Z:,因为那是 windows/Microsoft

因此,您需要在卷中指定一个 Linux 路径,例如 /data

volumes:
 -  /mnt/basis/software/docker/syncthing:/var/syncthing

还要确保 1006 对文件/目录/共享具有足够的权限

他们的 github 上有一个例子 docker-compose https://github.com/syncthing/syncthing/blob/main/README-Docker.md

    ---
version: "3"
services:
  syncthing:
    image: syncthing/syncthing
    container_name: syncthing
    hostname: my-syncthing
    environment:
      - PUID=1000
      - PGID=1000
    volumes:
      - /wherever/st-sync:/var/syncthing
    ports:
      - 8384:8384 # Web UI
      - 22000:22000/tcp # TCP file transfers
      - 22000:22000/udp # QUIC file transfers
      - 21027:21027/udp # Receive local discovery broadcasts
    restart: unless-stopped

相关内容