#!/usr/local/bin/perl
#
# Paul Traina (March 1993)
# Generate extended security access list for cisco routers
#
$new_acl_format = 1;		# support for ranges and log keyword was
				# added to cisco software rev 10.3

require 'netsec-data.pl';

########################################################################
#####
#####	Inbound ACL Policy Section
#####
########################################################################

&header_prelude;
&start_list(101);

#
# Deny ALL IP sourced with our internal networks coming from the outside.
# These addresses are caused by someone trying to spoof us or wayward
# multicast traffic.
#
&entry("deny",     "ip", "", @networks, "*", @multicast);
&entry("deny-log", "ip", "", @networks, "*", @anyone);

# Deny the loopback network (localhost!)
&entry("deny-log", "ip", "", "127.0.0.0 0.255.255.255", "*", @anyone);

# Deny anything sourced as an IP multicast, just for good measure.
&entry("deny-log", "ip", "", @multicast, "*", @anyone);

# Deny anything sourced or destined to an RFC-1918 reserved network
&entry("deny", "ip", "", @rfc1597, "*", @anyone);
&entry("deny", "ip", "", @anyone,  "*", @rfc1918);

# Permit established TCP connections (these are return packets from
# an originated outbound connection).  This line goes first so most
# of the time we don't have to run through the ACL's at all.

&entry("permit", "tcp", "established", @anyone,"*", @anyone);

# We're going to put a hard coded deny in for NFS just because it is so
# dangerous that it's worth the pain.

&entry("deny-log", "udp", "nfs", @anyone,"*", @anyone);

# Permit tacacs, snmp and tftp traffic to our routers outside the firewall.
# tacacs only needs the tacacs port, but tftp and snmp need user udp ports.
#
# HOLE: Leaving udp > 1023 makes us vulnerable to rpc based attacks.
#       So SNMP management and TFTP service is run on a "secure"
#	machine that doesn't run NFS or any other RPC.

@outside_routers = (
	"131.108.7.0 0.0.0.255"
);

# HOLE: The TFTP servers specified in this list must be armored against
#       bogus TFTP attacks.

@tftp_servers = (
	"flunky",
);

&entry("permit", "udp", "tftp",     @outside_routers,"*",@tftp_servers);

@snmp_managers = (
	"flunky",
);

&entry("permit", "udp", "snmp",     @outside_routers,"*",@snmp_managers);
&entry("permit", "udp", "snmp-trap",@outside_routers,"*",@snmp_managers);
&entry("permit", "udp", "gt 1023",  @outside_routers,"*",@snmp_managers);
&entry("permit", "udp", "syslog",   @outside_routers,"*",@snmp_managers);

@tacacs_servers = (
	"vince-glorto",			# keymaster
);

&entry("permit", "udp", "tacacs",   @outside_routers,"*",@tacacs_servers);
&entry("permit", "udp", "tacacs-ds",@outside_routers,"*",@tacacs_servers);

#
# HOLE: Allow UDP 1558 (streamworks) across for real-time audio/video
# use on the web.  Note, I don't like this, since 1558 is in the RPC
# range.
#
&entry("permit", "udp", "streamworks", @anyone, "*", @anyone);

# HOLE: We're allowing UDP greater than 4999, in hopes that we're out
# of the portmapper range.  In reality, this is not very secure, as RPC based
# servers under UNIX can appear anywhere, but they usualy show up in the
# in the 1023-4999 range.  This is an "90% solution" only.

&entry("permit", "udp", "gt 4999", @anyone,"*", @anyone);

#
# Internal mail servers servers
#
@smtp_servers = (
	"oprah",
	"rolanda",
	"gordon"
);

# Anyone is allowed to make SMTP connections to the following machines
&entry("permit", "tcp", "smtp",    @anyone,"*", @smtp_servers);

#
# Anyone is allowed to telnet into checkpoint-charlie which is a enigma
# based terminal server
#
@telnet_servers = (
	"checkpoint-charlie"
);
&entry("permit", "tcp", "telnet",  @anyone,"*", @telnet_servers);


#
# Anyone is allowed to access the FTP server on the following machines
#
@ftp_servers = (
	"ftp-eng",		 # new FTP server
);
&entry("permit", "tcp", "ftp-cmd",  @anyone,"*", @ftp_servers);
&entry("permit", "tcp", "ftp-data", @anyone,"*", @ftp_servers);
&entry("permit", "tcp", "gt 1023",  @anyone,"*", @ftp_servers);

#
# WWW servers
#
@www_servers = (
	"www"			  # www server
);
&entry("permit", "tcp", "www", @anyone,"*", @www_servers);

#
# Permit DNS requests and replies to machines authorized to serve DNS
# to the outside world.
#
# HOLE: It is possible to use DNS poisioning to attack cacheing DNS servers
#       inside and therefore spoof nameservice, which leaves us open
#	to attacks based upon DNS being secure.
#
# We need to allow DNS over TCP for zone transfers, we can limit
# it to the master servers, but generally people get upset about this
# so just allow DNS over UDP and TCP everywhere.
#
# We're FORCED to allow DNS over UDP everywhere because IS servers are
# not configured to forward requests ot the DNS master servers inside.
# This sucks.
#
&entry("permit", "tcp", "dns", @anyone,"*", @anyone);
&entry("permit", "udp", "dns", @anyone,"*", @anyone);

#
# Allow NTP for now
# HOLE: people can theoretically hose our clocks, however we have a
# local stratum one and many stratum 2 machines, so this should be
# nearly impossible.
#
&entry("permit", "udp", "ntp", @anyone,"*", @anyone);

#
# Allow remote folks to authenticate with local kerberos KDCs
# so they can establish encrypted rlogin sessions or at least
# prove they are trusted folks.
#
# Encrypted rlogin/telnet and other kerberos services still need to
# be restricted on a case-by-case basis because someone gaining priveleged
# access on an internal host could set up the host to allow cross-realm
# authentication (i.e. allow "pst@stanford.edu" in).
#
&entry("permit", "udp", "kerberos5",       @anyone,"*", @anyone);
&entry("permit", "tcp", "kerberos5",       @anyone,"*", @anyone);
&entry("permit", "udp", "kerberos-sec",    @anyone,"*", @anyone);
&entry("permit", "tcp", "kerberos-sec",    @anyone,"*", @anyone);
&entry("permit", "udp", "kerberos_master", @anyone,"*", @anyone);
&entry("permit", "tcp", "kerberos_master", @anyone,"*", @anyone);
&entry("permit", "tcp", "kerberos-adm",    @anyone,"*", @anyone);
&entry("permit", "udp", "kerberos-adm",    @anyone,"*", @anyone);

#
# The following list of internal NNTP servers may receive NNTP connections
# from the list of authorized peers.
#
@nntp_peers = (
	"news.uunet.net",
	"nntp.barrnet.net"
);
&entry("permit", "tcp", "nntp", @nntp_peers,"*", "dan-rather");

#
# Deny X, OpenWindows, and any other nasties above 1023
#
if ($new_acl_format != 0) {
    &entry("deny", "tcp", "x11-range",     @anyone,"*", @anyone);
    &entry("deny", "tcp", "openwin-range", @anyone,"*", @anyone);
} else {
    &entry("deny", "tcp", "x11",       @anyone,"*", @anyone);
    &entry("deny", "tcp", "x11:1",     @anyone,"*", @anyone);
    &entry("deny", "tcp", "x11:2",     @anyone,"*", @anyone);
    &entry("deny", "tcp", "openwin",   @anyone,"*", @anyone);
    &entry("deny", "tcp", "openwin:1", @anyone,"*", @anyone);
    &entry("deny", "tcp", "openwin:2", @anyone,"*", @anyone);
}

#
# HOLE: Permit TCP connections with port numbers greater than 1023
# into a very limited set of hosts.  Opening up a hole to a UNIX host
# requires consent of the entire security task force.
#
# This is so that people can FTP out without using passive-mode FTP.
# There's really no need for /any/ machine other than the socks server
# to be in this list,  however,  some holes are here so that a certain
# big-shot who is too stupid to use passive mode FTP can run FTP on his
# machintosh.
#
# **WARNING: See also "ftp_servers" which requires similar holes.
#
@inbound_user_tcp = (
	"lazy-dickhead-mac",		# big-shot twerp
	"socks-server",			# socks server
);
&entry("permit", "tcp", "gt 1023", @anyone,"*", @inbound_user_tcp);

######
###### Temporary holes
######

# All holes listed here must have an expiration date associated, point
# of contact, and justification.  Any violations of this rule will be
# expunged on discovery.

#####
#####	Other IP protocols
#####

# Permit all IGMP messages (this allows mrinfo and mtrace to work)
&entry("permit", "igmp", "", @anyone, "*", @anyone);

# Deny and log IP to our multicast addresses (no multicast pings please!)
&entry("deny-log","icmp", "", @anyone,"*", @multicast);

# Permit ICMP everywhere else
&entry("permit",  "icmp", "", @anyone,"*", @anyone);

# there are some 'non-log' denys here so we don't bother logging noise
&entry("deny",     "tcp", "ident", @anyone, "*", @anyone);


# warn us about anything else
&entry("deny-log", "ip",  "",      @anyone, "*", @anyone);

########################################################################
#####
#####	Outbound packet filter (relatively minimal)
#####
########################################################################

&start_list(102);

# Don't mollest TCP connections that are already running
&entry("permit", "tcp", "established", @anyone, "*", @anyone);

# Stop RFC1918 traffic from getting out
#
# This is done as a courtesy to our ISPs since people in the lab often
# screw up.
#
&entry("deny", "ip", "", @rfc1597, "*", @anyone);
&entry("deny", "ip", "", @anyone,  "*", @rfc1597);

# Allow SNMP polls of the outside routers, but deny SNMP access from us
# to the rest of the world (network management guys screw up all the time)
#
&entry("permit", "udp", "snmp",	    @anyone, "*", @outside_routers);
&entry("permit", "udp", "snmp-trap",@anyone, "*", @outside_routers);
&entry("deny",	 "udp", "snmp",	    @anyone, "*", @anyone);

# Send back host unreachables if someone's trying to contact one of the
# unapproved archie servers (it's nicer than making them time out).

&entry("permit", "udp", "prospero", @anyone, "*", @archie_servers);
&entry("permit", "udp", "dirsrv",   @anyone, "*", @archie_servers);
&entry("deny",	 "udp", "prospero", @anyone, "*", @anyone);
&entry("deny",	 "udp", "dirsrv",   @anyone, "*", @anyone);

# Let anything not specificly denied out
&entry("permit",  "ip", "", @anyone,	     "*", @anyone);

########################################################################
#####
#####	VTY access filter
#####
########################################################################

&start_list(51);

&fast_entry("deny",   @insecure_networks);
&fast_entry("permit", @networks);

$data_file = "exterior-access.policy";
&read_policy($data_file) if ($data_file ne "");
print "end\n";
