Walter Snel
2003-Oct-27 15:52 UTC
[Asterisk-Users] Asterisk behind nat with hole, hardcoding solution
Hi, A brief 6-step guide on how to hardcode a change in the Asterisk source that will allow it to work from behind a nat device. I know it?s messy, but it may prove useful to some people. 1. First punch a whole in your nat device. I just forwarded the port 5060 (for sip) and all ports between 10000 to 10020 (for rtp) to my asterisk gateway. 2. Now make sure your /etc/asterisk/rtp.conf correctly reflects the 'rtp' hole in the nat device (for me that's between 10000 and 10020). Now we need to make three small changes to the file /usr/src/asterisk/channels/chan_sip.c 3. First find the function build_contact( ) and insert your ?outside? ip address in the right position, as is indicated below (the original line is commented out): static void build_contact(struct sip_pvt *p) { /* Construct Contact: header */ if (ourport != 5060) snprintf(p->our_contact, sizeof(p->our_contact), "<sip:%s@%s:%d>", p->exten, inet_ntoa(p->ourip), ourport); else // snprintf(p->our_contact, sizeof(p->our_contact), "<sip:%s@%s>", p->exten, inet_ntoa(p->ourip)); snprintf(p->our_contact, sizeof(p->our_contact), "<sip:%s@213.84.4.39>", p->exten, inet_ntoa(p->ourip)); } 4. Now find the function add_sdp( ) and replace the variable strings with the ?outside? ip address (two times) as indicated below: snprintf(v, sizeof(v), "v=0\r\n"); // snprintf(o, sizeof(o), "o=root %d %d IN IP4 %s\r\n", getpid(), getpid(), inet_ntoa(dest.sin_addr)); snprintf(o, sizeof(o), "o=root %d %d IN IP4 213.84.4.39\r\n", getpid(), getpid()); snprintf(s, sizeof(s), "s=session\r\n"); // snprintf(c, sizeof(c), "c=IN IP4 %s\r\n", inet_ntoa(dest.sin_addr)); snprintf(c, sizeof(c), "c=IN IP4 213.84.4.39\r\n"); snprintf(t, sizeof(t), "t=0 0\r\n"); snprintf(m, sizeof(m), "m=audio %d RTP/AVP", ntohs(dest.sin_port)); snprintf(m2, sizeof(m2), "m=video %d RTP/AVP", ntohs(vdest.sin_port)); /* Start by sending our preferred codecs */ cur = prefs; 5. Perform a ?make? in this directory, and copy the resulting ?chan_sip.so? file to your /usr/lib/asterisk/modules/ directory. 6. Restart asterisk. It works for me (tested with xten softphone) This causes Asterisk to use the outside address in all sip connections, as a result Asterisk may become useless for sip phones on the 'inside' network. Naturally it would be much better to make this behavior: 1. Configurable. 2. Dependent on something like an ip addressfilter so that only connections for peers that are actually behind the nat (as indicated by a match with the filter) are 'redirected' to the outside address. With kind regards, Walter Snel