The hardware

I built this on an HP T620 … a thin client, not a real server. Dual-core AMD GX-217GA SoC, the kind of chip that used to sit in front of a cash register or a hospital terminal, not something anyone would call fast. No AES-NI either, which matters more than you’d think once you’re running encrypted traffic through it all day. If you’ve got something like this sitting in a drawer, it’s genuinely enough to run a small personal NAS. Don’t expect it to be quick. Expect it to just work, reliably, once it’s set up right.

Installing Fedora Server

I used the Fedora Server “Everything” ISO rather than the regular netinstall … it pulls a fuller package set from the start, which saved me chasing down individual packages later for things like samba, nfs-utils, cockpit, and firewalld that I knew I’d want anyway.

Standard install, nothing exotic. I did make one deliberate choice at partitioning: XFS for root, not ext4. XFS handles the kind of mixed read/write traffic a file server generates a bit better, and its journal tuning options gave me a real, measurable improvement later once I actually had Samba/SFTP traffic flowing through it.

The login banner

Small thing, did it early, still happy I did. Every time I SSH into this box, I get a real banner, not the generic Fedora default … tells me immediately which machine I’m on and that I should be paying attention:

sudo nano /etc/ssh/banner

Paste whatever ASCII art or plain text you want … mine’s a big block

 ░░█ ▄▀█ █▀▀ █▄▀ █▀ █▀█ ▄▀█ █▀█ █▀█ █▀█ █░█░█   ▀█
 █▄█ █▀█ █▄▄ █░█ ▄█ █▀▀ █▀█ █▀▄ █▀▄ █▄█ ▀▄▀▄▀   █▄


                      ()_/¯ 🌱

 ╔═══════════════════════════════════════════════════════╗
 ║   JackSparrow2 — HP T620 NAS | Fedora Server 44 ║   Authorised access only. All sessions are logged.    ║
 ╚═══════════════════════════════════════════════════════╝

                          🍄

“JACKSPARROW2” header, a small note about what the box actually is, and a line making clear sessions are logged. Then point sshd at it:

sudo nano /etc/ssh/sshd_config

Add or edit:

Banner /etc/ssh/banner
sudo sshd -t && sudo systemctl restart sshd

sshd -t first … validates the config before you actually restart the service, so a typo doesn’t lock you out of your own SSH session. Learned that habit the hard way on something else, kept it for everything since.

Samba … the actual file sharing

Install it:

sudo dnf install -y samba samba-client

Here’s the /etc/samba/smb.conf global section I landed on, after getting bitten by leaving anonymous access open by default without realising it:

[global]
restrict anonymous      = 2
access based share enum = yes
workgroup               = WORKGROUP
server string           = MyServer NAS
security                = user
map to guest            = never
server role             = standalone server
passdb backend          = tdbsam
min protocol            = SMB2
max protocol            = SMB3

map to guest = never and restrict anonymous = 2 together mean nobody gets in without a real account and password … no accidental open share reachable by anyone who finds the IP. I found this out by testing it myself with a fake username after the fact and being surprised it let me see a share I definitely didn’t mean to expose.

access based share enum = yes is the one I’d call genuinely essential if more than one person uses the box … it hides shares from the browse list entirely for anyone who isn’t allowed to access them, instead of just denying the connection after they’ve already seen the name.

Per-user home folders on the same server

This is the part that took me longest to get right, and the part most guides skip. I wanted each user to log in and land in their own private space, automatically, without me manually creating a share per person.

Samba has a built-in special share for exactly this:

[homes]
comment                 = Home Directories
browseable              = no
writable                = yes
valid users             = %S
create mask             = 0700
directory mask          = 0700

%S is the trick … it resolves to whatever share name is being requested, and for [homes] that’s automatically the connecting username. Brian connects, he lands in his own folder. Muriel connects, she lands in hers. Neither sees the other’s, and neither shows up in anyone else’s browse list.

Each person still needs an actual account to log in with:

sudo useradd -M -s /sbin/nologin brian
sudo smbpasswd -a brian

-M skips creating a real Linux home directory since Samba’s [homes] share handles that. -s /sbin/nologin means they get file access only … no shell, no SSH login, nothing beyond what Samba gives them.

SFTP … the part I fought with the most

I wanted SFTP too, not just Samba, so people could pull files without needing a full Samba client. The naive way is just enabling SFTP subsystem in sshd_config and calling it done … except that gives anyone with an account full filesystem browsing, not just their own folder. Not what I wanted.

The actual fix is a chroot jail per user. Add a group:

sudo groupadd sftpusers
sudo usermod -aG sftpusers brian

Then in sshd_config:

Match Group sftpusers
ChrootDirectory /srv/sftp/%u
ForceCommand internal-sftp
X11Forwarding no
AllowTcpForwarding no
PermitTunnel no

The one thing that cost me real time here: SSH refuses the entire session if the chroot directory itself isn’t owned root:root with 755 permissions … not the content inside it, the jail root folder specifically. Get that wrong and you don’t get a helpful error, you just get disconnected with no obvious reason why.

sudo mkdir -p /srv/sftp/brian/home
sudo chown root:root /srv/sftp/brian
sudo chmod 755 /srv/sftp/brian

Their actual files live one level in, bind-mounted from their real home directory:

sudo mount --bind /home/brian /srv/sftp/brian/home

That bind mount needs to survive a reboot or it silently stops working and nobody notices until someone can’t log in. Add it properly to /etc/fstab:

/home/brian   /srv/sftp/brian/home   none   bind,nofail   0 0

What I’d tell someone trying this themselves

Test the SSH banner and config with sshd -t before ever restarting the service … don’t lock yourself out over a typo. Set map to guest = never on Samba from day one, don’t find out later that guest access was quietly open. And if you’re doing per-user SFTP jails for more than one or two people, don’t hand-write the bind mounts one at a time … write one small script that loops through everyone and does it consistently, because you will forget the exact steps by the third person and start making small inconsistent mistakes.

None of this needed expensive hardware. It needed patience, a habit of actually reading the error messages instead of guessing, and a willingness to redo something three times until it was actually right, not just working by accident.