Filebin is a web application that facilitates convenient file sharing over the web.
翻譯準備中
取自儲存庫 README
正在載入完整 README。
檢視完整 README ↗Filebin2 is a web application that facilitates convenient file sharing over the web. It is the software that powers https://filebin.net/. It is still in development status and will see breaking changes.
A couple of (in hindsight) bad architectural decisions in the previous version of filebin paved the road for filebin2. Filebin2 is using a PostgreSQL database to handle meta data and S3 to store files. I decided to move to a new repository because of breaking changes from the previous verson of filebin.
Filebin2 requires read write access to an S3 bucket for file storage and a PostgreSQL database that it will use for meta data. The Filebin application itself is written in Go and builds to a single binary that is configured using command line arguments and/or environment variables.
The quickest way to get a fully working setup is to use the included docker-compose.yml, which builds Filebin from source and starts it together with PostgreSQL and Stupid Simple S3):
docker compose up --build
This makes Filebin available at http://localhost:8080/ with an admin interface at http://admin:changeme@localhost:8081/admin.
Review and adjust the environment variables in docker-compose.yml to suit your needs. See the Configuration section for all available options.
Multi-arch container images (linux/amd64 and linux/arm64) are published to GitHub Container Registry for each release. The container images are distroless and contain only the filebin binary:
ghcr.io/espebra/filebin2:latest
Run the container with the required environment variables pointing to your PostgreSQL database and S3 bucket:
docker run -p 8080:8080 \
-e FILEBIN_DATABASE_HOST=db.example.com \
-e FILEBIN_DATABASE_NAME=filebin \
-e FILEBIN_DATABASE_USERNAME=filebin \
-e FILEBIN_DATABASE_PASSWORD=secret \
-e FILEBIN_S3_ENDPOINT=s3.example.com \
-e FILEBIN_S3_REGION=us-east-1 \
-e FILEBIN_S3_BUCKET=filebin \
-e FILEBIN_S3_ACCESS_KEY=accesskey \
-e FILEBIN_S3_SECRET_KEY=secretkey \
-e FILEBIN_LISTEN_HOST=0.0.0.0 \
-e [email protected] \
ghcr.io/espebra/filebin2:latest
Pre-built binaries for Linux and macOS (amd64 and arm64) are attached to each release. Download the appropriate binary for your platform:
| Binary | Platform |
|---|---|
filebin2-linux-amd64 | Linux x86_64 |
filebin2-linux-arm64 | Linux ARM64 |
filebin2-darwin-amd64 | macOS x86_64 |
filebin2-darwin-arm64 | macOS ARM64 (Apple Silicon) |
Make the binary executable and run it with the required flags:
chmod +x filebin2-linux-amd64
./filebin2-linux-amd64 \
--db-host db.example.com \
--db-name filebin \
--db-username filebin \
--db-password secret \
--s3-endpoint s3.example.com \
--s3-region us-east-1 \
--s3-bucket filebin \
--s3-access-key accesskey \
--s3-secret-key secretkey \
--listen-host 0.0.0.0 \
--contact [email protected]
Filebin can be configured using command line arguments or environment variables. Environment variables use the FILEBIN_ prefix with uppercase letters and underscores instead of hyphens. Command line flags take precedence over environment variables.
Base URL
FILEBIN_BASEURL--baseurlhttps://filebin.netThe base URL to use, which impacts URLs that are presented to the user for files and bins. It needs to point to the hostname of the filebin instance.
Contact
FILEBIN_CONTACT--contactThe e-mail address to show on the website on the contact page.
Expiration
FILEBIN_EXPIRATION--expiration604800Bin expiration time in seconds since the last bin update. Bins will be inaccessible after this time, and files will be removed by the lurker.
Temporary Directory
FILEBIN_TMPDIR--tmpdir/tmpDirectory for temporary files for upload and download.
Temporary Directory Capacity Threshold
FILEBIN_TMPDIR_CAPACITY_THRESHOLD--tmpdir-capacity-threshold4.0Workspace capacity threshold multiplier. A workspace must have at least this multiplier times the file size available to be selected (e.g., 4.0 requires 4x the file size available).
Manual Approval
FILEBIN_MANUAL_APPROVAL--manual-approvalfalseIf enabled, the administrator needs to manually approve new bins before files and archives can be downloaded. Bin and file operations except downloading are accepted while a bin is pending approval. This is a mechanism added to limit abuse. The API request used to approve a bin is an authenticated PUT /admin/approve/{bin} to the admin listener.
Require Verification Cookie
FILEBIN_REQUIRE_VERIFICATION_COOKIE--require-verification-cookiefalseIf enabled, a warning page will be shown before a user can download files. If the user accepts to continue past the warning page, a cookie will be set to identify that the user understands the risk of downloading files.
Verification Cookie Lifetime
FILEBIN_VERIFICATION_COOKIE_LIFETIME--verification-cookie-lifetime365Number of days before cookie expiration. See --require-verification-cookie.
Expected Cookie Value
FILEBIN_EXPECTED_COOKIE_VALUE--expected-cookie-value2024-05-24Which cookie value to expect to avoid showing a warning message. See --require-verification-cookie.
GeoIP City Database
FILEBIN_MMDB_CITY--mmdb-cityThe path to an mmdb formatted geoip database like GeoLite2-City.mmdb. This is optional.
GeoIP ASN Database
FILEBIN_MMDB_ASN--mmdb-asnThe path to an mmdb formatted geoip database like GeoLite2-ASN.mmdb. This is optional.
Allow Robots
FILEBIN_ALLOW_ROBOTS--allow-robotsfalseIf enabled, the X-Robots-Tag response header will allow search engines to index and show Filebin in search results. Otherwise, robots will be instructed to not show files and bins in search results.
Pre-Upload Hook
FILEBIN_PRE_UPLOAD_HOOK--pre-upload-hookCommand to execute before every file upload is accepted. The command runs after the file has been received from the client and its content type and checksums have been calculated, but before it is stored in S3 or its metadata persisted to the database. It is intended for validation, for example checking the checksums against a blocklist or a malware scanning service. It is invoked with the following named arguments: --request-id, --bin, --filename, --content-type, --size, --md5, --sha1, and --sha256. The checksums are hex encoded.
The exit code determines the outcome:
1 — Reject the upload with HTTP 403 (Forbidden). The last line of stdout from the command is returned to the client as the response message.0 — Accept the upload.Only exit code 1 rejects an upload. A command that cannot be started, or that does not finish within the timeout, is logged and the upload is accepted, so that a broken or hung hook cannot block uploads. An example hook script is provided in misc/pre-upload-hook-example.
Pre-Upload Hook Timeout
FILEBIN_PRE_UPLOAD_HOOK_TIMEOUT--pre-upload-hook-timeout5sTimeout for the pre-upload hook command execution. If the command does not complete within this duration, it is killed and the timeout is logged, but the upload is accepted so that a slow or hung hook does not block uploads. The value is specified using Go duration format, examples: 5s, 30s, 1m.
Post-Upload Hook
FILEBIN_POST_UPLOAD_HOOK--post-upload-hookCommand to execute after every successful file upload. The command runs after the file has been stored in S3 and its metadata persisted to the database, and is intended for notifications and post-processing (for example, triggering an indexing job or webhook). It is invoked with the following named arguments: --request-id, --bin, --filename, --content-type, --size, --md5, --sha1, and --sha256. The checksums are hex encoded.
The hook does not affect the response to the client: any non-zero exit code or stdout/stderr is logged but the upload is always reported as successful. An example hook script is provided in misc/post-upload-hook-example.
Post-Upload Hook Timeout
FILEBIN_POST_UPLOAD_HOOK_TIMEOUT--post-upload-hook-timeout10sTimeout for the post-upload hook command execution. If the command does not complete within this duration, it is killed and the failure is logged, but the upload is still reported as successful to the client. The value is specified using Go duration format, examples: 5s, 30s, 1m.
Limit File Downloads
FILEBIN_LIMIT_FILE_DOWNLOADS--limit-file-downloads0Limit the number of downloads per file. 0 means no limit. If the value is 100, then each file can be downloaded 100 times before further downloads are rejected.
Limit Storage
FILEBIN_LIMIT_STORAGE--limit-storage0Limit the storage capacity that filebin will use. 0 means no limit. If set to "200GB", filebin will allow file uploads until the total storage surpasses 200 GB. New file uploads will be rejected until storage consumption is below 200 GB again.
Reject File Extensions
FILEBIN_REJECT_FILE_EXTENSIONS--reject-file-extensionsA whitespace separated list of file extensions that will be rejected. Example: "exe bat dll".
Filebin serves HTTP on two listeners:
--listen-host and --listen-port) serves the web interface, the API, uploads and downloads. None of its endpoints require authentication, so it is safe to expose to the internet.--admin-listen-host and --admin-listen-port) serves the admin interface (/admin), the Prometheus metrics (/metrics) and the Go profiling endpoints (/debug/pprof/). These endpoints are not available on the public listener. The admin listener is not meant to be exposed to the internet, but to be reached from the host itself, a private network or through a tunnel such as ssh -L 8081:127.0.0.1:8081 or kubectl port-forward. The admin interface and the profiling endpoints still require the admin credentials. Links from the admin interface to bins and files point to the public listener using the base URL, so make sure it is set correctly.Both listeners serve /filebin-status, /storage-status and the static files, so that health checks can be pointed at either of them.
Listen Host
FILEBIN_LISTEN_HOST--listen-host127.0.0.1Which IP address Filebin will bind to. The default value of 127.0.0.1 is a safe default that does not expose Filebin outside of the host.
Listen Port
FILEBIN_LISTEN_PORT--listen-port8080Which port Filebin will listen to. The default of 8080 does not require privileged access.
Admin Listen Host
FILEBIN_ADMIN_LISTEN_HOST--admin-listen-host127.0.0.1Which IP address the admin listener will bind to. The default value of 127.0.0.1 only allows access from the host itself.
Admin Listen Port
FILEBIN_ADMIN_LISTEN_PORT--admin-listen-port8081Which port the admin listener will listen to. It must be different from --listen-port. Set to 0 to disable the admin listener.
Access Log
FILEBIN_ACCESS_LOG--access-logPath to a filename for the access log output, in the combined log format. Requests to both the public and the admin listener are logged. The access log is disabled if this is not set. A typical value is /var/log/filebin/access.log.
Audit Log Directory
FILEBIN_AUDIT_LOG_DIR--audit-log-dirDirectory for the audit log, which records uploads, downloads, archive downloads, deletions, admin actions and bin expiry with timestamps, request ids, client IP addresses, network and location details, and the checksums of the files transferred. It is written as one JSON lines file per day (UTC), named audit-YYYY-MM-DD.jsonl. The file of the current day is plain text, and the files of previous days are gzip compressed. The audit log is written outside of the database, and is intended to be kept long after the files themselves have been deleted. The audit log is disabled if this is not set. A typical value is /var/log/filebin/audit.
Audit Log Retention
FILEBIN_AUDIT_RETENTION--audit-retention14The number of days to keep audit log files. The lurker removes the files of days that are older than this, regardless of whether the bins and files they refer to still exist. Set to 0 to keep the files forever.
Proxy Headers
FILEBIN_PROXY_HEADERS--proxy-headersfalseIf enabled, the client IP will be read from the proxy headers provided in the incoming HTTP requests on the public listener. This should only be enabled if there is an HTTP proxy running in front of Filebin that uses proxy headers to tell Filebin the original client IP address. This setting does not affect the admin listener, see --admin-proxy-headers.
Admin Proxy Headers
FILEBIN_ADMIN_PROXY_HEADERS--admin-proxy-headersfalseIf enabled, the client IP will be read from the proxy headers provided in the incoming HTTP requests on the admin listener. This should only be enabled if the admin listener is reachable exclusively through an HTTP proxy that uses proxy headers to tell Filebin the original client IP address. Otherwise, clients can spoof their IP address in the admin login tracking and the logs.
Read Timeout
FILEBIN_READ_TIMEOUT--read-timeout1hRead timeout for the HTTP server. File uploads need to complete within this timeout before they are terminated.
Read Header Timeout
FILEBIN_READ_HEADER_TIMEOUT--read-header-timeout2sRead header timeout for the HTTP server.
Write Timeout
FILEBIN_WRITE_TIMEOUT--write-timeout1hWrite timeout for the HTTP server.
Idle Timeout
FILEBIN_IDLE_TIMEOUT--idle-timeout30sIdle timeout for the HTTP server.
Database Host
FILEBIN_DATABASE_HOST--db-hostWhich PostgreSQL host to connect to. This can be an IP address or a hostname.
Database Port
FILEBIN_DATABASE_PORT--db-port5432The port to use when connecting to the PostgreSQL database.
Database Name
FILEBIN_DATABASE_NAME--db-nameThe name of the PostgreSQL database to use.
Database Username
FILEBIN_DATABASE_USERNAME--db-usernameThe username to use when authenticating to the PostgreSQL database.
Database Password
FILEBIN_DATABASE_PASSWORD--db-passwordThe password to use when authenticating to the PostgreSQL database.
Max Open Connections
FILEBIN_DATABASE_MAX_OPEN_CONNS--db-max-open-conns25Maximum number of open database connections.
Max Idle Connections
FILEBIN_DATABASE_MAX_IDLE_CONNS--db-max-idle-conns25Maximum number of idle database connections.
Connection Max Lifetime
FILEBIN_DATABASE_CONN_MAX_LIFETIME--db-conn-max-lifetime5mMaximum time a database connection may be reused before it is closed and replaced. The value is specified using Go duration format, examples: 5m, 10m, 1h.
Connection Max Idle Time
FILEBIN_DATABASE_CONN_MAX_IDLE_TIME--db-conn-max-idle-time1mMaximum time a database connection may sit idle before it is closed. The value is specified using Go duration format, examples: 1m, 5m, 10m.
S3 Endpoint
FILEBIN_S3_ENDPOINT--s3-endpointThe S3 endpoint to connect to. This can be the hostname or IP address. When self hosting S3 on a non-standard port, the port can be specified using hostname:port.
S3 Bucket
FILEBIN_S3_BUCKET--s3-bucketThe name of the bucket in S3 where files will be stored.
S3 Region
FILEBIN_S3_REGION--s3-regionThe S3 region where the bucket lives.
S3 Access Key
FILEBIN_S3_ACCESS_KEY--s3-access-keyThe access key to use when connecting to the S3 bucket where files will be stored.
S3 Secret Key
FILEBIN_S3_SECRET_KEY--s3-secret-keyThe secret key to use when connecting to the S3 bucket where files will be stored.
S3 Secure
FILEBIN_S3_SECURE--s3-securetrueWhether or not Filebin will require the connection to S3 to be TLS encrypted using https. If set to false, Filebin will attempt connecting to S3 using plain http.
S3 URL TTL
FILEBIN_S3_URL_TTL--s3-url-ttl1mWhen a Filebin user downloads a file, that is done using a presigned URL that contains a token with limited time to live. The default allows presigned URLs to be used for 1 minute before they expire. The value is specified using the time unit, examples: 30s, 5m, 2h.
S3 Timeout
FILEBIN_S3_TIMEOUT--s3-timeout30sTimeout for quick S3 operations (delete, head, stat).
S3 Transfer Timeout
FILEBIN_S3_TRANSFER_TIMEOUT--s3-transfer-timeout10mTimeout for S3 data transfers (put, get, copy).
Lurker Interval
FILEBIN_LURKER_INTERVAL--lurker-interval300The lurker is a batch job that runs automatically and in the background to delete expired bins and remove old log entries from the database. This specifies the time in seconds for the lurker to sleep between each execution.
Lurker Throttle
FILEBIN_LURKER_THROTTLE--lurker-throttle250Milliseconds to wait between S3 deletions to throttle the deletion rate.
Log Retention
FILEBIN_LOG_RETENTION--log-retention7The number of days to keep transaction log entries in the PostgreSQL database before they are removed by the lurker.
Admin Username
FILEBIN_ADMIN_USERNAME--admin-usernameUsername to require for access to the /admin and /debug/pprof/ endpoints on the admin listener. If the username is not set, then these endpoints will not be available.
Admin Password
FILEBIN_ADMIN_PASSWORD--admin-passwordPassword to require for access to the /admin and /debug/pprof/ endpoints on the admin listener. If the password is not set, then these endpoints will not be available. Make sure to keep this password a secret.
Enable Metrics
FILEBIN_METRICS--metricsfalseEnables the /metrics endpoint on the admin listener. If this is not set, the endpoint will not return any metrics.
Metrics Username
FILEBIN_METRICS_USERNAME--metrics-usernameThe username used for authentication to the /metrics endpoint for Prometheus metrics.
Metrics Password
FILEBIN_METRICS_PASSWORD--metrics-passwordThe password used for authentication to the /metrics endpoint for Prometheus metrics.
Metrics Auth
FILEBIN_METRICS_AUTH--metrics-authEnables authentication. Currently only basic auth is supported. If set to basic, basic auth will be required. If not set, the endpoint is open to anyone who can reach the admin listener.
Metrics ID
FILEBIN_METRICS_ID--metrics-id$HOSTNAMEThe string used as the identification of the filebin instance in the Prometheus metrics. By default, this is the $HOSTNAME environment variable.
Slack Secret
FILEBIN_SLACK_SECRET--slack-secretThe secret that Slack will need to use when connecting to the http api. If this secret is not set, the Slack integration will be disabled.
Slack Domain
FILEBIN_SLACK_DOMAIN--slack-domainLimits which Slack domain is allowed to access the http api. Other domains will be rejected.
Slack Channel
FILEBIN_SLACK_CHANNEL--slack-channelIf Filebin is set to require manual approval of new bins, then this approval can be given using the user interface, the http api directly or via Slack (using the http api). The http endpoint /integration/slack can be accessed using a webhook from Slack. This parameter limits which Slack channel is allowed to access the http api. Requests from other channels will be rejected.
The admin interface (/admin), the Prometheus metrics (/metrics) and the profiling endpoints (/debug/pprof/) are no longer served on the public listener. They are only served on the new admin listener, which listens on 127.0.0.1:8081 by default. On the public listener, these paths are now handled like any other bin or file path, and no longer give an authentication challenge.
When upgrading:
http://127.0.0.1:8081/metrics.PUT /admin/approve/{bin} to use the admin listener. The Slack integration is unaffected, as it is served on the public listener./admin, /metrics and /debug/pprof/ on the public listener.--admin-listen-host to an address on a private network and restrict access to it with a firewall. Avoid exposing it to the internet.--baseurl is set correctly, as the admin interface uses it to link to bins and files on the public listener.--admin-listen-host 0.0.0.0 (or FILEBIN_ADMIN_LISTEN_HOST=0.0.0.0).The development environment consists of one PostgreSQL instance, one Stupid Simple S3 object storage instance and an instance of filebin2 built from source. The easiest way to set up this environment is to clone this repository and do:
# With Docker
docker compose up --build
# With Podman
podman compose up --build
This will make:
localhost:5432.The easiest way to run the test suite is to run it in docker compose. Docker will exit successfully (return code 0) if the tests succeed, and exit with an error code other than 0 if the tests fail.
# Docker
docker compose -f integration-tests.yml up --abort-on-container-exit
# Podman
podman compose -f integration-tests.yml up --abort-on-container-exit
The program can be built using:
# Build for Linux amd64 only
make linux
# Build for all platforms:
make build-all
The output will be the Filebin program as binaries in the artifacts/ folder called filebin2-linux-amd64 (depending on the platform). The filebin binary take the following environment variables and command line parameters.
Releases are built and published by the release workflow, which runs when a tag matching v* is pushed. There is no version number to bump in the source; the version is taken from the tag.
Make sure master is up to date and that the CI workflow passes on the commit to release.
Pick the next version following semantic versioning, based on the changes since the previous release:
git fetch --tags
git describe --tags --abbrev=0 # Previous release, e.g. v1.3.0
git log --oneline $(git describe --tags --abbrev=0)..master
Tag the commit and push the tag:
git tag v1.4.0 master
git push origin v1.4.0
Follow the run on the release workflow page. When it completes, it has:
.deb and .rpm packages for Linux (amd64 and arm64).ghcr.io/espebra/filebin2, tagged with the full version (1.4.0), the minor version (1.4), the major version (1), and latest.checksums.txt file, and release notes generated from the commits and pull requests since the previous release.The tag and commit are compiled into the binaries and container images. They are logged at startup and printed by filebin2 --version.
If the workflow fails, fix the problem on master, then delete the tag and create it again on the fixed commit:
git push --delete origin v1.4.0
git tag -d v1.4.0
git tag v1.4.0 master
git push origin v1.4.0
If the GitHub release was already created before the failure, delete it on the releases page before pushing the tag again.
Filebin2 comes with a /metrics endpoint on the admin listener that is compatible with Prometheus. There is an example dashboard that visualizes this data.
This integration may be useful if manual approval is required (see --manual-approval). The integration allows members of a Slack channel to list the recently updated bins and approve specific bins directly in the Slack channel using slash commands. The slash commands available are:
| Slash command | Description |
|---|---|
/filebin approve bin_id | Approve the bin bin_id |
/filebin lastupdated | List the 10 last updated bins |
/filebin lastupdated n | List the n last updated bins |
The documention on how to configure Slack to work with this integration does not exist currently.