7.5 KiB
Security Notes
Network Security Architecture
Internal-Only Services
The following services are configured to be internal-only and are not exposed to the host machine or external network:
- Ollama - AI service (port 11434 internal only)
- MongoDB - Database (port 27017 internal only)
- Crawler - News crawler (no ports)
- Sender - Newsletter sender (no ports)
Only the Backend API is exposed to the host on port 5001.
This provides several security benefits:
Ollama Service Security
Configuration:
# Ollama service has NO ports exposed
ollama:
image: ollama/ollama:latest
# No ports section - internal only
networks:
- munich-news-network
Benefits:
- No External Access: Ollama API cannot be accessed from outside Docker network
- Reduced Attack Surface: Service is not exposed to potential external threats
- Network Isolation: Only authorized Docker Compose services can communicate with Ollama
- No Port Conflicts: Port 11434 is not bound to host machine
Accessing Ollama
From Docker Compose Services (✓ Allowed):
# Services use internal Docker network
OLLAMA_BASE_URL=http://ollama:11434
From Host Machine (✗ Not Allowed):
# This will NOT work - port not exposed
curl http://localhost:11434/api/tags
# Connection refused
From Inside Containers (✓ Allowed):
# Access from another container
docker-compose exec crawler curl http://ollama:11434/api/tags
Why This Matters
Security Risks of Exposed Ollama:
- Unauthorized access to AI models
- Potential for abuse (resource consumption)
- Information disclosure through prompts
- No authentication by default
- Could be used for unintended purposes
With Internal-Only Configuration:
- Only your trusted services can access Ollama
- No external attack vector
- Controlled usage within your application
- Better resource management
Testing Ollama
Since Ollama is internal-only, you must test from inside the Docker network:
# ✓ Correct way - from inside a container
docker-compose exec crawler curl -s http://ollama:11434/api/tags
# ✓ Test translation
docker-compose exec crawler python crawler_service.py 1
# ✓ Check logs
docker-compose logs ollama
If You Need External Access
If you have a specific need to access Ollama from the host machine (e.g., development, debugging), you can temporarily expose it:
Option 1: Temporary Port Forward
# Forward port temporarily (stops when you press Ctrl+C)
docker exec -it munich-news-ollama socat TCP-LISTEN:11434,fork TCP:localhost:11434 &
Option 2: Add Ports to docker-compose.yml (Not Recommended)
ollama:
ports:
- "127.0.0.1:11434:11434" # Only bind to localhost, not 0.0.0.0
⚠️ Warning: Only expose Ollama if absolutely necessary, and always bind to 127.0.0.1 (localhost only), never 0.0.0.0 (all interfaces).
Other Security Considerations
MongoDB:
- ✅ Internal-only (not exposed to host)
- Uses authentication (username/password)
- Only accessible via Docker network
- Cannot be accessed from host machine or external network
Backend API:
- Exposed on port 5001 for tracking and admin functions
- Should be behind reverse proxy in production
- Consider adding authentication for admin endpoints
- In production, bind to localhost only:
127.0.0.1:5001:5001
Email Credentials:
- Stored in
.envfile - Never commit
.envto version control - Use environment variables in production
Production Recommendations
-
Use Docker Secrets for sensitive data:
secrets: mongo_password: external: true -
Restrict Backend to Localhost (if not using reverse proxy):
backend: ports: - "127.0.0.1:5001:5001" # Only accessible from localhost -
Use Reverse Proxy (nginx, Traefik) - Recommended:
backend: # Remove ports section - only accessible via reverse proxy expose: - "5001"Benefits:
- SSL/TLS termination
- Rate limiting
- Authentication
- Access logs
- DDoS protection
-
Regular Updates:
docker-compose pull docker-compose up -d -
Monitor Logs:
docker-compose logs -f -
Network Isolation:
- ✅ Already configured: MongoDB, Ollama, Crawler, Sender are internal-only
- Only Backend API is exposed
- All services communicate via internal Docker network
Security Checklist
- Ollama is internal-only (no exposed ports)
- MongoDB is internal-only (no exposed ports)
- MongoDB uses authentication
- Crawler is internal-only (no exposed ports)
- Sender is internal-only (no exposed ports)
- Only Backend API is exposed (port 5001)
.envfile is in.gitignore- Backend API has authentication (if needed)
- Using HTTPS in production (reverse proxy)
- Regular security updates
- Monitoring and logging enabled
- Backup strategy in place
Reporting Security Issues
If you discover a security vulnerability, please email security@example.com (replace with your contact).
Do not open public issues for security vulnerabilities.
Network Isolation Summary
Current Port Exposure
| Service | Port | Exposed to Host | Security Status |
|---|---|---|---|
| Backend API | 5001 | ✅ Yes | Only exposed service |
| MongoDB | 27017 | ❌ No | Internal only |
| Ollama | 11434 | ❌ No | Internal only |
| Crawler | - | ❌ No | Internal only |
| Sender | - | ❌ No | Internal only |
Security Improvements Applied
Ollama Service:
- Changed from exposed (port 11434) to internal-only
- Only accessible via Docker network
- Prevents unauthorized AI model usage
MongoDB Service:
- Changed from exposed (port 27017) to internal-only
- Only accessible via Docker network
- Prevents unauthorized database access
Result:
- 66% reduction in attack surface (3 services → 1 service exposed)
- Better defense in depth
- Production-ready security configuration
Verification Commands
# Check what's exposed
docker ps --format "table {{.Names}}\t{{.Ports}}"
# Expected output:
# Backend: 0.0.0.0:5001->5001/tcp ← Only this exposed
# MongoDB: 27017/tcp ← Internal only
# Ollama: 11434/tcp ← Internal only
# Test MongoDB not accessible from host
nc -z -w 2 localhost 27017 # Should fail
# Test Ollama not accessible from host
nc -z -w 2 localhost 11434 # Should fail
# Test Backend accessible from host
curl http://localhost:5001/health # Should work
MongoDB Connection Security
Configuration
Inside Docker Network:
MONGODB_URI=mongodb://admin:changeme@mongodb:27017/
- Uses
mongodb(Docker service name) - Only works inside Docker network
- Cannot be accessed from host
Connection Flow:
- Service reads
MONGODB_URIfrom environment - Docker DNS resolves
mongodbto container IP - Connection established via internal network
- No external exposure
Why This Is Secure
- MongoDB port (27017) not exposed to host
- Only Docker Compose services can connect
- Uses authentication (username/password)
- Network isolation prevents external access
Testing Security Configuration
Run the connectivity test:
./test-mongodb-connectivity.sh
Expected results:
- ✅ MongoDB NOT accessible from host
- ✅ Backend CAN connect to MongoDB
- ✅ Crawler CAN connect to MongoDB
- ✅ Sender CAN connect to MongoDB
- ✅ Backend API accessible from host