Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

GitHub

This documentation is part of the "Projects with Books" initiative at zenOSmosis.

The source code for this project is available on GitHub.

User and Permissions

Relevant source files

Purpose and Scope

This page documents the user account and permission model used within the docker-sshfs container. It explains how the sshuser account is configured, why the /samba-share directory has world-writable permissions (777), and how FUSE's user_allow_other option enables cross-service filesystem access between SSHFS and Samba processes.

For information about SSHFS mount options that interact with these permissions, see 5.3. For details about the Samba configuration that enforces user identity, see 5.1).


The sshuser Account

The container creates a dedicated non-root user account specifically for running SSHFS mount operations. This account is created during the Docker image build process.

Account Specifications

PropertyValueLocation
UsernamesshuserDockerfile9
PasswordsshpassDockerfile9
User TypeNon-root with home directoryDockerfile9
UID1000 (default for first non-root user)Assigned by useradd
GID1000 (default primary group)Assigned by useradd

The account is created using the useradd command with the -m flag to create a home directory:

useradd -m sshuser && echo "sshuser:sshpass" | chpasswd

Sources : Dockerfile9

Role in the System

The sshuser account serves three critical functions:

  1. SSHFS Mount Owner : When users manually execute sshfs commands inside the container, they typically do so as sshuser via docker exec
  2. File Operation Identity : All files accessed through Samba are forced to use sshuser as the effective user (via force user = sshuser in smb.conf19)
  3. Permission Boundary : This account provides a consistent identity layer between the guest-authenticated SMB clients and the remote SSH server

Sources : Dockerfile9 smb.conf19


Directory Permissions

The container's filesystem uses deliberately permissive settings to enable cross-service access between SSHFS mounts and Samba shares.

/samba-share Directory Permissions

The /samba-share directory is configured with 777 permissions (read, write, execute for all users):

chmod -R 777 /samba-share

Permission Breakdown :

OctalBinaryOwnerGroupOther
777111 111 111rwxrwxrwx

This configuration is set at Dockerfile21 Notably, line 20 contains a commented-out alternative approach:

# RUN chown -R sshuser:sshuser /samba-share

This indicates that the design evolved from ownership-based access control to permission-based access control, choosing broad permissions over restricted ownership.

Sources : Dockerfile:20-21

Why 777 Permissions Are Used

The 777 permission mode is necessary because:

  1. Multiple Process Access : Both the smbd daemon and SSHFS mount processes need write access to directories under /samba-share
  2. Symbolic Link Traversal : The symbolic link at /samba-share/remote (created at Dockerfile30) points to /remote, and both services must traverse this link
  3. Unknown Client UIDs : macOS clients connecting as "guest" might have their requests mapped to various internal UIDs by Samba
  4. Write-Through Requirements : Files created by macOS clients must be writable through the SSHFS mount to the remote SSH server

Sources : Dockerfile21 Dockerfile30


FUSE user_allow_other Configuration

The most critical permission setting for cross-service integration is the FUSE user_allow_other option, enabled in /etc/fuse.conf.

Configuration Line

The Dockerfile appends this setting to the FUSE configuration:

echo "user_allow_other" >> /etc/fuse.conf

This occurs at Dockerfile24

Sources : Dockerfile24

What user_allow_other Does

By default, FUSE mounts are only accessible by the user who performed the mount operation. When sshuser mounts a remote filesystem via SSHFS to /remote, only sshuser can read or write files at that mount point.

graph TD
    subgraph "Without user_allow_other"
        SSHFS1["sshfs mount by sshuser\nMounted at: /remote"]
SambaProc1["smbd process\nRunning as: root or other user"]
Access1["File Access Denied"]
SSHFS1 -->|Access check| Access1
 
       SambaProc1 -->|Attempts to read /remote| SSHFS1
    end
    
    subgraph "With user_allow_other"
        SSHFS2["sshfs mount by sshuser\nOptions: allow_other\nMounted at: /remote"]
SambaProc2["smbd process\nRunning as: root or other user"]
Access2["File Access Granted"]
SSHFS2 -->|Access check allow_other active| Access2
 
       SambaProc2 -->|Attempts to read /remote| SSHFS2
    end

The user_allow_other setting changes this behavior:

Permission Flow :

  1. Without user_allow_other: FUSE kernel module checks if requesting process UID matches mount owner UID
  2. With user_allow_other + allow_other mount option: FUSE allows access from any user, delegating permission checks to the underlying filesystem

Sources : Dockerfile24

Interaction with SSHFS Mount Options

The /etc/fuse.conf setting enables the capability , but users must also specify -o allow_other when mounting with SSHFS:

Without the system-level user_allow_other configuration in /etc/fuse.conf, the allow_other mount option would be rejected with an error like:

fusermount: option allow_other only allowed if 'user_allow_other' is set in /etc/fuse.conf

Sources : Dockerfile24


Samba Force User Mechanism

The Samba configuration enforces a consistent user identity for all file operations, regardless of how clients authenticate.

Configuration Settings

The [SSHFS Share] section in smb.conf contains:

This appears at smb.conf19 alongside guest access settings:

Sources : smb.conf:13-14 smb.conf19

graph LR
    subgraph "macOS Client Request Flow"
        MacOS["macOS Finder\nConnects as: Guest"]
SMBAuth["Samba Authentication\nmap to guest = bad user"]
ForceUser["Force User Transform\nforce user = sshuser"]
FileOp["Filesystem Operation\nEffective UID: 1000 (sshuser)"]
end
    
 
   MacOS -->|SMB connection| SMBAuth
 
   SMBAuth -->|Guest credentials| ForceUser
 
   ForceUser -->|All operations as sshuser| FileOp

Force User Behavior

The force user directive overrides the authenticated user identity for all filesystem operations:

Effective Result : Whether the macOS client connects as "Guest" (which it must, given guest only = yes), or even if future configurations allowed authenticated users, all file operations would execute as sshuser (UID 1000).

Sources : smb.conf4 smb.conf:13-14 smb.conf19


flowchart TB
    subgraph "macOS Client Layer"
        Finder["macOS Finder\nUser identity: Varies"]
end
    
    subgraph "Samba Layer (Container)"
        SMB["smbd process\nConfiguration applies"]
GuestMap["map to guest = bad user\nGuest authentication"]
ForceUser["force user = sshuser\nUID override to 1000"]
end
    
    subgraph "Filesystem Layer (Container)"
        SambaShare["/samba-share\nPermissions: 777\nAccessible by all"]
SymLink["/samba-share/remote\nSymbolic link"]
RemoteMount["/remote\nSSHFS mount point"]
end
    
    subgraph "FUSE Layer (Container)"
        FUSEConf["user_allow_other\nin /etc/fuse.conf"]
MountOpts["SSHFS mount options:\nallow_other\nuid=1000\ngid=1000"]
end
    
    subgraph "Remote Layer"
        SSH["SSH connection\nAuthenticated as sshuser"]
RemoteFS["Remote filesystem\nFiles owned by remote user"]
end
    
 
   Finder -->|SMB protocol| SMB
 
   SMB --> GuestMap
 
   GuestMap --> ForceUser
 
   ForceUser -->|UID: 1000| SambaShare
 
   SambaShare --> SymLink
 
   SymLink --> RemoteMount
 
   RemoteMount --> FUSEConf
 
   FUSEConf -->|Allows cross-user access| MountOpts
 
   MountOpts -->|Files appear as UID 1000| SSH
 
   SSH --> RemoteFS

Complete Permission Model

The following diagram maps the complete permission flow from macOS client through Samba and SSHFS to the remote server:

Cross-Service Permission Flow

Sources : smb.conf4 smb.conf19 Dockerfile21 Dockerfile24 Dockerfile30


Permission Requirements by Operation

Different operations in the system have specific permission requirements:

OperationRequired PermissionsConfiguration Source
Samba reads /samba-shareWorld-readable (r--)Dockerfile21
Samba writes to /samba-shareWorld-writable (-w-)Dockerfile21
Samba traverses symlinkWorld-executable (--x)Dockerfile21
Samba accesses /remoteuser_allow_other + allow_otherDockerfile24
SSHFS mounts remote filesUser sshuser credentialsManual sshfs command
Files created via SambaOwned by UID 1000 (forced)smb.conf19
File permission on creation0777 (create_mask)smb.conf17
Directory permission on creation0777 (directory_mask)smb.conf18

Sources : Dockerfile21 Dockerfile24 smb.conf:17-19


graph TD
    subgraph "Identity Layers"
        Layer1["Layer 1: macOS Client\nIdentity: Guest (varies)"]
Layer2["Layer 2: Samba Process\nForced Identity: sshuser (UID 1000)"]
Layer3["Layer 3: SSHFS Mount\nFile Owner: UID 1000"]
Layer4["Layer 4: Remote SSH Server\nIdentity: SSH user (varies)"]
end
    
 
   Layer1 -->|force user = sshuser| Layer2
 
   Layer2 -->|Filesystem operations| Layer3
 
   Layer3 -->|uid=1000 mount option| Layer4

UID/GID Mapping

The system uses consistent UID/GID values to maintain identity across service boundaries:

Identity Mapping Table

Key Points :

  • UID 1000 : The numeric user ID for sshuser, used consistently across Samba and SSHFS
  • GID 1000 : The primary group ID for sshuser
  • SSHFS uid/gid options : When mounting with uid=1000,gid=1000, files on the remote server appear to be owned by UID 1000 locally, enabling write access

Sources : Dockerfile9 smb.conf19


Why This Permission Model Works

The permission architecture solves a complex cross-service access problem:

The Core Challenge

Two separate processes with different identities need to access the same mounted filesystem:

  1. The smbd daemon (running as root or dedicated samba user)
  2. The SSHFS mount (owned by sshuser)

The Solution Components

ComponentPurposeWhy It's Necessary
sshuser accountConsistent identityProvides a known UID (1000) for both Samba and SSHFS
777 on /samba-sharePermissive directory accessAllows any process to traverse and write
user_allow_other in fuse.confEnable cross-user FUSE accessAllows smbd to read sshuser's mounts
allow_other mount optionActivate cross-user accessMust be specified when mounting
force user = sshuserIdentity enforcementEnsures Samba operations use UID 1000
uid=1000,gid=1000 mount optionsFile ownership mappingMakes remote files appear owned by sshuser

Sources : Dockerfile9 Dockerfile21 Dockerfile24 smb.conf19


Security Implications

The permission model prioritizes functionality over strict security , which is appropriate given the container's isolation:

Relaxed Security Elements

  1. World-Writable Directories : The 777 permissions on /samba-share allow any process in the container to modify files
  2. Guest-Only Access : No authentication required to connect via SMB (smb.conf:13-14)
  3. Hardcoded Password : The sshuser password is sshpass, visible in the Dockerfile
  4. Privileged Container : The container typically runs with --privileged flag to enable FUSE

Mitigating Factors

  1. Container Isolation : Permissions are isolated within the container namespace
  2. Localhost Port Binding : SMB ports are bound to 127.0.0.1 only (see 3.3)
  3. Single-Purpose Container : No other services or users exist in the container
  4. Controlled Environment : Users explicitly choose to run this container and trust its purpose

Sources : Dockerfile9 Dockerfile21 smb.conf:13-14


Code-to-System Entity Mapping

The following table maps permission-related identifiers in code to their system-level meanings:

Code IdentifierFileLine(s)System EntityPurpose
sshuserDockerfile9Linux user accountSSHFS mount owner
sshpassDockerfile9Password stringAuthentication credential
useradd -mDockerfile9CommandUser creation with home dir
777Dockerfile21Octal permissionWorld-readable/writable/executable
user_allow_otherDockerfile24FUSE config optionEnable cross-user mount access
/etc/fuse.confDockerfile24Config file pathFUSE system configuration
force usersmb.conf19Samba directiveOverride client user identity
guest oksmb.conf13Samba directiveAllow guest connections
guest onlysmb.conf14Samba directiveEnforce guest authentication
map to guestsmb.conf4Samba directiveGuest authentication trigger
create masksmb.conf17Samba directiveNew file permissions
directory masksmb.conf18Samba directiveNew directory permissions

Sources : Dockerfile9 Dockerfile21 Dockerfile24 smb.conf4 smb.conf:13-14 smb.conf:17-19


Summary

The docker-sshfs container implements a permission model that uses:

  • A dedicated sshuser account (UID 1000) as the consistent identity layer
  • World-writable permissions (777) on /samba-share for cross-process access
  • FUSE's user_allow_other configuration to enable Samba access to SSHFS mounts
  • Samba's force user directive to normalize all client operations to sshuser
  • Consistent UID/GID mapping (1000:1000) across SSHFS mount options

This architecture trades strict security controls for operational simplicity, relying on Docker's container isolation to maintain security boundaries. The result is a system where macOS clients can seamlessly access remote SSH filesystems through Samba without encountering permission-denied errors.

Sources : Dockerfile9 Dockerfile21 Dockerfile24 smb.conf4 smb.conf:13-14 smb.conf:17-19