added tests/checksec.sh, added Security section to README.md

This commit is contained in:
Ricard Bejarano 2019-03-21 09:13:24 +01:00
parent 1fad91b403
commit fa03bb2250
No known key found for this signature in database
GPG key ID: 5A5105DD6B91CA19
2 changed files with 118 additions and 0 deletions

View file

@ -19,6 +19,7 @@ Available at [`ricardbejarano/nginx`](https://hub.docker.com/r/ricardbejarano/ng
* Built `FROM scratch`, see the [Filesystem](#Filesystem) section below for an exhaustive list of the image's contents
* Included [TLS1.3](https://tools.ietf.org/html/rfc8446) protocol support (with [OpenSSL](https://www.openssl.org/))
* Reduced attack surface (no `bash`, no UNIX tools, no package manager...)
* Built with exploit mitigations enabled (see [Security](#Security))
## Building
@ -40,6 +41,62 @@ $ docker build -t nginx:musl -f musl/Dockerfile .
```
## Security
This image attempts to build a secure NGINX Docker image.
It does so by the following ways:
- downloading and verifying the source code of NGINX and every library it is built with,
- packaging the image with only those files required during runtime (see [Filesystem](#Filesystem)),
- by enforcing a series of exploit mitigations (PIE, full RELRO, full SSP, NX and Fortify)
### Verifying the presence of exploit mitigations
To check whether a binary in a Docker image has those mitigations enabled, use [tests/checksec.sh](https://github.com/ricardbejarano/nginx/blob/master/tests/checksec.sh).
#### Usage
```
usage: checksec.sh docker_image executable_path
Docker-based wrapper for checksec.sh.
Requires a running Docker daemon.
Example:
$ checksec.sh ricardbejarano/nginx:glibc /nginx
Extracts the '/nginx' binary from the 'ricardbejarano/nginx:glibc' image,
downloads checksec (github.com/slimm609/checksec.sh) and runs it on the
binary.
Everything runs inside Docker containers.
```
#### Example:
Testing the `/nginx` binary in `ricardbejarano/nginx:glibc`:
```
$ bash tests/checksec.sh ricardbejarano/nginx:glibc /nginx
Downloading ricardbejarano/nginx:glibc...Done!
Extracting ricardbejarano/nginx:glibc:/nginx...Done!
Downloading checksec.sh...Done!
Running checksec.sh:
RELRO STACK CANARY NX PIE RPATH RUNPATH Symbols FORTIFY Fortified Fortifiable FILE
Full RELRO Canary found NX enabled PIE enabled No RPATH No RUNPATH 11563 Symbols Yes 0 34 /tmp/.checksec-ui8eKi3Q
Cleaning up...Done!
```
This wrapper script works with any binary in a Docker image. Feel free to use it with any other image.
Other examples:
- `bash tests/checksec.sh debian /bin/bash`
- `bash tests/checksec.sh alpine /bin/sh`
- `bash tests/checksec.sh nginx /usr/sbin/nginx`
## Filesystem
The images' contents are:

61
tests/checksec.sh Normal file
View file

@ -0,0 +1,61 @@
#!/bin/bash
usage() {
echo "usage: checksec.sh docker_image executable_path"
echo ""
echo "Docker-based wrapper for checksec.sh."
echo "Requires a running Docker daemon."
echo ""
echo "Example:"
echo ""
echo " $ checksec.sh ricardbejarano/nginx:glibc /nginx"
echo ""
echo " Extracts the '/nginx' binary from the 'ricardbejarano/nginx:glibc' image,"
echo " downloads checksec (github.com/slimm609/checksec.sh) and runs it on the"
echo " binary."
echo " Everything runs inside Docker containers."
exit 1
}
checksec() {
printf "Downloading $1..."
docker pull "$1" >/dev/null
echo "Done!"
printf "Extracting $1:$2..."
image_container="$(docker create "$1")"
executable_file="$(mktemp .checksec-XXXXXXXX)"
docker cp "$image_container":"$2" "$executable_file"
docker rm "$image_container" >/dev/null
echo "Done!"
printf "Downloading checksec.sh..."
docker run \
--interactive \
--tty \
--rm \
--volume "$PWD/$executable_file":"/tmp/$executable_file" \
debian \
bash \
-c "\
apt update &>/dev/null && \
apt install -y curl file procps binutils openssl &>/dev/null && \
curl \
--silent \
--show-error \
--output /bin/checksec \
https://raw.githubusercontent.com/slimm609/checksec.sh/master/checksec && \
chmod +x /bin/checksec && \
echo 'Done!' && \
echo 'Running checksec.sh:' && \
checksec -f /tmp/$executable_file"
printf "Cleaning up..."
rm -f "$executable_file"
echo "Done!"
exit 0
}
if [ -z "$2" ]; then usage; fi
checksec "$1" "$2"