Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add user before boot-up. #161

Closed
synchronizing opened this issue Aug 29, 2020 · 12 comments
Closed

Add user before boot-up. #161

synchronizing opened this issue Aug 29, 2020 · 12 comments
Labels
enhancement New feature or request

Comments

@synchronizing
Copy link

synchronizing commented Aug 29, 2020

Wondering if there is some sort of environmental variable or file that can be utilized to boot-up the initial user(s) to the service. In relation to #159, this would be an environmental variables that can be set by the user on start:

docker run \
    -p 8000:8000 \ 
    -p 2022:2022 \
    -e SFTPGO_USER=felipe \
    -e SFTPGO_PASSWORD=felipe \
    sftpgo

Following the pattern suggest on #159 (comment), atmoz/sftp currently uses a users.conf to store initial user information, as well as accept the initial user configuration as a param on startup.

Configuration File

docker run \
    -v <host-dir>/users.conf:/etc/sftp/users.conf:ro \
    -v mySftpVolume:/home \
    -p 2222:22 -d atmoz/sftp
users.conf
foo:123:1001:100
bar:abc:1002:100
baz:xyz:1003:100

Start-up Command

Reference here.

docker run -p 22:22 -d atmoz/sftp foo:pass:::upload

This works due to the definition of the Dockerfile here:

ENTRYPOINT ["/entrypoint"]

Which initializes the shell entrypoint file here, and executes:

...
    if $startSshd; then
        # Append users from arguments to final config
        for user in "$@"; do
            echo "$user" >> "$userConfFinalPath"
        done
    fi
...

And adds user to the newly generated configuration file in which atmoz/sftp then reads to provide initial authentication. Despite how atmoz/sftp implements this solution, I would stress a simple environmental variable that is read on start-up and written to the database as an authorized admin user.

@drakkan
Copy link
Owner

drakkan commented Aug 29, 2020

Hi,

we can restore a dump (a json file) but the service must be started. Restoring a dump before starting the service is currently only supported for the memory provider.

A single user can be created in portable mode via CLI arguments or env vars.

Creating a new user using username and password is ok in simple use cases, we have a lot of parameters, we probably need to expose all of them if we want to support this feature.

@synchronizing
Copy link
Author

synchronizing commented Aug 29, 2020

A single user can be created in portable mode via CLI arguments or env vars.

Likely the best and easier choice to implement on the Dockerfile side of things (either or will work). Either way would add the following support:

docker run \
    -p 8000:8000 \ 
    -p 2022:2022 \
    -e SFTPGO_USER=felipe \
    -e SFTPGO_PASSWORD=felipe \
    sftpgo

Env variables, specifically, would have make no difference within Dockerfile assuming that within SFTPGo initialization they are used to create the first user. In the case of CLI argument, Dockerfile would look something like so:

ENTRYPOINT sftpgo serve --username $SFTPGO_USERNAME --password $SFTPGO_PASSWORD

To clarify, whichever way would still have the docker run code above looking the exact same. The -e variable sets the environmental args for runtime, in which ENTRYPOINT is in (that means the $SFTPGO_ variables you see in the ENTRYPOINT command are not Docker build arguments, but rather bash access to an env arg during runtime.)

@synchronizing
Copy link
Author

I made a "boot-leg" solution for my use case. Since the REST API is always on, I created a new folder called /entrypoint inside of the /app directory, moved a add_admin.sh file inside of it:

set_username() {
    if [[ -z "$1" ]]; then
         username="admin"
    else
         username="$1"
    fi
} 

set_password() {
    if [[ -z "$1" ]]; then
         password="secret"
    else
         password="$1"
    fi
} 

# Sets the username and password to the env variable.
set_username ${SFTPGO_USERNAME}
set_password ${SFTPGO_PASSWORD}

# Sends web request to API to add username and password.
curl --header "Content-Type: application/json" \
     --request POST \
     --data '{"username": "'${username}'", "password": "'${password}'", "status": 1, "home_dir": "/app/data/", "permissions": {"/": ["*"]}}' \
     http://127.0.0.1:8080/api/v1/user

And then have all the shell files inside of /app/entrypoint running on boot-up:

ENTRYPOINT (sleep 3 && for f in /app/entrypoint/*.sh; do bash "$f" -H; done) & sftpgo serve

Simply calling the below works.

docker run \
    -p 8000:8000 \ 
    -p 2022:2022 \
    -e SFTPGO_USER=felipe \
    -e SFTPGO_PASSWORD=felipe \
    sftpgo

@drakkan
Copy link
Owner

drakkan commented Aug 30, 2020

Hi,

I think using the REST API is the right way to add users, this way we can avoid to use data provider specific code, we could also restore a provider independent dump file.

We could allow to execute custom scripts from a specific folder, so the users can customize things.

I think your add_admin.sh should be a custom script.

We should execute initprovider inside a docker-entrypoint.sh script or similar. MySQL do a lot of things inside its entrypoint

@drakkan
Copy link
Owner

drakkan commented Aug 30, 2020

after 600a107 we can call initprovider unconditionally

@synchronizing
Copy link
Author

synchronizing commented Sep 3, 2020

Okay, understood. Let me ask you this: Is there a command line utility to add users, or is the REST API the only way? With Docker, it is my opinion, the user should be able to test out the SFTP server via a single command line utility. That is, simply running (the below) without any SFTPGo files present on their machine should be enough to query DockerHub for the sftpgo image, and boot-up a server that allows instant access to it for testing purposes.

docker run \
    -p 8000:8000 \ 
    -p 2022:2022 \
    sftpgo

Is it your choice to limit the users account creation to specifically the web portal? I'm trying to understand how you would like to go about it so I can implement the Dockerfile accordingly. :)

@synchronizing
Copy link
Author

Also, is there a list of all available ENV variables for which sftpgo access? Looking through the repo for SFTPGO_HTTPD__BIND_ADDRESS I see no mention of this inside the code. Only mention is here:

ENV SFTPGO_HTTPD__BIND_ADDRESS=""

@drakkan
Copy link
Owner

drakkan commented Sep 3, 2020

Hi,

first of all thank you for working on this, I would like to help but I'm quite busy and I can only do quick tasks on SFTPGo at the moment.

Regarding your questions:

  1. SFTPGo exposes a REST API for users and connections management. We provide and OpenAPI schema. The web interface is a sample implementation, we have a sample CLI too. There are several OpenAPI generators available, please read the doc here for more details
  2. all configuration parameters and the serve flags are available as env vars. Please read the doc here for details. This section explains how to override the configuration options using environment variables.

I agree that we should be able to run SFTPGo for testing purpose with a command like this:

docker run \
    -p 8000:8000 \ 
    -p 2022:2022 \
    sftpgo

user creation should be optional.

Maybe a convenient API to create users is the loaddata REST API using mode 1 existing users are not modified so we can run it uncoditionatally. This is only a guess. Thank you!

@drakkan
Copy link
Owner

drakkan commented Oct 5, 2020

Hi,

please give a try to the package here

https://github.com/users/drakkan/packages/container/package/sftpgo

@sagikazarmark did a great work! Documentation will follow, maybe after 1.1.0 release

Regarding the feature you requested here I think I'll add a new configuration that allow to restore users from a backup something like restore_path. The file will be deleted after a successfull restore, what do you think about?

Creating users from env var is not easy we have a lot of options, you could simply create on or more users from a test instance, create a dump via REST API and let SFTPGo restore this dump on startup.

@sagikazarmark
Copy link
Contributor

Ideally, the official docker image should be free of custom logic and should serve as a base for customizations. The image produced by the current Dockerfile allows you to build a custom image and run sftpgo in portable mode with the desired environment variables.

@drakkan
Copy link
Owner

drakkan commented Oct 5, 2020

If you need a single user overriding the default CMD and using the portable mode is the way to go.

I'm wondering if it could be useful to have a shortcut to restore a backup on startup as alternative to the REST API.

@sagikazarmark
Copy link
Contributor

I'm generally against everything, that magically modifies state on startup. 😄 It's a loaded gun aimed at your foot.

@drakkan drakkan added the enhancement New feature or request label Oct 20, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants