%&distorted

\ifx\dumped\xxundefined

\documentclass[article, a4paper, 10pt, notitlepage, numbering]{strayman}
\usepackage[palatino, helvetica, maths=cmr]{mdwfonts}
\usepackage[T1]{fontenc}
\usepackage{at}
\usepackage[mdwmargin]{mdwthm}
\usepackage{mdwtab}
\usepackage[all, dvips]{xy}

\atdef l#1{{\normalfont\sffamily #1}}
\atdef c#1{\textbf{#1}}

\newtheorem*{observation}{Observation}

\def\cbox#1{%
  \vbox{%
    \let\\\cr%
    \halign{%
      \hfil\strut\ignorespaces##\unskip\hfil\cr%
      #1%
      \crcr%
    }%
  }%
}

\errorcontextlines=999

\let\dumped\relax\expandafter\dump\fi

\begin{document}
\title{@l{distorted.org.uk} network design}
\author{Mark Wooding}
\maketitle

\thispagestyle{empty}
\pagestyle{empty}

\tableofcontents
\listoffigures
\listoftables

\clearpage
\pagestyle{fancy}

%%%--------------------------------------------------------------------------
\section{Concepts}

We begin by defining our basic concepts.
\begin{description}
\item[@c{Safe}] A @c{safe} network is one whose hosts are protected from
  potentially dangerous network traffic.  Hosts on a @c{safe} network may
  communicate only (a) using trusted protocols (e.g., SSH) or (b) with
  @c{trusted} hosts.
\item[@c{Trusted}] A @c{trusted} network is one whose hosts are permitted to
  communicate with @c{safe} networks.
\end{description}

\begin{observation}
  It is impossible to protect hosts on a @c{safe} network from each other.
  Therefore, a @c{safe} network must be @c{trusted}.  As an immediate
  corollary, an @c{untrusted} network cannot be @c{safe}.
\end{observation}

We therefore distinguish three types of networks:
\begin{enumerate}
\item @c{Safe}, and therefore @c{trusted}.
\item @c{Trusted} but @c{unsafe}.
\item @c{Untrusted}, and therefore @c{unsafe}.
\end{enumerate}


%%%--------------------------------------------------------------------------
\section{Existing hosts}

We have the following hosts.  All of them should be @c{trusted}.
\begin{description}
\item[@l{metalzone}] A Linux server and desktop machine.  It is capable of
  providing most services to the network, including mail, news, web proxying,
  etc., and of providing services to the Internet at large.  It can also
  provide a powerful and versatile firewall.  It should not be kept @c{safe}.
\item[@l{tubescreamer}] A dual-boot Linux desktop and Windows desktop.  It
  spends most of its time running Windows.  It must be kept @c{safe}.
\item[@l{fuzzface}] A small Linux laptop.  It doesn't have enough disk
  capacity for running services, and wouldn't be around or turned on
  regularly enough anyway, but it is capable of firewalling itself.  We'd
  like to attach this to a wireless network.  It need not be kept @c{safe}
  and we'd like it to be @c{trusted}.
\item[@l{guvnor}] An ADSL router.  It is capable of providing minimal
  services, and it has a fairly powerful firewall built-in.  It must not be
  kept @c{safe}.
\item[@l{evolution}] (Not yet commissioned.)  A wireless access point.  It is
  capable of running Linux, but due to limited memory capacity cannot provide
  many services.  It has a powerful and versatile firewall.  It cannot be
  kept @c{safe}.
\end{description}

We may also have guest machines.  We suspect that keeping these @c{safe}
would be onerous to our guests, requiring configuration of web proxies and
suchlike.  Guest machines can probably be @c{trusted}: violations of this
trust can be rectified using a cluebat.

%%%--------------------------------------------------------------------------
\section{Structure}

We require the following physical networks.
\begin{itemize}
\item A (wired) Ethernet, for the permanent desktop machines and servers, and
  for any guest hosts which need physical wiring.
\item A wireless Ethernet, for laptops.
\end{itemize}


\subsection{The wired network}

Some hosts on our wired network (particularly @l{tubescreamer}) must be
@c{safe}; others (e.g., @l{metalzone}) must not in order for them to do their
jobs.  It is tempting to split the wired network into two parts: @c{unsafe}
and @c{safe}.  But this introduces a new potential point of failure, and
anyway fails to acknowledge the fact that both sides are already @c{trusted}.


\subsection{The wireless network}

It is important to note that the security provided by wireless networks is
minimal, and cannot be relied upon.  Therefore a wireless network must be
both @c{untrusted} and @c{unsafe}.  We may allow unrestricted communication
with the global Internet, and to other @c{unsafe} networks, though hosts on
the wireless network must not be allowed to communicate with @c{safe}
networks.

This restriction is annoying, and motivates us to introduce a @/virtual
private network/, providing authentication and encryption; hosts on the VPN
can be @c{trusted}, since we know who they are and (ideally) how they're
configured.


\subsection{Virtual private networks}

As discussed earlier, we want a VPN so that hosts attached to the wireless
network can communicate with @c{safe} hosts.  Also, we wish to participate in
the Sinister Green VPN.  This introduces two kinds of VPN: our own can be
@c{trusted}, but the SGVPN should not be.

The question arises: should our VPN be @c{safe}?  We can see no particular
reasons why it shouldn't be: after all, a host on the VPN already has a route
to the global Internet (either it's communicating with us over the Internet
already, or it's on some @c{unsafe} network).

Finally, we wish to provide some @/emulated hosts/, running old operating
systems; for example, a machine running ITS.%
  \footnote{The Incompatible Timesharing System -- an old PDP--10 operating
    system, which hosted MACLISP and the original EMACS implementation.}
Such old operating systems are likely to have major security problems, and
should be kept @c{safe} from outside attack.  It seems reasonable to place
these emulated hosts in the @l{virtual} network, since (a)~we've just
determined that @l{virtual} hosts should be @c{safe}, and (b)~emulated hosts
are `virtual' in a sense anyway.


%%%--------------------------------------------------------------------------
\section{Networks and numbering}

We therefore have the following networks.
\begin{description}
\item[@l{fretwank} (wired, @c{safe}/@c{unsafe} mix)] Contains @l{guvnor}
  (router to the Internet and main firewall), @l{metalzone} (main server),
  @l{evolution} (wireless router), and @l{tubescreamer}.  Also contains guest
  machines allocated addresses by DHCP.
\item[@l{wireless} (wireless, @c{untrusted})] Contains @l{fuzzface}, at least
  sometimes, and a number of guest machines allocated addresses by DHCP;
  @l{evolution} is its router.
\item[@l{virtual} (virtual, @c{safe})] Contains @l{fuzzface} again, and
  possibly various other hosts.  Not really a proper network: more a random
  collection of point-to-point associations.  No dynamic allocation required.
\end{description}
See figure~\ref{fig:network} for a diagrammatic representation of the
network, and how the various hosts fit into it.

\begin{figure}
  \[\begin{xy}
    0; <1cm, 0cm>:
    (0, 0) ="fwA"; (11, 0) ="fwB" **[butt][|3pt][=NET]@{-},
    ?(.5) ="fwM" ?(.18) ="fwX" ?(.82) ="fwY",
    "fwM" *+!U\cbox{@l{fretwank} (172.29.199.0/25)},
    "fwM" + (0, 2) *+=(3, 1.5)[F:<12pt>][F*:green:<12pt>]
      \cbox{@l{guvnor} \\ 83.105.60.35 \\ 172.29.199.1} ="guvnor",
    "guvnor"; "fwM" **@{-},
    "guvnor"; + (0, 4)
      *+=(4, 3)[o][F][F*:red] \cbox{Global \\ Internet}
      **@{-} ?<>(.5) *@{//} *+!L{A},
    "fwY"; p + (0, 2)
      *+=(3, 1.5)[F:<12pt>]\cbox{(DHCP guests)}
      **@{-},
    "fwY"; p - (0, 2)
      *+=(3, 1.5)[F:<12pt>][F*:green:<12pt>]
        \cbox{@l{evolution} \\ 172.29.198.1 \\ 172.29.199.3} ="evolution"
      **@{-},  
    "fwX"; p + (0, 2)
      *+=(3, 1.5)[F:<12pt>][F*:yellow:<12pt>]
        \cbox{@l{tubescreamer} \\ 172.29.199.65}
      **@{-},
    "fwX"; p - (0, 2)
      *+=(3, 1.5)[F:<12pt>][F*:green:<12pt>]
        \cbox{@l{metalzone} \\ 172.29.199.2} ="metalzone"
      **@{-},
    "metalzone" + (-3, 1) ="sgvpnA"; p - (0, 10) ="sgvpnB" **[NET]@{-},
    ?(.5) ="sgvpnM",
    "sgvpnM" *[left]+!R\cbox{SGO VPN (various RFC1918 addresses)},
    "metalzone"; p - (3, 0) **@{-} ?<>(.5) *@{//} *+!U{B},
    "metalzone" + (3, 1) ="vpnA"; p - (0, 8) ="vpnB" **[NET]@{-},
    ?(.5) ="vpnM",
    "vpnM" *[left]+!L\cbox{@l{virtual} (172.29.199.128/28)},
    "metalzone"; p + (3, 0) **@{-} ?<>(.5) *@{//} *+!U{C},
    "metalzone" - (0, 2)
      *+=(3, 1.5)[F:<12pt>][F*:yellow:<12pt>]
        \cbox{@l{fuzzface} \\ 172.29.199.129} ="fuzzface";
      p + (3, 0) **@{-},
    "fuzzface" - (0, 2)
      *+=(3, 1.5)[F:<12pt>][F*:yellow:<12pt>]
        \cbox{@l{mz} \\ 172.29.199.130} ="mz";
      p + (3, 0) **@{-},
    "mz" - (0, 2)
      *+=(3, 1.5)[F:<12pt>]\cbox{(VPN hosts)} ="x";
      p + (3, 0) **@{-},
    "x" - (0, 2)
      *+=(3, 1.5)[F:<12pt>]\cbox{(SGO hosts)} ="x";
      p - (3, 0) **@{-},
    "evolution" + (3, 1) ="wlanA"; p - (0, 4) ="wlanB" **[NET]@{-},
    ?(.5) ="wlanM",
    "wlanM" *[left]+!L\cbox{@l{wireless} (172.29.198.0/26)},
    "evolution"; p + (3, 0) **@{-} ?<>(.5) *@{//} *+!U{D},
    "evolution" - (0, 2)
      *+=(3, 1.5)[F:<12pt>]\cbox{(DHCP guests)};
      p + (3, 0) **@{-},
  \end{xy}\]

  \caption{Diagram of @l{distorted.org.uk} networks}
  \label{fig:network}
\end{figure}

We must assign address ranges to these networks.  The @l{distorted.org.uk}
domain has a block of 512 addresses allocated from the Cambridge G-RIN:
172.29.198.0/23.  The low 256 addresses, 172.29.198.0/24, are used for
@c{untrusted} hosts; the upper addresses, 172.29.199.0/24, are used for
@c{trusted} and @c{safe} hosts.

The @c{untrusted} address range is currently only used for the @l{wireless}
network.  It is allocated 64 addresses.  This seems relatively generous:
however, there is no small practical limit (such as the number of available
ports on switches or hubs) on the number of hosts which can join the network.
Since hosts on the network are granted temporary addresses via DHCP, the
network can be resized relatively easily by reconfiguring @l{evolution}: a
major flag day is not necessary.

The @c{trusted} network is more difficult.  We start with the wired Ethernet
@l{fretwank}.  The number of hosts which can join the Ethernet is limited by
the number of available ports on the various switches and hubs.  Currently we
have
\begin{itemize}
\item 4 ports on @l{guvnor}'s built-in switch,
\item 8 ports on a Netgear fast Ethernet switch, and
\item 16 ports on an old 10baseT hub,
\end{itemize}
for a total of 28 ports.  (In fact, the total is only 24, since four of the
ports would be used up joining the hub and switches together.)  Hence, a
single block of 32 addresses would suffice.  However, this makes
administration difficult.  Instead, we allocate @/four/ groups of 32
addresses:
\begin{itemize}
\item a group for @c{trusted} but @c{unsafe} hosts with fixed addresses, used
  for servers and routers;
\item a group for @c{safe} hosts with fixed addresses, used for our
  vulnerable workstations;
\item a group for @c{trusted} but @c{unsafe} hosts with addresses dynamically
  allocated by DHCP, for guests; and
\item a group of addresses reserved for some currently unforeseen purpose.
\end{itemize}

The VPN is at this stage allocated 32 addresses.  This can be increased
easily should the need arise; but we envisage that the various VPN hosts will
each need individual treatment in the firewall rules.

The network address allocations are shown in detail in
table~\ref{tab:addresses}.

\begin{table}
  \begin{tabular}[C]{|lll|}                                         \hlx{hv}
    @*Network*       & @*Status*       & @*Address range*        \\ \hlx{vhv}
    @l{wireless}     & @c{Untrusted}   & 172.29.198.0/26 (64)    \\ \hlx{v}
    @l{fretwank}     & Mixture         & 172.29.199.0/25 (128)   \\
    \quad Unsafe, fixed & @c{Trusted}  & 172.29.199.0/27 (32)    \\
    \quad Unsafe, DHCP & @c{Trusted}   & 172.29.199.32/27 (32)   \\
    \quad Safe       & @c{Safe}        & 172.29.199.64/27 (32)   \\
    \quad Reserved   & ---             & 172.29.199.96/27 (32)   \\ \hlx{v}
    @l{virtual}      & @c{Safe}        & 172.29.199.128/27 (32)  \\ \hlx{v}
    Reserved         & ---             & $\vcenter{
      \hbox{172.29.199.160/27 (32)}
      \hbox{172.29.199.192/26 (64)}
    } \Bigr\}$ (96)                                             \\ \hlx{vh}
  \end{tabular}

  \caption{Network address allocations}
  \label{tab:addresses}
\end{table}


%%%--------------------------------------------------------------------------
\section{Firewall considerations}

We filter network traffic at four points, shown as
`$\begin{xy}*+@{//}\end{xy}$' in figure~\ref{fig:network}:
\begin{itemize}
\item at the boundary with the global Internet, at @l{guvnor} ($A$);
\item at the join between the @l{wireless} network and our @c{trusted}
  networks, at @l{evolution} ($D$); and
\item at the join between the VPNs and our @c{trusted} networks, ($B$ and
  $C$).
\end{itemize}
(Technically, since we trust hosts on @l{virtual}, we needn't introduce
filtering between it and @l{fretwank}, but doing so is cheap and relatively
easy, and it does little harm.)

The main purpose of the firewalls is to protect the hosts which are supposed
to be @c{safe}.  Their secondary purposes are to act as an additional
protection for @c{trusted} hosts providing services, and to limit access to
some services to @c{trusted} hosts only.


\subsection{Externally visible services}

The server @l{metalzone} provides a number of services which need to be
externally available: these are shown in table~\ref{tab:services}.

\begin{table}
  \centering
  \begin{minipage}{0.8\textwidth}
  \begin{tabular}[C]{|*{3}{ll|}}                                    \hlx{hv}
    @*Service* & @*Port(s)* &
      @*Service* & @*Port(s)* &
      @*Service* & @*Port(s)*                                    \\ \hlx{vhv}
    FTP & TCP 20, 21     & SSH & TCP 22     & SMTP & TCP 25      \\
    DNS & TCP/UDP 53     & Finger & TCP 79  & HTTP & TCP 80      \\
    Ident & TCP 113      & NTP & UDP 123%
      %%\footnote{Only to upstream ISP's time servers.}
                                            & HTTPS & TCP 443    \\
    TrIPE & UDP 22\,003
      & \multicolumn{2}{c|}{---}
      & \multicolumn{2}{c|}{---}                                 \\ \hlx{vh}
  \end{tabular}
  \end{minipage}

  \caption{Externally visible services}
  \label{tab:services}
\end{table}

Additionally, @l{metalzone} provides a web proxy on port 3128 which should be
available to all hosts, including @c{untrusted} hosts, whose connection to
the global Internet is via @l{guvnor}.  (Allowing external users to use the
proxy is bad, because they can eat up our 'net connection bandwidth very
easily.  Disallowing @c{untrusted} hosts from using the proxy is silly,
though, since they can @/already/ gobble the 'net connection, and using the
proxy may help reduce the impact of many users.)

Finally, @l{metalzone} supports active FTP, and occasionally other temporary
services, on high-numbered ports.  TCP and UDP ports with numbers in the
range 32\,000--65\,535 should be left unfiltered.


\subsection{Trusted protocols}

All hosts, including @c{safe} hosts, are permitted to contact any address on
TCP port~22, for the purpose of setting up an SSH connection.  (Messing about
with proxies for SSH is too tedious.)  So that this can stand a chance of
working properly, we also allow ICMP.  This isn't, perhaps, ideal, but all
manner of things go wrong if ICMP is blocked.  Besides, it means that @/ping/
is likely to work, which is also useful.




%%% A
%%%   1. Packets from WAN
%%%        if src-addr in rfc1918-addresses: DROP
%%%        if src-addr in localnet: DROP
%%%        if src-addr == guvnor.demon: DROP
%%%        if dest-addr not in distorted-net: DROP
%%%        if protocol == icmp: ACCEPT
%%%        if protocol == tcp and src-port == 22 and ack: ACCEPT
%%%        if dest-addr in fretwank-safe: DROP
%%%        if dest-addr in vpn: DROP
%%%        if protocol == tcp and ack: ACCEPT
%%%        if dest-addr == metalzone.fretwank and
%%%           protocol/dest-port in external-services:
%%%          ACCEPT
%%%        DENY
%%%
%%%   2. Packets from LAN
%%%      if src-addr not in distorted-net: DROP
%%%      ACCEPT

%%% D
%%%   1. Packets from WLAN
%%%        if src-addr not in wireless: DROP
%%%        if dest-addr not in distorted-net: DROP
%%%        if protocol == icmp: ACCEPT
%%%        if protocol == tcp and src-port == 22 and ack: ACCEPT
%%%        if dest-addr in fretwank-safe: DROP
%%%        if dest-addr in vpn: DROP
%%%        if protocol == tcp and ack: ACCEPT
%%%        if dest-addr == metalzone.fretwank and
%%%           (protocol/dest-port in external-services or
%%%            protocol == tcp and dest-port == 3128):
%%%          ACCEPT
%%%        DENY
%%%


\end{document}
