Skip to content

feat: Add NAT localnet support with custom ports 6060/6061#113

Merged
Amygos merged 11 commits into
mainfrom
157-under-nat-localnet
Feb 10, 2026
Merged

feat: Add NAT localnet support with custom ports 6060/6061#113
Amygos merged 11 commits into
mainfrom
157-under-nat-localnet

Conversation

@paolovisintin

@paolovisintin paolovisintin commented Dec 18, 2025

Copy link
Copy Markdown
Collaborator

This pull request introduces several improvements and bug fixes related to SIP port forwarding, firewall rules, and Kamailio configuration to better handle NAT scenarios and internal service network routing. The changes focus on more robust port forwarding management, expanded firewall port exposure, and enhanced Kamailio socket selection logic for both requests and replies, particularly when traffic is destined for internal networks or behind NAT.

Firewall and Port Forwarding Management:

  • Added dynamic creation and cleanup of rich firewall rules for SIP port forwarding (5060/5061 to 6060/6061) based on detected local networks in configure-module, with matching removal logic in destroy-module. This ensures correct port forwarding when the configuration changes or is destroyed. [1] [2]
  • Expanded public firewall exposure to include custom SIP ports (6060/6061 TCP/UDP) in addition to standard SIP/SIPS and RTP ports.

Kamailio Configuration and Routing:

  • Enhanced Kamailio bootstrap and config files to add listeners for ports 6060/6061 and to select the correct outbound socket (PRIVATE_IP:6060 or SERVICE_IP:5060) depending on whether traffic is destined for local networks or the internal service network (Asterisk). This improves NAT traversal and internal routing. [1] [2] [3] [4] [5] [6]
  • Ensured that ACKs and in-dialog NOTIFYs use the correct socket by invoking the new SET_SOCKET route in Kamailio config.

Update and Maintenance Scripts:

  • Added a new Python script to safely reapply configuration during module updates if the FQDN is valid, improving update reliability.
  • Removed an obsolete workaround script (90srv) from update-module.d, cleaning up the update process.
  • Modified restart logic to only restart relevant services (Postgres, Redis) instead of all SIP-related services, reducing unnecessary restarts.

Miscellaneous:

  • Updated .gitignore and .cursorindexingignore to exclude SpecStory project files and auto-saves, improving repo hygiene. [1] [2]
  • Updated image build labels to reflect new authorizations for portsadm.

NethServer/dev#7725

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds support for NAT configurations with custom ports 6060/6061 and introduces a LOCAL_SOURCE_SUBNETS feature to handle SIP clients from local subnets differently than external clients, avoiding the use of advertised public IP for internal clients.

Key changes:

  • Added custom TCP/UDP port 6060 and TLS port 6061 for SIP traffic
  • Implemented LOCAL_SOURCE_SUBNETS functionality to selectively use private IP for clients in specified local subnets
  • Added firewall rules, configuration validation, and comprehensive documentation

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
imageroot/actions/create-module/20firewall Opens custom ports 6060 (TCP/UDP) and 6061 (TCP) in firewall
modules/kamailio/bootstrap.sh Adds listen directives for custom ports 6060/6061 and initializes LOCAL_SOURCE_SUBNETS environment variable
modules/kamailio/config/kamailio.cfg Implements CHECK_LOCAL_SOURCE route to selectively use private IP for requests from configured local subnets
modules/kamailio/config/template.kamailio-local.cfg Adds LOCAL_SOURCE_SUBNETS configuration variable
imageroot/actions/configure-module/20configure Handles LOCAL_SOURCE_SUBNETS configuration from API input
imageroot/actions/get-configuration/20read Returns LOCAL_SOURCE_SUBNETS in configuration output
imageroot/actions/configure-module/validate-input.json Adds validation schema for local_source_subnets array with CIDR pattern
tests/10_actions/15_configure_local_source_subnets.robot Adds automated tests for LOCAL_SOURCE_SUBNETS configuration
examples/test-local-source-subnets.sh Provides test script for manual verification of LOCAL_SOURCE_SUBNETS
examples/configure-with-local-subnets.json Sample configuration with local_source_subnets
docs/LOCAL_SOURCE_SUBNETS.md Technical documentation for LOCAL_SOURCE_SUBNETS feature
README_LOCAL_SOURCE_SUBNETS_IT.md Italian user guide for LOCAL_SOURCE_SUBNETS
CHANGELOG.md Documents the new LOCAL_SOURCE_SUBNETS feature

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread imageroot/actions/get-configuration/20read Outdated
Comment thread README_LOCAL_SOURCE_SUBNETS_IT.md Outdated
Comment thread CHANGELOG.md Outdated
Comment thread modules/kamailio/bootstrap.sh
Comment thread modules/kamailio/bootstrap.sh Outdated
Comment thread modules/kamailio/bootstrap.sh Outdated
Comment thread imageroot/actions/configure-module/validate-input.json Outdated
Comment thread modules/kamailio/config/template.kamailio-local.cfg Outdated
Comment thread imageroot/actions/configure-module/20configure Outdated
@Amygos
Amygos force-pushed the 157-under-nat-localnet branch 2 times, most recently from 33786ee to 93fc0b7 Compare January 26, 2026 10:26
@Amygos
Amygos requested a review from Copilot January 27, 2026 07:57

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 8 out of 9 changed files in this pull request and generated 10 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread scripts/baresipCall.sh
Comment thread scripts/rsync.sh
Comment thread scripts/baresipCall.sh
Comment thread modules/kamailio/config/kamailio.cfg
Comment on lines +1071 to +1075
if ($du != $null && $du != 0 && $du != "") {
$var(destination_ip) = $(du{uri.host});
} else {
$var(destination_ip) = $(ru{uri.host}); # fetch the destination ip from ru
}

Copilot AI Jan 27, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new logic to extract destination_ip from $du when present (lines 1071-1075) is a good improvement. However, the comparison $du != 0 is checking if $du is the numeric value 0, which may not be meaningful for a URI string. Consider simplifying to just check $du != $null && $du != "" for clarity.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@paolovisintin What do you think about this?

Comment thread imageroot/actions/create-module/20firewall Outdated
Comment thread modules/kamailio/config/kamailio.cfg
Comment thread modules/kamailio/config/kamailio.cfg Outdated
Comment thread modules/kamailio/config/kamailio.cfg Outdated

Copilot AI commented Jan 29, 2026

Copy link
Copy Markdown
Contributor

@Amygos I've opened a new pull request, #129, to work on those changes. Once the pull request is ready, I'll request review from you.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 11 out of 12 changed files in this pull request and generated 5 comments.

Comments suppressed due to low confidence (1)

modules/kamailio/bootstrap.sh:46

  • When behind NAT, the script adds listeners for ports 6060/6061, but when not behind NAT (lines 40-46), these additional listeners are not added. This creates an inconsistency where the new ports are only available in NAT scenarios. Consider whether this is intentional or if the non-NAT case should also include these listeners.
else
    # now I have to add the listen with the public IP in the kamailio-local-additional.cfg
    echo "listen=udp:${PUBLIC_IP}:5060" > /tmp/kamailio-local-additional.cfg
    # doind the same for TCP
    echo "listen=tcp:${PUBLIC_IP}:5060" >> /tmp/kamailio-local-additional.cfg
    # doing the same for TLS
    echo "listen=tls:${PUBLIC_IP}:5061" >> /tmp/kamailio-local-additional.cfg

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread imageroot/actions/destroy-module/20firewall Outdated
Comment thread modules/kamailio/config/kamailio.cfg
Comment thread imageroot/actions/configure-module/20configure Outdated
Comment thread imageroot/actions/destroy-module/20firewall

Copilot AI commented Jan 29, 2026

Copy link
Copy Markdown
Contributor

@Amygos I've opened a new pull request, #130, to work on those changes. Once the pull request is ready, I'll request review from you.

Copilot AI commented Jan 29, 2026

Copy link
Copy Markdown
Contributor

@Amygos I've opened a new pull request, #131, to work on those changes. Once the pull request is ready, I'll request review from you.

Copilot AI commented Jan 29, 2026

Copy link
Copy Markdown
Contributor

@Amygos I've opened a new pull request, #132, to work on those changes. Once the pull request is ready, I'll request review from you.

Paolo and others added 8 commits January 29, 2026 16:14
Open custom ports:
  * 6060 udp/tcp: SIP
  * 6061 tcp: SIPS
Enable port 6060 and 6061 in the Kamailio bootstrap script.
Update SET_SOCKET route to handle LOCALNETWORKS and INTERNAL_NETWORK
more accurately. This forces PRIVATE_IP for LAN SIP traffic and uses
SERVICE_IP for service network destinations (e.g., Asterisk). Fixes NAT
connectivity issues for clients behind local subnets by ensuring
advertised address matches network scope.
Add a script for making SIP calls using the baresip application.
The script includes functions for printing banners, scenarios, usage,
steps, success messages, and information messages. It also includes
functions for starting the caller and callee, initiating the call,
displaying progress, and cleaning up after the call. The script
supports LAN, WAN reverse call scenarios.
Updated the rsync destination path in.sh script to correctly sync files
the specified directory on the server.
Added .cursorindexingignore to exclude SpecStory auto-save files from
indexing and allow explicit context inclusion via @ references. Also
added .specstory/.gitignore to ignore SpecStory project identity and
explanation files.
Wrap TT157 xlog statements in conditional debug checks to reduce
unnecessary log noise in production.
Introduce helper to generate IPv4 rich rules mapping SIP ports 5060/5061
to alternate targets when proxy is behind NAT. Ensure previous rules are
removed before applying updates, preventing stale firewall entries. Also
store multiple local networks in environment, improving flexibility for
multi-subnet deployments.
@Amygos
Amygos force-pushed the 157-under-nat-localnet branch from 0019e79 to 64e0fcb Compare January 30, 2026 10:43
Ensure any port forwarding rich rules created during module
configuration are cleaned up when destroying the module, but only in
scenarios where BEHIND_NAT is true and a public IP was present.
Introduce 40reconfigure step to reapply configuration when FQDN is
valid and not ending with ".invalid". This ensures smooth update
flows and allows modules to self-correct without manual intervention.

Remove restart logic for kamailio and rtpengine from 20restart, as
those services are no longer required to be restarted here.
Remove the obsolete 90srv workaround script, this step is now performed
by module reconfiguration.
Bump the org.nethserver.min-core label from 3.12.4-0 to 3.17.0-0 to
align container metadata with the required release for issue
NethServer/dev#7836.
@Amygos
Amygos force-pushed the 157-under-nat-localnet branch from 46f03b9 to 7e9f414 Compare February 10, 2026 11:12
@Amygos
Amygos merged commit ffa708d into main Feb 10, 2026
9 checks passed
@Amygos
Amygos deleted the 157-under-nat-localnet branch February 10, 2026 11:30
Amygos added a commit that referenced this pull request Feb 23, 2026
Describe the on-premise behind-NAT scenario introduced in PR #113
(NethServer/dev#7725): how Kamailio avoids hairpin NAT by advertising
the private IP in SDP for local clients via port-forwarding rules and
dedicated listeners on ports 6060/6061.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Amygos added a commit that referenced this pull request Mar 10, 2026
Describe the on-premise behind-NAT scenario introduced in PR #113
(NethServer/dev#7725): how Kamailio avoids hairpin NAT by advertising
the private IP in SDP for local clients via port-forwarding rules and
dedicated listeners on ports 6060/6061.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants