diff --git a/modules/kamailio/config/kamailio.cfg b/modules/kamailio/config/kamailio.cfg index bc652675..005814fe 100644 --- a/modules/kamailio/config/kamailio.cfg +++ b/modules/kamailio/config/kamailio.cfg @@ -298,6 +298,11 @@ request_route { } $dlg_var(du) = $du; route(SET_TIMERS); + # Tag initial INVITE with the original source IP so downstream Asterisk + # can match IP-based trunks via "match header" on X-Forwarded-For. + if (is_method("INVITE") && !has_totag()) { + route(ADD_X_FORWARDED_FOR); + } route(RELAY); } else { # what could happen here ? @@ -788,13 +793,14 @@ route[SET_CDR_VARS] { } # end route[SET_CDR_VARS] # ----------------------------------------------------------------------------- -# route[ADD_X_REAL_IP] -# add header X-Forwarded-For +# route[ADD_X_FORWARDED_FOR] +# Add X-Forwarded-For header with the source IP so downstream Asterisk can +# match IP-based trunks even when the INVITE arrives from this proxy. # ----------------------------------------------------------------------------- -route[ADD_X_REAL_IP] { - remove_hf("X-Real-IP"); - insert_hf("X-Real-IP: $si \r\n"); -} # end route[ADD_X_REAL_IP] +route[ADD_X_FORWARDED_FOR] { + remove_hf("X-Forwarded-For"); + insert_hf("X-Forwarded-For: $si\r\n"); +} # end route[ADD_X_FORWARDED_FOR] # ----------------------------------------------------------------------------- # branch, onreply, failure Route definition @@ -1050,6 +1056,12 @@ route[HANDLE_ALIAS] { if ($rc == 1) { if ($shv(debug) == 1) xlog('L_WARN', "[DEV] - $ci $rm-$cs - handle_ruri_alias returned 1, doing RELAY \n"); route(SET_TIMERS); + # Same X-Forwarded-For tagging as the main inbound path: when the RURI + # carries an ;alias= param, HANDLE_ALIAS shortcuts to RELAY and skips + # the main flow, so we must add the header here too. + if (is_method("INVITE") && !has_totag()) { + route(ADD_X_FORWARDED_FOR); + } route(RELAY); } } # end of route[HANDLE_ALIAS] diff --git a/tests/02_kamailio_routing.robot b/tests/02_kamailio_routing.robot new file mode 100644 index 00000000..7985763c --- /dev/null +++ b/tests/02_kamailio_routing.robot @@ -0,0 +1,51 @@ +*** Settings *** +Library SSHLibrary + +*** Test Cases *** +Kamailio config defines ADD_X_FORWARDED_FOR route + [Documentation] The route that injects the X-Forwarded-For header on + ... inbound INVITEs must be defined in the runtime config. + ${output} ${rc} = Execute Command + ... runagent -m ${module_id} podman exec kamailio grep -c '^route\\[ADD_X_FORWARDED_FOR\\]' /etc/kamailio/kamailio.cfg + ... return_rc=True + Should Be Equal As Integers ${rc} 0 + Should Be Equal As Integers ${output} 1 + +Kamailio config inserts X-Forwarded-For with source IP + [Documentation] The route body must remove any existing header and + ... insert one carrying the source IP variable ($si). + ${output} ${rc} = Execute Command + ... runagent -m ${module_id} podman exec kamailio grep -E 'insert_hf\\(.*X-Forwarded-For:[[:space:]]*\\$si' /etc/kamailio/kamailio.cfg + ... return_rc=True + Should Be Equal As Integers ${rc} 0 + Should Contain ${output} X-Forwarded-For + +Kamailio main flow invokes ADD_X_FORWARDED_FOR on initial INVITE + [Documentation] The main inbound branch (direction=in) must call the + ... route guarded by is_method INVITE and !has_totag. + ${output} ${rc} = Execute Command + ... runagent -m ${module_id} podman exec kamailio grep -c 'route(ADD_X_FORWARDED_FOR)' /etc/kamailio/kamailio.cfg + ... return_rc=True + Should Be Equal As Integers ${rc} 0 + # Two call sites: main flow + HANDLE_ALIAS shortcut + Should Be True ${output} >= 2 + +Kamailio HANDLE_ALIAS shortcut also tags X-Forwarded-For + [Documentation] When handle_ruri_alias() shortcuts to RELAY, the + ... header tagging must still run, otherwise INVITEs with + ... an ;alias= param reach Asterisk without the header. + ${output} ${rc} = Execute Command + ... runagent -m ${module_id} podman exec kamailio awk '/^route\\[HANDLE_ALIAS\\]/,/^} # end of route\\[HANDLE_ALIAS\\]/' /etc/kamailio/kamailio.cfg + ... return_rc=True + Should Be Equal As Integers ${rc} 0 + Should Contain ${output} route(ADD_X_FORWARDED_FOR) + +Kamailio kamcmd reports the running config without parse errors + [Documentation] A loaded broken config would have prevented the + ... container from staying up; this asserts kamcmd still + ... answers, confirming the runtime accepted the cfg. + ${output} ${rc} = Execute Command + ... runagent -m ${module_id} podman exec kamailio kamcmd core.uptime + ... return_rc=True + Should Be Equal As Integers ${rc} 0 + Should Contain ${output} uptime