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
| Port | Protocol | Purpose |
|---|---|---|
| 139 | NetBIOS Session Service | Legacy SMB over NetBIOS |
| 445 | SMB over TCP/IP | Modern 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:
- Port forwarding operates at Layer 4 (transport layer), forwarding TCP connections from
127.0.0.1to the container - SMB protocol negotiation includes hostname/IP checks at the application layer
- macOS's SMB client validates the target address during connection establishment
- 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 runcommand
Outbound (SSH)
- Source: Container's
sshfsclient 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
sshfsmount 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
- IP Discovery: User runs
docker inspectto find container IP - SMB Connection: Finder connects to
smb://172.17.0.x:445 - Request Routing:
smbdreceives request for files in/samba-share - Symbolic Link Traversal: Path resolves to
/remotevia symlink - FUSE Intercept: SSHFS intercepts filesystem operations on
/remote - SSH Transport: Request forwarded to remote server over SSH
- Remote Execution: Remote server performs actual filesystem operation
- 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 :
| Component | Network Exposure | Justification |
|---|---|---|
| Samba ports (139/445) | Localhost only (127.0.0.1 binding) | Prevents external network access to file shares |
| Container IP | Docker bridge network only | Not exposed to external networks without additional Docker configuration |
| SSH client | Outbound only | No 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