Default to nat=yes; warn when nat in general and peer differ

It is possible to enumerate SIP usernames when the general and user/peer
nat settings differ in whether to respond to the port a request is sent
from or the port listed for responses in the Via header. In 1.4 and 1.6.2,
this would mean if one setting was nat=yes or nat=route and the other was
either nat=no or nat=never. In 1.8 and 10, this would mean when one was
nat=force_rport and the other was nat=no.

In order to address this problem, it was decided to switch the default
behavior to nat=yes/force_rport as it is the most commonly used option
and to strongly discourage setting nat per-peer/user when at all possible.

For more discussion of the issue, please see:
  http://lists.digium.com/pipermail/asterisk-dev/2011-November/052191.html

(closes issue ASTERISK-18862)
Review: https://reviewboard.asterisk.org/r/1591/


git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.4@345776 65c4cc65-6c06-0410-ace0-fbb531ad65f3
1.4
Terry Wilson 14 years ago
parent 36b9cc1d49
commit 656d2e043a

@ -1,3 +1,11 @@
Changes since Asterisk 1.4.42
* Due to potential username discovery vulnerabilities, the 'nat' setting in sip.conf
now defaults to yes. It is very important that phones requiring nat=no be
specifically set as such instead of relying on the default setting. If at all
possible, all devices should have nat settings configured in the general section as
opposed to configuring nat per-device.
Changes since Asterisk 1.2:
* over 4,000 commits since 1.2

@ -18206,15 +18206,14 @@ static int handle_common_options(struct ast_flags *flags, struct ast_flags *mask
}
} else if (!strcasecmp(v->name, "nat")) {
ast_set_flag(&mask[0], SIP_NAT);
ast_clear_flag(&flags[0], SIP_NAT);
if (!strcasecmp(v->value, "never"))
ast_set_flag(&flags[0], SIP_NAT_NEVER);
else if (!strcasecmp(v->value, "route"))
ast_set_flag(&flags[0], SIP_NAT_ROUTE);
else if (ast_true(v->value))
ast_set_flag(&flags[0], SIP_NAT_ALWAYS);
else
ast_set_flag(&flags[0], SIP_NAT_RFC3581);
ast_set_flag(&flags[0], SIP_NAT_ALWAYS);
if (!strcasecmp(v->value, "never")) {
ast_set_flags_to(&flags[0], SIP_NAT, SIP_NAT_NEVER);
} else if (!strcasecmp(v->value, "route")) {
ast_set_flags_to(&flags[0], SIP_NAT, SIP_NAT_ROUTE);
} else if (ast_false(v->value)) {
ast_set_flags_to(&flags[0], SIP_NAT, SIP_NAT_RFC3581);
}
} else if (!strcasecmp(v->name, "canreinvite")) {
ast_set_flag(&mask[0], SIP_REINVITE);
ast_clear_flag(&flags[0], SIP_REINVITE);
@ -18956,6 +18955,18 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, str
return peer;
}
static void display_nat_warning(const char *cat, int reason, struct ast_flags *flags) {
int global_nat, specific_nat;
if (reason == CHANNEL_MODULE_LOAD && (specific_nat = ast_test_flag(&flags[0], SIP_NAT)) != (global_nat = ast_test_flag(&global_flags[0], SIP_NAT))) {
ast_log(LOG_WARNING, "!!! PLEASE NOTE: Setting 'nat' for a peer/user that differs from the global setting can make\n");
ast_log(LOG_WARNING, "!!! the name of that peer/user discoverable by an attacker. Replies for non-existent peers/users\n");
ast_log(LOG_WARNING, "!!! will be sent to a different port than replies for an existing peer/user. If at all possible,\n");
ast_log(LOG_WARNING, "!!! use the global 'nat' setting and do not set 'nat' per peer/user.\n");
ast_log(LOG_WARNING, "!!! (config category='%s' global='%s' peer/user='%s')\n", cat, nat2str(global_nat), nat2str(specific_nat));
}
}
/*! \brief Re-read SIP.conf config file
\note This function reloads all config data, except for
active peers (with registrations). They will only
@ -19095,9 +19106,10 @@ static int reload_config(enum channelreloadreason reason)
ast_copy_string(default_mohinterpret, DEFAULT_MOHINTERPRET, sizeof(default_mohinterpret));
ast_copy_string(default_mohsuggest, DEFAULT_MOHSUGGEST, sizeof(default_mohsuggest));
ast_copy_string(default_vmexten, DEFAULT_VMEXTEN, sizeof(default_vmexten));
ast_set_flag(&global_flags[0], SIP_DTMF_RFC2833); /*!< Default DTMF setting: RFC2833 */
ast_set_flag(&global_flags[0], SIP_NAT_RFC3581); /*!< NAT support if requested by device with rport */
ast_set_flag(&global_flags[0], SIP_CAN_REINVITE); /*!< Allow re-invites */
ast_set_flag(&global_flags[0], SIP_DTMF_RFC2833); /*!< Default DTMF setting: RFC2833 */
ast_set_flag(&global_flags[0], SIP_NAT_RFC3581); /*!< NAT support if requested by device with rport */
ast_set_flag(&global_flags[0], SIP_CAN_REINVITE); /*!< Allow re-invites */
ast_set_flag(&global_flags[0], SIP_NAT_ALWAYS); /*!< Default to nat=yes */
ast_set_flag(&global_flags[1], SIP_PAGE2_FORWARD_LOOP_DETECTED); /*!< Set up call forward on 482 Loop Detected */
/* Debugging settings, always default to off */
@ -19477,6 +19489,7 @@ static int reload_config(enum channelreloadreason reason)
if (is_user) {
user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0);
if (user) {
display_nat_warning(cat, reason, &user->flags[0]);
ASTOBJ_CONTAINER_LINK(&userl,user);
ASTOBJ_UNREF(user, sip_destroy_user);
user_count++;
@ -19485,6 +19498,9 @@ static int reload_config(enum channelreloadreason reason)
if (is_peer) {
peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0, 0);
if (peer) {
if (!is_user) {
display_nat_warning(cat, reason, &peer->flags[0]);
}
ASTOBJ_CONTAINER_LINK(&peerl,peer);
ASTOBJ_UNREF(peer, sip_destroy_peer);
peer_count++;
@ -19492,6 +19508,7 @@ static int reload_config(enum channelreloadreason reason)
}
}
}
if (ast_find_ourip(&__ourip, bindaddr)) {
ast_log(LOG_WARNING, "Unable to get own IP address, SIP disabled\n");
ast_config_destroy(cfg);

@ -354,12 +354,20 @@ srvlookup=yes ; Enable DNS SRV lookups on outbound calls
; firewall's support of SIP+RTP ports. You configure Asterisk choice of RTP
; ports for incoming audio in rtp.conf
;
;nat=no ; Global NAT settings (Affects all peers and users)
; yes = Always ignore info and assume NAT
;nat=yes ; Global NAT settings (Affects all peers and users)
; yes = Always ignore info and assume NAT (default)
; no = Use NAT mode only according to RFC3581 (;rport)
; never = Never attempt NAT mode or RFC3581 support
; route = Assume NAT, don't send rport
; (work around more UNIDEN bugs)
;
; IT IS IMPORTANT TO NOTE that if the nat setting in the general section differs from
; the nat setting in a peer definition, then the peer username will be discoverable
; by outside parties as Asterisk will respond to different ports for defined and
; undefined peers. For this reason it is recommended to ONLY DEFINE NAT SETTINGS IN THE
; GENERAL SECTION. Specifically, if nat=route or nat=yes in one section and nat=no or
; nat=never in the other, then valid users with settings differing from those in the
; general section will be discoverable.
;----------------------------------- MEDIA HANDLING --------------------------------
; By default, Asterisk tries to re-invite the audio to an optimal path. If there's
@ -627,7 +635,6 @@ srvlookup=yes ; Enable DNS SRV lookups on outbound calls
; on incoming calls to Asterisk
;host=192.168.0.23 ; we have a static but private IP address
; No registration allowed
;nat=no ; there is not NAT between phone and Asterisk
;canreinvite=yes ; allow RTP voice traffic to bypass Asterisk
;dtmfmode=info ; either RFC2833 or INFO for the BudgeTone
;call-limit=1 ; permit only 1 outgoing call and 1 incoming call at a time
@ -659,7 +666,6 @@ srvlookup=yes ; Enable DNS SRV lookups on outbound calls
;regexten=1234 ; When they register, create extension 1234
;callerid="Jane Smith" <5678>
;host=dynamic ; This device needs to register
;nat=yes ; X-Lite is behind a NAT router
;canreinvite=no ; Typically set to NO if behind NAT
;disallow=all
;allow=gsm ; GSM consumes far less bandwidth than ulaw
@ -725,9 +731,6 @@ srvlookup=yes ; Enable DNS SRV lookups on outbound calls
;type=friend
;secret=blah
;qualify=200 ; Qualify peer is no more than 200ms away
;nat=yes ; This phone may be natted
; Send SIP and RTP to the IP address that packet is
; received from instead of trusting SIP headers
;host=dynamic ; This device registers with us
;canreinvite=no ; Asterisk by default tries to redirect the
; RTP media stream (audio) to go directly from

Loading…
Cancel
Save