Kong Security Best Practices
Introduction
Kong is a popular, open-source API gateway that helps manage, secure, and extend APIs. As APIs become the standard way of connecting services and applications, securing these pathways becomes crucial. This guide focuses on essential security best practices when using Kong API Gateway to protect your APIs from common threats and vulnerabilities.
Whether you're deploying Kong in a development environment or a production setting, implementing these security measures will help you build a robust security posture for your API infrastructure.
Core Security Concepts in Kong
Before diving into specific best practices, let's understand the core security concepts in Kong:
- Authentication: Verifying the identity of clients accessing your APIs
- Authorization: Determining what resources authenticated clients can access
- Rate Limiting: Protecting APIs from abuse by limiting request volumes
- Request/Response Transformation: Modifying requests and responses to eliminate security risks
- Logging and Monitoring: Tracking API activity to detect and respond to suspicious behavior
Setting Up Secure Kong Deployments
Secure Installation Best Practices
When setting up Kong, follow these security-focused installation steps:
# Use specific versions rather than 'latest' to avoid unexpected changes
$ kong config -c kong.conf --v prepare
$ kong migrations bootstrap
# Run Kong with minimal privileges
$ kong start -c kong.conf
Ensure your kong.conf
file includes these security-focused settings:
# Disable the Admin API on public interfaces
admin_listen = 127.0.0.1:8001
# Enable HTTPS for Admin API
admin_ssl_cert = /path/to/admin_ssl.cert
admin_ssl_cert_key = /path/to/admin_ssl.key
# Enforce HTTPS for proxy
proxy_ssl_cert = /path/to/proxy_ssl.cert
proxy_ssl_cert_key = /path/to/proxy_ssl.key
# Set strict security headers
headers = server_tokens=off
Network Security Configuration
Authentication and Authorization
Implementing Strong Authentication
Kong provides several authentication plugins. Here's how to implement the JWT (JSON Web Token) authentication plugin:
# Create a service
$ curl -i -X POST http://localhost:8001/services/ \
--data "name=my-service" \
--data "url=http://my-upstream-service.com"
# Create a route for the service
$ curl -i -X POST http://localhost:8001/services/my-service/routes \
--data "paths[]=/api"
# Enable the JWT plugin
$ curl -X POST http://localhost:8001/services/my-service/plugins \
--data "name=jwt"
After configuring the JWT plugin, clients must include a valid JWT in their requests:
# Example of a client request with JWT authentication
$ curl -i -X GET http://kong:8000/api \
--header "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
Implementing OAuth 2.0
For more advanced authentication scenarios, Kong's OAuth 2.0 plugin provides a complete OAuth 2.0 server implementation:
# Enable the OAuth 2.0 plugin
$ curl -X POST http://localhost:8001/services/my-service/plugins \
--data "name=oauth2" \
--data "config.enable_authorization_code=true" \
--data "config.mandatory_scope=true" \
--data "config.global_credentials=false" \
--data "config.scopes=email,phone,address" \
--data "config.token_expiration=7200"
With this configuration, clients must first obtain an access token before accessing the protected API:
# Request an authorization code
$ curl -i -X POST http://kong:8000/oauth2/authorize \
--data "client_id=CLIENT_ID" \
--data "response_type=code" \
--data "scope=email"
# Exchange the authorization code for an access token
$ curl -i -X POST http://kong:8000/oauth2/token \
--data "grant_type=authorization_code" \
--data "code=AUTHORIZATION_CODE" \
--data "client_id=CLIENT_ID" \
--data "client_secret=CLIENT_SECRET"
# Use the access token to access the API
$ curl -i -X GET http://kong:8000/api \
--header "Authorization: Bearer ACCESS_TOKEN"
Implementing Rate Limiting
Rate limiting helps protect your APIs from abuse and denial of service attacks:
# Add rate limiting to a service
$ curl -X POST http://localhost:8001/services/my-service/plugins \
--data "name=rate-limiting" \
--data "config.second=5" \
--data "config.hour=10000" \
--data "config.policy=local"
This configuration limits clients to 5 requests per second and 10,000 requests per hour.
Advanced Rate Limiting with Redis
For distributed deployments, use Redis to synchronize rate limiting across Kong nodes:
$ curl -X POST http://localhost:8001/services/my-service/plugins \
--data "name=rate-limiting" \
--data "config.second=5" \
--data "config.hour=10000" \
--data "config.policy=redis" \
--data "config.redis_host=redis-server" \
--data "config.redis_port=6379" \
--data "config.redis_timeout=2000"
API Key Security
Protect your APIs with API key authentication:
# Enable the key-auth plugin
$ curl -X POST http://localhost:8001/services/my-service/plugins \
--data "name=key-auth" \
--data "config.key_names=apikey" \
--data "config.hide_credentials=true"
# Create a consumer
$ curl -X POST http://localhost:8001/consumers/ \
--data "username=consumer1"
# Provision an API key for the consumer
$ curl -X POST http://localhost:8001/consumers/consumer1/key-auth \
--data "key=SECURE_API_KEY"
With this configuration, clients must include the API key in their requests:
# Example request with API key
$ curl -i -X GET http://kong:8000/api \
--header "apikey: SECURE_API_KEY"
IP Restriction
Limit API access to trusted IP addresses:
# Allow only specific IP addresses
$ curl -X POST http://localhost:8001/services/my-service/plugins \
--data "name=ip-restriction" \
--data "config.allow=192.168.1.0/24,10.0.0.0/8"
SSL/TLS Configuration
Enforcing HTTPS
Always enforce HTTPS for your APIs to prevent man-in-the-middle attacks:
# Enable HTTPS enforcement with the SSL plugin
$ curl -X POST http://localhost:8001/services/my-service/plugins \
--data "name=ssl" \
--data "config.cert=/path/to/cert.pem" \
--data "config.key=/path/to/key.pem" \
--data "config.only_https=true"
Alternatively, configure Kong to redirect HTTP to HTTPS:
# kong.yml configuration
plugins:
- name: request-transformer
config:
http_method: GET
remove:
headers:
- Host
replace:
uri: $(uri:gsub("^http://", "https://"))
Regular Security Audits
Regularly audit your Kong configuration using the Admin API:
# List all plugins to review security configurations
$ curl -s http://localhost:8001/plugins | jq
# Check for exposed services without authentication
$ curl -s http://localhost:8001/services | jq '.data[] | {name, plugins: .plugins.data[].name}'
# Review rate limiting configurations
$ curl -s http://localhost:8001/plugins?name=rate-limiting | jq
Monitoring and Logging
Setting Up Comprehensive Logging
Configure Kong to log detailed information for security monitoring:
# Enable HTTP Log plugin to send logs to an external system
$ curl -X POST http://localhost:8001/services/my-service/plugins \
--data "name=http-log" \
--data "config.http_endpoint=http://logger:3000/logs" \
--data "config.method=POST" \
--data "config.timeout=10000" \
--data "config.keepalive=60000"
Integrating with Security Information and Event Management (SIEM)
For enterprise environments, integrate Kong logs with your SIEM system:
# Enable TCP Log plugin for SIEM integration
$ curl -X POST http://localhost:8001/services/my-service/plugins \
--data "name=tcp-log" \
--data "config.host=siem-server" \
--data "config.port=5140"
Request and Response Transformation
Enhance security by transforming requests and responses:
# Remove sensitive headers from requests
$ curl -X POST http://localhost:8001/services/my-service/plugins \
--data "name=request-transformer" \
--data "config.remove.headers=Authorization,Cookie"
# Add security headers to responses
$ curl -X POST http://localhost:8001/services/my-service/plugins \
--data "name=response-transformer" \
--data "config.add.headers=Strict-Transport-Security:max-age=31536000; includeSubDomains,X-Content-Type-Options:nosniff,X-Frame-Options:DENY"
Advanced Security with Kong Enterprise
If you're using Kong Enterprise, additional security features are available:
OpenID Connect Integration
# Enable the OpenID Connect plugin
$ curl -X POST http://localhost:8001/services/my-service/plugins \
--data "name=openid-connect" \
--data "config.issuer=https://accounts.google.com/.well-known/openid-configuration" \
--data "config.client_id=YOUR_CLIENT_ID" \
--data "config.client_secret=YOUR_CLIENT_SECRET" \
--data "config.scopes=openid,email,profile" \
--data "config.verify_parameters=false"
Role-Based Access Control (RBAC)
# Create a role
$ curl -X POST http://localhost:8001/rbac/roles \
--data "name=read-only"
# Add permissions to the role
$ curl -X POST http://localhost:8001/rbac/roles/read-only/endpoints \
--data "endpoint=*" \
--data "actions=read"
# Assign the role to a user
$ curl -X POST http://localhost:8001/rbac/users \
--data "name=user123" \
--data "user=user123" \
--data "roles=read-only"
Common Pitfalls and How to Avoid Them
-
Exposing the Admin API: Always restrict access to the Admin API by binding it to localhost or using network controls.
-
Using Default Configurations: Kong's default configurations prioritize ease of use over security. Always customize settings with security in mind.
-
Overlooking Rate Limiting: Implement rate limiting for all services to prevent abuse.
-
Inadequate Monitoring: Set up comprehensive logging and monitor for unusual patterns or security incidents.
-
Neglecting Regular Updates: Keep Kong and its plugins updated to protect against known vulnerabilities.
Security Checklist for Kong Deployments
Use this checklist to ensure your Kong deployment follows security best practices:
- Admin API is secured and not publicly accessible
- HTTPS is enforced for all API traffic
- Authentication is enabled for all services
- Rate limiting is configured appropriately
- IP restrictions are applied where needed
- Logging and monitoring are properly set up
- Security headers are added to responses
- Kong and plugins are regularly updated
- Regular security audits are performed
- Sensitive data is not exposed in logs
Summary
Implementing these Kong security best practices helps protect your APIs from common threats while ensuring your services remain available and performant. Remember that security is an ongoing process that requires regular reviews and updates as your API infrastructure evolves.
By following these guidelines, you'll establish a solid security foundation for your Kong API Gateway deployment and build more secure, robust API services.
Additional Resources
Practice Exercises
- Set up a Kong gateway with JWT authentication and test it using
curl
commands. - Configure rate limiting with Redis and test how it behaves under high load.
- Create a security audit script that checks your Kong configuration for common misconfigurations.
- Implement request and response transformations to enhance the security of an existing API.
- Set up a comprehensive monitoring solution for your Kong deployment to detect potential security incidents.
If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)