Initial commit of Postgre-TLS project
This commit is contained in:
commit
5203f014a0
|
@ -0,0 +1,48 @@
|
||||||
|
# PostgreSQL data directories
|
||||||
|
data/
|
||||||
|
logs/
|
||||||
|
|
||||||
|
# Secrets directory
|
||||||
|
secrets/
|
||||||
|
|
||||||
|
# SSL certificates
|
||||||
|
ssl/
|
||||||
|
*.crt
|
||||||
|
*.key
|
||||||
|
*.pem
|
||||||
|
|
||||||
|
# Environment files with secrets
|
||||||
|
.env
|
||||||
|
.env.local
|
||||||
|
.env.production
|
||||||
|
|
||||||
|
# Temporary files
|
||||||
|
*.tmp
|
||||||
|
*.log
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
*~
|
||||||
|
|
||||||
|
# OS generated files
|
||||||
|
.DS_Store
|
||||||
|
.DS_Store?
|
||||||
|
._*
|
||||||
|
.Spotlight-V100
|
||||||
|
.Trashes
|
||||||
|
ehthumbs.db
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# Docker
|
||||||
|
.dockerignore
|
||||||
|
|
||||||
|
# IDE files
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
*.sublime-project
|
||||||
|
*.sublime-workspace
|
||||||
|
|
||||||
|
# Backup files
|
||||||
|
*.bak
|
||||||
|
*.backup
|
||||||
|
*.sql.gz
|
||||||
|
*.sql.bz2
|
|
@ -0,0 +1,37 @@
|
||||||
|
FROM postgres:15-alpine
|
||||||
|
|
||||||
|
# Install additional packages for encryption and utilities
|
||||||
|
RUN apk add --no-cache \
|
||||||
|
openssl \
|
||||||
|
curl \
|
||||||
|
bash \
|
||||||
|
&& rm -rf /var/cache/apk/*
|
||||||
|
|
||||||
|
# Set environment variables for non-interactive operation
|
||||||
|
ENV PGUSER=postgres \
|
||||||
|
POSTGRES_HOST_AUTH_METHOD=scram-sha-256 \
|
||||||
|
PAGER=cat \
|
||||||
|
ENABLE_FALLBACK_SSL=true
|
||||||
|
|
||||||
|
# Create necessary directories
|
||||||
|
RUN mkdir -p /var/lib/postgresql/ssl \
|
||||||
|
&& mkdir -p /var/log/postgresql \
|
||||||
|
&& mkdir -p /docker-entrypoint-initdb.d
|
||||||
|
|
||||||
|
# Copy configuration files
|
||||||
|
COPY postgresql.conf /etc/postgresql/postgresql.conf
|
||||||
|
COPY entrypoint.sh /usr/local/bin/entrypoint.sh
|
||||||
|
|
||||||
|
# Make scripts executable
|
||||||
|
RUN chmod +x /usr/local/bin/entrypoint.sh
|
||||||
|
|
||||||
|
# Set proper ownership
|
||||||
|
RUN chown -R postgres:postgres /var/lib/postgresql/ssl \
|
||||||
|
&& chown -R postgres:postgres /var/log/postgresql \
|
||||||
|
&& chown postgres:postgres /etc/postgresql/postgresql.conf
|
||||||
|
|
||||||
|
# Expose PostgreSQL port
|
||||||
|
EXPOSE 5432
|
||||||
|
|
||||||
|
# Set the custom start script as entrypoint
|
||||||
|
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
|
|
@ -0,0 +1,57 @@
|
||||||
|
# Postgre-TLS - Secure PostgreSQL Docker Setup with SSL/TLS
|
||||||
|
|
||||||
|
A secure PostgreSQL Docker container with enforced SSL/TLS encryption, certificate verification, and advanced security features.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- **SSL/TLS Encryption**: TLSv1.3 with 256-bit AES-GCM encryption
|
||||||
|
- **Certificate Verification**: Full SSL certificate verification enabled
|
||||||
|
- **SCRAM-SHA-256 Authentication**: Secure password authentication
|
||||||
|
- **Row-Level Security**: Built-in support for fine-grained access control
|
||||||
|
- **Audit Logging**: Comprehensive audit trail for database operations
|
||||||
|
- **Data Integrity**: Checksums enabled for data corruption detection
|
||||||
|
- **Monitoring**: Built-in performance monitoring with pg_stat_statements
|
||||||
|
- **Encryption Functions**: pgcrypto extension for additional encryption capabilities
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
1. **Start the PostgreSQL container**:
|
||||||
|
```bash
|
||||||
|
./start.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Connect to the database**:
|
||||||
|
```bash
|
||||||
|
./connect.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Stop the container**:
|
||||||
|
```bash
|
||||||
|
docker-compose down
|
||||||
|
```
|
||||||
|
|
||||||
|
## SSL Connection Details
|
||||||
|
|
||||||
|
The setup provides enterprise-grade security with:
|
||||||
|
- **Encryption**: TLSv1.3 with TLS_AES_256_GCM_SHA384 cipher
|
||||||
|
- **Key Size**: 256-bit encryption
|
||||||
|
- **Certificate**: Self-signed with full verification
|
||||||
|
- **Authentication**: SCRAM-SHA-256 password hashing
|
||||||
|
|
||||||
|
## Manual Connection
|
||||||
|
|
||||||
|
You can also connect manually using psql:
|
||||||
|
```bash
|
||||||
|
psql "host=localhost port=5432 dbname=ploughgres user=ploughgres_user sslmode=verify-full sslrootcert=secrets/ca_crt"
|
||||||
|
```
|
||||||
|
|
||||||
|
For non-interactive connection, set the PGPASSWORD environment variable:
|
||||||
|
```bash
|
||||||
|
export PGPASSWORD=$(cat secrets/postgres_password || echo "change_me_in_production")
|
||||||
|
psql "host=localhost port=5432 dbname=ploughgres user=ploughgres_user sslmode=verify-full sslrootcert=secrets/ca_crt"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Project Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
```
|
|
@ -0,0 +1,80 @@
|
||||||
|
# PloughGres Usage Guide
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
1. **Start the PostgreSQL container:**
|
||||||
|
```bash
|
||||||
|
./start.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Connect to the database:**
|
||||||
|
```bash
|
||||||
|
./connect.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Stop the container:**
|
||||||
|
```bash
|
||||||
|
docker-compose down
|
||||||
|
```
|
||||||
|
|
||||||
|
## Common Operations
|
||||||
|
|
||||||
|
### Database Management
|
||||||
|
- **View container status:** `docker ps`
|
||||||
|
- **View container logs:** `docker logs ploughgres-db`
|
||||||
|
- **Access PostgreSQL shell:** `./connect.sh`
|
||||||
|
- **Restart container:** `docker-compose restart`
|
||||||
|
|
||||||
|
### SSL Connection Testing
|
||||||
|
The setup uses TLSv1.3 with 256-bit encryption. Connection details:
|
||||||
|
- **Host:** localhost
|
||||||
|
- **Port:** 5432
|
||||||
|
- **Database:** ploughgres
|
||||||
|
- **User:** ploughgres_user
|
||||||
|
- **SSL Mode:** verify-full (certificate verification enabled)
|
||||||
|
|
||||||
|
### Data Persistence
|
||||||
|
- Database data is stored in `./data/` directory
|
||||||
|
- SSL certificates are in `./secrets/` directory
|
||||||
|
- All data remains in the project directory (userspace)
|
||||||
|
|
||||||
|
### Security Features
|
||||||
|
- ✅ SSL/TLS encryption (TLSv1.3)
|
||||||
|
- ✅ Certificate verification
|
||||||
|
- ✅ SCRAM-SHA-256 authentication
|
||||||
|
- ✅ Row-level security enabled
|
||||||
|
- ✅ Audit logging
|
||||||
|
- ✅ Encryption functions (pgcrypto)
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Container Issues
|
||||||
|
- **Container won't start:** Check `docker logs ploughgres-db`
|
||||||
|
- **Port conflicts:** Ensure port 5432 is available
|
||||||
|
- **Permission issues:** Check file permissions in `secrets/` directory
|
||||||
|
|
||||||
|
### SSL Connection Issues
|
||||||
|
- **Certificate errors:** Verify certificates exist in `secrets/`
|
||||||
|
- **Connection refused:** Ensure container is running and healthy
|
||||||
|
- **Authentication failed:** Check password in `secrets/postgres_password.txt`
|
||||||
|
|
||||||
|
## Development
|
||||||
|
|
||||||
|
### Making Changes
|
||||||
|
1. Stop the container: `docker-compose down`
|
||||||
|
2. Make your changes
|
||||||
|
3. Rebuild and restart: `./start.sh`
|
||||||
|
|
||||||
|
### Viewing SSL Status
|
||||||
|
Connect to the database and run:
|
||||||
|
```sql
|
||||||
|
SELECT ssl, version, cipher, bits FROM pg_stat_ssl WHERE pid = pg_backend_pid();
|
||||||
|
```
|
||||||
|
|
||||||
|
## Files Overview
|
||||||
|
- `docker-compose.yml` - Container configuration
|
||||||
|
- `start.sh` - Initialization and startup script
|
||||||
|
- `connect.sh` - SSL connection test script
|
||||||
|
- `Dockerfile` - Container image definition
|
||||||
|
- `secrets/` - SSL certificates and passwords
|
||||||
|
- `data/` - PostgreSQL data directory
|
|
@ -0,0 +1,62 @@
|
||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Colors for output
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
RED='\033[0;31m'
|
||||||
|
NC='\033[0m' # No Color
|
||||||
|
YELLOW='\033[0;33m' # Yellow
|
||||||
|
|
||||||
|
echo -e "${GREEN}[Postgre-TLS] Testing SSL connection to PostgreSQL...${NC}"
|
||||||
|
|
||||||
|
# Load password
|
||||||
|
PASSWORD=$([ -f secrets/postgres_password ] && cat secrets/postgres_password || echo "change_me_in_production")
|
||||||
|
export PGPASSWORD="$PASSWORD"
|
||||||
|
|
||||||
|
# Test basic connection
|
||||||
|
OUTPUT=$(psql "host=localhost port=5432 dbname=ploughgres user=ploughgres_user sslmode=verify-full sslrootcert=secrets/ca.crt" \
|
||||||
|
-c "SELECT version(), current_user, current_database();" -t) || {
|
||||||
|
echo -e "${RED}[Postgre-TLS] Connection failed!${NC}"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
echo "$OUTPUT"
|
||||||
|
|
||||||
|
# Check SSL details
|
||||||
|
echo -e "\n${GREEN}[Postgre-TLS] SSL Connection Details:${NC}"
|
||||||
|
SSL_DETAILS=$(psql "host=localhost port=5432 dbname=ploughgres user=ploughgres_user sslmode=verify-full sslrootcert=secrets/ca.crt" \
|
||||||
|
-c "SELECT ssl, version as ssl_version, cipher as ssl_cipher, bits as ssl_bits FROM pg_stat_ssl WHERE pid = pg_backend_pid();" -t) || {
|
||||||
|
echo -e "${RED}[Postgre-TLS] Failed to get SSL details!${NC}"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
echo "$SSL_DETAILS"
|
||||||
|
|
||||||
|
# Test non-SSL connection (should fail)
|
||||||
|
echo -e "\n${YELLOW}[Postgre-TLS] Testing non-SSL connection (expected to fail):${NC}"
|
||||||
|
psql "host=localhost port=5432 dbname=ploughgres user=ploughgres_user sslmode=disable" -c "SELECT 1;" 2>&1 | grep "SSL" || echo -e "${GREEN}Non-SSL connection correctly refused.${NC}"
|
||||||
|
|
||||||
|
# Advanced database operations over SSL
|
||||||
|
echo -e "\n${GREEN}[Postgre-TLS] Performing advanced tests over SSL:${NC}"
|
||||||
|
|
||||||
|
# Create test table
|
||||||
|
psql "host=localhost port=5432 dbname=ploughgres user=ploughgres_user sslmode=verify-full sslrootcert=secrets/ca.crt" -c "CREATE TABLE IF NOT EXISTS test_table (id SERIAL PRIMARY KEY, data TEXT);" || { echo -e "${RED}Failed to create test table!${NC}"; exit 1; }
|
||||||
|
echo "Test table created."
|
||||||
|
|
||||||
|
# Insert data
|
||||||
|
psql "host=localhost port=5432 dbname=ploughgres user=ploughgres_user sslmode=verify-full sslrootcert=secrets/ca.crt" -c "INSERT INTO test_table (data) VALUES ('Hello, SSL World!');" || { echo -e "${RED}Failed to insert data!${NC}"; exit 1; }
|
||||||
|
echo "Data inserted."
|
||||||
|
|
||||||
|
# Query data
|
||||||
|
QUERY_RESULT=$(psql "host=localhost port=5432 dbname=ploughgres user=ploughgres_user sslmode=verify-full sslrootcert=secrets/ca.crt" -c "SELECT data FROM test_table WHERE id = (SELECT MAX(id) FROM test_table);" -t) || { echo -e "${RED}Failed to query data!${NC}"; exit 1; }
|
||||||
|
echo "Queried data: $QUERY_RESULT"
|
||||||
|
|
||||||
|
# Drop test table
|
||||||
|
psql "host=localhost port=5432 dbname=ploughgres user=ploughgres_user sslmode=verify-full sslrootcert=secrets/ca.crt" -c "DROP TABLE test_table;" || { echo -e "${RED}Failed to drop test table!${NC}"; exit 1; }
|
||||||
|
echo "Test table dropped."
|
||||||
|
|
||||||
|
# Check if all tests passed
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
echo -e "\n${GREEN}[Postgre-TLS] All advanced SSL connection tests successful!${NC}"
|
||||||
|
else
|
||||||
|
echo -e "\n${RED}[Postgre-TLS] Advanced tests failed!${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
|
@ -0,0 +1,34 @@
|
||||||
|
services:
|
||||||
|
postgres:
|
||||||
|
build: .
|
||||||
|
container_name: postgretls-db
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
POSTGRES_DB: ploughgres
|
||||||
|
POSTGRES_USER: ploughgres_user
|
||||||
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-change_me_in_production}
|
||||||
|
# Enable SSL/TLS
|
||||||
|
POSTGRES_INITDB_ARGS: "--auth-local=password --auth-host=scram-sha-256"
|
||||||
|
# Enable fallback for local development
|
||||||
|
ENABLE_FALLBACK_SSL: "true"
|
||||||
|
ports:
|
||||||
|
- "5432:5432"
|
||||||
|
volumes:
|
||||||
|
- postgretls_data:/var/lib/postgresql/data
|
||||||
|
- postgretls_logs:/var/log/postgresql
|
||||||
|
- ./secrets:/run/secrets:ro
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "pg_isready -U ploughgres_user -d ploughgres"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 5
|
||||||
|
networks:
|
||||||
|
- postgretls-network
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
postgretls_data:
|
||||||
|
postgretls_logs:
|
||||||
|
|
||||||
|
networks:
|
||||||
|
postgretls-network:
|
||||||
|
driver: bridge
|
|
@ -0,0 +1,260 @@
|
||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Colors for output
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
|
echo -e "${GREEN}[Postgre-TLS] Starting PostgreSQL with encryption...${NC}"
|
||||||
|
|
||||||
|
# Function to setup SSL certificates from Docker Swarm secrets
|
||||||
|
setup_ssl_certificates() {
|
||||||
|
echo -e "${YELLOW}[Postgre-TLS] Setting up SSL certificates from Docker Swarm secrets...${NC}"
|
||||||
|
|
||||||
|
# Debug: list contents of /run/secrets
|
||||||
|
echo -e "${YELLOW}[Postgre-TLS] Listing contents of /run/secrets:${NC}"
|
||||||
|
ls -la /run/secrets/ || echo "No /run/secrets directory found"
|
||||||
|
|
||||||
|
# Check if running in Docker Swarm mode
|
||||||
|
if [ -f "/run/secrets/server_crt" ] || [ -f "/run/secrets/server.crt" ]; then
|
||||||
|
echo -e "${YELLOW}[Postgre-TLS] Using SSL certificates from Docker Swarm secrets...${NC}"
|
||||||
|
|
||||||
|
# Copy certificates from Docker secrets to expected locations
|
||||||
|
if [ -f "/run/secrets/ca_crt" ]; then
|
||||||
|
cp /run/secrets/ca_crt /var/lib/postgresql/ssl/ca.crt
|
||||||
|
elif [ -f "/run/secrets/ca.crt" ]; then
|
||||||
|
cp /run/secrets/ca.crt /var/lib/postgresql/ssl/ca.crt
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f "/run/secrets/server_crt" ]; then
|
||||||
|
cp /run/secrets/server_crt /var/lib/postgresql/ssl/server.crt
|
||||||
|
elif [ -f "/run/secrets/server.crt" ]; then
|
||||||
|
cp /run/secrets/server.crt /var/lib/postgresql/ssl/server.crt
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f "/run/secrets/server_key" ]; then
|
||||||
|
cp /run/secrets/server_key /var/lib/postgresql/ssl/server.key
|
||||||
|
elif [ -f "/run/secrets/server.key" ]; then
|
||||||
|
cp /run/secrets/server.key /var/lib/postgresql/ssl/server.key
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Set proper permissions
|
||||||
|
chmod 600 /var/lib/postgresql/ssl/server.key
|
||||||
|
chmod 644 /var/lib/postgresql/ssl/server.crt
|
||||||
|
chmod 644 /var/lib/postgresql/ssl/ca.crt
|
||||||
|
|
||||||
|
# Set ownership to postgres user
|
||||||
|
chown postgres:postgres /var/lib/postgresql/ssl/*
|
||||||
|
|
||||||
|
echo -e "${GREEN}[Postgre-TLS] SSL certificates from Docker Swarm configured successfully${NC}"
|
||||||
|
elif [ "$ENABLE_FALLBACK_SSL" = "true" ]; then
|
||||||
|
echo -e "${YELLOW}[Postgre-TLS] Generating fallback SSL certificates for local development...${NC}"
|
||||||
|
|
||||||
|
# Generate CA private key
|
||||||
|
openssl genrsa -out /var/lib/postgresql/ssl/ca.key 2048
|
||||||
|
|
||||||
|
# Generate CA certificate
|
||||||
|
openssl req -new -x509 -key /var/lib/postgresql/ssl/ca.key \
|
||||||
|
-out /var/lib/postgresql/ssl/ca.crt -days 365 \
|
||||||
|
-subj "/C=US/ST=State/L=City/O=Postgre-TLS/CN=Postgre-TLS-CA"
|
||||||
|
|
||||||
|
# Generate server private key
|
||||||
|
openssl genrsa -out /var/lib/postgresql/ssl/server.key 2048
|
||||||
|
|
||||||
|
# Generate server certificate signing request
|
||||||
|
openssl req -new -key /var/lib/postgresql/ssl/server.key \
|
||||||
|
-out /var/lib/postgresql/ssl/server.csr \
|
||||||
|
-subj "/C=US/ST=State/L=City/O=Postgre-TLS/CN=localhost"
|
||||||
|
|
||||||
|
# Generate server certificate signed by CA
|
||||||
|
openssl x509 -req -in /var/lib/postgresql/ssl/server.csr \
|
||||||
|
-CA /var/lib/postgresql/ssl/ca.crt \
|
||||||
|
-CAkey /var/lib/postgresql/ssl/ca.key \
|
||||||
|
-CAcreateserial -out /var/lib/postgresql/ssl/server.crt \
|
||||||
|
-days 365
|
||||||
|
|
||||||
|
# Clean up CSR
|
||||||
|
rm /var/lib/postgresql/ssl/server.csr
|
||||||
|
|
||||||
|
# Set proper permissions
|
||||||
|
chmod 600 /var/lib/postgresql/ssl/server.key
|
||||||
|
chmod 644 /var/lib/postgresql/ssl/server.crt
|
||||||
|
chmod 644 /var/lib/postgresql/ssl/ca.crt
|
||||||
|
|
||||||
|
# Set ownership to postgres user
|
||||||
|
chown postgres:postgres /var/lib/postgresql/ssl/*
|
||||||
|
|
||||||
|
echo -e "${GREEN}[Postgre-TLS] Fallback SSL certificates generated successfully${NC}"
|
||||||
|
else
|
||||||
|
echo -e "${RED}[Postgre-TLS] Error: SSL certificates must be provided via Docker Swarm secrets. Fallback generation is not supported.${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to check if database needs initialization
|
||||||
|
needs_initialization() {
|
||||||
|
if [ ! -s "$PGDATA/PG_VERSION" ]; then
|
||||||
|
return 0 # true - needs initialization
|
||||||
|
else
|
||||||
|
return 1 # false - already initialized
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to load secrets from Docker Swarm or environment
|
||||||
|
load_secrets() {
|
||||||
|
echo -e "${YELLOW}[Postgre-TLS] Loading secrets...${NC}"
|
||||||
|
|
||||||
|
# Check if secrets are available
|
||||||
|
if [ -f "/run/secrets/postgres_password" ]; then
|
||||||
|
echo -e "${YELLOW}[Postgre-TLS] Loading secrets from /run/secrets...${NC}"
|
||||||
|
export POSTGRES_PASSWORD=$(cat /run/secrets/postgres_password)
|
||||||
|
export BACKUP_ENCRYPTION_KEY=$(cat /run/secrets/backup_encryption_key 2>/dev/null || echo "")
|
||||||
|
export JWT_SECRET=$(cat /run/secrets/jwt_secret 2>/dev/null || echo "")
|
||||||
|
export APP_SECRET_KEY=$(cat /run/secrets/app_secret_key 2>/dev/null || echo "")
|
||||||
|
echo -e "${GREEN}[Postgre-TLS] Secrets loaded from /run/secrets${NC}"
|
||||||
|
echo "Loaded POSTGRES_PASSWORD: $POSTGRES_PASSWORD"
|
||||||
|
else
|
||||||
|
echo -e "${YELLOW}[Postgre-TLS] Using environment variables for secrets${NC}"
|
||||||
|
export POSTGRES_PASSWORD="${POSTGRES_PASSWORD:-change_me_in_production}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Set default values for other variables
|
||||||
|
export POSTGRES_DB="${POSTGRES_DB:-ploughgres}"
|
||||||
|
export POSTGRES_USER="${POSTGRES_USER:-ploughgres_user}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to initialize database with encryption
|
||||||
|
initialize_database() {
|
||||||
|
echo -e "${YELLOW}[Postgre-TLS] Initializing database...${NC}"
|
||||||
|
|
||||||
|
# Create a temporary password file with proper ownership
|
||||||
|
su-exec postgres sh -c "echo '$POSTGRES_PASSWORD' > /tmp/pgpass"
|
||||||
|
su-exec postgres chmod 600 /tmp/pgpass
|
||||||
|
|
||||||
|
# Initialize the database with proper encoding and authentication
|
||||||
|
# Create the main database during initdb
|
||||||
|
export POSTGRES_DB="${POSTGRES_DB:-ploughgres}"
|
||||||
|
su-exec postgres initdb \
|
||||||
|
--pgdata="$PGDATA" \
|
||||||
|
--username="$POSTGRES_USER" \
|
||||||
|
--pwfile=/tmp/pgpass \
|
||||||
|
--auth-local=scram-sha-256 \
|
||||||
|
--auth-host=scram-sha-256 \
|
||||||
|
--encoding=UTF8 \
|
||||||
|
--locale=C.UTF-8 \
|
||||||
|
--data-checksums
|
||||||
|
|
||||||
|
# Clean up password file
|
||||||
|
rm -f /tmp/pgpass
|
||||||
|
|
||||||
|
echo -e "${GREEN}[Postgre-TLS] Database initialized successfully${NC}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to start PostgreSQL
|
||||||
|
start_postgresql() {
|
||||||
|
echo -e "${YELLOW}[Postgre-TLS] Starting PostgreSQL server...${NC}"
|
||||||
|
|
||||||
|
# Start PostgreSQL with custom configuration
|
||||||
|
exec su-exec postgres postgres \
|
||||||
|
-c config_file=/etc/postgresql/postgresql.conf \
|
||||||
|
-c ssl=on \
|
||||||
|
-c ssl_cert_file=/var/lib/postgresql/ssl/server.crt \
|
||||||
|
-c ssl_key_file=/var/lib/postgresql/ssl/server.key \
|
||||||
|
-c ssl_ca_file=/var/lib/postgresql/ssl/ca.crt \
|
||||||
|
-c shared_preload_libraries=pg_stat_statements \
|
||||||
|
-c log_statement=ddl \
|
||||||
|
-c log_destination=stderr \
|
||||||
|
-c logging_collector=on \
|
||||||
|
-c log_directory=/var/log/postgresql \
|
||||||
|
-c log_filename=postgresql.log
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main execution
|
||||||
|
main() {
|
||||||
|
# Set PGDATA if not set
|
||||||
|
export PGDATA="${PGDATA:-/var/lib/postgresql/data}"
|
||||||
|
|
||||||
|
# Ensure data directory exists and has proper permissions
|
||||||
|
# mkdir -p "$PGDATA"
|
||||||
|
# chown postgres:postgres "$PGDATA"
|
||||||
|
# chmod 700 "$PGDATA"
|
||||||
|
|
||||||
|
# Load secrets from Docker Swarm or environment
|
||||||
|
load_secrets
|
||||||
|
|
||||||
|
# Setup SSL certificates
|
||||||
|
setup_ssl_certificates
|
||||||
|
|
||||||
|
# Initialize database if needed
|
||||||
|
if needs_initialization; then
|
||||||
|
echo -e "${YELLOW}[Postgre-TLS] Database not found, initializing...${NC}"
|
||||||
|
initialize_database
|
||||||
|
|
||||||
|
# Create temporary pg_hba.conf for trust authentication during init
|
||||||
|
echo 'local all all trust' > /tmp/pg_hba.conf
|
||||||
|
echo 'host all all 127.0.0.1/32 trust' >> /tmp/pg_hba.conf
|
||||||
|
echo 'host all all ::1/128 trust' >> /tmp/pg_hba.conf
|
||||||
|
|
||||||
|
# Start PostgreSQL temporarily with temporary hba for initialization
|
||||||
|
echo -e "${YELLOW}[Postgre-TLS] Starting PostgreSQL temporarily for initialization...${NC}"
|
||||||
|
su-exec postgres postgres \
|
||||||
|
-c config_file=/etc/postgresql/postgresql.conf \
|
||||||
|
-c ssl=off \
|
||||||
|
-c listen_addresses=localhost \
|
||||||
|
-c port=5432 \
|
||||||
|
-c hba_file=/tmp/pg_hba.conf &
|
||||||
|
|
||||||
|
# Wait for PostgreSQL to start
|
||||||
|
until su-exec postgres pg_isready -h localhost -p 5432; do
|
||||||
|
echo -e "${YELLOW}[Postgre-TLS] Waiting for PostgreSQL to start...${NC}"
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
|
||||||
|
# Create the application database if it doesn't exist
|
||||||
|
echo -e "${YELLOW}[Postgre-TLS] Creating database: $POSTGRES_DB${NC}"
|
||||||
|
su-exec postgres createdb -h localhost -p 5432 -U "$POSTGRES_USER" "$POSTGRES_DB" 2>/dev/null || echo -e "${GREEN}[Postgre-TLS] Database $POSTGRES_DB already exists${NC}"
|
||||||
|
|
||||||
|
# Run initialization scripts
|
||||||
|
for f in /docker-entrypoint-initdb.d/*; do
|
||||||
|
case "$f" in
|
||||||
|
*.sh)
|
||||||
|
echo -e "${YELLOW}[Postgre-TLS] Running $f${NC}"
|
||||||
|
bash "$f"
|
||||||
|
;;
|
||||||
|
*.sql)
|
||||||
|
echo -e "${YELLOW}[Postgre-TLS] Running $f${NC}"
|
||||||
|
su-exec postgres psql -v ON_ERROR_STOP=1 -h localhost -p 5432 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" < "$f"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo -e "${YELLOW}[Postgre-TLS] Ignoring $f${NC}"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# Stop the temporary PostgreSQL instance
|
||||||
|
su-exec postgres pg_ctl -D "$PGDATA" -m fast -w stop
|
||||||
|
|
||||||
|
# Configure final pg_hba.conf for SSL connections
|
||||||
|
echo -e "${YELLOW}[Postgre-TLS] Configuring pg_hba.conf for SSL...${NC}"
|
||||||
|
cat > "$PGDATA/pg_hba.conf" <<EOF
|
||||||
|
# TYPE DATABASE USER ADDRESS METHOD
|
||||||
|
local all all scram-sha-256
|
||||||
|
hostssl all all 0.0.0.0/0 scram-sha-256
|
||||||
|
hostssl all all ::/0 scram-sha-256
|
||||||
|
EOF
|
||||||
|
chown postgres:postgres "$PGDATA/pg_hba.conf"
|
||||||
|
chmod 600 "$PGDATA/pg_hba.conf"
|
||||||
|
|
||||||
|
echo -e "${GREEN}[Postgre-TLS] Database initialization completed${NC}"
|
||||||
|
else
|
||||||
|
echo -e "${GREEN}[Postgre-TLS] Database already initialized${NC}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Start PostgreSQL with full configuration
|
||||||
|
start_postgresql
|
||||||
|
}
|
||||||
|
|
||||||
|
# Run main function
|
||||||
|
main "$@"
|
|
@ -0,0 +1,70 @@
|
||||||
|
# PostgreSQL Configuration for PloughGres
|
||||||
|
# Security and Encryption Focused Configuration
|
||||||
|
|
||||||
|
# Connection Settings
|
||||||
|
listen_addresses = '*'
|
||||||
|
port = 5432
|
||||||
|
max_connections = 100
|
||||||
|
|
||||||
|
# SSL/TLS Configuration
|
||||||
|
ssl = on
|
||||||
|
ssl_cert_file = '/var/lib/postgresql/ssl/server.crt'
|
||||||
|
ssl_key_file = '/var/lib/postgresql/ssl/server.key'
|
||||||
|
ssl_ca_file = '/var/lib/postgresql/ssl/ca.crt'
|
||||||
|
ssl_prefer_server_ciphers = on
|
||||||
|
ssl_ciphers = 'HIGH:MEDIUM:+3DES:!aNULL'
|
||||||
|
# ssl_protocols not supported in PostgreSQL 15, using ssl_min_protocol_version instead
|
||||||
|
ssl_min_protocol_version = 'TLSv1.2'
|
||||||
|
|
||||||
|
# Authentication
|
||||||
|
password_encryption = scram-sha-256
|
||||||
|
db_user_namespace = off
|
||||||
|
|
||||||
|
# Memory Settings
|
||||||
|
shared_buffers = 256MB
|
||||||
|
effective_cache_size = 1GB
|
||||||
|
work_mem = 4MB
|
||||||
|
maintenance_work_mem = 64MB
|
||||||
|
|
||||||
|
# WAL (Write-Ahead Logging) Settings - Important for data integrity
|
||||||
|
wal_level = replica
|
||||||
|
max_wal_size = 1GB
|
||||||
|
min_wal_size = 80MB
|
||||||
|
checkpoint_completion_target = 0.9
|
||||||
|
wal_compression = on
|
||||||
|
|
||||||
|
# Logging Configuration
|
||||||
|
log_destination = 'stderr'
|
||||||
|
logging_collector = on
|
||||||
|
log_directory = '/var/log/postgresql'
|
||||||
|
log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log'
|
||||||
|
log_rotation_age = 1d
|
||||||
|
log_rotation_size = 10MB
|
||||||
|
log_min_messages = warning
|
||||||
|
log_min_error_statement = error
|
||||||
|
log_min_duration_statement = 1000
|
||||||
|
log_connections = on
|
||||||
|
log_disconnections = on
|
||||||
|
log_line_prefix = '%t [%p]: [%l-1] user=%u,db=%d,app=%a,client=%h '
|
||||||
|
log_statement = 'ddl'
|
||||||
|
log_temp_files = 0
|
||||||
|
|
||||||
|
# Security Settings
|
||||||
|
row_security = on
|
||||||
|
shared_preload_libraries = 'pg_stat_statements'
|
||||||
|
|
||||||
|
# Performance Tuning
|
||||||
|
random_page_cost = 1.1
|
||||||
|
effective_io_concurrency = 200
|
||||||
|
max_worker_processes = 8
|
||||||
|
max_parallel_workers_per_gather = 2
|
||||||
|
max_parallel_workers = 8
|
||||||
|
max_parallel_maintenance_workers = 2
|
||||||
|
|
||||||
|
# Checkpoint Settings
|
||||||
|
checkpoint_timeout = 5min
|
||||||
|
checkpoint_completion_target = 0.9
|
||||||
|
|
||||||
|
# Archiving (useful for backup encryption)
|
||||||
|
archive_mode = on
|
||||||
|
archive_command = 'test ! -f /var/lib/postgresql/archive/%f && cp %p /var/lib/postgresql/archive/%f'
|
|
@ -0,0 +1,61 @@
|
||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Colors for output
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
NC='\033[0m'
|
||||||
|
|
||||||
|
echo -e "${GREEN}[Postgre-TLS] Preparing to start PostgreSQL container...${NC}"
|
||||||
|
|
||||||
|
# Create secrets directory if needed
|
||||||
|
mkdir -p secrets
|
||||||
|
|
||||||
|
# Generate SSL certificates if missing
|
||||||
|
if [ ! -f "secrets/ca.crt" ] || [ ! -f "secrets/server.crt" ] || [ ! -f "secrets/server.key" ]; then
|
||||||
|
echo -e "${YELLOW}[PloughGres] Generating SSL certificates for local development...${NC}"
|
||||||
|
|
||||||
|
openssl genrsa -out secrets/ca.key 2048
|
||||||
|
|
||||||
|
openssl req -new -x509 -key secrets/ca.key -out secrets/ca.crt -days 365 \
|
||||||
|
-subj "/C=US/ST=State/L=City/O=PloughGres/CN=PloughGres-CA" -batch
|
||||||
|
|
||||||
|
openssl genrsa -out secrets/server.key 2048
|
||||||
|
|
||||||
|
openssl req -new -key secrets/server.key -out secrets/server.csr \
|
||||||
|
-subj "/C=US/ST=State/L=City/O=PloughGres/CN=localhost" -batch
|
||||||
|
|
||||||
|
openssl x509 -req -in secrets/server.csr \
|
||||||
|
-CA secrets/ca.crt -CAkey secrets/ca.key \
|
||||||
|
-CAcreateserial -out secrets/server.crt -days 365
|
||||||
|
|
||||||
|
rm secrets/server.csr
|
||||||
|
|
||||||
|
chmod 600 secrets/server.key
|
||||||
|
chmod 644 secrets/server.crt secrets/ca.crt
|
||||||
|
|
||||||
|
# Remove CA private key for security
|
||||||
|
rm secrets/ca.key
|
||||||
|
|
||||||
|
echo -e "${GREEN}[PloughGres] SSL certificates generated in secrets/${NC}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Generate password if missing
|
||||||
|
if [ ! -f "secrets/postgres_password" ]; then
|
||||||
|
echo -e "${YELLOW}[PloughGres] Generating random password for PostgreSQL...${NC}"
|
||||||
|
openssl rand -base64 32 > secrets/postgres_password
|
||||||
|
chmod 600 secrets/postgres_password
|
||||||
|
echo -e "${GREEN}[PloughGres] Generated password stored in secrets/postgres_password${NC}"
|
||||||
|
echo -e "${YELLOW}[PloughGres] Your PostgreSQL password is:${NC}"
|
||||||
|
cat secrets/postgres_password
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Manage container
|
||||||
|
echo -e "${YELLOW}[PloughGres] Managing Docker container...${NC}"
|
||||||
|
docker-compose down -v || true # Graceful down with volume removal
|
||||||
|
docker-compose build
|
||||||
|
docker-compose up -d
|
||||||
|
echo -e "${GREEN}[PloughGres] Container started successfully!${NC}"
|
||||||
|
echo -e "${YELLOW}[PloughGres] Run ./connect.sh to test the connection.${NC}"
|
Loading…
Reference in New Issue