Files
forward_auth_server/README.md
2025-11-04 21:22:10 +02:00

7.4 KiB

Forward Auth TOTP

A lightweight forward authentication service for Caddy (or any reverse proxy) that uses TOTP (Time-based One-Time Password) tokens for user authentication.

Features

  • 🔐 TOTP-based authentication (compatible with Google Authenticator, Authy, 1Password, etc.)
  • 🎫 JWT session management with configurable duration
  • 👥 Support for multiple users (1-20+ TOTP seeds)
  • 🪶 Lightweight SQLite database
  • 🚀 Single binary deployment
  • 🔄 Works with Caddy's forward_auth directive
  • 📱 Mobile-friendly login page

Prerequisites

  • Go 1.21 or higher
  • SQLite3
  • Caddy v2 (or any reverse proxy that supports forward authentication)

Installation

Clone the repository

git clone https://github.com/yourusername/forward-auth-totp.git
cd forward-auth-totp

Install dependencies

go mod download

Build the application

go build -o forward-auth main.go

Configuration

Environment Variables

Variable Description Default Required
JWT_SECRET Secret key for signing JWT tokens (insecure default) Recommended

Important: Always set a secure JWT_SECRET in production:

export JWT_SECRET="your-very-secure-random-secret-here-min-32-chars"

Generate a secure secret:

openssl rand -base64 32

Application Constants

You can modify these constants in main.go:

  • sessionDuration: JWT session duration (default: 24 hours)
  • dbFile: SQLite database file path (default: auth.db)
  • jwtCookie: Cookie name for JWT token (default: auth_token)

Usage

First Run

On first run, the application will automatically generate a TOTP seed:

./forward-auth

Output:

No seeds found, generating one...
New TOTP seed generated:
Secret: JBSWY3DPEHPK3PXP
OTPAuth URL: otpauth://totp/ForwardAuthApp:user?secret=JBSWY3DPEHPK3PXP&issuer=ForwardAuthApp
Use this to set up your authenticator app.
Starting auth server on :3000

Scan the QR code (use the OTPAuth URL with a QR generator) or manually enter the secret into your authenticator app.

Generate Additional TOTP Seeds

For multiple users, generate additional seeds:

./forward-auth -generate

Each seed can be used by a different user with their own authenticator app.

Running as a Service

systemd (Linux)

Create /etc/systemd/system/forward-auth.service:

[Unit]
Description=Forward Auth TOTP Service
After=network.target

[Service]
Type=simple
User=www-data
WorkingDirectory=/opt/forward-auth
Environment="JWT_SECRET=your-secure-secret-here"
ExecStart=/opt/forward-auth/forward-auth
Restart=on-failure
RestartSec=5s

[Install]
WantedBy=multi-user.target

Enable and start:

sudo systemctl enable forward-auth
sudo systemctl start forward-auth

Caddy Configuration

Basic Configuration

# Your protected application
app.example.com {
    forward_auth localhost:3000 {
        uri /verify
        copy_headers X-Original-URI
    }
    
    reverse_proxy localhost:8080
}

# Auth service (optional, if you want it accessible externally)
auth.example.com {
    reverse_proxy localhost:3000
}

Advanced Configuration with Error Handling

app.example.com {
    # Allow access to login page without auth
    @login {
        path /login*
    }
    handle @login {
        reverse_proxy localhost:3000
    }
    
    # Protect everything else
    forward_auth localhost:3000 {
        uri /verify
        copy_headers X-Original-URI
    }
    
    reverse_proxy localhost:8080
}

Multiple Protected Services

# Auth service
auth.example.com {
    reverse_proxy localhost:3000
}

# Protected app 1
app1.example.com {
    forward_auth auth.example.com {
        uri /verify
        copy_headers X-Original-URI
    }
    reverse_proxy localhost:8080
}

# Protected app 2
app2.example.com {
    forward_auth auth.example.com {
        uri /verify
        copy_headers X-Original-URI
    }
    reverse_proxy localhost:8081
}

API Endpoints

Endpoint Method Description
/verify GET Verify JWT token (for forward auth)
/login GET Display login form
/login POST Process OTP submission
/health GET Health check endpoint

Security Considerations

Production Checklist

  • Set a strong JWT_SECRET environment variable
  • Enable HTTPS and uncomment Secure: true in cookie settings
  • Restrict database file permissions: chmod 600 auth.db
  • Run the service as a non-root user
  • Keep the TOTP secrets secure and backed up
  • Consider rate limiting on the /login endpoint
  • Monitor failed authentication attempts

HTTPS Configuration

For production, uncomment the Secure flag in main.go:

http.SetCookie(w, &http.Cookie{
    Name:     jwtCookie,
    Value:    tokenStr,
    Expires:  time.Now().Add(sessionDuration),
    HttpOnly: true,
    SameSite: http.SameSiteLaxMode,
    Secure:   true, // Uncomment this line
    Path:     "/",
})

Database Management

Backup

cp auth.db auth.db.backup

View All Seeds

sqlite3 auth.db "SELECT * FROM seeds;"

Remove a Seed

sqlite3 auth.db "DELETE FROM seeds WHERE id = 1;"

Reset Database

rm auth.db
./forward-auth  # Will generate a new seed automatically

Troubleshooting

"Invalid OTP" Error

  • Ensure your device time is synchronized (TOTP is time-based)
  • Check that you're using the correct seed in your authenticator app
  • Verify the OTP code hasn't expired (codes are valid for 30 seconds)

Authentication Not Working

  • Check Caddy logs: journalctl -u caddy -f
  • Check forward-auth logs: journalctl -u forward-auth -f
  • Verify the forward auth service is running: curl http://localhost:3000/health
  • Ensure X-Original-URI header is being passed correctly
  • Verify you're using HTTPS in production with Secure: true
  • Check that the cookie path matches your application structure
  • Ensure SameSite attribute is compatible with your setup

Performance

This application is designed for light usage (1-20 users, <100 requests/day):

  • Memory footprint: ~10-15 MB
  • CPU usage: Minimal (<1% on modern systems)
  • Database size: <1 KB for up to 20 seeds
  • Startup time: <100ms

Development

Run in Development Mode

go run main.go

Run Tests

go test -v ./...

Build for Different Platforms

# Linux
GOOS=linux GOARCH=amd64 go build -o forward-auth-linux main.go

# macOS
GOOS=darwin GOARCH=amd64 go build -o forward-auth-macos main.go

# Windows
GOOS=windows GOARCH=amd64 go build -o forward-auth.exe main.go

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

MIT License - see LICENSE file for details

Acknowledgments

Support

For issues and questions, please open an issue on GitHub.


Note: This is a simple authentication service suitable for personal or small team use. For larger deployments, consider more robust authentication solutions with features like account lockout, audit logging, and multi-factor authentication options.