Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 31 additions & 74 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,88 +11,45 @@ on:
- master
workflow_dispatch:

permissions:
contents: read
security-events: write
permissions: {}

jobs:
lint:
name: Lint Dockerfile
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- name: Run hadolint
uses: hadolint/hadolint-action@2332a7b74a6de0dda2e2221d575162eba76ba5e5 # v3.3.0
with:
dockerfile: Dockerfile
ignore: DL3018

build:
name: Build Docker Image
runs-on: ubuntu-latest
needs: lint
permissions:
contents: read
steps:
- name: Checkout code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4.2.0

- name: Build Docker image
uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0
with:
context: .
push: false
tags: ghcr.io/netresearch/docker-ftp-server:test
cache-from: type=gha
cache-to: type=gha,mode=max

security-scan:
name: Security Scan
runs-on: ubuntu-latest
needs: build
# Gold-standard container CI via the org meta-reusable: Dockerfile lint
# (+ shellcheck), YAML/compose lint, validation-only image build with
# Trivy, secret scanning and dependency review — one call site.
# References @feat/docker-gold-standard until netresearch/.github#251
# merges; flip to @main afterwards.
docker-ci:
uses: netresearch/.github/.github/workflows/docker-image-ci.yml@main
permissions:
contents: read
packages: write
security-events: write
steps:
- name: Checkout code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4.2.0

- name: Build Docker image
uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0
with:
context: .
load: true
tags: ghcr.io/netresearch/docker-ftp-server:test
cache-from: type=gha

- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0
with:
image-ref: ghcr.io/netresearch/docker-ftp-server:test
format: 'sarif'
output: 'trivy-results.sarif'
severity: 'CRITICAL,HIGH'

- name: Upload Trivy results to GitHub Security tab
uses: github/codeql-action/upload-sarif@7188fc363630916deb702c7fdcf4e481b751f97a # v4.37.1
if: always()
with:
sarif_file: 'trivy-results.sarif'

id-token: write
attestations: write
actions: read
pull-requests: write
with:
image-name: docker-ftp-server
dockerfile: ./Dockerfile
lint-container: true
shell-scandirs: setup
lint-yaml: true
lint-markdown: false
lint-compose: true
compose-files: docker-compose.yml
enable-gitleaks: true
enable-codeql: false
enable-smoke-test: false
secrets:
GITLEAKS_LICENSE: ${{ secrets.GITLEAKS_LICENSE }}

# Bespoke runtime test — boots the image and asserts vsftpd listens on
# port 21. Not covered by the meta (its smoke-test uses
# container-structure-test), so it stays here.
test:
name: Test FTP Server
runs-on: ubuntu-latest
needs: build
permissions:
contents: read
steps:
Expand Down
6 changes: 6 additions & 0 deletions .hadolint.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
# Carries forward the DL3018 ignore the previous CI set inline
# (`ignore: DL3018`). Alpine `apk add` version pinning is impractical for
# this image, so DL3018 (pin package versions) stays suppressed.
ignored:
- DL3018
22 changes: 12 additions & 10 deletions setup/docker-entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,26 @@
set -e

# Add Users and Home directories
# shellcheck disable=SC2206 # intentional split of ;-separated USERS into an array
arrUSERS=(${USERS//;/ })
for userAndPass in "${arrUSERS[@]}"
do
username=${userAndPass%%:*}
# Check if user exists and create if not
userInfo="$(id ${username} || echo 'no such user')"
userInfo="$(id "${username}" || echo 'no such user')"
if [ "${userInfo}" == "no such user" ]; then
adduser -h /home/./${username} -s /bin/false -D ${username}
adduser -h "/home/./${username}" -s /bin/false -D "${username}"
echo "Create user ${username}"
fi
echo "${userAndPass}" | /usr/sbin/chpasswd
if [ -z ${GROUP} ]; then
if [ -z "${GROUP}" ]; then

Check failure on line 18 in setup/docker-entrypoint.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=netresearch_docker-ftp-server&issues=AZ-DYrHKSF-_auD-sG88&open=AZ-DYrHKSF-_auD-sG88&pullRequest=121
GROUP=${username}
fi

chown ${username}:${GROUP} /home/${username}/ -R
chmod 2700 /home/${username}
find /home/${username}/* -type d -exec chmod 2775 {} \; || :
find /home/${username}/* -type f -exec chmod 0664 {} \; || :
chown "${username}:${GROUP}" "/home/${username}/" -R
chmod 2700 "/home/${username}"
find "/home/${username}"/* -type d -exec chmod 2775 {} \; || :
find "/home/${username}"/* -type f -exec chmod 0664 {} \; || :
done

# Fix vsftpd.conf permissions
Expand All @@ -30,6 +31,7 @@


if [ "${ENABLE_LOGGING}" == "yes" ]; then
# shellcheck disable=SC2129 # sequential appends to vsftpd.conf are clearer than a grouped block
echo "xferlog_enable=YES" >> /etc/vsftpd/vsftpd.conf
echo "xferlog_std_format=NO" >> /etc/vsftpd/vsftpd.conf
echo "log_ftp_protocol=YES" >> /etc/vsftpd/vsftpd.conf
Expand All @@ -40,15 +42,15 @@
echo "port_enable=YES" >> /etc/vsftpd/vsftpd.conf
fi

if [ ! -z ${PASSIVE_MODE_MIN_PORT} ]; then
if [ -n "${PASSIVE_MODE_MIN_PORT}" ]; then

Check failure on line 45 in setup/docker-entrypoint.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=netresearch_docker-ftp-server&issues=AZ-DYrHKSF-_auD-sG89&open=AZ-DYrHKSF-_auD-sG89&pullRequest=121
echo "pasv_min_port=${PASSIVE_MODE_MIN_PORT}" >> /etc/vsftpd/vsftpd.conf
fi

if [ ! -z ${PASSIVE_MODE_MAX_PORT} ]; then
if [ -n "${PASSIVE_MODE_MAX_PORT}" ]; then

Check failure on line 49 in setup/docker-entrypoint.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=netresearch_docker-ftp-server&issues=AZ-DYrHKSF-_auD-sG8-&open=AZ-DYrHKSF-_auD-sG8-&pullRequest=121
echo "pasv_max_port=${PASSIVE_MODE_MAX_PORT}" >> /etc/vsftpd/vsftpd.conf
fi

if [ ! -z ${PASSIVE_MODE_ADDRESS} ]; then
if [ -n "${PASSIVE_MODE_ADDRESS}" ]; then

Check failure on line 53 in setup/docker-entrypoint.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=netresearch_docker-ftp-server&issues=AZ-DYrHKSF-_auD-sG8_&open=AZ-DYrHKSF-_auD-sG8_&pullRequest=121
echo "pasv_address=${PASSIVE_MODE_ADDRESS}" >> /etc/vsftpd/vsftpd.conf
fi

Expand Down
Loading