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

View File

@@ -1,49 +1,22 @@
NAME := vsftpd
TAG := latest
IMAGE_NAME := panubo/$(NAME)
docker_tag = panubo/vsftpd
.PHONY: build build-local bash run run-ssl help push clean
help:
@printf "$$(grep -hE '^\S+:.*##' $(MAKEFILE_LIST) | sed -e 's/:.*##\s*/:/' -e 's/^\(.\+\):\(.*\)/\\x1b[36m\1\\x1b[m:\2/' | column -c2 -t -s :)\n"
UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S),Linux)
APP_HOST := localhost
endif
ifeq ($(UNAME_S),Darwin)
APP_HOST := $(shell docker-machine ip default)
endif
build: ## Build for publishing
docker build --pull -t $(IMAGE_NAME):latest .
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) .
build:
docker build -t $(docker_tag) .
bash:
docker run --rm -it $(IMAGE_NAME):$(TAG) bash
docker run --rm -it $(docker_tag) bash
env:
@echo "FTP_USER=ftp" >> env
@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}))
run:
$(eval ID := $(shell docker run -d ${docker_tag}))
$(eval IP := $(shell docker inspect --format '{{ .NetworkSettings.IPAddress }}' ${ID}))
@echo "Running ${ID} @ ftp://${IP}"
@docker attach ${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
[![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.
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
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.
For example use `--build-arg FTP_UID=1000 --build-arg FTP_GID=1000` to set the UID and GID to 1000:1000.
The FTP user has been set to uid 48 and gid 48.
## Options
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`
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_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
- `FTP_USERS_ROOT`: sets `local_root=/srv/$USER` so each user is chrooted to their own directory instead of a shared one.
## 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
@@ -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.
```
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 \
docker.io/panubo/vsftpd vsftpd /etc/vsftpd_ssl.conf
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
```
## 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
# Adds a virtual ftp user to /etc/vsftpd/virtual-users.db
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 >&2
echo "[ -d ] Delete the database first" >&2
@@ -21,4 +20,4 @@ if [[ "${1}" == "-d" ]]; then
shift
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
# vsftpd container entrypoint script
set -e
[[ "${DEBUG}" == "true" ]] && set -x
[[ "${DEBUG}" == 'true' ]] && set -x
# Generate password if hash not set
if [[ ! -z "${FTP_PASSWORD}" ]] && [[ -z "${FTP_PASSWORD_HASH}" ]]; then
FTP_PASSWORD_HASH="$(echo "${FTP_PASSWORD}" | mkpasswd -s -m sha-512)"
if [[ ! -z "${FTP_PASSWORD}" && -z "${FTP_PASSWORD_HASH}" ]]; then
FTP_PASSWORD_HASH=$(echo "${FTP_PASSWORD}" | mkpasswd -s -m sha-512)
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}"
fi
# Support multiple users
while read -r user; do
IFS=: read -r name pass <<< "${!user}"
while read user; do
IFS=: read name pass <<< "${!user}"
echo "Adding user ${name}"
/add-virtual-user.sh "${name}" "${pass}"
done < <(env | grep "FTP_USER_" | sed 's/^\(FTP_USER_[a-zA-Z0-9]*\)=.*/\1/')
# Support user directories
if [[ ! -z "${FTP_USERS_ROOT}" ]]; then
# shellcheck disable=SC2016
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
sed -i 's/local_root=.*/local_root=\/srv\/$USER/' "/etc/vsftpd*.conf"
fi
vsftpd_stop() {
@@ -51,13 +38,13 @@ vsftpd_stop() {
echo "Done"
}
if [[ "${1}" == "vsftpd" ]]; then
if [[ "$1" == "vsftpd" ]]; then
trap vsftpd_stop SIGINT SIGTERM
echo "Running ${*}"
"${@}" &
pid="${!}"
echo "Running $@"
$@ &
pid="$!"
echo "${pid}" > /var/run/vsftpd/vsftpd.pid
wait "${pid}" && exit ${?}
wait "${pid}" && exit $?
else
exec "${@}"
exec "$@"
fi

View File

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