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.

Network Architecture

Relevant source files

Purpose and Scope

This page explains the network configuration of the sshfs-mac-docker system, including port mappings, container networking, and the critical limitation that prevents localhost-based SMB connections. For information about the protocols themselves (SSH and SMB), see Protocol Translation. For security implications of the network design, see Security Model.


Port Mapping Configuration

The container exposes Samba services through explicit port forwarding defined in the docker run command:

These port mappings bind the container's Samba ports to the host's localhost interface only.

Port Definitions

PortProtocolPurpose
139NetBIOS Session ServiceLegacy SMB over NetBIOS
445SMB over TCP/IPModern SMB direct over TCP

Both ports are mapped to ensure compatibility with different macOS versions and SMB client configurations. The 127.0.0.1 prefix restricts access to the host machine only, preventing external network exposure.

Sources: README.md31 README.md34 Dockerfile27


Docker Bridge Network Topology

The container operates on Docker's default bridge network, receiving a dynamically assigned IP address in the 172.17.0.0/16 subnet (typical default). This creates a two-tier network architecture:

Diagram: Docker Bridge Network Topology

graph TB
    subgraph HostNetwork["macOS Host Network Space"]
HostLoopback["127.0.0.1\n(localhost)"]
HostPhysical["Physical Network Interfaces"]
FinderClient["Finder SMB Client"]
end
    
    subgraph DockerBridge["Docker Bridge Network (172.17.0.0/16)"]
ContainerIP["Container IP\n(e.g., 172.17.0.2)\nDynamically Assigned"]
subgraph Container["docker-sshfs Container"]
Port139["Port 139\n(NetBIOS)"]
Port445["Port 445\n(SMB/TCP)"]
SmbdProcess["smbd process"]
end
    end
    
    subgraph ExternalNetwork["External Network"]
RemoteSSH["Remote SSH Server\nPort 22"]
end
    
 
   HostLoopback -.->|Port Forwarding -p 127.0.0.1:139:139| Port139
 
   HostLoopback -.->|Port Forwarding -p 127.0.0.1:445:445| Port445
    
 
   Port139 --> SmbdProcess
 
   Port445 --> SmbdProcess
    
 
   FinderClient -->|Direct Connection smb://172.17.0.2| ContainerIP
 
   ContainerIP --> SmbdProcess
    
 
   Container -->|Outbound SSH Port 22| RemoteSSH
    
 
   HostPhysical -.->|Docker NAT| DockerBridge

The container exists in an isolated network namespace with its own IP address. Port forwarding creates a mapping from 127.0.0.1 on the host to the container's internal ports, but this forwarding has limitations (see next section).

Sources: README.md:57-61


The Localhost Limitation

A critical quirk of this system is that macOS Finder cannot connect to the Samba share usingsmb://127.0.0.1 or smb://localhost, despite the port forwarding configuration. Instead, clients must use the container's internal Docker IP address.

Discovery of Container IP

The container's IP address must be discovered dynamically using Docker's inspection command:

This command queries the container's network settings and returns the assigned IP address (e.g., 172.17.0.2).

Technical Explanation

The localhost limitation exists because:

  1. Port forwarding operates at Layer 4 (transport layer), forwarding TCP connections from 127.0.0.1 to the container
  2. SMB protocol negotiation includes hostname/IP checks at the application layer
  3. macOS's SMB client validates the target address during connection establishment
  4. When connecting to 127.0.0.1, the SMB client receives responses from a different IP address (the container's bridge IP), causing address mismatch errors

The workaround is to bypass port forwarding entirely and connect directly to the container's IP address on the Docker bridge network. This works because:

  • Docker's default bridge network is accessible from the host
  • The container's ports (139, 445) are directly reachable on the bridge network
  • No address translation occurs, avoiding SMB protocol conflicts

Platform Differences

The README notes that OrbStack is highly recommended over Docker Desktop for this reason. OrbStack provides better network transparency between the host and container networks, making direct container IP connections more reliable.

Sources: README.md:57-58 README.md:60-61 README.md9


Connection Types and Directions

The system handles two distinct types of network connections with different security profiles:

Diagram: Bidirectional Network Connections

graph LR
    subgraph Inbound["Inbound Connections (SMB)"]
MacOS["macOS Finder"]
Direction1["Direction: IN"]
Destination1["Container Port 139/445"]
Security1["Security: Localhost-only\nvia port forwarding"]
end
    
    subgraph Container["Container Network"]
SmbdSvc["smbd service"]
SSHFSClient["sshfs client"]
end
    
    subgraph Outbound["Outbound Connections (SSH)"]
RemoteHost["Remote SSH Server"]
Direction2["Direction: OUT"]
Source2["Container (any port)"]
Security2["Security: Encrypted SSH\nNo firewall required"]
end
    
 
   MacOS -->|smb://172.17.0.2| SmbdSvc
 
   SSHFSClient -->|Port 22| RemoteHost
    
 
   Direction1 -.-> Destination1
 
   Direction2 -.-> Source2
 
   Security1 -.-> MacOS
 
   Security2 -.-> RemoteHost

Inbound (SMB)

  • Source: macOS Finder on the host
  • Destination: Container ports 139/445
  • Protocol: SMB/CIFS
  • Security: Port forwarding limits access to 127.0.0.1, but clients connect via container IP
  • Configuration: Defined in docker run command

Outbound (SSH)

  • Source: Container's sshfs client process
  • Destination: Remote SSH server, port 22 (standard SSH)
  • Protocol: SSH with FUSE extensions
  • Security: Encrypted SSH tunnel, uses standard SSH authentication
  • Configuration: Specified in sshfs mount command arguments

Sources: README.md31 README.md49


flowchart TD
    subgraph macOS["macOS Host (127.0.0.1)"]
Finder["Finder Client"]
DockerCLI["docker inspect command"]
end
    
    subgraph DockerNet["Docker Bridge Network"]
ContainerNS["Container Network Namespace\n(172.17.0.x)"]
subgraph Ports["Exposed Ports"]
P139["Port 139"]
P445["Port 445"]
end
        
        subgraph Services["Running Services"]
Smbd["smbd\n(Samba daemon)"]
SSHFS["sshfs\n(FUSE client)"]
end
        
        subgraph Storage["Filesystem"]
SambaDir["/samba-share"]
RemoteDir["/remote"]
SymLink["Symbolic Link\n/samba-share/remote"]
end
    end
    
    subgraph External["External Network"]
RemoteServer["Remote SSH Server\nuser@host:path"]
end
    
 
   DockerCLI -->|Query container IP| ContainerNS
 
   ContainerNS -->|Return 172.17.0.x| DockerCLI
    
 
   Finder -->|1. SMB Connection smb://172.17.0.x| P445
 
   P445 --> Smbd
 
   Smbd -->|2. Serve files from| SambaDir
 
   SambaDir -.->|3. Contains symlink| SymLink
 
   SymLink -.->|4. Points to| RemoteDir
 
   RemoteDir -->|5. Mounted by| SSHFS
 
   SSHFS -->|6. SSH Protocol Port 22| RemoteServer
    
 
   RemoteServer -.->|7. File data returns| SSHFS
 
   SSHFS -.->|8. FUSE operations| RemoteDir
 
   RemoteDir -.->|9. Via symlink| SambaDir
 
   SambaDir -.->|10. SMB protocol| Smbd
 
   Smbd -.->|11. Network packets| P445
 
   P445 -.->|12. To macOS| Finder

Complete Network Flow

The following diagram shows the complete data path from macOS Finder to the remote SSH server:

Diagram: Complete Network Data Flow

Flow Stages

  1. IP Discovery: User runs docker inspect to find container IP
  2. SMB Connection: Finder connects to smb://172.17.0.x:445
  3. Request Routing: smbd receives request for files in /samba-share
  4. Symbolic Link Traversal: Path resolves to /remote via symlink
  5. FUSE Intercept: SSHFS intercepts filesystem operations on /remote
  6. SSH Transport: Request forwarded to remote server over SSH
  7. Remote Execution: Remote server performs actual filesystem operation
  8. Response Return: Data travels back through SSHFS → symlink → Samba → macOS

This multi-hop architecture explains why the system requires careful configuration of permissions (allow_other in SSHFS, force user in Samba) to maintain consistent access across all layers.

Sources: README.md:57-69 README.md49 Dockerfile30


Network Security Model

The network configuration implements a principle of least exposure :

ComponentNetwork ExposureJustification
Samba ports (139/445)Localhost only (127.0.0.1 binding)Prevents external network access to file shares
Container IPDocker bridge network onlyNot exposed to external networks without additional Docker configuration
SSH clientOutbound onlyNo inbound SSH access to container; connects to remote servers

The --privileged flag required for the container is for FUSE operations, not network access. Network restrictions are maintained through port binding and Docker's default firewall rules.

For detailed security implications, including authentication and permission models, see Security Model.

Sources: README.md31 README.md34


Platform-Specific Considerations

OrbStack vs Docker Desktop

The README strongly recommends OrbStack over Docker Desktop due to networking differences:

  • OrbStack: Provides seamless network integration between host and container, making direct container IP connections reliable
  • Docker Desktop: May require additional network route modifications for SMB to function properly

The exact networking behavior depends on Docker Desktop's version and configuration, particularly its VM-based networking on macOS.

For more details on platform-specific setup, see Prerequisites and Platform Requirements. For troubleshooting Docker Desktop networking issues, see Platform-Specific Issues.

Sources: README.md9