Ransomware safe server: SMB (Samba) and FTP server

A SMB (Samba) and FTP server which is safe against ransomware attacks from the client

Public Chat
Similar projects worth following
I have made a ransomware safe SMB (Samba) and FTP server using a RPi Zero W. Files on the server can be modified, but every time backups are made which are read only. All changes can therefor be reverted. This will (at the end) fill the storage space. Files can only be deleted after a hardware switch is switched. To get this native functionality I modified the FAT32 File System to a Protected Revertible File System (PRFS) as a kernel module.

Ransomware works by modifying the data in the file system. The original data is overwritten with the data encrypted. The data can only be retrieved with the key to undo the encryption. According to PentestPeople, in 2021, Ransomware Attacks cost businesses an estimated $11.5 billion (

A WORM file system stands for Write Once Read Many. A file can only be written once, but cannot be changed afterwards. This would in itself be safe against ransomware. The file cannot be modified once it s created. There are however some disadvantages, besides there are no WORM file systems available for Linux.

Often a file has to be modified during its use. If you are programming code, you test the code, find the bugs, and then modify the code. A solution would be to store the old file as backup, before modification, as was done in the old VMS system. These backup files should be read only, otherwise the ransomware can delete/encrypt  these backup files. Let’s call this kind of file system: a Protected Revertible File System (PRFS).

At some point the storage will be full with old copies and you want to delete these old copies (once you have tested the newest files are intact). So there should be some way to delete the old files. But if you can, so can the ransomware. A solution is a switch; the storage can be in three modes; the protected PRFS mode, a read-only mode, and a mode in which only the backup files can be deleted. In the read-only mode the files can be safely analyzed. In the last mode, ransomware cannot modify the normal files since modification of the latest file is not allowed.

This system cannot be implemented as file system on the computer itself. If the ransomware would gain root access, it can circumvent the file system and modify the data on a lower level. That is why this should be implemented on another server (e.g. SMB or FTP), or (in possible future projects) in the controller of the storage device (USB, SATA, M2, RAID).

I have created a file system on a RPi Zero W with storage. It is based on the FAT32 code included in the kernel.. All servers that can run on a RPi can use the PRFS file system. In this project both a FTP and a SMB server are using the PRFS and are safe against ransomware attacks from the client on the windows laptop. Any FAT32 formatted storage device can be used.


STL file for the bottom of the housing

Standard Tesselated Geometry - 20.79 kB - 09/03/2023 at 08:45



Open SCAD file for the housing

scad - 3.62 kB - 09/03/2023 at 08:45



STL file for the lid of the housing

Standard Tesselated Geometry - 12.39 kB - 09/03/2023 at 08:45


  • 1 × Raspberry Pi Zero W including SD card
  • 1 × 3-way Switch
  • 1 × Case 3D printed
  • 1 × Power supply USB 5 V, 2.4 A
  • 1 × LED Fiber Optics / Emitters

View all 7 components

  • Mount the PRFS disk at boot

    Elbert09/26/2023 at 20:24 0 comments

    It was some experimenting, but I managed to get the PRFS working at boot. Also the Samba server and ProFTPD are started at boot. So now after putting on the power, one can use it directly. 

    During experimenting the RPi stopped booting after I modified /etc/modules and /etc/fstab. The easiest way to get the RPi working again was to take the SD card and connect it to (through an USB card reader) to my laptop. After starting Linux in Virtual Box and have the USB bridged to Linux, I could access /etc/modules and /etc/fstab again and commented out the changes.  

    There were two unexpected things that were different than one would expect. Firstly the modules should be copied in /lib/modules/6.1.21+ and not in one of the subdirectories. Also one should use kmod and not depmod, by creating a symbolic link.

    I have updated the building instructions. 

  • The project is working

    Elbert09/03/2023 at 08:10 0 comments

    The project is working. The file system works in the three modes which can be controlled with the switch.

    The sources can be found on GitHub:

    Proftpd and samba are working. Only Windows get really confused when switching the modes while working on the files through samba. But this was also not the intended use. Also, if you delete a backup file through samba, it seems to be deleted, but after a refresh the file is back.

  • First version of PRFS file system is working

    Elbert08/26/2023 at 07:18 0 comments

    After further experimenting I have a first version working. When a file is written, a makes a copy of the existing file with the name of this file, trailed with 14 characters, of which the first an dthe last are underscores, and in between only numbers (actually the time seconds since the epoch). So the file “test.txt” gets a backup “_001693031634_test.txt”.

    More specific’, there is a hook in the kernel function:

    • When a file is read, everything goes as normal.
    • When a file is written:
      • It checks whether the filename has a backup file format (_NNNNNNNNNNNN_).
      • If it is a backup file: If the file does not exist (or is empty) it can be written (*), otherwise it cannot be written
      • If it is not a backup file, it makes a copy of the file as backup file. If the backup is successful, the file can be modified. Otherwise it cannot be modified.

    (*) This step seems maybe unnecessary. However, the function is called both form user space as from kernel space. And the kernel module cannot distinguish between them. And we want to be able to write to the backup file from the kernel module, but not from ransomware from the servers in the user space. But this is not possible. So the solution here is that it treats the backup file as WORM: you can write them once, but not change them afterwards.

    I also write “(or is empty)”. This is due to the Linux kernel. The kernel knows already form the directory listing whether a file exist or not. If a file does not exist, it first calls the vfat_create function, before the function. So the file does exits already, but is empty (and has different flags). So this does determine whether it ‘exists’ or not.

    The PRFS works fine when editing text within the RPi linux environment. And also the FTP server (proftpd) works reliable. Samba does not work properly yet.

    Still to do:

    • Fix samba
    • Connect the switch for the cleaning the disc
    • Make a backup copy at delete and rename

  • Getting experience with kernel module writing

    Elbert08/21/2023 at 21:42 0 comments

    You would think that the functions fopen, fprintf and fclose have counterpart functions in the kernel module. Looking for those functions showed that this is not the case. The kernel is already doing that and the kernel module is at a lower level. I could not find good documentation, so I did put debugging messages at the different functions, so I could see which functions I could put my code in.

    Also a surprise for me: in kernel modules you have to use different – and limited set of – functions. With printk one could see the output with dmesg.

    I looked that no functions were actually called. But the kernel module was reading and writing just fine. It turned out you should be very careful with the EXPORT_SYMBOL macro. I did not change all the function names properly, in all the files. And that is why my kernel module just jumped to the FAT kernel functions half way. You do not get any compiler warnings or run time errors, since this will work fine. Maybe next time I should use an IDE, instead of gedit, but maybe that will be even slower on a Rpi zero… After correcting this, I can see which functions are called. When you write from a pipe: fat_write_begin is called. When you e.g. edit a file: fat_write_pages.  

  • I got my own port of the FAT file system working

    Elbert08/14/2023 at 21:22 0 comments

    I came a long way with modifying tarfs. I managed to fool the system to read a file form another drive while the system was thinking I was reading the tar file. This would have been a good basis for the PRFS. However, I kept reading that it is not a good idea to read files from another file system in a kernel module, Also, it was rather difficult to get e.g. a list of the files and their properties.

    So once again, a change of plans…

    I will use the FAT32 file system and will modify it to my own file system: FATPRFS. I copied the source of the FAT system from Raspberry Pi OS. Since it was part of a larger build, I had to modify the Makefile and give the file system a new name: fatprfs. The module also exports some variables to the kernel. Since it is the same names as the official FAT source, I had to change these names too.

    My micro-USB OTG adapter has not arrived yet (to mount an USB memory stick) so with Gparted (offline on another PC with Linux on Virtual Box) I made a FAT32 partition on the SD card by resizing (reducing) the ext4 partition and adding the FAT32 partition. Now I can test mounting FAT32 partitions

    After some trial-and-error experimenting I got it working. I have now an fatprfs file partition! OK, it is still a normal FAT32 partition, but now I can start implementing the prfs-part in the kernel module.

  • I have made an example file system working

    Elbert08/10/2023 at 21:34 0 comments

    After trying to port vsftpd, I realized I was on the wrong way. It would be a messy work. And Samba would even be much larger. So another change of plan. Why not making a new file system? Then all servers could just write to the PRFS file system (Protected Revertible File System) without having to modify the server software!

    The ‘easiest’ way is to make a kernel module. This can be loaded on the fly.

    After reading and compiling some tutorials and compiling, I was ready for the real work.

    I have taken a file system which (transparently) reads a TAR file, as was it a file system:

    Raspbian OS seems to bit a little ‘off’. So I had to change a few things (with a lot of Googling and a little logical thinking):

    • The way to install the header files is: sudo apt-get install raspberrypi-kernel-headers
    • In tar.h and tar.c
      • timespec -> timespec64
      • kstrtoul -> kstrtoll
    • In driver.c
      • Adding struct timespec64 CURRENT_TIME; and ktime_get_real_ts64(&CURRENT_TIME);
      • First parameter added: inode_init_owner(sb->s_user_ns, root, NULL, ROOT_INO_MODE);
      • Last parameter added: static struct posix_acl *tarfs_get_acl(struct inode *inode, int flags, bool rcu)
      • .readlink = generic_readlink -> .readlink = vfs_readlink

    I have mounted the kernel module and it works!

    Next step is to make it read from a normal (mounted) file system.

  • Getting the Rpi to work

    Elbert08/07/2023 at 12:23 0 comments

    I received the Rpi Zero W. I was surprised it does not have an USB host. It seems to be possible, but that is of later concern. I can use the SD storage for the moment.

    I burned the SD card with the Raspberry Pi Imager (32 bit with desktop). I used the advanced options in the Imager to get SSH and WiFi set up, without having to (set up and) use the monitor (mini HDMI) and keyboard. I named it “raspberrypizw”. I had to wait 5 minutes the first time before it showed up in the LAN scan.

    I enabled the VNC interface (sudo raspi-config) via SSH terminal (Teraterm, for old times sake) and changed the resoution too. I also installed and RealVNC on the PC. I could use “raspberypizw” to log into VNC. I am ready to program!

  • FTP server from Github

    Elbert07/31/2023 at 20:31 0 comments

    I want to modify a simple FTP server. Github has many FTP servers. I think I will start with

View all 8 project logs

  • 1
    Build a RPi server

    Get a Raspberry Pi (Zero W).

    If you want to use external USB storage (USB memory stick, USB external SDD, etc): use a USB OTG cable and attach the storage device. 

    Get the Raspberry Pi Imager from and install on PC.

    Install the 32 bit Raspberry Pi OS on de SD card. Recommended:  use the advanced options in the Imager to set SSH and WiFi set up.

    If you want to use part of the SD card as PRFS: install gparted on the PC (or other RPi). Shrink the Ext4 partition with the Raspberry Pi OS. Make a FA32 partition of the remaining space.

    Put the SD card in the RPi, boot the RPi and log in with SSH.

    Optional: install VNC for graphical remote access.

  • 2
    Install FAT32PRFS

    Download FAT32PRFS from:

    Follow the make instructions in the file.

    Load the kernel modules as described.

    Install the server of choice, e.g. Samba, Proftpd, etc. Use the FAT32PRFS mount point as root for the server.

  • 3
    Install the switch

    Download the software from:

    Follow the make instructions in the file.

    Follow the electronics schematics: a LED, with a resistor of 330 Ohm, is connected to GPIO23 and ground. A 3 way switch, with a protective resistor of 330 Ohm, is connected to GPIO 24 and 25 and ground (see file Switch_schematics.jpg).

View all 6 instructions

Enjoy this project?



Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates