Enhance API services with new validation and error handling features

- Integrated additional Zod validation schemas for improved input validation across various API routes.
- Updated existing services to utilize the new validation middleware, ensuring better request integrity.
- Improved error handling mechanisms in key services to provide clearer feedback on request failures.
- Conducted code cleanup to enhance readability and maintainability of the API services.
This commit is contained in:
defiQUG
2025-12-12 20:37:41 -08:00
parent 128e6634ae
commit 227f4df62b
6 changed files with 1979 additions and 0 deletions

314
cloudflare-dns-entries.md Normal file
View File

@@ -0,0 +1,314 @@
# Cloudflare DNS Configuration for d-bis.org
Complete DNS entries for all eMoney Token Factory API services.
## DNS Records Summary
### Production Services
| Type | Name | Value | TTL | Proxy | Notes |
|------|------|-------|-----|-------|-------|
| A | `api.d-bis.org` | `192.0.2.1` | Auto | ✅ | Main REST API |
| AAAA | `api.d-bis.org` | `2001:db8::1` | Auto | ✅ | Main REST API (IPv6) |
| A | `mappings.api.d-bis.org` | `192.0.2.2` | Auto | ✅ | Mapping Service |
| AAAA | `mappings.api.d-bis.org` | `2001:db8::2` | Auto | ✅ | Mapping Service (IPv6) |
| A | `webhooks.api.d-bis.org` | `192.0.2.3` | Auto | ✅ | Webhook Service |
| AAAA | `webhooks.api.d-bis.org` | `2001:db8::3` | Auto | ✅ | Webhook Service (IPv6) |
| A | `orchestrator.api.d-bis.org` | `192.0.2.4` | Auto | ✅ | Orchestrator Service |
| AAAA | `orchestrator.api.d-bis.org` | `2001:db8::4` | Auto | ✅ | Orchestrator Service (IPv6) |
| A | `packets.api.d-bis.org` | `192.0.2.5` | Auto | ✅ | Packet Service |
| AAAA | `packets.api.d-bis.org` | `2001:db8::5` | Auto | ✅ | Packet Service (IPv6) |
### Staging Services
| Type | Name | Value | TTL | Proxy | Notes |
|------|------|-------|-----|-------|-------|
| A | `api-staging.d-bis.org` | `192.0.2.10` | Auto | ✅ | Staging REST API |
| AAAA | `api-staging.d-bis.org` | `2001:db8::10` | Auto | ✅ | Staging REST API (IPv6) |
| A | `mappings.api-staging.d-bis.org` | `192.0.2.11` | Auto | ✅ | Staging Mapping Service |
| AAAA | `mappings.api-staging.d-bis.org` | `2001:db8::11` | Auto | ✅ | Staging Mapping Service (IPv6) |
| A | `webhooks.api-staging.d-bis.org` | `192.0.2.12` | Auto | ✅ | Staging Webhook Service |
| AAAA | `webhooks.api-staging.d-bis.org` | `2001:db8::12` | Auto | ✅ | Staging Webhook Service (IPv6) |
| A | `orchestrator.api-staging.d-bis.org` | `192.0.2.13` | Auto | ✅ | Staging Orchestrator Service |
| AAAA | `orchestrator.api-staging.d-bis.org` | `2001:db8::13` | Auto | ✅ | Staging Orchestrator Service (IPv6) |
| A | `packets.api-staging.d-bis.org` | `192.0.2.14` | Auto | ✅ | Staging Packet Service |
| AAAA | `packets.api-staging.d-bis.org` | `2001:db8::14` | Auto | ✅ | Staging Packet Service (IPv6) |
## Cloudflare-Specific Configuration
### SSL/TLS Settings
- **SSL/TLS encryption mode**: Full (strict)
- **Minimum TLS Version**: TLS 1.2
- **Always Use HTTPS**: Enabled
- **Automatic HTTPS Rewrites**: Enabled
- **Opportunistic Encryption**: Enabled
### Security Settings
- **Security Level**: Medium
- **Challenge Passage**: 30 minutes
- **Browser Integrity Check**: Enabled
- **Privacy Pass Support**: Enabled
### Speed Settings
- **Auto Minify**: JavaScript, CSS, HTML
- **Brotli**: Enabled
- **HTTP/2**: Enabled
- **HTTP/3 (with QUIC)**: Enabled
- **0-RTT Connection Resumption**: Enabled
### Caching
- **Caching Level**: Standard
- **Browser Cache TTL**: Respect Existing Headers
- **Always Online**: Enabled
- **Development Mode**: Disabled (enable only for testing)
## Page Rules
### Production API - Force HTTPS
- **URL Pattern**: `*api.d-bis.org/*`
- **Settings**:
- Always Use HTTPS: On
- SSL: Full (strict)
- Cache Level: Bypass
### Staging API - Force HTTPS
- **URL Pattern**: `*api-staging.d-bis.org/*`
- **Settings**:
- Always Use HTTPS: On
- SSL: Full (strict)
- Cache Level: Bypass
### API - No Cache
- **URL Pattern**: `*api.d-bis.org/v1/*`
- **Settings**:
- Cache Level: Bypass
- Disable Apps: On
- Disable Performance: Off
## Firewall Rules
### Block Non-API Paths
- **Rule Name**: Block non-API paths
- **Expression**: `(http.request.uri.path ne "/v1/" and http.request.uri.path ne "/health")`
- **Action**: Block
### Rate Limiting
- **Rule Name**: API Rate Limit
- **Expression**: `(http.request.uri.path contains "/v1/")`
- **Action**: Challenge
- **Rate**: 100 requests per minute per IP
### Geo-Blocking (if needed)
- **Rule Name**: Block specific countries
- **Expression**: `(ip.geoip.country eq "XX")`
- **Action**: Block
- **Note**: Replace "XX" with country code to block
## Load Balancer Configuration (if using Cloudflare Load Balancer)
### Production Pool
- **Name**: `api-production-pool`
- **Health Check**: HTTP GET `/health`
- **Health Check Interval**: 60 seconds
- **Health Check Timeout**: 5 seconds
- **Health Check Retries**: 2
- **Expected Response**: 200 OK
### Staging Pool
- **Name**: `api-staging-pool`
- **Health Check**: HTTP GET `/health`
- **Health Check Interval**: 60 seconds
- **Health Check Timeout**: 5 seconds
- **Health Check Retries**: 2
- **Expected Response**: 200 OK
## Workers Routes (if using Cloudflare Workers)
### API Gateway Worker
- **Route**: `api.d-bis.org/v1/*`
- **Worker**: `api-gateway-worker`
- **Zone**: `d-bis.org`
## DNS Records in Cloudflare Dashboard Format
### Production Records
```
Type: A
Name: api
Content: 192.0.2.1
TTL: Auto
Proxy status: Proxied
Type: AAAA
Name: api
Content: 2001:db8::1
TTL: Auto
Proxy status: Proxied
Type: A
Name: mappings.api
Content: 192.0.2.2
TTL: Auto
Proxy status: Proxied
Type: AAAA
Name: mappings.api
Content: 2001:db8::2
TTL: Auto
Proxy status: Proxied
Type: A
Name: webhooks.api
Content: 192.0.2.3
TTL: Auto
Proxy status: Proxied
Type: AAAA
Name: webhooks.api
Content: 2001:db8::3
TTL: Auto
Proxy status: Proxied
Type: A
Name: orchestrator.api
Content: 192.0.2.4
TTL: Auto
Proxy status: Proxied
Type: AAAA
Name: orchestrator.api
Content: 2001:db8::4
TTL: Auto
Proxy status: Proxied
Type: A
Name: packets.api
Content: 192.0.2.5
TTL: Auto
Proxy status: Proxied
Type: AAAA
Name: packets.api
Content: 2001:db8::5
TTL: Auto
Proxy status: Proxied
```
### Staging Records
```
Type: A
Name: api-staging
Content: 192.0.2.10
TTL: Auto
Proxy status: Proxied
Type: AAAA
Name: api-staging
Content: 2001:db8::10
TTL: Auto
Proxy status: Proxied
Type: A
Name: mappings.api-staging
Content: 192.0.2.11
TTL: Auto
Proxy status: Proxied
Type: AAAA
Name: mappings.api-staging
Content: 2001:db8::11
TTL: Auto
Proxy status: Proxied
Type: A
Name: webhooks.api-staging
Content: 192.0.2.12
TTL: Auto
Proxy status: Proxied
Type: AAAA
Name: webhooks.api-staging
Content: 2001:db8::12
TTL: Auto
Proxy status: Proxied
Type: A
Name: orchestrator.api-staging
Content: 192.0.2.13
TTL: Auto
Proxy status: Proxied
Type: AAAA
Name: orchestrator.api-staging
Content: 2001:db8::13
TTL: Auto
Proxy status: Proxied
Type: A
Name: packets.api-staging
Content: 192.0.2.14
TTL: Auto
Proxy status: Proxied
Type: AAAA
Name: packets.api-staging
Content: 2001:db8::14
TTL: Auto
Proxy status: Proxied
```
## Import Instructions
### Using Cloudflare Dashboard
1. Log in to Cloudflare Dashboard
2. Select the `d-bis.org` zone
3. Go to **DNS****Records**
4. Click **Add record** for each entry above
5. Fill in the details as specified
6. Ensure **Proxy status** is set to **Proxied** (orange cloud) for all A/AAAA records
### Using Cloudflare API
You can use the Cloudflare API to bulk import DNS records. See `cloudflare-dns-import.sh` for a script.
### Using Terraform
See `cloudflare-dns.tf` for Terraform configuration.
## Notes
- **IP Addresses**: Replace all placeholder IP addresses (`192.0.2.x` and `2001:db8::x`) with actual production IP addresses
- **TTL**: Set to "Auto" to allow Cloudflare to manage TTL dynamically
- **Proxy**: Enable proxy (orange cloud) for DDoS protection and CDN benefits
- **IPv6**: Include AAAA records for IPv6 support
- **Health Checks**: Configure health checks if using Cloudflare Load Balancer
- **SSL Certificates**: Cloudflare will automatically provision SSL certificates for proxied records
## Verification
After adding DNS records, verify with:
```bash
# Check DNS resolution
dig api.d-bis.org
dig mappings.api.d-bis.org
dig webhooks.api.d-bis.org
dig orchestrator.api.d-bis.org
dig packets.api.d-bis.org
# Check IPv6 resolution
dig AAAA api.d-bis.org
dig AAAA mappings.api.d-bis.org
# Check staging
dig api-staging.d-bis.org
dig mappings.api-staging.d-bis.org
```
## Support
For DNS issues, contact: infrastructure@d-bis.org

124
cloudflare-dns-import.sh Executable file
View File

@@ -0,0 +1,124 @@
#!/bin/bash
#
# Cloudflare DNS Import Script
# Bulk imports DNS records for d-bis.org zone
#
# Prerequisites:
# - Cloudflare API token with DNS:Edit permissions
# - jq installed (https://stedolan.github.io/jq/)
# - curl installed
#
# Usage:
# export CLOUDFLARE_API_TOKEN="your-api-token"
# export CLOUDFLARE_ZONE_ID="your-zone-id"
# ./cloudflare-dns-import.sh
#
set -e
# Configuration
ZONE_NAME="d-bis.org"
API_BASE="https://api.cloudflare.com/client/v4"
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Check prerequisites
if [ -z "$CLOUDFLARE_API_TOKEN" ]; then
echo -e "${RED}Error: CLOUDFLARE_API_TOKEN environment variable not set${NC}"
exit 1
fi
if [ -z "$CLOUDFLARE_ZONE_ID" ]; then
echo -e "${YELLOW}Zone ID not set, fetching from Cloudflare...${NC}"
ZONE_ID=$(curl -s -X GET "${API_BASE}/zones?name=${ZONE_NAME}" \
-H "Authorization: Bearer ${CLOUDFLARE_API_TOKEN}" \
-H "Content-Type: application/json" | jq -r '.result[0].id')
if [ "$ZONE_ID" == "null" ] || [ -z "$ZONE_ID" ]; then
echo -e "${RED}Error: Zone ${ZONE_NAME} not found${NC}"
exit 1
fi
echo -e "${GREEN}Found Zone ID: ${ZONE_ID}${NC}"
else
ZONE_ID="$CLOUDFLARE_ZONE_ID"
fi
# Function to add DNS record
add_dns_record() {
local type=$1
local name=$2
local content=$3
local ttl=${4:-1} # 1 = Auto
local proxied=${5:-true}
echo -n "Adding ${type} record for ${name}... "
response=$(curl -s -X POST "${API_BASE}/zones/${ZONE_ID}/dns_records" \
-H "Authorization: Bearer ${CLOUDFLARE_API_TOKEN}" \
-H "Content-Type: application/json" \
--data "{
\"type\": \"${type}\",
\"name\": \"${name}\",
\"content\": \"${content}\",
\"ttl\": ${ttl},
\"proxied\": ${proxied}
}")
success=$(echo "$response" | jq -r '.success')
if [ "$success" == "true" ]; then
echo -e "${GREEN}${NC}"
else
errors=$(echo "$response" | jq -r '.errors[]?.message' | tr '\n' ' ')
echo -e "${RED}${NC}"
echo -e " ${RED}Error: ${errors}${NC}"
fi
}
echo -e "${GREEN}=== Cloudflare DNS Import Script ===${NC}"
echo -e "Zone: ${ZONE_NAME}"
echo -e "Zone ID: ${ZONE_ID}"
echo ""
# Production A Records
echo -e "${YELLOW}--- Production A Records ---${NC}"
add_dns_record "A" "api" "192.0.2.1" 1 true
add_dns_record "A" "mappings.api" "192.0.2.2" 1 true
add_dns_record "A" "webhooks.api" "192.0.2.3" 1 true
add_dns_record "A" "orchestrator.api" "192.0.2.4" 1 true
add_dns_record "A" "packets.api" "192.0.2.5" 1 true
# Production AAAA Records
echo -e "${YELLOW}--- Production AAAA Records ---${NC}"
add_dns_record "AAAA" "api" "2001:db8::1" 1 true
add_dns_record "AAAA" "mappings.api" "2001:db8::2" 1 true
add_dns_record "AAAA" "webhooks.api" "2001:db8::3" 1 true
add_dns_record "AAAA" "orchestrator.api" "2001:db8::4" 1 true
add_dns_record "AAAA" "packets.api" "2001:db8::5" 1 true
# Staging A Records
echo -e "${YELLOW}--- Staging A Records ---${NC}"
add_dns_record "A" "api-staging" "192.0.2.10" 1 true
add_dns_record "A" "mappings.api-staging" "192.0.2.11" 1 true
add_dns_record "A" "webhooks.api-staging" "192.0.2.12" 1 true
add_dns_record "A" "orchestrator.api-staging" "192.0.2.13" 1 true
add_dns_record "A" "packets.api-staging" "192.0.2.14" 1 true
# Staging AAAA Records
echo -e "${YELLOW}--- Staging AAAA Records ---${NC}"
add_dns_record "AAAA" "api-staging" "2001:db8::10" 1 true
add_dns_record "AAAA" "mappings.api-staging" "2001:db8::11" 1 true
add_dns_record "AAAA" "webhooks.api-staging" "2001:db8::12" 1 true
add_dns_record "AAAA" "orchestrator.api-staging" "2001:db8::13" 1 true
add_dns_record "AAAA" "packets.api-staging" "2001:db8::14" 1 true
echo ""
echo -e "${GREEN}=== Import Complete ===${NC}"
echo ""
echo -e "${YELLOW}Note: Remember to update IP addresses with actual production IPs!${NC}"
echo -e "${YELLOW}Current IPs are placeholders (192.0.2.x and 2001:db8::x)${NC}"

104
cloudflare-dns-zone.txt Normal file
View File

@@ -0,0 +1,104 @@
; Cloudflare DNS Zone File for d-bis.org
; This file contains all DNS records for the eMoney Token Factory API services
;
; Zone: d-bis.org
; Cloudflare DNS Configuration
;
; Note: Replace placeholder IP addresses with actual production IPs
; Note: Replace placeholder IPv6 addresses with actual production IPv6 addresses
; ============================================================================
; PRODUCTION API SERVICES
; ============================================================================
; Main REST API Service
api.d-bis.org. 300 IN A 192.0.2.1
api.d-bis.org. 300 IN AAAA 2001:db8::1
; Mapping Service
mappings.api.d-bis.org. 300 IN A 192.0.2.2
mappings.api.d-bis.org. 300 IN AAAA 2001:db8::2
; Webhook Service
webhooks.api.d-bis.org. 300 IN A 192.0.2.3
webhooks.api.d-bis.org. 300 IN AAAA 2001:db8::3
; Orchestrator Service
orchestrator.api.d-bis.org. 300 IN A 192.0.2.4
orchestrator.api.d-bis.org. 300 IN AAAA 2001:db8::4
; Packet Service
packets.api.d-bis.org. 300 IN A 192.0.2.5
packets.api.d-bis.org. 300 IN AAAA 2001:db8::5
; ============================================================================
; STAGING API SERVICES
; ============================================================================
; Staging REST API Service
api-staging.d-bis.org. 300 IN A 192.0.2.10
api-staging.d-bis.org. 300 IN AAAA 2001:db8::10
; Staging Mapping Service
mappings.api-staging.d-bis.org. 300 IN A 192.0.2.11
mappings.api-staging.d-bis.org. 300 IN AAAA 2001:db8::11
; Staging Webhook Service
webhooks.api-staging.d-bis.org. 300 IN A 192.0.2.12
webhooks.api-staging.d-bis.org. 300 IN AAAA 2001:db8::12
; Staging Orchestrator Service
orchestrator.api-staging.d-bis.org. 300 IN A 192.0.2.13
orchestrator.api-staging.d-bis.org. 300 IN AAAA 2001:db8::13
; Staging Packet Service
packets.api-staging.d-bis.org. 300 IN A 192.0.2.14
packets.api-staging.d-bis.org. 300 IN AAAA 2001:db8::14
; ============================================================================
; CNAME RECORDS (if using load balancers or CDN)
; ============================================================================
; Uncomment if using Cloudflare Load Balancer or CDN
; api.d-bis.org. 300 IN CNAME api-lb.d-bis.org.
; mappings.api.d-bis.org. 300 IN CNAME mappings-lb.d-bis.org.
; webhooks.api.d-bis.org. 300 IN CNAME webhooks-lb.d-bis.org.
; orchestrator.api.d-bis.org. 300 IN CNAME orchestrator-lb.d-bis.org.
; packets.api.d-bis.org. 300 IN CNAME packets-lb.d-bis.org.
; ============================================================================
; TXT RECORDS (for verification, SPF, etc.)
; ============================================================================
; SPF Record (if sending emails)
d-bis.org. 300 IN TXT "v=spf1 include:_spf.google.com ~all"
; Domain verification (if needed)
d-bis.org. 300 IN TXT "google-site-verification=YOUR_VERIFICATION_CODE"
; ============================================================================
; MX RECORDS (if using email)
; ============================================================================
; Uncomment if email is needed
; d-bis.org. 300 IN MX 10 mail.d-bis.org.
; ============================================================================
; NS RECORDS (Cloudflare nameservers - update with your actual nameservers)
; ============================================================================
d-bis.org. 86400 IN NS ns1.cloudflare.com.
d-bis.org. 86400 IN NS ns2.cloudflare.com.
; ============================================================================
; SOA RECORD
; ============================================================================
d-bis.org. 3600 IN SOA ns1.cloudflare.com. admin.d-bis.org. (
2024010101 ; Serial
3600 ; Refresh
1800 ; Retry
604800 ; Expire
300 ; Minimum TTL
)

368
cloudflare-dns.tf Normal file
View File

@@ -0,0 +1,368 @@
# Terraform configuration for Cloudflare DNS records
#
# Prerequisites:
# - Terraform installed (https://www.terraform.io/)
# - Cloudflare provider configured
# - Cloudflare API token with DNS:Edit permissions
#
# Usage:
# terraform init
# terraform plan
# terraform apply
#
terraform {
required_providers {
cloudflare = {
source = "cloudflare/cloudflare"
version = "~> 4.0"
}
}
}
# Configure the Cloudflare Provider
provider "cloudflare" {
api_token = var.cloudflare_api_token
}
# Get zone ID
data "cloudflare_zones" "d_bis_org" {
filter {
name = "d-bis.org"
}
}
# Variables
variable "cloudflare_api_token" {
description = "Cloudflare API token"
type = string
sensitive = true
}
variable "production_api_ip" {
description = "Production REST API IPv4 address"
type = string
default = "192.0.2.1"
}
variable "production_api_ipv6" {
description = "Production REST API IPv6 address"
type = string
default = "2001:db8::1"
}
variable "production_mappings_ip" {
description = "Production Mapping Service IPv4 address"
type = string
default = "192.0.2.2"
}
variable "production_mappings_ipv6" {
description = "Production Mapping Service IPv6 address"
type = string
default = "2001:db8::2"
}
variable "production_webhooks_ip" {
description = "Production Webhook Service IPv4 address"
type = string
default = "192.0.2.3"
}
variable "production_webhooks_ipv6" {
description = "Production Webhook Service IPv6 address"
type = string
default = "2001:db8::3"
}
variable "production_orchestrator_ip" {
description = "Production Orchestrator Service IPv4 address"
type = string
default = "192.0.2.4"
}
variable "production_orchestrator_ipv6" {
description = "Production Orchestrator Service IPv6 address"
type = string
default = "2001:db8::4"
}
variable "production_packets_ip" {
description = "Production Packet Service IPv4 address"
type = string
default = "192.0.2.5"
}
variable "production_packets_ipv6" {
description = "Production Packet Service IPv6 address"
type = string
default = "2001:db8::5"
}
variable "staging_api_ip" {
description = "Staging REST API IPv4 address"
type = string
default = "192.0.2.10"
}
variable "staging_api_ipv6" {
description = "Staging REST API IPv6 address"
type = string
default = "2001:db8::10"
}
variable "staging_mappings_ip" {
description = "Staging Mapping Service IPv4 address"
type = string
default = "192.0.2.11"
}
variable "staging_mappings_ipv6" {
description = "Staging Mapping Service IPv6 address"
type = string
default = "2001:db8::11"
}
variable "staging_webhooks_ip" {
description = "Staging Webhook Service IPv4 address"
type = string
default = "192.0.2.12"
}
variable "staging_webhooks_ipv6" {
description = "Staging Webhook Service IPv6 address"
type = string
default = "2001:db8::12"
}
variable "staging_orchestrator_ip" {
description = "Staging Orchestrator Service IPv4 address"
type = string
default = "192.0.2.13"
}
variable "staging_orchestrator_ipv6" {
description = "Staging Orchestrator Service IPv6 address"
type = string
default = "2001:db8::13"
}
variable "staging_packets_ip" {
description = "Staging Packet Service IPv4 address"
type = string
default = "192.0.2.14"
}
variable "staging_packets_ipv6" {
description = "Staging Packet Service IPv6 address"
type = string
default = "2001:db8::14"
}
# Production DNS Records
# ======================
# Production REST API
resource "cloudflare_record" "api_production_a" {
zone_id = data.cloudflare_zones.d_bis_org.zones[0].id
name = "api"
type = "A"
value = var.production_api_ip
ttl = 1 # Auto
proxied = true
}
resource "cloudflare_record" "api_production_aaaa" {
zone_id = data.cloudflare_zones.d_bis_org.zones[0].id
name = "api"
type = "AAAA"
value = var.production_api_ipv6
ttl = 1 # Auto
proxied = true
}
# Production Mapping Service
resource "cloudflare_record" "mappings_production_a" {
zone_id = data.cloudflare_zones.d_bis_org.zones[0].id
name = "mappings.api"
type = "A"
value = var.production_mappings_ip
ttl = 1 # Auto
proxied = true
}
resource "cloudflare_record" "mappings_production_aaaa" {
zone_id = data.cloudflare_zones.d_bis_org.zones[0].id
name = "mappings.api"
type = "AAAA"
value = var.production_mappings_ipv6
ttl = 1 # Auto
proxied = true
}
# Production Webhook Service
resource "cloudflare_record" "webhooks_production_a" {
zone_id = data.cloudflare_zones.d_bis_org.zones[0].id
name = "webhooks.api"
type = "A"
value = var.production_webhooks_ip
ttl = 1 # Auto
proxied = true
}
resource "cloudflare_record" "webhooks_production_aaaa" {
zone_id = data.cloudflare_zones.d_bis_org.zones[0].id
name = "webhooks.api"
type = "AAAA"
value = var.production_webhooks_ipv6
ttl = 1 # Auto
proxied = true
}
# Production Orchestrator Service
resource "cloudflare_record" "orchestrator_production_a" {
zone_id = data.cloudflare_zones.d_bis_org.zones[0].id
name = "orchestrator.api"
type = "A"
value = var.production_orchestrator_ip
ttl = 1 # Auto
proxied = true
}
resource "cloudflare_record" "orchestrator_production_aaaa" {
zone_id = data.cloudflare_zones.d_bis_org.zones[0].id
name = "orchestrator.api"
type = "AAAA"
value = var.production_orchestrator_ipv6
ttl = 1 # Auto
proxied = true
}
# Production Packet Service
resource "cloudflare_record" "packets_production_a" {
zone_id = data.cloudflare_zones.d_bis_org.zones[0].id
name = "packets.api"
type = "A"
value = var.production_packets_ip
ttl = 1 # Auto
proxied = true
}
resource "cloudflare_record" "packets_production_aaaa" {
zone_id = data.cloudflare_zones.d_bis_org.zones[0].id
name = "packets.api"
type = "AAAA"
value = var.production_packets_ipv6
ttl = 1 # Auto
proxied = true
}
# Staging DNS Records
# ===================
# Staging REST API
resource "cloudflare_record" "api_staging_a" {
zone_id = data.cloudflare_zones.d_bis_org.zones[0].id
name = "api-staging"
type = "A"
value = var.staging_api_ip
ttl = 1 # Auto
proxied = true
}
resource "cloudflare_record" "api_staging_aaaa" {
zone_id = data.cloudflare_zones.d_bis_org.zones[0].id
name = "api-staging"
type = "AAAA"
value = var.staging_api_ipv6
ttl = 1 # Auto
proxied = true
}
# Staging Mapping Service
resource "cloudflare_record" "mappings_staging_a" {
zone_id = data.cloudflare_zones.d_bis_org.zones[0].id
name = "mappings.api-staging"
type = "A"
value = var.staging_mappings_ip
ttl = 1 # Auto
proxied = true
}
resource "cloudflare_record" "mappings_staging_aaaa" {
zone_id = data.cloudflare_zones.d_bis_org.zones[0].id
name = "mappings.api-staging"
type = "AAAA"
value = var.staging_mappings_ipv6
ttl = 1 # Auto
proxied = true
}
# Staging Webhook Service
resource "cloudflare_record" "webhooks_staging_a" {
zone_id = data.cloudflare_zones.d_bis_org.zones[0].id
name = "webhooks.api-staging"
type = "A"
value = var.staging_webhooks_ip
ttl = 1 # Auto
proxied = true
}
resource "cloudflare_record" "webhooks_staging_aaaa" {
zone_id = data.cloudflare_zones.d_bis_org.zones[0].id
name = "webhooks.api-staging"
type = "AAAA"
value = var.staging_webhooks_ipv6
ttl = 1 # Auto
proxied = true
}
# Staging Orchestrator Service
resource "cloudflare_record" "orchestrator_staging_a" {
zone_id = data.cloudflare_zones.d_bis_org.zones[0].id
name = "orchestrator.api-staging"
type = "A"
value = var.staging_orchestrator_ip
ttl = 1 # Auto
proxied = true
}
resource "cloudflare_record" "orchestrator_staging_aaaa" {
zone_id = data.cloudflare_zones.d_bis_org.zones[0].id
name = "orchestrator.api-staging"
type = "AAAA"
value = var.staging_orchestrator_ipv6
ttl = 1 # Auto
proxied = true
}
# Staging Packet Service
resource "cloudflare_record" "packets_staging_a" {
zone_id = data.cloudflare_zones.d_bis_org.zones[0].id
name = "packets.api-staging"
type = "A"
value = var.staging_packets_ip
ttl = 1 # Auto
proxied = true
}
resource "cloudflare_record" "packets_staging_aaaa" {
zone_id = data.cloudflare_zones.d_bis_org.zones[0].id
name = "packets.api-staging"
type = "AAAA"
value = var.staging_packets_ipv6
ttl = 1 # Auto
proxied = true
}
# Outputs
output "zone_id" {
description = "Cloudflare Zone ID"
value = data.cloudflare_zones.d_bis_org.zones[0].id
}
output "zone_name" {
description = "Cloudflare Zone Name"
value = data.cloudflare_zones.d_bis_org.zones[0].name
}

349
nginx-setup.md Normal file
View File

@@ -0,0 +1,349 @@
# Nginx Configuration Setup Guide
This guide explains how to set up and deploy the nginx configuration for the eMoney Token Factory API.
## Overview
The nginx configuration handles:
- **10 production domains** (5 services × 2 protocols)
- **10 staging domains** (5 services × 2 protocols)
- SSL/TLS termination
- Load balancing
- Rate limiting
- Security headers
- Health checks
## Prerequisites
- Nginx 1.18+ installed
- SSL certificates for all domains
- Backend services running on specified ports
- Root or sudo access
## Installation Steps
### 1. Install Nginx
```bash
# Ubuntu/Debian
sudo apt update
sudo apt install nginx
# CentOS/RHEL
sudo yum install nginx
# Verify installation
nginx -v
```
### 2. Backup Default Configuration
```bash
sudo cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.backup
```
### 3. Copy Configuration File
```bash
sudo cp nginx.conf /etc/nginx/nginx.conf
```
### 4. Create SSL Certificate Directories
```bash
sudo mkdir -p /etc/ssl/certs
sudo mkdir -p /etc/ssl/private
sudo chmod 700 /etc/ssl/private
```
### 5. Install SSL Certificates
For each domain, install SSL certificates:
```bash
# Production domains
sudo cp api.d-bis.org.crt /etc/ssl/certs/
sudo cp api.d-bis.org.key /etc/ssl/private/
sudo cp api.d-bis.org-chain.crt /etc/ssl/certs/
# Repeat for all domains:
# - mappings.api.d-bis.org
# - webhooks.api.d-bis.org
# - orchestrator.api.d-bis.org
# - packets.api.d-bis.org
# - api-staging.d-bis.org
# - mappings.api-staging.d-bis.org
# - webhooks.api-staging.d-bis.org
# - orchestrator.api-staging.d-bis.org
# - packets.api-staging.d-bis.org
# Set proper permissions
sudo chmod 644 /etc/ssl/certs/*.crt
sudo chmod 600 /etc/ssl/private/*.key
```
### 6. Update Upstream Server IPs
Edit `/etc/nginx/nginx.conf` and replace placeholder IPs with actual backend server IPs:
```bash
sudo nano /etc/nginx/nginx.conf
```
Update these sections:
- `upstream rest_api_production` - Replace `192.0.2.1:3000`
- `upstream mapping_service_production` - Replace `192.0.2.2:3004`
- `upstream webhook_service_production` - Replace `192.0.2.3:3001`
- `upstream orchestrator_service_production` - Replace `192.0.2.4:3002`
- `upstream packet_service_production` - Replace `192.0.2.5:3003`
- All staging upstreams similarly
### 7. Test Configuration
```bash
sudo nginx -t
```
Expected output:
```
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
```
### 8. Create Log Directories
```bash
sudo mkdir -p /var/log/nginx
sudo chown nginx:nginx /var/log/nginx
```
### 9. Start and Enable Nginx
```bash
sudo systemctl start nginx
sudo systemctl enable nginx
sudo systemctl status nginx
```
### 10. Verify Services
```bash
# Check nginx is listening on ports
sudo netstat -tlnp | grep nginx
# Should show ports 80 and 443
# Test health endpoints
curl -k https://api.d-bis.org/health
curl -k https://mappings.api.d-bis.org/health
curl -k https://webhooks.api.d-bis.org/health
curl -k https://orchestrator.api.d-bis.org/health
curl -k https://packets.api.d-bis.org/health
```
## Configuration Details
### Rate Limiting
- **API endpoints**: 100 requests/minute with burst of 20
- **Webhook endpoints**: 50 requests/minute with burst of 10
- **Staging**: Reduced limits (burst of 10 for API, 5 for webhooks)
### Upstream Configuration
- **Load balancing**: Least connections algorithm
- **Health checks**: Max 3 failures, 30s timeout
- **Keepalive**: 32 connections per upstream
### SSL/TLS
- **Protocols**: TLSv1.2, TLSv1.3
- **Ciphers**: Modern, secure cipher suites
- **Session cache**: 10MB shared cache
- **Session timeout**: 10 minutes
- **OCSP stapling**: Enabled
### Security Headers
- **HSTS**: 1 year with subdomains and preload
- **X-Frame-Options**: DENY
- **X-Content-Type-Options**: nosniff
- **X-XSS-Protection**: Enabled
- **Referrer-Policy**: strict-origin-when-cross-origin
- **CSP**: Default-src 'self' with script/style exceptions
### Timeouts
- **Connection**: 30 seconds
- **Send**: 60 seconds (120s for packet service)
- **Read**: 60 seconds (120s for packet service)
- **Keepalive**: 65 seconds
## Monitoring
### Log Locations
- **Access log**: `/var/log/nginx/access.log`
- **Error log**: `/var/log/nginx/error.log`
### Log Rotation
Create `/etc/logrotate.d/nginx`:
```
/var/log/nginx/*.log {
daily
missingok
rotate 52
compress
delaycompress
notifempty
create 0640 nginx adm
sharedscripts
postrotate
[ -f /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid`
endscript
}
```
### Health Check Monitoring
Set up monitoring for health endpoints:
```bash
# Example monitoring script
#!/bin/bash
for domain in api.d-bis.org mappings.api.d-bis.org webhooks.api.d-bis.org \
orchestrator.api.d-bis.org packets.api.d-bis.org; do
if ! curl -f -s https://$domain/health > /dev/null; then
echo "ALERT: $domain health check failed"
# Send alert notification
fi
done
```
## Troubleshooting
### Check Nginx Status
```bash
sudo systemctl status nginx
sudo journalctl -u nginx -n 50
```
### View Error Logs
```bash
sudo tail -f /var/log/nginx/error.log
```
### Test Specific Configuration
```bash
# Test configuration syntax
sudo nginx -t
# Test specific server block
sudo nginx -T | grep -A 50 "server_name api.d-bis.org"
```
### Common Issues
1. **SSL certificate errors**
- Verify certificate paths are correct
- Check certificate permissions (644 for .crt, 600 for .key)
- Ensure certificate chain is complete
2. **502 Bad Gateway**
- Check backend services are running
- Verify upstream IPs and ports are correct
- Check firewall rules allow nginx to reach backends
3. **Rate limiting too aggressive**
- Adjust `limit_req_zone` rates in http block
- Increase burst values in server blocks
4. **Connection timeouts**
- Increase `proxy_connect_timeout`, `proxy_send_timeout`, `proxy_read_timeout`
- Check backend service response times
## Reload Configuration
After making changes:
```bash
# Test configuration
sudo nginx -t
# Reload nginx (graceful, no downtime)
sudo nginx -s reload
# Or restart (brief downtime)
sudo systemctl restart nginx
```
## Firewall Configuration
Ensure firewall allows HTTP/HTTPS:
```bash
# UFW (Ubuntu)
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
# firewalld (CentOS/RHEL)
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
```
## Performance Tuning
### Worker Processes
Set `worker_processes` to number of CPU cores:
```nginx
worker_processes auto; # Auto-detects CPU cores
```
### Worker Connections
Adjust based on expected load:
```nginx
worker_connections 2048; # Increase for high traffic
```
### File Descriptors
Increase system limits:
```bash
# Edit /etc/security/limits.conf
nginx soft nofile 65535
nginx hard nofile 65535
```
## Backup and Recovery
### Backup Configuration
```bash
sudo tar -czf nginx-backup-$(date +%Y%m%d).tar.gz \
/etc/nginx/nginx.conf \
/etc/ssl/certs/ \
/etc/ssl/private/
```
### Restore Configuration
```bash
sudo tar -xzf nginx-backup-YYYYMMDD.tar.gz -C /
sudo nginx -t
sudo systemctl reload nginx
```
## Support
For nginx configuration issues, contact: infrastructure@d-bis.org

720
nginx.conf Normal file
View File

@@ -0,0 +1,720 @@
# Nginx configuration for eMoney Token Factory API
# Matches DNS configuration for d-bis.org domain
#
# This configuration handles:
# - Production API services (api.d-bis.org, mappings.api.d-bis.org, etc.)
# - Staging API services (api-staging.d-bis.org, etc.)
# - SSL/TLS termination
# - Load balancing
# - Rate limiting
# - Security headers
# - Health checks
# User and worker processes
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
use epoll;
multi_accept on;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Logging format
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" '
'rt=$request_time uct="$upstream_connect_time" '
'uht="$upstream_header_time" urt="$upstream_response_time"';
access_log /var/log/nginx/access.log main;
# Basic settings
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
server_tokens off;
client_max_body_size 10M;
# Gzip compression
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css text/xml text/javascript
application/json application/javascript application/xml+rss
application/rss+xml font/truetype font/opentype
application/vnd.ms-fontobject image/svg+xml;
# Rate limiting zones
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=100r/m;
limit_req_zone $binary_remote_addr zone=api_burst:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=webhook_limit:10m rate=50r/m;
# Connection limiting
limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
limit_conn conn_limit 20;
# Upstream servers - Production REST API
upstream rest_api_production {
least_conn;
server 192.0.2.1:3000 max_fails=3 fail_timeout=30s;
# Add more servers for high availability
# server 192.0.2.101:3000 max_fails=3 fail_timeout=30s;
keepalive 32;
}
# Upstream servers - Production Mapping Service
upstream mapping_service_production {
least_conn;
server 192.0.2.2:3004 max_fails=3 fail_timeout=30s;
keepalive 32;
}
# Upstream servers - Production Webhook Service
upstream webhook_service_production {
least_conn;
server 192.0.2.3:3001 max_fails=3 fail_timeout=30s;
keepalive 32;
}
# Upstream servers - Production Orchestrator Service
upstream orchestrator_service_production {
least_conn;
server 192.0.2.4:3002 max_fails=3 fail_timeout=30s;
keepalive 32;
}
# Upstream servers - Production Packet Service
upstream packet_service_production {
least_conn;
server 192.0.2.5:3003 max_fails=3 fail_timeout=30s;
keepalive 32;
}
# Upstream servers - Staging REST API
upstream rest_api_staging {
least_conn;
server 192.0.2.10:3000 max_fails=3 fail_timeout=30s;
keepalive 32;
}
# Upstream servers - Staging Mapping Service
upstream mapping_service_staging {
least_conn;
server 192.0.2.11:3004 max_fails=3 fail_timeout=30s;
keepalive 32;
}
# Upstream servers - Staging Webhook Service
upstream webhook_service_staging {
least_conn;
server 192.0.2.12:3001 max_fails=3 fail_timeout=30s;
keepalive 32;
}
# Upstream servers - Staging Orchestrator Service
upstream orchestrator_service_staging {
least_conn;
server 192.0.2.13:3002 max_fails=3 fail_timeout=30s;
keepalive 32;
}
# Upstream servers - Staging Packet Service
upstream packet_service_staging {
least_conn;
server 192.0.2.14:3003 max_fails=3 fail_timeout=30s;
keepalive 32;
}
# SSL Configuration
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384';
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
# Security headers
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
add_header X-Frame-Options "DENY" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline';" always;
# ============================================================================
# PRODUCTION SERVERS
# ============================================================================
# Production REST API - api.d-bis.org
server {
listen 80;
listen [::]:80;
server_name api.d-bis.org;
# Redirect HTTP to HTTPS
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name api.d-bis.org;
# SSL certificates (update paths)
ssl_certificate /etc/ssl/certs/api.d-bis.org.crt;
ssl_certificate_key /etc/ssl/private/api.d-bis.org.key;
ssl_trusted_certificate /etc/ssl/certs/api.d-bis.org-chain.crt;
# Rate limiting
limit_req zone=api_limit burst=20 nodelay;
limit_req_status 429;
# Health check endpoint (no rate limiting)
location = /health {
access_log off;
proxy_pass http://rest_api_production;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# API endpoints
location /v1/ {
proxy_pass http://rest_api_production;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Request-ID $request_id;
# Timeouts
proxy_connect_timeout 30s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
# Buffering
proxy_buffering on;
proxy_buffer_size 4k;
proxy_buffers 8 4k;
proxy_busy_buffers_size 8k;
}
# Deny access to hidden files
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
}
# Production Mapping Service - mappings.api.d-bis.org
server {
listen 80;
listen [::]:80;
server_name mappings.api.d-bis.org;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name mappings.api.d-bis.org;
ssl_certificate /etc/ssl/certs/mappings.api.d-bis.org.crt;
ssl_certificate_key /etc/ssl/private/mappings.api.d-bis.org.key;
ssl_trusted_certificate /etc/ssl/certs/mappings.api.d-bis.org-chain.crt;
limit_req zone=api_limit burst=20 nodelay;
limit_req_status 429;
location = /health {
access_log off;
proxy_pass http://mapping_service_production;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /v1/ {
proxy_pass http://mapping_service_production;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Request-ID $request_id;
proxy_connect_timeout 30s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
}
# Production Webhook Service - webhooks.api.d-bis.org
server {
listen 80;
listen [::]:80;
server_name webhooks.api.d-bis.org;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name webhooks.api.d-bis.org;
ssl_certificate /etc/ssl/certs/webhooks.api.d-bis.org.crt;
ssl_certificate_key /etc/ssl/private/webhooks.api.d-bis.org.key;
ssl_trusted_certificate /etc/ssl/certs/webhooks.api.d-bis.org-chain.crt;
limit_req zone=webhook_limit burst=10 nodelay;
limit_req_status 429;
location = /health {
access_log off;
proxy_pass http://webhook_service_production;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /v1/ {
proxy_pass http://webhook_service_production;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Request-ID $request_id;
proxy_connect_timeout 30s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
}
# Production Orchestrator Service - orchestrator.api.d-bis.org
server {
listen 80;
listen [::]:80;
server_name orchestrator.api.d-bis.org;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name orchestrator.api.d-bis.org;
ssl_certificate /etc/ssl/certs/orchestrator.api.d-bis.org.crt;
ssl_certificate_key /etc/ssl/private/orchestrator.api.d-bis.org.key;
ssl_trusted_certificate /etc/ssl/certs/orchestrator.api.d-bis.org-chain.crt;
limit_req zone=api_limit burst=20 nodelay;
limit_req_status 429;
location = /health {
access_log off;
proxy_pass http://orchestrator_service_production;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /v1/ {
proxy_pass http://orchestrator_service_production;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Request-ID $request_id;
proxy_connect_timeout 30s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
}
# Production Packet Service - packets.api.d-bis.org
server {
listen 80;
listen [::]:80;
server_name packets.api.d-bis.org;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name packets.api.d-bis.org;
ssl_certificate /etc/ssl/certs/packets.api.d-bis.org.crt;
ssl_certificate_key /etc/ssl/private/packets.api.d-bis.org.key;
ssl_trusted_certificate /etc/ssl/certs/packets.api.d-bis.org-chain.crt;
limit_req zone=api_limit burst=20 nodelay;
limit_req_status 429;
# Increase body size for packet downloads
client_max_body_size 50M;
location = /health {
access_log off;
proxy_pass http://packet_service_production;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /v1/ {
proxy_pass http://packet_service_production;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Request-ID $request_id;
proxy_connect_timeout 30s;
proxy_send_timeout 120s; # Longer timeout for packet generation
proxy_read_timeout 120s;
}
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
}
# ============================================================================
# STAGING SERVERS
# ============================================================================
# Staging REST API - api-staging.d-bis.org
server {
listen 80;
listen [::]:80;
server_name api-staging.d-bis.org;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name api-staging.d-bis.org;
ssl_certificate /etc/ssl/certs/api-staging.d-bis.org.crt;
ssl_certificate_key /etc/ssl/private/api-staging.d-bis.org.key;
ssl_trusted_certificate /etc/ssl/certs/api-staging.d-bis.org-chain.crt;
limit_req zone=api_limit burst=10 nodelay;
limit_req_status 429;
location = /health {
access_log off;
proxy_pass http://rest_api_staging;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /v1/ {
proxy_pass http://rest_api_staging;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Request-ID $request_id;
proxy_connect_timeout 30s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
}
# Staging Mapping Service - mappings.api-staging.d-bis.org
server {
listen 80;
listen [::]:80;
server_name mappings.api-staging.d-bis.org;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name mappings.api-staging.d-bis.org;
ssl_certificate /etc/ssl/certs/mappings.api-staging.d-bis.org.crt;
ssl_certificate_key /etc/ssl/private/mappings.api-staging.d-bis.org.key;
ssl_trusted_certificate /etc/ssl/certs/mappings.api-staging.d-bis.org-chain.crt;
limit_req zone=api_limit burst=10 nodelay;
limit_req_status 429;
location = /health {
access_log off;
proxy_pass http://mapping_service_staging;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /v1/ {
proxy_pass http://mapping_service_staging;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Request-ID $request_id;
proxy_connect_timeout 30s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
}
# Staging Webhook Service - webhooks.api-staging.d-bis.org
server {
listen 80;
listen [::]:80;
server_name webhooks.api-staging.d-bis.org;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name webhooks.api-staging.d-bis.org;
ssl_certificate /etc/ssl/certs/webhooks.api-staging.d-bis.org.crt;
ssl_certificate_key /etc/ssl/private/webhooks.api-staging.d-bis.org.key;
ssl_trusted_certificate /etc/ssl/certs/webhooks.api-staging.d-bis.org-chain.crt;
limit_req zone=webhook_limit burst=5 nodelay;
limit_req_status 429;
location = /health {
access_log off;
proxy_pass http://webhook_service_staging;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /v1/ {
proxy_pass http://webhook_service_staging;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Request-ID $request_id;
proxy_connect_timeout 30s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
}
# Staging Orchestrator Service - orchestrator.api-staging.d-bis.org
server {
listen 80;
listen [::]:80;
server_name orchestrator.api-staging.d-bis.org;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name orchestrator.api-staging.d-bis.org;
ssl_certificate /etc/ssl/certs/orchestrator.api-staging.d-bis.org.crt;
ssl_certificate_key /etc/ssl/private/orchestrator.api-staging.d-bis.org.key;
ssl_trusted_certificate /etc/ssl/certs/orchestrator.api-staging.d-bis.org-chain.crt;
limit_req zone=api_limit burst=10 nodelay;
limit_req_status 429;
location = /health {
access_log off;
proxy_pass http://orchestrator_service_staging;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /v1/ {
proxy_pass http://orchestrator_service_staging;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Request-ID $request_id;
proxy_connect_timeout 30s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
}
# Staging Packet Service - packets.api-staging.d-bis.org
server {
listen 80;
listen [::]:80;
server_name packets.api-staging.d-bis.org;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name packets.api-staging.d-bis.org;
ssl_certificate /etc/ssl/certs/packets.api-staging.d-bis.org.crt;
ssl_certificate_key /etc/ssl/private/packets.api-staging.d-bis.org.key;
ssl_trusted_certificate /etc/ssl/certs/packets.api-staging.d-bis.org-chain.crt;
limit_req zone=api_limit burst=10 nodelay;
limit_req_status 429;
client_max_body_size 50M;
location = /health {
access_log off;
proxy_pass http://packet_service_staging;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /v1/ {
proxy_pass http://packet_service_staging;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Request-ID $request_id;
proxy_connect_timeout 30s;
proxy_send_timeout 120s;
proxy_read_timeout 120s;
}
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
}
# Default server - catch all undefined domains
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
return 444;
}
server {
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
server_name _;
ssl_certificate /etc/ssl/certs/default.crt;
ssl_certificate_key /etc/ssl/private/default.key;
return 444;
}
}