#!/bin/sh

# don't allow root to run the script
if [ `id -u` = "0" ]; then
   echo 'Please run this script as a normal user.'
   echo 'If you have not created a normal user, please run "adduser"'
   exit 2
fi
USER=`id -urn`


# Information about the machine
ARCH=`uname -m`
OBSD=`uname -r`

#			 Prompt user for inputs



cat <<EOT
We will set up the firewall, NAT, DNS, sendmail, DHCP, NTP, and Apache.
Don't worry, the firewall will be setup conservatively and I will ask
you about the things that the outside world will be able to see.

Network interface selection
EOT

for line in `dmesg | awk '/address ..:..:..:..:..:../{print $1 "-" $NF}'`; do
    echo $line | tr '-' ' ' >/tmp/cfgfw$$
    read iface mac </tmp/cfgfw$$
    rm /tmp/cfgfw$$
    iface=${iface%:}
    read ans?"Use $iface (MAC $mac) for the inside or outside interface? [io] "
    case $ans in
    i)
	if [ "X$INSIDE" != "X" ]; then
	    echo "Sorry, you have already selected $iface for the inside"
	else
	    INSIDE=$iface
	fi ;;
    o)
	if [ "X$OUTSIDE" != "X" ]; then
	    echo "Sorry, you have already selected $OUTSIDE for the outside"
	else
	    OUTSIDE=$iface
	fi ;;
    *)
	echo "Skipping $iface"
	;;
    esac
done

if [ -z "$OUTSIDE" ]; then
    echo "You have not selected an interface for the outside."
    exit 1
fi

if [ -z "$INSIDE" ]; then
    echo "You have not selected an interface for the inside."
    exit 1
fi

echo "Using $INSIDE for the inside interface and $OUTSIDE for the outside."

IPNUM=`/sbin/ifconfig $OUTSIDE | awk '/inet /{print $2}'`
echo
echo "Your outside IP number appears to be $IPNUM - if this is not correct,"
echo "you didn't tell me the inside and outside interfaces correctly, Please"
echo "press Ctrl-C and re-run this script."

echo
read DOMAIN?"What is your domain name? "

RCF_XDM=NO
if [ -e /usr/X11R6/bin/X ]; then
    SYSCTL_X11='s/^#machdep.allowaperture=/machdep.allowaperture=1/;'
    read XDM_YES?"Do you want xdm (X Windows login) to be started at boot time? [yn] "
    if [ "X$XDM_YES" = "Xy" -o "X$XDM_YES" = "XY" ]; then
        RCF_XDM=""
    fi
fi

read HTTP_YES?"Will you be running a web server visible to the world? [yn] "
if [ "X$HTTP_YES" = "Xy" -o "X$HTTP_YES" = "XY" ]; then
    PF_HTTPD="http, "
    RCF_HTTPD=""
    read SSL_YES?"Will it also run SSL? [yn] "
    if [ "X$SSL_YES" = "Xy" -o "X$SSL_YES" = "XY" ]; then
        PF_SSL="https, "
        RCF_HTTPD="-DSSL"
        echo "Be sure to read the manpage for SSL and create your keys."
    fi
else
    RCF_HTTPD="NO"
fi

read SMTP_YES?"Will you be running an email server visible to the world? [yn] "
if [ "X$SMTP_YES" = "Xy" -o "X$SMTP_YES" = "XY" ]; then
    PF_SENDMAIL="smtp, "
    RCF_SENDMAIL="-L sm-mta -bd -q30m"
else
    RCF_SENDMAIL="-q30m"
fi



echo
read COUNTRY?"Which country are you in? [two-letter ISO code] "
if [ "X$COUNTRY" = "Xus" -o "X$COUNTRY" = "XUS" ]; then
   read STATE?"Which state are you in? [two-letter postal code] "
   COUNTRY="$COUNTRY-$STATE"
fi
echo "$COUNTRY" | tr a-z A-Z >/tmp/cfgfw$$
read COUNTRY < /tmp/cfgfw$$




#			    NAT and Packet Filter



mkdir -p cfg/etc

cat >cfg/etc/pf.conf <<EOT
#####################################################################
#
# IP packet filtering rules (firewall)
# Shamim Mohamed 3/2002

# See pf.conf(5) for syntax and examples

# If you change this file, run
#    pfctl -R /etc/pf.conf
# to update kernel tables (also run "pfctl -e" if pf was not running)

# Network interfaces
internal = "$INSIDE"
external = "$OUTSIDE"

# Services visible from the outside - remove any you're not using
services = "{ $PF_HTTPD $PF_SSL $PF_SENDMAIL ssh }"

# You shouldn't need to change anything below this line
#####################################################################
EOT

cat >>cfg/etc/pf.conf <<'EOT'
# Non-routable IP numbers
nonroutable = "{ 192.168.0.0/16, 127.0.0.0/8, 172.16.0.0/12, 10.0.0.0/8,
    0.0.0.0/8, 169.254.0.0/16, 192.0.2.0/24, 204.152.64.0/23, 224.0.0.0/3,
    255.255.255.255/32 }"

# All rules are "quick" so go strictly top to bottom

# Fix fragmented packets
scrub in all

#  Don't bug loopback
#
pass out quick on lo0 from any to any
pass in quick on lo0 from any to any

#  Don't bother the inside interface either
#
pass out quick on $internal from any to any
pass in quick on $internal from any to any

#####################################################################
#
#  First, we deal with bogus packets.
#

#  Block any inherently bad packets coming in from the outside world.
#  These include ICMP redirect packets and IP fragments so short the
#  filtering rules won't be able to examine the whole UDP/TCP header.
#
block in log quick on $external inet proto icmp from any to any icmp-type redir

#  Block any IP spoofing atempts.  (Packets "from" non-routable
#  addresses shouldn't be coming in from the outside).
#
block in quick on $external from $nonroutable to any

#  Don't allow non-routable packets to leave our network
#
block out quick on $external from any to $nonroutable

#
#####################################################################

#####################################################################
#
#  Now the normal filtering rules
#

#  ICMP: allow incoming ping and traceroute only
#
pass in quick on $external inet proto icmp from any to any icmp-type echorep
pass in quick on $external inet proto icmp from any to any icmp-type echoreq
pass in quick on $external inet proto icmp from any to any icmp-type timex
pass in quick on $external inet proto icmp from any to any icmp-type unreach
block in log quick on $external inet proto icmp from any to any

#  TCP: Allow ssh, smtp, http and https incoming. Only match
#  SYN packets, and allow the state table to handle the rest of the
#  connection.
#
pass in quick on $external inet proto tcp from any to any port $services flags S/SA keep state

#  Of course we need to allow packets coming in as replies to our
#  connections so we keep state. Strictly speaking, with packets
#  coming from our network we don't have to only match SYN, but
#  what the hell.
#
pass out quick on $external inet proto tcp  from any to any flags S/SA keep state
pass out quick on $external inet proto udp  all keep state
pass out quick on $external inet proto icmp from any to any keep state

#  End of rules. Block everything to all ports, all protocols and return
#  RST (TCP) or ICMP/port-unreachable (UDP).
#
block return-rst in log quick on $external inet proto tcp from any to any
block return-icmp in log quick on $external inet proto udp from any to any
block in quick on $external all

#
#  End of file
#
#####################################################################
EOT

cat >cfg/etc/nat.conf <<EOT
#####################################################################
#
# NAT rules
# Shamim Mohamed 3/2002
 
# If you edit this file, run
#    pfctl -N /etc/nat.conf
# to update kernel tables

# See nat.conf(5) for syntax and examples

# replace $OUTSIDE with external interface name, 192.168.1.0/24 with internal
# network (if different) and $IPNUM with your external address

# nat: packets going out through $OUTSIDE with source address 192.168.1.0/24
# will get translated as coming from 192.168.1.1.  State is created for such
# packets, and incoming packets will be redirected to the internal address.

nat on $OUTSIDE from 192.168.1.0/24 to any -> $IPNUM

# End of file
########################################################################
EOT



#			    The DHCP server



cat >cfg/etc/dhcpd.conf <<EOT
#       $OpenBSD: dhcpd.conf,v 1.1 1998/08/19 04:25:45 form Exp $
#
# DHCP server options.
# See dhcpd.conf(5) and dhcpd(8) for more information.
#
 
# Network:              192.168.1.0/255.255.255.0
# Domain name:          my.domain
# Name servers:         192.168.1.3 and 192.168.1.5
# Default router:       192.168.1.1
# Addresses:            192.168.1.32 - 192.168.1.127
#
shared-network LOCAL-NET {
        option  domain-name "$DOMAIN";
        option  domain-name-servers 192.168.1.1;
 
        subnet 192.168.1.0 netmask 255.255.255.0 {
                option routers 192.168.1.1;
 
                range 192.168.1.32 192.168.1.127;
        }
}
EOT

cat >cfg/etc/dhcpd.interfaces <<EOT
#       $OpenBSD: dhcpd.interfaces,v 1.1 1998/08/19 04:25:45 form Exp $
#
# List of network interfaces served by dhcpd(8).
#
# ep0
# ed0 le0
# de1
$INSIDE
EOT

mkdir -p cfg/var/db
touch cfg/var/db/dhcpd.leases



#				sendmail


mkdir -p cfg/etc/mail
sed 's/^#Dj$w.Foo.COM/Dj'"$DOMAIN/" </etc/mail/sendmail.cf >cfg/etc/mail/sendmail.cf
cp /etc/mail/aliases cfg/etc/mail/aliases
cat >>cfg/etc/mail/aliases <<EOT
root: $USER
manager: $USER
dumper: $USER
EOT



#				  NTP



echo
echo "Here is a list of nearby time servers:"
awk "/$COUNTRY/"'{print $2}' <<'EOT'
AR tick.nap.com.ar
AR time.sinectis.com.ar
AR tock.nap.com.ar
AU ntp.saard.net
AU time.deakin.edu.au
AU time.esec.com.au
BE ntp1.be
BE ntp2.belbone.be
BR ntp.cais.rnp.br
BR ntp.pop-df.rnp.br
BR ntp.pop-pr.rnp.br
BR ntp.ufes.br
BR ntp1.pucpr.br
CA ntp.cpsc.ucalgary.ca
CA ntp1.cmc.ec.gc.ca
CA ntp2.cmc.ec.gc.ca
CA tick.utoronto.ca
CA time.chu.nrc.ca
CA time.nrc.ca
CA timelord.uregina.ca
CA tock.utoronto.ca
CZ ntp.karpo.cz
DK clock.netcetera.dk
GR ntp.mikroskosmos.com
DK clock2.netcetera.dk
ES slug.ctv.es
FI tick.keso.fi
FI tock.keso.fi
FR ntp1.curie.fr
FR ntp2curie.fr
FR ntp3.curie.fr
FR ntp.obspm.fr
FR ntp.tuxfamily.net
FR ntp1.tuxfamily.net
FR ntp2.tuxfamily.net
FR ntp.univ-lyon1.fr
FR ntp.via.ecp.fr
HR zg1.ntp.carnet.hr
HR zg2.ntp.carnet.hr
HR st.ntp.carnet.hr
HR ri.ntp.carnet.hr
HR os.ntp.carnet.hr
HU time.kfki.hu
ID ntp.incaf.net
IE ntp.maths.tcd.ie
IT ntps.net4u.it
JP ntp.cyber-fleet.net[203.139.30.195]
KR time.nuri.net[203.255.112.4]
MX ntp2a.audiotel.com.mx
MX ntp2b.audiotel.com.mx
MX ntp2c.audiotel.com.mx
NG ntp.supernet300.com
NL ntp1.theinternetone.net
NL ntp2.theinternetone.net
NL ntp3.theinternetone.net
NO fartein.ifi.uio.no
NO time.alcanet.no
NZ ntp.massey.ac.nz
NZ ntp.public.otago.ac.nz
NZ tk1.ihug.co.nz,
NZ ntp.waikato.ac.nz
PL info.cyf-kr.edu.pl:
PT bug.fe.up.pt
RO ntp.ip.ro
RU ntp.psn.ru
RU sign.chg.ru
SE ntp.lth.se
SG ntp.shim.org
SI calvus.rzs-hm.si
SI biofiz.mf.uni-lj.si
SI ntp1.arnes.si
SI ntp2.arnes.si
SI time.ijs.si
SI time.ijs.si
SV clock.cimat.ues.edu.sv
UK ntp.cs.strath.ac.uk
UK ntp.exnet.com
UK ntp0.uk.uu.net
UK ntp1.uk.uu.net
UK ntp2.uk.uu.net
UK ntp2a.mcc.ac.uk
UK ntp2b.mcc.ac.uk
UK ntp2c.mcc.ac.uk
UK ntp2d.mcc.ac.uk
UK tick.tanac.net
US-AR sushi.compsci.lyon.edu
US-AZ ntp.drydog.com
US-CA ntp.ucsd.edu
US-CA ntp1.mainecoon.com
US-CA ntp2.mainecoon.com
US-CA ntp1.sf-bay.org
US-CA ntp2.sf-bay.org
US-CA reloj.kjsl.com
US-CA time.berkeley.netdot.net
US-CA time.five-ten-sg.com
US-DE louie.udel.edu
US-GA ntp.shorty.com
US-GA rolex.usg.edu
US-GA timex.usg.edu
US-IL chrivh40.cch.com
US-IL ntp-0.cso.uiuc.edu
US-IL ntp-1.cso.uiuc.edu
US-IL ntp-1.mcs.anl.gov
US-IL ntp-2.cso.uiuc.edu
US-IL ntp-2.mcs.anl.gov
US-IN gilbreth.ecn.purdue.edu
US-IN harbor.ecn.purdue.edu
US-IN molecule.ecn.purdue.edu
US-KS ntp1.kansas.net
US-KS ntp2.kansas.net
US-MA ntp.ourconcord.net
US-MA timeserver.cs.umb.edu
US-MN ns.nts.umn.edu
US-MN nss.nts.umn.edu
US-MO time-ext.missouri.edu
US-MT chronos1.umt.edu
US-MT chronos2.umt.edu
US-MT chronos3.umt.edu
US-NC clock1.unc.edu
US-NV cuckoo.nevada.edu
US-NV tick.cs.unlv.edu
US-NV tock.cs.unlv.edu
US-NY clock.linuxshell.net
US-NY ntp.ctr.columbia.edu
US-NY ntp0.cornell.edu
US-NY ntp1.mpis.net
US-NY ntp2.mpis.net
US-NY sundial.columbia.edu
US-NY timex.cs.columbia.edu
US-OK constellation.ecn.uoknor.edu
US-PA clock-1.cs.cmu.edu
US-PA clock-2.cs.cmu.edu
US-PA clock.psu.edu
US-PA fuzz.psc.edu
US-PA ntp-1.ece.cmu.edu
US-PA ntp-2.ece.cmu.edu
US-TX ntp.cox.smu.edu
US-TX ntp.fnbhs.com
US-TX ntp.tmc.edu
US-TX ntp5.tamu.edu
US-TX tick.greyware.com
US-TX tock.greyware.com
US-VA ntp-1.vt.edu
US-VA ntp-2.vt.edu
US-VA ntp.cmr.gov
US-VT ntp0.state.vt.us
US-VT ntp1.state.vt.us
US-VT ntp2.state.vt.us
US-WA clock.tricity.wsu.edu
US-WA ntp.ultimeth.net
US-WI ntp1.cs.wisc.edu
US-WI ntp3.cs.wisc.edu
VE ntp.linux.org.ve
ZA ntp.cs.unp.ac.za
EOT

read NTP1?"Please pick one server from the list: "
read NTP2?"Please pick another server from the list: "
cat >cfg/etc/ntp.conf <<EOT
server $NTP1
server $NTP2
EOT

if [ ! -x /usr/local/sbin/ntpd ]; then
    echo "NTP is not installed on your system."
    echo 'Please switch to another VT (Ctrl-Alt-F2) and, as root, run this:'
    echo "    pkg_add -v ftp://ftp.openbsd.org/pub/OpenBSD/$OBSD/packages/$ARCH/ntp-4.1.71.tgz"
    echo 'Then come back here (Ctrl-Alt-F1) and hit return.'
    read junk
fi

if [ ! -x /usr/local/libexec/smbd ]; then
    echo "Samba (for MS-Windows file sharing) is not installed on your system."
    echo 'Please switch to another VT (Ctrl-Alt-F2) and, as root, run this:'
    echo "    pkg_add -v ftp://ftp.openbsd.org/pub/OpenBSD/$OBSD/packages/$ARCH/samba-2.2.1a.tgz"
    echo 'Then come back here (Ctrl-Alt-F1) and hit return. '
    read junk
fi



#				  DNS


mkdir -p cfg/var/named/namedb

echo $IPNUM | awk -F. '{printf("%s.%s.%s.%s\n", $4, $3, $2, $1)}'>/tmp/cfgfw$$
read IPNUM_REV </tmp/cfgfw$$

awk '/nameserver/{NS = NS " " $2}END{print NS}' </etc/resolv.conf >/tmp/cfgfw$$
read NAMESERVERS </tmp/cfgfw$$

cat >cfg/var/named/named.boot <<EOT
primary $DOMAIN                     $DOMAIN.db
primary 1.168.192.in-addr.arpa      $DOMAIN.rev
  
; your static IP number, reversed
primary $IPNUM_REV.in-addr.arpa     dsl.rev

; we got this information from /etc/resolv.conf set up at install time
forwarders                      $NAMESERVERS
EOT

cat >cfg/var/named/namedb/$DOMAIN.db <<EOT
@       IN      SOA     gateway.$DOMAIN.
root.$DOMAIN.
(
                                 14      ; Serial
                                 10800   ; Refresh
                                 3600    ; Retry
                                 604800  ; Expire
                                 86400 ) ; Minimum
  
         IN      NS      gateway.$DOMAIN.
  
  
gateway IN      A       192.168.1.1
; add other machines here
; mypc  IN      A       192.168.1.2
; otherbox IN	A	192.168.1.3
; etc.

; your static IP number
dsl     IN      A       $IPNUM
  
www     IN      CNAME   dsl
mail    IN      CNAME   gateway
gateway IN      CNAME   gateway
EOT

cat >cfg/var/named/namedb/$DOMAIN.rev <<EOT
@       IN      SOA     gateway.$DOMAIN.     root.$DOMAIN. (
                                 14      ; Serial
                                 10800   ; Refresh
                                 3600    ; Retry
                                 604800  ; Expire
                                 86400 ) ; Minimum
  
        IN      NS      gateway.$DOMAIN.
  
  
1       IN      PTR     gateway.$DOMAIN.

; add other machines here...
; 2     IN      PTR     mypc.$DOMAIN.
; 3	IN	PTR	otherbox.$DOMAIN.
; etc.
EOT

cat >cfg/var/named/namedb/dsl.rev <<EOT
@       IN      SOA     gateway.$DOMAIN.     root.$DOMAIN. (
                                14      ; Serial
                                10800   ; Refresh
                                3600    ; Retry
                                604800  ; Expire
                                86400 ) ; Minimum

        IN      NS      gateway.$DOMAIN.
        IN      PTR     dsl.$DOMAIN.
EOT

cat >cfg/etc/resolv.conf <<EOT
search $DOMAIN
nameserver 192.168.1.1
lookup file bind
EOT





#			       smb.conf



mkdir -p cfg/etc/samba
WG=${DOMAIN%.*}
cat >cfg/etc/samba/smb.conf <<EOT
# Global parameters
[global]
        workgroup = $WG
        netbios name = gateway
        server string = bastion host (OpenBSD $OBSD)
        interfaces = 192.168.1.1/24
        security = SHARE
        log file = /var/log/smbd.%m
        max log size = 50
        os level = 0
        local master = No
        dns proxy = No
        hosts allow = 192.168.1.
 
[homes]
        comment = Home Directories
        writeable = Yes
        browseable = No
 
[printers]
        comment = All Printers
        path = /usr/spool/samba
        printable = Yes
        browseable = No
 
[web files]
        comment = Web files exported to the world
        path = /var/www/htdocs
        guest ok = Yes
EOT



#				rc.conf


sed "\
s/^sendmail_flags=.*/sendmail_flags=\"$RCF_SENDMAIL\"/;\
s/^named_flags=.*/named_flags=\"\"/;\
s/^ntpdate_flags=.*/ntpdate_flags=\"$NTP1\"/;\
s/^httpd_flags=.*/httpd_flags=\"$RCF_HTTPD\"/;\
s/^xdm_flags=.*/xdm_flags=\"$RCF_XDM\"/;\
s/^dhcpd_flags=.*/dhcpd_flags=\"-q\"/;\
s/^pf=.*/pf=YES/;\
s/^ntpd=.*/ntpd=YES/;\
s/^smbd=.*/smbd=YES/;\
s/^nmbd=.*/nmbd=YES/;\
" </etc/rc.conf >cfg/etc/rc.conf




#			      sysctl.conf


sed "s/^#net.inet.ip.forwarding=/net.inet.ip.forwarding=1/;$SYSCTL_X11"</etc/sysctl.conf>cfg/etc/sysctl.conf


#				All Done

cat <<EOT

I have written a bunch of files for you in ./cfg - Please look over
everything and if you're happy, copy them to the real locations. You can
do that with this command (as root):
    cd cfg; tar cf - | (cd /; tar xf -)

Please run "newaliases" as root; this will make sure that you get
administrative and security notices from the system.

Then you can start the gateway going by running these commands (as root):
    pfctl -F all -R /etc/pf.conf -N /etc/nat.conf -e
    ntpdate -b $NTP1
    named -t /var/named -u named
    dhcpd -q $INSIDE
    smbd -D
    nmbd -D
(or you could reboot the machine, but you don't have to.)

Also, run "man afterboot" and look over everything it tells you about.

Good luck!

EOT

