01 / Connect
Ask what a client asks.
Handshakes at each TLS version, one request for the front page, and the DNS records a mail server reads. Nothing is sent that a browser or a mail server would not send.
Porch by denyfirst
What your infrastructure presents to the outside world: the TLS handshake and certificate, how the site is reached, and what the domain's DNS says about its mail. Each finding cites the rule behind it, and what could not be measured is said.
TLS & certificatesWeb reachMail policyDNSName inventory
How it worksTry itLive
This deployment checks only the domains this project runs. To check yours, run Porch yourself.
How it works
Here it checks our own domain. Run it yourself for the infrastructure you are responsible for.
01 / Connect
Handshakes at each TLS version, one request for the front page, and the DNS records a mail server reads. Nothing is sent that a browser or a mail server would not send.
02 / Examine
Each check has its own rule set, and every finding cites the standard it rests on. Where no standard sets a line, the fact is reported rather than graded.
03 / Understand
Each check leads with its verdict and its findings, with the tables and limits underneath. Your own copy lets you save every report.
Get started
Docker on the server, and nothing else. The image is named by its digest, and the compose file that names it is signed.
One paste puts the compose file shown below on the server, with its
signed checksums, and checks both. It carries the release key rather
than fetching it. The last line has to print
Good "file" signature with the key
SHA256:ut6bginhZ4lZINMSXNDv3vJ6fyvmDHhtnoBJH0/Nr9Y
and docker-compose.yml: OK. If a check fails, the compose
file is removed and the next step has nothing to start.
What each check proves.
mkdir -p porch && cd porch
for f in docker-compose.yml SHA256SUMS SHA256SUMS.sig; do curl -fsSLO "https://github.com/denyfirst/porch/releases/latest/download/${f}"; done
echo 'releases@denyfirst.dev ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDD7Ie9zRf76RynH052/Abkv5k2nzosQd2DihyQMixVR' > allowed_signers
ssh-keygen -Y verify -f allowed_signers -I releases@denyfirst.dev -n file -s SHA256SUMS.sig < SHA256SUMS && sha256sum --ignore-missing -c SHA256SUMS || { rm -f docker-compose.yml; echo 'STOP: docker-compose.yml did not verify and was removed'; }
Make the data directory and start it. Proof of control and a password are always on.
mkdir -p porch-data && sudo chown 65534:65534 porch-data
docker compose up -d
It listens only on the server itself. Reach it through SSH, then open
http://localhost:8080.
ssh -L 8080:127.0.0.1:8080 you@your-server
docker-compose.ymlWhat step 1 puts on your server, to read before it runs. Nothing to copy here: the copy that runs is the one step 1 checked.
services:
porch:
image: ghcr.io/denyfirst/porch@sha256:a2af6b0c8c7f940961f14a653aafdf99ee96dfcac63dcb17d01564ab43fd0a18
command:
- "-listen"
- "0.0.0.0:8080"
- "-verification-secret-file"
- "/data/secret"
- "-access-file"
- "/data/access"
ports:
- "127.0.0.1:8080:8080"
volumes:
- /etc/ssl/certs:/etc/ssl/certs:ro
- ./porch-data:/data
environment:
SSL_CERT_DIR: /etc/ssl/certs
read_only: true
security_opt:
- no-new-privileges:true
cap_drop:
- ALL
restart: unless-stopped
scan:
image: ghcr.io/denyfirst/porch@sha256:a2af6b0c8c7f940961f14a653aafdf99ee96dfcac63dcb17d01564ab43fd0a18
profiles: ["cli"]
entrypoint: ["/porch-scan", "-verification-secret-file", "/data/secret"]
volumes:
- /etc/ssl/certs:/etc/ssl/certs:ro
- ./porch-data:/data:ro
environment:
SSL_CERT_DIR: /etc/ssl/certs
read_only: true
security_opt:
- no-new-privileges:true
cap_drop:
- ALL
To upgrade, run step 1 again in the same directory,
then docker compose up -d. To remove it,
docker compose down --rmi all, then delete the directory and the
DNS record. Everything else is in the
self-hosting guide.
For your own infrastructure
Self-hosted, with proof of control for every domain, and nothing sent to us.