📄 nat-howto.txt
字号:
You can also indicate a specific protocol (`-p' or `--protocol'), such
as TCP or UDP; only packets of this protocol will match the rule. The
main reason for doing this is that specifying a protocol of tcp or udp
then allows extra options: specifically the `--source-port' and
`--destination-port' options (abbreviated as `--sport' and `--dport').
These options allow you to specify that only packets with a certain
source and destination port will match the rule. This is useful for
redirecting web requests (TCP port 80 or 8080) and leaving other
packets alone.
These options must follow the `-p' option (which has a side-effect of
loading the shared library extension for that protocol). You can use
port numbers, or a name from the /etc/services file.
All the different qualities you can select a packet by are detailed in
painful detail in the manual page (man iptables).
[1m6. Saying How To Mangle The Packets[0m
So now we know how to select the packets we want to mangle. To
complete our rule, we need to tell the kernel exactly what we want it
to do to the packets.
[1m6.1. Source NAT[0m
You want to do Source NAT; change the source address of connections to
something different. This is done in the POSTROUTING chain, just
before it is finally sent out; this is an important detail, since it
means that anything else on the Linux box itself (routing, packet
filtering) will see the packet unchanged. It also means that the `-o'
(outgoing interface) option can be used.
Source NAT is specified using `-j SNAT', and the `--to-source' option
specifies an IP address, a range of IP addresses, and an optional port
or range of ports (for UDP and TCP protocols only).
## Change source addresses to 1.2.3.4.
# iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to 1.2.3.4
## Change source addresses to 1.2.3.4, 1.2.3.5 or 1.2.3.6
# iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to 1.2.3.4-1.2.3.6
## Change source addresses to 1.2.3.4, ports 1-1023
# iptables -t nat -A POSTROUTING -p tcp -o eth0 -j SNAT --to 1.2.3.4:1-1023
[1m6.1.1. Masquerading[0m
There is a specialized case of Source NAT called masquerading: it
should only be used for dynamically-assigned IP addresses, such as
standard dialups (for static IP addresses, use SNAT above).
You don't need to put in the source address explicitly with
masquerading: it will use the source address of the interface the
packet is going out from. But more importantly, if the link goes
down, the connections (which are now lost anyway) are forgotten,
meaning fewer glitches when connection comes back up with a new IP
address.
## Masquerade everything out ppp0.
# iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE
[1m6.2. Destination NAT[0m
This is done in the PREROUTING chain, just as the packet comes in;
this means that anything else on the Linux box itself (routing, packet
filtering) will see the packet going to its `real' destination. It
also means that the `-i' (incoming interface) option can be used.
Destination NAT is specified using `-j DNAT', and the `--to-
destination' option specifies an IP address, a range of IP addresses,
and an optional port or range of ports (for UDP and TCP protocols
only).
## Change destination addresses to 5.6.7.8
# iptables -t nat -A PREROUTING -i eth0 -j DNAT --to 5.6.7.8
## Change destination addresses to 5.6.7.8, 5.6.7.9 or 5.6.7.10.
# iptables -t nat -A PREROUTING -i eth0 -j DNAT --to 5.6.7.8-5.6.7.10
## Change destination addresses of web traffic to 5.6.7.8, port 8080.
# iptables -t nat -A PREROUTING -p tcp --dport 80 -i eth0 \
-j DNAT --to 5.6.7.8:8080
[1m6.2.1. Redirection[0m
There is a specialized case of Destination NAT called redirection: it
is a simple convenience which is exactly equivalent to doing DNAT to
the address of the incoming interface.
## Send incoming port-80 web traffic to our squid (transparent) proxy
# iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 80 \
-j REDIRECT --to-port 3128
Note that squid needs to be configured to know it's a transparent
proxy!
[1m6.3. Mappings In Depth[0m
There are some subtleties to NAT which most people will never have to
deal with. They are documented here for the curious.
[1m6.3.1. Selection Of Multiple Addresses in a Range[0m
If a range of IP addresses is given, the IP address to use is chosen
based on the least currently used IP for connections the machine knows
about. This gives primitive load-balancing.
[1m6.3.2. Creating Null NAT Mappings[0m
You can use the `-j ACCEPT' target to let a connection through without
any NAT taking place.
[1m6.3.3. Standard NAT Behavior[0m
The default behavior is to alter the connection as little as possible,
within the constraints of the rule given by the user. This means we
won't remap ports unless we have to.
[1m6.3.4. Implicit Source Port Mapping[0m
Even when no NAT is requested for a connection, source port
translation may occur implicitly, if another connection has been
mapped over the new one. Consider the case of masquerading, which is
rather common:
1. A web connection is established by a box 192.1.1.1 from port 1024
to www.netscape.com port 80.
2. This is masqueraded by the masquerading box to use its source IP
address (1.2.3.4).
3. The masquerading box tries to make a web connection to
www.netscape.com port 80 from 1.2.3.4 (its external interface
address) port 1024.
4. The NAT code will alter the source port of the second connection to
1025, so that the two don't clash.
When this implicit source mapping occurs, ports are divided into three
classes:
o Ports below 512
o Ports between 512 and 1023
o Ports 1024 and above.
A port will never be implicitly mapped into a different class.
[1m6.3.5. What Happens When NAT Fails[0m
If there is no way to uniquely map a connection as the user requests,
it will be dropped. This also applies to packets which could not be
classified as part of any connection, because they are malformed, or
the box is out of memory, etc.
[1m6.3.6. Multiple Mappings, Overlap and Clashes[0m
You can have NAT rules which map packets onto the same range; the NAT
code is clever enough to avoid clashes. Hence having two rules which
map the source address 192.168.1.1 and 192.168.1.2 respectively onto
1.2.3.4 is fine.
Furthermore, you can map over real, used IP addresses, as long as
those addresses pass through the mapping box as well. So if you have
an assigned network (1.2.3.0/24), but have one internal network using
those addresses and one using the Private Internet Addresses
192.168.1.0/24, you can simply NAT the 192.168.1.0/24 source addresses
onto the 1.2.3.0 network, without fear of clashing:
# iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth1 \
-j SNAT --to 1.2.3.0/24
The same logic applies to addresses used by the NAT box itself: this
is how masquerading works (by sharing the interface address between
masqueraded packets and `real' packets coming from the box itself).
Moreover, you can map the same packets onto many different targets,
and they will be shared. For example, if you don't want to map
anything over 1.2.3.5, you could do:
# iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth1 \
-j SNAT --to 1.2.3.0-1.2.3.4 --to 1.2.3.6-1.2.3.254
[1m6.3.7. Altering the Destination of Locally-Generated Connections[0m
The NAT code allows you to insert DNAT rules in the OUTPUT chain, but
this is not fully supported in 2.4 (it can be, but it requires a new
configuration option, some testing, and a fair bit of coding, so
unless someone contracts Rusty to write it, I wouldn't expect it
soon).
The current limitation is that you can only change the destination to
the local machine (e.g. `j DNAT --to 127.0.0.1'), not to any other
machine, otherwise the replies won't be translated correctly.
[1m7. Special Protocols[0m
Some protocols do not like being NAT'ed. For each of these protocols,
two extensions must be written; one for the connection tracking of the
protocol, and one for the actual NAT.
Inside the netfilter distribution, there are currently modules for
ftp: ip_conntrack_ftp.o and ip_nat_ftp.o. If you insmod these into
your kernel (or you compile them in permanently), then doing any kind
of NAT on ftp connections should work. If you don't, then you can
only use passive ftp, and even that might not work reliably if you're
doing more than simple Source NAT.
[1m8. Caveats on NAT[0m
If you are doing NAT on a connection, all packets passing [1mboth [22mways
(in and out of the network) must pass through the NAT'ed box,
otherwise it won't work reliably. In particular, the connection
tracking code reassembles fragments, which means that not only will
connection tracking not be reliable, but your packets may not get
through at all, as fragments will be withheld.
[1m9. Source NAT and Routing[0m
If you are doing SNAT, you will want to make sure that every machine
the SNAT'ed packets goes to will send replies back to the NAT box.
For example, if you are mapping some outgoing packets onto the source
address 1.2.3.4, then the outside router must know that it is to send
reply packets (which will have [1mdestination [22m1.2.3.4) back to this box.
This can be done in the following ways:
1. If you are doing SNAT onto the box's own address (for which routing
and everything already works), you don't need to do anything.
2. If you are doing SNAT onto an unused address on the local LAN (for
example, you're mapping onto 1.2.3.99, a free IP on your 1.2.3.0/24
network), your NAT box will need to respond to ARP requests for
that address as well as its own: the easiest way to do this is
create an IP alias, e.g.:
# ip address add 1.2.3.99 dev eth0
3. If you are doing SNAT onto a completely different address, you will
have to ensure that the machines the SNAT packets will hit will
route this address back to the NAT box. This is already achieved
if the NAT box is their default gateway, otherwise you will need to
advertise a route (if running a routing protocol) or manually add
routes to each machine involved.
[1m10. Destination NAT Onto the Same Network[0m
If you are doing port forwarding back onto the same network, you need
to make sure that both future packets and reply packets pass through
the NAT box (so they can be altered). The NAT code will now (since
2.4.0-test6), block the outgoing ICMP redirect which is produced when
the NAT'ed packet heads out the same interface it came in on, but the
receiving server will still try to reply directly to the client (which
won't recognize the reply).
The classic case is that internal staff try to access your `public'
web server, which is actually DNAT'ed from the public address
(1.2.3.4) to an internal machine (192.168.1.1), like so:
# iptables -t nat -A PREROUTING -d 1.2.3.4 \
-p tcp --dport 80 -j DNAT --to 192.168.1.1
One way is to run an internal DNS server which knows the real
(internal) IP address of your public web site, and forward all other
requests to an external DNS server. This means that the logging on
your web server will show the internal IP addresses correctly.
The other way is to have the NAT box also map the source IP address to
its own for these connections, fooling the server into replying
through it. In this example, we would do the following (assuming the
internal IP address of the NAT box is 192.168.1.250):
# iptables -t nat -A POSTROUTING -d 192.168.1.1 -s 192.168.1.0/24 \
-p tcp --dport 80 -j SNAT --to 192.168.1.250
Because the [1mPREROUTING [22mrule gets run first, the packets will already
be destined for the internal web server: we can tell which ones are
internally sourced by the source IP addresses.
[1m11. Thanks[0m
Thanks first to WatchGuard, and David Bonn, who believed in the
netfilter idea enough to support me while I worked on it.
And to everyone else who put up with my ranting as I learnt about the
ugliness of NAT, especially those who read my diary.
Rusty.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -