Overview
IP filtering restricts access to Ant Media Server’s REST API and web dashboard based on the client’s IP address. This provides network-level security by allowing only trusted IP addresses or ranges to access administrative functions.
IPFilter Implementation
The IPFilter class (filter/IPFilter.java:18) controls access to REST API endpoints and the management dashboard.
How IP Filtering Works
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
HttpServletRequest httpRequest = (HttpServletRequest) request;
// Check if IP is allowed or internal cluster token is valid
if (isAllowed(request.getRemoteAddr()) ||
RestProxyFilter.isNodeCommunicationTokenValid(
httpRequest.getHeader("ClusterAuthorization"),
getAppSettings().getClusterCommunicationKey(),
httpRequest.getRequestURI()
)) {
chain.doFilter(request, response);
return;
}
// Deny access
response.sendError(HttpServletResponse.SC_FORBIDDEN, "Not allowed IP");
}
See filter/IPFilter.java:27-43 for the complete implementation.
Enabling IP Filtering
Via REST API
curl -X PUT "https://your-server/rest/v2/applications/settings/LiveApp" \
-H "Content-Type: application/json" \
-d '{
"ipFilterEnabled": true,
"allowedCIDRList": ["192.168.1.0/24", "10.0.0.0/8"]
}'
Via Configuration File
Edit the application settings:
<bean id="app.settings" class="io.antmedia.AppSettings">
<property name="ipFilterEnabled" value="true"/>
<property name="allowedCIDRList">
<list>
<value>192.168.1.0/24</value>
<value>10.0.0.0/8</value>
</list>
</property>
</bean>
CIDR Notation
IP filtering uses CIDR (Classless Inter-Domain Routing) notation to define IP ranges.
<IP Address>/<Prefix Length>
Examples:
192.168.1.0/24 - Allows 192.168.1.0 through 192.168.1.255 (256 addresses)
10.0.0.0/8 - Allows 10.0.0.0 through 10.255.255.255 (16,777,216 addresses)
172.16.0.0/12 - Allows 172.16.0.0 through 172.31.255.255 (1,048,576 addresses)
203.0.113.5/32 - Allows only 203.0.113.5 (single IP)
Common CIDR Ranges
| CIDR | IP Range | Number of IPs | Use Case |
|---|
| /32 | Single IP | 1 | Specific server |
| /24 | x.x.x.0 - x.x.x.255 | 256 | Local subnet |
| /16 | x.x.0.0 - x.x.255.255 | 65,536 | Large network |
| /8 | x.0.0.0 - x.255.255.255 | 16,777,216 | Class A network |
IP Validation Logic
The validation process (filter/IPFilter.java:51-65):
public boolean isAllowed(final String remoteIPAddress) {
AppSettings appSettings = getAppSettings();
boolean result = false;
if (appSettings != null) {
if (appSettings.isIpFilterEnabled()) {
result = checkCIDRList(appSettings.getAllowedCIDRList(), remoteIPAddress);
} else {
result = true; // Allow all if filtering is disabled
}
}
return result;
}
CIDR Matching Implementation
The checkCIDRList method from AbstractFilter (filter/AbstractFilter.java:66-94) handles CIDR validation:
public boolean checkCIDRList(Queue<NetMask> allowedCIDRList, final String remoteIPAddress) {
try {
String ipToCheck;
// Handle IPv4 format
if (InetAddresses.isInetAddress(remoteIPAddress)) {
ipToCheck = remoteIPAddress;
} else {
// Strip port number (e.g., Azure Application Gateway)
ipToCheck = remoteIPAddress.substring(0, remoteIPAddress.lastIndexOf(':'));
}
// Check against each CIDR range
InetAddress addr = InetAddress.getByName(ipToCheck);
for (final NetMask nm : allowedCIDRList) {
if (nm.matches(addr)) {
return true;
}
}
} catch (UnknownHostException e) {
logger.error("Error performing CIDR filtering for IP {}", remoteIPAddress, e);
}
return false;
}
Configuration Examples
Allow Single Office IP
{
"ipFilterEnabled": true,
"allowedCIDRList": ["203.0.113.50/32"]
}
Allow Local Network
{
"ipFilterEnabled": true,
"allowedCIDRList": ["192.168.0.0/16"]
}
Allow Multiple Networks
{
"ipFilterEnabled": true,
"allowedCIDRList": [
"192.168.1.0/24",
"10.0.0.0/8",
"172.16.0.0/12",
"203.0.113.100/32"
]
}
Allow Localhost and Private Networks
{
"ipFilterEnabled": true,
"allowedCIDRList": [
"127.0.0.1/32",
"192.168.0.0/16",
"10.0.0.0/8",
"172.16.0.0/12"
]
}
What Gets Filtered
Protected Resources
IP filtering applies to:
- REST API endpoints (
/rest/v2/*)
- Web management dashboard
- Administrative interfaces
Exceptions
- ACM Endpoints: Ant Certificate Manager endpoints are exempt:
if (request.getRequestURL().toString().contains("rest/v2/acm")) {
chain.doFilter(request, response); // Always allow
return;
}
- Cluster Communication: Internal cluster tokens bypass IP filtering:
RestProxyFilter.isNodeCommunicationTokenValid(
httpRequest.getHeader("ClusterAuthorization"),
getAppSettings().getClusterCommunicationKey(),
httpRequest.getRequestURI()
)
See filter/IPFilter.java:33-41 for exception handling.
Not Filtered
IP filtering does NOT apply to:
- Stream playback endpoints
- WebRTC publishing/playback
- HLS/DASH manifest requests
For stream-level access control, use Token-Based Access or JWT Authentication.
Cluster Mode Considerations
In cluster deployments:
Edge-Origin Communication
Edge nodes must communicate with origin nodes. Use cluster authorization tokens instead of adding all edge IPs to the CIDR list:
String clusterToken = httpRequest.getHeader("ClusterAuthorization");
boolean validClusterToken = RestProxyFilter.isNodeCommunicationTokenValid(
clusterToken,
appSettings.getClusterCommunicationKey(),
httpRequest.getRequestURI()
);
Configuration Strategy
- Option 1: Add all cluster node IPs to
allowedCIDRList
- Option 2: Use cluster communication keys and minimal CIDR list
- Recommended: Combine both for defense-in-depth
Load Balancer Considerations
When behind a load balancer or proxy, the remoteIPAddress may be the load balancer’s IP, not the client’s IP.
The filter handles some proxy scenarios:
// Strip port number suffix (e.g., Azure Application Gateway)
ipToCheck = remoteIPAddress.substring(0, remoteIPAddress.lastIndexOf(':'));
Trusting Proxies
If using a reverse proxy:
- Configure the proxy to set
X-Forwarded-For header
- Add the proxy’s IP to
allowedCIDRList
- Consider using application-level authentication in addition to IP filtering
Security Best Practices
Always use IP filtering in combination with authentication. IP addresses can be spoofed in some network configurations, so IP filtering should not be your only security mechanism.
Be careful with broad CIDR ranges like /8 or /16. These allow millions of IP addresses. Use the smallest range necessary for your use case.
When enabling IP filtering for the first time, ensure you include your own IP address in the allowed list. Otherwise, you may lock yourself out.
Document your CIDR configuration. Future administrators need to know which ranges are allowed and why.
Test IP filtering in a development environment before applying to production. Misconfiguration can block all access to your server.
Use Cases
Corporate Office Access
Allow only office network:
{
"ipFilterEnabled": true,
"allowedCIDRList": ["203.0.113.0/24"]
}
Multi-Office Deployment
Allow multiple office locations:
{
"ipFilterEnabled": true,
"allowedCIDRList": [
"203.0.113.0/24", // New York office
"198.51.100.0/24", // London office
"192.0.2.0/24" // Singapore office
]
}
Development Environment
Allow localhost and private networks:
{
"ipFilterEnabled": true,
"allowedCIDRList": [
"127.0.0.1/32",
"192.168.0.0/16",
"10.0.0.0/8"
]
}
VPN-Only Access
Allow only VPN network:
{
"ipFilterEnabled": true,
"allowedCIDRList": ["10.8.0.0/24"]
}
Monitoring and Logging
Failed access attempts are logged:
WARN [IPFilter] Access denied for IP: 198.51.100.5
Monitor logs for:
- Repeated access attempts from unauthorized IPs
- Patterns indicating port scanning or attacks
- Legitimate users being blocked (indicates CIDR misconfiguration)
Troubleshooting
Locked Out of Server
If you’ve locked yourself out:
- Access server via SSH
- Edit application settings file directly
- Disable IP filtering:
# Set ipFilterEnabled to false in settings
vi /usr/local/antmedia/webapps/LiveApp/WEB-INF/red5-web.properties
- Restart Ant Media Server
IP Not Matching CIDR
Check:
- Verify your actual IP:
curl ifconfig.me
- Check CIDR notation is correct
- Test CIDR match: Use online CIDR calculator
- Review server logs for attempted IP address
Load Balancer Issues
If behind a load balancer:
- Add load balancer IP to CIDR list
- Configure load balancer to preserve client IP
- Use application-level authentication as backup
Combining with Other Security
IP filtering works best when combined with:
JWT Authentication
# IP filtering + JWT for API access
curl -X GET "https://your-server/rest/v2/broadcasts" \
-H "Authorization: Bearer <jwt-token>"
Token-Based Access
# IP filtering on API + tokens on streams
curl -X POST "https://your-server/rest/v2/broadcasts/stream1/token"
SSL/TLS
# IP filtering + encrypted connections
https://your-server/rest/v2/broadcasts
Next Steps