In networking, incoming traffic refers to data packets arriving at your server from external sources, while outgoing traffic consists of packets leaving your server destined for other systems. For HTTP/HTTPS services, this translates to:
# Incoming: Port 80/443 traffic FROM clients TO your server
# Outgoing: Port 80/443 traffic FROM your server TO other systems
A standard web server primarily needs incoming ports 80/443 open to:
- Accept HTTP/HTTPS requests from browsers
- Receive API calls from client applications
- Handle file uploads through web forms
However, outgoing rules become necessary when your server needs to:
# Example: Server needs to make external API calls
curl -X GET https://api.example.com/data
# Or when acting as reverse proxy
ProxyPass /external http://other-service.com
For a basic web server using iptables
:
# Allow incoming HTTP/HTTPS
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# Allow outgoing responses (established connections)
iptables -A OUTPUT -p tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp --sport 443 -m state --state ESTABLISHED -j ACCEPT
# Allow new outgoing HTTP/HTTPS connections (if needed)
iptables -A OUTPUT -p tcp --dport 80 -j ACCEPT
iptables -A OUTPUT -p tcp --dport 443 -j ACCEPT
Security-conscious setups might block outgoing HTTP/HTTPS except to specific trusted destinations:
# Only allow outgoing HTTPS to payment processor
iptables -A OUTPUT -p tcp -d api.stripe.com --dport 443 -j ACCEPT
# Block all other outgoing web traffic
iptables -A OUTPUT -p tcp --dport 80 -j DROP
iptables -A OUTPUT -p tcp --dport 443 -j DROP
Some applications require both:
- Load balancers making health checks to backend servers
- Microservices architectures with bidirectional HTTP calls
- Webhook implementations where servers initiate connections
For a Node.js server making outbound API calls while serving web pages:
const express = require('express');
const axios = require('axios');
const app = express();
// Incoming traffic (normal web server)
app.get('/', (req, res) => {
// Outgoing traffic (API call)
axios.get('https://api.example.com/data')
.then(response => res.send(response.data));
});
app.listen(3000);
In network security, traffic direction is defined relative to your server:
- Incoming traffic (ingress): Packets arriving at your server's network interface
- Outgoing traffic (egress): Packets leaving your server's interface
A typical web request involves both directions:
Client (port 54321) → [INCOMING] Server:80 → Processing → [OUTGOING] Server:443 → Client
For a functional web server, you generally need:
# iptables example for HTTP/HTTPS
iptables -A INPUT -p tcp --dport 80 -j ACCEPT # Incoming HTTP
iptables -A INPUT -p tcp --dport 443 -j ACCEPT # Incoming HTTPS
iptables -A OUTPUT -p tcp --sport 80 -j ACCEPT # Outgoing HTTP responses
iptables -A OUTPUT -p tcp --sport 443 -j ACCEPT # Outgoing HTTPS responses
Security-conscious configurations might limit outbound traffic:
# Only allow outbound HTTP/HTTPS to specific IPs
iptables -A OUTPUT -p tcp --dport 80 -d 203.0.113.45 -j ACCEPT
iptables -A OUTPUT -p tcp --dport 443 -d 198.51.100.10 -j ACCEPT
iptables -A OUTPUT -p tcp --dport 80 -j DROP
iptables -A OUTPUT -p tcp --dport 443 -j DROP
Many admins don't realize that:
- Responses to client requests still count as outbound traffic
- Server-initiated API calls (e.g., webhooks) require outbound rules
- Port numbering conventions apply differently to each direction
Test your configuration with these commands:
# Check incoming connectivity
telnet yourserver.com 80
# Verify outbound requests
curl -v http://example.com
# Monitor active connections
netstat -tulnp