diff --git a/base_trusted_proxies/README.rst b/base_trusted_proxies/README.rst new file mode 100644 index 00000000000..2f89a385606 --- /dev/null +++ b/base_trusted_proxies/README.rst @@ -0,0 +1,114 @@ +==================== +Base Trusted Proxies +==================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:b320b75a55c1d00f3e4e9fd14c94da5fd8839700e761376f26f3aebd45bd42db + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-LGPL--3-blue.png + :target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html + :alt: License: LGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fserver--tools-lightgray.png?logo=github + :target: https://github.com/OCA/server-tools/tree/18.0/base_trusted_proxies + :alt: OCA/server-tools +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/server-tools-18-0/server-tools-18-0-base_trusted_proxies + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/server-tools&target_branch=18.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +Allow configuration of the number of trusted proxies for accurate Client +IP detection. + +By default, Odoo’s http.ProxyFix is hardcoded to trust exactly one +proxy. In this configuration, Odoo assumes the rightmost IP in the +X-Forwarded-For header is the immediate proxy and the one preceding it +is the Client IP. + +However, in complex network topologies, the X-Forwarded-For list +contains multiple hops. If Odoo only trusts one hop when two or more +exist, it will incorrectly identify one of your internal proxies as the +"Client IP". + +This module allows you to configure the number of trusted proxies via an +environment variable, enabling Odoo to "peel back" the correct number of +layers to find the authentic Client IP. + +**Table of contents** + +.. contents:: + :local: + +Configuration +============= + +Adjust environment variable, for instance: ``ODOO_TRUSTED_PROXIES=2`` + +Then load ``base_trusted_proxies`` as a server wide module: + +- Using command line: + + - Start Odoo with ``--load=web,base_trusted_proxies --proxy-mode`` + +- Using the Odoo configuration file: + +.. code:: ini + + [options] + (...) + proxy_mode = True + server_wide_modules = web,base_trusted_proxies + +Known issues / Roadmap +====================== + +- Attention, setting ``ODOO_TRUSTED_PROXIES`` to a value higher than + the actual number of trusted proxies allows IP Spoofing. +- Add a special value reserved to mean that all the proxies are + trusted. + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +------- + +* ACSONE SA/NV + +Maintainers +----------- + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +This module is part of the `OCA/server-tools `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/base_trusted_proxies/__init__.py b/base_trusted_proxies/__init__.py new file mode 100644 index 00000000000..50b5c08f4c0 --- /dev/null +++ b/base_trusted_proxies/__init__.py @@ -0,0 +1 @@ +from .post_load import post_load diff --git a/base_trusted_proxies/__manifest__.py b/base_trusted_proxies/__manifest__.py new file mode 100644 index 00000000000..62aaac75f9d --- /dev/null +++ b/base_trusted_proxies/__manifest__.py @@ -0,0 +1,16 @@ +# Copyright 2026 ACSONE SA/NV () +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html). +{ + "name": "Base Trusted Proxies", + "summary": """ + Allow configuration of the number of trusted proxies + for accurate Client IP detection. + """, + "author": "ACSONE SA/NV, Odoo Community Association (OCA)", + "website": "https://github.com/OCA/server-tools", + "version": "18.0.1.0.0", + "license": "LGPL-3", + "depends": ["base"], + "data": [], + "post_load": "post_load", +} diff --git a/base_trusted_proxies/post_load.py b/base_trusted_proxies/post_load.py new file mode 100644 index 00000000000..bac035c3f89 --- /dev/null +++ b/base_trusted_proxies/post_load.py @@ -0,0 +1,44 @@ +# Copyright 2026 ACSONE SA/NV () +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html). + +import functools +import logging +import os + +from odoo import http, tools + +_logger = logging.getLogger(__name__) + + +def post_load(): + if tools.config["test_enable"]: + return + trusted_proxies_env_var = os.environ.get("ODOO_TRUSTED_PROXIES") + if not trusted_proxies_env_var: + _logger.warning( + "Missing configuration for module 'base_trusted_proxies': " + "'ODOO_TRUSTED_PROXIES' environment variable." + ) + return + if not trusted_proxies_env_var.isdigit(): + _logger.warning( + "'ODOO_TRUSTED_PROXIES' environment variable must be a positive integer." + ) + return + + trusted_proxies_nbr = int(trusted_proxies_env_var) + if trusted_proxies_nbr < 1: + _logger.warning( + "'ODOO_TRUSTED_PROXIES' environment variable must be a positive integer." + ) + return + + _logger.info( + f"Patch ProxyFix to trust {trusted_proxies_nbr} proxies in X-Forwarded-For." + ) + + from werkzeug.middleware.proxy_fix import ProxyFix as ProxyFix_ + + http.ProxyFix = functools.partial( + ProxyFix_, x_for=trusted_proxies_nbr, x_proto=1, x_host=1 + ) diff --git a/base_trusted_proxies/pyproject.toml b/base_trusted_proxies/pyproject.toml new file mode 100644 index 00000000000..4231d0cccb3 --- /dev/null +++ b/base_trusted_proxies/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/base_trusted_proxies/readme/CONFIGURE.md b/base_trusted_proxies/readme/CONFIGURE.md new file mode 100644 index 00000000000..e2ca25ca4d3 --- /dev/null +++ b/base_trusted_proxies/readme/CONFIGURE.md @@ -0,0 +1,15 @@ +Adjust environment variable, for instance: `ODOO_TRUSTED_PROXIES=2` + +Then load ``base_trusted_proxies`` as a server wide module: + +- Using command line: + - Start Odoo with `--load=web,base_trusted_proxies --proxy-mode` + +- Using the Odoo configuration file: + +``` ini +[options] +(...) +proxy_mode = True +server_wide_modules = web,base_trusted_proxies +``` diff --git a/base_trusted_proxies/readme/DESCRIPTION.md b/base_trusted_proxies/readme/DESCRIPTION.md new file mode 100644 index 00000000000..f9f79bb45f9 --- /dev/null +++ b/base_trusted_proxies/readme/DESCRIPTION.md @@ -0,0 +1,7 @@ +Allow configuration of the number of trusted proxies for accurate Client IP detection. + +By default, Odoo’s http.ProxyFix is hardcoded to trust exactly one proxy. In this configuration, Odoo assumes the rightmost IP in the X-Forwarded-For header is the immediate proxy and the one preceding it is the Client IP. + +However, in complex network topologies, the X-Forwarded-For list contains multiple hops. If Odoo only trusts one hop when two or more exist, it will incorrectly identify one of your internal proxies as the "Client IP". + +This module allows you to configure the number of trusted proxies via an environment variable, enabling Odoo to "peel back" the correct number of layers to find the authentic Client IP. \ No newline at end of file diff --git a/base_trusted_proxies/readme/ROADMAP.md b/base_trusted_proxies/readme/ROADMAP.md new file mode 100644 index 00000000000..f6e6355b20f --- /dev/null +++ b/base_trusted_proxies/readme/ROADMAP.md @@ -0,0 +1,2 @@ +- Attention, setting `ODOO_TRUSTED_PROXIES` to a value higher than the actual number of trusted proxies allows IP Spoofing. +- Add a special value reserved to mean that all the proxies are trusted. diff --git a/base_trusted_proxies/static/description/index.html b/base_trusted_proxies/static/description/index.html new file mode 100644 index 00000000000..131b220e2da --- /dev/null +++ b/base_trusted_proxies/static/description/index.html @@ -0,0 +1,457 @@ + + + + + +Base Trusted Proxies + + + +
+

Base Trusted Proxies

+ + +

Beta License: LGPL-3 OCA/server-tools Translate me on Weblate Try me on Runboat

+

Allow configuration of the number of trusted proxies for accurate Client +IP detection.

+

By default, Odoo’s http.ProxyFix is hardcoded to trust exactly one +proxy. In this configuration, Odoo assumes the rightmost IP in the +X-Forwarded-For header is the immediate proxy and the one preceding it +is the Client IP.

+

However, in complex network topologies, the X-Forwarded-For list +contains multiple hops. If Odoo only trusts one hop when two or more +exist, it will incorrectly identify one of your internal proxies as the +“Client IP”.

+

This module allows you to configure the number of trusted proxies via an +environment variable, enabling Odoo to “peel back” the correct number of +layers to find the authentic Client IP.

+

Table of contents

+ +
+

Configuration

+

Adjust environment variable, for instance: ODOO_TRUSTED_PROXIES=2

+

Then load base_trusted_proxies as a server wide module:

+
    +
  • Using command line:
      +
    • Start Odoo with --load=web,base_trusted_proxies --proxy-mode
    • +
    +
  • +
  • Using the Odoo configuration file:
  • +
+
+[options]
+(...)
+proxy_mode = True
+server_wide_modules = web,base_trusted_proxies
+
+
+
+

Known issues / Roadmap

+
    +
  • Attention, setting ODOO_TRUSTED_PROXIES to a value higher than +the actual number of trusted proxies allows IP Spoofing.
  • +
  • Add a special value reserved to mean that all the proxies are +trusted.
  • +
+
+
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +feedback.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • ACSONE SA/NV
  • +
+
+
+

Maintainers

+

This module is maintained by the OCA.

+ +Odoo Community Association + +

OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use.

+

This module is part of the OCA/server-tools project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ +