Your own private cloud file share with Samba, Alpine Linux, and Nebula

There is a certain kind of person who looks at services like Dropbox or OneDrive and thinks: "Why would I let someone else hold my files when I can spend three hours on a Saturday doing it myself and have something objectively cooler?" If you are that kind of person, welcome. This article is for you.*
What we are building here is a private Samba file server running on Alpine Linux, accessible exclusively through a Nebula overlay network. The end result is a share that behaves like a classic network drive but lives on your own infrastructure and is, by design, invisible to the rest of the internet. No open ports. No exposed services. No surprises.
Why Nebula?
Nebula is a scalable, peer-to-peer overlay network built by Slack. It uses WireGuard-style cryptography, certificate-based authentication, and punches through NAT without needing a central relay. Nodes on a Nebula network can communicate directly with each other regardless of where they physically are, on a VPS, behind a home router, or on a laptop in a coffee shop.
The relevant property for this setup is that a service bound exclusively to a Nebula interface is simply not reachable from the public internet. There is no firewall rule to forget, no accidental exposure. If you are not on the Nebula network with a valid certificate, the service does not exist as far as you are concerned. That is not security through obscurity, that is just topology.
Prerequisites
- A server running Alpine Linux (this was tested on Alpine 3.23.2)
- Nebula installed and running on that server with a static Nebula IP (we will use
10.x.x.1as the example throughout) - A client machine also connected to the same Nebula network
- Basic comfort with the command line
Step 1: Install Samba
apk add samba
Alpine's package manager pulls in both smbd (the file sharing daemon) and nmbd (the name resolution daemon). After installation, /etc/samba/ exists and is ready to be configured.
Step 2: Create a system user
Each person who gets a share needs a corresponding system user. Samba relies on the underlying OS user database for file ownership, but we do not want these accounts to have any actual access to the server itself.
adduser -D -H -s /sbin/nologin alice
Breaking this down:
-D— do not set a system password. The account cannot be used for system login regardless, but this makes that explicit.-H— do not create a home directory under/home/. There is no reason for one.-s /sbin/nologin— assign/sbin/nologinas the shell. This is not a real shell. It is a small binary that prints "This account is currently not available" and terminates the session immediately. SSH, console login, su --> all blocked. The user exists purely as a system principal so that file ownership works correctly.
You can verify the effect yourself:
cat /etc/shells # lists all valid login shells on the system
cat /etc/passwd # shows every user and their assigned shell
/sbin/nologin is not listed in /etc/shells, which is what prevents it from being used as a login shell.
Step 3: Set a Samba password
Linux and Samba maintain completely separate password databases. The system uses /etc/shadow. Samba uses its own TDB (Trivial Database) file at /var/lib/samba/private/passdb.tdb. You can have a system account with no password and a perfectly valid Samba password, which is exactly what we want.
smbpasswd -a alice
The -a flag adds the user to Samba's password database and prompts you to set a password. This is what alice will use when mounting the share from her client.
Step 4: Create the user's directory
mkdir -p /mnt/alice
chown alice:alice /mnt/alice
chmod 700 /mnt/alice
mkdir -pcreates the directory, and the-pflag means it will not complain if the directory already exists.chown alice:alicesets both the owner and the group toalice. This is what ties the filesystem permissions to the Samba user.chmod 700means the owner can read, write, and traverse the directory. Nobody else can see it, let alone touch it.
Step 5: Check your Nebula interface name
Before writing the Samba configuration, identify the name of your Nebula network interface:
ip link show
Look for an interface with your Nebula IP. It will typically be nebula0 or nebula1, and its type will show as POINTOPOINT. Note the name — you will need the IP address in the next step.
ip a | grep nebula
In this setup the interface was nebula1 with the address 10.x.x.1/24.
Step 6: Configure Samba
cat > /etc/samba/smb.conf << 'EOF'
[global]
workgroup = WORKGROUP
server string = My Samba Server
security = user
map to guest = never
passdb backend = tdbsam
interfaces = lo 10.x.x.1/24
bind interfaces only = yes
disable netbios = yes
smb ports = 445
[alice]
path = /mnt/alice
valid users = alice
read only = no
browseable = yes
EOF
What each directive does and why it matters
[global] section:
security = user— clients must authenticate with a username and password. No anonymous access.map to guest = never— if authentication fails, the connection is dropped. There is no fallback to a guest session.passdb backend = tdbsam— use Samba's built-in TDB password database, which is whatsmbpasswdwrites to.interfaces = lo 10.x.x.1/24— instruct Samba to listen only on the loopback interface and the Nebula interface. The/24subnet notation is important here: Nebula uses aPOINTOPOINTtunnel interface, and without the subnet mask Samba may fail to bind to it correctly. This was the root cause of the issue encountered during this setup, without/24, Samba stubbornly listened only on127.0.0.1.bind interfaces only = yes— enforce the interface restriction strictly. Samba will not listen on any interface not listed above.disable netbios = yes— NetBIOS is a legacy broadcast-based name resolution protocol from the 1980s. We do not need it. Disabling it reduces noise and removes an unnecessary attack surface.smb ports = 445— modern SMB runs on TCP port 445. Port 139 (the old NetBIOS session port) is not needed.
[alice] section:
path— the filesystem path being shared.valid users— only the named user can access this share. Even if someone else on the Nebula network knows the share exists, they cannot authenticate into it.read only = no— the user can read and write. Self-explanatory.browseable = yes— the share appears in the share list when browsing to the server. Since the server is only reachable via Nebula and all Nebula nodes are trusted, hiding the share name provides no real benefit.
You can verify the configuration is syntactically valid before restarting anything:
testparm
Step 7: Start Samba and enable it on boot
Alpine uses OpenRC as its init system:
rc-service samba start
rc-update add samba default
rc-service samba start— starts bothsmbdandnmbdimmediately.rc-update add samba default— registers Samba in thedefaultrunlevel so it comes back up after a reboot without any manual intervention.
Verify that Samba is actually listening on the Nebula IP:
netstat -tlnp | grep 445
You want to see 10.x.x.1:445 in the output. If you only see 127.0.0.1:445, double-check that you included the /24 subnet mask in the interfaces line and restart.
Step 8: Connect from a client
From a macOS client connected to the same Nebula network, open Finder and press ⌘K, then enter:
smb://10.x.x.1/alice
On Windows, open File Explorer and go to:
\\10.x.x.1\alice
Authenticate with the Samba username and the password set in step 3. The share mounts as a regular network drive. You can map it permanently if you want it available at every login.
Adding more users
The process is entirely repeatable. For each new user:
adduser -D -H -s /sbin/nologin bob
smbpasswd -a bob
mkdir -p /mnt/bob
chown bob:bob /mnt/bob
chmod 700 /mnt/bob
Add a corresponding block to /etc/samba/smb.conf:
[bob]
path = /mnt/bob
valid users = bob
read only = no
browseable = yes
Then reload:
rc-service samba restart
Each user can see their own share and nothing else. Users cannot traverse into each other's directories due to the chmod 700 permissions, and the valid users directive in Samba provides an additional layer on top of that.
A note on backups
If you are running a backup job that archives /mnt/ (like I do) and you should be, all user shares under /mnt/ are automatically included without any changes to the backup configuration. There is nothing special about the Samba directories from the filesystem's perspective. They are just directories.
Why this is actually a private cloud share
The key property of this setup is that the Samba service is bound exclusively to a Nebula interface. No firewall rule is required to block access from the public internet because the service is not listening on any public interface in the first place. A port scanner hitting your server's public IP will find nothing on port 445.
Access requires two things: a valid Nebula certificate (issued by your Nebula certificate authority) and a valid Samba password. Both are required. One without the other is useless.
The result is a file share that is accessible from anywhere your Nebula nodes can reach each other, which is effectively anywhere with an internet connection, while remaining completely invisible to everyone else. That is a private cloud file share in the most literal sense of the word, without a third party holding your data, without a subscription, and without a monthly bill reminding you that convenience has a price.
The only thing it costs is a Saturday afternoon. Some would call that a bargain.