Simple and efficient self-hosted, CLI-oriented file sharing service over HTTP.
I needed a file sharing service that could be easily used with only curl and wget for maximum
compatibility with all possible contexts (even light live environments or BusyBox-like shells).
What I also needed, was a way to get access to a file once uploaded using a moderately secure key
that I could remember for at least some minutes, enough to retrieve the file from another computer
with... you guessed it, another curl or wget.
👍 What you get with CLIup:
- Self-hosted service up and running in seconds
- Upload files with PUT or POST requests from your favorite terminal
- Get a random password composed of several common words in return
👎 What you don't get with CLIup:
- An end-to-end encrypted file sharing service
- Bulletproof encryption of the files on the server
- A scalable service able to serve thousands of requests
Well, no. For obvious reasons, running a public anonymous file-sharing service is not a good idea these days.
So if you want to test it, install it on your own server! 👷♀️
# Easiest & shortest, using curl + PUT
$ curl -T myfile.bin http://myhost.tld
File uploaded successfully. The password for your file is:
foundation-balance-february
# [Alternative] If you prefer wget or you don't have curl
# You need to set the name of your file in the path after the host
$ wget --method PUT --body-file=myfile.bin http://myhost.tld/myfile.bin -O - -nvYou may also use POST like so:
# You need to set the name of your file in the path after the host
$ curl -F "[email protected]" http://myhost.tld/myfile.bin
File uploaded successfully. The password for your file is:
foundation-balance-february☝ There is no wget alternative with POST as of today.
# Use the password you got previously
$ curl -OJ http://myhost.tld/foundation-balance-february
# Or with wget
$ wget -q --content-disposition http://myhost.tld/foundation-balance-februaryIn these examples, the -OJ flags (resp. --content-disposition) tell curl (resp. wget) to create a file with
the result data (instead of printing it to the console) and use the original filename (ex from above: myfile.bin).
To delete a file, you only need its password too:
$ curl -X DELETE http://myhost.tld/foundation-balance-february
OK, the file has been deleted.# By default, will listen on localhost:8080
$ make server-startQuick & dirty:
$ docker run -d -p 80:8080 nanawel/cliupWith proper upload folder and UID/GID:
$ mkdir -m 700 ./uploads
$ chown 1000:1000 ./uploads
$ docker run -d -p 80:8080 -v ./uploads:/uploads -u 1000:1000 nanawel/cliupYou might want to use the provided docker-compose.yml instead as a base.
Of course you should use SSL/TLS with this service. But it's not embedded in the Docker itself nor in the server code. So you should configure properly a reverse-proxy with the solution of your choice.
You must set an appropriate client_max_body_size value depending on the MAX_UPLOAD_SIZE you
set for the service (see §Configuration below).
Example in your vhost (here for 100 MB max):
client_max_body_size 100M;Also add the following directives in the location section:
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;With Apache, you have 2 configurations value to check: LimitRequestBody but also Proxy100Continue
that must be disabled (Off).
So for a hard limit to 100 MB, this should be:
LimitRequestBody 104857600
Proxy100Continue OffAlso add the following directives in your vhost:
RequestHeader set X-Forwarded-Proto expr=%{REQUEST_SCHEME}
RequestHeader set X-Forwarded-Host expr=%{SERVER_NAME}
RequestHeader set X-Forwarded-Port expr=%{SERVER_PORT}See more: https://httpd.apache.org/docs/2.4/fr/mod/mod_proxy.html#proxy100continue
Files are not automatically removed as there is no cronjob inside the Docker container. You should add such a job yourself on the host if you want expired files to be really deleted and thus space reclaimed:
$ docker exec <your-container> php admin.php purgeYou can use the following environment variables to configure the service:
BASE_PATH (default: <empty> / Example: "/cliup")
DEBUG (default: 0)
ENCRYPTION_ENABLED (default: 0)
EXPIRATION_TIME (default: 86400 => 1 day)
HASH_SALT (default: <empty>)
PASS_WORDS_COUNT (default: 3)
LOG_ACTIVITY (default: 1)
LOG_PASSWORDS (default: 0)
TMP_DIR (default: "/tmp")
TRACE_CLIENT_INFO (default: 1)
UPLOAD_DIR (default: "/tmp" or "/uploads" on Docker)
UPLOAD_DIR_PERMS (default: "0700")
UPLOAD_NAME_MAX_LEN (default: 255)
WORDSLIST_FILE (default: "./wordslist.txt")
Note: BASE_URL is deprecated. Use the following variables instead (or their corresponding headers set
from your reverse-proxy) to allow the proper generation of URLs by the app:
HTTP_FORWARDED_PROTO/X-Forwarded-ProtoHTTP_FORWARDED_HOST/X-Forwarded-HostHTTP_FORWARDED_PORT/X-Forwarded-Port
