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.

Samba Configuration (smb.conf)

Relevant source files

Purpose and Scope

This document provides a complete reference for the smb.conf file, which configures the Samba server running inside the docker-sshfs container. The configuration establishes the SMB/CIFS protocol bridge that makes remote SSH filesystems accessible to macOS Finder through guest-authenticated network shares.

For information about FUSE configuration that enables Samba to access SSHFS mounts, see FUSE Configuration. For details about SSHFS mount options that work with this configuration, see SSHFS Mount Options. For the broader security model, see Security Model.

Sources : smb.conf:1-20


Configuration File Structure

The smb.conf file contains two distinct sections that control different aspects of the Samba server:

SectionLinesPurpose
[global]smb.conf:1-8Server-wide settings including security model, protocol versions, and network identity
[SSHFS Share]smb.conf:10-19Share-specific settings for the /samba-share directory including permissions and user mapping

Sources : smb.conf:1-20


Global Configuration Section

The [global] section at smb.conf:1-8 defines server-wide behavior for the Samba daemon. These settings apply to all shares and control how the server identifies itself on the network and handles client connections.

graph LR
    subgraph "Configuration"
        workgroup["workgroup = WORKGROUP\nLine 2"]
netbios["netbios name = sambaserver\nLine 6"]
serverstring["server string = Samba Server %v\nLine 5"]
end
    
    subgraph "macOS Finder Discovery"
        BrowseList["Network Browser\nShows: sambaserver"]
ConnectionDialog["Connection Dialog\nWorkgroup: WORKGROUP"]
end
    
    subgraph "SMB Protocol"
        NetBIOS["NetBIOS Name Resolution\nPort 139"]
DirectTCP["Direct TCP/IP\nPort 445"]
end
    
 
   workgroup --> ConnectionDialog
 
   netbios --> BrowseList
 
   netbios --> NetBIOS
 
   netbios --> DirectTCP
 
   serverstring --> BrowseList

Network Identity Settings

DirectiveValueLinePurpose
workgroupWORKGROUPsmb.conf2Sets Windows workgroup name; matches default macOS SMB client expectations
netbios namesambaserversmb.conf6Defines the server's NetBIOS identity for network browsing and name resolution
server stringSamba Server %vsmb.conf5Human-readable description displayed in network browsers; %v expands to Samba version

Sources : smb.conf:2-6

Security and Authentication Model

The security configuration at smb.conf:3-4 implements a guest-only access model that eliminates password requirements while maintaining consistent file ownership:

graph TB
    subgraph "Configuration Directives"
        security["security = user\nLine 3"]
mapguest["map to guest = bad user\nLine 4"]
end
    
    subgraph "Client Connection Flow"
        MacOSClient["macOS Finder Client\nConnect as Guest"]
BadPassword["Any Username\nInvalid/No Password"]
end
    
    subgraph "Authentication Processing"
        UserCheck["Samba Authentication Check"]
GuestMap["Map to Guest Account"]
ForceUserApply["Apply force user = sshuser"]
end
    
    subgraph "Resulting Access"
        SSHUserAccess["All Operations as sshuser\nUID 1000, GID 1000"]
FilesystemOps["Filesystem Operations\nVia /samba-share symlink"]
end
    
 
   security --> UserCheck
 
   mapguest --> GuestMap
    
 
   MacOSClient --> BadPassword
 
   BadPassword --> UserCheck
 
   UserCheck -->|User doesn't exist| GuestMap
 
   GuestMap --> ForceUserApply
 
   ForceUserApply --> SSHUserAccess
 
   SSHUserAccess --> FilesystemOps
DirectiveValueLineBehavior
securityusersmb.conf3Requires user-level authentication (not share-level); enables per-user access control but overridden by map to guest
map to guestbad usersmb.conf4Converts any connection with an invalid username into a guest connection; effectively disables password authentication

The bad user mapping combined with guest only = yes in the share definition creates a passwordless authentication flow where any connection attempt succeeds as guest access, then force user ensures all operations execute as sshuser.

Sources : smb.conf:3-4

Protocol Version Enforcement

Lines smb.conf:7-8 enforce minimum SMB protocol versions, eliminating support for the deprecated SMB1 protocol:

graph LR
    subgraph "Protocol Configuration"
        ClientMin["client min protocol = SMB2\nLine 7"]
ServerMin["server min protocol = SMB2\nLine 8"]
end
    
    subgraph "Supported Protocols"
        SMB2["SMB 2.0\n✓ Supported"]
SMB21["SMB 2.1\n✓ Supported"]
SMB3["SMB 3.x\n✓ Supported"]
end
    
    subgraph "Rejected Protocols"
        SMB1["SMB 1.0 / CIFS\n✗ Rejected"]
end
    
 
   ClientMin --> SMB2
 
   ServerMin --> SMB2
 
   ClientMin --> SMB21
 
   ServerMin --> SMB21
 
   ClientMin --> SMB3
 
   ServerMin --> SMB3
    
 
   ClientMin -.->|Blocks| SMB1
 
   ServerMin -.->|Blocks| SMB1
    
    subgraph "Security Benefits"
        NoSMB1Vulns["Eliminates SMB1\nSecurity Vulnerabilities"]
end
    
 
   SMB1 --> NoSMB1Vulns
DirectiveValueLineEffect
client min protocolSMB2smb.conf7Prevents Samba from acting as client using SMB1 (not directly relevant for this server-only use case)
server min protocolSMB2smb.conf8Rejects client connections attempting to use SMB1; enforces modern protocol versions

Modern macOS versions default to SMB2+ for new connections, making this configuration transparent for most users while preventing potential SMB1-related security issues.

Sources : smb.conf:7-8


Share Configuration Section

The [SSHFS Share] section at smb.conf:10-19 defines the actual network share that macOS clients connect to. This configuration establishes the critical link between the Samba server and the SSHFS-mounted filesystem.

graph TB
    subgraph "Share Configuration"
        ShareName["[SSHFS Share]\nLine 10"]
Path["path = /samba-share\nLine 11"]
Browseable["browseable = yes\nLine 16"]
end
    
    subgraph "Filesystem Structure"
        SambaShareDir["/samba-share Directory\nchmod 777\nCreated by Dockerfile"]
SymLink["/samba-share/remote\nSymbolic Link"]
RemoteMount["/remote Mount Point\nSSHFS Target"]
end
    
    subgraph "macOS Access"
        FinderBrowser["Finder Network Browser\nShows: SSHFS Share"]
MountPoint["Mounted Volume\nsmb://container-ip/SSHFS Share"]
end
    
 
   ShareName --> Path
 
   Path --> SambaShareDir
 
   Browseable --> FinderBrowser
    
 
   SambaShareDir --> SymLink
 
   SymLink -.->|Links to| RemoteMount
    
 
   FinderBrowser --> MountPoint
 
   MountPoint --> SambaShareDir

Share Path and Visibility

DirectiveValueLinePurpose
Share nameSSHFS Sharesmb.conf10Display name shown in macOS Finder network browser; spaces are preserved in SMB share names
path/samba-sharesmb.conf11Root directory served by this share; contains the symbolic link to /remote SSHFS mount point
browseableyessmb.conf16Makes share visible in network browsing; allows discovery without knowing share name in advance

The share name SSHFS Share (with space) appears verbatim in macOS Finder. The directory at /samba-share must exist with appropriate permissions (set to 777 by the Dockerfile) before Samba starts.

Sources : smb.conf:10-16

Write Access Configuration

The configuration at smb.conf:12-18 enables full read-write access with permissive file creation masks:

DirectiveValueLineEffect
writableyessmb.conf12Enables write operations (create, modify, delete); opposite of read only
read onlynosmb.conf15Explicitly disables read-only mode; redundant with writable = yes but included for clarity
create mask0777smb.conf17Sets permission mask for newly created files to full access (owner/group/other all have rwx)
directory mask0777smb.conf18Sets permission mask for newly created directories to full access

The 0777 masks are unusually permissive but necessary for this use case because:

  1. The force user directive causes all operations to run as sshuser
  2. SSHFS mount options set uid=1000,gid=1000 matching sshuser
  3. Files created must be accessible regardless of how they're accessed (via SMB or direct container shell)

Sources : smb.conf:12-18

Guest Access Enforcement

Lines smb.conf:13-14 enforce guest-only access at the share level, complementing the global map to guest setting:

graph TB
    subgraph "Global Settings"
        GlobalSecurity["security = user\nLine 3"]
MapGuest["map to guest = bad user\nLine 4"]
end
    
    subgraph "Share Settings"
        GuestOK["guest ok = yes\nLine 13"]
GuestOnly["guest only = yes\nLine 14"]
end
    
    subgraph "Connection Attempts"
        ValidUser["Valid Username\n+ Correct Password"]
InvalidUser["Invalid Username\n+ Any Password"]
Guest["Explicit Guest Connection"]
end
    
    subgraph "Authentication Result"
        AllGuest["All Connections\nAuthenticated as Guest"]
end
    
 
   GlobalSecurity --> MapGuest
 
   MapGuest --> GuestOK
 
   GuestOnly --> AllGuest
    
 
   ValidUser --> MapGuest
 
   InvalidUser --> MapGuest
 
   Guest --> GuestOK
    
 
   MapGuest --> AllGuest
 
   GuestOK --> AllGuest
DirectiveValueLineBehavior
guest okyessmb.conf13Allows guest connections to this share; permits access without valid credentials
guest onlyyessmb.conf14Forces all connections to use guest access even if valid credentials are provided; prevents authenticated access

The combination of guest ok = yes and guest only = yes creates a mandatory guest access policy. Even if a user provides valid credentials, Samba ignores them and processes the connection as guest. This works in conjunction with force user to ensure consistent identity.

Sources : smb.conf:13-14

User Identity Mapping

The force user directive at smb.conf19 is the critical configuration that ensures filesystem operations have correct ownership:

graph TB
    subgraph "Configuration Chain"
        GuestAuth["Guest Authentication\nLines 13-14"]
ForceUser["force user = sshuser\nLine 19"]
SSHUserAccount["sshuser Account\nUID 1000, GID 1000"]
end
    
    subgraph "SSHFS Mount"
        MountOptions["sshfs -o uid=1000,gid=1000\nMount Options"]
RemoteMount["/remote Mount Point\nOwned by UID 1000"]
end
    
    subgraph "Filesystem Operations"
        SambaWrite["SMB Write Request\nfrom macOS"]
ActualWrite["Filesystem Write\nas sshuser UID 1000"]
SSHFSWrite["SSHFS Operation\nto Remote Server"]
end
    
    subgraph "Permission Matching"
        UIDMatch["UID 1000 = UID 1000\nWrite Permission Granted"]
end
    
 
   GuestAuth --> ForceUser
 
   ForceUser --> SSHUserAccount
 
   SSHUserAccount --> ActualWrite
    
 
   MountOptions --> RemoteMount
 
   RemoteMount --> UIDMatch
 
   ActualWrite --> UIDMatch
    
 
   SambaWrite --> ActualWrite
 
   ActualWrite --> SSHFSWrite
DirectiveValueLinePurpose
force usersshusersmb.conf19Overrides the authenticated user identity; all filesystem operations execute as sshuser regardless of client credentials

Why This Matters : Without force user = sshuser, writes would fail because:

  1. Guest connections typically map to the nobody user
  2. The /remote SSHFS mount is owned by sshuser (UID 1000) due to mount options
  3. FUSE by default only allows the mounting user to access mounted filesystems
  4. Even with allow_other, write permissions depend on matching UIDs

The force user directive ensures that Samba's effective UID matches the SSHFS mount's ownership, enabling write access through the protocol bridge.

Sources : smb.conf19


graph TB
    subgraph "smb.conf Configuration"
        direction TB
        Global["[global] Section"]
Share["[SSHFS Share] Section"]
MapGuest["map to guest = bad user"]
ForceUser["force user = sshuser"]
Path["path = /samba-share"]
MinProtocol["server min protocol = SMB2"]
CreateMask["create mask = 0777"]
end
    
    subgraph "Dockerfile Setup"
        SSHUserCreate["RUN useradd -m -u 1000 sshuser"]
SambaShareMkdir["RUN mkdir -p /samba-share"]
SambaShareChmod["RUN chmod 777 /samba-share"]
SymlinkCreate["RUN ln -s /remote /samba-share/remote"]
end
    
    subgraph "FUSE Configuration"
        AllowOther["user_allow_other\nin /etc/fuse.conf"]
end
    
    subgraph "Runtime Operations"
        SSHFSMount["sshfs -o allow_other,uid=1000,gid=1000"]
SmbdProcess["smbd -F -S"]
MacOSConnection["macOS Finder\nSMB Connection"]
end
    
    subgraph "Filesystem Access"
        SambaRead["Read Operations\nvia /samba-share"]
SambaWrite["Write Operations\nas sshuser UID 1000"]
FUSEAccess["FUSE Mount Access\nallow_other enables"]
end
    
    %% Configuration dependencies
 
   ForceUser -.->|Requires user exists| SSHUserCreate
 
   Path -.->|Requires directory| SambaShareMkdir
 
   CreateMask -.->|Directory must be writable| SambaShareChmod
 
   Path -.->|Contains symlink| SymlinkCreate
    
    %% Runtime flow
 
   Global --> SmbdProcess
 
   Share --> SmbdProcess
 
   MinProtocol --> MacOSConnection
 
   MapGuest --> MacOSConnection
    
 
   SSHFSMount --> FUSEAccess
 
   AllowOther --> FUSEAccess
    
 
   SmbdProcess --> SambaRead
 
   SmbdProcess --> SambaWrite
 
   FUSEAccess --> SambaRead
 
   FUSEAccess --> SambaWrite
    
    %% Critical path
 
   ForceUser --> SambaWrite
 
   SSHFSMount -.->|UID must match| SambaWrite

Configuration Integration Map

This diagram shows how smb.conf directives integrate with other system components:

Sources : smb.conf:1-20


Security Implications

The smb.conf configuration implements a convenience-over-security model appropriate for local development but not production environments:

Security Trade-offs Table

Configuration ChoiceSecurity ImpactRationale
map to guest = bad user❌ No authentication requiredEliminates password friction for local development; container ports bound to 127.0.0.1 limits exposure
guest only = yes❌ Valid credentials ignoredEnsures consistent behavior; prevents confusion when credentials are provided but unused
create mask = 0777❌ World-writable filesRequired for UID/GID consistency across SMB and direct container access
directory mask = 0777❌ World-writable directoriesPrevents permission issues when accessing via different methods
force user = sshuser⚠️ Single user identityEnables write access through SSHFS mount; loses audit trail of actual user
server min protocol = SMB2✅ Blocks SMB1 vulnerabilitiesModern protocol enforcement reduces attack surface
Ports bound to 127.0.0.1✅ Localhost-only accessPrevents external network exposure despite guest access (requires Docker run configuration)

Mitigating Factors

The security model is acceptable for local development because:

  1. Network isolation : Docker run command binds ports to 127.0.0.1, preventing LAN access
  2. Temporary containers : Development containers are typically short-lived and frequently rebuilt
  3. Single-user context : Developer's workstation is single-user; no multi-tenant concerns
  4. Controlled environment : User has root access to host system anyway; container provides convenience not security boundary

Production Considerations

For production use, this configuration would require modifications:

  • Implement user authentication (remove map to guest)
  • Use restrictive create masks (0644 for files, 0755 for directories)
  • Configure per-user force user based on authenticated identity
  • Enable SMB signing and encryption
  • Use certificate-based authentication for SMB3+

Sources : smb.conf:3-19


graph TB
    subgraph "Required Alignments"
        direction TB
        
        Alignment1["force user = sshuser\n↕\nuseradd -u 1000 sshuser\n↕\nsshfs -o uid=1000"]
Alignment2["path = /samba-share\n↕\nmkdir -p /samba-share\n↕\nln -s /remote /samba-share/remote"]
Alignment3["create mask = 0777\n↕\nchmod 777 /samba-share\n↕\nsshfs -o allow_other"]
Alignment4["guest ok = yes\n↕\nmap to guest = bad user\n↕\nmacOS Connect as Guest"]
end
    
    subgraph "Failure Modes"
        direction TB
        
        Failure1["UID Mismatch\n→ Permission denied on write"]
Failure2["Missing Directory\n→ smbd fails to start"]
Failure3["Permission Conflict\n→ FUSE denies Samba access"]
Failure4["Auth Mismatch\n→ Connection rejected"]
end
    
 
   Alignment1 -.->|If misaligned| Failure1
 
   Alignment2 -.->|If misaligned| Failure2
 
   Alignment3 -.->|If misaligned| Failure3
 
   Alignment4 -.->|If misaligned| Failure4

Critical Configuration Dependencies

Certain smb.conf settings must align with other system configurations or functionality breaks:

Dependency Matrix

smb.conf SettingMust MatchLocationVerification Command
force user = sshuserUser account with UID 1000Dockerfileid sshuser should show uid=1000
force user = sshuserSSHFS mount uid=1000Mount command`mount
path = /samba-shareExisting directoryDockerfilels -ld /samba-share should exist with 777
path = /samba-shareContains symlink to /remoteDockerfilels -l /samba-share/remote should show symlink
create mask = 0777Directory permissions 777Dockerfilestat -c %a /samba-share should return 777
guest ok = yesmap to guest = bad user in [global]smb.conf4Both directives must be present
server min protocol = SMB2macOS SMB client versionmacOS 10.11+Modern macOS defaults to SMB2+

Sources : smb.conf:1-20


sequenceDiagram
    participant smbd as smbd Process
    participant config as smb.conf
    participant fs as Filesystem
    participant client as macOS Client
    participant mount as SSHFS Mount
    
    Note over smbd: Container starts
    smbd->>config: Parse /etc/samba/smb.conf
    smbd->>fs: Verify /samba-share exists
    fs-->>smbd: Directory found (777 permissions)
    smbd->>smbd: Bind ports 139, 445
    smbd->>smbd: Enable SMB2+ only
    Note over smbd: Ready to accept connections
    
    client->>smbd: SMB connection request
    smbd->>config: Check [global] security settings
    config-->>smbd: map to guest = bad user
    smbd->>smbd: Authenticate as guest
    
    client->>smbd: Browse shares
    smbd->>config: Read [SSHFS Share] section
    config-->>smbd: browseable = yes
    smbd-->>client: Return share list: SSHFS Share
    
    client->>smbd: Mount "SSHFS Share"
    smbd->>config: Get path directive
    config-->>smbd: path = /samba-share
    smbd->>config: Get force user directive
    config-->>smbd: force user = sshuser
    smbd->>fs: Access /samba-share as sshuser
    fs-->>smbd: Access granted (UID 1000)
    smbd-->>client: Mount success
    
    client->>smbd: Write file request
    smbd->>config: Check writable setting
    config-->>smbd: writable = yes
    smbd->>config: Get create mask
    config-->>smbd: create mask = 0777
    smbd->>fs: Create file as sshuser (0777)
    fs->>mount: Write propagates to SSHFS
    mount-->>fs: Write complete
    fs-->>smbd: File created
    smbd-->>client: Write success

Runtime Behavior

When the Samba daemon starts with this configuration, it produces the following behavior:

Sources : smb.conf:1-20


graph TB
    subgraph "Layer 3: Remote Server"
        RemoteFS["Remote Filesystem\nSSH Server"]
end
    
    subgraph "Layer 2: Docker Container"
        direction TB
        
        SSHFS["SSHFS Client\nuid=1000,gid=1000\nallow_other"]
RemoteMount["/remote Mount Point\nFUSE Filesystem"]
Symlink["/samba-share/remote\nSymbolic Link"]
SambaDir["/samba-share\nRoot Directory\nchmod 777"]
SmbConf["smb.conf\nConfiguration File"]
Smbd["smbd Daemon\nServing /samba-share"]
end
    
    subgraph "Layer 1: macOS Host"
        Finder["macOS Finder\nSMB Client"]
end
    
    %% Connections
 
   RemoteFS -->|SSH Protocol| SSHFS
 
   SSHFS -->|Mounts to| RemoteMount
 
   RemoteMount -.->|Linked by| Symlink
 
   Symlink -->|Points to| SambaDir
 
   SambaDir -->|Contains| Symlink
    
 
   SmbConf -->|Configures| Smbd
 
   SmbConf -.->|Defines path = /samba-share| SambaDir
 
   SmbConf -.->|Defines force user = sshuser| SSHFS
    
 
   Smbd -->|Serves| SambaDir
 
   Finder -->|SMB Protocol| Smbd
    
    style SmbConf fill:#fff4e1

Relationship to System Architecture

The smb.conf file sits at a critical integration point in the three-tier architecture:

The configuration file's path directive connects Samba to the filesystem layer, while force user ensures UID alignment with SSHFS mount ownership. Without correct smb.conf settings, the protocol bridge fails even if SSHFS and Samba are both operational.

Sources : smb.conf:11-19