The tiniest file-sharing server. Roughly equivalent to 1e-15 ordinary file-sharing servers.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

111 lines
5.6 KiB

7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
  1. Femtoshare
  2. ==========
  3. Ultra simple self-hosted file sharing in a single Python script, without any dependencies. All files can be accessed/modified by all users. Don't upload anything secret!
  4. Quickstart: `wget https://raw.githubusercontent.com/Uberi/femtoshare/master/femtoshare.py; chmod +x femtoshare.py; femtoshare.py`, then visit `http://localhost:8000/` in your web browser.
  5. ![Femtoshare Screenshot](screenshot.png)
  6. Options:
  7. $ ./femtoshare.py --help
  8. usage: femtoshare.py [-h] [--port PORT] [--public]
  9. optional arguments:
  10. -h, --help show this help message and exit
  11. --port PORT local network port to listen on
  12. --public listen on remote network interfaces (allows other hosts to see
  13. the website; otherwise only this host can see it)
  14. Rationale
  15. ---------
  16. I often need to send/receive files from untrusted computers. Google Drive can be used for receiving, but not sending - I don't care about people seeing the files, but I do care about not revealing my account credentials when logging in to upload files.
  17. Services like WeTransfer work for sending, but they often have tiny file size limits and long, hard-to-type file URLs, if they work at all.
  18. I made Femtoshare to fix these issues. It's basically an FTP server that only needs a web browser to browse/download/upload. No file size limits and easily-memorized links, plus no worries about revealing important account credentials! A site-wide password is easily added to keep out the most unsophisticated attackers.
  19. Deployment
  20. ----------
  21. Minimal public-facing deployment: `wget https://raw.githubusercontent.com/Uberi/femtoshare/master/femtoshare.py; chmod +x femtoshare.py; ./femtoshare.py --port 1234 --public` is visible at `http://YOUR_HOST:1234`.
  22. For improved security, authentication, and HTTPS support, we can run the script as a systemd daemon and put it behind an Nginx reverse proxy, configured to use HTTP Basic Authentication. Assuming a fresh Ubuntu 16.04 LTS machine:
  23. 1. SSH into the machine: `ssh ubuntu@ec2-35-166-68-253.us-west-2.compute.amazonaws.com`.
  24. 2. Run software updates: `sudo apt-get update && sudo apt-get upgrade`.
  25. 3. Harden SSH: in `/etc/ssh/sshd_config`, change `PasswordAuthentication` to `no` and `PermitRootLogin` to `no` and `AllowUsers` to `ubuntu`. Restart `sshd` using `sudo service sshd restart`.
  26. 4. Get requirements: `sudo apt-get nginx openssl`.
  27. 5. Get the code: `sudo mkdir -p /var/www/femtoshare && cd /var/www/femtoshare && sudo wget https://raw.githubusercontent.com/Uberi/femtoshare/master/femtoshare.py; sudo chmod +x femtoshare.py`.
  28. 6. Set up restricted user: `sudo adduser --system --no-create-home --disabled-login --group femtoshare` (there is a `nobody` user, but it's better to have our own user in case other daemons also use `nobody`).
  29. 7. Set up file storage directory: `sudo install -o femtoshare -g femtoshare -d /var/www/femtoshare/files`.
  30. 8. Set up systemd service to start Femtoshare on boot:
  31. ```bash
  32. sudo tee /lib/systemd/system/femtoshare.service << EOF
  33. [Unit]
  34. Description=Femtoshare
  35. [Service]
  36. Type=simple
  37. PrivateTmp=yes
  38. User=femtoshare
  39. Group=femtoshare
  40. ExecStart=/var/www/femtoshare/femtoshare.py
  41. Restart=always
  42. RestartSec=5
  43. [Install]
  44. WantedBy=multi-user.target
  45. EOF
  46. sudo systemctl daemon-reload
  47. sudo systemctl enable femtoshare.service
  48. ```
  49. 9. Set up a password file for HTTP Basic Authentication: `echo "user:$(openssl passwd -apr1 -salt 8b80ef96d09ffd0be0daa1202f55bb09 'YOUR_PASSWORD_HERE')" | sudo tee /var/www/femtoshare/.htpasswd`
  50. 10. Set up Nginx as a reverse proxy with HTTP Basic Authentication:
  51. ```bash
  52. sudo tee /etc/nginx/conf.d/femtoshare.conf << EOF
  53. server {
  54. listen 80;
  55. server_name ~.;
  56. # HTTP Basic Authentication
  57. auth_basic "Log in with username 'user' to access files";
  58. auth_basic_user_file /var/www/femtoshare/.htpasswd;
  59. # serve directory listing
  60. location = / {
  61. # HTTP Auth Just For POST Requests (This will allow users toread files but they won't be able to upload or delete anything)
  62. # limit_except GET HEAD {
  63. # auth_basic "Log in with username 'user' to access files";
  64. # auth_basic_user_file /var/www/femtoshare/.htpasswd;
  65. # }
  66. proxy_pass http://127.0.0.1:8000;
  67. client_max_body_size 1000M;
  68. }
  69. # serve uploaded file
  70. location ~ /.+ {
  71. root /var/www/femtoshare/files;
  72. }
  73. }
  74. EOF
  75. ```
  76. 11. Set up HTTPS with Let's Encrypt: `export LC_ALL="en_US.UTF-8"; export LC_CTYPE="en_US.UTF-8"; sudo wget https://dl.eff.org/certbot-auto && sudo chmod a+x certbot-auto && sudo ./certbot-auto --nginx --debug`
  77. 12. Set up twice-daily certificate renewal cronjob with Let's Encrypt: add `23 0,12 * * * PATH=/home/ubuntu/bin:/home/ubuntu/.local/bin:/home/ubuntu/bin:/home/ubuntu/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin /var/www/femtoshare/certbot-auto renew >> /var/www/femtoshare/letsencrypt-renew-certificate.log 2>&1` in the root crontab with `sudo crontab -e` (setting `PATH` is necessary in order to get Nginx config updates to work).
  78. 13. Start Femtoshare and Nginx: `sudo systemctl start femtoshare.service` and `sudo service nginx restart`.
  79. 14. Allow incoming and outgoing HTTP and HTTPS traffic through the firewall.
  80. License
  81. -------
  82. Copyright 2018-2018 [Anthony Zhang (Uberi)](http://anthonyz.ca).
  83. The source code is available online at [GitHub](https://github.com/Uberi/femtoshare).
  84. This program is made available under the MIT license. See ``LICENSE.txt`` in the project's root directory for more information.