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.