1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645
|
<html>
<head>
<link href="../lg.css" rel="stylesheet" type="text/css" media="screen, projection" />
<title>Firewalling with netfilter/iptables LG #103</title>
<style type="text/css" media="screen, projection">
<!--
.articlecontent {
position:absolute;
top:143px;
}
-->
</style>
</head>
<body>
<img src="../gx/2003/newlogo-blank-200-gold2.jpg" id="logo" alt="Linux Gazette"/>
<p id="fun">...making Linux just a little more fun!</p>
<div class="content articlecontent">
<div id="previousnexttop">
<A HREF="murray.html" ><-- prev</A> | <A HREF="seymour.html" >next --></A>
</div>
<h1>Firewalling with netfilter/iptables</h1>
<p id="by"><b>By <A HREF="../authors/odonovan.html">Barry O'Donovan</A></b></p>
<p>
<h3>Introduction</h3>
<p>
iptables is Linux's firewall which has been a part of the kernel since
version 2.4. It is often referred to as a <em>packet filter</em> as it
examines each packet transferred in every network connection to, from, and
within your computer. iptables replaced ipchains in the 2.4 kernel and
added many new features including <em>connection tracking</em> (also known
as stateful packet filtering). In this article we will use iptables to
build simple but effective firewalls for the following scenarios using
allow/disallow rules based on IP addresses, ports, and states:
<ol>
<li> a standard home computer;
<li> a home/small office network with a single Internet connection;
<li> port forwarding for a home/small office network.
</ol>
<h3>Rules, Targets, Chains, Tables, States, and all that jazz</h3>
<p>
iptables makes decisions on what to do with a packet based on
<em>rules</em> that the system administrator creates. Data is passed
through the Internet in the form of <em>packets of information</em>;
connecting from your computer to a website will cause many packets to be
exchanged in both directions. A rule specifies the criteria necessary for a
packet to match it. A decision is known as a <em>target</em> and it can be
a user-defined chain (not covered in this article) or one of the following:
<pre>
ACCEPT
Allow the packet through the firewall.
DROP
Drops the packet; the packet is not allowed through the firewall
and the sender of the packet is not notified. </pre>
There a number of other possible targets and we will cover some of these later.
<p>
Rules are grouped into <em>chains</em> which in turn are contained in
<em>tables</em>. There are three default tables which the packets may
traverse; we are only concerned with one of these right now: the
<code>filter</code> table. This is the default table and contains three
chains:
<pre>
OUTPUT
For packets generated by and leaving your computer; for example
when you connected to the Linux Gazette's web site your browser
created a packet and sent it out of your computer to the Gazette's
server.
INPUT
Any packets coming into your computer; for example the packets
containing the Gazette's web page sent back by its server to your
browser.
FORWARD
For packets being routed through your computer; for example
entering one network card and leaving through the other. We will
cover this in more detail later.
</pre>
<p>
The two other tables available by default are the <code>nat</code> table and the <code>mangle</code> table; we will use <code>nat</code> later for setting up a home network when only one network connection is available.
<p>
As I mentioned in the introduction, iptables is capable of stateful packet filtering. This means that we can create rules not only based on IPs and ports but also on whether a packet exists in any of the following states:
<pre>
NEW
The packet is trying to start a new connection; for example when
you first connected to the Linux Gazette website your browser
attempted to create a new connection with the Gazette's web server.
ESTABLISHED
A connection that has seen packets travel in both directions; once
the Gazette's web server replied to your browser the connection is
established.
RELATED
A packet that is starting a new connection but is related to an
existing connection. An example of this is downloading a file over
FTP. When you first connect to an FTP server you are creating a new
connection to its FTP port. However, when you download a file from
the FTP server using this connection a second new connection is
made between your computer and the FTP server for the file
download. Although it is a new connection it is related to the
first. This stateful packet filtering is useful as this new
connection does not use the FTP port and simple port based rules
are not appropriate for this.
INVALID
This packet is associated with no known connection. These packets
should be dropped.
</pre>
<h3>Creating and Storing Rules</h3>
<p>
Rules can be appended to the chains directly by using the <code>iptables</code> command. For example, to add a new rule to allow new connections to a web server running on your computer from anywhere we would execute the following:
<pre>
$ iptables -A INPUT -s 0/0 -d 1.2.3.4 -m state --state NEW -p tcp --dport 80 -i eth0 -j ACCEPT
</pre>
where:
<pre>
-s (or --src or --source) and -d (or --dst or --destination)
is the source and destination specification of the packet. It is
usually an IP address with an optional mask.
0/0 is shorthand for 0.0.0.0/0.0.0.0 meaning that the source can be <strong>any</strong> IP address.
1.2.3.4 is the IP our your machine and is equivalent to writing 1.2.3.4/32
or 1.2.3.4/255.255.255.255 meaning the destination must be <strong>this and only
this</strong> IP. Other examples include:
1.2.3.0/24
Any IP in the range 1.2.3.0 to 1.2.3.255 (256 possible IPs). Could also
have been written as 1.2.3.0/255.255.255.0
1.2.0.0/16
Any IP in the range 1.2.0.0 to 1.2.255.255 (65536 possible IPs). Could
also have been written as 1.2.0.0/255.255.0.0
! 1.2.3.0/24
The exclamation mark inverts the match so this will result is a
match if the IP is anything except one in the given range 1.2.3.0
to 1.2.3.255.
-m state --state NEW
matches only packets that have a status of NEW. This can be anyone
of or a comma separated list of the four possible states.
-p tcp
apply this rule to packets using the TCP protocol only. This can be
anyone of tcp, udp, icmp or all (default). The exclamation mark can
be used to invert the match.
--dport 80 (or --destination-port)
matches a packet trying to connect to port 80. The exclamation mark
can be used to invert this match also. A range of ports can be
given in the format begin:end.
-i eth0 (or --in-interface eth0)
name of an interface via which a packet is going to be received.
Possible interfaces on your computer can be found using the command
'ifconfig'. In this example your computer is connected to
the Internet through the first (or only) ethernet card.
-j ACCEPT
the target. In this case, if the incoming packet is creating a new
TCP connection from anywhere to port 80 on your computer through
the first ethernet card, we will allow it through.
</pre>
<p>
Note that in all of the following examples I am assuming that your computer is connected to the Internet through an ethernet card. Change <code>eth0</code> for <code>wifi0</code>, <code>ppp0</code>, etc., as appropriate for your computer. Furthermore I'm assuming that your computer's IP address is <code>1.2.3.4</code>.
<p>
Obviously we do not want to set up the firewall manually everytime we boot the computer. Most Linux distributions will give you the option of having these rules loaded automatically at boot from a file; in fact most distributions will come with a preconfigured firewall as standard. The location of this file will vary from distribution to distribution but it should be easily found by executing <code>locate iptables</code>'. For RedHat or Fedora Core users it can be found at <code>/etc/sysconfig/iptables</code>.
<p>
The essential elements of this file are:<br>
<em>(I have added the line numbers for explanation - they should not appear in a file intended for use with iptables):</em>
<pre>
1 # Firewall configuration
2 *filter
3 :INPUT <target> [0:0]
4 :FORWARD <target> [0:0]
5 :OUTPUT <target> [0:0]
6
7 # your rules here
8
9 COMMIT</pre>
<em>Listing 1 - The essential elements of an iptables file</em>
<p>
Line 2 of this file tells iptables that the following rules apply to the <code>filter</code> table. The next three lines (3-5) define the default targets for the three chains. We place our rules after these and before <code>COMMIT</code>, which does just that; commits our rules to the firewall.
<p>
Each packet traverses the rules of the appropriate chain from the first to the last. If a packet matches a rule then it stops traversing the chain at that rule and its fate is decided by that rule's target. If the packet does not match any rule then its fate is the default target of its chain.
<p>
I would recommend using the following skeleton configuration for all your firewalls:
<pre>
1 *filter
2 :INPUT DROP [0:0]
3 :FORWARD DROP [0:0]
4 :OUTPUT ACCEPT [0:0]
5
6 # allow local loopback connections
7 -A INPUT -i lo -j ACCEPT
8
9 # drop INVALID connections
10 -A INPUT -m state --state INVALID -j DROP
11 -A OUTPUT -m state --state INVALID -j DROP
12 -A FORWARD -m state --state INVALID -j DROP
13
14 # allow all established and related
15 -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
16
17 # add anymore rules here
18
19 COMMIT</pre>
<em><a href="/misc/odonovan/iptables-skel.txt">Listing 2</a> - Recommended skeleton configuration</em>
<p>
I've set the default target for the <code>INPUT</code> and <code>FORWARD</code> chains to <code>DROP</code>, while allowing all outgoing connections (lines 2-4). On a standard server or home computer we should not be routing any packets as standard (we will later and we will look at this in more detail then). Any outgoing connections will come from our computer and we can generally assume that they are not a security problem. In contrast, all incoming packets should be treated as a security risk unless we have explicitly allowed them.
<p>
Line 7 tells iptables to allow all connections originating from the local loopback network interface. This is used by many applications to connect to local services and you must permit these connections. Lines 10-12 drop all connections with a state of <code>INVALID</code>.
<p>
Line 15 should be self explanatory - it allows all incoming established or related connections through the firewall. For a connection to become established or related it must first have had a state of <code>NEW</code> <strong>and</strong> have been allowed though the firewall via a matching rule (had it not been allowed through it would have been dropped by default and could not result in an established or related connection).
<h3>Scenario 1: Standard Home Computer</h3>
<p>
For the standard user using his/her home computer for Internet browsing, e-mail, etc. then the above firewall is all that is needed as it allows all connections out while preventing any connections that are not related.
<p>
For a more paranoid user that wants to control and log all outgoing connections we might use a firewall configuration such as the following:
<pre>
1 *filter
2 :INPUT DROP [0:0]
3 :FORWARD DROP [0:0]
4 :OUTPUT DROP [0:0]
5
6 # allow local loopback connections
7 -A INPUT -i lo -j ACCEPT
8
9 # drop INVALID connections
10 -A INPUT -m state --state INVALID -j DROP
11 -A OUTPUT -m state --state INVALID -j DROP
12 -A FORWARD -m state --state INVALID -j DROP
13
14 # allow all established and related
15 -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
16 -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
17
18 # allow connections to my ISP's DNS servers
19 -A OUTPUT -d 2.3.4.10 -m state --state NEW -p udp --dport 53 -o eth0 -j ACCEPT
20 -A OUTPUT -d 2.3.4.11 -m state --state NEW -p udp --dport 53 -o eth0 -j ACCEPT
21
22 # allow outgoing connections to web servers
23 -A OUTPUT -d 0/0 -m state --state NEW -p tcp --dport http -o eth0 -j ACCEPT
24 -A OUTPUT -m state --state NEW -p tcp --dport https -o eth0 -j ACCEPT
25
26 # allow outgoing mail connections to my ISP's SMTP and POP3 server only
27 -A OUTPUT -d 2.3.4.5 -m state --state NEW -p tcp --dport smtp -o eth0 -j ACCEPT
28 -A OUTPUT -d 2.3.4.5 -m state --state NEW -p tcp --dport pop3 -o eth0 -j ACCEPT
29
30 # log all other attempted out going connections
31 -A OUTPUT -o eth0 -j LOG
32 # default is to DROP out-going connections
33
34 COMMIT</pre>
<em><a href="misc/odonovan/iptables-scen1a.txt">Listing 3</a> - Paranoid home user</em>
<p>
This configuration <strong>denies all connections</strong> by default and only allows those we explicitly define rules for. Line 16 adds a second rule based on the established or related rules for outgoing connections. Just as with line 15, this is necessary as the default rule of the <code>OUTPUT</code> chain is <code>DROP</code>. Also note that when we specifying the interface for the <code>OUTPUT</code> chain rules we use <code>-o</code> (or <code>--out-interface</code>) as opposed to <code>-i</code>.
<p>
The first rules we have added (lines 19 and 20) are to allow outgoing connections to your ISP's DNS server; I am assuming your ISP has a primary and a secondary DNS server with IPs <code>2.3.4.10</code> and <code>2.3.4.11</code> respectively. These connections are essential so your computer can convert a domain name (such as www.linuxgazette.net) into its IP address; without that conversion we would not be able to connect to the website. DNS lookups are usually done via the UDP protocol. Unless you are doing anything out of the ordinary this should be sufficient.
<p>
The next two rules (lines 23 and 24) allow your Internet browser to connect to any website using both the normal and the encrypted protocols. You'll notice that I have used http and https to specify the ports here instead of 80 and 443. This makes the rules more readable and you can substitute the service name for any port so long as it appears in the file <code>/etc/services</code>. You should also notice that in the second rule I omitted the destination IP mask; this is equivalent to writing 'match any destination IP' (<code>-d 0/0</code>). Lastly, I could have turned these two rules into one using:<br>
<code>-A OUTPUT -m state --state NEW -p tcp -m multiport --dport http,https -o eth0 -j ACCEPT</code>
<p>
Another standard operation that a home computer would be used for is e-mailing. E-mailing requires two services: SMTP to send mail and POP3 (or IMAP in some cases) to receive mail. I have added a rule for each of these (lines 27 and 28) where I am assuming that your ISP uses the same server for both (<code>2.3.4.5</code>). In most cases your ISP will not give you the IPs of its mail servers, but instead their domain names; e.g. <code>mail.my-isp.com</code>. We can rewrite these rules using this as follows:<br>
<code>-A OUTPUT -d mail.my-isp.com -m state --state NEW -p tcp --dport smtp -o eth0 -j ACCEPT<br>
-A OUTPUT -d mail.my-isp.com -m state --state NEW -p tcp --dport pop3 -o eth0 -j ACCEPT</code><br>
It is generally a better idea to use IPs wherever possible.
<p>
The final rule has a target we have not come across yet: the <code>LOG</code> target. This logs the details of a matching packet. You can review the log with the <code>dmesg</code> command or via <code>syslogd</code>. Some distributions have a utility called <code>logwatch</code> which will format these reports into an e-mail sent to the root account. The <code>LOG</code> target is a <strong>non-terminating target</strong>; the packet will continue traversing the chain. So in the above example we log all outgoing packets that have not matched one of the rules, that packet continues traversing the chain and as there are no other rules, the default target for the <code>OUTPUT</code> chain is used (<code>DROP</code>).
<p>
If you use any other services, such as Jabber, IRC, file sharing clients, etc., you will have to add rules for these also. Just follow the above example. If you don't know what ports to open and you can't find it in <code>/etc/services</code>, then add a logging rule at the beginning of the rules, e.g.<br>
<code>-A OUTPUT -i eth0 -j LOG<br></code>
and examine the output of the command <code>dmesg</code> (look for the destination port, <code>DPT=???</code>). I also feel I should mention that filtering the <code>OUTPUT</code> chain in this manner can be quite problematic; you might find some programs hanging or freezing while they try and establish connections you never thought of allowing, or using the UDP protocol instead of the TCP, etc. Unless you really want or need to lock the <code>OUTPUT</code> chain down, it might be just as easy to set the default rule to <code>ACCEPT</code> and then block the outgoing connections on a case by case basis.
<p>
<h3>Scenario 2: Home Network with a Single Connection</h3>
<p>
Most home users and small offices connect to the Internet via a single dial-up, ISDN or broadband (DSL) connection. This scenario covers the problem: 'I only have a single network connection, but I would like all my computers to have Internet access. How is this possible?' The examples in this scenario will enable you to set up a home or office network using your networked computer as a gateway for your other computers.
<p>
<img src="misc/odonovan/iptables-scen2.png" alt="Home Network - Scenario 2" width="352" height="241" align="top" border="0"><br>
<em>Figure 1 - Author's Home Network</em>
<p>
My own situation is depicted in <em>Figure 1</em>; I have a single broadband connection with a static IP address (<code>1.2.3.4</code>) connected to <code>eth0</code>. My second ethernet card (<code>eth1</code>) is a wireless PCI card. In my home there are two laptops, each also with wireless cards built in.
<p>
<p>
The first issue is that every computer on the Internet needs to be <strong>uniquely</strong> identifiable by an IP address. Irrespective of whether you have a dial-up or a broadband connection, you will only have been assigned one IP address. This can either be static (some broadband ISPs will allocate you a single IP that will not change) or dynamic (you will be assigned different IPs every time you reconnect to the network). When you send out a packet it includes the destination address and the source address. Although we can send a packet with any source address, only replies to ones with your source address will return to you.
<p>
Now we must assign an IP to every network interface on the network. In the case of <code>eth0</code>, it was assigned by my ISP. But what IPs will we give the wireless interface and the laptops? <a href="http://www.icann.org">ICANN</a> (Internet Corporation For Assigned Names and Numbers) has assigned certain blocks of IPs for use in private networks. One of these blocks is given by the IP mask <code>192.168.0.0/255.255.0.0</code>. Which IPs of this set you choose to use is entirely up to you. As you can see from <em>Figure 1</em>, I have assigned <code>192.168.0.1</code> to my wireless PCI card, and <code>192.168.0.2</code> and <code>192.168.0.3</code> to the laptops.
<p>
The <code>nat</code> (network address translation) table of iptables allows us to use one IP address for many different computers and works as follows: if the first laptop tries to connect to a website it sends a packet with the source address of <code>192.168.0.2</code> to <code>eth1</code> of the networked computer. The networked computer will then forward this packet from <code>eth1</code> to <code>eth0</code>. Just before the packet is transmitted, the <code>nat</code> table will change the source address from <code>192.168.0.2</code> to <code>1.2.3.4</code>. iptables will automatically <em>remember</em> that it did this and when the reply packets arrive with a destination of <code>1.2.3.4</code> and change it to <code>192.168.0.2</code>, routing it through <code>eth1</code> to the laptop.
<p>
Let's begin with the firewall configuration:
<pre>
1 *filter
2 :INPUT DROP [0:0]
3 :FORWARD DROP [0:0]
4 :OUTPUT DROP [0:0]
5
6 # allow local loopback connections
7 -A INPUT -i lo -j ACCEPT
8
9 # drop INVALID connections
10 -A INPUT -m state --state INVALID -j DROP
11 -A OUTPUT -m state --state INVALID -j DROP
12 -A FORWARD -m state --state INVALID -j DROP
13
14 # allow all established and related
15 -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
16 -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
17 -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
18
19 # allow connections to my ISP's DNS servers
20 -A OUTPUT -d 2.3.4.10 -m state --state NEW -p udp --dport 53 -o eth0 -j ACCEPT
21 -A OUTPUT -d 2.3.4.11 -m state --state NEW -p udp --dport 53 -o eth0 -j ACCEPT
22 -A FORWARD -d 2.3.4.10 -m state --state NEW -p udp --dport 53 -i eth1 -o eth0 -j ACCEPT
23 -A FORWARD -d 2.3.4.11 -m state --state NEW -p udp --dport 53 -i eth1 -o eth0 -j ACCEPT
24
25 # allow outgoing connections to web servers
26 -A OUTPUT -d 0/0 -m state --state NEW -p tcp -m multiport --dport http,https -o eth0 -j ACCEPT
27 -A FORWARD -d 0/0 -m state --state NEW -p tcp -m multiport --dport http,https -o eth0 \
-i eth1 -j ACCEPT
28
29 # allow outgoing mail connections to my ISP's SMTP and POP3 server only
30 -A OUTPUT -d mail.my-isp.com -m state --state NEW -p tcp -m multiport --dport smtp,pop3 \
-o eth0 -j ACCEPT
31 -A FORWARD -d mail.my-isp.com -m state --state NEW -p tcp -m multiport --dport smtp,pop3 \
-o eth0 -j ACCEPT
32
33 # log all other attempted out going connections
34 -A OUTPUT -o eth0 -j LOG
35 -A FORWARD -j LOG
36 # default is to DROP out-going connections
37
38 COMMIT
39
40 *nat
41
42 # set up IP forwarding and nat
43 -A POSTROUTING -o eth0 -j SNAT --to 1.2.3.4
44
45 COMMIT</pre>
<em><a href="misc/odonovan/iptables-scen2.txt">Listing 4</a> - Home/office network with NAT</em>
<p>
As well as demonstrating NAT, this example also introduces the use of the <code>FORWARD</code> chain. The networked computer is now also working as a router; as well an nat-ing the packets from the laptops, it is also routing them from <code>eth1</code> to <code>eth0</code> and vice-versa. As such we have adding another <code>ESTABLISHED,RELATED</code> rule on line 17, this time for the <CODE>FORWARD</CODE> chain.
<p>
Similarly, on lines 22,23,27,31, and 35, I have added in lines to allow the same connections we were allowing previously to come from the <code>FORWARD</code> chain. However, there is one big security risk here: I have not specified any source address. Anyone within range of the wireless network can assume an unused IP and use your broadband connection. We would prevent this by changing line 27, for example, to:
<pre>
-A FORWARD -s 192.168.0.2 -d 0/0 -m state --state NEW -p tcp -m multiport --dport http,https \
-o eth0 -i eth1 -j ACCEPT
-A FORWARD -s 192.168.0.3 -d 0/0 -m state --state NEW -p tcp -m multiport --dport http,https \
-o eth0 -i eth1 -j ACCEPT
</pre>
and similarly for the rest of the rules.
<p>
The iptables NAT-ing magic happens in the <code>nat</code> table with one rule:<br>
<code>
-A POSTROUTING -o eth0 -j SNAT --to 1.2.3.4
</code>
It's as simple as that! Almost. IP forwarding is disabled in the kernel by default and you must execute the following to turn it on:<br>
<code>$ echo 1 > /proc/sys/net/ipv4/ip_forward</code><br>
You can place this line in the iptables startup scripts (usually <code>/etc/rc.d/init.d/iptables</code>) or, preferably, in the <code>/etc/rc.d/rc.local</code> script which is the last script executed during startup.
<p>
What if you are using a dynamic IP? Simply change line 43 to:<br>
<code>-A POSTROUTING -o eth0 -j MASQUERADE</code><br>
This is a special case where the source IP of the outgoing packets are changed to the IP of the outgoing interface; i.e. the IP of <code>eth0</code>. This can be used for a static IP as well but you are advised to use the appropriate version for your set-up.
<p>
Using the wireless network as depicted will also require setting the <code>essid</code> and <code>mode</code> parameters of the wireless card. The <code>essid</code> is simply a one-word name for the wireless network. The <code>mode</code> in this example will be <code>Ad-Hoc</code> as opposed to <code>Managed</code> (usually the default) as the network cards are communicating directly as opposed to using a base station. These settings can usually be configured with the following commands:<br>
<code>
$ iwconfig eth1 essid barry_home<br>
$ iwconfig eth1 mode Ad-Hoc
</code><br>
(replacing <code>eth1</code> with <code>eth0</code>, <code>wifi0</code>, etc. as appropriate.
<p>
This scenario will work just as well if your set-up is a more typical small office set-up as depicted in <em>Figure 2</em>.
<p>
<img src="misc/odonovan/iptables-scen2a.png" alt="Office network (non-wireless)" width="511" height="160" align="top" border="0"><br>
<em>Figure 2 - Typical small office network</em>
<p>
In this case the networked computer is connected to a port on the switch or hub through <code>eth1</code>, and all other office computers are each connected to one of the other ports. The exact same firewall configuration as that in <em>Listing 4</em> can be used.
<p>
<h3>Required network settings for this configuration</h3>
<p>
To be able to access the Internet using NAT a number of network configuration settings are required by each computer; the DNS server(s) IP address(es), the gateway IP, subnet mask and an IP address. For the networked computer these will all be supplied by the ISP; let's assume that the ISP provided the following:
<pre>
<strong>IP address:</strong> <code>1.2.3.4</code>
<strong>Subnet mask:</strong> <code>255.255.255.192</code>
<strong>Primary DNS:</strong> <code>2.3.4.10</code>
<strong>Secondary DNS:</strong> <code>2.3.4.11</code>
<strong>Gateway:</strong> <code>2.3.4.1</code>
</pre>
<p>
The settings for each of the computers using NAT will then be:
<pre>
<strong>IP address:</strong> <code>192.168.0.???</code>
<strong>Subnet mask:</strong> <code>255.255.255.0</code>
<strong>Primary DNS:</strong> <code>2.3.4.10</code>
<strong>Secondary DNS:</strong> <code>2.3.4.11</code>
<strong>Gateway:</strong> <code>192.168.0.1</code>
</pre>
<p>
<strong>Note that the gateway for the NAT-ed computers is the second network interface of the networked computer.</strong>
<p>
<h3>Scenario 3: Port forwarding</h3>
<p>
For the last scenario, let us imagine that instead of hosting your web server on the firewall machine you want to host it on one of the others, say <code>192.168.0.3</code>. Let us also assume that you're using the <a href="http://jakarta.apache.org/tomcat/">Jakarta Tomcat</a> web server which listens on port 8080 by default. Can we use iptables to forward all requests from the firewall to the web server, and to forward all the responses back through the firewall to the originating request? Absolutely and, again, we can do it through the magic that is NAT.
<p>
<img src="misc/odonovan/iptables-scen3.png" alt="Port forwarding" width="347" height="158" align="top" border="0"><br>
<em>Figure 3 - Port forwarding</em>
<p>
There are two types of NAT; source NAT (SNAT) and destination NAT (DNAT). Scenario 2 used SNAT where we altered the source address of the packets coming from our internal network. This scenario will use DNAT to change the destination address of packets coming into our networked machine from the Internet.
<p>
This can be accomplished by adding one simple line (44) to our firewall:<br>
<br>
<pre>
40 *nat
41
42 # set up IP forwarding and nat
43 -A POSTROUTING -o eth0 -j SNAT --to 1.2.3.4
44 -A PREROUTING -i eth0 -p tcp -d 1.2.3.4 --dport 80 -j DNAT --to 192.168.0.3:8080
45
46 COMMIT
</pre>
<em>Listing 5 - Port forwarding</em>
<p>
Ensure you have enabled the kernel's IP forwarding when using the <code>nat</code> table. Now all connections originally bound for port 80 on our networked machine will be forwarded to port 8080 of <code>192.168.0.3</code>.
<p>
<h3>Last Remarks</h3>
<p>
One type of connection we did not cover was 'pings'. If you are running a server it is generally a good idea to allow echo-requests pings through the firewall using the following rule:<br>
<code>-A INPUT -p icmp --icmp-type echo-request -j ACCEPT</code><br>
You can use the <code>-s</code> option to limit the source IPs that are allowed to ping your machine.
<p>
Lastly, a common misconception among many people is that a firewall is "the last line of defence". It is not. <strong>It is only the first line of defense</strong> in what should be a properly secured, configured and up-to-date machine.
<p>
<h3>Community Disclaimer</h3>
<p>
This article is intended as <strong>introduction to iptables with practical and useful examples</strong>. It is nothing more and nothing less.
<p>
<h3>More Information</h3>
<p>
The best place for reading more on iptables and firewalling is the iptables homepage. It contains many how-to documents and tutorials:<br>
<a href="http://www.netfilter.org/">http://www.netfilter.org/</a><br>
And, as always, the man page for iptables gives a quick overview of the default options and tables.
<p>
If you found this article interesting then you might be interested in looking up some of the other features of iptables:
<ul>
<li> the <code>mangle</code> table; used for specialised packet alteration
<li> the string module; allows rule matching based on strings occurring anywhere within the data payload of a packet
<li> time-based rules; allows rules based on time of day and day of week
<li> tarpits; allows you to "catch and hold" connections from potential hackers, using up their resources but not your own
<li> control over limits on quota and bandwidth usage
<li> randomising; match packets randomly. Can be used for load balancing with DNAT, to simulate a faulty connection, etc.
</ul>
</p>
<!-- *** BEGIN author bio *** -->
<P>
<P>
<!-- *** BEGIN bio *** -->
<hr>
<p>
<! -- REPLACE THE FOLLOWING WITH AUTHOR'S ~200x200 PIC. -->
<img align="left" alt="[BIO]" src="../gx/2004/authors/odonovan.jpg" class="bio">
<em>
<! -- BIO GOES HERE -->
Barry O'Donovan graduated from the National University of Ireland, Galway
with a B.Sc. (Hons) in computer science and mathematics. He is currently
completing a Ph.D. in computer science with the <a
href="http://www.ihl.ucd.ie/">Information Hiding Laboratory</a>, University
College Dublin, Ireland in the area of audio watermarking.
<p> Barry has been using Linux since 1997 and his current flavor of choice
is Fedora Core. He is a member of the <a href="http://www.linux.ie/">Irish
Linux Users Group</a>. Whenever he's not doing his Ph.D. he can usually be
found in the local pub or running in the local park.
<em>
<br clear="all">
<!-- *** END bio *** -->
<!-- *** END author bio *** -->
<div id="articlefooter">
<p>
Copyright © 2004, Barry O'Donovan. Copying license
<a href="http://linuxgazette.net/copying.html">http://linuxgazette.net/copying.html</a>
</p>
<p>
Published in Issue 103 of Linux Gazette, June 2004
</p>
</div>
<div id="previousnextbottom">
<A HREF="murray.html" ><-- prev</A> | <A HREF="seymour.html" >next --></A>
</div>
</div>
<div id="navigation">
<a href="../index.html">Home</a>
<a href="../faq/index.html">FAQ</a>
<a href="../lg_index.html">Site Map</a>
<a href="../mirrors.html">Mirrors</a>
<a href="../mirrors.html">Translations</a>
<a href="../search.html">Search</a>
<a href="../archives.html">Archives</a>
<a href="../authors/index.html">Authors</a>
<a href="../contact.html">Contact Us</a>
</div>
<div id="breadcrumbs">
<a href="../index.html">Home</a> >
<a href="index.html">June 2004 (#103)</a> >
Article
</div>
<img src="../gx/2003/sit3-shine.7-2.gif" id="tux" alt="Tux"/>
</body>
</html>
|