1 Commits

Author SHA1 Message Date
Tim Robinson
a77eae39d3 Fix code styling 2017-07-29 13:11:44 +10:00
7 changed files with 54 additions and 126 deletions

4
.gitignore vendored
View File

@@ -1,4 +0,0 @@
*.swp
srv/
env
vsftpd.pem

View File

@@ -1,24 +1,16 @@
FROM debian:stretch FROM debian:jessie
ARG FTP_UID=48 RUN groupadd -g 48 ftp && \
ARG FTP_GID=48 useradd --no-create-home --home-dir /srv -s /bin/false --uid 48 --gid 48 -c 'ftp daemon' ftp
RUN set -x \
&& groupadd -g ${FTP_GID} ftp \
&& useradd --no-create-home --home-dir /srv -s /bin/false --uid ${FTP_UID} --gid ${FTP_GID} -c 'ftp daemon' ftp \
;
RUN set -x \ RUN apt-get update \
&& apt-get update \ && apt-get install -y --no-install-recommends vsftpd db5.3-util whois \
&& apt-get install -y --no-install-recommends vsftpd db5.3-util whois \ && apt-get clean \
&& apt-get clean \ && rm -rf /var/lib/apt/lists/*
&& rm -rf /var/lib/apt/lists/* \
;
RUN set -x \ RUN mkdir -p /var/run/vsftpd/empty /etc/vsftpd/user_conf /var/ftp /srv && \
&& mkdir -p /var/run/vsftpd/empty /etc/vsftpd/user_conf /var/ftp /srv \ touch /var/log/vsftpd.log && \
&& touch /var/log/vsftpd.log \ rm -rf /srv/ftp
&& rm -rf /srv/ftp \
;
COPY vsftpd*.conf /etc/ COPY vsftpd*.conf /etc/
COPY vsftpd_virtual /etc/pam.d/ COPY vsftpd_virtual /etc/pam.d/
@@ -29,4 +21,4 @@ VOLUME ["/etc/vsftpd", "/srv"]
EXPOSE 21 4559 4560 4561 4562 4563 4564 EXPOSE 21 4559 4560 4561 4562 4563 4564
ENTRYPOINT ["/entry.sh"] ENTRYPOINT ["/entry.sh"]
CMD ["vsftpd"] CMD ["vsftpd"]

View File

@@ -1,49 +1,22 @@
NAME := vsftpd docker_tag = panubo/vsftpd
TAG := latest
IMAGE_NAME := panubo/$(NAME)
.PHONY: build build-local bash run run-ssl help push clean UNAME_S := $(shell uname -s)
help: ifeq ($(UNAME_S),Linux)
@printf "$$(grep -hE '^\S+:.*##' $(MAKEFILE_LIST) | sed -e 's/:.*##\s*/:/' -e 's/^\(.\+\):\(.*\)/\\x1b[36m\1\\x1b[m:\2/' | column -c2 -t -s :)\n" APP_HOST := localhost
endif
ifeq ($(UNAME_S),Darwin)
APP_HOST := $(shell docker-machine ip default)
endif
build: ## Build for publishing build:
docker build --pull -t $(IMAGE_NAME):latest . docker build -t $(docker_tag) .
build-local: ## Builds with local users UID and GID
docker build --build-arg FTP_UID=$(shell id -u) --build-arg FTP_GID=$(shell id -g) -t $(IMAGE_NAME):$(TAG) .
bash: bash:
docker run --rm -it $(IMAGE_NAME):$(TAG) bash docker run --rm -it $(docker_tag) bash
env: run:
@echo "FTP_USER=ftp" >> env $(eval ID := $(shell docker run -d ${docker_tag}))
@echo "FTP_PASSWORD=ftp" >> env
vsftpd.pem:
openssl req -new -newkey rsa:2048 -days 365 -nodes -sha256 -x509 -keyout vsftpd.pem -out vsftpd.pem -subj '/CN=self_signed'
run: env
$(eval ID := $(shell docker run -d --env-file env -v $(shell pwd)/srv:/srv ${IMAGE_NAME}:${TAG}))
$(eval IP := $(shell docker inspect --format '{{ .NetworkSettings.IPAddress }}' ${ID})) $(eval IP := $(shell docker inspect --format '{{ .NetworkSettings.IPAddress }}' ${ID}))
@echo "Running ${ID} @ ftp://${IP}" @echo "Running ${ID} @ ftp://${IP}"
@docker attach ${ID} @docker attach ${ID}
@docker kill ${ID} @docker kill ${ID}
run-ssl: env vsftpd.pem
$(eval ID := $(shell docker run -d --env-file env -v $(shell pwd)/srv:/srv -v $(PWD)/vsftpd.pem:/etc/ssl/certs/vsftpd.crt -v $(PWD)/vsftpd.pem:/etc/ssl/private/vsftpd.key ${IMAGE_NAME}:${TAG} vsftpd /etc/vsftpd_ssl.conf))
$(eval IP := $(shell docker inspect --format '{{ .NetworkSettings.IPAddress }}' ${ID}))
@echo "Running ${ID} @ ftp://${IP}"
@docker attach ${ID}
@docker kill ${ID}
push: ## Pushes the docker image to hub.docker.com
# Don't --pull here, we don't want any last minute upsteam changes
docker build -t $(IMAGE_NAME):$(TAG) .
docker tag $(IMAGE_NAME):$(TAG) $(IMAGE_NAME):latest
docker push $(IMAGE_NAME):$(TAG)
docker push $(IMAGE_NAME):latest
clean: ## Remove built images
docker rmi $(IMAGE_NAME):latest
docker rmi $(IMAGE_NAME):$(TAG)

View File

@@ -1,42 +1,38 @@
# VSFTPD Docker Image # VSFTPD Docker Image
[![Docker Repository on Quay.io](https://quay.io/repository/panubo/vsftpd/status "Docker Repository on Quay.io")](https://quay.io/repository/panubo/vsftpd)
[![](https://badge.imagelayers.io/panubo/vsftpd:latest.svg)](https://imagelayers.io/?images=panubo/vsftpd:latest)
This is a micro-service image for VSFTPD. This is a micro-service image for VSFTPD.
There are a few limitations but it will work if you are using host networking There are a few limitations but it will work if you are using host networking
`--net host` or have a direct/routed network between the Docker container and `--net host` or have a direct/routed network between the Docker container and
the client. the client.
## Virtual Users ## Virtual User
This VSFTPD container uses virtual users. Each user that logs in will have the same system UID and GID. The real users has UID and GID of 48:48 by default, however using build-args this can be changed when building the container. The FTP user has been set to uid 48 and gid 48.
For example use `--build-arg FTP_UID=1000 --build-arg FTP_GID=1000` to set the UID and GID to 1000:1000.
## Options ## Options
The following environment variables are accepted. The following environment variables are accepted.
- `FTP_USER`: Sets the default FTP user - `FTP_USER`: Sets the default FTP user
- `FTP_PASSWORD`: Plain text password (not recommended), or - `FTP_PASSWORD`: Plain text password, or
- `FTP_PASSWORD_HASH`: Sets the password for the user specified by `FTP_USER`. This - `FTP_PASSWORD_HASH`: Sets the password for the user specified above. This
requires a hashed password such as the ones created with `mkpasswd -m sha-512` requires a hashed password such as the ones created with `mkpasswd -m sha-512`
which is in the _whois_ debian package. which is in the _whois_ debian package.
- `FTP_USER_*`: Adds multiple users. Value must be in the form of `username:hash`. Should not be used in conjunction with `FTP_USER` and `FTP_PASSWORD(_HASH)`. - `FTP_USER_*`: Adds mutliple users. Value must be in the form of `username:hash`. Should not be used in conjunction with `FTP_USER` and `FTP_PASSWORD(_HASH)`.
- `FTP_USERS_ROOT`: if set the vsftpd `local_root` will be set to `/srv/$USER` so each user is chrooted to their own directory instead of a shared one. - `FTP_USERS_ROOT`: sets `local_root=/srv/$USER` so each user is chrooted to their own directory instead of a shared one.
- `FTP_CHOWN_ROOT`: if set `chown` will be run against `/srv` setting the FTP user and group as owner and group of the directory. _Note: chown is run non-recursively ie. will only chown the root`_
- `FTP_PASV_ADDRESS`: override the IP address that vsftpd will advertise in
response to the PASV command
## Usage Example ## Usage Example
``` ```
docker run --rm -it -p 21:21 -p 4559-4564:4559-4564 -e FTP_USER=ftp -e FTP_PASSWORD=ftp docker.io/panubo/vsftpd:latest docker run --rm -it -p 21:21 -p 4559:4559 -p 4560:4560 -p 4561:4561 -p 4562:4562 -p 4563:4563 -p 4564:4564 -e FTP_USER=panubo -e FTP_PASSWORD=panubo panubo/vsftpd
``` ```
## SSL Usage ## SSL Usage
@@ -49,19 +45,5 @@ This example assumes the ssl cert and key are in the same file and are mounted
into the container read-only. into the container read-only.
``` ```
docker run --rm -it \ docker run --rm -it -e FTP_USER=panubo -e FTP_PASSWORD_HASH='$6$XWpu...DwK1' -v `pwd`/server.pem:/etc/ssl/certs/vsftpd.crt:ro -v `pwd`/server.pem:/etc/ssl/private/vsftpd.key:ro panubo/vsftpd vsftpd /etc/vsftpd_ssl.conf
-e FTP_USER=panubo -e FTP_PASSWORD_HASH='$6$XWpu...DwK1' \
-v `pwd`/server.pem:/etc/ssl/certs/vsftpd.crt:ro \
-v `pwd`/server.pem:/etc/ssl/private/vsftpd.key:ro \
docker.io/panubo/vsftpd vsftpd /etc/vsftpd_ssl.conf
``` ```
## Security
Currently `allow_writeable_chroot` is turned ON, however this isn't recommended as a security precaution. We might look at making this configurable in the future. The main consequence of turning this off is that the `local_root` can not be writable by the FTP user.
See [serverfault: vsftp: whu is allow_writable_chroot=YES a bad idea?](https://serverfault.com/q/743949/259651)
## Logs
To get the FTP logs mount `/var/log` outside of the container. For example add `-v /var/log/ftp:/var/log` to your `docker run ...` command.

View File

@@ -1,13 +1,12 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# Adds a virtual ftp user to /etc/vsftpd/virtual-users.db
set -e set -e
[[ "${DEBUG}" == "true" ]] && set -x [[ "${DEBUG}" == 'true' ]] && set -x
DB="/etc/vsftpd/virtual-users.db" DB=/etc/vsftpd/virtual-users.db
if [[ "${#}" -lt 2 ]] || [[ "${#}" -gt 3 ]]; then if [[ "$#" -lt 2 || "$#" -gt 3 ]]; then
echo "Usage: $0 [-d] <user> <password>" >&2 echo "Usage: $0 [-d] <user> <password>" >&2
echo >&2 echo >&2
echo "[ -d ] Delete the database first" >&2 echo "[ -d ] Delete the database first" >&2
@@ -21,4 +20,4 @@ if [[ "${1}" == "-d" ]]; then
shift shift
fi fi
printf '%s\n%s\n' "${1}" "${2}" | db5.3_load -T -t hash "${DB}" echo -e "${1}\n${2}" | db5.3_load -T -t hash "${DB}"

View File

@@ -1,42 +1,29 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# vsftpd container entrypoint script
set -e set -e
[[ "${DEBUG}" == "true" ]] && set -x [[ "${DEBUG}" == 'true' ]] && set -x
# Generate password if hash not set # Generate password if hash not set
if [[ ! -z "${FTP_PASSWORD}" ]] && [[ -z "${FTP_PASSWORD_HASH}" ]]; then if [[ ! -z "${FTP_PASSWORD}" && -z "${FTP_PASSWORD_HASH}" ]]; then
FTP_PASSWORD_HASH="$(echo "${FTP_PASSWORD}" | mkpasswd -s -m sha-512)" FTP_PASSWORD_HASH=$(echo "${FTP_PASSWORD}" | mkpasswd -s -m sha-512)
fi fi
if [[ ! -z "${FTP_USER}" ]] || [[ ! -z "${FTP_PASSWORD_HASH}" ]]; then if [[ ! -z "${FTP_USER}" && ! -z "${FTP_PASSWORD_HASH}" ]]; then
echo "Adding user ${FTP_USER}"
/add-virtual-user.sh -d "${FTP_USER}" "${FTP_PASSWORD_HASH}" /add-virtual-user.sh -d "${FTP_USER}" "${FTP_PASSWORD_HASH}"
fi fi
# Support multiple users # Support multiple users
while read -r user; do while read user; do
IFS=: read -r name pass <<< "${!user}" IFS=: read name pass <<< "${!user}"
echo "Adding user ${name}" echo "Adding user ${name}"
/add-virtual-user.sh "${name}" "${pass}" /add-virtual-user.sh "${name}" "${pass}"
done < <(env | grep "FTP_USER_" | sed 's/^\(FTP_USER_[a-zA-Z0-9]*\)=.*/\1/') done < <(env | grep "FTP_USER_" | sed 's/^\(FTP_USER_[a-zA-Z0-9]*\)=.*/\1/')
# Support user directories # Support user directories
if [[ ! -z "${FTP_USERS_ROOT}" ]]; then if [[ ! -z "${FTP_USERS_ROOT}" ]]; then
# shellcheck disable=SC2016 sed -i 's/local_root=.*/local_root=\/srv\/$USER/' "/etc/vsftpd*.conf"
sed -i 's/local_root=.*/local_root=\/srv\/$USER/' /etc/vsftpd*.conf
fi
# Support setting the passive address
if [[ ! -z "$FTP_PASV_ADDRESS" ]]; then
for f in /etc/vsftpd*.conf; do
echo "pasv_address=${FTP_PASV_ADDRESS}" >> "$f"
done
fi
# Manage /srv permissions
if [[ ! -z "${FTP_CHOWN_ROOT}" ]]; then
chown ftp:ftp /srv
fi fi
vsftpd_stop() { vsftpd_stop() {
@@ -51,13 +38,13 @@ vsftpd_stop() {
echo "Done" echo "Done"
} }
if [[ "${1}" == "vsftpd" ]]; then if [[ "$1" == "vsftpd" ]]; then
trap vsftpd_stop SIGINT SIGTERM trap vsftpd_stop SIGINT SIGTERM
echo "Running ${*}" echo "Running $@"
"${@}" & $@ &
pid="${!}" pid="$!"
echo "${pid}" > /var/run/vsftpd/vsftpd.pid echo "${pid}" > /var/run/vsftpd/vsftpd.pid
wait "${pid}" && exit ${?} wait "${pid}" && exit $?
else else
exec "${@}" exec "$@"
fi fi

View File

@@ -15,7 +15,6 @@ user_sub_token=$USER
#local_root=/srv/$USER #local_root=/srv/$USER
local_root=/srv/ local_root=/srv/
userlist_enable=NO userlist_enable=NO
allow_writeable_chroot=YES
# Logging # Logging
log_ftp_protocol=YES log_ftp_protocol=YES