2FAuth is a self-hostable web service for managing two-factor authentication tokens. It has a nice, clean interface, is responsive (so it can be simply added to the homescreen on iOS), and has various useful features:
- Adding new tokens by scanning QR codes;
- Searching for tokens;
- Lots of features related to security and usability.
Running the service itself is as straight forward as bringing up the supplied docker-compose.yml
file. However - as noted in this blog post - if, like me, you plan to run it inside of a Tailscale tailnet, you’ll need to ensure HTTPS is enabled in order for the camera to work. To do this, attach a reverse-proxy armed with the required certificates.
This note describes by setup for securely self-hosting thie service.
Step 1: Generate TLS certificates for the Tailscale machine
Generate a certificate for the machine using tailscale cert <machine name>
, and then put the resultant certificate and key file into a directory (e.g. certs/
).
You may want to set up your tailnet name first.
Step 2: Prepare Nginx
Create an nginx.conf
file like the one below:
events {
}
http {
server {
listen 443 ssl;
ssl_certificate /certs/certificate.crt;
ssl_certificate_key /certs/privatekey.key;
location / {
proxy_pass http://2fauth:8000/;
}
}
}
Step 3: Create a Docker compose file
Create a docker-compose.yml
file, including an nginx
container:
version: "3"
services:
2fauth:
image: 2fauth/2fauth
volumes:
- ./2fauth:/2fauth
environment:
- APP_NAME=2FAuth
- APP_ENV=local
- SITE_OWNER=change@me.com
- APP_KEY=changeme32chars
- APP_URL=http://changeme
- LOG_CHANNEL=daily
- LOG_LEVEL=notice
- DB_DATABASE="/srv/database/database.sqlite"
- CACHE_DRIVER=file
- SESSION_DRIVER=file
- AUTHENTICATION_GUARD=web-guard
- WEBAUTHN_NAME=2FAuth
- BROADCAST_DRIVER=log
- QUEUE_DRIVER=sync
- SESSION_LIFETIME=120
- REDIS_HOST=127.0.0.1
- REDIS_PASSWORD=null
- REDIS_PORT=6379
- PUSHER_APP_ID=
- PUSHER_APP_KEY=
- PUSHER_APP_SECRET=
- PUSHER_APP_CLUSTER=mt1
- MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
- MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
- MIX_ENV=local
nginx:
image: nginx:latest
ports:
- 8087:443
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
- ./certs:/certs
Bring up the services (with docker-compose up -d
) and 2FAuth is now available on HTTPS port 8087 for the machine name in the tailnet.