yeeti - Secure, encrypted file sharing with end-to-end encryption directly in your browser.
228

Secure, encrypted file sharing with end-to-end encryption directly in your browser.
Yeeti is an open-source solution for anonymous file sharing where no one, not even the server administrator, has access to your content. All encryption and decryption happens client-side in the browser, keeping both metadata and file contents protected at all times.
For encryption, Yeeti uses openpgpjs in version v6.3.2.
tl;dr: User selects file and password, clicks upload. File gets encrypted and uploaded. Once the upload is done they get a download link they can share with whomever they like. Clicking that link allows for downloading and decrypting the file - given you've got the password.
WriteStream to YEETI_UPLOAD_DIR/<fileID>
/uploads/01a10cf7-1e48-70f7-a4cc-f7bfde5817a4EOF, to which the backend responds with DONE.First of all: While I claim that Yeeti is open-source, I haven't published it's code, yet. This is going to take place very soon. Until then I must advise you not to use Yeeti, since you cannot verify it's integrity, yet.
There are some key features still missing, but already on the roadmap:
Once these are done, I plan to publish Yeeti on Codeberg. Stay tuned!
openpgp
As mentioned above, Yeeti utilizes openpgpjs and delivers a minified version of it (taken from openpgp on unpkg.com). For privacy reasons, I deliberately avoid using a CDN in Yeeti.
WebSocket server
For being able to stream the file encryption result directly into an upload process, Yeeti relies on a WebSocket connection per upload. Since I haven't found the time nor the motivation to implement the WebSocket protocol on top of node js' built-in httpServer myself, I'm using the ws npm package, which itself got zero dependencies.
For now, during the Yeeti Docker build npm ci runs only to install ws.
To run Yeeti via Docker (recommended), follow the steps below.
mkdir -p yeeti/data
cd yeeti
By default Yeeti runs under user yeeti with userid 1001, so you'll need to chown the created data dir for Yeeti to be able to save uploads and store the sqlite database:
chown -R 1001:1001 data/
Example compose file (replace the value of YEETI_BASE_URL):
name: yeeti
services:
yeeti:
image: sklieren/yeeti:latest
container_name: yeeti
ports:
- 8080:8080
volumes:
- ./data:/data
environment:
- YEETI_BASE_URL=https://yeeti.yourdomain.com
Instead of using a compose file, you can start Yeeti with the following docker run command:
docker run --name yeeti -v ./data:/data -p "8080:8080" -e YEETI_BASE_URL=https://yeeti.yourdomain.com sklieren/yeeti:latest
Now, Yeeti should be running on your machine, listening on port 8080 unless you've already done some configuration. Yeeti does not handle TLS termination, so you might want to use a reverse proxy such as nginx.
Example nginx configuration:
server {
listen 80;
listen [::]:80;
server_name yeeti.yourdomain.com;
server_tokens off;
# certbot challenge location
location /.well-known/acme-challenge/ {
alias /var/www/certbot/.well-known/acme-challenge/;
default_type "text/plain";
}
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name yeeti.yourdomain.com;
server_tokens off;
ssl_certificate /etc/letsencrypt/live/yeeti.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yeeti.yourdomain.com/privkey.pem;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
# Allow 250MB uploads
client_max_body_size 250M;
location / {
proxy_pass http://yeeti:8080;
proxy_pass_header yeeti-metadata;
# Required WebSocket headers
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
# Increase timeout for long-lived connections
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
}
}
Yeeti can be configured using the following environment variables.
| Name | Description | Default |
|---|---|---|
YEETI_BASE_URL | The (public) URL of your yeeti instance. (for example https://yeeti.yourdomain.com) | http://127.0.0.1:8080 |
YEETI_HOST | The host the http server is going to listen on. 0.0.0.0 for listening on all devices, 127.0.0.1 for listening on localhost only, etc. | 0.0.0.0 |
YEETI_PORT | The port the http server should listen on. | 8080 |
YEETI_UPLOAD_ID_ALPHABET | Upload IDs will consist of random characters out of this alphabet. I deliberately excluded letters which could easily be mistaken by others, such as uppercase i, lowercase L, etc. | abcdefghijkmnopqrstuvwxyzABCDEFGHKLMNOPQRSTUVWXYZ |
YEETI_UPLOAD_ID_LENGTH | Length of the generated files' ID. While the default of 7 may appear a little small, with the default alphabet and a length of 7 characters, there are about 678 billion unique IDs - this should be enough for temporary files. | 7 |
YEETI_SQLITE_FILE | Path to the sqlite file yeeti should use. Can be ':memory:' if no peristence is needed / wished. Will be located beneath YEETI_DATA_DIR. | yeeti.sqlite |
YEETI_DUMP_CONFIG_ON_STARTUP | Set this to any of [1, true, "1", "true", "yes", "enabled"] in order to instruct the yeeti server to log it's configuration on service startup. | undefined |
Content type
Image
Digest
sha256:ed16e2ad7…
Size
65.1 MB
Last updated
3 days ago
docker pull sklieren/yeeti