9001 / copyparty

Portable file server with accelerated resumable uploads, dedup, WebDAV, FTP, TFTP, zeroconf, media indexer, thumbnails++ all in one file, no deps
MIT License
873 stars 50 forks source link

Product configuration wizard #57

Open kkovaletp opened 1 year ago

kkovaletp commented 1 year ago

is your feature request related to a problem? Please describe. The product has so many configuration parameters with a lot of cross-dependencies between them already and new options keep coming with new releases. It would be not so easy task for a new user to go through all of them to configure a new product instance correctly according to the environment and business needs. Later, if the admin doesn't read each new release note, it would be difficult to stay on the same page and keep the product config in an optimal state.

Describe the idea / solution you'd like I propose to implement some stand-alone script, which would represent an installation and migration wizard with the next flow:

Describe any alternatives you've considered Keep it "as is" and force a user to manually configure the product putting all the responsibility of misconfiguration on the user's side

Additional context This request came from my personal experience of analyzing a long list of config params with not-so-clear (as to me) descriptions, and I believe that my setup is not optimal (it is running in a local network behind a firewall, so it isn't so critical, but still...) Feel free to ask some questions in comments in case you need to clarify something)

9001 commented 1 year ago

Yep, this is definitely becoming an issue -- and you're probably not surprised to hear that (something like) this has come up in discussions before :)

Part of the problem is that it's really hard to cover all the possible scenarios and usecases with an automated solution. I'll start by writing down all the stuff I can think of, using this post as a scratchpad and continue to edit over time. This section is just a list of things to keep in mind when designing this feature, to make sure we don't miss anything important.

  1. How is copyparty deployed? The python sfx? The windows exe? An OS package (nixos/arch)? A docker container?

    • The way you launch copyparty and give it configuration files is different, and the opportunities for copyparty to generate its own config can be tricky given some of these (well, primarily nixos)
  2. Is copyparty facing the internet directly? Through a reverse-proxy? In a docker container?

    • Need to configure X-Forwarded-For somehow; maybe it can show all the IP-addresses it can detect through common means and suggest different settings based on which IP looks to be correct
    • The correct setting for --rp-loc can possibly be autodetected if copyparty were to serve a setup GUI over HTTPS
  3. Are we running on Windows or Linux/macos?

    • Could affect how to visualize the filesystem for volume configuration

So far, I have been playing with the idea of copyparty offering a server setup GUI over HTTPS:

Later, if the admin doesn't read each new release note, it would be difficult to stay on the same page and keep the product config in an optimal state.

This is a good point! I think copyparty should remember the version which was previously running on the server, and then show a "news" printout on startup, explaining what happened since that version, with suggestions on what might be necessary to change in the settings. The settings GUI should also have a separate page with this information, where you can specify any version you would like to compare against.


given the ideas so far, the following would become the new options to enable the setup GUI:

and in --help-setup, there would be a note explaning how to mix autogenerated config with handwritten, more specialized configs:

note: to specify any settings which are not available through the GUI,
  add your settings to one or more files in ~/.config/copyparty/PROFILE/
  with filenames preferably starting with the letter x to ensure they
  will overwrite any settings generated by the GUI, or alternatively
  provide the paths to your custom config files using the -c option
kkovaletp commented 1 year ago

Happy to help with the logic, providing comments and my point of view (which might trigger some useful thoughts):

hard to cover all the possible scenarios and usecases with an automated solution

sure. it definitely is, taking into account the # of options and flexibility of the product. However, it's better to start from some basic and most typical cases, iteratively adding more complex ones to expand the coverage. The wizard shouldn't cover each and every case from the beginning: there could be a disclaimer at the beginning, that this wizard is provided for your convenience and covers the next setup scenarios. if your scenario is not 100% aligned, you could go through the wizard choose the closest one, and then edit the generated config manually aligning it to your needs, or configure Copyparty manually from scratch.

  1. How is copyparty deployed?

  2. Is copyparty facing the internet directly?

  3. Are we running on Windows or Linux/macos?

If I understood you correctly, these are the 1st steps of your wizard. the 3rd one doesn't even need to be asked: the answer could be easily found by the server itself.

  • By launching copyparty with --setup, it will autogenerate a passphrase for a URL which can be accessed to configure everything visually.

I'd not recommend making the wizard to be part of the main app, as it is a significant security risk. Instead, I'd make it as a separate server, running on a different port: in this case, the admin has all the power of routes and firewall configuration, making sure the admin UI is accessible to only the required subnet, as well as it doesn't depend on the main app, so the app and the wizard services could be started, stopped, and restarted independently at any time:

  • Since this means that copyparty would be generating its own config files, it would need to be fully in charge of the generated configs

Only in the scope of the covered scenarios, as it should clearly notify which are currently covered. So, in the case of additional configuration required, user has to do it manually taking all the responsibility of those changes.

  • The generated config would need to have a predetermined structure

Great idea: having a structure of configs, where each is for particular functionality, looks much better than having 1 long and complex file.

  • here must be a "profiles" concept where you can specify which profile to use for this instance

The wizard could ask for multi-instance usage, and if more than 1 profile is configured, it could show the server execution command for each profile configured, as a final step together with the path to generated configs.

  • There must be a way for users to provide their own handwritten config files in addition to the GUI-managed settings

Yes, as I mentioned before: just instruct a user to manually modify generated configs or server execution command if needed

  • The GUI must do an excellent job at visualizing whether a setting is either applied globally or per-volume

How about configuring all global settings at 1st, and then clearly notify a user that now we're going to configure volume level settings, after that, on each option's step could be a table with all volumes configured in lines and the default globally-defined value for the potion pre-selected in front of each volume with the ability to change it?

copyparty should remember the version which was previously running on the server, and then show a "news" printout on startup

I still think that the versioning of the config with parsing the version by the config GUI is much better:

9001 commented 1 year ago

Again thanks for your input :>

First off, one thing I forgot to mention in https://github.com/9001/copyparty/issues/57#issuecomment-1782731760 is that I try my best to not break any existing installations or configs by changing the behavior of existing functionality. If such a change is made, it will be noticed in the breaking changes section in the readme, assuming I do not fail to realize this myself. Of course, there can be new features which could be a good idea to enable for an existing installation, in regards to performance or security, so currently the best way to become aware of those is to read the github release-notes as you mentioned. New security enhancements are always default-enabled assuming they do not break expected functionality, cause unexpected behavior, or cause major user inconveniences.

And sorry for the confusion regarding the initial numbered list -- the intention was to keep track of all the complicating factors to keep in mind when designing this. Like you said, going for a separate configuration utility would make most of these concerns easier to handle, so they are mainly an issue when considering a built-in configuration GUI.

If I understood you correctly, these are the 1st steps of your wizard. the 3rd one doesn't even need to be asked: the answer could be easily found by the server itself.

This part is interesting, because it brings up another open question. Assuming we decide to go for a separate configuration utility, running on a dedicated port, then that is another piece of software which must be downloaded and executed on the server, possibly requiring firewall configuration and such, so a user with a linux server might decide to run the configuration utility at home on their windows computer instead. This would cause a big difference in the environment of copyparty itself and its setup utility, and less assumptions can be made. Of course, we could strongly recommend to run both copyparty and its setup utility in the same environment. But it looks like having copyparty provide its own setup GUI would make this less error-prone, and also give the GUI more opportunity to see things from the correct point of view.

make it as a separate server, running on a different port: in this case, the admin has all the power of routes and firewall configuration

I see you're pointing out the same things I did in the previous paragraph just now, but you're seeing it as an advantage :) and yes, I agree it does make for a more secure approach, but also I'm worried that the additional work that would be required to access and use the setup feature would then be too much of a drawback.

making sure the admin UI is accessible to only the required subnet

I may do some prototyping with the idea of providing a setup URL with an autogenerated passphrase, and see if that would become as secure as I was hoping it would, since that is our primary concern. I'm fairly confident that there would be no way for unintended people to access it, but I'll run the idea by some friends offline too.

as well as it doesn't depend on the main app, so the app and the wizard services could be started, stopped, and restarted independently at any time

This should be possible even if the setup-UI is built into the app too, with a tiny bit of python magic :) so I'll prototype a bit around that too!

The wizard could ask for multi-instance usage, and if more than 1 profile is configured, it could show the server execution command for each profile configured, as a final step together with the path to generated configs.

Good point! This would also apply to a built-in setup UI; it should display all automatically detected profiles, and make it obvious which one you are working on.

just instruct a user to manually modify generated configs or server execution command if needed

This is a possible approach, but it would make it harder for the wizard to understand its own configuration files afterwards, since it would have to "read around" the changes made by the user somehow, and those changes would also probably be lost the next time a new configuration is generated by the wizard. I hope it will be possible to make all customizations by creating an additional configuration file which is given to copyparty in addition to the wizard-generated config, but there might be some settings which must be modified this way indeed.

How about configuring all global settings at 1st, and then clearly notify a user that now we're going to configure volume level settings, after that, on each option's step could be a table with all volumes configured in lines and the default globally-defined value for the potion pre-selected in front of each volume with the ability to change it?

This could definitely work -- it depends on what order the setup steps would be performed in, or if it would instead be a fully dynamic settings GUI rather than a wizard. Both of them make sense.

the News page is functionally the same as the release description on Github with only the difference to be closer to the users, but if the admin doesn't read and follow the changes on Github, the News might be ignored as well.

Yes, more or less -- but it would only include the information that a user "must know", which is much less than all the bells-and-whistles mentioned in the full github notes. This would be displayed in the server log as copyparty is first launched after an upgrade, but should also be displayed as full-screen warnings when you access the settings UI, pointing out which options were affected directly.

But including the version number in the generated config is a good idea, so let's do that :+1:


Looking at how other similar software does it,

These provide their own Setup GUI available in the application UI, which can be accessed and modified at runtime by logging in with the admin account: ownCloud, Nextcloud, Seafile, HFSv3, Chibisafe, kodbox, filebrowser

These provide a full Setup GUI which is only accessible locally, not over HTTP: HFSv2

These provide a textmode Setup UI which is only accessible locally, not over HTTP: rclone

These provide no configuration helpers, expecting plaintext config files: FileGator, sftpgo

ownCloud and Nextcloud also provides a very minimal setup wizard for the first-time setup, to configure the password of your own admin account, and even includes a warning that this setup wizard should not be accessible to the internet due to the risk of malicious users being able to hijack the installation. However, these setup wizards require no authentication, so if copyparty generates a passphrase on startup as mentioned in https://github.com/9001/copyparty/issues/57#issuecomment-1782731760 then this should be fine.


Some more ideas,

Maybe an approach could be to bundle the setup GUI into copyparty, but adding an option to make copyparty enter into an entirely separate "setup mode" which disables all the usual features, and only provide the setup capabilities? Just another idea to consider once we get to it.

Another idea woud be to build the configuration utility into copyparty, but it would be a textmode / terminal menu-based GUI instead, and not a web-browser UI. But, while that does solve the security-related issues with having a built-in setup feature, I'm not sure if this is a good idea, partially because many docker-based deployments will never let copyparty show an interactive console.

I will probably not be able to pick this up for a while still, so that gives us plenty of time to think :)

9001 commented 1 year ago

I also just realized that it would be safe to keep the setup GUI enabled during normal use as well, because copyparty already supports argon2-hashed passwords. That way, the correct URL/passphrase you would need to access the setup GUI would never be printed to the server log, or displayed on startup, if you provide a hashed password when launching copyparty with --setup-pwd +aCBoaaRSwNv3psWx2HSwmBj-VTI_7RYp (the hashed version of the password you wish to use).

Assuming that the server log is considered safe from prying eyes (which is usually the case), then this is not really a concern in the first place, and using the autogenerated passphrase for permanent access is probably also alright.

EDIT: one concern is that the setup GUI password could be stolen from browser history, or through xss. This can be mitigated by requiring the user to authenticate using the regular login page instead, which generates an access token (stored as a cookie) which is valid for 6 hours, allowing access to the setup GUI. Still just an idea, but one more thing to consider...

kkovaletp commented 1 year ago

it would make it harder for the wizard to understand its own configuration files afterwards, since it would have to "read around" the changes made by the user somehow, and those changes would also probably be lost the next time a new configuration is generated by the wizard.

Well, here I have 2 co-existing points of view:

option to make copyparty enter into an entirely separate "setup mode" which disables all the usual features, and only provide the setup capabilities

interesting approach, it could work, but in that case admin won't be able to test the config at some intermediate states without completely exiting from the wizard and switching the server to the normal state, then getting all the steps in vice versa to continue. This is why I proposed going with independent server and wizard services, as here you could make the changes in the wizard and after a simple server restart see the impact, similar to the idea of nodemon in the scope of the web development

build the configuration utility into copyparty, but it would be a textmode / terminal menu-based GUI instead, and not a web-browser UI

Definitely, it is a more secure solution, as we don't open such sensitive API to the network. However, I'd agree that the very minimal docker containers without a shell won't let the user access this wizard (as well as some cloud deployments, where there is no SSH connect to the instances of deployed solution).

kkovaletp commented 1 year ago

it would be safe to keep the setup GUI enabled during normal use as well

well, my point is that the config UI is like a root: it is super-powerful and not needed during normal operations. There is a best practice to disable the root user on Linux at all. And here I follow the same logic: no matter how strong is the protection, if the door physically exists and thieves know about the gold behind, sooner or later it will be stolen. These days with GPU and cloud computing password bruteforcing is very fast...