OpenWISP 25.10

This release brings improvements to stability, security, scalability and usability.

Highlights

Key changes to stability and performance

  • Fixed performance issues in background tasks, VPN cache updates, and duplicated configuration synchronization.

  • Improved reliability of device communication with new connection retry logic.

  • Optimized monitoring threshold checks and reduced unnecessary alerts.

Key scalability changes

  • Improved handling of large datasets and asynchronous operations in RADIUS, controller, and monitoring modules.

  • Introduced automatic assignment of default templates to simplify the addition of new default/required templates.

Security and compatibility updates

  • Updated dependencies across all modules.

  • Added support for Django 5.x and Python 3.11–3.13.

  • Dropped support for Django 3.2, 4.1, and Python 3.8.

Key improvements to usability and features


Below you can find the detailed full change log for all the modules included in this release. Enjoy!

openwisp-users (v1.2)

Changes

Dependencies

  • Bumped django-organizations>=2.5.0,<2.6.0.

  • Bumped django-extensions>=3.2,<4.2.

  • Bumped django-allauth[socialaccount]>=65.12.0,<65.13.0.

  • Bumped django-phonenumber-field>=8.1.0,<8.2.0.

  • Bumped phonenumbers>=9.0.10,<9.1.0.

  • Bumped openwisp-utils[rest,celery]~=1.2.0.

  • Removed coveralls in favor of coverage package.

  • Added support for Django 5.x.

  • Dropped support for Django 3.2.0 and Django 4.1.0.

  • Added support for Python 3.11, 3.12, and 3.13.

  • Dropped support for Python 3.8.

openwisp-notifications (v1.2)

Features

Changes

Other changes

  • Improved UI of email notifications.

  • Disallowed changing preferences for generic_message notification type (#359).

  • Dropped dependency on django-notifications (#353).

  • Removed deprecated code for updating superuser notification settings (#283).

Dependencies

  • Bumped openwisp-users~=1.2.0.

  • Bumped openwisp-utils~=1.2.0.

  • Bumped markdown~=3.9.

  • Added support for Django 5.x.

  • Added support for Python 3.11, 3.12, and 3.13.

  • Dropped support for Django 3.2 and 4.1.

  • Dropped support for Python 3.8.

Bugfixes

  • Prevented notification toast from appearing while leaving a page (#264).

  • Ensured notification widget closes only on user-initiated clicks.

  • Fixed notification widget loading on non-admin pages (#271).

  • Allowed overriding openwisp_users app label in tests.

  • Hid notification preferences for disabled organizations (#366).

  • Fixed JavaScript logic for creating notification toasts.

  • Fixed issue with notification widget removing URL fragments.

openwisp-controller (v1.2)

Changes

Other changes

  • Stored configuration checksum in the database to fix the perennial modified status issue. The configuration status now changes to modified only when the checksum actually changes (#1113).

  • Templates marked as default or required are now automatically assigned to all eligible devices in a background task (#480).

  • Changed ZeroTier background notifications to use the Generic Message notification type (#1048).

  • Improved management of relevant templates: facilitated changing organizations and optimized performance (#204) (#1050).

  • Added relation from VpnClient objects to their associated Template. VpnClient objects are now automatically deleted when their template is deleted (#831).

  • Improved consistency across the REST API by renaming serializer modules to serializers, centralizing base serializer logic, fixing configuration creation when organization templates differ, and standardizing primary key parameter types and URL converters.

Dependencies

  • Bumped netjsonconfig~=1.2.0.

  • Bumped openwisp-notifications~=1.2.0.

  • Bumped openwisp-ipam~=1.2.0.

  • Bumped openwisp-users~=1.2.0.

  • Bumped openwisp-utils[celery,channels]~=1.2.0.

  • Bumped django-x509~=1.3.0.

  • Bumped django-loci~=1.2.0.

  • Bumped django-flat-json-widget~=0.4.0.

  • Bumped djangorestframework-gis~=1.2.0.

  • Bumped paramiko~=4.0.0.

  • Bumped django-cache-memoize~=0.2.1.

  • Bumped django-import-export~=4.3.10.

  • Bumped django-reversion~=6.0.0.

  • Bumped django-taggit~=6.1.0.

  • Added support for Django 5.x.

  • Added support for Python 3.11, 3.12, and 3.13.

  • Dropped support for Django 3.2 and 4.1.

  • Dropped support for Python 3.8.

Bugfixes

  • Fixed issue where the update_config background task could launch multiple times concurrently (#1128).

  • Enforced SSH command timeout in Paramiko. Previously, Paramiko ignored the configured command timeout.

  • Fixed incorrect label for device group filter in the device list (#1071).

  • Allow some unique fields to be NULL.

  • Fixed REST API access for non-superusers in DeviceConnection and Command endpoints. Previously, organization admins encountered a 500 server error when retrieving command details.

  • Avoided re-populating the VPN peers cache in post_save. Previously, VpnClient.post_save repopulated the peer cache immediately, causing slow or timed-out uWSGI requests for large peer sets. Now, it only invalidates the cache, which is later repopulated by the background task.

  • Fixed ordering of credentials in the REST API list view (#1040).

  • Fixed handling of non-existent devices in DeviceLocationView API.

  • Fixed unsaved changes alert showing for read-only maps (#560).

openwisp-monitoring (v1.2)

Features

  • Added logging for execution time of monitoring checks (#658).

  • Added WiFi Clients check to monitor AP load and inactivity.

Changes

Other changes

  • Updated netjsongraph.js to fix overlapping map clusters on the geo view.

  • Optimized logic for detecting when thresholds are crossed (#667).

  • Adjusted default alert tolerances to reduce unnecessary alert noise.

  • Added metric names to signal chart labels (#311).

  • Improved critical state evaluation (#566). Devices are now marked as critical only when all metrics defined in OPENWISP_MONITORING_CRITICAL_DEVICE_METRICS are unhealthy.

  • Recovery detection now triggers only for critical checks (#642).

Dependencies

  • Bumped openwisp-controller~=1.2.0.

  • Bumped django-nested-admin~=4.1.4.

  • Added support for Django 5.x.

  • Added support for Python 3.11, 3.12, and 3.13.

  • Dropped support for Django 3.2 and 4.1.

  • Dropped support for Python 3.8.

Bugfixes

  • Fixed issue where alerts were not sent for passive metrics (#670).

openwisp-firmware-upgrader (v1.2)

Features

  • Added device recognition mechanism (#165).

  • Allowed system-wide shared category (#204).

Changes

Other changes

  • Improved REST API for downloading firmware images (#69).

    Firmware downloads now use proper API URLs, respect user permissions, and avoid redundant permission checks.

Dependencies

  • Bumped openwisp-controller~=1.2.0.

  • Added support for Django 5.x.

  • Added support for Python 3.11, 3.12, and 3.13.

  • Dropped support for Django 3.2 and 4.1.

  • Dropped support for Python 3.8.

Bugfixes

  • Fixed firmware image deletion (#301).

    Firmware image files are now reliably removed from the filesystem when the corresponding FirmwareImage object is deleted.

openwisp-ipam (v1.2)

Changes

Dependencies

  • Bumped openwisp-users~=1.2.0.

  • Bumped openwisp-utils~=1.2.0.

  • Bumped django-reversion~=6.0.0.

  • Added support for Django 5.x.

  • Dropped support for Django 3.2.0 and Django 4.1.0.

  • Added support for Python 3.11, 3.12, and 3.13.

  • Dropped support for Python 3.8.

openwisp-network-topology (v1.2)

Changes

Dependencies

  • Bumped netdiff~=1.2.0.

  • Bumped openwisp-users~=1.2.0.

  • Bumped openwisp-utils~=1.2.0.

  • Bumped django-flat-json-widget~=0.4.0.

  • Added support for Django 5.x.

  • Added support for Python 3.11, 3.12, and 3.13.

  • Dropped support for Django 3.2 and 4.1.

  • Dropped support for Python 3.8.

openwisp-radius (v1.2)

Features

  • Added support for simultaneous-use (#615).

  • Added Called/Calling-Station-Id to the authorize API for improved Simultaneous-Use accuracy (#648).

  • Close stale sessions on Accounting-On requests (#617).

  • Added --number_of_hours option to cleanup_stale_radacct command.

Changes

Other changes

  • Large batch user creation operations are now executed asynchronously (#608).

  • Allowed counters to return multiple replies (#634).

  • Included RADIUS replies of the new group in Change of Authorization (CoA) requests (#643).

  • Added handling of MaxQuotaReached in CoA: users who exceed their limits now receive a Disconnect Message instead of a CoA Request (#643).

  • Refactored CoA logic to reuse counter and attribute handling from AuthorizeView._check_counters for improved maintainability (#643).

  • Allowed overriding configured RADIUS replies on MaxQuotaReached.

Dependencies

  • Bumped openwisp-users~=1.2.0.

  • Bumped openwisp-utils~=1.2.0.

  • Bumped weasyprint>=65,<67.

  • Bumped dj-rest-auth>=6.0,<7.1.

  • Bumped django-ipware>=5.0,<7.1.

  • Added support for Django 5.x.

  • Added support for Python 3.11, 3.12, and 3.13.

  • Dropped support for Django 3.2 and 4.1.

  • Dropped support for Python 3.8.

Bugfixes

  • Fixed timezone handling in delete_old_radiusbatch_users command (#611).

  • Fixed creation of RadiusGroup objects with related Group Checks or Group Replies from the admin (#604).

  • Fixed SMS message templates not being picked up by makemessages (#510).

openwisp-utils (v1.2)

Features

Changes

Backward-incompatible changes

  • Dropped support for OPENWISP_EMAIL_TEMPLATE setting (#482).

Other changes

  • Moved theme color definitions in CSS to variables (#487).

  • Standardized code style by switching to Prettier for CSS and JavaScript linting (#367).

  • Added line-length enforcement to prettier.

  • Unified Prettier checks into a single command; now includes YAML, Markdown, and JSON files.

  • Updated UI of HTML email templates.

  • Switched selenium browser tests to Firefox.

Dependencies

  • Bumped django-model-utils>=4.5,<5.1".

  • Bumped swapper~=1.4.0.

  • Bumped djangorestframework~=3.16.0.

  • Bumped celery~=5.5.3.

  • Bumped django-filter>=25.1,<26.0.

  • Bumped black>=25.1,<25.10.

  • Bumped flake8~=7.3.0.

  • Bumped isort~=6.0.1.

  • Bumped tblib~=3.1.0.

  • Bumped docstrfmt~=1.11.1.

  • Bumped selenium>=4.10,<4.36.

  • Added channels and channels-test extra requires (#388).

  • Removed coveralls in favor of coverage package.

  • Added support for Django 5.x.

  • Dropped support for Django 3.2.0 and Django 4.1.0.

  • Added support for Python 3.11, 3.12, and 3.13.

  • Dropped support for Python 3.8.

openwisp-wifi-login-pages (v1.2)

Features

  • Enabled synchronous captive portal authentication (#864).

  • Allowed swapping RADIUS accounting octets in the status page (#900).

  • Hid progress bar in the RADIUS usage component when the check value is zero.

  • Added Spanish translations for WiFi login pages.

  • Implemented daily log rotation (#46).

Changes

Other changes

  • Made warning message in status page customizable.

Dependencies
  • Bumped react==17.0.2.

  • Bumped react-cookie==8.0.1.

  • Bumped react-dom==17.0.2.

  • Bumped react-toastify==9.1.3.

  • Bumped axios==1.10.0.

  • Bumped compression==1.8.0.

  • Bumped express==5.1.0.

  • Bumped marked==16.3.0.

  • Bumped pretty-bytes==7.0.0.

  • Bumped regenerator-runtime==0.14.1.

  • Bumped universal-cookie-express==8.0.1.

  • Bumped winston-daily-rotate-file==5.0.0.

Bugfixes

  • Don’t render RADIUS usage in Internet mode.

  • Removed check for active session before performing captive portal login (#918).

  • Used calling_station_id instead of macaddr for MAC filtering (#914).

  • Server: consistently return NOT_FOUND message on 404 errors.

  • Displayed RADIUS usage in MB/GB (base 10) instead of MiB/GiB (base 2).

  • Made the plans modal scrollable in the status page.

  • Fixed upgrade button and limit exceeded message not rendering when users exceeded data usage on paid plans.

  • Don’t show Radius Usage if API does not return any check (#819)

openwisp-config (v1.2)

Features

  • Added hotplug script for management_interface to automatically update the management IP when the interface comes up (#208).

Changes

Other changes

  • Added random wait time between 5 and 20 seconds before retrying default tests after failure to reduce simultaneous retries and improve reliability.

  • Increased default test_retries to 10 for improved connection stability.

Bugfixes

  • Added IPv6 support to openwisp-get-address (#224).

openwrt-openwisp-monitoring (v0.3)

Bugfixes

  • Switch to portable df output (df -P) (#153).

  • Fixed issue where WiFi client data was sent even when no clients were connected.

  • Added check to ensure data file exists before sending to prevent errors (#102).

  • Ignored duplicate IP addresses in network configuration.

ansible-openwisp2 (v25.10)

Features

  • Made Daphne socket configurable.

  • Added Calling-Station-ID and Called-Station-ID attributes to the FreeRADIUS REST configuration (#548).

  • Added option to change the Celery execution pool.

  • Added support for restricting admin access to multiple subnets (#481) (#518).

  • Introduced new variable openwisp2_inventory_hostname_localhost.

Changes

  • Added default sqlite timeout (10 seconds).

Dependencies

  • Upgraded to OpenWISP Users 1.2.x (see change log).

  • Upgraded to OpenWISP Controller 1.2.x (see change log).

  • Upgraded to OpenWISP Monitoring 1.2.x (see change log).

  • Upgraded to OpenWISP Network Topology 1.2.x (see change log).

  • Upgraded to OpenWISP Firmware Upgrader 1.2.x (see change log).

  • Upgraded to OpenWISP RADIUS 1.2.x (see change log).

  • Upgraded to OpenWISP Notifications 1.2.x (see change log).

  • Upgraded to Netjsonconfig 1.2.x (see change log).

  • Bumped django-cors-headers>=4.9.0,<4.10.0

  • Bumped ansible-core>=2.15,<2.19.

  • Bumped channels_redis>=4.3.0,<4.4.0.

  • Bumped django-redis>=6.0.0,<6.1.0.

  • Bumped django-pipeline>=4.1.0,<4.2.0.

  • Bumped uwsgi>=2.0.30,<2.1.0.

  • Switched from django-celery-email to django-celery-email-reboot (#477).

  • Added support for Debian 13.

  • Dropped support for Ubuntu 20.04.

Bugfixes

  • Fixed Restart freeradius handler to properly restart the FreeRADIUS service instead of only ensuring it is running.

  • Ensured Django templates from OpenWISP extensions take precedence over those from other apps.

  • Moved OpenWISP version to a separate file to prevent circular imports.

docker-openwisp (v25.10)

Features

  • Added support for non-default external ports in the Nginx container (#496).

  • Updated FreeRADIUS REST module to include Calling-Station-ID and Called-Station-ID during authorization (#494).

  • Run collectstatic only when Python dependencies change (#246).

  • Added environment variables for configuring Redis (#463).

Changes

Dependencies

  • Upgraded to OpenWISP Users 1.2.x (see changelog).

  • Upgraded to OpenWISP Controller 1.2.x (see changelog).

  • Upgraded to OpenWISP Monitoring 1.2.x (see changelog).

  • Upgraded to OpenWISP Network Topology 1.2.x (see changelog).

  • Upgraded to OpenWISP Firmware Upgrader 1.2.x (see changelog).

  • Upgraded to OpenWISP RADIUS 1.2.x (see changelog).

  • Upgraded to OpenWISP Notifications 1.2.x (see changelog).

  • Upgraded to Netjsonconfig 1.2.x (see changelog).

  • Updated auto-install script to support Debian 13.

  • Updated auto-install script to support Ubuntu 24.04.

  • Updated base image of openwisp/openwisp-nginx to nginx:1.29.2-alpine.

  • Updated base image of openwisp/openwisp-freeradius to freeradius/freeradius-server:3.2.8-alpine.

  • Updated base image of openwisp/openwisp-postfix to alpine:3.22.

  • Updated base image of openwisp/openwisp-openvpn to kylemanna/openvpn:2.4.

  • Updated base image of openwisp/openwisp-dashboard, openwisp/openwisp-api, and openwisp/openwisp-websocket to python:3.13-slim-bullseye.

  • Bumped supervisor>=4.3.0,<4.4.0.

  • Bumped django-cors-headers>=4.9.0,<4.10.0.

  • Bumped django-pipeline>=4.1.0,<4.2.0.

  • Bumped uwsgi>=2.0.30,<2.1.0.

  • Bumped django-celery-email-reboot>=4.1.0,<5.0.0.

  • Bumped tldextract>=5.3.0,<5.4.0.

  • Bumped django-storages>=1.14.6,<1.15.0.

  • Bumped boto3>=1.40.49,<1.41.0.

Bugfixes

  • Fixed permissions issues in the Postfix container.

  • Fixed FreeRADIUS container exit caused by global write permissions.

  • Added error handling for Redis in load_init_data.py.

  • Updated Django URL patterns in the WebSocket container (#462).

  • Prevented creation of duplicate topology objects.

  • Fixed condition check in create_default_topology (#421).

  • Updated auto-install script to suggest the correct VPN hostname.