twinlakestech.com

Building a RAID 1 Storage Server with Linux and Samba

This is an old project I worked on to turn a Linux box into a simple network file server. The goal was to use two 1 TB hard drives in a RAID 1 array and then make the resulting storage available over the network using Samba.

RAID 1, also called mirroring, writes the same data to both drives. If one of the drives fails, the other drive still contains a complete copy of the data.

For this project, the Linux operating system was installed on a separate drive. The two 1 TB drives were dedicated to the RAID array.

The Plan

The basic layout was:

Linux OS drive
    ↓
/dev/sda

Western Digital Blue 1 TB x 2
    ↓
/dev/sdb ─┐
          ├── RAID 1 → /dev/md0 → /mnt/raid1
/dev/sdc ─┘

/mnt/raid1/sambashare
    ↓
Samba network share

Keeping the operating system on its own drive meant the two 1 TB drives could be dedicated entirely to the RAID array.

Identifying the Drives

I initially booted the system with only the operating system drive connected and used fdisk to identify it:

sudo fdisk -l

The output showed:

Disk /dev/sda
Disk identifier: 0x2ead5f4a

Device     Size     ID
/dev/sda1 238.5G   83

I then shut the system down and connected the two Western Digital Blue 1 TB drives.

After booting again, the drives appeared as:

/dev/sda  → Operating system drive
/dev/sdb  → 1 TB data drive
/dev/sdc  → 1 TB data drive

The two data drives were reported as approximately 931.5 GiB each. This is normal for a drive advertised as 1 TB because drive manufacturers use decimal units when calculating capacity, while Linux generally reports capacity using binary units.

Important: Device names such as /dev/sda, /dev/sdb, and /dev/sdc are not guaranteed to remain the same between boots or hardware changes. Before making any partitioning or RAID changes, always verify which physical drive corresponds to which device.

Preparing the Data Drives

I used fdisk to remove the existing partition information from the first data drive:

sudo fdisk /dev/sdb

Inside fdisk, I deleted the existing partition:

Command (m for help): d

and then wrote the changes:

Command (m for help): w

I repeated this process for the second data drive.

Creating New Partitions

I then created a new partition table and partition on the drives.

sudo fdisk /dev/sdb

Inside fdisk:

Command (m for help): o
Command (m for help): n

For the new partition, I accepted the default values so that the partition occupied the available space.

Finally, I wrote the changes:

Command (m for help): w

The same process was performed on /dev/sdc.

Marking the Partitions for RAID

My original notes used the old fd partition type, which was commonly described as Linux RAID autodetect:

Command (m for help): t
Command (m for help): fd

This was historically used to identify partitions intended for Linux software RAID.

Modern mdadm configurations generally do not require the old RAID autodetect partition type, so if you're following this guide on a current Linux installation, the important part is creating correctly sized partitions and using those partitions with mdadm. The exact partition type shown by fdisk may also depend on whether you're using an MBR or GPT partition table.

Installing mdadm

Linux software RAID is managed using mdadm, so I installed it with:

sudo apt install mdadm

mdadm provides the tools needed to create, inspect, maintain, and recover Linux software RAID arrays.

Checking the Drives Before Creating the Array

Before creating the RAID array, I used mdadm to examine the drives:

sudo mdadm -E /dev/sdb1 /dev/sdc1

The -E option displays RAID metadata information stored on a device.

This is a useful check before creating an array because it can reveal whether a drive already contains RAID metadata from a previous configuration.

Creating the RAID 1 Array

With both drives partitioned and ready, I created the RAID 1 array:

sudo mdadm --create /dev/md0 --level=1 --raid-devices=2 /dev/sdb1 /dev/sdc1

Here is what the command is doing:

Once created, the two physical drives are treated as a single RAID device:

/dev/sdb1 ─┐
           ├── /dev/md0
/dev/sdc1 ─┘

The RAID device is what I will eventually format and mount. I don't format the individual RAID member partitions with a normal filesystem.

Checking the RAID Array

I used mdadm to verify the RAID metadata:

sudo mdadm -E /dev/sdb1 /dev/sdc1

I also checked the array itself:

sudo mdadm --detail /dev/md0

The --detail command provides information about the array, including its RAID level, number of devices, state, and synchronization status.

When a RAID 1 array is first created, the drives need to synchronize with each other. Depending on the size and speed of the drives, this process can take some time.

Creating a Filesystem

Once the RAID device was created, I formatted it with the ext4 filesystem:

sudo mkfs.ext4 /dev/md0

The important distinction here is that the filesystem is created on /dev/md0, not directly on /dev/sdb1 or /dev/sdc1.

The RAID layer sits underneath the filesystem:

ext4
  ↓
/dev/md0
  ↓
RAID 1
  ↓
/dev/sdb1 + /dev/sdc1

Creating the Mount Point

I created a directory where the RAID filesystem would be mounted:

sudo mkdir /mnt/raid1

Then I mounted the RAID device:

sudo mount /dev/md0 /mnt/raid1/

At this point, /mnt/raid1 provides access to the storage contained within the RAID array.

I could verify the mounted filesystem with:

df -h

Configuring the RAID to Start Automatically

I wanted the RAID filesystem to be available automatically after rebooting, so I added it to /etc/fstab.

I edited the file:

sudo nano /etc/fstab

and added:

/dev/md0    /mnt/raid1    ext4    defaults    0    0

I then tested the configuration without rebooting:

sudo mount -av

This is a useful habit whenever modifying /etc/fstab. If there is a typo or other problem, mount -av can expose it immediately instead of discovering the problem after rebooting.

Note: For a modern system, using the filesystem UUID in /etc/fstab is generally preferable to relying on /dev/md0 or another device name.

Saving the mdadm Configuration

I also saved the RAID configuration so the system could identify the array during boot:

sudo mdadm --detail --scan --verbose >> /etc/mdadm.conf

The exact location of the mdadm configuration file can vary between Linux distributions. On many modern Debian systems, the configuration is stored in:

/etc/mdadm/mdadm.conf

If following this project on a current Debian installation, check which location your version of mdadm uses before adding the configuration.

Setting Up Samba

With the RAID storage working, the next step was to make it available over the network.

I first checked whether Samba was already installed:

samba --version

If it was not installed, I updated the package information and installed it:

sudo apt update
sudo apt upgrade
sudo apt install samba

Samba provides SMB/CIFS file sharing, allowing Linux to provide network shares that can be accessed by Windows, Linux, and other operating systems.

Configuring a Static IP Address

Because this machine was going to act as a file server, I wanted it to have a predictable IP address.

I checked the existing network configuration:

cat /etc/network/interfaces

The system was not configured there with a static IP, so I configured the static address through the desktop network configuration tools.

The important point is that a server should have a predictable address. Otherwise, clients may suddenly lose access to the server if DHCP assigns it a different address.

Creating the Samba Share

I created a directory inside the RAID filesystem to hold the files that would be shared across the network:

sudo mkdir /mnt/raid1/sambashare

I then changed the ownership of the directory:

sudo chown scott /mnt/raid1/sambashare

This allowed my normal Linux account to manage the files in the directory without needing to use sudo for every operation.

Configuring Samba

I opened the Samba configuration file:

sudo nano /etc/samba/smb.conf

and added the following share configuration:

[sambashare]
comment = Samba on Lubuntu
path = /mnt/raid1/sambashare
read only = no
browsable = yes

The settings mean:

After making the changes, I restarted Samba:

sudo service smbd restart

On a modern system, I would generally use:

sudo systemctl restart smbd

and check the service with:

sudo systemctl status smbd

Configuring the Firewall

The server also had a firewall enabled, so I needed to allow Samba traffic through it.

With UFW, this can be done with:

sudo ufw allow samba

This creates the appropriate firewall rules for Samba.

For a file server, I would recommend restricting SMB access to the local network rather than exposing it to the internet. There is almost never a good reason to expose SMB directly to the public internet.

Creating a Samba User

One important thing about Samba authentication is that Samba does not simply use the normal Linux account password.

I added my Linux user to the Samba password database:

sudo smbpasswd -a scott

I could then specify a Samba password for the account.

The Linux user must already exist on the system. In other words, you cannot use smbpasswd to create a completely unrelated Samba-only username.

This gives Samba an account it can use when authenticating clients connecting to the network share.

The Finished Setup

At the end of the project, the storage layout looked something like this:

                    Linux Server
                         │
          ┌──────────────┴──────────────┐
          │                             │
      OS Drive                     RAID 1 Storage
      /dev/sda                         /dev/md0
                                        │
                              ┌─────────┴─────────┐
                              │                   │
                          /dev/sdb1           /dev/sdc1
                              │                   │
                              └────── Mirror ─────┘
                                        │
                                  /mnt/raid1
                                        │
                                  sambashare
                                        │
                                     Samba
                                        │
                               Local Network

The result was a Linux file server with two 1 TB drives mirrored using RAID 1. The RAID array was mounted automatically at boot, and Samba provided authenticated network access to a directory stored on the array.

A Note About RAID 1

RAID 1 provides redundancy, not backup.

If one drive fails, the other drive should still contain the data. However, RAID does not protect against accidentally deleting a file, malware, filesystem corruption, theft, fire, or other events that affect both copies simultaneously.

For anything important, I would still want a separate backup in addition to the RAID array.

Looking Back

This was one of those projects where several different Linux concepts came together: partitioning disks, software RAID, filesystems, mounting storage, fstab, networking, firewalls, and Samba.

It was also a good practical example of how Linux can turn an otherwise ordinary computer and a couple of hard drives into a pretty capable little file server.