gosamba

module
v1.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 13, 2026 License: Apache-2.0

README

gosamba

A small, dependency-light SMB file server written in pure Go.

gosamba speaks the SMB2/SMB3 protocol directly, so it ships as a single static binary. It is designed to be easy to run on Linux for sharing a few directories with macOS, Windows, and iOS clients over the network.

It also builds and runs natively on macOS (darwin/amd64, darwin/arm64). Windows is not supported as a host platform. On macOS, binding :445 requires that the built-in SMB service (File Sharing / smbd) isn't already holding the port — disable macOS File Sharing or run gosamba on an alternate port with -l.

On macOS, the change-notify watcher opens one file descriptor per watched file/directory, so watching very large trees can hit the default 256 open-file limit — raise it with ulimit -n if you see notify setup failures on a big share.

Features

  • SMB2/SMB3 dialects — negotiates 2.0.2, 2.1, 3.0, 3.0.2, and 3.1.1.
  • Authentication — NTLMv2 over SPNEGO; passwords stored as NT hashes.
  • Encryption & signing — SMB3 encryption and message signing, required by default (configurable to preferred/off).
  • Durable handles — opens survive a dropped TCP connection and can be reclaimed after reconnect.
  • Locking, oplocks/leases, and change-notify for correct multi-client access.
  • Apple client support — AAPL create-context extensions and a synthesized AFP_AfpInfo stream so macOS Finder and the iOS Files app work smoothly.
  • Extended attributes & alternate data streams.
  • Safe path handling — symlink-escape and path-traversal protection keep access inside the share root.
  • Per-share access control — read-only and guest shares, with per-user share allow-lists.
  • Per-user privilege drop (optional) — serve each connection in a re-exec'd worker that drops to the authenticated user's uid/gid (requires root).
  • Zero-config discovery — advertises the service over mDNS/Bonjour so Apple clients find it automatically.
  • Flexible config — command-line flags, a TOML file, or both.

Build

Requires Go 1.25 or newer.

make build        # produces ./gosamba
# or
go build -o gosamba ./cmd/gosamba

Quick start

Share a single directory for one user — no system account required:

sudo mkdir -p /srv/files
sudo ./gosamba \
  --share /srv/files=public \
  --user alice:s3cret

This listens on :445 (the privileged SMB port, hence sudo), serves /srv/files as the share public, and authenticates the SMB user alice with password s3cret. Because no system_user was given, file operations run as the user that launched the server (here root). To drop to a specific account or uid instead, add a third field — see user mapping.

Connect from another machine:

smbclient //your-host/public -U alice

Note: passing a password on the command line with -u exposes it to other processes via /proc/<pid>/cmdline. For anything beyond a quick test, use a config file with a pre-computed nt_hash instead (see below).

Configuration

Command-line flags
Flag Description
-s, --share <path>[=<name>] Share a directory (repeatable). Name defaults to the basename.
-u, --user <smb_user>:<password>[:<system_user>] Define a user (repeatable). See user mapping.
-c, --config <file> Load a TOML config file.
-l, --listen <addr> Listen address (default :445).
--netbios Also bind the legacy NetBIOS port :139.
--mdns Advertise via mDNS/Bonjour (default on).
--no-encryption Allow non-encrypted SMB3 sessions.
--no-signing Allow unsigned messages.
--durable-timeout <dur> Durable-handle timeout, e.g. 60s.
--state-dir <path> Runtime state directory.
--per-user-privdrop Drop to each authenticated user's uid/gid (requires root).
--log-level <level> debug | info | warn | error.
--log-format <fmt> text | json.
-V, --version Print version and exit.
User mapping

The optional system_user field decides which OS identity a connection runs as, and whether gosamba privilege-drops:

-u form Runs as Privilege drop Reads /etc/passwd?
smb:pass the current process user no no
smb:pass:1000 uid 1000, gid 1000 yes, if uid differs from current no
smb:pass:1000/1001 uid 1000, gid 1001 yes, if uid differs from current no
smb:pass:alice system user alice yes, if it differs from current yes

Privilege drop only happens when the target uid differs from the current one and the server runs as root (per-connection, via a re-exec'd worker). Use a numeric system_user (or omit it) on minimal images such as the scratch container, which has no /etc/passwd — a named system_user requires it.

TOML config file

For production use, prefer a config file with NT-hashed passwords. The file must not be group/world-writable (mode ≤ 0640).

[server]
listen     = ":445"
encryption = "required"   # required | preferred | off
signing    = "required"   # required | preferred
mdns       = true

[log]
level  = "info"           # debug | info | warn | error
format = "text"           # text | json

[[share]]
name      = "public"
path      = "/srv/files"
read_only = false
guest_ok  = false

[[user]]
name         = "alice"
nt_hash      = "d4c619cb16d4632b275658316a7e657e"  # 32 hex chars (16-byte NT hash)
system_user  = "alice"    # optional: name, uid (e.g. "1000"), or uid/gid ("1000/1001")
allow_shares = ["public"]

Generate an nt_hash from a password with the built-in hash subcommand:

gosamba hash                          # prompts for the password
printf '%s' 's3cret' | gosamba hash   # or read it from stdin

Run with:

sudo ./gosamba -c /etc/gosamba.toml

Flags and the config file can be combined — explicit flags override file values.

Architecture

The codebase is split into focused internal packages:

Package Responsibility
cmd/gosamba Entry point, flag/config wiring, server lifecycle.
internal/config CLI + TOML parsing, merge, and validation.
internal/transport SMB direct-TCP framing.
internal/smb2 / internal/smb3 Protocol message codecs and negotiate logic.
internal/parent Connection/session handling, dispatch, and per-connection worker model.
internal/ntlm NTLMv2 authentication.
internal/userdb In-memory user store.
internal/vfs Safe filesystem access (path resolution, traversal guards).
internal/discovery mDNS/Bonjour advertisement.
internal/inotify Filesystem change notifications.
internal/logging Structured logging.

The only external dependencies are the golang.org/x extensions (crypto, sys, net, text).

Development

make test         # go test ./...
make test-race    # race detector
make vet          # go vet
make fmt          # go fmt

Some end-to-end tests drive a real smbclient against the server. Install it with:

make e2e-deps     # apt-get install smbclient

Security notes

  • Encryption and signing are required by default; only relax them (--no-encryption / --no-signing) on trusted networks.
  • Prefer config-file nt_hash entries over plaintext -u passwords.
  • Binding :445 requires elevated privileges; consider --per-user-privdrop (as root) so each connection runs with the authenticated user's permissions.

License

Licensed under the Apache License, Version 2.0.

Directories

Path Synopsis
cmd
gosamba command
internal
discovery
Package discovery provides mDNS/Bonjour service advertisement so Apple clients (macOS Finder, iOS) can auto-discover the gosamba SMB server.
Package discovery provides mDNS/Bonjour service advertisement so Apple clients (macOS Finder, iOS) can auto-discover the gosamba SMB server.
inotify
Package inotify is a thin recursive-watch wrapper over Linux inotify.
Package inotify is a thin recursive-watch wrapper over Linux inotify.
logging
Package logging configures slog handlers per gosamba's config.
Package logging configures slog handlers per gosamba's config.
ntlm
Package ntlm implements the NTLMSSP message types and NTLMv2 verification needed for SMB3 SESSION_SETUP.
Package ntlm implements the NTLMSSP message types and NTLMv2 verification needed for SMB3 SESSION_SETUP.
parent
Package parent contains the privileged SMB-server bootstrap.
Package parent contains the privileged SMB-server bootstrap.
smb2
Package smb2 implements the SMB2/3 wire protocol.
Package smb2 implements the SMB2/3 wire protocol.
smb3
Package smb3 implements SMB 3.x crypto primitives: SP800-108 KDF, AES-CMAC.
Package smb3 implements SMB 3.x crypto primitives: SP800-108 KDF, AES-CMAC.
transport
Package transport implements the NetBIOS Session Service framing (RFC 1002 §4.3.1) used to carry SMB over TCP.
Package transport implements the NetBIOS Session Service framing (RFC 1002 §4.3.1) used to carry SMB over TCP.
vfs
Package vfs handles share-relative path resolution and filesystem-info helpers for the SMB protocol.
Package vfs handles share-relative path resolution and filesystem-info helpers for the SMB protocol.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL