Objective
I want to block the database access URLs, like https://example.com/web/database/selector or https://example.com/web/database/manager, in an Odoo deployment for all outside traffic but a couple of specific IPs.
To avoid encouraging people sniffing around to go deeper with an Access Denied or Unauthorized Access message, I'd like to do so with a 404 Page not Found error message, and for that 404 to use Odoo's 404 Error Template and not Nginx Template.
Screenshot of the desired result
What I have tried and I'm aware of
I know the simplest way to deny will be adding a location block like this:
# Odoo Server #
upstream odoo {
server 127.0.0.1:8069;
}
# HTTP Web Server
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
# Block Database Manager/Selector Access via URL except for us
location ~* /web/database/* {
allow ###.###.###.###;
deny all;
proxy_pass http://odoo;
}
# Reverse Proxy Invocation for Odoo Server #
location / {
proxy_pass http://odoo;
}
This works perfectly except that it launches an Nginx Template 403 Forbidden message, and my objective is a 404 Page not Found error message, it also is not styled, formatted, or anything so it's also not the Odoo 404 Template.
I have also tried the following location block:
# Odoo Server #
upstream odoo {
server 127.0.0.1:8069;
}
# HTTP Web Server
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
# Block Database Manager/Selector Access via URL except for us
location ~* /web/database/* {
if ($remote_addr != ###.###.###.###) {
return 404;
proxy_pass http://odoo;
}
}
# Reverse Proxy Invocation for Odoo Server #
location / {
proxy_pass http://odoo;
}
This one will give me the 404 Page Not Found error message, however, it's the Nginx Template one, not Odoo's one, and the restriction doesn't work, I get the 404 Error even if the call comes from the IP ###.###.###.###.
However, if I change the !=
for a =
, and to test also change the return to 444, it does recognize the IP ###.###.###.### as I now get an 'ERR_EMPTY_RESPONSE' message.
I have read about using IF
inside a location block including the If is Evil article on nginx.com but it's supposed to work without issues on a return
action.
# Odoo Server #
upstream odoo {
server 127.0.0.1:8069;
}
# HTTP Web Server
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
# Block Database Manager/Selector Access via URL except for us
location ~* /web/database/* {
if ($remote_addr = ###.###.###.###) {
return 444;
proxy_pass http://odoo;
}
}
# Reverse Proxy Invocation for Odoo Server #
location / {
proxy_pass http://odoo;
}
What I have researched
It seems like this is achievable with a Rewrite instead by keeping it in the Web App and the URL used, I even found an example on how to achieve it on Apache, but all my attempts to try to understand it, or set it for Nginx have failed, it goes like this:
#Block database manager
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/web/database/manager [NC]
RewriteCond %{REMOTE_ADDR} !^##1\.###\.###\.###
RewriteCond %{REMOTE_ADDR} !^##2\.###\.###\.###
RewriteCond %{REMOTE_ADDR} !^##3\.###\.###\.###
RewriteRule ^ - [F]
#Block database selector
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/web/database/selector [NC]
RewriteCond %{REMOTE_ADDR} !^##1\.###\.###\.###
RewriteCond %{REMOTE_ADDR} !^##2\.###\.###\.###
RewriteCond %{REMOTE_ADDR} !^##3\.###\.###\.###
RewriteRule ^ - [F]
I also found this deployment that has what I want to implement, try this link
Current Nginx configuration file
This is my current Nginx Configuration File, everything is currently working including every feature of the app, but I do get the unwanted 403 Forbidden Access Nginx Template message when not coming from IP ###.###.###.###
I'm using Ubuntu 20.04, Odoo V15 and Nginx Version 1.22.0
# ============================================================================ #
# Web Server NGINX Configuration for Example.com #
# ============================================================================ #
# ============================================================================ #
# 1. Services #
# ============================================================================ #
# #
# Odoo Server #
upstream odoo {
server 127.0.0.1:8069;
}
# Longpolling Server (A must for Workers > 0 in the odoo.conf and for Chat) #
upstream longpolling {
server 127.0.0.1:8072;
}
# --------------------------------------------------------------- End Services #
# ============================================================================ #
# 2. HTTP Web Server #
# ============================================================================ #
# #
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
access_log /var/log/nginx/example.com.access.log;
error_log /var/log/nginx/example.com.error.log;
# Redirect to HTTPS #
location / {
return 301 https://example.com$request_uri;
}
}
# ------------------------------------------------------------ End HTTP Server #
# ============================================================================ #
# 3. HTTPS Web Server #
# ============================================================================ #
# #
server {
listen 443 ssl http2 default_server;
listen [::]:443;
server_name example.com www.example.com;
proxy_read_timeout 720s;
proxy_connect_timeout 720s;
access_log /var/log/nginx/example.com.ssl.access.log;
error_log /var/log/nginx/example.com.ssl.error.log;
# Certificate and Key Path #
ssl_certificate /path/to/chained.crt;
ssl_certificate_key /path/to/private.key;
# Proxy Performance Settings #
proxy_buffers 16 64k;
proxy_buffer_size 128k;
# Proxy Security Settings #
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Odoo-dbfilter "TEST";
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
# Block Database Manager/Selector Access via URL except for us
location ~* /web/database/* {
allow ###.###.###.###;
deny all;
proxy_pass http://odoo;
}
# Reverse Proxy Invocation for Odoo Server #
location / {
proxy_pass http://odoo;
}
# Reverse Proxy Invocation for Longpolling #
location /longpolling {
proxy_pass http://longpolling;
proxy_redirect off;
}
# Reverse Proxy Invocation for Web Assets #
location ~* /web/static/ {
proxy_cache_valid 200 60m;
proxy_buffering on;
expires 864000;
proxy_pass http://odoo;
}
# Reverse Proxy Invocation for Web Images #
location ~* /website/image/ir.attachment/ {
proxy_cache_valid 200 60m;
proxy_buffering on;
expires 864000;
proxy_pass http://odoo;
}
# Access to Common gzip files #
gzip_types text/css text/less text/plain text/xml application/xml application/json application/javascript;
gzip on;
}
# ####################### End NGINX Configuration File ####################### #
I also have a default.conf set to prevent access directly by the IP:
# ============================================================================ #
# Web Server NGINX Configuration for Defaukt #
# ============================================================================ #
# ============================================================================ #
# 1. HTTP and HTTPS Web Server to Block Access by IP #
# ============================================================================ #
# #
server {
listen 80 default_server;
listen [::]:80 default_server;
listen 443 ssl default_server;
listen [::]:443 default_server;
ssl_reject_handshake on;
server_name _;
return 444;
}
# ####################### End NGINX Configuration File ####################### #
I'll appreciate to be pointed in the right direction or told what am I missing or doing wrong.
Thanks.