For storage of non essential Session data, like attachments, stickers, GIF's and device mappings
Go to file
Jason Rhinelander e41b1e8f12
Remove debug
2022-03-03 23:52:03 -04:00
contrib Add v4 onion requests 2022-02-23 21:14:07 -04:00
doc Initial import 2021-10-18 23:59:48 -03:00
fileserver Remove debug 2022-03-03 23:52:03 -04:00
tests Add v4 onion requests 2022-02-23 21:14:07 -04:00
.drone.jsonnet Add v4 onion requests 2022-02-23 21:14:07 -04:00
.flake8 Add v4 onion requests 2022-02-23 21:14:07 -04:00
.gitignore Split up code similarly to what pysogs does 2021-11-22 12:24:34 -04:00
.gitmodules Add v4 onion requests 2022-02-23 21:14:07 -04:00
LICENSE.txt Initial import 2021-10-18 23:59:48 -03:00
README.md Add v4 onion requests 2022-02-23 21:14:07 -04:00
import.py Misc fixes 2022-02-23 21:32:30 -04:00
pyproject.toml Split up code similarly to what pysogs does 2021-11-22 12:24:34 -04:00
schema.pgsql Initial import 2021-10-18 23:59:48 -03:00

README.md

Session File Server

This is the Session file server that hosts encrypted avatars and attachments for the Session network. It is effectively a "dumb" store of data as it simply stores, retrieves, and expires but cannot read the encrypted blobs.

It has one additional feature used by Session which is acting as a cache and server of the current version of Session (as posted on GitHub) to allow Session clients to check the version without leaking metadata (by making an onion request through the Oxen service node network).

Requires

Python3

A reasonably recent version of Python 3 (3.8 or newer are tested, earlier may or may not work), with the following modules installed. (Most of these are available as apt install python3-NAME on Debian/Ubuntu).

  • flask
  • coloredlogs
  • psycopg 3.x (not the older psycopg2 currently found in most linux distros)
  • psycopg_pool
  • requests
  • uwsgidecorators
  • oxenmq
  • pyonionreq

(The last two are Oxen projects that either need to be installed manually, or via the Oxen deb repository).

WSGI request handler

The file server uses WSGI for incoming HTTP requests. See below for one possible way to set this up.

PostgreSQL

Everything is stored in PostgreSQL; no local file storage is used at all.

Getting started

  1. Create a user, clone the code as a user, run the code as a user, NOT as root.

  2. Install the required Python packages:

       sudo apt install python3 python3-flask python3-coloredlogs python3-requests python3-pip
    
       pip3 install psycopg psycopg_pool  # Or as above, once these enter Debian/Ubuntu
    

    You may optionally also install psycopg_c for some performance improvements; this likely requires first installing libpq-dev for postgresql headers.

  3. Build the required oxen Python modules:

    make
    
  4. Set up a postgresql database for the files to live in. Note that this can be large because file content is stored in the database, so ensure it is on a filesystem with lots of available storage.

    A quick setup, if you've never used it before, is:

    sudo apt install postgresql-server postgresql-client  # Install server and client
    sudo su - postgres  # Change to postgres system user
    createuser YOURUSER  # Replace with your username, *NOT* root
    createdb -O YOURUSER sessionfiles  # Creates an empty database for session files, owned by you
    exit  # Exit the postgres shell, return to your user
    
    # Test that postgresql lets us connect to the database:
    echo "select 'hello'" | psql sessionfiles
    # Should should you "ok / ---- / hello"; if it gives an error then something is wrong.
    
    # Load the database structure (run this from the session-file-server dir):
    psql -f schema.pgsql sessionfiles
    
    # The 'sessionfiles' database is now ready to go.
    
  5. Copy fileserver/config.py.sample to fileserver/config.py and edit as needed. In particular you'll need to edit the pgsql_connect_opts variable to specify database connection parameters.

  6. Set up the application to run via wsgi. The setup I use is:

    1. Install uwsgi-emperor and uwsgi-plugin-python3

    2. Configure it by adding cap = setgid,setuid and emperor-tyrant = true into /etc/uwsgi-emperor/emperor.ini

    3. Create a file /etc/uwsgi-emperor/vassals/sfs.ini with content:

      [uwsgi]
      chdir = /home/YOURUSER/session-file-server
      socket = sfs.wsgi
      chmod-socket = 660
      plugins = python3,logfile
      processes = 4
      manage-script-name = true
      mount = /=fileserver.web:app
      
      logger = file:logfile=/home/YOURUSER/session-file-server/sfs.log
      

      You will need to change the chdir and logger paths to match where you have set up the code.

  7. Run:

    sudo chown YOURUSER:www-data /etc/uwsgi-emperor/vassals/sfs.ini
    

    (For nginx, you may need to change www-data to nginx in the above command).

    Because of the configuration you added in step 5, the ownership of the sfs.ini determines the user and group the program runs as. Also note that uwsgi sensibly refuses to run as root, but if you are contemplating running this program in the first place then hopefully you knew not to do that anyway.

  8. Set up nginx or apache2 to serve HTTP or HTTPS requests that are handled by the file server.

    • For nginx you want this snippet added to your /etc/nginx/sites-enabled/SITENAME file (SITENAME can be default if you will only use the web server for the Session file server).:

      location / {
          uwsgi_pass unix:///home/YOURUSER/session-file-server/sfs.wsgi;
          include uwsgi_params;
      }
      
    • If you prefer to use Apache then you want to use a

      ProxyPass / unix:/home/YOURUSER/session-file-server/sfs.wsgi|uwsgi://uwsgi-session-file-server/
      

      directive in <VirtualHost> section serving the site.

  9. If you want to use HTTPS then set it up in nginx or apache and put the above directives in the location for the HTTPS server. This will work but is not required for Session and does not enhance the security because requests are always onion encrypted; the extra layer of HTTPS encryption adds nothing (and makes requests marginally slower).

  10. Restart the web server and UWSGI emperor: systemctl restart nginx uwsgi-emperor

  11. In the future, if you update the file server code and want to restart it, you can just touch /etc/uwsgi-emperor/vassals/sfs.ini — uwsgi-emperor watches the files for modifications and restarts gracefully upon modifications (or in this case simply touching, which updates the file's modification time without changing its content).