Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
[target.x86_64-unknown-linux-gnu]
linker = "/usr/bin/clang"
rustflags = ["-C", "link-arg=--ld-path=/usr/bin/mold"]

# Configuration for macOS to use MIT Kerberos from Homebrew
[target.aarch64-apple-darwin]
linker = "clang"
rustflags = [
"-L", "/opt/homebrew/opt/krb5/lib",
"-C", "link-args=-Wl,-rpath,/opt/homebrew/opt/krb5/lib"
]

[target.x86_64-apple-darwin]
linker = "clang"
rustflags = [
"-L", "/opt/homebrew/opt/krb5/lib",
"-C", "link-args=-Wl,-rpath,/opt/homebrew/opt/krb5/lib"
]
34 changes: 25 additions & 9 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
override: true
- name: Install CMake 3.31
run: |
sudo apt update && sudo apt install mold -y
sudo apt update && sudo apt install -y mold clang pkg-config protobuf-compiler
sudo apt remove cmake
sudo pip3 install cmake==3.31.6
cmake --version
Expand All @@ -32,14 +32,18 @@ jobs:
override: true
- name: Install CMake 3.31
run: |
sudo apt update && sudo apt install mold -y
sudo apt update && sudo apt install -y mold clang pkg-config protobuf-compiler
sudo apt remove cmake
sudo pip3 install cmake==3.31.6
cmake --version
- name: Install Kerberos dependencies
run: |
sudo apt update
sudo DEBIAN_FRONTEND=noninteractive apt install -y libkrb5-dev krb5-user krb5-config libgssapi-krb5-2
- name: Build
run: cargo build
run: cargo build --features gssapi
- name: Check release
run: cargo check --release
run: cargo check --release --features gssapi
tests:
runs-on: blacksmith-4vcpu-ubuntu-2404
steps:
Expand All @@ -51,6 +55,18 @@ jobs:
- uses: useblacksmith/rust-cache@v3
with:
prefix-key: "v1" # Change this when updating tooling
- name: Install Kerberos dependencies
run: |
sudo apt update
sudo DEBIAN_FRONTEND=noninteractive apt install -y libkrb5-dev krb5-user krb5-config libgssapi-krb5-2 krb5-kdc krb5-admin-server
- name: Setup Kerberos and create test keytabs
run: |
# The unified script handles everything: KDC setup, service start, keytab creation
chmod +x integration/gssapi/setup_test_keytabs.sh
CI=true VERBOSE=1 sudo -E bash integration/gssapi/setup_test_keytabs.sh

# Make keytabs readable by the test user
sudo chown -R $USER:$USER integration/gssapi/keytabs/
- name: Setup PostgreSQL
run: |
sudo service postgresql start
Expand All @@ -59,7 +75,7 @@ jobs:
sudo -u postgres psql -c 'ALTER SYSTEM SET max_prepared_transactions TO 1000;'
sudo service postgresql restart
bash integration/setup.sh
sudo apt update && sudo apt install -y python3-virtualenv mold
sudo apt install -y python3-virtualenv mold clang pkg-config protobuf-compiler
sudo gem install bundler
sudo apt remove -y cmake
sudo pip3 install cmake==3.31.6
Expand All @@ -68,10 +84,10 @@ jobs:
bash integration/toxi/setup.sh
- name: Install test dependencies
run: cargo install cargo-nextest --version "0.9.78" --locked
- name: Run tests
run: cargo nextest run -E 'package(pgdog)' --no-fail-fast --test-threads=1
- name: Run tests with GSSAPI
run: cargo nextest run -E 'package(pgdog)' --no-fail-fast --test-threads=1 --features gssapi
- name: Run documentation tests
run: cargo test --doc
run: cargo test --doc --features gssapi
integration:
runs-on: blacksmith-4vcpu-ubuntu-2404
steps:
Expand All @@ -92,7 +108,7 @@ jobs:
sudo -u postgres psql -c 'ALTER SYSTEM SET max_prepared_transactions TO 1000;'
sudo service postgresql restart
bash integration/setup.sh
sudo apt update && sudo apt install -y python3-virtualenv mold
sudo apt update && sudo apt install -y python3-virtualenv mold clang pkg-config protobuf-compiler
sudo gem install bundler
sudo apt remove -y cmake
sudo pip3 install cmake==3.31.6
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,13 @@ perf.data.old
/pgdog.toml
/users.toml
CLAUDE.local.md
AGENTS.md
.claude/plans/
.claude/completed_plans/

# Ignore generated bindings
pgdog-plugin/src/bindings.rs
local/
integration/log.txt
integration/gssapi/keytabs/*.keytab
pgdog/docs/*.md
43 changes: 43 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,49 @@ Contributions are welcome. If you see a bug, feel free to submit a PR with a fix
5. Launch pgdog configured for integration: `bash integration/dev-server.sh`.
6. Run the tests `cargo nextest run --test-threads=1`. If a test fails, try running it directly.

## Building with GSSAPI/Kerberos Support

PgDog supports GSSAPI/Kerberos authentication as an optional feature. To build and test with GSSAPI support:

### macOS

1. Install MIT Kerberos via Homebrew:
```bash
brew install krb5
```

2. Set the required environment variables:
```bash
export PKG_CONFIG_PATH="/opt/homebrew/opt/krb5/lib/pkgconfig"
export LIBGSSAPI_SYS_USE_PKG_CONFIG=1
```

3. Build with the GSSAPI feature:
```bash
cargo build --features gssapi
```

4. Run tests with GSSAPI enabled:
```bash
cargo nextest run --test-threads=1 --features gssapi
```

### Linux

On most Linux distributions, the system GSSAPI libraries should work without additional configuration:
```bash
cargo build --features gssapi
cargo nextest run --test-threads=1 --features gssapi
```

### Testing Notes

- The test suite is designed to work with or without the GSSAPI feature enabled
- Standard test users (`pgdog`, `pgdog-backend`) use password authentication
- GSSAPI test users have a `-gss` suffix (e.g., `alice-gss`, `bob-gss`, `pgdog-backend-gss`)
- GSSAPI-specific integration tests will only run when the feature is enabled
- If you need to test actual GSSAPI authentication, you'll need to configure PostgreSQL's `pg_hba.conf` and set up a Kerberos environment (KDC, keytabs, etc.)

## Coding

1. Please format your code with `cargo fmt`.
Expand Down
43 changes: 43 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

125 changes: 125 additions & 0 deletions integration/complex/gssapi/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
# GSSAPI (Kerberos) Authentication Configuration Example

This directory contains example configurations for using GSSAPI/Kerberos authentication with PGDog.

## Overview

PGDog supports GSSAPI authentication in a dual-context model:
- **Frontend**: Accepts GSSAPI authentication from clients
- **Backend**: Uses service credentials to authenticate to PostgreSQL servers

This approach preserves connection pooling while providing strong authentication.

## Files

- `pgdog.toml` - Main configuration with GSSAPI settings
- `users.toml` - User mappings for GSSAPI principals

## Key Features Demonstrated

### 1. Global GSSAPI Configuration
- Server keytab for accepting client connections
- Default backend credentials for PostgreSQL servers
- Ticket refresh intervals
- Realm stripping for username mapping

### 2. Per-Server Backend Authentication
- Different keytabs for different PostgreSQL servers
- Useful for multi-tenant or sharded deployments
- Fine-grained access control per database

### 3. Mixed Authentication
- GSSAPI for some databases, password for others
- Fallback options for migration scenarios

## Setup Requirements

### Prerequisites
1. Kerberos KDC (Key Distribution Center) configured
2. Service principals created for PGDog and PostgreSQL servers
3. Keytab files generated and placed in appropriate locations
4. PostgreSQL servers configured to accept GSSAPI authentication

### Keytab Files

#### Frontend (Client-facing)
```bash
# Create service principal for PGDog
kadmin.local -q "addprinc -randkey postgres/pgdog.example.com"
kadmin.local -q "ktadd -k /etc/pgdog/pgdog.keytab postgres/pgdog.example.com"
```

#### Backend (PostgreSQL-facing)
```bash
# Create service principal for backend connections
kadmin.local -q "addprinc -randkey pgdog-service"
kadmin.local -q "ktadd -k /etc/pgdog/backend.keytab pgdog-service"

# For per-server authentication
kadmin.local -q "addprinc -randkey pgdog-shard1"
kadmin.local -q "ktadd -k /etc/pgdog/shard1.keytab pgdog-shard1"
```

### PostgreSQL Configuration

Configure PostgreSQL servers to accept GSSAPI authentication from PGDog's service principal:

```postgresql
# pg_hba.conf
host all [email protected] 0.0.0.0/0 gss
host all [email protected] 0.0.0.0/0 gss
```

## Authentication Flow

1. **Client → PGDog**: Client authenticates using their Kerberos principal (e.g., [email protected])
2. **Username Mapping**: PGDog maps the principal to a user in users.toml (strips realm if configured)
3. **PGDog → PostgreSQL**: PGDog uses its service credentials to connect to the backend
4. **Connection Pooling**: PGDog maintains pooled connections using its service identity

## Security Considerations

- Keytab files should be readable only by the PGDog process user
- Use separate service principals for different environments (dev/staging/prod)
- Regularly rotate keytabs and update Kerberos passwords
- Consider using GSSAPI encryption if SQL inspection is not required
- Monitor ticket refresh logs for authentication issues

## Testing

```bash
# Test client authentication
kinit [email protected]
psql -h pgdog.example.com -p 6432 -d production -U alice

# Verify PGDog's service ticket
klist -k /etc/pgdog/pgdog.keytab

# Check backend connectivity
kinit -kt /etc/pgdog/backend.keytab [email protected]
psql -h pg1.example.com -p 5432 -d postgres -U pgdog-service
```

## Troubleshooting

### Common Issues

1. **Clock Skew**: Ensure all servers have synchronized time (use NTP)
2. **DNS Resolution**: Kerberos requires proper forward and reverse DNS
3. **Keytab Permissions**: Check file ownership and permissions (600 or 400)
4. **Principal Names**: Verify exact principal names including realm
5. **Ticket Expiration**: Monitor ticket refresh intervals

### Debug Logging

Enable Kerberos debug output:
```bash
export KRB5_TRACE=/tmp/krb5_trace.log
```

## Migration from Password Authentication

1. Enable `fallback_enabled = true` in GSSAPI configuration
2. Deploy PGDog with both authentication methods available
3. Migrate users gradually to GSSAPI
4. Once all users migrated, disable fallback
Loading
Loading