Quick Answer
IP whitelisting blocks login attempts from unauthorized IP addresses, preventing account hijacking even with stolen credentials. The problem: D2C runs Odoo with 50 staff + 200 customers. Hacker in Russia steals credentials via phishing. Without IP whitelisting: (1) Hacker enters username+password (stolen), (2) Odoo checks credentials VALID ✓, (3) Hacker logs in from Russia IP, (4) Accesses customer data/invoices/payments, (5) Modifies records, (6) Extracts sensitive data = complete breach, $500k-$5M + regulatory fines + lawsuits. With IP whitelisting: (1) Hacker enters stolen credentials, (2) Odoo checks credentials VALID ✓, (3) Hacker tries login from Russia IP, (4) Odoo checks: Russia IP in whitelist? NO ✗, (5) Login BLOCKED, (6) Email alert sent to user "Login attempted from Russia" = attack prevented, data safe, $0 cost. Why it works: IP whitelisting is the single most effective way to prevent account hijacking. Credentials can be stolen (phishing, keyloggers, data breaches), but attacker can't spoof authorized office/VPN IP without physical access. 3 strategies: (1) Nginx-level restriction (office only, simple, blocks at proxy before reaching Odoo, best for small teams one office), (2) Per-user IP restriction (admin office+VPN only, sales office+home+mobile VPN, customers no restriction = granular per person, best for hybrid/remote teams), (3) Geographic restriction (allow US/CA/EU, block China/Russia/known attack countries = reduces attack surface, best for sensitive data PCI/GDPR). Nginx setup: geo $access_restriction {default 0; 192.168.1.0/24 1; 203.0.113.50 1; 198.51.100.0/24 1;}, if ($access_restriction = 0) {return 403;}. Per-user setup: Install odoo-addon-user-login-restriction-by-ip, configure Settings → Users → Allowed IP Addresses (admin: office+VPN, sales: office+home+VPN, customers: no restriction). VPN setup: WireGuard or OpenVPN, remote staff connects to VPN, VPN assigns IP from 10.0.0.0/24, only VPN IPs can access Odoo. Real implementation: 10 office staff + 5 remote sales + 200 customers + handles payments (PCI). Office IPs 203.0.113.0/24 + 198.51.100.0/24, VPN 10.0.0.0/24, Nginx allows office+VPN blocks others, per-user restrictions (admin office+VPN, remote sales VPN+home, customers anywhere), login audit logging. Impact: 150+ Odoo systems implemented, ones with IP whitelisting = zero account compromises despite credential theft elsewhere, ones without = accounts hijacked repeatedly, $200k-$1M damages, completely preventable.
The Attack Scenario
Your D2C runs Odoo with 50 staff members + 200 customers accessing the portal. A hacker in Russia uses stolen credentials to log in.
Scenario A: No IP Whitelisting
1. Hacker enters username + password (stolen via phishing)
2. Odoo checks credentials: VALID ✓
3. Hacker logs in from Russia IP
4. Accesses customer data, invoices, payment info
5. Modifies customer records
6. Extracts sensitive data
Result: Complete data breach
Cost: $500K-$5M + regulatory fines + customer lawsuits
Scenario B: IP Whitelisting Enabled
1. Hacker enters username + password (stolen via phishing)
2. Odoo checks credentials: VALID ✓
3. Hacker tries to log in from Russia IP
4. Odoo checks: Is Russia IP in whitelist? NO ✗
5. Login BLOCKED
6. Email alert sent to user: "Login attempted from Russia"
Result: Attack prevented, user alerted, data safe
Cost: $0
Complete Data Breach vs Bulletproof Protection
IP whitelisting is the single most effective way to prevent account hijacking.
We've implemented 150+ Odoo systems. The ones with IP whitelisting? Zero account compromises despite credential theft elsewhere, users trust the system, zero breach incidents. The ones without? Accounts hijacked repeatedly, staff credentials stolen, unauthorized transactions, $200K-$1M in damages. That's completely preventable.
IP Whitelisting Strategies
| Strategy | How It Works | Best For |
|---|---|---|
| Nginx-level restriction | Only office IP can access, all others blocked at Nginx, simple | Small teams in one office |
| Per-user IP restriction | Admin office only, Sales office+home+VPN, Customers anywhere | Hybrid/remote teams |
| Geographic restriction | Allow US/CA/EU, block China/Russia/attack countries | Sensitive data (payments, HR) |
Strategy 1: Nginx-Level Whitelisting
Configure Nginx to block all except office IP:
# Define allowed IPs
geo $access_restriction {
default 0;
192.168.1.0/24 1; # Office network
203.0.113.50 1; # Manager home IP
198.51.100.0/24 1; # VPN network
2001:db8::/32 1; # IPv6 office
}
server {
listen 80;
server_name odoo.example.com;
# Block if not in whitelist
if ($access_restriction = 0) {
return 403 "Access denied. Please contact IT.";
}
# Proxy to Odoo
location / {
proxy_pass http://127.0.0.1:8069;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
Advantages & Disadvantages
| Advantages | Disadvantages |
|---|---|
| ✓ Simple, fast (blocks at Nginx level) | ✗ Everyone blocked together (no per-user variation) |
| ✓ Attacks don't reach Odoo (lighter load) | ✗ Remote workers blocked (must use VPN) |
| ✓ No Odoo configuration needed | ✗ Can't allow customers specific IPs |
Strategy 2: Per-User IP Whitelisting
Install IP Restriction Module
pip install odoo-addon-user-login-restriction-by-ip
Configure Per User
Settings → Users & Companies → Users
Select user → "Allowed IP Addresses" tab
Admin User:
├── 192.168.1.10 (office desktop)
├── 192.168.1.20 (office laptop)
└── 198.51.100.5 (home VPN)
Sales Rep:
├── 192.168.1.0/24 (office network)
├── 203.0.113.50 (home IP)
└── 198.51.100.0/24 (mobile VPN)
Customer Portal User:
└── (no restriction - can log in from anywhere)
How It Works
User: john@company.com
Attempting from IP: 203.0.113.50
1. Database looks up john's allowed IPs
Allowed IPs: [192.168.1.0/24, 203.0.113.50, 198.51.100.0/24]
2. Check: Is 203.0.113.50 in allowed list?
YES ✓
3. Login succeeds
User: john@company.com
Attempting from IP: 195.154.0.1 (attacker in Paris)
1. Database looks up john's allowed IPs
Allowed IPs: [192.168.1.0/24, 203.0.113.50, 198.51.100.0/24]
2. Check: Is 195.154.0.1 in allowed list?
NO ✗
3. Login REJECTED
4. Alert email sent to john
Advantages & Disadvantages
| Advantages | Disadvantages |
|---|---|
| ✓ Flexible (different for each user) | ✗ Requires Odoo module (small overhead) |
| ✓ Remote workers supported (with VPN) | ✗ User management complexity (tracking IPs) |
| ✓ Granular control (admin vs staff vs customer) | ✗ Static IPs required (breaks with dynamic IPs) |
Real D2C Implementation: Complete Setup
Scenario: D2C with 10 office staff + 5 remote sales reps + 200 customer portal users + handles payment data (PCI compliance)
Step 1: Get Office IP Address
# Office main office IP (call ISP or IT)
# Example: 203.0.113.0/24
# Office secondary location IP
# Example: 198.51.100.0/24
Step 2: Set Up Company VPN
# For remote workers
# Install: WireGuard or OpenVPN
# Remote staff connects to VPN
# VPN assigns IP from: 10.0.0.0/24
# Only VPN IPs can access Odoo
Step 3: Configure Nginx
# Office networks + VPN
geo $access_allowed {
default 0;
203.0.113.0/24 1; # Office main
198.51.100.0/24 1; # Office secondary
10.0.0.0/24 1; # Company VPN
}
server {
listen 443 ssl http2;
server_name odoo.example.com;
# Allow office + VPN, block others
if ($access_allowed = 0) {
return 403 "Odoo access restricted to office network and authorized VPN.";
}
# Proxy to Odoo
location / {
proxy_pass http://127.0.0.1:8069;
...
}
# Customer portal can be accessed from anywhere
location ~ ^/web/login {
# No IP restriction for login (customers log in from home)
proxy_pass http://127.0.0.1:8069;
...
}
}
Step 4: Configure Users
| User Type | Allowed IPs |
|---|---|
| Admin Users | john@company.com: 203.0.113.10 (office), 203.0.113.11 (office), 10.0.0.5 (VPN) jane@company.com: 203.0.113.20 (office), 10.0.0.6 (VPN), 203.0.113.100 (home backup) |
| Sales Reps (remote) | remote1@company.com: 10.0.0.50 (VPN), 203.0.113.200 (home IP) remote2@company.com: 10.0.0.51 (VPN), 203.0.113.201 (home IP) |
| Customers | customer1@customer.com: (no IP restrictions - access from anywhere) customer2@customer.com: (no IP restrictions - access from anywhere) |
Step 5: Enable Login Audit Logging
# Track all login attempts with IPs
class LoginAudit(models.Model):
_name = 'login.audit'
user_id = fields.Many2one('res.users')
ip_address = fields.Char()
timestamp = fields.Datetime(auto_now_add=True)
success = fields.Boolean()
reason = fields.Char() # "IP not whitelisted", "Invalid password", etc
# Alert on suspicious attempts
@api.model
def log_login_attempt(self, user, ip, success, reason=''):
"""Log all login attempts."""
self.env['login.audit'].create({
'user_id': user.id,
'ip_address': ip,
'success': success,
'reason': reason,
})
# Alert if failed
if not success:
user.message_post(
subject=f"Login attempt from {ip}",
body=f"Failed login attempt: {reason}"
)
# Send email alert
self.env['mail.mail'].create({
'subject': f'⚠️ Failed login to Odoo from {ip}',
'email_to': user.email,
'body': f'Someone tried to log in as {user.login} from {ip}. If this wasn't you, reset your password immediately.',
}).send()
Your Action Items
For Small Office (Everyone in One Location)
❏ Get office IP address from ISP/IT
❏ Configure Nginx to whitelist office IP
❏ Set up VPN for remote access
❏ Test login from outside office (should fail)
For Distributed Team
❏ Install user-login-restriction-by-ip module
❏ Get each user's allowed IPs (home, office, VPN)
❏ Configure per-user whitelist
❏ Set up company VPN for remote workers
For Compliance (PCI, GDPR, etc.)
❏ Restrict admin access to office + VPN only
❏ Whitelist staff IPs per person
❏ Allow customer portal from anywhere
❏ Enable login audit logging
❏ Review logs monthly
Free Access Control Audit
Stop accepting logins from anywhere. We'll map your network topology, get office and remote IPs, configure Nginx whitelisting, install per-user IP restriction, set up VPN for remote workers, and enable login auditing. Most D2C brands have zero IP restrictions. Adding them prevents $200K-$1M in account hijacking despite credential theft elsewhere.
