|
root / base / usr / src / cmd / ipf / examples
examples Plain Text 878 lines 27.1 KB
  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
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
#!/sbin/ipnat -f -
#
# THIS EXAMPLE IS WRITTEN FOR IP FILTER 3.3
#
# ppp0 - (external) PPP connection to ISP, address a.b.c.d/32
#
# ed0 - (internal) network interface, address w.x.y.z/32
#
# If we have only 1 valid IP address from our ISP, then we do this:
#
# To make ftp work, using the internal ftp proxy, use:
#
map ppp0 w.x.y.z/24 -> a.b.c.d/32 proxy port ftp ftp/tcp
#
# For normal TCP/UDP and other IP protocols
#
map ppp0 w.x.y.z/24 -> a.b.c.d/32 portmap tcp/udp 40000:60000
map ppp0 w.x.y.z/24 -> a.b.c.d/32
#
# if we get a different dialup IP address each time, then we would use:
#
#map ppp0 w.x.y.z/24 -> 0/32 portmap tcp/udp 40000:60000
#map ppp0 w.x.y.z/24 -> 0/32
#
# If we have a class C address space of valid IP#'s from our ISP, then we can
# do this:
#
#map ppp0 w.x.y.z/24 -> a.b.c.d/24 portmap tcp/udp 40000:60000
#map ppp0 w.x.y.z/24 -> a.b.c.d/24
#
# or, if we only have a small number of PC's, this:
#
#map ppp0 w.x.y.v/32 -> a.b.c.E/32 portmap tcp/udp 40000:60000
#map ppp0 w.x.y.v/32 -> a.b.c.E/32
#map ppp0 w.x.y.u/32 -> a.b.c.F/32 portmap tcp/udp 40000:60000
#map ppp0 w.x.y.u/32 -> a.b.c.F/32
#map ppp0 w.x.y.t/32 -> a.b.c.G/32 portmap tcp/udp 40000:60000
#map ppp0 w.x.y.t/32 -> a.b.c.G/32
#map ppp0 w.x.y.s/32 -> a.b.c.H/32 portmap tcp/udp 40000:60000
#map ppp0 w.x.y.s/32 -> a.b.c.H/32
#map ppp0 w.x.y.r/32 -> a.b.c.I/32 portmap tcp/udp 40000:60000
#map ppp0 w.x.y.r/32 -> a.b.c.I/32
#map ppp0 w.x.y.q/32 -> a.b.c.J/32 portmap tcp/udp 40000:60000
#map ppp0 w.x.y.q/32 -> a.b.c.J/32
#map ppp0 w.x.y.p/32 -> a.b.c.K/32 portmap tcp/udp 40000:60000
#map ppp0 w.x.y.p/32 -> a.b.c.K/32
#!/sbin/ipf -f -
#
# SAMPLE: RESTRICTIVE FILTER RULES
#
# THIS EXAMPLE IS WRITTEN FOR IP FILTER 3.3
#
# ppp0 - (external) PPP connection to ISP, address a.b.c.d/32
#
# ed0 - (internal) network interface, address w.x.y.z/32
#
# This file contains the basic rules needed to construct a firewall for the
# above situation.
#
#-------------------------------------------------------
# *Nasty* packets we don't want to allow near us at all!
# short packets which are packets fragmented too short to be real.
block in log quick all with short
#-------------------------------------------------------
# Group setup.
# ============
# By default, block and log everything.  This maybe too much logging
# (especially for ed0) and needs to be further refined.
#
block in log on ppp0 all head 100
block in log proto tcp all flags S/SA head 101 group 100 
block out log on ppp0 all head 150
block in log on ed0 from w.x.y.z/24 to any head 200
block in log proto tcp all flags S/SA head 201 group 200 
block in log proto udp all head 202 group 200
block out log on ed0 all head 250
#-------------------------------------------------------
# Localhost packets.
# ==================
# packets going in/out of network interfaces that aren't on the loopback
# interface should *NOT* exist.
block in log quick from 127.0.0.0/8 to any group 100
block in log quick from any to 127.0.0.0/8 group 100
block in log quick from 127.0.0.0/8 to any group 200
block in log quick from any to 127.0.0.0/8 group 200
# And of course, make sure the loopback allows packets to traverse it.
pass in quick on lo0 all
pass out quick on lo0 all
#-------------------------------------------------------
# Invalid Internet packets.
# =========================
#
# Deny reserved addresses.
#
block in log quick from 10.0.0.0/8 to any group 100
block in log quick from 192.168.0.0/16 to any group 100
block in log quick from 172.16.0.0/12 to any group 100
#
# Prevent IP spoofing.
#
block in log quick from a.b.c.d/24 to any group 100
#
#-------------------------------------------------------
# Allow outgoing DNS requests (no named on firewall)
#
pass in quick proto udp from any to any port = 53 keep state group 202
#
# If we were running named on the firewall and all internal hosts talked to
# it, we'd use the following:
#
#pass in quick proto udp from any to w.x.y.z/32 port = 53 keep state group 202
#pass out quick on ppp0 proto udp from a.b.c.d/32 to any port = 53 keep state
#
# Allow outgoing FTP from any internal host to any external FTP server.
#
pass in quick proto tcp from any to any port = ftp keep state group 201
pass in quick proto tcp from any to any port = ftp-data keep state group 201
pass in quick proto tcp from any port = ftp-data to any port > 1023 keep state group 101
#
# Allow NTP from any internal host to any external NTP server.
#
pass in quick proto udp from any to any port = ntp keep state group 202
#
# Allow outgoing connections: SSH, TELNET, WWW
#
pass in quick proto tcp from any to any port = 22 keep state group 201
pass in quick proto tcp from any to any port = telnet keep state group 201
pass in quick proto tcp from any to any port = www keep state group 201
#
#-------------------------------------------------------
block in log proto tcp from any to a.b.c.d/32 flags S/SA head 110 group 100
#
# Allow incoming to the external firewall interface: mail, WWW, DNS
#
pass in log quick proto tcp from any to any port = smtp keep state group 110
pass in log quick proto tcp from any to any port = www keep state group 110
pass in log quick proto tcp from any to any port = 53 keep state group 110
pass in log quick proto udp from any to any port = 53 keep state group 100
#-------------------------------------------------------
# Log these:
# ==========
# * return RST packets for invalid SYN packets to help the other end close
block return-rst in log proto tcp from any to any flags S/SA group 100
# * return ICMP error packets for invalid UDP packets
block return-icmp(net-unr) in proto udp all group 100
#!/sbin/ipf -f -
#
# SAMPLE: PERMISSIVE FILTER RULES
#
# THIS EXAMPLE IS WRITTEN FOR IP FILTER 3.3
#
# ppp0 - (external) PPP connection to ISP, address a.b.c.d/32
#
# ed0 - (internal) network interface, address w.x.y.z/32
#
# This file contains the basic rules needed to construct a firewall for the
# above situation.
#
#-------------------------------------------------------
# *Nasty* packets we don't want to allow near us at all!
# short packets which are packets fragmented too short to be real.
block in log quick all with short
#-------------------------------------------------------
# Group setup.
# ============
# By default, block and log everything.  This maybe too much logging
# (especially for ed0) and needs to be further refined.
#
block in log on ppp0 all head 100
block out log on ppp0 all head 150
block in log on ed0 from w.x.y.z/24 to any head 200
block out log on ed0 all head 250
#-------------------------------------------------------
# Invalid Internet packets.
# =========================
#
# Deny reserved addresses.
#
block in log quick from 10.0.0.0/8 to any group 100
block in log quick from 192.168.0.0/16 to any group 100
block in log quick from 172.16.0.0/12 to any group 100
#
# Prevent IP spoofing.
#
block in log quick from a.b.c.d/24 to any group 100
#
#-------------------------------------------------------
# Localhost packets.
# ==================
# packets going in/out of network interfaces that aren't on the loopback
# interface should *NOT* exist.
block in log quick from 127.0.0.0/8 to any group 100
block in log quick from any to 127.0.0.0/8 group 100
block in log quick from 127.0.0.0/8 to any group 200
block in log quick from any to 127.0.0.0/8 group 200
# And of course, make sure the loopback allows packets to traverse it.
pass in quick on lo0 all
pass out quick on lo0 all
#-------------------------------------------------------
# Allow any communication between the inside network and the outside only.
#
# Allow all outgoing connections (SSH, TELNET, FTP, WWW, gopher, etc)
#
pass in log quick proto tcp all flags S/SA keep state group 200 
#
# Support all UDP `connections' initiated from inside.
#
# Allow ping out
#
pass in log quick proto icmp all keep state group 200
#-------------------------------------------------------
# Log these:
# ==========
# * return RST packets for invalid SYN packets to help the other end close
block return-rst in log proto tcp from any to any flags S/SA group 100
# * return ICMP error packets for invalid UDP packets
block return-icmp(net-unr) in proto udp all group 100
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
# Use is subject to license terms.
#
#cmd/ipf/examples/Makefile
#

SHPROG=		mkfilters
EXAMPLES=	BASIC.NAT BASIC_1.FW BASIC_2.FW \
		example.1 example.2 example.3 example.4 \
		example.5 example.6 example.7 example.8 \
		example.9 example.10 example.11 example.12 \
		example.13 example.sr firewall ftp-proxy \
		ftppxy ip_rules nat-setup nat.eg \
		pool.conf server tcpstate

SHSRCS= $(SHPROG:%=%.sh)

include ../../Makefile.cmd

CLOBBERFILES =	$(SHPROG)

SHAREIPF= $(ROOT)/usr/share/ipfilter
SHAREIPFX= $(SHAREIPF)/examples

IPFEXAMPLES=	$(EXAMPLES:%=$(SHAREIPFX)/%)
IPFEXSHPROG=	$(SHPROG:%=$(SHAREIPFX)/%)

FILEMODE= 0644

$(IPFEXSHPROG): FILEMODE= 0755

$(SHAREIPFX)/% : % $(SHAREIPFX)
	$(INS.file)

$(SHAREIPF):
	$(INS.dir)

$(SHAREIPFX):
	$(INS.dir)

.KEEP_STATE:

all:		$(SHPROG)

clean:

install:	all $(SHAREIPF) $(SHAREIPFX)  \
		$(IPFEXAMPLES) $(IPFEXSHPROG)

lint:

include ../../Makefile.targ

.PARALLEL:

#
# block all incoming TCP packets on le0 from host 10.1.1.1 to any destination.
#
block in on le0 proto tcp from 10.1.1.1/32 to any
#
# pass ack packets (ie established connection)
#
pass in proto tcp from 10.1.0.0/16 port = 23 to 10.2.0.0/16 flags A/A
pass out proto tcp from 10.1.0.0/16 port = 23 to 10.2.0.0/16 flags A/A
#
# block incoming connection requests to my internal network from the big bad
# internet.
#
block in on le0 proto tcp from any to 10.1.0.0/16 flags S/SA
#  to block the replies:
block out on le0 proto tcp from 10.1.0.0 to any flags SA/SA
#
# allow any TCP packets from the same subnet as foo is on through to host
# 10.1.1.2 if they are destined for port 6667.
#
pass in proto tcp from 10.2.2.2/24 to 10.1.1.2/32 port = 6667
#
# allow in UDP packets which are NOT from port 53 and are destined for
# localhost
#
pass in proto udp from 10.2.2.2 port != 53 to localhost
#
# block anything trying to get to X terminal ports, X:0 to X:9
#
block in proto tcp from any to any port 5999 >< 6010
#
# allow any connections to be made, except to BSD print/r-services
# this will also protect syslog.
#
block in proto tcp/udp all
pass in proto tcp/udp from any to any port 512 <> 515
#
# allow any connections to be made, except to BSD print/r-services
# this will also protect syslog.
#
pass in proto tcp/udp all
block in proto tcp/udp from any to any port 511 >< 516
#
# get rid of all short IP fragments (too small for valid comparison)
#
block in proto tcp all with short
#
# drop and log any IP packets with options set in them.
#
block in log all with ipopts
#
# log packets with BOTH ssrr and lsrr set
#
log in all with opt lsrr,ssrr
#
# drop any source routing options
#
block in quick all with opt lsrr
block in quick all with opt ssrr
#
# Log all short TCP packets to qe3, with 10.3.3.3 as the intended
# destination for the packet.
#
block in on qe0 to qe3:10.3.3.3 proto tcp all with short
#
# Log all connection attempts for TCP
#
pass in on le0 dup-to le1:10.3.3.3 proto tcp all flags S/SA
#
# Route all UDP packets through transparently.
#
pass in on ppp0 fastroute proto udp all
#
# Route all ICMP packets to network 10 out through le1, to 10.3.3.1
#
pass in on le0 to le1:10.3.3.1 proto icmp all
#
# block all outgoing TCP packets on le0 from any host to port 23 of
# host 10.1.1.2
#
block out on le0 proto tcp from any to 10.1.1.3/32 port = 23
#
# block all inbound packets.
#
block in from any to any
#
# pass through packets to and from localhost.
#
pass in from 127.0.0.1/32 to 127.0.0.1/32
#
# allow a variety of individual hosts to send any type of IP packet to any
# other host.
#
pass in from 10.1.3.1/32 to any
pass in from 10.1.3.2/32 to any
pass in from 10.1.3.3/32 to any
pass in from 10.1.3.4/32 to any
pass in from 10.1.3.5/32 to any
pass in from 10.1.0.13/32 to any
pass in from 10.1.1.1/32 to any
pass in from 10.1.2.1/32 to any
#
#
# block all outbound packets.
#
block out from any to any
#
# allow any packets destined for localhost out.
#
pass out from any to 127.0.0.1/32
#
# allow any host to send any IP packet out to a limited number of hosts.
#
pass out from any to 10.1.3.1/32
pass out from any to 10.1.3.2/32
pass out from any to 10.1.3.3/32
pass out from any to 10.1.3.4/32
pass out from any to 10.1.3.5/32
pass out from any to 10.1.0.13/32
pass out from any to 10.1.1.1/32
pass out from any to 10.1.2.1/32
#
# block all ICMP packets.
#
block in proto icmp from any to any
#
# test ruleset
#
# allow packets coming from foo to bar through.
#
pass in from 10.1.1.2 to 10.2.1.1
#
# allow any TCP packets from the same subnet as foo is on through to host
# 10.1.1.2 if they are destined for port 6667.
#
pass in proto tcp from 10.2.2.2/24 to 10.1.1.2/32 port = 6667
#
# allow in UDP packets which are NOT from port 53 and are destined for
# localhost
#
pass in proto udp from 10.2.2.2 port != 53 to localhost
#
# block all ICMP unreachables.
#
block in proto icmp from any to any icmp-type unreach
#
# allow packets through which have a non-standard IP header length (ie there
# are IP options such as source-routing present).
#
pass in from any to any with ipopts
#
# block all TCP packets with only the SYN flag set (this is the first
# packet sent to establish a connection) out of the SYN-ACK pair.
#
block in proto tcp from any to any flags S/SA
# block all ICMP packets.
#
block in proto icmp all
#
# allow in ICMP echos and echo-replies.
#
pass in on le1 proto icmp from any to any icmp-type echo
pass in on le1 proto icmp from any to any icmp-type echorep
#
# block all ICMP destination unreachable packets which are port-unreachables
#
block in on le1 proto icmp from any to any icmp-type unreach code 3
#
# block all incoming TCP connections but send back a TCP-RST for ones to
# the ident port
#
block in proto tcp from any to any flags S/SA
block return-rst in quick proto tcp from any to any port = 113 flags S/SA
#
# block all inbound UDP packets and send back an ICMP error.
#
block return-icmp in proto udp from any to any
#
# drop all packets without IP security options
#
block in all
pass in all with opt sec
#
# only allow packets in and out on le1 which are top secret
#
block out on le1 all
pass out on le1 all with opt sec-class topsecret
block in on le1 all
pass in on le1 all with opt sec-class topsecret
#
# log all inbound packet on le0 which has IP options present
#
log in on le0 from any to any with ipopts
#
# block any inbound packets on le0 which are fragmented and "too short" to
# do any meaningful comparison on.  This actually only applies to TCP
# packets which can be missing the flags/ports (depending on which part
# of the fragment you see).
#
block in log quick on le0 from any to any with short frag
#
# log all inbound TCP packets with the SYN flag (only) set
#  (NOTE: if it were an inbound TCP packet with the SYN flag set and it
#         had IP options present, this rule and the above would cause it
#         to be logged twice).
#
log in on le0 proto tcp from any to any flags S/SA
#
# block and log any inbound ICMP unreachables
#
block in log on le0 proto icmp from any to any icmp-type unreach
#
# block and log any inbound UDP packets on le0 which are going to port 2049
# (the NFS port).
#
block in log on le0 proto udp from any to any port = 2049
#
# quickly allow any packets to/from a particular pair of hosts
#
pass in quick from any to 10.1.3.2/32
pass in quick from any to 10.1.0.13/32
pass in quick from 10.1.3.2/32 to any
pass in quick from 10.1.0.13/32 to any
#
# block (and stop matching) any packet with IP options present.
#
block in quick on le0 from any to any with ipopts
#
# allow any packet through
#
pass in from any to any
#
# block any inbound UDP packets destined for these subnets.
#
block in on le0 proto udp from any to 10.1.3.0/24
block in on le0 proto udp from any to 10.1.1.0/24
block in on le0 proto udp from any to 10.1.2.0/24
#
# block any inbound TCP packets with only the SYN flag set that are
# destined for these subnets.
#
block in on le0 proto tcp from any to 10.1.3.0/24 flags S/SA
block in on le0 proto tcp from any to 10.1.2.0/24 flags S/SA
block in on le0 proto tcp from any to 10.1.1.0/24 flags S/SA
#
# block any inbound ICMP packets destined for these subnets.
#
block in on le0 proto icmp from any to 10.1.3.0/24
block in on le0 proto icmp from any to 10.1.1.0/24
block in on le0 proto icmp from any to 10.1.2.0/24
Configuring IP Filter for firewall usage.
=========================================

Step 1 - Block out "bad" IP packets.
------------------------------------

Run the perl script "mkfilters".  This will generate a list of blocking
rules which:
	a) blocks all packets which might belong to an IP Spoofing attack;
	b) blocks all packets with IP options;
	c) blocks all packets which have a length which is too short for
	   any legal packet;

Step 2 - Convert Network Security Policy to filter rules.
---------------------------------------------------------

Draw up a list of which services you want to allow users to use on the
Internet (e.g. WWW, ftp, etc).  Draw up a separate list for what you
want each host that is part of your firewall to be allowed to do, including
communication with internal hosts.

Step 3 - Create TCP "keep state" rules.
---------------------------------------

For each service that uses TCP, create a rule as follows:

pass in on <int-a> proto tcp from <int-net> to any port <ext-service> flags S/SA keep state

where
* "int-a" is the internal interface of the firewall.  That is, it is the
  closest to your internal network in terms of network hops.

* "int-net" is the internal network IP# subnet address range.  This might
   be something like 10.1.0.0/16, or 128.33.1.0/24 

* "ext-service" is the service to which you wish to connect or if it doesn't
  have a proper name, a number can be used.  The translation of "ext-service"
  as a name to a number is controlled with the /etc/services file.

How to setup FTP proxying using the built in proxy code.
========================================================

NOTE: Currently, the built-in FTP proxy is only available for use with NAT
      (i.e. only if you're already using "map" rules with ipnat).  It does
      support null-NAT mappings, that is, using the proxy without changing
      the addresses.

Lets assume your network diagram looks something like this:


[host A]
   |a
---+-------------+----------
                 |b
             [host B]
                 |c
---+-------------+----------
   |d
[host C]

and IP Filter is running on host B.  If you want to proxy FTP from A to C
then you would do:

map int-c ipaddr-a/32 -> ip-addr-c-net/32 proxy port ftp ftp/tcp

int-c = name of "interface c"
ipaddr-a = ip# of interface a
ipaddr-c-net = another ip# on the C-network (usually not the same as the
interface).

e.g., if host A was 10.1.1.1, host B had two network interfaces ed0 and vx0
which had IP#'s 10.1.1.2 and 203.45.67.89 respectively, and host C was
203.45.67.90, you would do:

map vx0 10.1.1.1/32 -> 203.45.67.91/32 proxy port ftp ftp/tcp

where:
ipaddr-a = 10.1.1.1
int-c = vx0
ipaddr-c-net = 203.45.67.91

The "map" rule for this proxy should precede any other NAT rules you are
using.

#!/bin/sh
# The proxy bit is as follows:
# proxy [port <portname>] <tag>/<protocol>
# the <tag> should match a tagname in the proxy table, as does the protocol.
# this format isn't finalised yet
echo "map ed0 0/0 -> 192.1.1.1/32 proxy port ftp ftp/tcp" | /sbin/ipnat -f -
# Used to generate ../ip_rules.c and ../ip_rules.h
pass in all
pass out all
#!/bin/perl
# for best results, bring up all your interfaces before running this

if ($^O =~ m/^irix/i)
{
    &irix_mkfilters || regular_mkfilters || die $!;
}
else
{
    &regular_mkfilters || irix_mkfilters || die $!;
}

foreach $i (keys %ifaces) {
	$net{$i} = $inet{$i}."/".$netmask{$i} if (defined($inet{$i}));
}
#
# print out route suggestions
#
print "#\n";
print "# The following routes should be configured, if not already:\n";
print "#\n";
foreach $i (keys %ifaces) {
	next if (($i =~ /lo/) || !defined($net{$i}) || defined($ppp{$i}));
	print "# route add $inet{$i} localhost 0\n";
}
print "#\n";

#
# print out some generic filters which people should use somewhere near the top
#
print "block in log quick from any to any with ipopts\n";
print "block in log quick proto tcp from any to any with short\n";

$grpi = 0;

foreach $i (keys %ifaces) {
	if (!defined($inet{$i})) {
		next;
	}

	$grpi += 100;
	$grpo = $grpi + 50;

	if ($i !~ /lo/) {
		print "pass out on $i all head $grpo\n";
		print "block out from 127.0.0.0/8 to any group $grpo\n";
		print "block out from any to 127.0.0.0/8 group $grpo\n";
		print "block out from any to $inet{$i}/32 group $grpo\n";
		print "pass in on $i all head $grpi\n";
		print "block in from 127.0.0.0/8 to any group $grpi\n";
		print "block in from $inet{$i}/32 to any group $grpi\n";
		foreach $j (keys %ifaces) {
			if ($i ne $j && $j !~ /^lo/ && defined($net{$j})) {
				print "block in from $net{$j} to any group $grpi\n";
			}
		}
	}
}

sub irix_mkfilters
{
    open(NETSTAT, "/usr/etc/netstat -i|") || return 0;
    
    while (defined($line = <NETSTAT>))
    {
	if ($line =~ m/^Name/)
	{
	    next;
	}
	elsif ($line =~ m/^(\S+)/)
	{
	    open(I, "/usr/etc/ifconfig $1|") || return 0;
	    &scan_ifconfig;
	    close I;		# being neat... - Allen
	}
    }
    close NETSTAT;			# again, being neat... - Allen
    return 1;
}

sub regular_mkfilters
{
    open(I, "ifconfig -a|") || return 0;
    &scan_ifconfig;
    close I;			# being neat... - Allen
    return 1;
}

sub scan_ifconfig
{
    while (<I>) {
	chop;
	if (/^[a-zA-Z]+\d+:/) {
	    ($iface = $_) =~ s/^([a-zA-Z]+\d+).*/$1/;
	    $ifaces{$iface} = $iface;
	    next;
	}
	if (/inet/) {
	    if (/\-\-\>/) { # PPP, (SLIP?)
			($inet{$iface} = $_) =~ s/.*inet ([^ ]+) \-\-\> ([^ ]+).*/$1/;
			($ppp{$iface} = $_) =~ s/.*inet ([^ ]+) \-\-\> ([^ ]+).*/$2/;
		    } else {
			($inet{$iface} = $_) =~ s/.*inet ([^ ]+).*/$1/;
		    }
	}
	if (/netmask/) {
	    ($mask = $_) =~ s/.*netmask ([^ ]+).*/$1/;
		    $mask =~ s/^/0x/ if ($mask =~ /^[0-9a-f]*$/);
	    $netmask{$iface} = $mask;
	}
	if (/broadcast/) {
	    ($bcast{$iface} = $_) =~ s/.*broadcast ([^ ]+).*/$1/;
	}
    }
}
    
Configuring NAT on your network.
================================

To start setting up NAT, we need to define which is your "internal" interface
and which is your "external" interface.  The "internal" interface is the
network adapter connected to the network with private IP addresses which
you need to change for communicating on the Internet.  The "external"
interface is configured with a valid internet address.

For example, your internal interface might have an IP# of 10.1.1.1 and be
connected to your ethernet, whilst your external interface might be a PPP
connection with an IP number of 204.51.62.176.

Thus your network might look like this:

<Internal Network>
 [pc]      [pc]
  |         |
+-+---------+------+
                   |
               [firewall]
                   |
                   |
               Internet
<External Network>


Writing the map-rule.
---------------------
When you're connected to the Internet, you will either have a block of IP
addresses assigned to you, maybe several different blocks, or you use a
single IP address, i.e. with dialup PPP.  If you have a block of addresses
assigned, these can be used to create either a 1:1 mapping (if you have
only a few internal IP addresses) or N:1 mappings, where groups of internal
addresses map to a single IP address and unless you have enough Internet
addresses for a 1:1 mapping, you will want to do "portmapping" for TCP and
UDP port numbers.

For an N:1 situation, you might have:

map ppp0 10.1.0.0/16 -> 209.23.1.5/32 portmap tcp/udp 10000:40000
map ppp0 10.1.0.0/16 -> 209.23.1.5/32 portmap

where if you had 16 addresses available, you could do:

map ppp0 10.1.0.0/16 -> 209.23.1.0/28 portmap tcp/udp 10000:40000
map ppp0 10.1.0.0/16 -> 209.23.1.0/28 portmap

Or if you wanted to allocate subnets to each IP#, you might do:

map ppp0 10.1.1.0/24 -> 209.23.1.2/32 portmap tcp/udp 10000:40000
map ppp0 10.1.2.0/24 -> 209.23.1.3/32 portmap tcp/udp 10000:40000
map ppp0 10.1.3.0/24 -> 209.23.1.4/32 portmap tcp/udp 10000:40000
map ppp0 10.1.1.0/24 -> 209.23.1.2/32 portmap
map ppp0 10.1.2.0/24 -> 209.23.1.3/32 portmap
map ppp0 10.1.3.0/24 -> 209.23.1.4/32 portmap

*** NOTE: NAT rules are used on a first-match basis only!


Filtering with NAT.
-------------------
IP Filter will always translate addresses in a packet _BEFORE_ it checks its
access list for inbound packets and translates addresses _AFTER_ it has
checked the access control lists for outbound packets.

For example (using the above NAT rules), if you wanted to prevent all hosts
in the 10.1.2.0/24 subnet from using NAT, you might use the following rule
with ipf:

block out on ppp0 from 10.1.2.0/24 to any
block in on ppp0 from any to 10.1.2.0/24

and use these with ipnat:

map ppp0 10.1.0.0/16 -> 209.23.1.0/28 portmap tcp/udp 10000:40000
map ppp0 10.1.0.0/16 -> 209.23.1.0/28 portmap
# map all tcp connections from 10.1.0.0/16 to 240.1.0.1, changing the source
# port number to something between 10,000 and 20,000 inclusive.  For all other
# IP packets, allocate an IP # between 240.1.0.0 and 240.1.0.255, temporarily
# for each new user.
#
map ed1 10.1.0.0/16 -> 240.1.0.1/32 portmap tcp 10000:20000
map ed1 10.1.0.0/16 -> 240.1.0.0/24
#
# Redirection is triggered for input packets.
# For example, to redirect FTP connections through this box, to the local ftp
# port, forcing them to connect through a proxy, you would use:
#
rdr ed0 0.0.0.0/0 port ftp -> 127.0.0.1 port ftp
#
#
# ippool sample configuration file
#

table role = ipf type = tree number = 0 
{ 
	!10.0.0.0/8, 10.1.0.0/16, 10.1.1.0/24,
	!10.2.0.0/24, !10.2.1.0/24, !10.2.2.0/24,
	10.1.2.3/32, 10.1.2.15/32
};
#
# For a network server, which has two interfaces, 128.1.40.1 (le0) and
# 128.1.2.1 (le1), we want to block all IP spoofing attacks.  le1 is
# connected to the majority of the network, whilst le0 is connected to a
# leaf subnet.  We're not concerned about filtering individual services
# or 
#
pass in quick on le0 from 128.1.40.0/24 to any
block in log quick on le0 from any to any
block in log quick on le1 from 128.1.1.0/24 to any
pass in quick on le1 from any to any
#
# Only allow TCP packets in/out of le0 if there is an outgoing connection setup
# somewhere, waiting for it.
#
pass out quick on le0 proto tcp from any to any flags S/SAFR keep state
block out on le0 proto tcp all
block in on le0 proto tcp all
#
# allow nameserver queries and replies to pass through, but no other UDP
#
pass out quick on le0 proto udp from any to any port = 53 keep state
block out on le0 proto udp all
block in on le0 proto udp all