Making home FreeBSD torrent+NAS server

Key Takeaways

  • Don’t run this build as written. It targets FreeBSD 11, which reached end of life on 30 September 2021 and has received no security fixes since.
  • Three things in the original config were bad practice even in 2017: root SSH login, a world-writable share, and a Transmission RPC interface with its whitelist disabled. Corrections below.
  • portsnap is gone. It was removed in FreeBSD 14 — use pkg, or git clone the ports tree if you genuinely need to build from source.
  • You almost certainly don’t need to compile anything. Packages cover Samba and Transmission. The make.conf tuning in the original bought nothing measurable.
  • The structure still holds up: a small BSD box doing file sharing and torrents alongside a lab hypervisor is a good use of spare RAM. Only the details have moved on.

This was written in 2017 as notes from a box I built and ran, not a walkthrough assembled from documentation — a FreeBSD VM on the same VMware host as the home lab, doing Samba and Transmission. It stayed useful for a long time, and it is one of the most-read posts on the site, which is exactly why leaving it unmarked would be the wrong call now.

The original walkthrough is kept below as the record of what ran. Read this section first.

The FreeBSD Beastie mascot

What has changed since 2017

The release is end-of-life

FreeBSD 11.4 and the stable/11 branch went end of life on 30 September 2021. Nothing on that branch has had a security advisory applied since. If you have a box still running it — plausible, these things are quiet and get forgotten — that is the finding, not the Samba config.

FreeBSD 14.4 and 15.1 are the current releases at the time of writing. The installation section below is the part that has aged worst: there is no reason to hand-place a pre-built VMDK now, and the installer handles ZFS root properly.

portsnap no longer exists

The original uses portsnap fetch / portsnap extract to get the ports tree. From the FreeBSD 14.0 release notes:

The portsnap(8) utility has been removed. Users are encouraged to fetch the ports tree by using pkg install git and then git clone https://git.FreeBSD.org/ports.git /usr/ports.

The portsnap infrastructure itself was retired in April 2026, so the old commands do not merely warn — they have nothing to talk to.

Build from ports only if you have a reason

The original compiles Samba and Transmission from ports, inside screen, with a tuned make.conf. That was a fairly normal thing to do in 2017 and it is hard to justify now:

pkg install samba419 transmission-daemon

Binary packages, minutes rather than hours, and they update with pkg upgrade. Ports are still the right answer when you need a non-default build option — but “I want it faster” is not that reason. The CPUTYPE and -O3 -funroll-loops settings in the original make.conf are cargo cult: -O3 is not a supported optimisation level for the base system, it produces larger binaries with no reliable gain for I/O-bound workloads like these, and it occasionally produces subtly broken ones.

Three security problems in the original

PermitRootLogin yes — the original enables it to get in over SSH after the initial console setup. Don’t. Create a user, add it to wheel, and use su or doas:

pw useradd mike -m -G wheel -s /bin/sh
passwd mike

Better still, put a key in ~/.ssh/authorized_keys and set PasswordAuthentication no. The convenience the original was buying takes about ninety seconds to replace properly.

A world-writable sharemkdir /data && chmod 777 /data, with guest ok and map to guest = Bad Password in smb4.conf, is an anonymous read-write share for anyone who can reach port 445. On a flat home LAN in 2017 that felt fine. It is the same posture that makes a NAS the first thing ransomware finds today. Use real accounts:

[global]
    workgroup = WORKGROUP
    server string = NAS
    server min protocol = SMB2_10
    restrict anonymous = 2

[data]
    path = /data
    valid users = @nas
    read only = no
    create mask = 0660
    directory mask = 0770

Add users with pdbedit -a, and note server min protocol — SMB1 is off by default in current Samba and should stay off.

"rpc-whitelist-enabled": false — this is the one to fix first. It leaves Transmission’s RPC interface, and its web UI, open to any host that can reach port 9091, with no authentication configured. Transmission’s RPC lets a caller set the download directory and add torrents, which has been used as a remote code execution path more than once. Set it the other way round:

"rpc-bind-address": "192.168.1.100",
"rpc-whitelist-enabled": true,
"rpc-whitelist": "127.0.0.1,192.168.1.*",
"rpc-authentication-required": true,
"rpc-username": "mike",
"rpc-password": "put-a-real-one-here",

Stop the daemon before editing settings.json — Transmission rewrites the file on exit and will overwrite your changes otherwise. That is the detail that catches everyone.

Storage: use ZFS

ZFS is a combined filesystem and volume manager that checksums every block it stores, so it can detect and, given redundancy, repair silent corruption that a traditional filesystem would hand back to you intact-looking and wrong. The original does not mention filesystems, which means UFS on a single virtual disk. FreeBSD’s installer has offered root-on-ZFS for years and there is no reason to skip it on a file server. Checksums that catch silent corruption, snapshots before an upgrade, and zfs send for backups are the entire point of running BSD for this job.

zfs create -o mountpoint=/data tank/data
zfs set compression=lz4 tank/data
zfs snapshot tank/data@before-upgrade

Jails, if you want to be tidy

Jails are FreeBSD’s native OS-level virtualisation: a jailed process gets its own filesystem root, users and network stack while sharing the host kernel, which makes them cheaper than a VM and stronger than a chroot. The original runs Samba and Transmission side by side in one userland. Jails were available then and are easier now — bastille or plain vnet jails will separate the torrent client, which is the process handling untrusted input from the internet, from the file server holding the data. Not essential for a home box. A good habit if you are building this to learn.

One more term worth pinning down, because it is the reason this box exists at all. Samba is the open-source implementation of the SMB/CIFS protocol, which is what lets a Unix machine present shared folders that Windows, macOS and Linux clients all mount natively.

Would I build it this way now?

Probably not as a VM under VMware. The original build existed to squeeze a NAS out of a lab host’s spare RAM, and that constraint has largely gone — a small dedicated box with ZFS and a couple of mirrored disks is cheap, and it separates “storage I care about” from “lab I rebuild constantly”, which turned out to be the real lesson.

The FreeBSD part still stands up. ZFS, jails, and a base system that does not churn are genuinely good properties for something that should run untouched for years. Just start from a supported release.

Sources


The original 2017 build

Kept as written, for reference. It targets FreeBSD 11 and contains the issues described above — read the section on security problems before copying any of it.

Basically, it would be a VMware virtual machine.

Why FreeBSD? Just for fun — and I had a hope to save some RAM on my home-lab VMware host.

FreeBSD 11 installation

Download the FreeBSD pre-cooked VMDK from https://download.freebsd.org/ftp/releases/VM-IMAGES/11.0-RELEASE/amd64/Latest/ and un-xz it with 7zip. Create a new FreeBSD VM, add the unpacked VMDK as an existing hard drive, and power it on.

Initial configuration

Set a root password with passwd, then add an address and enable SSH:

ifconfig em0 192.168.1.100/24
vi /etc/ssh/sshd_config     # uncomment PermitRootLogin yes
service sshd onestart

Create /etc/rc.conf:

hostname="server.example.com"
ifconfig_em0="inet 192.168.1.100 netmask 255.255.255.0"
defaultrouter="192.168.1.1"
sshd_enable="YES"
ifconfig_em0_ipv6="inet6 accept_rtadv"
rtsold_enable="YES"

Add a nameserver to /etc/resolv.conf, then update:

freebsd-update fetch
freebsd-update install
pkg update && pkg upgrade

VMware tools

FreeBSD 11 was not supported by VMware Tools, so Open VM Tools went on instead:

pkg install open-vm-tools-nox11

And in /etc/rc.conf:

vmware_guest_vmblock_enable="YES"
vmware_guest_vmhgfs_enable="NO"
vmware_guest_vmmemctl_enable="YES"
vmware_guest_vmxnet_enable="YES"
vmware_guestd_enable="YES"

Open VM Tools is four kernel modules and a daemon. vmmemctl is the memory ballooning driver. vmxnet is the paravirtualised network driver. vmhgfs backs VMware’s shared-files feature and is not worth enabling on a server, which is why it is off above. vmblock provides drag-and-drop from the remote console. guestd handles guest-to-host communication including time sync.

Samba and Transmission

Timezone and time sync first:

cp /usr/share/zoneinfo/Europe/Kaliningrad /etc/localtime
ntpdate 0.freebsd.pool.ntp.org

Then the ports tree, screen, and the two packages built from source:

portsnap fetch && portsnap extract
cd /usr/ports/sysutils/screen/ && make install clean
screen
cd /usr/ports/net/samba46/ && make -DBATCH install clean
cd /usr/ports/net-p2p/transmission/ && make -DBATCH install clean

screen keeps the build alive across a dropped SSH session — reattach with screen -r. -DBATCH tells the ports system to take the default options rather than stopping to ask, which matters when you are not going to sit and watch it.

Both to autostart:

echo 'samba_server_enable="YES"' >> /etc/rc.conf
echo 'transmission_enable="YES"' >> /etc/rc.conf

The share, and the daemon:

mkdir /data
service samba_server start
service transmission start

The Samba share appearing as a network location in a file browser

Transmission’s web interface then answers on port 9091:

The Transmission web interface running on the FreeBSD server


Related: How to make a private VPN server in 10 minutes, Telnet on macOS for EVE-NG

More about Mike →

← Previous
Next →