This project transforms a Raspberry Pi (or similar Debian-based system) into an offline, anonymous file-sharing network. Users connect to the "PirateBox" Wi-Fi hotspot and are automatically redirected to a browser-based interface for uploading and downloading files.
Inspired by the discontinued PirateBox project, this lightweight implementation uses Nginx, PHP, dnsmasq, and hostapd without requiring a database. It functions as a "captive portal" similar to public Wi-Fi login pages found in hotels or libraries, but instead of requesting credentials, it immediately serves the file-sharing page.
This configuration has been tested on a Raspberry Pi Zero 2 W running Raspberry Pi OS Lite (Trixie).
- Offline Network: Creates its own Wi-Fi hotspot (SSID: PirateBox).
- Captive Portal: DNS redirection resolves all requests to the local server.
- File Sharing: Simple web interface to upload and download files.
- Messages: Guestbook style messages. Let people know that you were here.
- Live Chat: Have a conversation with others connected to the PirateBox.
- Auto-Cleanup: Script included to purge uploads and messages (optional via scheduled cron job).
- Raspberry Pi with Wi-Fi capability.
- OS: Raspbian / Debian.
- Root/Sudo access.
Tip: On the Raspberry Pi Zero 2 W, I used a usb hub that also has ethernet. This allowed me to SSH into the Pi while configuring hostapd.
- Run:
sudo raspi-configand set all of the localization settings, WIFI region, TimeZone, Keyboard layout, set hostname and enabled SSH.
Note: The time server is not set by default. This can break apt update and produce errors on screen. The issue is that the date/time of the repos do not match the date/time of the Raspberry Pi. They are out of sync. These steps should sync your date/time and you can then run apt update. Ignore all online suggestions about downloading certs. It's just a time sync issue.
sudo nano /etc/systemd/timesyncd.confSet the NTP server:
NTP=time.cloudflare.com
sudo systemctl restart systemd-timesyncdtimedatectlUpdate your system and install the required packages:
sudo apt updatesudo apt install -y hostapd dnsmasq dhcpcd5 nginx php-fpm git❗IMPORTANT❗
Run sudo rpi-update to install the latest firmware/kernel. This fixed so many issues that I was having with disconnects. iOS devices would connect and then the kernel would crash once the iOS device disconnected. I went down a rabbit hole trying to find a solution. Turns out, I just needed to update the kernel. Don't let this happen to you.
Edit /etc/dhcpcd.conf to set a static IP for the wireless interface:
interface wlan0
static ip_address=10.0.0.1/24
nohook wpa_supplicantEnable and restart the service:
sudo systemctl enable dhcpcd
sudo systemctl restart dhcpcdCreate /etc/hostapd/hostapd.conf:
interface=wlan0
driver=nl80211
ssid=PirateBox
hw_mode=g
channel=6
ieee80211n=1
wmm_enabled=1
auth_algs=1
wpa=0
country_code=USEdit: /etc/default/hostapd
Point the daemon to this config in /etc/default/hostapd:
DAEMON_CONF="/etc/hostapd/hostapd.conf"
DAEMON_OPTS=""Unmask and start hostapd:
sudo systemctl unmask hostapd
sudo systemctl enable hostapd
sudo systemctl start hostapdConfigure /etc/dnsmasq.conf to handle IP leasing and redirect all DNS queries to the PirateBox:
interface=wlan0
dhcp-range=10.0.0.10,10.0.0.250,12h
address=/#/10.0.0.1Restart dnsmasq:
sudo systemctl restart dnsmasqThe default Nginx site configuration handles the captive portal redirection and large file uploads.
Copy the provided configuration from etc/nginx/sites-available/default to /etc/nginx/sites-available/default.
Note: The setting client_max_body_size 150M; is included in this site configuration. You do not need to add it to /etc/nginx/nginx.conf globally unless you prefer a global setting.
Edit /etc/php/8.4/fpm/php.ini to secure the installation and allow larger uploads:
disable_functions = exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,show_source
upload_max_filesize = 120M
post_max_size = 130M
max_execution_time = 300
display_errors = Off
log_errors = OnNote: You may also need to set these values in the pool config (/etc/php/8.4/fpm/pool.d/www.conf) if php.ini changes don't take effect:
php_value[upload_max_filesize] = 120M
php_value[post_max_size] = 130MCopy the source files (index.php, upload.php, styles.css, images) to /var/www/html/.
Create the uploads directory and set permissions:
sudo mkdir -p /var/www/html/public/uploads
sudo mkdir -p /var/www/html/data
sudo chown -R www-data:www-data /var/www/html
sudo chmod 0755 /var/www/html/public/uploads
sudo chmod 0755 /var/www/html/dataA script purge_uploads.sh is provided to clean up uploads and messages.
sudo touch /var/log/purge_uploads.logsudo crontab -eEvery day at midnight
0 0 * * * /usr/local/bin/purge_uploads.sh > /var/log/purge_uploads.log 2>&1sudo systemctl disable bluetooth.service
sudo systemctl stop wpa_supplicant.service
sudo systemctl disable wpa_supplicant.service
sudo systemctl mask wpa_supplicant.serviceYou may also want to disable SSH. This will however mean that you will no longer be able to SSH into the device.
sudo systemctl disable --now ssh
sudo systemctl mask ssh
sudo systemctl status sshRun sudo rpi-update to install the latest firmware/kernel.
Set restart_hostapd.sh as a cron job to run every hour.



