OpenWRT and a SMB Share

This is an outline of what I did to create a SMB share on an external hard drive attached to an OpenWRT router. This would also let you attach a USB storage device to your router without setting up Samba, or you could set up Samba without having external storage ... but to me it makes more sense to have the two together.

I have no idea how secure this is: my guess is "not very" as at one point we use a parameter to force vers=1.0 - and if that means SMB version 1, it's fantastically old and insecure. I'm using this for sharing ISO files, photos, and videos ... but I wouldn't recommend it for anything sensitive.

While this worked for me, it should be considered more of a rough draft than a complete answer. I've tried to point out problem points as we go along. It's a fairly time-consuming process, although not too difficult if you're familiar with Linux command line system administration.

Obvious caveat: your router will have to have a way of attaching storage - in my case (and usually) a USB port.

Possible caveat: my router has a fair bit of memory. This requires installing several packages, so routers with minimal memory may not work for this. But then, if they have minimal memory they usually don't have a way to attach external storage.

On the router:

  • when you start, dmesg will acknowledge USB device insertion, but not mount the devices

  • by default, OpenWRT isn't equipped to repartition hard drives

    • it appears that the packages to do this are available - but I saw references to non-standard partitioning tools (probably because the ones we know and love like parted and fdisk are too big, so I chose to repartition the drive as ext4 on a Linux computer rather than attempt it on the router
  • add packages (these are kernel modules): kmod-usb-storage, kmod-scsi-storage

  • see my blog entry on opkg - it's more about writing shell scripts around opkg, but has some mention of the basics

  • choose the filesystem types you need (again, kernel modules):

    • I chose kmod-fs-msdos, kmod-fs-vfat (for USB sticks which are vfat formatted), kmod-fs-ext4 (has some deps)
  • least obvious: you need your local codepages to read details (like file names!) on the USB device (mount won't work without these):

    • kmod-nls-iso8859, kmod-nls-cp437
    • this should work for English speakers, if working in another language you may need others
  • you should be able to use mount/umount to access USB drives at this point

    • Samba and ownership permissions combine to create an interesting gotcha here: don't try to share the entire mounted partition, as obvious as that may seem. The share needs to be owned and writeable by the user we're going to create in Samba (and if you even think of doing that as root, I disown you). So create a folder on your newly mounted partition, and use chown -R giles.giles giles.
  • the standard mount command would look about like this: mount /dev/sda1 /mnt/sda1

  • once mount and umount work as expected on the drive, you'll probably want to ensure it's always mounted when the router boots: add a line like this to /etc/fstab: /dev/sda1 /mnt/sda1 ext4 rw,relatime 0 0

    • you may need different settings, but if you're using an ext4 formatted drive, the above is going to be very close to what you need
  • add the samba36-server package

  • you can create a totally open share ... I wouldn't recommend this, but it's the easiest path and can be done

  • authenticated shares are a PITA: you have to add users to the router, and there's no useradd or adduser command (Luci (the GUI) doesn't seem to have a user add-subtract interface either, at least not by default)

  • so to add a user you have to edit /etc/passwd and /etc/group by hand

    • the line added to /etc/passwd was giles:x:1000:1000:Giles:/home/giles:/bin/ash
    • the UID and GID were deliberately set to 1000 as that matches all my standard Unix machines, and 'ash' is OpenWRT's shell of choice (this probably doesn't matter with SMB, but would make a huge difference with NFS ... long story)
    • the 'x' is the password: you may need to use passwd <username> to change this (I say "may" because I did, but because smbpasswd manages the SMB passwords separately ... it might not be needed)
    • the line added to /etc/group was giles:x:1000:giles (indicating a new group called "giles" with a single member, the user "giles"
  • but it gets worse: passwd manages the router/Linux password, but you have to manage the SMB password entirely separately with smbpasswd (the two passwords don't have to be the same ... that's kind of a plus)

  • you can manage your smbpasswd separately ... but you can't have a user/smbpasswd combo without having a Linux user first

  • not required, but highly recommended: luci-i18n-samba-en (or in your language, many language codes available to replace '-en')

  • under Luci -> Services -> Network Shares you'll now find a section called "Shared Directories:"

    • I was uninventive and called the share "giles" with it pointing to /mnt/sda1/shares/giles (that carefully created folder I just covered)
    • the only allowed share user is "giles"
    • "Read-only" is unchecked, "Browseable" is checked, "Allow guests" is unchecked
    • I didn't set the "Create mask" or "Directory mask"

On your Linux computer:

  • testing can be done at any time with the smbclient command (provided by the samba-client package on Fedora)

    • it will help if you remember the very old ftp command line commands, like 'get' and 'put' although mostly testing will involve attempting to log in
    • 'put' will help you test if the share is writeable
  • I spent a lot of time with the man page for mount.cifs - where "CIFS" is "Common Internet File System" ( https://searchstorage.techtarget.com/definition/Common-Internet-File-System-CIFS ) which appears to have been developed in parallel with SMB, but eventually abandoned by Microsoft in favour of SMB (there have been several versions since)

  • to mount the SMB share from your router: mount -t cifs //<routername>.lan/giles /home/giles/routershare -o username=giles,vers=1.0 - which will then ask you for a password (make sure the mount point is an existing, preferably empty directory)

    • this has to be done as root, unfortunately: most mount operations require root access
  • once this is working properly, you may want to make it permanent with a line in the computer's /etc/fstab like this: //<routername>.lan/giles /home/giles/router cifs vers=1.0,credentials=/home/giles/.<routername>-cifs-credentials 1 2

    • note the credentials store: this is a well secured file (700 perms) in my home directory
    • it contains two lines: user=giles and the second: password=xxxyyy
    • this seems like the best way to store the credentials, as the primary alternative is directly in /etc/fstab which is a world-readable file
    • if you consider it insecure (you should already have come to that conclusion ...) then don't re-use a valuable password, use a password that you don't use anywhere else!

I hope you've succeeded in following along. It was an educational, difficult and useful journey for me. It's nice to have a 2TB shareable drive attached to the network - especially without having to attach a new device to the network to do it.

Bibliography

  • https://openwrt.org/docs/guide-user/storage/usb-drives - this seems to be LEDE's tutorial about adding USB devices - which is itself bad because after LEDE and OpenWRT (re-)merged, they went with OpenWRT branding ... which implies that this is at least a couple years old

    • they tell you to use the package "block-mount" which OpenWRT itself now tells you on install "don't use this"
    • they recommend using the package "usbutils" and the command 'lsusb' from that package: I haven't tried this
    • they also talk about how to install packages to allow repartitioning from within OpenWRT itself: this might be useful
  • http://wiki.openwrt.org/doc/howto/usb.storage - the older Wiki page ... I did much of the stuff you're reading above a while ago, from this page. But I've updated as appropriate.