GithubHelp home page GithubHelp logo

tenox7 / wfm Goto Github PK

View Code? Open in Web Editor NEW
45.0 7.0 8.0 1.04 MB

Web File/Content Management Application

License: Apache License 2.0

Shell 1.63% Go 96.77% Dockerfile 0.20% Makefile 1.40%
cgi git libgit2 cms file-manager filemanager cgi-bin

wfm's Introduction

WFM - Web File Manager

WFM is a lightweight, web based, file manager. You can use it as a web interface for a NAS box, FTP server, a "personal cloud", document sharing site or a lightweight CMS. It allows to perform basic file and folder operations such as download, upload, rename, move, delete files and organize directory tree structure. Text files, such as markup, markdown, config, etc can be edited directly in the browser. WFM can also create and open bookmarks, link and shortcut files, etc.

wfm screenshot

Usage

WFM is a standalone service with it's own web server. No need for Apache, Nginx, PHP, etc. It runs directly from systemd, sysvinit, launchd, rc or Docker. TLS/SSL is supported with automatic certificate generation by Lets Encrypt / Certbot.

Much like Docker, Kubernetes, Hugo, etc. WFM is written in Go language. The binary is statically linked, fully self contained and has zero external dependencies. Icons are unicode emojis. CA Certs are embedded at built time. No need for Python, PHP, SQL, JavaScript, Node or any other bloat. WFM outputs validated HTML 4.01 without JavaScript. It works on both modern and legacy web browsers going back to Internet Explorer 1.x and Netscape 3.x.

Directory tree

WFM exposes a directory tree via web based interface. The primary method of specifying the root directory is chroot via -chroot=/dir flag, or by your service manager. For example Systemd service file RootDirectory= directive. WFM is not intended to be used without chroot.

For some services like Docker, a subdirectory must be used, this can be specified by --prefix=/subdir:/ flag. A subdirectory should not be considered secure and you should assume users can access files above the prefix up to chroot.

Deployment scenarios

Systemd

You can have either Systemd, or WFM perform chroot and setuid. If you are binding to port 80 (and/or 443), you need to start WFM as root.

WFM as root

Like any other web server, WFM starts the process as root to binds to port 80 or 443. Then it setuids to a desired user specified with -setuid=myuser. Similarly the WFM performs chroot to a directory specified with -chroot=/datadir. An example service file is provided here.

WFM as user

You can specify Systemd User= other than root if you also use RootDirectory= for chroot and use non privileged port (above 1024, eg. 8080), or your binary has adequate capabilities set. Example here.

Systemd Install

To install wfm service file copy it to /etc/systemd/system/wfm.service edit the configuration and run:

$ sudo systemctl daemon-reload
$ sudo systemctl enable --now wfm

Launchd

An example launchd service file is provided here.

Docker

Docker hub: tenox7/wfm:latest GCR.io: gcr.io/tenox7/wrp:latest

Run:

$ docker run -d -p 8080:8080 --user 1234:1234 -v /some/host/dir:/data tenox7/wfm

WFM docker container expects the data directory to be mounted in /data inside the container. This can be overridden with --prefix flag if necessary.

To supply json password file to the docker container you can mount it:

$ docker run -d \
      -p 8080:8080 \
      --user 1234:1234 \
      -v /some/host/dir:/data \
      -v /some/dir/wfmpasswd.json:/etc/wfmusers.json
      tenox7/wfm -passwd=/etc/wfmusers.json

If not using password file you may also need add --nopass_rw.

If you don't specify --user in Docker run, you may also need --allow_root since WFM will be running as user id 0 inside the container.

SSL / TLS / Auto Cert Manager

You can use WFM as a SSL / TLS / https secure web server with Lets Encrypt Auto Cert Manager. ACM will automatically obtain SSL certificate for your site as well as the keypair.

Example deployment with SSL:

ExecStart=/usr/local/sbin/wfm \
	-passwd=/usr/local/etc/wfmpasswd.json \
	-chroot=/var/www/html \
	-setuid=user \
	-addr=:443 \
	-acm_addr=:80 \
	-acm_file=/var/cache/wfm-certs.json \
	-acm_host=www.snakeoil.com

The flag -addr=:443 makes WFM listen on port 443 for https requests. Flag -acm_addr=:80 is used for Auto Cert Manager to obtain the cert and then redirect to port 443/https. Flag -acm_file=/var/cache/wfm-certs.json is where the certificates and keys are stored. This file is opened before chroot.

The -acm_host= is a repeated flag that adds hosts to a whitelist. ACM will only obtain certificates for whitelisted hosts. If your WFM site has multiple names in DNS you need to add them to the whitelist.

If the https site is exposed externally outside of your firewall its sometimes desired to have a local http (non-SSL) listener as well. To enable this use -addr_extra=:8080 flag.

Authentication

Authentication is performed by HTTP Basic Auth (in future a custom login window may be implemented instead). If no password file is specified, or no users present in it (blank) and no hardcoded passwords are present WFM will not ask for username/password. Auth-less mode by will be read-only mode (like a regular web server) unless you specify -nopass_rw flag.

To enable authentication, specify password file via -passwd=/path/users.json flag. Passwords are read on startup and therefore can be placed outside of chroot directory. Passwords can also be hardcoded in the binary, se below.

User Management

Users can be managed using a built-in helper function that services the specified password json file.

Note that any changes to the password file require restart of wfm daemon to take effect. This is because the file is read once on startup before chroot(2) is performed.

Create new blank password file:

$ wfm -passwd=/path/users.json user newfile

Add user:

$ wfm -passwd=/path/users.json user add myuser rw

Delete user:

$ wfm -passwd=/path/users.json user delete myuser

Change password:

$ wfm -passwd=/path/users.json user passwd myuser

JSON password file format

The JSON file can be edited / managed manually.

An example file is provided. The format is a simple list of users with "User", "Salt", "Hash" strings and "RW" boolean field. User is self explanatory. Salt is a short random string used to make passwords harder to crack. It can be anything but it must be different for every user. The same salt must also be passed when generating the password. Hash is a hashed salt + password string. RW boolean specifies if user has read only or read write access.

Binary hardcoded

Password file can also be hardcoded inside the binary at compile time. To add hardcoded users add entries in to users var in auth.go.

Fail to ban

WFM monitors failed user login attempts and bans user for increasing period of time with more bad attempts. This is enabled by default. You can disable this behavior with -f2b=false flag. In addition for debugging purposes you can enable a prefix where ban database will be dumped for example -f2b_dump=/dumpf2b.

Prefix

By default WFM serves requests from "/" prefix of the built in web server. You can move it to a different prefix for example "/data" or "/wfm" with the flag -prefix=/:/httppath.

Flags

Usage of wfm:
  -about_runtime
        Display runtime info in About Dialog (default true)
  -acm_addr string
        autocert manager listen address, eg: :80
  -acm_file string
        autocert cache, eg: /var/cache/wfm-acme.json
  -acm_host value
        autocert manager allowed hostname (multi)
  -addr string
        Listen address, eg: :443 (default ":8080")
  -addr_extra string
        Extra non-TLS listener address, eg: :8081
  -allow_root
        allow to run as uid=0/root without setuid
  -cache_ctl string
        HTTP Header Cache Control (default "no-cache")
  -chroot string
        Directory to chroot to
  -f2b
        ban ip addresses on user/pass failures (default true)
  -f2b_dump string
        enable f2b dump at this prefix, eg. /f2bdump (default no)
  -favicon string
        custom favicon file, empty use default
  -list_archive_contents
        list contents of archives (expensive!)
  -logfile string
        Log file name (default stdout)
  -nopass_rw
        allow read-write access if there is no password file
  -passwd string
        wfm password file, eg: /usr/local/etc/wfmpw.json
  -prefix string
        Prefix for WFM access, /fsdir:/htpath eg.: /var/files:/myfiles (default "/:/")
  -proto string
        tcp, tcp4, tcp6, etc (default "tcp")
  -rate_limit int
        rate limit for upload/download in MB/s, 0 no limit
  -robots
        allow robots
  -setuid string
        Username to setuid to
  -show_dot
        show dot files and folders
  -site_name string
        local site name to display (default "WFM")

History

WFM begun its life around 1994 as a Perl CGI script for CERN httpd server. It was developed to allow uploading logs, dumps and other case data by field support engineers, customers, etc. over the web and as a front end to FTP server. Later rewritten in C language, when CGIC library and Apache httpd were released. Up to 2015 WFM has been a closed source commercial application used for lightweight document management and supported by a few customers. It has since been open sourced. In 2022 WFM has been rewritten in Go as a stand-alone application with built-in web server for more modern deployment scenarios.

wfm's People

Contributors

clashthebunny avatar tenox7 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

wfm's Issues

better support for older browsers

issues

  • on old netscapes there is a huge gap between the header and first line of the table
  • mozilla/5 on openvms detected as modern but it's not, displays ? for chars - maybe lack of utf8
  • provide non-utf8 option?
  • old internet explorer displays black borders around checkboxes

Trailing slash on directory= leads to cryptic errors

I was often getting an HTML error dialog from wfm when trying to view or work with files in certain directories:

Basename path too short

Other files & dirs would work fine, and I think this problem might be made worse by symlinks.

I modified the relevant code in wfm.c to provide me more info:

if(strlen(dirname(temp_dirname)) < strlen(cfg.homedir))
error("Basename path too short. temp_dirname:'%s' cfg.homedir:'%s'", temp_dirname, cfg.homedir);

This spat out the answer:

Basename path too short. temp_dirname:'/home/abcd/site/public' cfg.homedir:'/home/abcd/site/public/'

:(

Removing the trailing slash from my directory=asdf line in my wfm config fixed this problem.

Suggested solutions

(1) Make error messages show the evidence of why there is an error, rather than just claiming there is one cryptically. ie print out the strings that were compared.

(2) Warn the user not to end their directory=xxx in a slash via a comment in the config file or a message at runtime (the former is probably enough).

... OR ...

(3) Silently strip away any slashes at the end of directory=xxx on loading.

text editor md5 sum

do an md5 sum inside text editor via javascipt
do another md5 sum when tmp file is received
compare before rename

Provide own certificate/key for https

Is there any way to provide my own certificate/key for https?
Looking at the code (to my limited understanding) this is not possible.
Or would it be possible by pre-populating the .cert dir? If yes, please tell me about file names/formats.
Otherwise kindly accept it as a feature request.
Thanks for the cool work!

configuration issue for writing file

HI,
I tried to configurate apache user authentication as https://www.digitalocean.com/community/tutorials/how-to-set-up-password-authentication-with-apache-on-ubuntu-14-04,
for example generate passwd for user admin
sudo htpasswd -c /etc/apache2/.htpasswd admin

then apache using the password file located at /etc/apache2/.htpasswd for authentication.
my /etc/apache2/conf-available/serve-cgi-bin.conf configuration

ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
<Directory "/usr/lib/cgi-bin">
AllowOverride None
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
# Require all granted
AuthType Basic
AuthName "Restricted Content"
AuthUserFile /etc/apache2/.htpasswd
Require valid-user

my www configuration /etc/apache2/sites-available/000-default.conf

<Directory "/var/www/html">
AuthType Basic
AuthName "Restricted Content"
AuthUserFile /etc/apache2/.htpasswd
Require valid-user

I run command echo -n "foo:bar" | md5sum to generate md5 password for wfm.cfg.
for example
access-md5pw=rw:admin:323299f9fdacfe5a7bb15c40fb00fe03

I set wfm.cfg directory=/var/www/html/ since I want to edit the html under the www root directory. I login in local computer via http://127.0.0.1/cgi-bin/wfm/, the web page shows admin login and have read write permission, hut I can not save the files under it, it says no file permission.

I tried chown the html files to user www-data which apache runs by.

sudo chown www-data:www-data /usr/lib/cgi-bin/wfm

I runs ubuntu under windows 10 linux sub system.

my apache auth login user name is admin, I do not have a linux user name admin, But I noticed there is a group named amdin under linux.

Remove globals

use structure containing all file and folder location information instead of globals

wfm stores autocert cache in the data directory

this is potentially a security risk, it was initially mitigated by disallowing access to the cache dir, however if we expose a directory that is also exported by ftp/nfsd/rsync etc then there may be a problem

possible other mitigations:

  • force autocert manager to obtain certificate before chroot
    it will likely not work for cert refreshes without process restart
  • dont store cert in cache
    is this even possible?
  • implement alternative to autocert.DirCache() that will store it somewhere else
    for example fork a daemon that will stay outside of chroot, and accept put/get/delete via socket

FTP support

Hi,
the description says "You can use it as a web interface for a NAS box, FTP server, a "personal cloud", document sharing site or a lightweight CMS."

So can I connect to plain ftp server and use WFM to manage files? At least cannot find from documentation...

BR,
Timo

Option to view files instead of download

Hi. Awesome program, just what I've been looking for!

Might it be possible to have an option to view certain files (pdf, jpg, png) in the browser instead of downloading?

Example compose file / usage of prefix parameter

I would like to use wfm behind an nginx, both in docker, ideally with docker compose (separate files).

My docker-compose.yml for wfm currently is:

version: '3'
services:
  wfm:
    image: tenox7/wfm:latest
    user: 1001:1001
    container_name: wfm
    #command: -prefix=/data:/wfm
    volumes:
      - ./wfmpasswd.json:/etc/wfmusers.json
      - /:/data:ro
    expose:
      - 8080
    restart: always
    networks:
      - nginx_network

networks:
  nginx_network:
    external: true

nginx.conf:

{ ...
    location /wfm/ {
        proxy_pass         http://wfm:8080/;
    }
...
}

I can access wfm on <host>/wfm/but all the directory links lead to <host>/<dir>instead of <host>/wfm/<dir>

My understanding was that adding -prefix fixes this. But if I add the commented line above (command: -prefix=/data:/wfm):

  • wfm is only available under <host>/wfm/wfm/
  • the links inside wfm lead to <host>/wfm/<dir> thus "outside" of /wfm/wfm

How can I fix this?

Thanks!

PS: The documentation of prefix is a bit misleading. The text contains "data" and "wfm" but the solution is "httppath". It might be helpful to pick up one of the examples, not something entirely else.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.