diff options
author | piso <piso@FreeBSD.org> | 2009-02-07 18:49:42 +0000 |
---|---|---|
committer | piso <piso@FreeBSD.org> | 2009-02-07 18:49:42 +0000 |
commit | d34fad29235ccc0edbe6d08993a47cfe168f59d9 (patch) | |
tree | b37eefe3826754719d7024fb68cb7d239167d799 /sbin/ipfw | |
parent | fabbde3ecefd44749fcd5f1c5d4349bda2c61c54 (diff) | |
parent | 8af3d78dd29ac07a9612994c5bdf8ea196ee5599 (diff) | |
download | FreeBSD-src-d34fad29235ccc0edbe6d08993a47cfe168f59d9.zip FreeBSD-src-d34fad29235ccc0edbe6d08993a47cfe168f59d9.tar.gz |
Add SCTP NAT support.
Submitted by: CAIA (http://caia.swin.edu.au)
Diffstat (limited to 'sbin/ipfw')
-rw-r--r-- | sbin/ipfw/ipfw.8 | 167 | ||||
-rw-r--r-- | sbin/ipfw/nat.c | 67 |
2 files changed, 218 insertions, 16 deletions
diff --git a/sbin/ipfw/ipfw.8 b/sbin/ipfw/ipfw.8 index 83ba7a4..997be62 100644 --- a/sbin/ipfw/ipfw.8 +++ b/sbin/ipfw/ipfw.8 @@ -2183,17 +2183,173 @@ Redirect and LSNAT support follow closely the syntax used in See Section .Sx EXAMPLES for some examples on how to do redirect and lsnat. +.Sh SCTP NAT SUPPORT +Sctp nat can be configured in a simillar manner to TCP through the +ipfw command line tool +.Xr ipfw 8 +, the main difference is that +.Nm sctp nat +does not do port +translation. Since the local and global side ports will be the same, +there is no need to specify both. Ports are redirected as follows: +.Bd -ragged -offset indent +.Bk -words +.Cm nat +.Ar nat_number +.Cm config if +.Ar nic +.Cm redirect_port sctp +.Ar ip_address [,addr_list] {[port | port-port] [,ports]} +.Ek +.Ed +.Pp +. +Most +.B sctp nat +configuration can be done in real-time through the +.B sysctl(8) +interface. All may be changed dynamically, though the hash_table size will only +change for new +.Nm nat +instances. See +.Sx SYSCTL VARIABLES +for more info. .Sh SYSCTL VARIABLES A set of .Xr sysctl 8 variables controls the behaviour of the firewall and associated modules -.Pq Nm dummynet , bridge . +.Pq Nm dummynet , bridge , sctp nat . These are shown below together with their default value (but always check with the .Xr sysctl 8 command what value is actually in use) and meaning: .Bl -tag -width indent +.It Va net.inet.ip.alias.sctp.accept_global_ootb_addip: No 0 +Defines how the +.Nm nat +responds to receipt of global OOTB ASCONF-AddIP: +.Bl -tag -width indent +.It Cm 0 +No response (unless a partially matching association exists - +ports and vtags match but global address does not) +.It Cm 1 +.Nm nat +will accept and process all OOTB global AddIP messages. +.El +.Pp +Option 1 should never be selected as this forms a security risk. An attacker can +establish multiple fake associations by sending AddIP messages. +.It Va net.inet.ip.alias.sctp.chunk_proc_limit: No 5 +Defines the maximum number of chunks in an SCTP packet that will be parsed for a +packet that matches an existing association. This value is enforced to be greater or equal +than +.Cm net.inet.ip.alias.sctp.initialising_chunk_proc_limit . +A high value is +a DoS risk yet setting too low a value may result in important control chunks in +the packet not being located and parsed. +.It Va net.inet.ip.alias.sctp.error_on_ootb: No 1 +Defines when the +.Nm nat +responds to any Out-of-the-Blue (OOTB) packets with ErrorM +packets. An OOTB packet is a packet that arrives with no existing association +registered in the +.Nm nat +and is not an INIT or ASCONF-AddIP packet: +.Bl -tag -width indent +.It Cm 0 +ErrorM is never sent in response to OOTB packets. +.It Cm 1 +ErrorM is only sent to OOTB packets received on the local side. +.It Cm 2 +ErrorM is sent to the local side and on the global side ONLY if there is a +partial match (ports and vtags match but the source global IP does not). This +value is only useful if the +.Nm nat +is tracking global IP addresses. +.It Cm 3 +ErrorM is sent in response to all OOTB packets on both the local and global side +(DoS risk). +.El +.Pp +At the moment the default is 0, since the ErrorM packet is not yet +supported by most SCTP stacks. When it is supported, and if not tracking +global addresses, we recommend setting this value to 1 to allow +multi-homed local hosts to function with the +.Nm nat . +To track global addresses, we recommend setting this value to 2 to +allow global hosts to be informed when they need to (re)send an +ASCONF-AddIP. Value 3 should never be chosen (except for debugging) as +the +.Nm nat +will respond to all OOTB global packets (a DoS risk). +.It Va net.inet.ip.alias.sctp.hashtable_size: No 2003 +Size of hash tables used for +.Nm nat +lookups (100 < prime_number > 1000001) +This value sets the +.Nm hash table +size for any future created +.Nm nat +instance and therefore must be set prior to creating a +.Nm nat +instance. +The table sizes my be changed to suit specific needs. If there will be few +concurrent associations, and memory is scarce, you may make these smaller. If +there will be many thousands (or millions) of concurrent associations, you +should make these larger. A prime number is best for the table size. The sysctl +update function will adjust your input value to the next highest prime number. +.It Va net.inet.ip.alias.sctp.holddown_time: No 0 +Hold association in table for this many seconds after receiving a +SHUTDOWN-COMPLETE. This allows endpoints to correct shutdown gracefully if a +shutdown_complete is lost and retransmissions are required. +.It Va net.inet.ip.alias.sctp.init_timer: No 15 +Timeout value while waiting for (INIT-ACK|AddIP-ACK). +This value cannot be 0. +.It Va net.inet.ip.alias.sctp.initialising_chunk_proc_limit: No 2 +Defines the maximum number of chunks in an SCTP packet that will be parsed when +no existing association exists that matches that packet. Ideally this packet +will only be an INIT or ASCONF-AddIP packet. A higher value may become a DoS +risk as malformed packets can consume processing resources. +.It Va net.inet.ip.alias.sctp.param_proc_limit: No 25 +Defines the maximum number of parameters within a chunk that will be parsed in a +packet. As for other similar sysctl variables, larger values pose a DoS risk. +.It Va net.inet.ip.alias.sctp.log_level: No 0 +Level of detail in the system log messages (0 \- minimal, 1 \- event, +2 \- info, 3 \- detail, 4 \- debug, 5 \- max debug). May be a good +option in high loss environments. +.It Va net.inet.ip.alias.sctp.shutdown_time: No 15 +Timeout value while waiting for SHUTDOWN-COMPLETE. +This value cannot be 0. +.It Va net.inet.ip.alias.sctp.track_global_addresses: No 0 +Enables/disables global IP address tracking within the +.Nm nat +and places an +upper limit on the number of addresses tracked for each association: +.Bl -tag -width indent +.It Cm 0 +Global tracking is disabled +.It Cm >1 +Enables tracking, the maximum number of addresses tracked for each +association is limited to this value +.El +.Pp +This variable is fully dynamic, the new value will be adopted for all newly +arriving associations, existing association are treated as they were previously. +Global tracking will decrease the number of collisions within the +.Nm nat +at a cost +of increased processing load, memory usage, complexity, and possible +.Nm nat +state +problems in complex networks with multiple +.Nm nats . +We recommend not tracking +global IP addresses, this will still result in a fully functional +.Nm nat . +.It Va net.inet.ip.alias.sctp.up_timer: No 300 +Timeout value to keep an association up with no traffic. +This value cannot be 0. .It Va net.inet.ip.dummynet.expire : No 1 Lazily delete dynamic pipes/queue once they have no pending traffic. You can disable this by setting the variable to 0, in which case @@ -2718,6 +2874,15 @@ as part of a Summer of Code 2005 project. Work on .Nm dummynet traffic shaper supported by Akamba Corp. +.Pp +Sctp +.Nm nat +support has been developed by +.An The Centre for Advanced Internet Architectures (CAIA) Aq http://www.caia.swin.edu.au . +The primary developers and maintainers are David Hayes and Jason But. +For further information visit: +.Aq http://www.caia.swin.edu.au/urp/SONATA +. .Sh BUGS The syntax has grown over the years and sometimes it might be confusing. Unfortunately, backward compatibility prevents cleaning up mistakes diff --git a/sbin/ipfw/nat.c b/sbin/ipfw/nat.c index da8896c..bfc325a 100644 --- a/sbin/ipfw/nat.c +++ b/sbin/ipfw/nat.c @@ -257,7 +257,9 @@ StrToProto (const char* str) if (!strcmp (str, "udp")) return IPPROTO_UDP; - errx (EX_DATAERR, "unknown protocol %s. Expected tcp or udp", str); + if (!strcmp (str, "sctp")) + return IPPROTO_SCTP; + errx (EX_DATAERR, "unknown protocol %s. Expected sctp, tcp or udp", str); } static int @@ -433,13 +435,27 @@ setup_redir_port(char *spool_buf, int len, strncpy(tmp_spool_buf, *av, strlen(*av)+1); lsnat = 1; } else { - if (StrToAddrAndPortRange (*av, &r->laddr, protoName, - &portRange) != 0) - errx(EX_DATAERR, "redirect_port:" - "invalid local port range"); + /* + * The sctp nat does not allow the port numbers to be mapped to + * new port numbers. Therefore, no ports are to be specified + * in the target port field. + */ + if (r->proto == IPPROTO_SCTP) { + if (strchr (*av, ':')) + errx(EX_DATAERR, "redirect_port:" + "port numbers do not change in sctp, so do not " + "specify them as part of the target"); + else + StrToAddr(*av, &r->laddr); + } else { + if (StrToAddrAndPortRange (*av, &r->laddr, protoName, + &portRange) != 0) + errx(EX_DATAERR, "redirect_port:" + "invalid local port range"); - r->lport = GETLOPORT(portRange); - numLocalPorts = GETNUMPORTS(portRange); + r->lport = GETLOPORT(portRange); + numLocalPorts = GETNUMPORTS(portRange); + } } INC_ARGCV(); @@ -463,6 +479,10 @@ setup_redir_port(char *spool_buf, int len, } r->pport = GETLOPORT(portRange); + if (r->proto == IPPROTO_SCTP) { /* so the logic below still works */ + numLocalPorts = GETNUMPORTS(portRange); + r->lport = r->pport; + } r->pport_cnt = GETNUMPORTS(portRange); INC_ARGCV(); @@ -518,14 +538,31 @@ setup_redir_port(char *spool_buf, int len, goto nospace; len -= SOF_SPOOL; space += SOF_SPOOL; - if (StrToAddrAndPortRange(sep, &tmp->addr, protoName, - &portRange) != 0) - errx(EX_DATAERR, "redirect_port:" - "invalid local port range"); - if (GETNUMPORTS(portRange) != 1) - errx(EX_DATAERR, "redirect_port: local port" - "must be single in this context"); - tmp->port = GETLOPORT(portRange); + /* + * The sctp nat does not allow the port numbers to be mapped to new port numbers + * Therefore, no ports are to be specified in the target port field + */ + if (r->proto == IPPROTO_SCTP) { + if (strchr (sep, ':')) { + errx(EX_DATAERR, "redirect_port:" + "port numbers do not change in " + "sctp, so do not specify them as " + "part of the target"); + } else { + StrToAddr(sep, &tmp->addr); + tmp->port = r->pport; + } + } else { + if (StrToAddrAndPortRange(sep, &tmp->addr, + protoName, &portRange) != 0) + errx(EX_DATAERR, "redirect_port:" + "invalid local port range"); + if (GETNUMPORTS(portRange) != 1) + errx(EX_DATAERR, "redirect_port: " + "local port must be single in " + "this context"); + tmp->port = GETLOPORT(portRange); + } r->spool_cnt++; /* Point to the next possible cfg_spool. */ spool_buf = &spool_buf[SOF_SPOOL]; |