embedded cert.sh
This commit is contained in:
parent
488acf16c1
commit
962624e294
16
.drone.yml
16
.drone.yml
@ -42,11 +42,11 @@ steps:
|
||||
dockerfile: Dockerfile
|
||||
force_tag: true
|
||||
password:
|
||||
from_secret: docker_gitea_password
|
||||
from_secret: gitea_docker_password
|
||||
registry: git.asperti.com
|
||||
repo: git.asperti.com/paspo/docker-ftps
|
||||
username:
|
||||
from_secret: docker_gitea_username
|
||||
from_secret: gitea_docker_username
|
||||
tags:
|
||||
- ${DRONE_TAG}-linux-amd64
|
||||
- ${DRONE_SEMVER_MAJOR}.${DRONE_SEMVER_MINOR}-linux-amd64
|
||||
@ -100,11 +100,11 @@ steps:
|
||||
dockerfile: Dockerfile
|
||||
force_tag: true
|
||||
password:
|
||||
from_secret: docker_gitea_password
|
||||
from_secret: gitea_docker_password
|
||||
registry: git.asperti.com
|
||||
repo: git.asperti.com/paspo/docker-ftps
|
||||
username:
|
||||
from_secret: docker_gitea_username
|
||||
from_secret: gitea_docker_username
|
||||
tags:
|
||||
- ${DRONE_TAG}-linux-arm64
|
||||
- ${DRONE_SEMVER_MAJOR}.${DRONE_SEMVER_MINOR}-linux-arm64
|
||||
@ -158,11 +158,11 @@ steps:
|
||||
dockerfile: Dockerfile
|
||||
force_tag: true
|
||||
password:
|
||||
from_secret: docker_gitea_password
|
||||
from_secret: gitea_docker_password
|
||||
registry: git.asperti.com
|
||||
repo: git.asperti.com/paspo/docker-ftps
|
||||
username:
|
||||
from_secret: docker_gitea_username
|
||||
from_secret: gitea_docker_username
|
||||
tags:
|
||||
- ${DRONE_TAG}-linux-arm
|
||||
- ${DRONE_SEMVER_MAJOR}.${DRONE_SEMVER_MINOR}-linux-arm
|
||||
@ -203,9 +203,9 @@ steps:
|
||||
ignore_missing: true
|
||||
spec: manifest2.tmpl
|
||||
username:
|
||||
from_secret: docker_gitea_username
|
||||
from_secret: gitea_docker_username
|
||||
password:
|
||||
from_secret: docker_gitea_password
|
||||
from_secret: gitea_docker_password
|
||||
tags:
|
||||
- latest
|
||||
- ${DRONE_TAG}
|
||||
|
16
Dockerfile
16
Dockerfile
@ -1,17 +1,9 @@
|
||||
FROM alpine:edge
|
||||
FROM alpine:latest
|
||||
|
||||
RUN \
|
||||
echo "http://dl-cdn.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories && \
|
||||
apk -U add proftpd proftpd-mod_tls proftpd-mod_ifsession proftpd-utils openssl perl && \
|
||||
apk -U add proftpd proftpd-mod_tls proftpd-mod_ifsession proftpd-utils openssl perl acme.sh && \
|
||||
mkdir -p /var/run/proftpd /etc/proftpd/custom.conf.d/
|
||||
|
||||
COPY custom.conf /etc/proftpd/conf.d/custom.conf
|
||||
COPY run.sh /run.sh
|
||||
COPY cron.sh /cron.sh
|
||||
COPY rootfs /
|
||||
|
||||
RUN \
|
||||
chmod +x /run.sh && \
|
||||
chmod +x /cron.sh && \
|
||||
ln -s /cron.sh /etc/periodic/15min/reconfigure_certs.sh
|
||||
|
||||
ENTRYPOINT ["/run.sh"]
|
||||
ENTRYPOINT ["/app/entrypoint.sh"]
|
||||
|
60
README.md
60
README.md
@ -22,7 +22,7 @@ docker run -d --name my-ftps \
|
||||
```
|
||||
|
||||
The *MASQUERADE* parameter is the only required one. You can use an IP address (which is discouraged) or a DNS name.
|
||||
You must provide valid certificates for TLS; if you use Lets'Encrypt, you can mofify like this:
|
||||
You must provide valid certificates for TLS; if you use Lets'Encrypt, you can modify like this:
|
||||
|
||||
```bash
|
||||
docker run -d --name my-ftps \
|
||||
@ -33,7 +33,7 @@ docker run -d --name my-ftps \
|
||||
docker.asperti.com/paspo/ftps
|
||||
```
|
||||
|
||||
## docker-compose
|
||||
## docker-compose (external certificate)
|
||||
|
||||
```yaml
|
||||
version: "3"
|
||||
@ -56,12 +56,66 @@ services:
|
||||
- PASSIVEPORTS_START=21210
|
||||
- PASSIVEPORTS_END=21220
|
||||
- MAXCLIENTS=500
|
||||
- MAXCLIENTSPERHOST=100
|
||||
- MAXCLIENTSPERHOST=100
|
||||
- TLS_CERT=/certs/live/ftp.mydomain.com/cert.pem
|
||||
- TLS_KEY=/certs/live/ftp.mydomain.com/privkey.pem
|
||||
- TLS_CHAIN=/certs/live/ftp.mydomain.com/chain.pem
|
||||
```
|
||||
|
||||
## docker-compose (using internal acme.sh)
|
||||
|
||||
```yaml
|
||||
version: "3"
|
||||
services:
|
||||
|
||||
ftps-server:
|
||||
image: docker.asperti.com/paspo/ftps
|
||||
restart: always
|
||||
ports:
|
||||
- "21:21"
|
||||
- "20:20"
|
||||
- "21210-21220:21210-21220"
|
||||
volumes:
|
||||
- "/srv/ftps/auth:/auth"
|
||||
- "/srv/ftps/conf:/etc/proftpd/custom.conf.d:ro"
|
||||
- "/srv/ftps/data:/home"
|
||||
- "/srv/ftps/acme:/acme"
|
||||
environment:
|
||||
- MASQUERADE=ftp.mydomain.com
|
||||
- PASSIVEPORTS_START=21210
|
||||
- PASSIVEPORTS_END=21220
|
||||
- MAXCLIENTS=500
|
||||
- MAXCLIENTSPERHOST=100
|
||||
- ENABLE_ACME=1 # "1" will enable, anything else means external cert
|
||||
- ACME_SERVER=letsencrypt # optional
|
||||
- ACME_EMAIL=myemail@gmail.com # used by letsencrypt
|
||||
- ACME_DNS=dns_ovh # see below
|
||||
- OVH_END_POINT=ovh-eu
|
||||
- OVH_AK=abc123abc123abc1 # application key
|
||||
- OVH_AS=abc123abc123abc1abc123abc123abc1 # application secret
|
||||
- OVH_CK=abc123abc123abc1abc123abc123abc1 # consumer key
|
||||
```
|
||||
|
||||
## The rationale behind the acme.sh alternative
|
||||
|
||||
You normally use an external letsencrypt client to obtain the certificate and then pass it to the docker container. In some cases, you can't use an external acme client and/or you can't do HTTP-01 auth.
|
||||
The included `acme.sh` client will help you to setup DNS-01 auth and in keeping the cert updated.
|
||||
Please check [here](https://github.com/acmesh-official/acme.sh/wiki/dnsapi) for supported dns providers.
|
||||
Each provider will use different environment variables, you have to add these variables to the container's environment.
|
||||
|
||||
### OVH
|
||||
|
||||
A quick way to create required credentials for OVH:
|
||||
|
||||
- login to your [OVH accuont](https://www.ovh.com/manager/)
|
||||
- paste in your browser an URL like the following one:
|
||||
|
||||
```txt
|
||||
https://api.ovh.com/createToken/?GET=/domain/zone/mydomain.com/*&POST=/domain/zone/mydomain.com/*&PUT=/domain/zone/mydomain.com/*&GET=/domain/zone/mydomain.com&DELETE=/domain/zone/mydomain.com/record/*
|
||||
```
|
||||
|
||||
This will create some credentials that'll allow management only for that domain (`mydomain.com`).
|
||||
|
||||
## passive ports
|
||||
|
||||
If you want to change the passive ports range (which by default is 50000-50050), you can do so via environment variables (PASSIVEPORTS_START and PASSIVEPORTS_END).
|
||||
|
28
rootfs/app/acme-cert-init.sh
Executable file
28
rootfs/app/acme-cert-init.sh
Executable file
@ -0,0 +1,28 @@
|
||||
#!/bin/sh
|
||||
|
||||
MASQUERADE=${MASQUERADE:-127.0.0.1}
|
||||
ACME_SERVER=${ACME_SERVER:-letsencrypt}
|
||||
ACME_DNS=${ACME_DNS:-myapi}
|
||||
|
||||
if [ ! -d /acme/cert ] ; then
|
||||
mkdir -p /acme/cert
|
||||
fi
|
||||
|
||||
if [ -n "${ACME_EMAIL}" ] ; then
|
||||
ACME_EMAIL="--accountemail ${ACME_EMAIL}"
|
||||
fi
|
||||
|
||||
if [ ! -f "/acme/cert/cert.pem" ] ; then
|
||||
echo "Initializing certificate with acme.sh"
|
||||
# shellcheck disable=SC2086
|
||||
acme.sh --issue -d "${MASQUERADE}" \
|
||||
--home /acme \
|
||||
--dns "${ACME_DNS}" \
|
||||
--server "${ACME_SERVER}" \
|
||||
--cert-file /acme/cert/cert.pem \
|
||||
--key-file /acme/cert/privkey.pem \
|
||||
--fullchain-file /acme/cert/chain.pem \
|
||||
--reloadcmd /app/acme-refresh-cert.sh ${ACME_EMAIL}
|
||||
else
|
||||
echo "Certificate ready"
|
||||
fi
|
5
rootfs/app/acme-cron.sh
Executable file
5
rootfs/app/acme-cron.sh
Executable file
@ -0,0 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ "$ENABLE_ACME" = "1" ] ; then
|
||||
/usr/bin/acme.sh --cron --home /acme
|
||||
fi
|
38
rootfs/app/acme-refresh-cert.sh
Executable file
38
rootfs/app/acme-refresh-cert.sh
Executable file
@ -0,0 +1,38 @@
|
||||
#!/bin/sh
|
||||
|
||||
############ FILES
|
||||
|
||||
TLS_CERT=/acme/cert/cert.pem
|
||||
TLS_KEY=/acme/cert/privkey.pem
|
||||
TLS_CHAIN=/acme/cert/chain.pem
|
||||
|
||||
[ ! -f "$TLS_CERT" ] && exit 1
|
||||
[ ! -f "$TLS_KEY" ] && exit 1
|
||||
[ ! -f "$TLS_CHAIN" ] && exit 1
|
||||
|
||||
############ CHECK CERT KEY ALGO
|
||||
ALGO=$(openssl x509 -in "$TLS_CERT"-text | sed -n 's/\ *Public Key Algorithm: //p' | tr '\n')
|
||||
|
||||
############ UPDATE cert config if needed
|
||||
if [ "$ALGO" = "id-ecPublicKey" ] ; then
|
||||
cat > /etc/proftpd/conf.d/certificate.conf <<EOF
|
||||
<IfModule mod_tls.c>
|
||||
TLSECCertificateFile "$TLS_CERT"
|
||||
TLSECCertificateKeyFile "$TLS_KEY"
|
||||
TLSCertificateChainFile "$TLS_CHAIN"
|
||||
</IfModule>
|
||||
EOF
|
||||
fi
|
||||
|
||||
if [ "$ALGO" = "rsaEncryption" ] ; then
|
||||
cat > /etc/proftpd/conf.d/certificate.conf <<EOF
|
||||
<IfModule mod_tls.c>
|
||||
TLSRSACertificateFile "$TLS_CERT"
|
||||
TLSRSACertificateKeyFile "$TLS_KEY"
|
||||
TLSCertificateChainFile "$TLS_CHAIN"
|
||||
</IfModule>
|
||||
EOF
|
||||
fi
|
||||
|
||||
############ RELOAD PROFTPD IF RUNNING
|
||||
pidof proftpd >/dev/null && killall -HUP proftpd
|
20
cron.sh → rootfs/app/cert-init.sh
Normal file → Executable file
20
cron.sh → rootfs/app/cert-init.sh
Normal file → Executable file
@ -1,23 +1,18 @@
|
||||
#!/bin/sh
|
||||
|
||||
############ TLS
|
||||
|
||||
TLS_CERT=${TLS_CERT:-/certs/cert.pem}
|
||||
TLS_KEY=${TLS_KEY:-/certs/privkey.pem}
|
||||
TLS_CHAIN=${TLS_CHAIN:-/certs/chain.pem}
|
||||
|
||||
cat $TLS_CERT > /etc/proftpd/cert.pem
|
||||
cat $TLS_KEY > /etc/proftpd/privkey.pem
|
||||
cat $TLS_CHAIN > /etc/proftpd/chain.pem
|
||||
|
||||
############ IF CERT IS THE SAME, THEN EXIT
|
||||
|
||||
md5sum -c /sums 1&>2 2>/dev/null && exit
|
||||
cat "$TLS_CERT" > /etc/proftpd/cert.pem
|
||||
cat "$TLS_KEY" > /etc/proftpd/privkey.pem
|
||||
cat "$TLS_CHAIN "> /etc/proftpd/chain.pem
|
||||
|
||||
############ CHECK CERT KEY ALGO
|
||||
|
||||
ALGO=$(openssl x509 -in /etc/proftpd/cert.pem -text | sed -n 's/\ *Public Key Algorithm: //p' | tr '\n')
|
||||
|
||||
############ UPDATE cert config if needed
|
||||
if [ "$ALGO" = "id-ecPublicKey" ] ; then
|
||||
cat > /etc/proftpd/conf.d/certificate.conf <<EOF
|
||||
<IfModule mod_tls.c>
|
||||
@ -38,8 +33,5 @@ cat > /etc/proftpd/conf.d/certificate.conf <<EOF
|
||||
EOF
|
||||
fi
|
||||
|
||||
md5sum "$TLS_CERT" > /sums
|
||||
|
||||
############ RELOAD
|
||||
|
||||
killall -HUP proftpd
|
||||
md5sum "$TLS_CERT" > /app/sums
|
||||
echo "Certificate ready"
|
52
run.sh → rootfs/app/cron.sh
Normal file → Executable file
52
run.sh → rootfs/app/cron.sh
Normal file → Executable file
@ -1,29 +1,23 @@
|
||||
#!/bin/sh
|
||||
|
||||
############ MASQUERADE
|
||||
|
||||
MASQUERADE=${MASQUERADE:-127.0.0.1}
|
||||
echo "MasqueradeAddress ${MASQUERADE}" > /etc/proftpd/conf.d/masquerade.conf
|
||||
|
||||
############ AUTH
|
||||
|
||||
[ ! -f /auth/passwd ] && touch /auth/passwd
|
||||
|
||||
chmod 0600 /auth/passwd
|
||||
chmod 0700 /auth
|
||||
############ IF ACME IS ENABLED, THIS IS THE WRONG SCRIPT
|
||||
if [ ! "$ENABLE_ACME" = "1" ] ; then
|
||||
exit
|
||||
fi
|
||||
|
||||
############ TLS
|
||||
|
||||
TLS_CERT=${TLS_CERT:-/certs/cert.pem}
|
||||
TLS_KEY=${TLS_KEY:-/certs/privkey.pem}
|
||||
TLS_CHAIN=${TLS_CHAIN:-/certs/chain.pem}
|
||||
|
||||
cat $TLS_CERT > /etc/proftpd/cert.pem
|
||||
cat $TLS_KEY > /etc/proftpd/privkey.pem
|
||||
cat $TLS_CHAIN > /etc/proftpd/chain.pem
|
||||
cat "$TLS_CERT" > /etc/proftpd/cert.pem
|
||||
cat "$TLS_KEY" > /etc/proftpd/privkey.pem
|
||||
cat "$TLS_CHAIN" > /etc/proftpd/chain.pem
|
||||
|
||||
############ IF CERT IS THE SAME, THEN EXIT
|
||||
md5sum -c /app/sums >/dev/null 2>/dev/null && exit
|
||||
|
||||
############ CHECK CERT KEY ALGO
|
||||
|
||||
ALGO=$(openssl x509 -in /etc/proftpd/cert.pem -text | sed -n 's/\ *Public Key Algorithm: //p' | tr '\n')
|
||||
|
||||
if [ "$ALGO" = "id-ecPublicKey" ] ; then
|
||||
@ -46,27 +40,7 @@ cat > /etc/proftpd/conf.d/certificate.conf <<EOF
|
||||
EOF
|
||||
fi
|
||||
|
||||
md5sum "$TLS_CERT" > /sums
|
||||
md5sum "$TLS_CERT" > /app/sums
|
||||
|
||||
############ PASSIVE PORTS
|
||||
|
||||
PASSIVEPORTS_START=${PASSIVEPORTS_START:-50000}
|
||||
PASSIVEPORTS_END=${PASSIVEPORTS_END:-50050}
|
||||
|
||||
echo "PassivePorts ${PASSIVEPORTS_START} ${PASSIVEPORTS_END}" > /etc/proftpd/conf.d/passive_ports.conf
|
||||
|
||||
############ MAX CLIENTS
|
||||
|
||||
MAXCLIENTS=${MAXCLIENTS:-30}
|
||||
MAXCLIENTSPERHOST=${MAXCLIENTSPERHOST:-5}
|
||||
|
||||
echo "Maxclients ${MAXCLIENTS}" > /etc/proftpd/conf.d/maxclients.conf
|
||||
echo "MaxClientsPerHost ${MAXCLIENTSPERHOST}" >> /etc/proftpd/conf.d/maxclients.conf
|
||||
|
||||
############ START CRON
|
||||
|
||||
crond -b
|
||||
|
||||
############ START
|
||||
|
||||
proftpd -n
|
||||
############ RELOAD
|
||||
killall -HUP proftpd
|
36
rootfs/app/entrypoint.sh
Executable file
36
rootfs/app/entrypoint.sh
Executable file
@ -0,0 +1,36 @@
|
||||
#!/bin/sh
|
||||
|
||||
############ MASQUERADE
|
||||
MASQUERADE=${MASQUERADE:-127.0.0.1}
|
||||
echo "MasqueradeAddress ${MASQUERADE}" > /etc/proftpd/conf.d/masquerade.conf
|
||||
|
||||
############ AUTH
|
||||
[ ! -f /auth/passwd ] && touch /auth/passwd
|
||||
chmod 0600 /auth/passwd
|
||||
chmod 0700 /auth
|
||||
|
||||
############ PASSIVE PORTS
|
||||
PASSIVEPORTS_START=${PASSIVEPORTS_START:-50000}
|
||||
PASSIVEPORTS_END=${PASSIVEPORTS_END:-50050}
|
||||
echo "PassivePorts ${PASSIVEPORTS_START} ${PASSIVEPORTS_END}" > /etc/proftpd/conf.d/passive_ports.conf
|
||||
|
||||
############ MAX CLIENTS
|
||||
MAXCLIENTS=${MAXCLIENTS:-30}
|
||||
MAXCLIENTSPERHOST=${MAXCLIENTSPERHOST:-5}
|
||||
echo "Maxclients ${MAXCLIENTS}" > /etc/proftpd/conf.d/maxclients.conf
|
||||
echo "MaxClientsPerHost ${MAXCLIENTSPERHOST}" >> /etc/proftpd/conf.d/maxclients.conf
|
||||
|
||||
############ CERT INIT
|
||||
ENABLE_ACME=${ENABLE_ACME:-no}
|
||||
|
||||
if [ "$ENABLE_ACME" = "1" ] ; then
|
||||
/app/acme-cert-init.sh
|
||||
else
|
||||
/app/cert-init.sh
|
||||
fi
|
||||
|
||||
############ START CRON
|
||||
crond -b
|
||||
|
||||
############ START
|
||||
proftpd -n
|
38
rootfs/app/refresh-cert.sh
Executable file
38
rootfs/app/refresh-cert.sh
Executable file
@ -0,0 +1,38 @@
|
||||
#!/bin/sh
|
||||
|
||||
############ FILES
|
||||
|
||||
TLS_CERT=/acme/cert/cert.pem
|
||||
TLS_KEY=/acme/cert/privkey.pem
|
||||
TLS_CHAIN=/acme/cert/chain.pem
|
||||
|
||||
[ ! -f "$TLS_CERT" ] && exit 1
|
||||
[ ! -f "$TLS_KEY" ] && exit 1
|
||||
[ ! -f "$TLS_CHAIN" ] && exit 1
|
||||
|
||||
############ CHECK CERT KEY ALGO
|
||||
ALGO=$(openssl x509 -in "$TLS_CERT"-text | sed -n 's/\ *Public Key Algorithm: //p' | tr '\n')
|
||||
|
||||
############ UPDATE cert config if needed
|
||||
if [ "$ALGO" = "id-ecPublicKey" ] ; then
|
||||
cat > /etc/proftpd/conf.d/certificate.conf <<EOF
|
||||
<IfModule mod_tls.c>
|
||||
TLSECCertificateFile "$TLS_CERT"
|
||||
TLSECCertificateKeyFile "$TLS_KEY"
|
||||
TLSCertificateChainFile "$TLS_CHAIN"
|
||||
</IfModule>
|
||||
EOF
|
||||
fi
|
||||
|
||||
if [ "$ALGO" = "rsaEncryption" ] ; then
|
||||
cat > /etc/proftpd/conf.d/certificate.conf <<EOF
|
||||
<IfModule mod_tls.c>
|
||||
TLSRSACertificateFile "$TLS_CERT"
|
||||
TLSRSACertificateKeyFile "$TLS_KEY"
|
||||
TLSCertificateChainFile "$TLS_CHAIN"
|
||||
</IfModule>
|
||||
EOF
|
||||
fi
|
||||
|
||||
############ RELOAD PROFTPD IF RUNNING
|
||||
pidof proftpd >/dev/null && killall -HUP proftpd
|
1
rootfs/etc/periodic/daily/acme-cron.sh
Symbolic link
1
rootfs/etc/periodic/daily/acme-cron.sh
Symbolic link
@ -0,0 +1 @@
|
||||
../../../app/acme-cron.sh
|
1
rootfs/etc/periodic/hourly/cron.sh
Symbolic link
1
rootfs/etc/periodic/hourly/cron.sh
Symbolic link
@ -0,0 +1 @@
|
||||
../../../app/cron.sh
|
Loading…
Reference in New Issue
Block a user