<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.ampr.org/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Cross</id>
	<title>44Net Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.ampr.org/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Cross"/>
	<link rel="alternate" type="text/html" href="https://wiki.ampr.org/wiki/Special:Contributions/Cross"/>
	<updated>2026-05-05T07:15:45Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.42.3</generator>
	<entry>
		<id>https://wiki.ampr.org/w/index.php?title=IPIP_Mesh/Quick_Start&amp;diff=2443</id>
		<title>IPIP Mesh/Quick Start</title>
		<link rel="alternate" type="text/html" href="https://wiki.ampr.org/w/index.php?title=IPIP_Mesh/Quick_Start&amp;diff=2443"/>
		<updated>2026-03-20T13:10:41Z</updated>

		<summary type="html">&lt;p&gt;Cross: Link to setting up a gateway on OpenBSD&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{DISPLAYTITLE:IPIP Mesh Quick Start (Stub)}}&lt;br /&gt;
&lt;br /&gt;
== What this page is ==&lt;br /&gt;
This is an orientation stub for joining the shared IPIP Mesh model on 44Net.&lt;br /&gt;
A full quick start procedure is not published yet.&lt;br /&gt;
&lt;br /&gt;
== What you can do today ==&lt;br /&gt;
* Confirm that a shared mesh model fits your goals in [[Provisioning Methods|Provisioning Methods]].&lt;br /&gt;
* Complete account and verification prerequisites in [[GetStarted|Getting started]] and [[Portal/Sign Up|Portal Sign Up]].&lt;br /&gt;
* Identify local or regional peers and gateway expectations via [[Community|Community and mailing lists]].&lt;br /&gt;
* Review routing responsibilities in [[Routing|Routing and connectivity]].&lt;br /&gt;
&lt;br /&gt;
== What this page will cover ==&lt;br /&gt;
* Prerequisites for mesh participation and peering.&lt;br /&gt;
* Endpoint setup expectations and addressing model.&lt;br /&gt;
* Shared gateway behavior and traffic flow patterns.&lt;br /&gt;
* Operational coordination with regional maintainers.&lt;br /&gt;
* Validation and troubleshooting checklist.&lt;br /&gt;
&lt;br /&gt;
== Related pages ==&lt;br /&gt;
* [[Provisioning Methods|Provisioning Methods]]&lt;br /&gt;
* [[GetStarted|Getting started]]&lt;br /&gt;
* [[Routing|Routing and connectivity]]&lt;br /&gt;
* [[Community|Community and mailing lists]]&lt;br /&gt;
* [[Portal/Request Address Space|Request Address Space]]&lt;br /&gt;
* [[Contributing|Contributing]]&lt;br /&gt;
* [[Decentralization|How Connect, IPIP Mesh, and BGP fit together]]&lt;br /&gt;
&lt;br /&gt;
== Contribute / next steps ==&lt;br /&gt;
If you already operate in the mesh, contribute a minimal reproducible setup path with topology notes and failure modes. Submit through [[Contributing]] so this stub can become a complete Quick Start.&lt;br /&gt;
&lt;br /&gt;
== Older docs and notes ==&lt;br /&gt;
Earlier pages that may still be useful:&lt;br /&gt;
* [[Gateway]]&lt;br /&gt;
* [[Registering Your Gateway]]&lt;br /&gt;
* [[Encap.txt]]&lt;br /&gt;
* [[Encap.txt/get-encap]]&lt;br /&gt;
* [[Rip44d]]&lt;br /&gt;
* [[RIP44.lua]]&lt;br /&gt;
* [[Amprgw]]&lt;br /&gt;
* [[Ampr-ripd]]&lt;br /&gt;
* [[Setting up a gateway on Linux]]&lt;br /&gt;
* [[Setting up a gateway on OpenBSD]]&lt;br /&gt;
* See [[Archive]] for more.&lt;br /&gt;
[[Category:Participation Methods]]&lt;br /&gt;
[[Category:IPIP Mesh]]&lt;br /&gt;
[[Category:Getting Started]]&lt;/div&gt;</summary>
		<author><name>Cross</name></author>
	</entry>
	<entry>
		<id>https://wiki.ampr.org/w/index.php?title=DNS&amp;diff=1121</id>
		<title>DNS</title>
		<link rel="alternate" type="text/html" href="https://wiki.ampr.org/w/index.php?title=DNS&amp;diff=1121"/>
		<updated>2024-06-02T12:37:23Z</updated>

		<summary type="html">&lt;p&gt;Cross: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= DNS: The Domain Name System =&lt;br /&gt;
&lt;br /&gt;
The Domain Name System is the primary mechanism by which symbolic host names, such as &#039;&#039;kz2x.ampr.org&#039;&#039; are translated into numeric host IP addresses, such as 44.44.48.2.  It is implemented as a network protocol, with clients sending &#039;&#039;queries&#039;&#039; to servers, that uses the network itself to perform translations.  The DNS protocol is an Internet standard that is defined by a set of &amp;quot;Request for Comment&amp;quot; documents, or RFCs; the current revision of the DNS specification is in [https://datatracker.ietf.org/doc/html/rfc1035 RFC1035].  It is used heavily on AMPRNet.&lt;br /&gt;
&lt;br /&gt;
== Historical Background ==&lt;br /&gt;
&lt;br /&gt;
Before DNS, individual sites on the Internet maintained a local mapping of host names to IP addresses in the form of a &amp;quot;hosts&amp;quot; file; this was often a text file resident on each Internet-connected computer.  However, this quickly became untenable as the network grew: not only did the file itself become so large as to be unwieldy and slow to search, keeping it up to date required significant effort.  Furthermore, coordinating updates from many different organizations, and avoiding name collisions as new hosts were added, added even more complexity.&lt;br /&gt;
&lt;br /&gt;
A clever insight was that the problem could be addressed using the network itself, by providing a network service that could translate between host names and IP addresses.  Early work around this idea ultimately lead to the design of the DNS.&lt;br /&gt;
&lt;br /&gt;
== Concepts ==&lt;br /&gt;
&lt;br /&gt;
The DNS uses the client/server model, in which &#039;&#039;client&#039;&#039; machines send name related &#039;&#039;queries&#039;&#039; to DNS &#039;&#039;servers&#039;&#039; scattered around the Internet, which in turn, provide answers.  The process of answering a query is called &amp;quot;resolution.&amp;quot;  Resolved queries may be &amp;quot;cached&amp;quot; by servers for some period of time, called the &amp;quot;time to live&amp;quot; or TTL, given by the source server.  The DNS allows clients to make queries for a fixed set of types of information for a particular &#039;&#039;domain name&#039;&#039;.  For example, one might request make an &amp;quot;address&amp;quot; (or &amp;quot;A&amp;quot;) query for a name.  For each name, a set of &amp;quot;records&amp;quot; corresponding to these  information types name are input by an administrator and held in some DNS server; these are called &amp;quot;resource records&amp;quot; or &amp;quot;RRs&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Domains, Zones, and Authority ===&lt;br /&gt;
&lt;br /&gt;
Names are hierarchical, and organized into &#039;&#039;domains&#039;&#039;: Starting from &amp;quot;.&amp;quot;, the &amp;quot;root&amp;quot;, and descending through a &amp;quot;top-level&amp;quot; domain (TLD) such &amp;quot;.org&amp;quot;, then through an organizational domain such as &amp;quot;ampr&amp;quot;. Each such level forms a &amp;quot;domain&amp;quot;, so that &amp;quot;.org&amp;quot; and &amp;quot;ampr.org&amp;quot; are separate domains. This organization provides resilience against collisions, since names need only be unique within a domain, and facilitates separation of administrative concerns.&lt;br /&gt;
&lt;br /&gt;
Collections of domains that fall under a single administrative entity form &amp;quot;zones&amp;quot;.  A zone is said to be &#039;&#039;authoritative&#039;&#039; for the domains under its control, but not otherwise; non-authoritative data typically comes out of caches established in response to earlier queries.  Authoritative responses to queries always override cached data.&lt;br /&gt;
&lt;br /&gt;
Just as domain names are hierarchical, DNS servers are also arranged into a logical hierarchy, where different servers are responsible for providing information about names at different levels of the domain hierarchy; this is done by means of &#039;&#039;NS&#039;&#039; resource records, which point to the name servers for a given domain.  At the root are a set of &amp;quot;root servers,&amp;quot; the IP addresses of which are well-known: these provide information about top-level domains like &amp;quot;.org&amp;quot;, and specifically include NS RRs for the name servers that are known to be authoritative for those domains.  Subsequent levels are organized similarly: each server at some level provides information about servers at the next level, and so on.&lt;br /&gt;
&lt;br /&gt;
=== Servers, Resolvers, and Stub Resolvers ===&lt;br /&gt;
&lt;br /&gt;
As mentioned, clients resolve requests for information about domain names by sending queries to servers, but different kinds of servers play different roles:&lt;br /&gt;
&lt;br /&gt;
* Non-Recursive, Authoritative Servers, or just Authoritative Servers, are the ultimate sources of authority for domains under a zone.  They only accept queries for the domains in the zones they are authoritative for and answer them either with resolved data or with an error, such as when a query is issued for name that does not exist.&lt;br /&gt;
* Resolvers, or Recursive Servers, are intermediaries; they accept &amp;quot;recursive&amp;quot; queries and forward these to other servers until they receive a definitive reply.  They then usually cache the results so that subsequent requests for the same query can be answered quickly.  The cached data expires once its TTL is exceeded.&lt;br /&gt;
* Stub resolvers are small bits of software embedded in client programs that make DNS queries: these program fragments send queries to remote servers and interpret the results, providing them to the rest of the program.&lt;br /&gt;
&lt;br /&gt;
Usually, any program that wants to make use of the DNS will do so via a stub resolver, which will forward the query to some recursive server. The stub resolver learns what recursive server to send its queries to via some administrative mechanism; for example, a DHCP server might supply the IP address of the server to use, or the stub might look in a file on the local system.  The name servers the stub sends requests to must be given by IP address; doing otherwise would create a chicken and egg problem, since the whole point is that the DNS is way we translate names into addresses.&lt;br /&gt;
&lt;br /&gt;
= Setting Up a Recursive Resolver on OpenBSD =&lt;br /&gt;
&lt;br /&gt;
[https://www.openbsd.org OpenBSD] is a variant of Unix known for security and a focus on code correctness.  It also comes bundled with a high performance caching, validating, recursive DNS resolver package called [https://www.nlnetlabs.nl/projects/unbound/about/ Unbound]. Unbound is easily configured, we will give an example of doing so here.&lt;br /&gt;
&lt;br /&gt;
== Configuring the unbound server ==&lt;br /&gt;
&lt;br /&gt;
The first step is to configure the server by editing its configuration file, &amp;lt;code&amp;gt;/var/unbound/etc/unbound.conf&amp;lt;/code&amp;gt;.  The format and allowable settings in this file are given in the man page, [https://man.openbsd.org/unbound.conf &#039;&#039;unbound.conf&#039;&#039;(5)], but at a high level it contains several sections:&lt;br /&gt;
&lt;br /&gt;
* A &amp;lt;code&amp;gt;server:&amp;lt;/code&amp;gt; section allows us to set settings for the server itself.&lt;br /&gt;
* A &amp;lt;code&amp;gt;remote-control:&amp;lt;/code&amp;gt; section lets setup access for a control client.&lt;br /&gt;
* An arbitrary number of optional zone-specific sections that allow us to configure options for those zones.  This gives us the ability to forward to specific authoritative servers for a zone and so on.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s an example of what a configuration file might look like:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;server:&lt;br /&gt;
        interface: 0.0.0.0&lt;br /&gt;
        interface: ::0&lt;br /&gt;
&lt;br /&gt;
        access-control: 0.0.0.0/0 refuse&lt;br /&gt;
        access-control: ::0/0 refuse&lt;br /&gt;
&lt;br /&gt;
        access-control: 127.0.0.0/8 allow&lt;br /&gt;
        access-control: ::1 allow&lt;br /&gt;
&lt;br /&gt;
        access-control: 44.0.0.0/9 allow&lt;br /&gt;
        access-control: 44.128.0.0/10 allow&lt;br /&gt;
&lt;br /&gt;
        hide-identity: yes&lt;br /&gt;
        hide-version: yes&lt;br /&gt;
&lt;br /&gt;
        # Perform DNSSEC validation.&lt;br /&gt;
        auto-trust-anchor-file: &amp;quot;/var/unbound/db/root.key&amp;quot;&lt;br /&gt;
        val-log-level: 2&lt;br /&gt;
&lt;br /&gt;
        # Synthesize NXDOMAINs from DNSSEC NSEC chains.&lt;br /&gt;
        # https://tools.ietf.org/html/rfc8198&lt;br /&gt;
        #&lt;br /&gt;
        aggressive-nsec: yes&lt;br /&gt;
&lt;br /&gt;
        # Use TCP for &amp;quot;forward-zone&amp;quot; requests. Useful if you are making&lt;br /&gt;
        # DNS requests over an SSH port forwarding.&lt;br /&gt;
        #tcp-upstream: yes&lt;br /&gt;
&lt;br /&gt;
        # CA Certificates used for forward-tls-upstream (RFC7858) hostname&lt;br /&gt;
        # verification.  Since it&#039;s outside the chroot it is only loaded at&lt;br /&gt;
        # startup and thus cannot be changed via a reload.&lt;br /&gt;
        #tls-cert-bundle: &amp;quot;/etc/ssl/cert.pem&amp;quot;&lt;br /&gt;
&lt;br /&gt;
remote-control:&lt;br /&gt;
        control-enable: yes&lt;br /&gt;
        control-interface: /var/run/unbound.sock&lt;br /&gt;
&lt;br /&gt;
stub-zone:&lt;br /&gt;
        name: &amp;quot;ampr.org.&amp;quot;&lt;br /&gt;
        stub-addr: 44.1.1.44&lt;br /&gt;
        stub-host: ns2.us.ardc.org&lt;br /&gt;
        stub-host: ns.ardc.org&lt;br /&gt;
        stub-host: ns1.de.ardc.org&lt;br /&gt;
        stub-host: a.gw4.uk&lt;br /&gt;
&lt;br /&gt;
stub-zone:&lt;br /&gt;
        name: &amp;quot;44.in-addr.arpa.&amp;quot;&lt;br /&gt;
        stub-addr: 44.1.1.44&lt;br /&gt;
        stub-host: ns2.us.ardc.org&lt;br /&gt;
        stub-host: ns.ardc.org&lt;br /&gt;
        stub-host: ns1.de.ardc.org&lt;br /&gt;
        stub-host: a.gw4.uk&lt;br /&gt;
        stub-first: yes&lt;br /&gt;
&lt;br /&gt;
stub-zone:&lt;br /&gt;
        name: &amp;quot;128.44.in-addr.arpa.&amp;quot;&lt;br /&gt;
        stub-addr: 44.1.1.44&lt;br /&gt;
        stub-host: ns2.us.ardc.org&lt;br /&gt;
        stub-host: ns.ardc.org&lt;br /&gt;
        stub-host: ns1.de.ardc.org&lt;br /&gt;
        stub-host: a.gw4.uk&lt;br /&gt;
        stub-first: yes&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This configuration sets some non-default options in the &amp;lt;code&amp;gt;server:&amp;lt;/code&amp;gt; section, such as what interface to listen on for incoming connections, and options for what machines are allowed to send us queries.  Here, we listen on all addresses on all interfaces for both IPv4 and IPv6 and we allow any AMPRNet host to send us queries.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;remote-control:&amp;lt;/code&amp;gt; section enables and configures a Unix domain socket that allows us to control the unbound daemon with the client control program, &amp;lt;code&amp;gt;unbound-control&amp;lt;/code&amp;gt;; this way, we can ask it for performance and usage statistics, force it to flush its cache, etc, without stopping and restarting it.&lt;br /&gt;
&lt;br /&gt;
The most interesting parts are the &amp;lt;code&amp;gt;stub-zone:&amp;lt;/code&amp;gt; sections.  These allow us to tell unbound about servers that are authoritative for particular zones, bypassing querying through the root for domains under those zones.  In the three sections given here, we tell it to query the ARDC-administered non-recursive authoritative servers for the &#039;&#039;ampr.org&#039;&#039;, &#039;&#039;44.in-addr.arpa&#039;&#039; and &#039;&#039;128.44.in-addr.arpa&#039;&#039; zones; that is, for anything related to AMPRNet, we forward directly to the authoritative servers.&lt;br /&gt;
&lt;br /&gt;
Note the &amp;lt;code&amp;gt;stub-first: yes&amp;lt;/code&amp;gt; lines for the two reverse domains: some reverse domains are &#039;&#039;delegated&#039;&#039; to other services.  This line says to try the ARDC servers first, and if those return an error, to perform the standard query from the root.&lt;br /&gt;
&lt;br /&gt;
Once the server is configured, we can enable it by adding a line to &amp;lt;code&amp;gt;/etc/rc.conf.local&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;unbound_flags=&amp;quot;&amp;quot;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now, if we reboot, we will find the unbound daemon running the next time we login.  We should be able to direct DNS queries to the local server now, and we can edit the &amp;lt;code&amp;gt;/etc/resolv.conf&amp;lt;/code&amp;gt; file to include a reference to our unbound instance.  For example, our resolv.conf file might look something like:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;lookup file bind&lt;br /&gt;
domain your-call.ampr.org&lt;br /&gt;
search your-call.ampr.org ampr.org&lt;br /&gt;
nameserver 127.0.0.1&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Of course, one likely wants to query one&#039;s own callsign based subdomain, not &amp;quot;your-call&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Now, other machines can be configured to connect to your unbound instance.  Here is an example from a machine at KZ2X:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;lookup file bind&lt;br /&gt;
domain kz2x.ampr.org&lt;br /&gt;
search kz2x.ampr.org ampr.org&lt;br /&gt;
nameserver 44.44.48.29&lt;br /&gt;
nameserver 8.8.8.8&lt;br /&gt;
nameserver 1.1.1.1&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that &amp;lt;code&amp;gt;44.44.48.29&amp;lt;/code&amp;gt; is the machine that runs unbound.&lt;br /&gt;
&lt;br /&gt;
Congratulations!  You have set up a caching, validating, recursive resolver that can serve DNS to any machine on AMPRNet.&lt;/div&gt;</summary>
		<author><name>Cross</name></author>
	</entry>
	<entry>
		<id>https://wiki.ampr.org/w/index.php?title=DNS&amp;diff=1120</id>
		<title>DNS</title>
		<link rel="alternate" type="text/html" href="https://wiki.ampr.org/w/index.php?title=DNS&amp;diff=1120"/>
		<updated>2024-06-02T01:37:28Z</updated>

		<summary type="html">&lt;p&gt;Cross: Add OpenBSD example&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= DNS: The Domain Name System =&lt;br /&gt;
&lt;br /&gt;
The Domain Name System is the primary mechanism by which symbolic host names, such as &#039;&#039;kz2x.ampr.org&#039;&#039; are translated into numeric host IP addresses, such as 44.44.48.2.  It is implemented as a network protocol, with clients sending &#039;&#039;queries&#039;&#039; to servers, that uses the network itself to perform translations.  The DNS protocol is an Internet standard that is defined by a set of &amp;quot;Request for Comment&amp;quot; documents, or RFCs; the current revision of the DNS specification is in [https://datatracker.ietf.org/doc/html/rfc1035 RFC1035].  It is used heavily on AMPRNet.&lt;br /&gt;
&lt;br /&gt;
== Historical Background ==&lt;br /&gt;
&lt;br /&gt;
Before DNS, individual sites on the Internet maintained a local mapping of host names to IP addresses in the form of a &amp;quot;hosts&amp;quot; file; this was often a text file resident on each Internet-connected computer.  However, this quickly became untenable as the network grew: not only did the file itself become so large as to be unwieldy and slow to search, keeping it up to date required significant effort.  Furthermore, coordinating updates from many different organizations, and avoiding name collisions as new hosts were added, added even more complexity.&lt;br /&gt;
&lt;br /&gt;
A clever insight was that the problem could be addressed using the network itself, by providing a network service that could translate between host names and IP addresses.  Early work around this idea ultimately lead to the design of the DNS.&lt;br /&gt;
&lt;br /&gt;
== Concepts ==&lt;br /&gt;
&lt;br /&gt;
The DNS uses the client/server model, in which &#039;&#039;client&#039;&#039; machines send name related &#039;&#039;queries&#039;&#039; to DNS &#039;&#039;servers&#039;&#039; scattered around the Internet, which in turn, provide answers.  The process of answering a query is called &amp;quot;resolution.&amp;quot;  Resolved queries may be &amp;quot;cached&amp;quot; by servers for some period of time, called the &amp;quot;time to live&amp;quot; or TTL, given by the source server.  The DNS allows clients to make queries for a fixed set of types of information for a particular &#039;&#039;domain name&#039;&#039;.  For example, one might request make an &amp;quot;address&amp;quot; (or &amp;quot;A&amp;quot;) query for a name.  For each name, a set of &amp;quot;records&amp;quot; corresponding to these  information types name are input by an administrator and held in some DNS server; these are called &amp;quot;resource records&amp;quot; or &amp;quot;RRs&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Domains, Zones, and Authority ===&lt;br /&gt;
&lt;br /&gt;
Names are hierarchical, and organized into &#039;&#039;domains&#039;&#039;: Starting from &amp;quot;.&amp;quot;, the &amp;quot;root&amp;quot;, and descending through a &amp;quot;top-level&amp;quot; domain (TLD) such &amp;quot;.org&amp;quot;, then through an organizational domain such as &amp;quot;ampr&amp;quot;. Each such level forms a &amp;quot;domain&amp;quot;, so that &amp;quot;.org&amp;quot; and &amp;quot;ampr.org&amp;quot; are separate domains. This organization provides resilience against collisions, since names need only be unique within a domain, and facilitates separation of administrative concerns.&lt;br /&gt;
&lt;br /&gt;
Collections of domains that fall under a single administrative entity form &amp;quot;zones&amp;quot;.  A zone is said to be &#039;&#039;authoritative&#039;&#039; for the domains under its control, but not otherwise; non-authoritative data typically comes out of caches established in response to earlier queries.  Authoritative responses to queries always override cached data.&lt;br /&gt;
&lt;br /&gt;
Just as domain names are hierarchical, DNS servers are also arranged into a logical hierarchy, where different servers are responsible for providing information about names at different levels of the domain hierarchy; this is done by means of &#039;&#039;NS&#039;&#039; resource records, which point to the name servers for a given domain.  At the root are a set of &amp;quot;root servers,&amp;quot; the IP addresses of which are well-known: these provide information about top-level domains like &amp;quot;.org&amp;quot;, and specifically include NS RRs for the name servers that are known to be authoritative for those domains.  Subsequent levels are organized similarly: each server at some level provides information about servers at the next level, and so on.&lt;br /&gt;
&lt;br /&gt;
=== Servers, Resolvers, and Stub Resolvers ===&lt;br /&gt;
&lt;br /&gt;
As mentioned, clients resolve requests for information about domain names by sending queries to servers, but different kinds of servers play different roles:&lt;br /&gt;
&lt;br /&gt;
* Non-Recursive, Authoritative Servers, or just Authoritative Servers, are the ultimate sources of authority for domains under a zone.  They only accept queries for the domains in the zones they are authoritative for and answer them either with resolved data or with an error, such as when a query is issued for name that does not exist.&lt;br /&gt;
* Resolvers, or Recursive Servers, are intermediaries; they accept &amp;quot;recursive&amp;quot; queries and forward these to other servers until they receive a definitive reply.  They then usually cache the results so that subsequent requests for the same query can be answered quickly.  The cached data expires once its TTL is exceeded.&lt;br /&gt;
* Stub resolvers are small bits of software embedded in client programs that make DNS queries: these program fragments send queries to remote servers and interpret the results, providing them to the rest of the program.&lt;br /&gt;
&lt;br /&gt;
Usually, any program that wants to make use of the DNS will do so via a stub resolver, which will forward the query to some recursive server. The stub resolver learns what recursive server to send its queries to via some administrative mechanism; for example, a DHCP server might supply the IP address of the server to use, or the stub might look in a file on the local system.  The name servers the stub sends requests to must be given by IP address; doing otherwise would create a chicken and egg problem, since the whole point is that the DNS is way we translate names into addresses.&lt;br /&gt;
&lt;br /&gt;
= Setting Up a Recursive Resolver on OpenBSD =&lt;br /&gt;
&lt;br /&gt;
[https://www.openbsd.org OpenBSD] is a variant of Unix known for security and a focus on code correctness.  It also comes bundled with a high performance caching, validating, recursive DNS resolver package called [https://www.nlnetlabs.nl/projects/unbound/about/ Unbound]. Unbound is easily configured, we will give an example of doing so here.&lt;br /&gt;
&lt;br /&gt;
== Configuring the unbound server ==&lt;br /&gt;
&lt;br /&gt;
The first step is to configure the server by editing its configuration file, &amp;lt;code&amp;gt;/var/unbound/etc/unbound.conf&amp;lt;/code&amp;gt;.  The format and allowable settings in this file are given in the man page, [https://man.openbsd.org/unbound.conf &#039;&#039;unbound.conf&#039;&#039;(5)], but at a high level it contains several sections:&lt;br /&gt;
&lt;br /&gt;
* A &amp;lt;code&amp;gt;server:&amp;lt;/code&amp;gt; section allows us to set settings for the server itself.&lt;br /&gt;
* A &amp;lt;code&amp;gt;remote-control:&amp;lt;/code&amp;gt; section lets setup access for a control client.&lt;br /&gt;
* An arbitrary number of optional zone-specific sections that allow us to configure options for those zones.  This gives us the ability to forward to specific authoritative servers for a zone and so on.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s an example of what a configuration file might look like:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;server:&lt;br /&gt;
        interface: 0.0.0.0&lt;br /&gt;
        interface: ::0&lt;br /&gt;
&lt;br /&gt;
        access-control: 0.0.0.0/0 refuse&lt;br /&gt;
        access-control: ::0/0 refuse&lt;br /&gt;
&lt;br /&gt;
        access-control: 127.0.0.0/8 allow&lt;br /&gt;
        access-control: ::1 allow&lt;br /&gt;
&lt;br /&gt;
        access-control: 44.0.0.0/9 allow&lt;br /&gt;
        access-control: 44.128.0.0/10 allow&lt;br /&gt;
&lt;br /&gt;
        hide-identity: yes&lt;br /&gt;
        hide-version: yes&lt;br /&gt;
&lt;br /&gt;
        # Perform DNSSEC validation.&lt;br /&gt;
        auto-trust-anchor-file: &amp;quot;/var/unbound/db/root.key&amp;quot;&lt;br /&gt;
        val-log-level: 2&lt;br /&gt;
&lt;br /&gt;
        # Synthesize NXDOMAINs from DNSSEC NSEC chains.&lt;br /&gt;
        # https://tools.ietf.org/html/rfc8198&lt;br /&gt;
        #&lt;br /&gt;
        aggressive-nsec: yes&lt;br /&gt;
&lt;br /&gt;
        # Use TCP for &amp;quot;forward-zone&amp;quot; requests. Useful if you are making&lt;br /&gt;
        # DNS requests over an SSH port forwarding.&lt;br /&gt;
        #tcp-upstream: yes&lt;br /&gt;
&lt;br /&gt;
        # CA Certificates used for forward-tls-upstream (RFC7858) hostname&lt;br /&gt;
        # verification.  Since it&#039;s outside the chroot it is only loaded at&lt;br /&gt;
        # startup and thus cannot be changed via a reload.&lt;br /&gt;
        #tls-cert-bundle: &amp;quot;/etc/ssl/cert.pem&amp;quot;&lt;br /&gt;
&lt;br /&gt;
remote-control:&lt;br /&gt;
        control-enable: yes&lt;br /&gt;
        control-interface: /var/run/unbound.sock&lt;br /&gt;
&lt;br /&gt;
stub-zone:&lt;br /&gt;
        name: &amp;quot;ampr.org.&amp;quot;&lt;br /&gt;
        stub-addr: 44.1.1.44&lt;br /&gt;
        stub-host: ns2.us.ardc.org&lt;br /&gt;
        stub-host: ns.ardc.org&lt;br /&gt;
        stub-host: ns1.de.ardc.org&lt;br /&gt;
        stub-host: a.gw4.uk&lt;br /&gt;
&lt;br /&gt;
stub-zone:&lt;br /&gt;
        name: &amp;quot;44.in-addr.arpa.&amp;quot;&lt;br /&gt;
        stub-addr: 44.1.1.44&lt;br /&gt;
        stub-host: ns2.us.ardc.org&lt;br /&gt;
        stub-host: ns.ardc.org&lt;br /&gt;
        stub-host: ns1.de.ardc.org&lt;br /&gt;
        stub-host: a.gw4.uk&lt;br /&gt;
        stub-first: yes&lt;br /&gt;
&lt;br /&gt;
stub-zone:&lt;br /&gt;
        name: &amp;quot;128.44.in-addr.arpa.&amp;quot;&lt;br /&gt;
        stub-addr: 44.1.1.44&lt;br /&gt;
        stub-host: ns2.us.ardc.org&lt;br /&gt;
        stub-host: ns.ardc.org&lt;br /&gt;
        stub-host: ns1.de.ardc.org&lt;br /&gt;
        stub-host: a.gw4.uk&lt;br /&gt;
        stub-first: yes&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This configuration sets some non-default options in the &amp;lt;code&amp;gt;server:&amp;lt;/code&amp;gt; section, such as what interface to listen on for incoming connections, and options for what machines are allowed to send us queries.  Here, we listen on all addresses on all interfaces for both IPv4 and IPv6 and we allow any AMPRNet host to send us queries.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;remote-control:&amp;lt;/code&amp;gt; section enables and configures a Unix domain socket that allows us to control the unbound daemon with the client control program, &amp;lt;code&amp;gt;unbound-control&amp;lt;/code&amp;gt;; this way, we can ask it for performance and usage statistics, force it to flush its cache, etc, without stopping and restarting it.&lt;br /&gt;
&lt;br /&gt;
The most interesting parts are the &amp;lt;code&amp;gt;stub-zone:&amp;lt;/code&amp;gt; sections.  These allow us to tell unbound about servers that are authoritative for particular zones, bypassing querying through the root for domains under those zones.  In the three sections given here, we tell it to query the ARDC-administered non-recursive authoritative servers for the &#039;&#039;ampr.org&#039;&#039;, &#039;&#039;44.in-addr.arpa&#039;&#039; and &#039;&#039;128.44.in-addr.arpa&#039;&#039; zones; that is, for anything related to AMPRNet, we forward directly to the authoritative servers.&lt;br /&gt;
&lt;br /&gt;
Note the &amp;lt;code&amp;gt;stub-first: yes&amp;lt;/code&amp;gt; lines for the two reverse domains: some reverse domains are &#039;&#039;delegated&#039;&#039; to other services.  This line says to try the ARDC servers first, and if those return an error, to perform the standard query from the root.&lt;br /&gt;
&lt;br /&gt;
Once the server is configured, we can enable it by adding a line to &amp;lt;code&amp;gt;/etc/rc.conf.local&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;unbound_flags=&amp;quot;&amp;quot;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now, if we reboot, we will find the unbound daemon running the next time we login.  We should be able to direct DNS queries to the local server now, and we can edit the &amp;lt;code&amp;gt;/etc/resolv.conf&amp;lt;/code&amp;gt; file to include a reference to our unbound instance.  For example, our resolv.conf file might look something like:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;lookup file bind&lt;br /&gt;
domain your-call.ampr.org&lt;br /&gt;
search your-call.ampr.org ampr.org&lt;br /&gt;
nameserver 127.0.0.1&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Of course, one likely wants to query one&#039;s own callsign based subdomain, not &amp;quot;your-call&amp;quot;.  Other machines can be configured to connect to your unbound instance; here is an example from a machine at KZ2X:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;lookup file bind&lt;br /&gt;
domain kz2x.ampr.org&lt;br /&gt;
search kz2x.ampr.org ampr.org&lt;br /&gt;
family inet6 inet4&lt;br /&gt;
nameserver 44.44.48.29&lt;br /&gt;
nameserver 8.8.8.8&lt;br /&gt;
nameserver 1.1.1.1&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here, &amp;lt;code&amp;gt;44.44.48.29&amp;lt;/code&amp;gt; is the machine that runs unbound.&lt;/div&gt;</summary>
		<author><name>Cross</name></author>
	</entry>
	<entry>
		<id>https://wiki.ampr.org/w/index.php?title=Services&amp;diff=1119</id>
		<title>Services</title>
		<link rel="alternate" type="text/html" href="https://wiki.ampr.org/w/index.php?title=Services&amp;diff=1119"/>
		<updated>2024-05-23T18:03:04Z</updated>

		<summary type="html">&lt;p&gt;Cross: Wording consistency.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Maintainer !! Service Name!! URL/IP !! Service Type !! Description !! Other Information&lt;br /&gt;
|-&lt;br /&gt;
| AMPR ||[[Portal]] ||  https://portal.ampr.org || HTTPS || Used to request allocations, manage user profile information, [[Gateway]] entries, [[Encap.txt]] preferences and ampr.org DNS entries|| NONE&lt;br /&gt;
|-&lt;br /&gt;
| AMPR ||Website ||  https://www.ampr.org || HTTPS || AMPRNet Main Page|| NONE&lt;br /&gt;
|-&lt;br /&gt;
| AMPR ||Wiki ||  https://wiki.ampr.org || HTTPS || This Wiki|| NONE&lt;br /&gt;
|-&lt;br /&gt;
| AMPR ||44Net discussion group ||  https://ardc.groups.io/g/44net || HTTPS || AMPR discussion group|| NONE&lt;br /&gt;
|-&lt;br /&gt;
| AMPR ||ARDC announcements ||  https://ardc.groups.io/g/main || HTTPS || ARDC announcements|| NONE&lt;br /&gt;
|-&lt;br /&gt;
| AMPR ||AMPRNet Gateway [[Amprgw|(AMPRGW)]] || amprgw.ucsd.edu/169.228.34.84 || IP and IPENCAP [[Tunnel]]|| Routes traffic between the public internet and AMPRNet hosts connected via the IPIP mesh and originates [[RIP]] packets || Gateways use IP Protocol 4 (IPENCAP) to receive traffic via AMPRGW. Allocation must be registered in the [[Portal]] with a ampr.org DNS entry, and gateways must run an AMPRNet routing protocol (i.e. [[RIP]]44 or [[munge script]])&lt;br /&gt;
|-&lt;br /&gt;
| AMPR ||[[RIP]]44 || provided via [https://en.wikipedia.org/wiki/Broadcasting_%28networking%29 broadcast] from 44.0.0.1 to all [[gateway]]s registered in the [[portal]] || Routing Information (modified RIPv2 protocol) || distributed by main AMPRNet Router to multicast address 224.0.0.9|| 1.) an enabled IPENCAP tunnel, and 2.) [[ampr-ripd]] or [[rip44d]] must be running and properly configured on your registered gateway&lt;br /&gt;
|-&lt;br /&gt;
| AMPR ||[[Encap.txt]] || N/A || Routing Information (EMAIL/FTP/HTTP)|| routing information for download|| file must be must be parsed by a self-developed [[munge script]]&lt;br /&gt;
|-&lt;br /&gt;
| Various Operators||[[Ampr.org]] DNS and Reverse DNS (44.in-addr.arpa) ||&lt;br /&gt;
ns.ardc.net&amp;lt;br /&amp;gt;&lt;br /&gt;
a.gw4.uk&amp;lt;br /&amp;gt;&lt;br /&gt;
ns2.us.ardc.net&amp;lt;br /&amp;gt;&lt;br /&gt;
ns1.de.ardc.net&amp;lt;br /&amp;gt;&lt;br /&gt;
(These hosts are authoritative for AMPR.ORG and most of the &#039;[0-191].44.in-addr.arpa&#039; reverse zones.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
44.0.0.0/9 thru 44.128.0.0/10 hosts may use dns-mdc.ampr.org (44.60.44.3) as a recursive DNS server. It also has a copy of HAMWAN.ORG&amp;lt;br /&amp;gt;&lt;br /&gt;
srv.kz2x.ampr.org (44.44.48.29) is a recursive resolver available to 44.0.0.0/9 and 44.128.0.0/10&amp;lt;br /&amp;gt;&lt;br /&gt;
|| DNS || name resolution services||&lt;br /&gt;
|-&lt;br /&gt;
| Various Operators||Network Tools||&lt;br /&gt;
http://whatismyip.ampr.org&amp;lt;br /&amp;gt;&lt;br /&gt;
http://yo2tm.ampr.org/nettools.php&amp;lt;br /&amp;gt;&lt;br /&gt;
http://kb3vwg-010.ampr.org/tools&amp;lt;br /&amp;gt;&lt;br /&gt;
http://speedtest.ampr.org&amp;lt;br /&amp;gt;&lt;br /&gt;
 || HTTP|| source IP checker, speed test, Ping, Traceroute, etc.|| &#039;&#039;&#039;kb3vwg-010.ampr.org&#039;&#039;&#039; only available from hosts with an AMPRNet IP address&lt;br /&gt;
|-&lt;br /&gt;
| Various Operators ||Network Time Protocol || ntp.vk2hff.ampr.org (Stratum 1, AU)&amp;lt;br /&amp;gt;time.kz2x.ampr.org (Stratum 1, US)&amp;lt;br /&amp;gt;kb3vwg-001.ampr.org (Stratum 2, US)&amp;lt;br /&amp;gt;gw-44-137.pi9noz.ampr.org (Stratum 2)|| NTP|| Stratum 2 Network Time Server - References US, Canadian and Mexican|| &#039;&#039;&#039;kb3vwg-001.ampr.org&#039;&#039;&#039; only available from hosts with an AMPRNet IP address&amp;lt;br /&amp;gt;&#039;&#039;&#039;time.kz2x.ampr.org&#039;&#039;&#039; only available from hosts with an AMPRNet IP address&lt;br /&gt;
|-&lt;br /&gt;
| N1URO  ||AMPRNet/RF faxing || http://wiki.ampr.org/wiki/axMail-FAX || Facsimile || Online IP based Facsimile service. You have the ability to send emergency communications from packet via Fax. || [http://axmail.sourceforge.net axMail-FAX] Sofware is here.&lt;br /&gt;
|-&lt;br /&gt;
| [http://allstarlink.org AllStar Link] || AllStar || http://allstarlink.org || Linking of repeaters || AllStar Link core network services are provided via redundant datacenters using 44net IP space.  || [https://wiki.allstarlink.org/wiki/Main_Page ASL wiki]&lt;br /&gt;
|-&lt;br /&gt;
| N2NOV and G1FEF || Hub_NA and Hub_EU for WWconvers Chat System || 44.68.41.2:3600&amp;lt;br /&amp;gt;convers.g1fef.co.uk:3600 || Telnet || Only connections from other 44Net addresses allowed using port 3600. Stations like JNOS with a built-in local chat server can link to it.&amp;lt;br /&amp;gt; Individuals without a local chat portal can use an IRC client to a public IP address that must be arranged with the owner. || None&lt;br /&gt;
|-&lt;br /&gt;
| N2NOV || AMPRNet NE US Regional Portal || http://n2nov.ampr.org/hamgate.html || HTTP || AMPRNet NE US Regional Portal || None&lt;br /&gt;
|-&lt;br /&gt;
| [https://flscg.org/ FSG]|| HamWAN Remote || https://flscg.org/2022/04/hamwan-remote/ || VPN/BGP || We provide a VPN based remote site connection to [https://flscg.org/hamwan/ HamWAN Tampa] and can announce your IP space.  Performance of over 1gbit/s is possible and we provide an local connection point for amateurs in the South Eastern United States. || https://wiki.w9cr.net/index.php/HamWAN_Remote_Site &lt;br /&gt;
|-&lt;br /&gt;
| [https://hamwan.org HamWAN]||HamWAN Open Peering||https://hamwan.org/Labs/Open%20Peering%20Policy.html||BGP/IPSec(AH)||We provide IPsec VPN w/ BGP peering + Internet announcing.||&lt;br /&gt;
|-}&lt;br /&gt;
&lt;br /&gt;
Services previously available on AMPRNet but no longer actively supported can be viewed on the [[Services/Historic|Historic Services]] page.&lt;/div&gt;</summary>
		<author><name>Cross</name></author>
	</entry>
	<entry>
		<id>https://wiki.ampr.org/w/index.php?title=Services&amp;diff=1118</id>
		<title>Services</title>
		<link rel="alternate" type="text/html" href="https://wiki.ampr.org/w/index.php?title=Services&amp;diff=1118"/>
		<updated>2024-05-23T18:01:46Z</updated>

		<summary type="html">&lt;p&gt;Cross: time.kz2x.ampr.org is available.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Maintainer !! Service Name!! URL/IP !! Service Type !! Description !! Other Information&lt;br /&gt;
|-&lt;br /&gt;
| AMPR ||[[Portal]] ||  https://portal.ampr.org || HTTPS || Used to request allocations, manage user profile information, [[Gateway]] entries, [[Encap.txt]] preferences and ampr.org DNS entries|| NONE&lt;br /&gt;
|-&lt;br /&gt;
| AMPR ||Website ||  https://www.ampr.org || HTTPS || AMPRNet Main Page|| NONE&lt;br /&gt;
|-&lt;br /&gt;
| AMPR ||Wiki ||  https://wiki.ampr.org || HTTPS || This Wiki|| NONE&lt;br /&gt;
|-&lt;br /&gt;
| AMPR ||44Net discussion group ||  https://ardc.groups.io/g/44net || HTTPS || AMPR discussion group|| NONE&lt;br /&gt;
|-&lt;br /&gt;
| AMPR ||ARDC announcements ||  https://ardc.groups.io/g/main || HTTPS || ARDC announcements|| NONE&lt;br /&gt;
|-&lt;br /&gt;
| AMPR ||AMPRNet Gateway [[Amprgw|(AMPRGW)]] || amprgw.ucsd.edu/169.228.34.84 || IP and IPENCAP [[Tunnel]]|| Routes traffic between the public internet and AMPRNet hosts connected via the IPIP mesh and originates [[RIP]] packets || Gateways use IP Protocol 4 (IPENCAP) to receive traffic via AMPRGW. Allocation must be registered in the [[Portal]] with a ampr.org DNS entry, and gateways must run an AMPRNet routing protocol (i.e. [[RIP]]44 or [[munge script]])&lt;br /&gt;
|-&lt;br /&gt;
| AMPR ||[[RIP]]44 || provided via [https://en.wikipedia.org/wiki/Broadcasting_%28networking%29 broadcast] from 44.0.0.1 to all [[gateway]]s registered in the [[portal]] || Routing Information (modified RIPv2 protocol) || distributed by main AMPRNet Router to multicast address 224.0.0.9|| 1.) an enabled IPENCAP tunnel, and 2.) [[ampr-ripd]] or [[rip44d]] must be running and properly configured on your registered gateway&lt;br /&gt;
|-&lt;br /&gt;
| AMPR ||[[Encap.txt]] || N/A || Routing Information (EMAIL/FTP/HTTP)|| routing information for download|| file must be must be parsed by a self-developed [[munge script]]&lt;br /&gt;
|-&lt;br /&gt;
| Various Operators||[[Ampr.org]] DNS and Reverse DNS (44.in-addr.arpa) ||&lt;br /&gt;
ns.ardc.net&amp;lt;br /&amp;gt;&lt;br /&gt;
a.gw4.uk&amp;lt;br /&amp;gt;&lt;br /&gt;
ns2.us.ardc.net&amp;lt;br /&amp;gt;&lt;br /&gt;
ns1.de.ardc.net&amp;lt;br /&amp;gt;&lt;br /&gt;
(These hosts are authoritative for AMPR.ORG and most of the &#039;[0-191].44.in-addr.arpa&#039; reverse zones.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
44.0.0.0/9 thru 44.128.0.0/10 hosts may use dns-mdc.ampr.org (44.60.44.3) as a recursive DNS server. It also has a copy of HAMWAN.ORG&amp;lt;br /&amp;gt;&lt;br /&gt;
srv.kz2x.ampr.org (44.44.48.29) is a recursive resolver available to 44.0.0.0/9 and 44.128.0.0/10&amp;lt;br /&amp;gt;&lt;br /&gt;
|| DNS || name resolution services||&lt;br /&gt;
|-&lt;br /&gt;
| Various Operators||Network Tools||&lt;br /&gt;
http://whatismyip.ampr.org&amp;lt;br /&amp;gt;&lt;br /&gt;
http://yo2tm.ampr.org/nettools.php&amp;lt;br /&amp;gt;&lt;br /&gt;
http://kb3vwg-010.ampr.org/tools&amp;lt;br /&amp;gt;&lt;br /&gt;
http://speedtest.ampr.org&amp;lt;br /&amp;gt;&lt;br /&gt;
 || HTTP|| source IP checker, speed test, Ping, Traceroute, etc.|| &#039;&#039;&#039;kb3vwg-010.ampr.org&#039;&#039;&#039; only available from hosts with an AMPRNet IP address&lt;br /&gt;
|-&lt;br /&gt;
| Various Operators ||Network Time Protocol || ntp.vk2hff.ampr.org (Stratum 1, AU)&amp;lt;br /&amp;gt;time.kz2x.ampr.org (Stratum 1, US)&amp;lt;br /&amp;gt;kb3vwg-001.ampr.org (Stratum 2, US)&amp;lt;br /&amp;gt;gw-44-137.pi9noz.ampr.org (Stratum 2)|| NTP|| Stratum 2 Network Time Server - References US, Canadian and Mexican|| &#039;&#039;&#039;kb3vwg-001.ampr.org&#039;&#039;&#039; only available from hosts with an AMPRNet IP address&amp;lt;br /&amp;gt;&#039;&#039;&#039;time.kz2x.ampr.org&#039;&#039;&#039; only available to AMPRNet hosts&lt;br /&gt;
|-&lt;br /&gt;
| N1URO  ||AMPRNet/RF faxing || http://wiki.ampr.org/wiki/axMail-FAX || Facsimile || Online IP based Facsimile service. You have the ability to send emergency communications from packet via Fax. || [http://axmail.sourceforge.net axMail-FAX] Sofware is here.&lt;br /&gt;
|-&lt;br /&gt;
| [http://allstarlink.org AllStar Link] || AllStar || http://allstarlink.org || Linking of repeaters || AllStar Link core network services are provided via redundant datacenters using 44net IP space.  || [https://wiki.allstarlink.org/wiki/Main_Page ASL wiki]&lt;br /&gt;
|-&lt;br /&gt;
| N2NOV and G1FEF || Hub_NA and Hub_EU for WWconvers Chat System || 44.68.41.2:3600&amp;lt;br /&amp;gt;convers.g1fef.co.uk:3600 || Telnet || Only connections from other 44Net addresses allowed using port 3600. Stations like JNOS with a built-in local chat server can link to it.&amp;lt;br /&amp;gt; Individuals without a local chat portal can use an IRC client to a public IP address that must be arranged with the owner. || None&lt;br /&gt;
|-&lt;br /&gt;
| N2NOV || AMPRNet NE US Regional Portal || http://n2nov.ampr.org/hamgate.html || HTTP || AMPRNet NE US Regional Portal || None&lt;br /&gt;
|-&lt;br /&gt;
| [https://flscg.org/ FSG]|| HamWAN Remote || https://flscg.org/2022/04/hamwan-remote/ || VPN/BGP || We provide a VPN based remote site connection to [https://flscg.org/hamwan/ HamWAN Tampa] and can announce your IP space.  Performance of over 1gbit/s is possible and we provide an local connection point for amateurs in the South Eastern United States. || https://wiki.w9cr.net/index.php/HamWAN_Remote_Site &lt;br /&gt;
|-&lt;br /&gt;
| [https://hamwan.org HamWAN]||HamWAN Open Peering||https://hamwan.org/Labs/Open%20Peering%20Policy.html||BGP/IPSec(AH)||We provide IPsec VPN w/ BGP peering + Internet announcing.||&lt;br /&gt;
|-}&lt;br /&gt;
&lt;br /&gt;
Services previously available on AMPRNet but no longer actively supported can be viewed on the [[Services/Historic|Historic Services]] page.&lt;/div&gt;</summary>
		<author><name>Cross</name></author>
	</entry>
	<entry>
		<id>https://wiki.ampr.org/w/index.php?title=Services/Historic&amp;diff=1117</id>
		<title>Services/Historic</title>
		<link rel="alternate" type="text/html" href="https://wiki.ampr.org/w/index.php?title=Services/Historic&amp;diff=1117"/>
		<updated>2024-05-23T18:00:20Z</updated>

		<summary type="html">&lt;p&gt;Cross: time.kz2x.ampr.org works, but was blocked by a firewall rule&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Below is a list of historic services that were previously offered by ampr users but are not currently available.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Maintainer !! Service Name!! URL/IP !! Service Type !! Description !! Other Information&lt;br /&gt;
|-&lt;br /&gt;
| N1URO ||Network Tools|| http://n1uro.ampr.org/do.shtml&amp;lt;br /&amp;gt; || HTTP|| source IP checker, speed test, Ping, Traceroute, etc.|| DNS entry no longer exists&lt;br /&gt;
|-&lt;br /&gt;
| Various Operators ||Network Time Protocol Server || ns.ardc.net (Stratum 2, UK)&amp;lt;br /&amp;gt;server.yo2loj.ampr.org (Stratum 2)&amp;lt;br /&amp;gt;f4gve.ampr.org (Stratum 3)&amp;lt;br /&amp;gt;ntp1.on3rvh.ampr.org&amp;lt;br /&amp;gt; || NTP|| Stratum 2 Network Time Server - References US, Canadian and Mexican|| No NTP server configured on host&lt;br /&gt;
|-&lt;br /&gt;
| OH7LZB ||[[AMPRNet_VPN]] || http://wiki.ampr.org/wiki/AMPRNet_VPN || VPN|| [http://en.wikipedia.org/wiki/OpenVPN OpenVPN]-based || &#039;&#039;&#039;Unavailable as of May 2024&#039;&#039;&#039; &amp;lt;br /&amp;gt;You must have a X.509 certificate issued by [http://www.arrl.org/logbook-of-the-world ARRL Logbook of the World (LoTW)]. ARRL membership is not required.&lt;br /&gt;
|-}&lt;/div&gt;</summary>
		<author><name>Cross</name></author>
	</entry>
	<entry>
		<id>https://wiki.ampr.org/w/index.php?title=DNS&amp;diff=1114</id>
		<title>DNS</title>
		<link rel="alternate" type="text/html" href="https://wiki.ampr.org/w/index.php?title=DNS&amp;diff=1114"/>
		<updated>2024-05-17T12:25:02Z</updated>

		<summary type="html">&lt;p&gt;Cross: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= DNS: The Domain Name System =&lt;br /&gt;
&lt;br /&gt;
The Domain Name System is the primary mechanism by which symbolic host names, such as &#039;&#039;kz2x.ampr.org&#039;&#039; are translated into numeric host IP addresses, such as 44.44.48.2.  It is implemented as a network protocol, understood by both clients and servers, that use the network itself to effect translation.  The DNS protocol is an Internet standard that is defined by a set of &amp;quot;Request for Comment&amp;quot; documents, or RFCs; the current revision of the DNS specification is in [https://datatracker.ietf.org/doc/html/rfc1035 RFC1035].  It is used heavily on AMPRNet.&lt;br /&gt;
&lt;br /&gt;
== Historical Background ==&lt;br /&gt;
&lt;br /&gt;
Before DNS, individual sites on the Internet maintained a local mapping of host names to IP addresses in the form of a &amp;quot;hosts&amp;quot; file; this was often a text file resident on each Internet-connected computer.  However, this quickly became untenable as the network grew: not only did the file itself become so large as to be unwieldy and slow to search, keeping it up to date required significant effort.  Furthermore, coordinating updates from many different organizations, and avoiding name collisions as new hosts were added, added even more complexity.&lt;br /&gt;
&lt;br /&gt;
A clever insight was that the problem could be addressed using the network itself, by providing a network service that could translate between host names and IP addresses.  Early work around this idea ultimately lead to the design of the DNS.&lt;br /&gt;
&lt;br /&gt;
== Concepts ==&lt;br /&gt;
&lt;br /&gt;
The DNS uses the client/server model, in which &#039;&#039;client&#039;&#039; machines send name service queries to DNS &#039;&#039;servers&#039;&#039; scattered around the Internet, which in turn, provide answers.  The process of answering a query related to a host name is called &amp;quot;resolution.&amp;quot;  Resolved queries may be &amp;quot;cached&amp;quot; by servers for some period of time, called the &amp;quot;time to live&amp;quot; or TTL, given by the source server.  The DNS allows clients to make requests about a fixed set of types of information for a particular &#039;&#039;domain name&#039;&#039;.  For example, one might request make an &amp;quot;address&amp;quot; (or &amp;quot;A&amp;quot;) query for a name.  For each name, a set of &amp;quot;records&amp;quot; corresponding to these  information types name are input by an administrator and held in DNS server; these are called &amp;quot;resource records&amp;quot; or &amp;quot;RRs&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Domains, Zones, and Authority ===&lt;br /&gt;
&lt;br /&gt;
Names are hierarchical, and organized into &#039;&#039;domains&#039;&#039;: Starting from &amp;quot;.&amp;quot;, the &amp;quot;root&amp;quot;, and descending through a &amp;quot;top-level&amp;quot; domain (TLD) such &amp;quot;.org&amp;quot;, then through an organizational domain such as &amp;quot;ampr&amp;quot;. Each such level forms a &amp;quot;domain&amp;quot;, so that &amp;quot;.org&amp;quot; and &amp;quot;ampr.org&amp;quot; are separate domains. This organization provides resilience against collisions, since names need only be unique within a domain, and and facilitating separation of administrative concerns.&lt;br /&gt;
&lt;br /&gt;
Collections of domains that fall under a single administrative entity form &amp;quot;zones&amp;quot;.  A zone is said to be authoritative for the domains under its control, but not otherwise; non-authoritative data typically comes out of caches established in response to earlier queries.  Authoritative responses to queries always override cached data.&lt;br /&gt;
&lt;br /&gt;
Just as domain names themselves are hierarchical, so too are DNS servers arranged into a logical hierarchy, with different servers serving information about different levels of the hierarchy.  At the root are a set of well known &amp;quot;root servers,&amp;quot; the IP addresses of which are well-known: these provide information about top-level domains and specifically include references to the name servers that are known to be authoritative about those domains.&lt;br /&gt;
&lt;br /&gt;
=== Servers, Resolvers, and Stub Resolvers ===&lt;br /&gt;
&lt;br /&gt;
As mentioned, clients resolve requests for information about domain names by sending queries to servers, but different kinds of servers play different roles:&lt;br /&gt;
&lt;br /&gt;
* Non-Recursive, Authoritative Servers, or just Authoritative Servers, are the ultimate sources of authority for domains under a zone.  They accept queries answer them, either with resolved data or with an error, such as when a query is issued for name that does not exist.&lt;br /&gt;
* Resolvers, or Recursive Servers, are intermediaries; they accept &amp;quot;recursive&amp;quot; queries and forward these to other servers until they receive a definitive reply.  They then usually cache the results so that subsequent requests for the same query can be answered quickly.  The cached data expires once its TTL is exceeded.&lt;br /&gt;
* Stub resolvers are small bits of software embedded in client programs that make DNS queries: these program fragments send queries to remote servers and interpret the results, providing them the rest of the program.&lt;br /&gt;
&lt;br /&gt;
Usually, any program that wants to make use of the DNS will do so via a stub resolver, which will forward the query to some recursive server. The stub resolver learns about what recursive server to send its queries to via some administrative mechanism; for example, a DHCP server might supply the IP address of the server to use.&lt;/div&gt;</summary>
		<author><name>Cross</name></author>
	</entry>
	<entry>
		<id>https://wiki.ampr.org/w/index.php?title=User:Cross&amp;diff=1113</id>
		<title>User:Cross</title>
		<link rel="alternate" type="text/html" href="https://wiki.ampr.org/w/index.php?title=User:Cross&amp;diff=1113"/>
		<updated>2024-05-17T12:09:11Z</updated>

		<summary type="html">&lt;p&gt;Cross: Cross user page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;My name is Dan Cross, call sign KZ2X&amp;lt;br /&amp;gt;&lt;br /&gt;
I am an engineer at Oxide Computer Company.&amp;lt;br /&amp;gt;&lt;br /&gt;
I have a radio page at https://kz2x.radio&amp;lt;br /&amp;gt;&lt;br /&gt;
See also my QRZ biography page at https://qrz.com/db/KZ2X&amp;lt;br /&amp;gt;&lt;br /&gt;
You can find out more about me on my personal web page: https://pub.gajendra.net/&lt;/div&gt;</summary>
		<author><name>Cross</name></author>
	</entry>
	<entry>
		<id>https://wiki.ampr.org/w/index.php?title=Services&amp;diff=1112</id>
		<title>Services</title>
		<link rel="alternate" type="text/html" href="https://wiki.ampr.org/w/index.php?title=Services&amp;diff=1112"/>
		<updated>2024-05-17T01:05:41Z</updated>

		<summary type="html">&lt;p&gt;Cross: Add KZ2X services&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Maintainer !! Service Name!! URL/IP !! Service Type !! Description !! Other Information&lt;br /&gt;
|-&lt;br /&gt;
| AMPR ||[[Portal]] ||  https://portal.ampr.org || HTTPS || manage [[Gateway]], [[Encap.txt]] preferences and ampr.org domain entries (domain entry functionality still under development)|| NONE&lt;br /&gt;
|-&lt;br /&gt;
| AMPR ||Website ||  https://www.ampr.org || HTTPS || AMPRNet Main Page|| NONE&lt;br /&gt;
|-&lt;br /&gt;
| AMPR ||Wiki ||  https://wiki.ampr.org || HTTPS || This Wiki|| NONE&lt;br /&gt;
|-&lt;br /&gt;
| AMPR ||44Net discussion group ||  https://ardc.groups.io/g/44net || HTTPS || AMPR discussion group|| NONE&lt;br /&gt;
|-&lt;br /&gt;
| AMPR ||ARDC announcements ||  https://ardc.groups.io/g/main || HTTPS || ARDC announcements|| NONE&lt;br /&gt;
|-&lt;br /&gt;
| AMPR ||AMPRNet [[Gateway]] (AMPRGW) || 169.228.34.84 || IP and IPENCAP [[Tunnel]]|| main AMPRNet Router|| Gateways use IP Protocol 4 (IPENCAP) to receive traffic via AMPRGW. Allocation must be registered in the [[Portal]] and gateways must run an AMPRNet routing protocol (i.e. [[RIP]]44 or [[munge script]]).&lt;br /&gt;
|-&lt;br /&gt;
| AMPR ||[[RIP]]44 || provided via [https://en.wikipedia.org/wiki/Broadcasting_%28networking%29 broadcast] from 44.0.0.1 to all [[gateway]]s registered in the [[portal]] || Routing Information (modified RIPv2 protocol) || distributed by main AMPRNet Router to multicast address 224.0.0.9|| 1.) an enabled IPENCAP tunnel, and 2.) [[ampr-ripd]] or [[rip44d]] must be running and properly configured on your registered gateway&lt;br /&gt;
|-&lt;br /&gt;
| AMPR ||[[Encap.txt]] || N/A || Routing Information (EMAIL/FTP/HTTP)|| routing information for download|| file must be must be parsed by a self-developed [[munge script]]&lt;br /&gt;
|-&lt;br /&gt;
| Various Operators||[[Ampr.org]] DNS and Reverse DNS (44.in-addr.arpa) ||&lt;br /&gt;
ns.ardc.net&amp;lt;br /&amp;gt;&lt;br /&gt;
a.gw4.uk&amp;lt;br /&amp;gt;&lt;br /&gt;
ns2.us.ardc.net&amp;lt;br /&amp;gt;&lt;br /&gt;
ns1.de.ardc.net&amp;lt;br /&amp;gt;&lt;br /&gt;
(These hosts are authoritative for AMPR.ORG and most of the &#039;[0-191].44.in-addr.arpa&#039; reverse zones.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
44.0.0.0/9 thru 44.128.0.0/10 hosts may use dns-mdc.ampr.org (44.60.44.3) as a recursive DNS server. It also has a copy of HAMWAN.ORG&amp;lt;br /&amp;gt;&lt;br /&gt;
srv.kz2x.ampr.org (44.44.48.29) is a recursive resolver available to 44.0.0.0/9 and 44.128.0.0/10&amp;lt;br /&amp;gt;&lt;br /&gt;
|| DNS || name resolution services||&lt;br /&gt;
|-&lt;br /&gt;
| Various Operators||Network Tools||&lt;br /&gt;
http://whatismyip.ampr.org&amp;lt;br /&amp;gt;&lt;br /&gt;
http://yo2tm.ampr.org/nettools.php&amp;lt;br /&amp;gt;&lt;br /&gt;
http://kb3vwg-010.ampr.org/tools&amp;lt;br /&amp;gt;&lt;br /&gt;
http://speedtest.ampr.org&amp;lt;br /&amp;gt;&lt;br /&gt;
http://n1uro.ampr.org/do.shtml&amp;lt;br /&amp;gt;&lt;br /&gt;
 || HTTP|| source IP checker, speed test, Ping, Traceroute, etc.|| NONE&lt;br /&gt;
|-&lt;br /&gt;
| Various Operators ||Network Time Protocol Server || ns.ardc.net (Stratum 2, UK)&amp;lt;br /&amp;gt;ntp.vk2hff.ampr.org (Stratum 1, AU)&amp;lt;br /&amp;gt;time.kz2x.ampr.org (Stratum 1, US)&amp;lt;br /&amp;gt;kb3vwg-001.ampr.org (Stratum 2, US)&amp;lt;br /&amp;gt;gw-44-137.pi9noz.ampr.org (Stratum 2)&amp;lt;br /&amp;gt;server.yo2loj.ampr.org (Stratum 2)&amp;lt;br /&amp;gt;f4gve.ampr.org (Stratum 3)&amp;lt;br /&amp;gt;ntp1.on3rvh.ampr.org&amp;lt;br /&amp;gt; || NTP|| Stratum 2 Network Time Server - References US, Canadian and Mexican|| AMPRNet hosts have OPEN ACCESS to these time servers &lt;br /&gt;
|-&lt;br /&gt;
| OH7LZB ||[[AMPRNet_VPN]] || http://wiki.ampr.org/wiki/AMPRNet_VPN || VPN|| [http://en.wikipedia.org/wiki/OpenVPN OpenVPN]-based || You must have a X.509 certificate issued by [http://www.arrl.org/logbook-of-the-world ARRL Logbook of the World (LoTW)]. ARRL membership is not required.&lt;br /&gt;
|-&lt;br /&gt;
| N1URO  ||AMPRNet/RF faxing || http://wiki.ampr.org/wiki/axMail-FAX || Facsimile || Online IP based Facsimile service. You have the ability to send emergency communications from packet via Fax. || [http://axmail.sourceforge.net axMail-FAX] Sofware is here.&lt;br /&gt;
|-&lt;br /&gt;
| [http://allstarlink.org AllStar Link] || AllStar || http://allstarlink.org || Linking of repeaters || AllStar Link core network services are provided via redundant datacenters using 44net IP space.  || [https://wiki.allstarlink.org/wiki/Main_Page ASL wiki]&lt;br /&gt;
|-&lt;br /&gt;
| N2NOV and G1FEF || Hub_NA and Hub_EU for WWconvers Chat System || 44.68.41.2:3600&amp;lt;br /&amp;gt;convers.g1fef.co.uk:3600 || Telnet || Only connections from other 44Net addresses allowed using port 3600. Stations like JNOS with a built-in local chat server can link to it.&amp;lt;br /&amp;gt; Individuals without a local chat portal can use an IRC client to a public IP address that must be arranged with the owner. || None&lt;br /&gt;
|-&lt;br /&gt;
| N2NOV || AMPRNet NE US Regional Portal || http://n2nov.ampr.org/hamgate.html || HTTP || AMPRNet NE US Regional Portal || None&lt;br /&gt;
|-&lt;br /&gt;
| [https://flscg.org/ FSG]|| HamWAN Remote || https://flscg.org/2022/04/hamwan-remote/ || VPN/BGP || We provide a VPN based remote site connection to [https://flscg.org/hamwan/ HamWAN Tampa] and can announce your IP space.  Performance of over 1gbit/s is possible and we provide an local connection point for amateurs in the South East || https://wiki.w9cr.net/index.php/HamWAN_Remote_Site &lt;br /&gt;
|-&lt;br /&gt;
| [https://hamwan.org HamWAN]||[https://hamwan.org/Labs/Open%20Peering%20Policy.html OPP Website]||Open Peering ||BGP feed||We provide IPsec VPN w/ BGP peering + Internet announcing.||&lt;br /&gt;
|-}&lt;/div&gt;</summary>
		<author><name>Cross</name></author>
	</entry>
	<entry>
		<id>https://wiki.ampr.org/w/index.php?title=DNS&amp;diff=1111</id>
		<title>DNS</title>
		<link rel="alternate" type="text/html" href="https://wiki.ampr.org/w/index.php?title=DNS&amp;diff=1111"/>
		<updated>2024-05-16T19:52:31Z</updated>

		<summary type="html">&lt;p&gt;Cross: Skeletal DNS page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= DNS: The Domain Name System =&lt;br /&gt;
&lt;br /&gt;
The Domain Name System is the mechanism by which symbolic host names, such as &#039;&#039;kz2x.ampr.org&#039;&#039; are translated into numeric host IP addresses, such as 44.44.48.2.  It is heavily used on AMPRNet. Cleverly&lt;br /&gt;
&lt;br /&gt;
DNS is an Internet standard that is defined by a set of &amp;quot;Request for Comment&amp;quot; documents, or RFCs.  The current revision of the DNS specification is in [https://datatracker.ietf.org/doc/html/rfc1035 RFC1035].&lt;br /&gt;
&lt;br /&gt;
== Historical Background ==&lt;br /&gt;
&lt;br /&gt;
Before DNS, individual sites on the Internet maintained a local mapping of host names to IP addresses in the form of a &amp;quot;hosts&amp;quot; file; this was often a text file resident on each Internet-connected computer.  However, as the network grew, this quickly became untenable: not only did the file itself become so large as to be unwieldy and slow to search, keeping it up to date required significant effort.  Furthermore, coordinating updates from many different organizations, and avoiding name collisions as new hosts were added, added even more complexity.&lt;br /&gt;
&lt;br /&gt;
A clever insight was that the problem could be addressed using the network itself, by providing a network service that could translate between host names and IP addresses.  Early work around this idea ultimately lead to DNS.&lt;br /&gt;
&lt;br /&gt;
== Concepts ==&lt;br /&gt;
&lt;br /&gt;
The DNS on the client/server model, in which &#039;&#039;client&#039;&#039; machines send name service queries to DNS &#039;&#039;servers&#039;&#039; scattered around the Internet, which in turn, provide answers.  The process of answering a query related to a host name is called &amp;quot;resolution.&amp;quot;  Resolved queries may be &amp;quot;cached&amp;quot; by servers for some period of time, called the &amp;quot;time to live&amp;quot; or TTL, given by the source server.&lt;br /&gt;
&lt;br /&gt;
=== Domains, Zones, and Authority ===&lt;br /&gt;
&lt;br /&gt;
Names are hierarchical, and organized into &#039;&#039;domains&#039;&#039;: Starting from &amp;quot;.&amp;quot;, the &amp;quot;root&amp;quot;, and descending through a &amp;quot;top-level&amp;quot; domain (TLD) such &amp;quot;.org&amp;quot;, then through an organizational domain such as &amp;quot;ampr&amp;quot;. Each such level forms a &amp;quot;domain&amp;quot;, so that &amp;quot;.org&amp;quot; and &amp;quot;ampr.org&amp;quot; are separate domains. This organization provides resilience against collisions, since names need only be unique within a domain, and and facilitating separation of administrative concerns.&lt;br /&gt;
&lt;br /&gt;
Collections of domains that fall under a single administrative entity form &amp;quot;zones&amp;quot;.  A zone is said to be authoritative for the domains under its control, but not otherwise; non-authoritative data typically comes out of caches established in response to earlier queries.  Authoritative responses to queries always override cached data.&lt;br /&gt;
&lt;br /&gt;
=== Servers, Resolvers, and Stub Resolvers ===&lt;br /&gt;
&lt;br /&gt;
As mentioned, clients resolve queries about domain names by sending those queries to servers, but different kinds of servers play different roles:&lt;br /&gt;
&lt;br /&gt;
* Servers, or Authoritative Servers, are the ultimate sources of authority for domains under some zone.  They accept queries answer them, either with resolved data or with an error, such as when a query is issued for name that does not exist.&lt;br /&gt;
* Resolvers, or Recursive Servers, are intermediaries; they accept &amp;quot;recursive&amp;quot; queries and forward these to other servers until they receive a definitive reply.  They then usually cache the results so that subsequent requests for the same query can be answered quickly.  The cached data expires once its TTL is exceeded.&lt;br /&gt;
* Stub resolvers are small bits of software embedded in client programs that make DNS queries: these program fragments send queries to remote servers and interpret the results, providing them the rest of the program.&lt;br /&gt;
&lt;br /&gt;
Usually, any program that wants to make use of the DNS will do so via a stub resolver, which will forward the query to some recursive server. The stub resolver learns about what recursive server to send its queries to via some administrative mechanism; for example, a DHCP server might supply the IP address of the server to use.&lt;/div&gt;</summary>
		<author><name>Cross</name></author>
	</entry>
	<entry>
		<id>https://wiki.ampr.org/w/index.php?title=Firewalls&amp;diff=1110</id>
		<title>Firewalls</title>
		<link rel="alternate" type="text/html" href="https://wiki.ampr.org/w/index.php?title=Firewalls&amp;diff=1110"/>
		<updated>2024-05-04T12:12:02Z</updated>

		<summary type="html">&lt;p&gt;Cross: Mention OpenBSD and PF&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Welcome to the Firewall Wiki.&lt;br /&gt;
&lt;br /&gt;
This page is intended to be edited by the community to add use practices, command syntax, etc. regarding firewalling and security on AMPRNet nodes. While each operator is ultimately responsible for the administration of their node, it is highly suggested amongst the [[44Net mailing list]] Community that nodes be firewalled.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Cisco ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== DD-WRT ==&lt;br /&gt;
&lt;br /&gt;
DD-WRT uses an iptables-based firewall (see iptables below). Custom rules can be entered at &#039;&#039;&#039;Administration &amp;gt; Commands &amp;gt; &amp;quot;Save Firewall&amp;quot;&#039;&#039;&#039; on the web GUI.&lt;br /&gt;
&lt;br /&gt;
See:&lt;br /&gt;
&lt;br /&gt;
* https://www.dd-wrt.com/wiki/index.php/Iptables&lt;br /&gt;
* https://www.dd-wrt.com/wiki/index.php/Firewall&lt;br /&gt;
&lt;br /&gt;
== D-Link ==&lt;br /&gt;
&lt;br /&gt;
On some D-Link devices, the port forwarding feature allows for the options: TCP, UDP and Other. The &amp;quot;Other&amp;quot; option on these models are capable of Destination NAT of IPENCAP packets.&lt;br /&gt;
&lt;br /&gt;
To enable input of IPENCAP (IP Protocol Number 4) &#039;&#039;&#039;Note: this rule is required for other AMPR nodes to initiate inbound traffic to your node.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In Port Forwarding on the web GUI:&lt;br /&gt;
&lt;br /&gt;
* Create a new Port Forward&lt;br /&gt;
* Enter the LAN IP of your AMPR node&lt;br /&gt;
* Select &amp;quot;Other&amp;quot;&lt;br /&gt;
* Type the number &#039;&#039;&#039;4&#039;&#039;&#039; into the field&lt;br /&gt;
&lt;br /&gt;
== iptables ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTE:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* On an iptables-based firewall, you must enable connection tracking on the tunl0 interface in order to enable Stateful Packet Inspection (i.e. a stateful firewall).&lt;br /&gt;
* Since the IPENCAP Linux Kernel Module IPIP is in the kernel, &#039;&#039;&#039;you must set the default forwarding policy to DROP or REJECT.&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;If you set your default routing policy to ACCEPT, all packets that have not been explicitly DROPped or REJECTed elsewhere, will route, regardless of firewall policies.&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;For most embedded devices, it is suggested to use [[Firewalls#ipset|ipset]] rules instead&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;General Bogon rules&#039;&#039;&#039; - see: https://en.wikipedia.org/wiki/Bogon_filtering&lt;br /&gt;
&lt;br /&gt;
 ############################################################&lt;br /&gt;
 # DROPS IP TRAFFIC THAT&#039;S INVALID ENTERING OR EXITING AMPR&lt;br /&gt;
 # THIS PREVENTS A GENERAL LOOP&lt;br /&gt;
 iptables -I FORWARD -i tunl0 -o tunl0 -j DROP&lt;br /&gt;
 # DROPS OUTBOUND IPs NOT FROM YOUR ALLOCATION (BCP 38)&lt;br /&gt;
 iptables -t raw -I PREROUTING ! -s 44.xxx.xxx.xxx/xx -i br-amprnet -j DROP&lt;br /&gt;
 # DROPS ROGUE INBOUND ASSIGNED IPs FROM LOOPING THROUGH tunl0 VIA IPENCAP&lt;br /&gt;
 iptables -t raw -I PREROUTING -s 44.xxx.xxx.xxx/xx -i tunl0 -j DROP&lt;br /&gt;
 # DROPS OUTBOUND UNASSIGNED IPs FROM LOOPING THROUGH tunl0 VIA IPENCAP&lt;br /&gt;
 # YOU MUST ADD A RULE UNDER THIS LINE TO MAKE EXCEPTIONS (BCP 38)&lt;br /&gt;
 iptables -I FORWARD ! -s 44.xxx.xxx.xxx/xx -o tunl0 -j DROP&lt;br /&gt;
 ############################################################&lt;br /&gt;
 # DROPS BOGONS ENTERING AMPRNet&lt;br /&gt;
 # SEE http://www.team-cymru.org/Services/Bogons/bogon-bn-nonagg.txt&lt;br /&gt;
 iptables -t raw -I PREROUTING -s 0.0.0.0/8 -i tunl0 -j DROP&lt;br /&gt;
 iptables -t raw -I PREROUTING -s 10.0.0.0/8 -i tunl0 -j DROP&lt;br /&gt;
 iptables -t raw -I PREROUTING -s 100.64.0.0/10 -i tunl0 -j DROP&lt;br /&gt;
 iptables -t raw -I PREROUTING -s 127.0.0.0/8 -i tunl0 -j DROP&lt;br /&gt;
 iptables -t raw -I PREROUTING -s 169.254.0.0/16 -i tunl0 -j DROP&lt;br /&gt;
 iptables -t raw -I PREROUTING -s 172.16.0.0/12 -i tunl0 -j DROP&lt;br /&gt;
 iptables -t raw -I PREROUTING -s 192.0.0.0/24 -i tunl0 -j DROP&lt;br /&gt;
 iptables -t raw -I PREROUTING -s 192.0.2.0/24 -i tunl0 -j DROP&lt;br /&gt;
 iptables -t raw -I PREROUTING -s 192.168.0.0/16 -i tunl0 -j DROP&lt;br /&gt;
 iptables -t raw -I PREROUTING -s 198.18.0.0/15 -i tunl0 -j DROP&lt;br /&gt;
 iptables -t raw -I PREROUTING -s 198.51.100.0/24 -i tunl0 -j DROP&lt;br /&gt;
 iptables -t raw -I PREROUTING -s 203.0.113.0/24 -i tunl0 -j DROP&lt;br /&gt;
 iptables -t raw -I PREROUTING -s 224.0.0.0/4 -i tunl0 -j DROP&lt;br /&gt;
 iptables -t raw -I PREROUTING -s 240.0.0.0/4 -i tunl0 -j DROP&lt;br /&gt;
 # Block of Test AMPRNet Subnet&lt;br /&gt;
 # iptables -t raw -I PREROUTING -s 44.128.0.0/16 -i tunl0 -j DROP&lt;br /&gt;
 # (you can optionally block your subnet)&lt;br /&gt;
 ############################################################&lt;br /&gt;
 # THIS PREVENTS NESTED IPENCAP (BCP 38)&lt;br /&gt;
 iptables -t raw -I PREROUTING -p 4 -i tunl0 -j DROP&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Dynamic IPENCAP Filtering of AMPR Nodes (using iptables)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To enable dynamic filtering of IPENCAP (IP Protocol Number 4)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;NOTE:&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;This script needs work, see Thu Jan 10 11:09:27 PST 2019 message in the [[44Net mailing list]] archive. Due to extreme overheard running on many devices, the ipset script is suggested instead.&#039;&#039;&lt;br /&gt;
* This rule (or one of the ipset or static rules below) is required for other AMPR nodes to initiate inbound traffic to your node.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;REQUIRED:&#039;&#039;&lt;br /&gt;
[[ampr-ripd]] (using the -x and -d arguments), the diff command from the [http://www.gnu.org/software/diffutils/manual/diffutils.html diffutils package] and the [https://www.gnu.org/software/sed/manual/sed.html sed command].&lt;br /&gt;
&lt;br /&gt;
 # Place this rule a the last firewall command&lt;br /&gt;
 # Uncomment sleep command below if the rule does not appear&lt;br /&gt;
 # as load_ipipfilter.sh is still executing&lt;br /&gt;
 # sleep 10&lt;br /&gt;
 # load ipipfilter list rule&lt;br /&gt;
 iptables -t filter -I INPUT -p 4 -i &#039;&#039;&#039;&amp;lt;INTERFACE OF WAN&amp;gt;&#039;&#039;&#039; -j ipipfilter&lt;br /&gt;
&lt;br /&gt;
 #!/bin/sh&lt;br /&gt;
 # load encap.txt into ipipfilter list&lt;br /&gt;
 # by Rob, PE1CHL&lt;br /&gt;
 # load_ipipfilter.sh&lt;br /&gt;
 &lt;br /&gt;
 PATH=&amp;quot;/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin&amp;quot;&lt;br /&gt;
 AMPRGW=&amp;quot;&#039;&#039;&#039;&amp;lt;AMPRGW&amp;gt;&#039;&#039;&#039;&amp;quot;&lt;br /&gt;
 gwfile=&amp;quot;/tmp/gw&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 cd /var/lib/ampr-ripd || exit 1&lt;br /&gt;
 &lt;br /&gt;
 # Parse encap.txt for Node IPs and place in /tmp/gw&lt;br /&gt;
 grep addprivate encap.txt | sed -e &#039;s/.*encap //&#039; | sort -u &amp;gt;$gwfile&lt;br /&gt;
 &lt;br /&gt;
 # Run command to create CHAIN, IF no system output, CHAIN was created&lt;br /&gt;
 iptables -N ipipfilter 2&amp;gt;/dev/null&lt;br /&gt;
 if [ $? -eq 0 ]&lt;br /&gt;
 &#039;&#039;&#039;# DO NOT PLACE EMPTY LINES BETWEEN THE TWO COMMANDS ABOVE. ###&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;# THE EQUATION ASKS IF THE LAST SYSTEM COMMAND ENTERED ###&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;# RETURNS &amp;quot;NOTHING.&amp;quot; ADDING A SPACE WILL CHANGE RESULTS OF THE IF COMMAND. ###&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 ##The two lines above replace the line below, which does not work on OpenWRT&lt;br /&gt;
 # if iptables -N ipipfilter 2&amp;gt;/dev/null&lt;br /&gt;
 ## &lt;br /&gt;
 &lt;br /&gt;
 # IF no system output, THEN flush the CHAIN and add AMPRGW,&lt;br /&gt;
 # add nodes in encap.txt and a final DROP rule&lt;br /&gt;
 then&lt;br /&gt;
     iptables -F ipipfilter&lt;br /&gt;
     iptables -A ipipfilter -s $AMPRGW -j ACCEPT&lt;br /&gt;
 &lt;br /&gt;
     while read ip&lt;br /&gt;
     do&lt;br /&gt;
         iptables -A ipipfilter -s $ip -j ACCEPT&lt;br /&gt;
     done &amp;lt;$gwfile&lt;br /&gt;
 &lt;br /&gt;
     iptables -A ipipfilter -j DROP&lt;br /&gt;
 &lt;br /&gt;
 # ELSE, the CHAIN already exists, determine changes&lt;br /&gt;
 # and INSERT new nodes and DELETE old nodes (excluding AMPRGW)&lt;br /&gt;
 else&lt;br /&gt;
     iptables -L ipipfilter -n | grep ACCEPT | fgrep -v $AMPRGW | \&lt;br /&gt;
         sed -e &#039;s/.*--  //&#039; -e &#039;s/ .*//&#039; | sort | diff - $gwfile | \&lt;br /&gt;
         while read d ip&lt;br /&gt;
         do&lt;br /&gt;
             case &amp;quot;$d&amp;quot; in&lt;br /&gt;
             &amp;quot;&amp;gt;&amp;quot;)&lt;br /&gt;
                 iptables -I ipipfilter -s $ip -j ACCEPT&lt;br /&gt;
                 ;;&lt;br /&gt;
             &amp;quot;&amp;lt;&amp;quot;)&lt;br /&gt;
                 iptables -D ipipfilter -s $ip -j ACCEPT&lt;br /&gt;
                 ;;&lt;br /&gt;
             *)&lt;br /&gt;
                 ;;&lt;br /&gt;
             esac&lt;br /&gt;
         done&lt;br /&gt;
 fi&lt;br /&gt;
 &lt;br /&gt;
 # Delete /tmp/gw when done&lt;br /&gt;
 rm -f $gwfile&lt;br /&gt;
 &lt;br /&gt;
 # The full pathname of this script /usr/local/sbin/load_ipipfilter is passed with the new -x&lt;br /&gt;
 # option to ampr-ripd.   It will load the entire filter the first time, and later it will only update&lt;br /&gt;
 # the filters that have changed.  It is required that the -s option is passed as well, so the&lt;br /&gt;
 # encap.txt file is created by ampr-ripd.&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;&#039;Static IPENCAP Filtering of AMPR Nodes&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To enable input of IPENCAP (IP Protocol Number 4)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note:&#039;&#039;&lt;br /&gt;
* This rule (the dynamic rule above, or the ipset rules) is required for other AMPR nodes to initiate inbound traffic to your node.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
 iptables -t filter -I INPUT -p 4 -i &#039;&#039;&#039;&amp;lt;INTERFACE OF YOUR WAN&amp;gt;&#039;&#039;&#039; -j ACCEPT &lt;br /&gt;
&lt;br /&gt;
If your AMPR node is downstream, you will create an INPUT &#039;&#039;&#039;and&#039;&#039;&#039; DNAT forward rule to the destination LAN IP of your AMPR node.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;To enable receipt of [[RIP]]44&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
 iptables -t filter -I INPUT -p udp -s 44.0.0.1 --sport 520 -d 224.0.0.9 --dport 520 -i tunl0 -j ACCEPT&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Masquerade LAN Subnets to AMPRNet&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* In this instance, eth1 is your 192.168.1.0/24 LAN - (thanks to Brian, N1URO)&lt;br /&gt;
&#039;&#039;See: https://n1uro.ampr.org/linuxconf/44nat.html&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
 # NAT setup&lt;br /&gt;
 iptables -t nat -A POSTROUTING -s 192.168.0/24 -o tunl0 -j MASQUERADE -d 44.0.0.0/8&lt;br /&gt;
 iptables -A FORWARD -s 192.168.1/22 -i eth1 -o tunl0 -m state --state RELATED,ESTABLISHED -j ACCEPT -d 44.0.0.0/8&lt;br /&gt;
 iptables -A FORWARD -s 192.168.1/22 -i eth1 -o tunl0 -j ACCEPT -d 44.0.0.0/8&lt;br /&gt;
&lt;br /&gt;
== ipset ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;General Bogon rules using ipset&#039;&#039;&#039; - see: https://en.wikipedia.org/wiki/Bogon_filtering&lt;br /&gt;
&lt;br /&gt;
 #######################BOGON FILTER ########################                                                                                                                                          &lt;br /&gt;
 ipset create bogons hash:net&lt;br /&gt;
 # BOGON LIST                                                                                                                                                                                          &lt;br /&gt;
 # SEE http://www.team-cymru.org/Services/Bogons/bogon-bn-nonagg.txt                                                                                                                                   &lt;br /&gt;
 ipset -A bogons 0.0.0.0/8                                                                                                                                                                             &lt;br /&gt;
 ipset -A bogons 10.0.0.0/8                                                                                                                                                                            &lt;br /&gt;
 ipset -A bogons 100.64.0.0/10                                                                                                                                                                         &lt;br /&gt;
 ipset -A bogons 127.0.0.0/8                                                                                                                                                                           &lt;br /&gt;
 ipset -A bogons 169.254.0.0/16                                                                                                                                                                        &lt;br /&gt;
 ipset -A bogons 172.16.0.0/12                                                                                                                                                                         &lt;br /&gt;
 ipset -A bogons 192.0.0.0/24                                                                                                                                                                          &lt;br /&gt;
 ipset -A bogons 192.0.2.0/24                                                                                                                                                                          &lt;br /&gt;
 ipset -A bogons 192.168.0.0/16                                                                                                                                                                        &lt;br /&gt;
 ipset -A bogons 198.18.0.0/15                                                                                                                                                                         &lt;br /&gt;
 ipset -A bogons 198.51.100.0/24                                                                                                                                                                       &lt;br /&gt;
 ipset -A bogons 203.0.113.0/24                                                                                                                                                                        &lt;br /&gt;
 ipset -A bogons 224.0.0.0/4                                                                                                                                                                           &lt;br /&gt;
 ipset -A bogons 240.0.0.0/4   &lt;br /&gt;
 # Block of your own AMPRNet Subnet                                                                                                                                                                        &lt;br /&gt;
 # ipset -A bogons 44.xxx.xxx.xxx/xx&lt;br /&gt;
 # Block of Test AMPRNet Subnet&lt;br /&gt;
 # ipset -A bogons 44.128.0.0/16&lt;br /&gt;
&lt;br /&gt;
(you can optionally block your subnet)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Dynamic IPENCAP Filtering of AMPR Nodes (using ipset)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To enable dynamic filtering of IPENCAP (IP Protocol Number 4)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;REQUIRED:&#039;&#039; [[ampr-ripd]] (using the -x and -d arguments) and the ipset package.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
 #!/bin/sh&lt;br /&gt;
 # load encap.txt into ipipfilter list&lt;br /&gt;
 &lt;br /&gt;
 PATH=&amp;quot;/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 cd /var/lib/ampr-ripd || exit 1&lt;br /&gt;
 &lt;br /&gt;
 ipset -N ipipfilter hash:ip 2&amp;gt;/dev/null&lt;br /&gt;
 ipset flush ipipfilter&lt;br /&gt;
 ipset -A ipipfilter &amp;lt;AMPRGW&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 grep addprivate encap.txt | sed -e &#039;s/.*encap //&#039; | sort -u | while read ip&lt;br /&gt;
 do&lt;br /&gt;
     ipset -A ipipfilter $ip&lt;br /&gt;
 done&lt;br /&gt;
&lt;br /&gt;
== Microtik ==&lt;br /&gt;
&lt;br /&gt;
== OpenBSD ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;See the Instructions for [[Setting up a gateway on OpenBSD]].&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
OpenBSD comes with a robust, flexible and highly performant firewall called &amp;quot;PF&amp;quot; that works well on AMPRNet. See https://www.openbsd.org/faq/pf/ for more information.&lt;br /&gt;
&lt;br /&gt;
== OpenWrt ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;See: [[Firewalls#iptables|iptables]] and [[Firewalls#ipset|ipset]] (above), and the Instructions for [[setting up a gateway on OpenWRT|setting up a gateway on OpenWRT]].&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* the Bogon ipset script is added to &#039;&#039;&#039;System &amp;gt; Startup&#039;&#039;&#039; on the web GUI - or into the Unified Configuration Interface (UCI) file &#039;&#039;/etc/rc.local&#039;&#039;&lt;br /&gt;
* [[Firewalls#iptables|iptables]]-based scripts are entered at &#039;&#039;&#039;Network &amp;gt; Firewall &amp;gt; Custom Firewall&#039;&#039;&#039; on the LuCI web GUI interface - or into the Unified Configuration Interface (UCI) file &#039;&#039;/etc/firewall.user&#039;&#039;&lt;br /&gt;
* [[Firewalls#ipset|ipset]]-based rules are entered on the command line - into the Unified Configuration Interface (UCI) file &#039;&#039;/etc/config/firewall&#039;&#039; &#039;&#039;(OpenWrt syntax must be used in this file!)&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;MSS Clamping is enabled in the Firewall Section, you should enable this on both the AMPRLAN and AMPRWAN interfaces&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Adding Bogon drop rule to OpenWrt (using [[Firewalls#ipset|ipset]])&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
 # in /etc/config/firewall&lt;br /&gt;
 config rule&lt;br /&gt;
 	option name &#039;Drop-Bogons_In_AMPRWAN&#039;&lt;br /&gt;
 	option family &#039;ipv4&#039;&lt;br /&gt;
 	option proto &#039;all&#039;&lt;br /&gt;
 	option src &#039;amprwan&#039;&lt;br /&gt;
 	option target &#039;DROP&#039;&lt;br /&gt;
 	option extra &#039;-m set --match-set bogons src&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Adding IPENCAP Filtering of AMPR Nodes to OpenWrt (using [[Firewalls#ipset|ipset]])&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
 # in /etc/config/firewall&lt;br /&gt;
 config rule&lt;br /&gt;
 	option target &#039;ACCEPT&#039;&lt;br /&gt;
 	option src &#039;wan&#039;&lt;br /&gt;
 	option family &#039;ipv4&#039;&lt;br /&gt;
 	option proto &#039;4&#039;&lt;br /&gt;
 	option name &#039;Allow-AMPR_IPENCAP&#039;&lt;br /&gt;
 	option extra &#039;-m set --match-set ipipfilter src&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Adding ICMP Filtering of AMPR Nodes to OpenWrt (using [[Firewalls#ipset|ipset]])&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
 # in /etc/config/firewall&lt;br /&gt;
 config rule&lt;br /&gt;
 	option target &#039;ACCEPT&#039;&lt;br /&gt;
 	option family &#039;ipv4&#039;&lt;br /&gt;
 	option proto &#039;icmp&#039;&lt;br /&gt;
 	list icmp_type &#039;echo-request&#039;&lt;br /&gt;
 	option src &#039;*&#039; &lt;br /&gt;
 	option extra &#039;-m set --match-set ipipfilter src&#039;&lt;br /&gt;
 	option name &#039;Ping_fromIPENCAPS&#039;&lt;/div&gt;</summary>
		<author><name>Cross</name></author>
	</entry>
	<entry>
		<id>https://wiki.ampr.org/w/index.php?title=Amprgw&amp;diff=1109</id>
		<title>Amprgw</title>
		<link rel="alternate" type="text/html" href="https://wiki.ampr.org/w/index.php?title=Amprgw&amp;diff=1109"/>
		<updated>2024-05-04T12:09:46Z</updated>

		<summary type="html">&lt;p&gt;Cross: Suggested edits from KC8QBA.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;AMPRGW is amprgw.ucsd.edu, at IP address 169.228.34.84.  It is the Internet-to-AMPRNet router.&lt;br /&gt;
&lt;br /&gt;
When initially configuring a local IPENCAP gateway, or when rebooting a gateway, traffic to and from the public internet may be unavailable and/or throttled for up to one hour if AMPRGW detects errors related to the gateway being down.&lt;br /&gt;
&lt;br /&gt;
Additionally, traffic to the public internet will not be passed across the AMPRGW unless it originates from a ARMPNet IP address that has a DNS &amp;quot;A&amp;quot; record in the [[ampr.org]] domain.&lt;/div&gt;</summary>
		<author><name>Cross</name></author>
	</entry>
	<entry>
		<id>https://wiki.ampr.org/w/index.php?title=OH7LZB_VPN&amp;diff=1108</id>
		<title>OH7LZB VPN</title>
		<link rel="alternate" type="text/html" href="https://wiki.ampr.org/w/index.php?title=OH7LZB_VPN&amp;diff=1108"/>
		<updated>2024-05-04T12:03:28Z</updated>

		<summary type="html">&lt;p&gt;Cross: KC8QBA suggests bolding the sentence about the OH7LZB VPN being down.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The OH7LZB VPN was an experimental method to access the IPIP Mesh using a VPN from anywhere on the Internet. The VPN was openly available to any amateur radio operators who had successfully applied for an X.509 certificate from one of the following Certificate Authorities:&lt;br /&gt;
&lt;br /&gt;
* [http://www.arrl.org/logbook-of-the-world ARRL Logbook of the World (LoTW)]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;As of May, 2024, the OH7LZB VPN appears to no longer be operational.&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Certificate Authority (CA) validates using a relatively strong method that the operator is actually licensed, and gives the operator a cryptographic certificate to prove that. Other services, such as this VPN can then check that the operator possesses a valid amateur radio operator certificate (and the accompanying private key), without any manual work being performed by the operators of those services. The operator can use his private key to sign LoTW log files, or any other information he wishes to communicate, and other parties trusting the CA can use the certificate to check that they have been transmitted by someone who has a private key and a certificate for a callsign from the CA.&lt;br /&gt;
&lt;br /&gt;
If and when other organisations start to give out X.509 certificates, after sufficient amateur radio license validation, the VPN will be configured to accept those in addition to the LoTW. If you&#039;re not willing to obtain a LoTW certificate, please set up a CA for your local club or association, document the method of license validation you&#039;re using, and I&#039;ll be happy to trust your certificates.&lt;br /&gt;
&lt;br /&gt;
The VPN operator (Hessu, OH7LZB) does not have time to run a CA and validate licenses manually, so please don&#039;t ask for a certificate from anywhere else than the CAs listed above. Thanks!&lt;br /&gt;
&lt;br /&gt;
The VPN is only used to access the IPIP Mesh. While you&#039;re connected to the VPN, the VPN client will only transmit packets from you to the IPIP Mesh via the VPN. Packets from you to the rest of the Internet will not go via the VPN - they&#039;ll flow out from your local network connection as before. This is called a [http://en.wikipedia.org/wiki/Split_tunneling split tunnel VPN configuration].&lt;br /&gt;
&lt;br /&gt;
The setup is still a bit complicated - it can be made easier and more automatic with a little additional software in a later phase.&lt;br /&gt;
&lt;br /&gt;
The VPN is an experimental service. It might be shut down for technical or political reasons - we&#039;ll see if it&#039;s a feasible idea or not.&lt;br /&gt;
&lt;br /&gt;
= Getting a certificate from LoTW =&lt;br /&gt;
&lt;br /&gt;
Go through [https://lotw.arrl.org/lotw-help/getting-started/ these simple steps]. After step 4 you&#039;re ready to continue with the VPN.&lt;br /&gt;
&lt;br /&gt;
It&#039;s going to take some time to validate, and you&#039;ll have to do some manual work (especially if you&#039;re outside the USA), but that is intentional. It significantly reduces abuse of the system, and increases its security.&lt;br /&gt;
&lt;br /&gt;
= Extracting the certificate from LoTW =&lt;br /&gt;
&lt;br /&gt;
LoTW uses a custom file format (.TQ*) to exchange certificates, but after the LoTW certificate process is done and the TrustedQSL software has your certificates, they can be easily copied from TrustedQSL&#039;s directories. You&#039;ll need three files: your &#039;&#039;&#039;user certificate&#039;&#039;&#039;, an &#039;&#039;&#039;intermediate certificate&#039;&#039;&#039; that was used to sign it, and your &#039;&#039;&#039;private key&#039;&#039;&#039;. The only secret piece of information is the private key - you should not reveal it to anyone at any point, as they could then use services on your behalf, using your callsign.&lt;br /&gt;
&lt;br /&gt;
== Windows ==&lt;br /&gt;
&lt;br /&gt;
* C:\Documents and Settings\your-username\Application Data\TrustedQSL contains two directories, &#039;&#039;&#039;certs&#039;&#039;&#039; and &#039;&#039;&#039;keys&#039;&#039;&#039;.&lt;br /&gt;
* certs\user contains the &#039;&#039;&#039;user certificate&#039;&#039;&#039;&lt;br /&gt;
* certs\authorities contains an &#039;&#039;&#039;intermediate certificate&#039;&#039;&#039;&lt;br /&gt;
* keys\YOURCALL contains, within some XML, your &#039;&#039;&#039;private key&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Make copies of those files in another directory, and work on those copies in order to avoid breaking the originals.&lt;br /&gt;
&lt;br /&gt;
The user and intermediate certificates need to be concatenated to a single file named &#039;&#039;&#039;client.crt&#039;&#039;&#039;. The user certificate must be first, followed by the intermediate certificate. That can be done by an ascii editor such as Notepad (Wordpad or Word is likely to mess it up in a big way).&lt;br /&gt;
&lt;br /&gt;
The private key needs to be extracted from the YOURCALL file. The file is a regular ASCII text file, and contains a block which looks something like this (just longer):&lt;br /&gt;
&lt;br /&gt;
 -----BEGIN RSA PRIVATE KEY-----&lt;br /&gt;
 Proc-Type: 4,ENCRYPTED&lt;br /&gt;
 DEK-Info: DES-EDE3-CBC,0C7B5495F6A91F31&lt;br /&gt;
 &lt;br /&gt;
 0xmWfliK/v9U88MFyYtUbteRoAkfVMK6BllcdID3pZzmdykHaPLZUjXOCUh3vFUX&lt;br /&gt;
 1bjnYwXpLX/CxgZ6NIxQIk7jMjL3iaP5SkWzCswqi9mCO+zHxuS6PWq7YwbWNFgo&lt;br /&gt;
 7smNcko1yTp7f/VbS4CZ5kgIF9kCgNaiqdxq+v0IcphQHRR4xjfLpBQ4ckYOi4nC&lt;br /&gt;
 jqFR1BitwBL4K2JeE9PGUkkUBwvU4oOi9PGChuoxMXs8PwKi/dZTmSWM7kOfMiBw&lt;br /&gt;
 -----END RSA PRIVATE KEY-----&lt;br /&gt;
&lt;br /&gt;
Copy-paste that block to a separate file named &#039;&#039;&#039;client.key&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Linux and Mac ==&lt;br /&gt;
&lt;br /&gt;
* ~/.tqsl/certs/user contains the &#039;&#039;&#039;user certificate&#039;&#039;&#039;&lt;br /&gt;
* ~/.tqsl/certs/authorities contains an &#039;&#039;&#039;intermediate certificate&#039;&#039;&#039;&lt;br /&gt;
* ~/.tqsl/keys/YOURCALL contains, within some XML, your &#039;&#039;&#039;private key&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The user and intermediate certificates need to be concatenated to a single file named &#039;&#039;&#039;client.crt&#039;&#039;&#039;. The user certificate must be first, followed by the intermediate certificate. That can be done by a single command:&lt;br /&gt;
&lt;br /&gt;
 cat ~/.tqsl/certs/user ~/.tqsl/certs/authorities &amp;gt; client.crt&lt;br /&gt;
&lt;br /&gt;
The private key needs to be extracted from the YOURCALL file. The file is a regular ASCII text file, and contains a block which looks something like this (just longer):&lt;br /&gt;
&lt;br /&gt;
 -----BEGIN RSA PRIVATE KEY-----&lt;br /&gt;
 Proc-Type: 4,ENCRYPTED&lt;br /&gt;
 DEK-Info: DES-EDE3-CBC,0C7B5495F6A91F31&lt;br /&gt;
 &lt;br /&gt;
 0xmWfliK/v9U88MFyYtUbteRoAkfVMK6BllcdID3pZzmdykHaPLZUjXOCUh3vFUX&lt;br /&gt;
 1bjnYwXpLX/CxgZ6NIxQIk7jMjL3iaP5SkWzCswqi9mCO+zHxuS6PWq7YwbWNFgo&lt;br /&gt;
 7smNcko1yTp7f/VbS4CZ5kgIF9kCgNaiqdxq+v0IcphQHRR4xjfLpBQ4ckYOi4nC&lt;br /&gt;
 jqFR1BitwBL4K2JeE9PGUkkUBwvU4oOi9PGChuoxMXs8PwKi/dZTmSWM7kOfMiBw&lt;br /&gt;
 -----END RSA PRIVATE KEY-----&lt;br /&gt;
&lt;br /&gt;
Copy-paste that block to a separate file named &#039;&#039;&#039;client.key&#039;&#039;&#039;. If you&#039;re going to open up the original private key file in a text editor, it&#039;s a good idea to make a backup copy of that file first in case of an accidental corruption of its contents.&lt;br /&gt;
&lt;br /&gt;
= Configuring the VPN =&lt;br /&gt;
&lt;br /&gt;
== Windows: OpenVPN ==&lt;br /&gt;
&lt;br /&gt;
# [http://openvpn.net/index.php/download/community-downloads.html Download the Windows Installer], it&#039;s free and open source.&lt;br /&gt;
# Run the installer to install it.&lt;br /&gt;
# [http://he.fi/amprnet-vpn/amprnet-vpn-win.zip Download the AMPRNet VPN configuration files for Windows]&lt;br /&gt;
# Open up the zip file, it contains two files: amprnet-vpn.ovpn and amprnet-vpn-ca.crt.&lt;br /&gt;
# In Start menu, under OpenVPN =&amp;gt; Shortcuts you&#039;ll find an entry named &#039;&#039;&#039;OpenVPN configuration file directory&#039;&#039;&#039;. Open it, and move the two files from the zip to the configuration file directory. &lt;br /&gt;
# Place client.crt and client.key, which were created previously, in the configuration file directory.&lt;br /&gt;
# Run the &#039;&#039;&#039;OpenVPN GUI&#039;&#039;&#039; from the desktop icon or start menu. A new icon will appear in the lower right corner (two computers with red screens + a globe on the side).&lt;br /&gt;
# Right-click the OpenVPN toolbar icon and select &#039;&#039;&#039;Connect&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
If you chose to encrypt your private key with a password (or passphrase) when initially applying for a LoTW certificate and generating the Certificate Request, OpenVPN will ask you for that password when connecting.&lt;br /&gt;
&lt;br /&gt;
To rephrase: When OpenVPN says &amp;quot;Enter Password&amp;quot;, the password being asked is the one you picked when you first applied for a LoTW certificate. It&#039;s not something the VPN operator knows (or should know). It&#039;s not the one you got on a postcard. Only you have ever been aware of that password (hopefully).&lt;br /&gt;
&lt;br /&gt;
== Linux: OpenVPN ==&lt;br /&gt;
&lt;br /&gt;
=== Ubuntu 15.10 ===&lt;br /&gt;
&lt;br /&gt;
Here is steps to install the VPN to Ubuntu 15.10 destop. Install OpenVPN plugin to network manager.&lt;br /&gt;
Open terminal and type&lt;br /&gt;
&lt;br /&gt;
 sudo apt-get install network-manager-open vpn-gnome&lt;br /&gt;
&lt;br /&gt;
Then add VPN-connection information to NetworkManager&lt;br /&gt;
&lt;br /&gt;
# Click network manager icon on taskbar&lt;br /&gt;
# Edit connections&lt;br /&gt;
# Add&lt;br /&gt;
# OpenVPN&lt;br /&gt;
# Create&lt;br /&gt;
#* Connection name: AMPRNet&lt;br /&gt;
#* Gateway: amprnet-vpn1.aprs.fi&lt;br /&gt;
#* Select proper files to User Certificate, CA certificate and Private key&lt;br /&gt;
#* Optionally enter private key password if you are set one&lt;br /&gt;
# Click Advanced&lt;br /&gt;
#* [x] Use custom gateway port: 1773&lt;br /&gt;
#* [x] Use LZO data compression&lt;br /&gt;
# Click OK&lt;br /&gt;
# Click Save&lt;br /&gt;
# Click Close&lt;br /&gt;
&lt;br /&gt;
Now you can connect to VPN &lt;br /&gt;
&lt;br /&gt;
# Click network manager icon on taskbar&lt;br /&gt;
# VPN connections -&amp;gt; AMPRNet&lt;br /&gt;
# Connection should be established&lt;br /&gt;
&lt;br /&gt;
== Linux (Raspberry PI): OpenVPN ==&lt;br /&gt;
&lt;br /&gt;
Log in to Raspberry Pi console. Install openvpn software.&lt;br /&gt;
&lt;br /&gt;
 sudo apt-get install openvpn&lt;br /&gt;
&lt;br /&gt;
Create openvpn client configuration file with your favourite editor to /etc/openvpn/client.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
client&lt;br /&gt;
dev tun&lt;br /&gt;
proto udp&lt;br /&gt;
remote amprnet-vpn1.aprs.fi 1773&lt;br /&gt;
resolv-retry infinite&lt;br /&gt;
persist-key&lt;br /&gt;
persist-tun&lt;br /&gt;
ca amprnet-vpn-ca.crt&lt;br /&gt;
cert client.crt&lt;br /&gt;
key client.key&lt;br /&gt;
comp-lzo&lt;br /&gt;
verb 3&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Extract your client certificate and key as explained above section Extracting the certificate from LoTW. Copy your certificate files client.crt and client.key to /etc/openvpn/ . You also need amprnet-vpn-ca.crt which can be found inside this archive&lt;br /&gt;
http://he.fi/amprnet-vpn/amprnet-vpn-win.zip . Extract it and copy to /etc/openvpn/&lt;br /&gt;
&lt;br /&gt;
Restart openvpn&lt;br /&gt;
&lt;br /&gt;
 service openvpn restart&lt;br /&gt;
&lt;br /&gt;
All done.&lt;br /&gt;
&lt;br /&gt;
== Mac OS X: Tunnelblick ==&lt;br /&gt;
&lt;br /&gt;
# [https://tunnelblick.net/ Download Tunnelblick], it&#039;s free and open source, and works like a charm. It&#039;s based on OpenVPN.&lt;br /&gt;
# [http://he.fi/amprnet-vpn/amprnet-vpn-tblk.zip Download the VPN configuration for Tunnelblick], it&#039;s a zip file containing a directory with a couple files&lt;br /&gt;
# Double-click the downloaded zip file to extract it, you&#039;ll get a directory named &#039;&#039;&#039;amprnet-vpn.tblk&#039;&#039;&#039;&lt;br /&gt;
# Move the &#039;&#039;&#039;private key&#039;&#039;&#039; (in a file which was named &#039;&#039;&#039;client.key&#039;&#039;&#039; in the previous step) to that directory&lt;br /&gt;
# Move the certificates (in a file which was named &#039;&#039;&#039;client.crt&#039;&#039;&#039; in the previous step) to that directory&lt;br /&gt;
# Double-click the &#039;&#039;&#039;amprnet-vpn.tblk&#039;&#039;&#039; directory - this will launch Tunnelblick and install the VPN configuration&lt;br /&gt;
&lt;br /&gt;
You should now see a &amp;quot;tunnel&amp;quot; icon in the top right corner of the screen. Click it to see a few menu items allowing you to connect and disconnect the VPN.&lt;br /&gt;
&lt;br /&gt;
If you chose to encrypt your private key with a password (or passphrase) when initially applying for a LoTW certificate and generating the Certificate Request, Tunnelblick will ask you for that passphrase when connecting.&lt;br /&gt;
&lt;br /&gt;
To rephrase: When Tunnelblick says &amp;quot;A passphrase is required to connect to amprnet-vpn&amp;quot;, the passphrase being asked is the one you picked when you first applied for a LoTW certificate. It&#039;s not something the VPN operator knows (or should know). Only you have ever been aware of that passphrase (hopefully).&lt;/div&gt;</summary>
		<author><name>Cross</name></author>
	</entry>
	<entry>
		<id>https://wiki.ampr.org/w/index.php?title=Gateway&amp;diff=1107</id>
		<title>Gateway</title>
		<link rel="alternate" type="text/html" href="https://wiki.ampr.org/w/index.php?title=Gateway&amp;diff=1107"/>
		<updated>2024-05-04T12:02:04Z</updated>

		<summary type="html">&lt;p&gt;Cross: Suggestions from KC8QBA re AMPRGW, and light edits for formatting and grammar&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Much of the AMPRNet address space is interconnected via [[gateway|gateways]] that implement IPENCAP ([http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml IP Protocol Number 4]) encapsulated [[tunnel|tunnels]]. These tunnels provide endpoints for the AMPRNet address space allocated to a particular region or end user, effectively forming a mesh network of interconnected tunnels between AMPR subnets. There is a database of all the gateways, their public IP addresses, and the subnets they serve on the [[portal]] that is used to dynamically generate routing information that is distributed to the set of all gateways via modified [[RIP]] advertisements. This database is also regularly copied into a text file called [[encap.txt]] which is basically a routing table describing what subnets can be reached via which gateway.&lt;br /&gt;
&lt;br /&gt;
In order to keep this database up to date, everyone that operates a gateway must register on the [[portal]] and have their gateway(s) assigned to their account and associated with their allocation(s).&lt;br /&gt;
&lt;br /&gt;
In addition to the gateways operated by users who connect via IPENCAP tunnels, traffic exchanged between the ARMPNet mesh and the public Internet is routed via the [[Amprgw]] – please see the [[Amprgw]] page for important details on passing traffic between the public Internet and the IPENCAP tunnel mesh.&lt;br /&gt;
&lt;br /&gt;
Learn how to [[Setting up a gateway on Cisco Routers|set up a  Cisco Router gateway]]&lt;br /&gt;
&lt;br /&gt;
Learn how to [[Setting up a gateway on Linux|set up a Linux gateway]]&lt;br /&gt;
&lt;br /&gt;
Learn how to [[setting up a gateway on MikroTik Routers|set up a gateway on MikroTik Routers]]&lt;br /&gt;
&lt;br /&gt;
Learn how to [[Setting up a gateway on OpenBSD|set up an OpenBSD gateway]]&lt;br /&gt;
&lt;br /&gt;
Learn how to [[Setting up a gateway on OpenWRT|set up an OpenWRT gateway]]&lt;/div&gt;</summary>
		<author><name>Cross</name></author>
	</entry>
	<entry>
		<id>https://wiki.ampr.org/w/index.php?title=FAQ&amp;diff=1106</id>
		<title>FAQ</title>
		<link rel="alternate" type="text/html" href="https://wiki.ampr.org/w/index.php?title=FAQ&amp;diff=1106"/>
		<updated>2024-05-03T17:24:49Z</updated>

		<summary type="html">&lt;p&gt;Cross: Mention that AMPRGW will throttle traffic to a tunnel when it detects errors related to that tunnel.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Frequently Asked Questions&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;What is AMPRNet?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
AMPRNet stands for AMateur Packet Radio NETwork. It is a collection of amateur radio-oriented computers, connected together via a variety of technologies, including radio, Internet, and ethernet. However, all of these computers have an IP address that begins with 44 (that is, IP addresses of the form 44.0.0.0/9 or 44.128.0.0/10). For this reason, AMPRnet can also be referred to as 44Net. &lt;br /&gt;
&lt;br /&gt;
Some further details can be found at https://en.wikipedia.org/wiki/AMPRNet and https://wiki.ampr.org/wiki/Main_Page&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;What is AMPRNet for?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The purpose of AMPRNet is to permit experimentation by amateurs in digital networking and to provide computer services to other amateurs using AMPRNet.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;What does it cost to use AMPRNet?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
There is no cost for using any AMPRNet facilities, however, there may be costs associated with Internet access to reach AMPRNet and/or amateur radio equipment costs.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;How do I connect to AMPRNet?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
There are four main methods people use:&lt;br /&gt;
&lt;br /&gt;
* VPN&lt;br /&gt;
* BGP routing (See Also [[Announcing your allocation directly]])&lt;br /&gt;
* Direct radio links.&lt;br /&gt;
* IP Tunneling&lt;br /&gt;
&lt;br /&gt;
Note: Functionally, a VPN and a tunnel do much the same thing, except a VPN is designed for privacy (i.e. strong authentication and encryption), whilst IP tunnelling in the AMPRNet context is actually an all-to-all interconnected mesh of tunnels and is not encrypted (as often the data is transferred over radio).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;What is IP Tunneling?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The information that traverses the Internet does so as &amp;quot;packets&amp;quot; of data, traveling over a variety of routes, between a source and a destination. Each packet contains a header, which tells all the devices along the route information such as the source and destination, plus the payload, which is the data to actually be transferred. Clearly, there must be a path all the way from the sources to the destination, and back. &lt;br /&gt;
AMPRNet consists of small, non-connected groups of computers, that would otherwise not be able to connect to one another. However, since internet devices along the route really don&#039;t care about the contents of the payload section, you can put a completely new packet into that section, including an entirely different header, and its own payload section. That second header has source and destination addresses completely different from the first header - all that is required is that the first destination recognizes the encapsulated packet, de-encapsulates it, and forwards it to the second header destination. Return traffic follows a corresponding process. In that way, 44-net hosts can communicate with other 44-net hosts, by means of encapsulating their data packets in packets to non-44net hosts. This is called tunneling (or encapsulating). A later section in this FAQ discusses installing a tunnel. &lt;br /&gt;
Tunneling is probably the most commonly used method of accessing AMPRNet.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;How does AMPR over IP tunnel actually work?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
AMPR nodes are actually not connected via a single tunnel but via a large mesh network of tunnels. Suppose user1 has public IP address 198.51.100.1 and user2 has 203.0.113.1. These two can normally communicate over the internet. However, if both users have a 44net IP address, user1 can encapsulate the 44 packet into an outer packet and send it to 203.0.113.1. Similarly, user2 can encapsulate the IP packet with the 44net addresses and send it to 198.51.100.1. In Linux (and most other systems), this is accomplished using a single ipip device and adding a route using the &amp;quot;nexthop&amp;quot; statement. When a packet is pushed into the ipip device, the outer IP header is added and sent to the router in the nexthop statement. A list of all AMPR users is required and this can be either accomplished by downloading a simple textfile and adding the routes manually or by using RIP44, as discussed in the FAQ section below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;What is a VPN?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
VPN stands for Virtual Private Network. It is a facility that enables a computer to act (using the Internet) as though is physically connected to another computer network. There are many different ways to set up a VPN, so this is beyond the scope of this FAQ. However, it always involves configuring software and accounts on a computer, to connect to the VPN server. Some amateurs who have connections to AMPRNet have set up VPN servers so that other amateurs can achieve a &amp;quot;virtual&amp;quot; connection to AMPRNet. The technical details, account details, and IP address details must be obtained from the operator of that VPN. One such VPN is listed at https://wiki.ampr.org/wiki/AMPRNet_VPN.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;What is BGP Routing?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The Internet has millions of different computers connected to it, each having an address. Devices called routers deliver traffic between computers and can send &amp;quot;advertisements&amp;quot; to other routers to tell those other routers about the locations of some of those addresses. The protocol used is called BGP, Border Gateway Protocol. If you are fortunate enough to have a computer that can send BGP advertisements, then you can advertise that your computer is part of the AMPRNet address range, and hence receive AMPRNet traffic.&lt;br /&gt;
&lt;br /&gt;
Unfortunately, most companies and most commercial ISPs will not permit their users to originate BGP advertisements (especially for address ranges that are not in their usual address range), so BGP is not a viable means to connect to AMPRNet for most people.  There are Virtual Private Server (VPS) Providers (or Cloud Providers) who will announce your AMPRNet allocation without the need for your own Autonomous System (AS) number. [[Routing your allocation via BGP]] has a list of VPS/Cloud Providers.&lt;br /&gt;
&lt;br /&gt;
Installing BGP is beyond the scope of this FAQ. Note however that you must have written permission from the administrator of the ARDC 44 address space, before you BGP advertise any part of that space.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;What about radio links?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In many places, groups of amateurs have established networks of radio links, and often have used one of the preceding approaches so that those radio networks connect to and become part of AMPRNet. You would need to contact those groups regarding frequencies, modes, and address allocations.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Do I need to consider security?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Yes! Any computer connected to the Internet must be configured and maintained in a secure fashion, and this includes any computer connected to AMPRNet (regardless of the connection technique). Repeat - you MUST secure your computer! This includes using firewalls, keeping software up to date, using strong passwords, etc etc. In some cases, encryption may also be used.&lt;br /&gt;
&lt;br /&gt;
How to maintain security is beyond the scope of this FAQ. Searching for &amp;quot;How to secure my computer&amp;quot; will return many, many hits though!&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;How do I get an address allocation?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
If you connect to an existing VPN or existing radio network, it is likely that the operators of those facilities will already have address ranges established and will allocate your address(es). If you wish to establish a new tunnel or BGP-based link, then the process is handled by a semi-automated process on our portal. The steps are:&lt;br /&gt;
    1. Register using your callsign on the portal https://portal.ampr.org&lt;br /&gt;
    2. Log in and navigate to the  Networks page.&lt;br /&gt;
    3. Click on your country.  A list of regions/subnets may appear; if so, click on the appropriate one.&lt;br /&gt;
    4. Click on the subnet and you&#039;ll be presented with a simple form to complete.&lt;br /&gt;
    5. If you are requesting a single address for a host, leave the netmask as /32;&lt;br /&gt;
    6. if you are requesting a  block/subnet, select the appropriate netwidth. E.g. for a 256 host subnet, select /24.&lt;br /&gt;
    7. Put a short message explaining your request in the Message area of the form.  Be sure to indicate&lt;br /&gt;
    if you are planning to directly route a subnet as these require special handling&lt;br /&gt;
    8. Click Send.  Your request will be forwarded to the coordinator for your region/subnet.  You&#039;ll&lt;br /&gt;
    receive a confirming email.  The coordinator may contact you for further details if required.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Can I have a domain name entry for my AMPRNet host?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Yes. Currently, domain name requests are handled by the area coordinators - contact details are on the portal. Note: the old email robot facility no longer functions.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;What about IPv6?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
There is no IPv6 equivalent of AMPRNet at present.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;How do I configure a Tunnel?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The technique varies according to the Operating System you use. However, all involve the creation of a new &amp;quot;pseudo&amp;quot; interface - unlike your normal ethernet network connection, this one doesn&#039;t actually exist on the back panel of your computer. However, it exists as far as the Operating System is concerned. A normal ethernet device accepts a data packet (consisting of a header and payload, as previously discussed) and sends it out the ethernet cable (often via a modem, to the Internet).  A &amp;quot;pseudo&amp;quot; interface however accepts a data packet, encapsulates it in the data portion of a new packet, adds a new and different header, and passes all that to the ethernet device, which then processes this new data packet as normal, sending it to a recipient who will de-encapsulate it. Reception of tunneled traffic is the reverse process. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Consequently, two requirements apply:&lt;br /&gt;
&lt;br /&gt;
a) The computer must have full connectivity to the non-44 hosts that will send or receive the tunneled packets containing 44-net traffic. You cannot route ALL traffic to the pseudo interface!&lt;br /&gt;
&lt;br /&gt;
b) The pseudo driver must have a mechanism to tell it which non-44 net hosts can handle particular subsets of 44-net traffic - very few can handle the entire 44-net range! It should be noted that the information changes quite frequently, as tunnel hosts come and go, so must be updated as described below.&lt;br /&gt;
&lt;br /&gt;
https://wiki.ampr.org/wiki/Main_Page has links to several different ways of configuring tunnels.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;How do I obtain and maintain a list of tunnel hosts?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
There are three main mechanisms:&lt;br /&gt;
&lt;br /&gt;
a) log on to the portal (as described above) and navigate to the &amp;quot;Gateways/List&amp;quot; section that permits downloading of the &amp;quot;encap&amp;quot; file. Download that file, and use a script on the computer to turn it into commands that update the configuration of the tunnel device.&lt;br /&gt;
&lt;br /&gt;
b) receive the encap file by mail, and use a script to process it. You can register for this email on the portal &amp;quot;Gateways/Options&amp;quot; page.&lt;br /&gt;
&lt;br /&gt;
c) Receive and process &amp;quot;broadcasts&amp;quot; of configuration data that are available.  This information is broadcast to all gateways listed on the portal. There is a software package called &amp;quot;ampr-ripd&amp;quot; that enables this process&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Can I just route all 44net traffic via a single tunnel?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
No. The main AMPRNet gateway does not provide this functionality - you must have a tunnel to each system you wish to contact.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;What is the AmprGW?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The AmprGW is a server run by ARDC at UCSD as part of a long-running Internet research project. It has a number of functions:&lt;br /&gt;
&lt;br /&gt;
a) It provides a selective gateway between non-AMPRNet internet devices and the IPIP (mesh) AMPRNet. For this traffic, it filters at the per-host(/32) level. Each host which is to receive traffic from the Internet into AMPRNet must individually be listed in the permissions file, which is built from the AMPR.ORG DNS &#039;A&#039; records. If there is no DNS A record for a tunneled amprnet destination host, the traffic is not forwarded in either direction. Therefore, if you want hosts on your subnet to be able to communicate with the Internet, you will need to have your local coordinator add them to the AMPR.ORG DNS for you.&lt;br /&gt;
&lt;br /&gt;
b) It forwards traffic between Internet hosts (including those AMPRNet that are directly connected to the Internet [BGP-routed]) and IPIP tunneled AMPRNet hosts. Some &amp;quot;validity&amp;quot; filtering is applied during this process - traffic that is invalid or misconfigured will be dropped. Note: AmprGW does NOT forward between different IPIP tunneled AMPRNet hosts. That is why you cannot have just a single IPIP tunnel for all of AMPRNet. Thus the tunneled AMPRNet as a whole forms a fully-connected mesh, not a &#039;star&#039; configuration.&lt;br /&gt;
&lt;br /&gt;
c) AmprGW originates RIP44 broadcasts containing routing information about gateways and the AMPRNet subnets they service. The RIP44 transmissions are sent as IPIP encapsulated UDP packets for port 520 from 169.228.34.84 and sent individually to the commercial (external) address of every gateway. The packets have an inner source address of 44.0.0.1 and an inner destination of 224.0.0.9, the RIP multicast address. They are IPIP encapsulated packets, so without de-encapsulating them, the RIP is not visible to conventional routing software. Specialized software such as &#039;ampr-ripd&#039; may be employed to make use of the RIP44 broadcasts, to set up AMPRNet routes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;I rebooted my router and now I can&#039;t talk to the Internet, what&#039;s going on?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
If AMPRGW detects errors when attempting to send traffic to a tunnel&#039;s configured gateway, it will automatically throttle traffic through that tunnel for approximately one hour. This is meant to prevent endlessly sending traffic to gateways that are no longer in service. An example of the sort of errors that will trigger this are ICMP Host Unreachable messages generated by an upstream provider, such as an ISP. Empirically, several users have observed that rebooting a gateway can pause traffic long enough for this to happen. However, traffic will start flowing again in an hour or so.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Can BGP, VPN, and IP tunnel hosts inter-communicate?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Yes. The AMPRNet gateway has been configured to support this functionality.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Can I put my tunnel on my home LAN and use NAT?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Yes. However, in general, a home modem using NAT won&#039;t be able to correctly process inbound tunneled 44-net traffic and forward it to the correct host - the &amp;quot;port forward&amp;quot; facility in most NAT devices relies on a port number, but there are no port numbers for a tunnel packet! However, most modems have a &amp;quot;DMZ&amp;quot; facility, whereby all unrecognized traffic (and this includes tunneled traffic) can be forwarded to one particular host on the LAN. That host can then be configured to recognize and correctly process tunneled data. However - security alert! - it will also be exposed to all sorts of other, unwanted traffic as well! See the Security section above.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Can I use an AMPRNet VPN on my home LAN?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Generally, yes. Most home modem/routers have good support for VPN usage, although you mustn&#039;t use it for general internet access as it is for amateur radio use only!&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;How can I get help with AMPRNet issues?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Many amateurs are willing to assist other hams. You can find some of them on the groups.io 44Net group here https://ardc.groups.io/g/44net&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;What about 44.128.0.0/16?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Subnet 44.128.0.0/16 is currently reserved for testing.  No operational subnets are planned for this address space. Older documentation incorrectly referred to this block of addresses as &amp;quot;private&amp;quot;, that is, unrouted like the 192.168.0.0/16 RFC1918 subnet. This is incorrect; the 44.128.0.0/16 subnet can be routed, but do not use it except for brief test purposes.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Credits&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This FAQ was originally commenced by Steve VK5ASF, using material from earlier FAQs, from various contributors to the 44net mailing list, and from Brian Kantor.&lt;/div&gt;</summary>
		<author><name>Cross</name></author>
	</entry>
	<entry>
		<id>https://wiki.ampr.org/w/index.php?title=Amprgw&amp;diff=1105</id>
		<title>Amprgw</title>
		<link rel="alternate" type="text/html" href="https://wiki.ampr.org/w/index.php?title=Amprgw&amp;diff=1105"/>
		<updated>2024-05-03T17:16:21Z</updated>

		<summary type="html">&lt;p&gt;Cross: Mention that AMPRGW will throttle traffic if a router reboots.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;AMPRGW is amprgw.ucsd.edu, at IP address 169.228.34.84.  It is the Internet-to-AMPRNet router.&lt;br /&gt;
&lt;br /&gt;
Note that, if AMPRGW detects errors for an endpoint, it will throttle traffic to that endpoint for approximately one hour.  Often, rebooting a gateway system will be enough to trigger this behavior.&lt;/div&gt;</summary>
		<author><name>Cross</name></author>
	</entry>
	<entry>
		<id>https://wiki.ampr.org/w/index.php?title=OH7LZB_VPN&amp;diff=1104</id>
		<title>OH7LZB VPN</title>
		<link rel="alternate" type="text/html" href="https://wiki.ampr.org/w/index.php?title=OH7LZB_VPN&amp;diff=1104"/>
		<updated>2024-05-03T17:14:08Z</updated>

		<summary type="html">&lt;p&gt;Cross: KC8QBA reports on the 44Net mailing list that the OH7LZB VPN is no longer working; mention that on the wiki page.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The OH7LZB VPN was an experimental method to access the IPIP Mesh using a VPN from anywhere on the Internet. The VPN was openly available to any amateur radio operators who had successfully applied for an X.509 certificate from one of the following Certificate Authorities:&lt;br /&gt;
&lt;br /&gt;
* [http://www.arrl.org/logbook-of-the-world ARRL Logbook of the World (LoTW)]&lt;br /&gt;
&lt;br /&gt;
As of May, 2024, the OH7LZB VPN appears to no longer be operational.&lt;br /&gt;
&lt;br /&gt;
The Certificate Authority (CA) validates using a relatively strong method that the operator is actually licensed, and gives the operator a cryptographic certificate to prove that. Other services, such as this VPN can then check that the operator possesses a valid amateur radio operator certificate (and the accompanying private key), without any manual work being performed by the operators of those services. The operator can use his private key to sign LoTW log files, or any other information he wishes to communicate, and other parties trusting the CA can use the certificate to check that they have been transmitted by someone who has a private key and a certificate for a callsign from the CA.&lt;br /&gt;
&lt;br /&gt;
If and when other organisations start to give out X.509 certificates, after sufficient amateur radio license validation, the VPN will be configured to accept those in addition to the LoTW. If you&#039;re not willing to obtain a LoTW certificate, please set up a CA for your local club or association, document the method of license validation you&#039;re using, and I&#039;ll be happy to trust your certificates.&lt;br /&gt;
&lt;br /&gt;
The VPN operator (Hessu, OH7LZB) does not have time to run a CA and validate licenses manually, so please don&#039;t ask for a certificate from anywhere else than the CAs listed above. Thanks!&lt;br /&gt;
&lt;br /&gt;
The VPN is only used to access the IPIP Mesh. While you&#039;re connected to the VPN, the VPN client will only transmit packets from you to the IPIP Mesh via the VPN. Packets from you to the rest of the Internet will not go via the VPN - they&#039;ll flow out from your local network connection as before. This is called a [http://en.wikipedia.org/wiki/Split_tunneling split tunnel VPN configuration].&lt;br /&gt;
&lt;br /&gt;
The setup is still a bit complicated - it can be made easier and more automatic with a little additional software in a later phase.&lt;br /&gt;
&lt;br /&gt;
The VPN is an experimental service. It might be shut down for technical or political reasons - we&#039;ll see if it&#039;s a feasible idea or not.&lt;br /&gt;
&lt;br /&gt;
= Getting a certificate from LoTW =&lt;br /&gt;
&lt;br /&gt;
Go through [https://lotw.arrl.org/lotw-help/getting-started/ these simple steps]. After step 4 you&#039;re ready to continue with the VPN.&lt;br /&gt;
&lt;br /&gt;
It&#039;s going to take some time to validate, and you&#039;ll have to do some manual work (especially if you&#039;re outside the USA), but that is intentional. It significantly reduces abuse of the system, and increases its security.&lt;br /&gt;
&lt;br /&gt;
= Extracting the certificate from LoTW =&lt;br /&gt;
&lt;br /&gt;
LoTW uses a custom file format (.TQ*) to exchange certificates, but after the LoTW certificate process is done and the TrustedQSL software has your certificates, they can be easily copied from TrustedQSL&#039;s directories. You&#039;ll need three files: your &#039;&#039;&#039;user certificate&#039;&#039;&#039;, an &#039;&#039;&#039;intermediate certificate&#039;&#039;&#039; that was used to sign it, and your &#039;&#039;&#039;private key&#039;&#039;&#039;. The only secret piece of information is the private key - you should not reveal it to anyone at any point, as they could then use services on your behalf, using your callsign.&lt;br /&gt;
&lt;br /&gt;
== Windows ==&lt;br /&gt;
&lt;br /&gt;
* C:\Documents and Settings\your-username\Application Data\TrustedQSL contains two directories, &#039;&#039;&#039;certs&#039;&#039;&#039; and &#039;&#039;&#039;keys&#039;&#039;&#039;.&lt;br /&gt;
* certs\user contains the &#039;&#039;&#039;user certificate&#039;&#039;&#039;&lt;br /&gt;
* certs\authorities contains an &#039;&#039;&#039;intermediate certificate&#039;&#039;&#039;&lt;br /&gt;
* keys\YOURCALL contains, within some XML, your &#039;&#039;&#039;private key&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Make copies of those files in another directory, and work on those copies in order to avoid breaking the originals.&lt;br /&gt;
&lt;br /&gt;
The user and intermediate certificates need to be concatenated to a single file named &#039;&#039;&#039;client.crt&#039;&#039;&#039;. The user certificate must be first, followed by the intermediate certificate. That can be done by an ascii editor such as Notepad (Wordpad or Word is likely to mess it up in a big way).&lt;br /&gt;
&lt;br /&gt;
The private key needs to be extracted from the YOURCALL file. The file is a regular ASCII text file, and contains a block which looks something like this (just longer):&lt;br /&gt;
&lt;br /&gt;
 -----BEGIN RSA PRIVATE KEY-----&lt;br /&gt;
 Proc-Type: 4,ENCRYPTED&lt;br /&gt;
 DEK-Info: DES-EDE3-CBC,0C7B5495F6A91F31&lt;br /&gt;
 &lt;br /&gt;
 0xmWfliK/v9U88MFyYtUbteRoAkfVMK6BllcdID3pZzmdykHaPLZUjXOCUh3vFUX&lt;br /&gt;
 1bjnYwXpLX/CxgZ6NIxQIk7jMjL3iaP5SkWzCswqi9mCO+zHxuS6PWq7YwbWNFgo&lt;br /&gt;
 7smNcko1yTp7f/VbS4CZ5kgIF9kCgNaiqdxq+v0IcphQHRR4xjfLpBQ4ckYOi4nC&lt;br /&gt;
 jqFR1BitwBL4K2JeE9PGUkkUBwvU4oOi9PGChuoxMXs8PwKi/dZTmSWM7kOfMiBw&lt;br /&gt;
 -----END RSA PRIVATE KEY-----&lt;br /&gt;
&lt;br /&gt;
Copy-paste that block to a separate file named &#039;&#039;&#039;client.key&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Linux and Mac ==&lt;br /&gt;
&lt;br /&gt;
* ~/.tqsl/certs/user contains the &#039;&#039;&#039;user certificate&#039;&#039;&#039;&lt;br /&gt;
* ~/.tqsl/certs/authorities contains an &#039;&#039;&#039;intermediate certificate&#039;&#039;&#039;&lt;br /&gt;
* ~/.tqsl/keys/YOURCALL contains, within some XML, your &#039;&#039;&#039;private key&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The user and intermediate certificates need to be concatenated to a single file named &#039;&#039;&#039;client.crt&#039;&#039;&#039;. The user certificate must be first, followed by the intermediate certificate. That can be done by a single command:&lt;br /&gt;
&lt;br /&gt;
 cat ~/.tqsl/certs/user ~/.tqsl/certs/authorities &amp;gt; client.crt&lt;br /&gt;
&lt;br /&gt;
The private key needs to be extracted from the YOURCALL file. The file is a regular ASCII text file, and contains a block which looks something like this (just longer):&lt;br /&gt;
&lt;br /&gt;
 -----BEGIN RSA PRIVATE KEY-----&lt;br /&gt;
 Proc-Type: 4,ENCRYPTED&lt;br /&gt;
 DEK-Info: DES-EDE3-CBC,0C7B5495F6A91F31&lt;br /&gt;
 &lt;br /&gt;
 0xmWfliK/v9U88MFyYtUbteRoAkfVMK6BllcdID3pZzmdykHaPLZUjXOCUh3vFUX&lt;br /&gt;
 1bjnYwXpLX/CxgZ6NIxQIk7jMjL3iaP5SkWzCswqi9mCO+zHxuS6PWq7YwbWNFgo&lt;br /&gt;
 7smNcko1yTp7f/VbS4CZ5kgIF9kCgNaiqdxq+v0IcphQHRR4xjfLpBQ4ckYOi4nC&lt;br /&gt;
 jqFR1BitwBL4K2JeE9PGUkkUBwvU4oOi9PGChuoxMXs8PwKi/dZTmSWM7kOfMiBw&lt;br /&gt;
 -----END RSA PRIVATE KEY-----&lt;br /&gt;
&lt;br /&gt;
Copy-paste that block to a separate file named &#039;&#039;&#039;client.key&#039;&#039;&#039;. If you&#039;re going to open up the original private key file in a text editor, it&#039;s a good idea to make a backup copy of that file first in case of an accidental corruption of its contents.&lt;br /&gt;
&lt;br /&gt;
= Configuring the VPN =&lt;br /&gt;
&lt;br /&gt;
== Windows: OpenVPN ==&lt;br /&gt;
&lt;br /&gt;
# [http://openvpn.net/index.php/download/community-downloads.html Download the Windows Installer], it&#039;s free and open source.&lt;br /&gt;
# Run the installer to install it.&lt;br /&gt;
# [http://he.fi/amprnet-vpn/amprnet-vpn-win.zip Download the AMPRNet VPN configuration files for Windows]&lt;br /&gt;
# Open up the zip file, it contains two files: amprnet-vpn.ovpn and amprnet-vpn-ca.crt.&lt;br /&gt;
# In Start menu, under OpenVPN =&amp;gt; Shortcuts you&#039;ll find an entry named &#039;&#039;&#039;OpenVPN configuration file directory&#039;&#039;&#039;. Open it, and move the two files from the zip to the configuration file directory. &lt;br /&gt;
# Place client.crt and client.key, which were created previously, in the configuration file directory.&lt;br /&gt;
# Run the &#039;&#039;&#039;OpenVPN GUI&#039;&#039;&#039; from the desktop icon or start menu. A new icon will appear in the lower right corner (two computers with red screens + a globe on the side).&lt;br /&gt;
# Right-click the OpenVPN toolbar icon and select &#039;&#039;&#039;Connect&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
If you chose to encrypt your private key with a password (or passphrase) when initially applying for a LoTW certificate and generating the Certificate Request, OpenVPN will ask you for that password when connecting.&lt;br /&gt;
&lt;br /&gt;
To rephrase: When OpenVPN says &amp;quot;Enter Password&amp;quot;, the password being asked is the one you picked when you first applied for a LoTW certificate. It&#039;s not something the VPN operator knows (or should know). It&#039;s not the one you got on a postcard. Only you have ever been aware of that password (hopefully).&lt;br /&gt;
&lt;br /&gt;
== Linux: OpenVPN ==&lt;br /&gt;
&lt;br /&gt;
=== Ubuntu 15.10 ===&lt;br /&gt;
&lt;br /&gt;
Here is steps to install the VPN to Ubuntu 15.10 destop. Install OpenVPN plugin to network manager.&lt;br /&gt;
Open terminal and type&lt;br /&gt;
&lt;br /&gt;
 sudo apt-get install network-manager-open vpn-gnome&lt;br /&gt;
&lt;br /&gt;
Then add VPN-connection information to NetworkManager&lt;br /&gt;
&lt;br /&gt;
# Click network manager icon on taskbar&lt;br /&gt;
# Edit connections&lt;br /&gt;
# Add&lt;br /&gt;
# OpenVPN&lt;br /&gt;
# Create&lt;br /&gt;
#* Connection name: AMPRNet&lt;br /&gt;
#* Gateway: amprnet-vpn1.aprs.fi&lt;br /&gt;
#* Select proper files to User Certificate, CA certificate and Private key&lt;br /&gt;
#* Optionally enter private key password if you are set one&lt;br /&gt;
# Click Advanced&lt;br /&gt;
#* [x] Use custom gateway port: 1773&lt;br /&gt;
#* [x] Use LZO data compression&lt;br /&gt;
# Click OK&lt;br /&gt;
# Click Save&lt;br /&gt;
# Click Close&lt;br /&gt;
&lt;br /&gt;
Now you can connect to VPN &lt;br /&gt;
&lt;br /&gt;
# Click network manager icon on taskbar&lt;br /&gt;
# VPN connections -&amp;gt; AMPRNet&lt;br /&gt;
# Connection should be established&lt;br /&gt;
&lt;br /&gt;
== Linux (Raspberry PI): OpenVPN ==&lt;br /&gt;
&lt;br /&gt;
Log in to Raspberry Pi console. Install openvpn software.&lt;br /&gt;
&lt;br /&gt;
 sudo apt-get install openvpn&lt;br /&gt;
&lt;br /&gt;
Create openvpn client configuration file with your favourite editor to /etc/openvpn/client.conf&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
client&lt;br /&gt;
dev tun&lt;br /&gt;
proto udp&lt;br /&gt;
remote amprnet-vpn1.aprs.fi 1773&lt;br /&gt;
resolv-retry infinite&lt;br /&gt;
persist-key&lt;br /&gt;
persist-tun&lt;br /&gt;
ca amprnet-vpn-ca.crt&lt;br /&gt;
cert client.crt&lt;br /&gt;
key client.key&lt;br /&gt;
comp-lzo&lt;br /&gt;
verb 3&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Extract your client certificate and key as explained above section Extracting the certificate from LoTW. Copy your certificate files client.crt and client.key to /etc/openvpn/ . You also need amprnet-vpn-ca.crt which can be found inside this archive&lt;br /&gt;
http://he.fi/amprnet-vpn/amprnet-vpn-win.zip . Extract it and copy to /etc/openvpn/&lt;br /&gt;
&lt;br /&gt;
Restart openvpn&lt;br /&gt;
&lt;br /&gt;
 service openvpn restart&lt;br /&gt;
&lt;br /&gt;
All done.&lt;br /&gt;
&lt;br /&gt;
== Mac OS X: Tunnelblick ==&lt;br /&gt;
&lt;br /&gt;
# [https://tunnelblick.net/ Download Tunnelblick], it&#039;s free and open source, and works like a charm. It&#039;s based on OpenVPN.&lt;br /&gt;
# [http://he.fi/amprnet-vpn/amprnet-vpn-tblk.zip Download the VPN configuration for Tunnelblick], it&#039;s a zip file containing a directory with a couple files&lt;br /&gt;
# Double-click the downloaded zip file to extract it, you&#039;ll get a directory named &#039;&#039;&#039;amprnet-vpn.tblk&#039;&#039;&#039;&lt;br /&gt;
# Move the &#039;&#039;&#039;private key&#039;&#039;&#039; (in a file which was named &#039;&#039;&#039;client.key&#039;&#039;&#039; in the previous step) to that directory&lt;br /&gt;
# Move the certificates (in a file which was named &#039;&#039;&#039;client.crt&#039;&#039;&#039; in the previous step) to that directory&lt;br /&gt;
# Double-click the &#039;&#039;&#039;amprnet-vpn.tblk&#039;&#039;&#039; directory - this will launch Tunnelblick and install the VPN configuration&lt;br /&gt;
&lt;br /&gt;
You should now see a &amp;quot;tunnel&amp;quot; icon in the top right corner of the screen. Click it to see a few menu items allowing you to connect and disconnect the VPN.&lt;br /&gt;
&lt;br /&gt;
If you chose to encrypt your private key with a password (or passphrase) when initially applying for a LoTW certificate and generating the Certificate Request, Tunnelblick will ask you for that passphrase when connecting.&lt;br /&gt;
&lt;br /&gt;
To rephrase: When Tunnelblick says &amp;quot;A passphrase is required to connect to amprnet-vpn&amp;quot;, the passphrase being asked is the one you picked when you first applied for a LoTW certificate. It&#039;s not something the VPN operator knows (or should know). Only you have ever been aware of that passphrase (hopefully).&lt;/div&gt;</summary>
		<author><name>Cross</name></author>
	</entry>
	<entry>
		<id>https://wiki.ampr.org/w/index.php?title=Setting_up_a_gateway_on_OpenBSD&amp;diff=1103</id>
		<title>Setting up a gateway on OpenBSD</title>
		<link rel="alternate" type="text/html" href="https://wiki.ampr.org/w/index.php?title=Setting_up_a_gateway_on_OpenBSD&amp;diff=1103"/>
		<updated>2024-04-28T02:19:56Z</updated>

		<summary type="html">&lt;p&gt;Cross: Specify use of the `-cloning` flag when creating routes.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
[https://www.openbsd.org OpenBSD] is a mature Unix-like operating system that focuses on security and correctness. It features a flexible, robust, performant TCP/IP stack and a [https://www.openbsd.org/faq/pf/ highly configurable firewall]. This page describes how to configure a computer running OpenBSD as an AMPRNet router to transfer traffic between AMPRNet subnets and the Internet.&lt;br /&gt;
&lt;br /&gt;
OpenBSD natively supports [https://en.wikipedia.org/wiki/IP_in_IP IPENCAP (IP-IP)] tunnels through [https://man.openbsd.org/gif.4 &#039;&#039;gif&#039;&#039;(4)] pseudo-devices. Each &#039;&#039;gif&#039;&#039; device is a virtual network interface, synthesized by the operating system, that implements a point-to-point tunnel. Unlike Linux, OpenBSD requires a separate &#039;&#039;gif&#039;&#039; interface for each tunnel. An essentially arbitrary number of such interfaces can be created and it scales to the number required to route all of AMPRNet.&lt;br /&gt;
&lt;br /&gt;
One can manually configure &#039;&#039;gif&#039;&#039; tunnels and routes at the command line, or configure the system to establish tunnels and routes at boot time.&lt;br /&gt;
&lt;br /&gt;
We will describe how to set things up by way of example. Assume a system configuration that looks substantially similar to the following:&lt;br /&gt;
&lt;br /&gt;
* A dedicated static IP address to use as an endpoint for AMPRNet traffic.&lt;br /&gt;
* An ISP-provided router that is just a router; no NATing, no firewall.&lt;br /&gt;
* An OpenBSD computer with three ethernet interfaces. For example, using a Ubiquiti EdgeRouter 3 Lite:&lt;br /&gt;
*# cnmac0 is the external interface connected to the ISP&#039;s network (in this example, we use 23.30.150.141 routing to 23.30.150.142)&lt;br /&gt;
*# cnmac1 connects to an internal network (its configuration is irrelevant)&lt;br /&gt;
*# cnmac2 is the internal interface connected to the subnet (in this example, we use 44.44.107.1 routing for 44.44.107.0/24)&lt;br /&gt;
&lt;br /&gt;
Let us start by configuring a single tunnel and route to the AMPRNet gateway at UCSD:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;ifconfig gif1 create&lt;br /&gt;
ifconfig gif1 tunnel 23.30.150.141 169.228.34.84&lt;br /&gt;
ifconfig gif1 inet 44.44.107.1 netmask 255.255.255.255&lt;br /&gt;
route add -host 44.0.0.1 -link -iface gif1 -cloning&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first command creates the interface, causing the kernel to synthesize it into existence. The second configures the tunnel itself: that is, the the IP addresses that will be put into the IPENCAP datagram that the tunnel creates: the first address is the &#039;&#039;local&#039;&#039; address, which will serve as the source address for the IPENCAP packet, while the second is the &#039;&#039;remote&#039;&#039; address, to which the packet will be sent. The third sets an IP address for the local endpoint of the interface: this exists solely so that traffic that is generated by the router, such as ICMP error messages (host or port unreachable, for example), have a valid source address. Note that despite the fact that this is a point-to-point interface, we do not specify the IP address of the remote end.&lt;br /&gt;
&lt;br /&gt;
The fourth and final command creates a host route and associates it with the tunnel interface. The &amp;lt;code&amp;gt;-link&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;-iface&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;-cloning&amp;lt;/code&amp;gt; flags indicate that this is an interface route, that traffic for the route should go directly to the given interface (&amp;lt;code&amp;gt;gif1&amp;lt;/code&amp;gt;) instead of identifying the gateway via an IP address, and that routes should be dynamically cloned when used. We can examine this route from the command line. E.g.,&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;$ route -n show -inet | grep &#039;44\.0\.0\.1 &#039;&lt;br /&gt;
44.0.0.1           link#7             UHCSh      1        2     -     8 gif1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Consult the manual page for [https://man.openbsd.org/netstat.1 &#039;&#039;netstat&#039;&#039;(1)] for details on what the &amp;lt;code&amp;gt;UHCSh&amp;lt;/code&amp;gt; flags mean.&lt;br /&gt;
&lt;br /&gt;
We can repeat this process for each AMPRNet tunnel, creating interfaces and adding routes for each subnet.&lt;br /&gt;
&lt;br /&gt;
== Handling Encapsulated Inbound Traffic Without a Reciprocal Tunnel ==&lt;br /&gt;
&lt;br /&gt;
When an inbound IPENCAP datagram arrives on our external interface, the network stack in the OpenBSD kernel recognizes it by examining the protocol number in the IP header: IPENCAP is protocol number 4 (not to be confused with IP version 4). Any such packets are passed to the packet input function in the &#039;&#039;gif&#039;&#039; implementation, which searches all configured &#039;&#039;gif&#039;&#039; interfaces trying to match the configured tunnel source and destinations addresses with the corresponding addresses in the inbound packet. If such an interface is found, the packet is enqueued to the interface, which will strip the IPENCAP header and route the resulting &amp;quot;de-encapsulated&amp;quot; IP packet. This works for tunnels that are configured bidirectionally between any two sites. That is, if site A has a tunnel to site B, and B has a corresponding tunnel to A, they can send each other traffic.&lt;br /&gt;
&lt;br /&gt;
Now consider the case where site A has a tunnel configured to send traffic to site B, but B has no tunnel configured to A: in this case, the datagram arrives as before and is presented to the &#039;&#039;gif&#039;&#039; implementation, but the search above fails since B has no tunnel to A, so nothing matches the source &#039;&#039;and&#039;&#039; destination addresses on the incoming packet. In this case, the system might be responsible for routing such packets to another computer or network, so the packet is not decapsulated and processed. However, in an AMPRNet context, we very well may want to process that packet. Accordingly, the &#039;&#039;gif&#039;&#039; implementation has a mechanism for describing an interface that accepts encapsulated traffic from any source destined to a local address. If we configure a &#039;&#039;gif&#039;&#039; interface where the distant end of the &#039;&#039;tunnel&#039;&#039; set to &amp;lt;code&amp;gt;0.0.0.0&amp;lt;/code&amp;gt;, then any incoming datagram where the destination address is the same as the local address on the interface will be accepted, decapsulated and processed as before. Using this, we can set up an interface specifically for accepting traffic from systems to which we have not defined a tunnel:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;ifconfig gif0 create&lt;br /&gt;
ifconfig gif0 tunnel 23.30.150.141 0.0.0.0&lt;br /&gt;
ifconfig gif0 inet 44.44.107.1 255.255.255.255&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note the &amp;lt;code&amp;gt;0.0.0.0&amp;lt;/code&amp;gt; as the remote address in the &amp;lt;code&amp;gt;ifconfig tunnel&amp;lt;/code&amp;gt; command. Again, we set an interface address using our local AMPRNet router address purely for locally generated traffic.&lt;br /&gt;
&lt;br /&gt;
One this interface is configured, IPENCAP traffic from remote systems that have defined tunnels to us will flow, regardless of whether we have created a tunnel to them.&lt;br /&gt;
&lt;br /&gt;
== Policy-based Routing Using Routing Domains ==&lt;br /&gt;
&lt;br /&gt;
The configuration explored so far is sufficient to make connections to AMPRNet subnets we have manually configured tunnels for, but suffers from a number of deficiencies. In particular, the following two issues that we will discuss now.&lt;br /&gt;
&lt;br /&gt;
First, there is a problem with exchanging traffic with non-AMPRNet systems on the Internet. Presumably, these systems are not aware of AMPRNet tunneling, so traffic from them goes to the gateway at UCSD, where it will be encapsulated and sent through a tunnel to the external interface on our router. There, it will be decapsulated and delivered into our subnet. However, return traffic will be sent to the local router, but since the destination is generally not a tunnel, it will be sent via the default route, but with an AMPRNet source address. Since most ISPs will not pass AMPRNet traffic, the result will likely be lost before it reaches the destination. We may think it would be possible to work around that using a firewall rule to NAT the source address to something provided by our ISP, but even if the resulting datagram made it to the destination, for a protocol like TCP it would no longer match the 5-tuple for the connection, and would thus be lost.&lt;br /&gt;
&lt;br /&gt;
The second problem is reaching AMPRNet systems for which we have not configured a tunnel.  Without a tunnel, and thus a route, we cannot send traffic to those systems.&lt;br /&gt;
&lt;br /&gt;
We can solve both of these problems by sending all of our traffic through a tunnel interface to the UCSD gateway by default, e.g., by setting the default route:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;route add default 4.0.0.1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However this creates a new problem: how does the encapsulated traffic from the tunnel interface get sent to our ISP&#039;s gateway? We can add a host route for the UCSD gateway in our local routing table, but we have to do this for every tunnel, which is unwieldy. Further, connecting to our external interface becomes complicated: suppose someone &amp;lt;code&amp;gt;ping&amp;lt;/code&amp;gt;s our local router&#039;s external interface. Assuming we permit this, the response would be routed through the UCSD gateway tunnel, but even if the gateway passed arbitrary traffic back onto the Internet, the packet might be lost as upstream ISPs would refuse to route it and even if delivered, it wouldn&#039;t match the destination address of the original ICMP echo request packet anyway.&lt;br /&gt;
&lt;br /&gt;
The solution to all of these problems is to use [https://en.wikipedia.org/wiki/Policy-based_routing &#039;&#039;policy-based routing&#039;&#039;]. Specifically, we would like to make routing decisions based on the source IP address of our traffic. We might be able to do this with firewall rules, but the edge cases get complicated very quickly. Fortunately, there is another way: [https://man.openbsd.org/rdomain.4 routing domains].&lt;br /&gt;
&lt;br /&gt;
Routing domains in OpenBSD are a mechanism to isolate routing decisions from one another. Network interfaces are configured into exactly one routing domain, which has its own private set of routing tables. Those tables are isolated, but traffic can be passed between routing domains via firewall rules.&lt;br /&gt;
&lt;br /&gt;
In our example, we put our external and local AMPRNet gateway interfaces into separate routing domains: all of the &#039;&#039;gif&#039;&#039; interfaces and the local AMPRNet gateway interface can both be assigned to routing domain 44, while the external interface might be 23. Routing domain 0 is the default. Note that the numbers here are arbitrary, and we can choose any value below 256 that we like; these are chosen to match the first octet of our example addresses.&lt;br /&gt;
&lt;br /&gt;
The routing domain on an interface is set using the &amp;lt;code&amp;gt;rdomain&amp;lt;/code&amp;gt; parameter to &amp;lt;code&amp;gt;ifconfig&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;ifconfig cnmac0 rdomain 23&lt;br /&gt;
ifconfig gif0 rdomain 44&lt;br /&gt;
ifconfig gif1 rdomain 44&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We set the default route in the routing domain that owns our external interface to our ISP&#039;s router, while in the routing domain hosting our AMPRNet presence we can set it to the UCSD gateway:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;route -T 23 add default 23.30.150.242&lt;br /&gt;
route -T 44 add default 44.0.0.1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now traffic on our AMPRNet subnet will be routed through the UCSD gateway, while traffic on the external interface will be routed through our ISP&#039;s router.&lt;br /&gt;
&lt;br /&gt;
Another piece of functionality lets us dispense with much of the complexity of routing between domains: the tunnel assigned to a &#039;&#039;gif&#039;&#039; can be in a different routing domain than the interface itself. Going back to our example, if we place each of our &#039;&#039;gif&#039;&#039; interfaces into routing domain 44 then traffic routed out to or coming in from the tunnel will be routed with our AMPRNet-specific routing table. But if we place the tunnel on that interface into routing domain 23, then the encapsulated traffic that we send to and from the Internet (e.g., to other tunnel end points) will be routed in that domain, thus routing through our ISP&#039;s network. Critically, matching incoming datagrams to &#039;&#039;gif&#039;&#039; interfaces as described above happens in the routing domain associated with the tunnel, so inbound traffic coming through our external interface will be directed to the correct interface.&lt;br /&gt;
&lt;br /&gt;
We specify the routing domain of a tunnel via the &amp;lt;code&amp;gt;tunneldomain&amp;lt;/code&amp;gt; parameter to &amp;lt;code&amp;gt;ifconfig&amp;lt;/code&amp;gt; when configuring the route on an interface:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;ifconfig gif0 tunnel 23.30.150.141 0.0.0.0 tunneldomain 23&lt;br /&gt;
ifconfig gif1 tunnel 23.30.150.141 169.228.34.84 tunneldomain 23&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With this in place, routing works as expected for all of the cases mentioned above.&lt;br /&gt;
&lt;br /&gt;
== Persistent Configuration Across Router Restarts ==&lt;br /&gt;
&lt;br /&gt;
We now have enough information that we can set up tunnels between our router and arbitrary AMPRNet subnets. However, doing so manually is tedious and not particularly robust. We would like the system to automatically configure our tunnels and default routes at boot time. Fortunately, the OpenBSD startup code can do this easily. For each network interface &amp;lt;code&amp;gt;$if&amp;lt;/code&amp;gt; on the system, we can configure it automatically at boot time by putting configuration commands into the file &amp;lt;code&amp;gt;/etc/hostname.$if&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
There are four interfaces we have configured: the two ethernet interfaces for our external and AMPRNet networks, and the two &#039;&#039;gif&#039;&#039; interfaces with the default incoming tunnel and the tunnel to the UCSD gateway.  Thus, there are four files:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/etc/hostname.cnmac0&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;rdomain 23&lt;br /&gt;
inet 23.30.150.141 0xfffffff8&lt;br /&gt;
!ifconfig lo23 inet 127.0.0.1&lt;br /&gt;
!route -qn -T 23 add default 23.30.150.142&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/etc/hostname.cnmac2&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;rdomain 44&lt;br /&gt;
inet 44.44.107.1 255.255.255.0&lt;br /&gt;
!ifconfig lo44 inet 127.0.0.1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/etc/hostname.gif0&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;rdomain 44&lt;br /&gt;
tunnel 23.30.150.141 0.0.0.0 tunneldomain 23&lt;br /&gt;
inet 44.44.107.1 255.255.255.255&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/etc/hostname.gif1&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;tunnel 23.30.150.141 169.228.34.84 tunneldomain 23&lt;br /&gt;
inet 44.44.107.1 255.255.255.255&lt;br /&gt;
!route -qn -T 44 add 44.0.0.1/32 -link -iface gif1 -cloning&lt;br /&gt;
!route -qn -T 44 add default 44.0.0.1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that each routing domain also has its own associated loopback interface, hence configuring &amp;lt;code&amp;gt;lo23&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;lo44&amp;lt;/code&amp;gt;. These interfaces are automatically created when the routing domain is created, but we configure them when we bring up the associated ethernet interfaces.&lt;br /&gt;
&lt;br /&gt;
We can examine the interfaces and separate routing tables to ensure that things are set up as expected:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;$ ifconfig cnmac0&lt;br /&gt;
cnmac0: flags=8843&amp;lt;UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST&amp;gt; rdomain 23 mtu 1500&lt;br /&gt;
        lladdr 44:d9:e7:9f:a7:64&lt;br /&gt;
        index 1 priority 0 llprio 3&lt;br /&gt;
        media: Ethernet autoselect (1000baseT full-duplex)&lt;br /&gt;
        status: active&lt;br /&gt;
        inet 23.30.150.141 netmask 0xfffffff8 broadcast 23.30.150.143&lt;br /&gt;
$ ifconfig cnmac2&lt;br /&gt;
cnmac2: flags=8843&amp;lt;UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST&amp;gt; rdomain 44 mtu 1500&lt;br /&gt;
        lladdr 44:d9:e7:9f:a7:66&lt;br /&gt;
        index 3 priority 0 llprio 3&lt;br /&gt;
        media: Ethernet autoselect (1000baseT full-duplex,master)&lt;br /&gt;
        status: active&lt;br /&gt;
        inet 44.44.107.1 netmask 0xffffff00 broadcast 44.44.107.255&lt;br /&gt;
$ ifconfig gif0&lt;br /&gt;
gif0: flags=8051&amp;lt;UP,POINTOPOINT,RUNNING,MULTICAST&amp;gt; rdomain 44 mtu 1280&lt;br /&gt;
        index 6 priority 0 llprio 3&lt;br /&gt;
        encap: txprio payload rxprio payload&lt;br /&gt;
        groups: gif&lt;br /&gt;
        tunnel: inet 23.30.150.141 -&amp;gt; 0.0.0.0 ttl 64 nodf ecn rdomain 23&lt;br /&gt;
        inet 44.44.107.1 --&amp;gt; 0.0.0.0 netmask 0xffffffff&lt;br /&gt;
$ ifconfig gif1&lt;br /&gt;
gif1: flags=8051&amp;lt;UP,POINTOPOINT,RUNNING,MULTICAST&amp;gt; rdomain 44 mtu 1280&lt;br /&gt;
        index 7 priority 0 llprio 3&lt;br /&gt;
        encap: txprio payload rxprio payload&lt;br /&gt;
        groups: gif&lt;br /&gt;
        tunnel: inet 23.30.150.141 -&amp;gt; 169.228.34.84 ttl 64 nodf ecn rdomain 23&lt;br /&gt;
        inet 44.44.107.1 --&amp;gt; 0.0.0.0 netmask 0xffffffff&lt;br /&gt;
$ route -T 23 -n show -inet&lt;br /&gt;
Routing tables&lt;br /&gt;
&lt;br /&gt;
Internet:&lt;br /&gt;
Destination        Gateway            Flags   Refs      Use   Mtu  Prio Iface&lt;br /&gt;
default            23.30.150.142      UGS        0    51126     -     8 cnmac0&lt;br /&gt;
23.30.150.136/29   23.30.150.141      UCn        1        7     -     4 cnmac0&lt;br /&gt;
23.30.150.141      44:d9:e7:9f:a7:64  UHLl       0    88377     -     1 cnmac0&lt;br /&gt;
23.30.150.142      4a:1d:70:de:c3:5a  UHLch      1      386     -     3 cnmac0&lt;br /&gt;
23.30.150.143      23.30.150.141      UHb        0        0     -     1 cnmac0&lt;br /&gt;
127.0.0.1          127.0.0.1          UHl        0        0 32768     1 lo23&lt;br /&gt;
$ route -T 44 -n show -inet&lt;br /&gt;
Routing tables&lt;br /&gt;
&lt;br /&gt;
Internet:&lt;br /&gt;
Destination        Gateway            Flags   Refs      Use   Mtu  Prio Iface&lt;br /&gt;
default            44.0.0.1           UGS        0    54718     -     8 gif1&lt;br /&gt;
44.0.0.1           link#7             UHCSh      1        2     -     8 gif1&lt;br /&gt;
44.44.107/24       44.44.107.1        UCn       16        4     -     4 cnmac2&lt;br /&gt;
44.44.107.1        44:d9:e7:9f:a7:66  UHLl       0     4825     -     1 cnmac2&lt;br /&gt;
44.44.107.255      44.44.107.1        UHb        0        0     -     1 cnmac2&lt;br /&gt;
127.0.0.1          127.0.0.1          UHl        0        0 32768     1 lo44&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Restricting Traffic with the [https://www.openbsd.org/faq/pf/ PF] Firewall ==&lt;br /&gt;
&lt;br /&gt;
All of these interfaces will fully integrate with the PF firewall software that comes with OpenBSD, and we can implement nearly arbitrary policies in our configuration.  For example, we might restrict traffic on the external interface to only ICMP messages and IPENCAP datagrams by setting the following rules in &amp;lt;code&amp;gt;/etc/pf.conf&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;# Constants&lt;br /&gt;
extif = &amp;quot;cnmac0&amp;quot;&lt;br /&gt;
extamprgate = &amp;quot;23.30.150.141&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Options&lt;br /&gt;
set skip on lo&lt;br /&gt;
set block-policy return&lt;br /&gt;
&lt;br /&gt;
block return    # block stateless traffic&lt;br /&gt;
pass            # establish keep-state&lt;br /&gt;
&lt;br /&gt;
# Normalize incoming packets.&lt;br /&gt;
match in all scrub (no-df random-id max-mss 1440)&lt;br /&gt;
&lt;br /&gt;
# By default, block everything.  We selectively override in subsequent rules.&lt;br /&gt;
block in on $extif&lt;br /&gt;
&lt;br /&gt;
# Pass 44net traffic&lt;br /&gt;
pass in on $extif inet proto ipencap from any to $extamprgate&lt;br /&gt;
&lt;br /&gt;
# Pass ping and ICMP unreachable messages on external interface&lt;br /&gt;
pass in on $extif inet proto icmp icmp-type echoreq code 0 keep state&lt;br /&gt;
pass in on $extif inet proto icmp icmp-type unreach keep state&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We can verify that these rules are in place as expected by querying the rule tables:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;# pfctl -sr -vv&lt;br /&gt;
@0 block return all&lt;br /&gt;
  [ Evaluations: 115977    Packets: 3776      Bytes: 168422      States: 0     ]&lt;br /&gt;
  [ Inserted: uid 0 pid 31812 State Creations: 0     ]&lt;br /&gt;
@1 pass all flags S/SA&lt;br /&gt;
  [ Evaluations: 115977    Packets: 242418    Bytes: 25899015    States: 253   ]&lt;br /&gt;
  [ Inserted: uid 0 pid 31812 State Creations: 102105]&lt;br /&gt;
@2 match in all scrub (no-df random-id max-mss 1440)&lt;br /&gt;
  [ Evaluations: 115977    Packets: 261105    Bytes: 31394491    States: 136   ]&lt;br /&gt;
  [ Inserted: uid 0 pid 31812 State Creations: 0     ]&lt;br /&gt;
@3 block return in on cnmac0 all&lt;br /&gt;
  [ Evaluations: 64726     Packets: 5925      Bytes: 325492      States: 0     ]&lt;br /&gt;
  [ Inserted: uid 0 pid 31812 State Creations: 0     ]&lt;br /&gt;
@4 pass in on cnmac0 inet proto icmp all icmp-type echoreq code 0&lt;br /&gt;
  [ Evaluations: 8149      Packets: 342       Bytes: 27424       States: 0     ]&lt;br /&gt;
  [ Inserted: uid 0 pid 31812 State Creations: 171   ]&lt;br /&gt;
@5 pass in on cnmac0 inet proto icmp all icmp-type unreach&lt;br /&gt;
  [ Evaluations: 308       Packets: 5         Bytes: 368         States: 0     ]&lt;br /&gt;
  [ Inserted: uid 0 pid 31812 State Creations: 0     ]&lt;br /&gt;
@6 pass in on cnmac0 inet proto ipencap from any to 23.30.150.141&lt;br /&gt;
  [ Evaluations: 8149      Packets: 126197    Bytes: 16538717    States: 5     ]&lt;br /&gt;
  [ Inserted: uid 0 pid 31812 State Creations: 2048  ]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A site can add more elaborate rules as desired.&lt;br /&gt;
&lt;br /&gt;
== Maintaining Mesh Routes with 44ripd ==&lt;br /&gt;
&lt;br /&gt;
The above shows how to set up AMPRNet tunnel interfaces, set routes to them, use routing domains for policy-based routing, and set firewall rules. However, so far all of these steps have been manual. This works for a handful of tunnels and routes, but there are hundreds of subnets AMPRNet in the AMPRNet mesh; maintaining all of these manually is not reasonable.&lt;br /&gt;
&lt;br /&gt;
However, Dan Cross (KZ2X) has written a daemon specific to OpenBSD called &amp;lt;code&amp;gt;44ripd&amp;lt;/code&amp;gt; that maintains tunnel and route information as distributed via the [https://wiki.ampr.org/wiki/RIP AMPRNet RIP] variant sent from &amp;lt;code&amp;gt;44.0.0.1&amp;lt;/code&amp;gt;. To use this, make sure that multicasting is enabled on the host by setting &amp;lt;code&amp;gt;multicast=YES&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;/etc/rc.conf.local&amp;lt;/code&amp;gt;, and then retrieve the 44ripd software from Github at https://github.com/dancrossnyc/44ripd. The software is built with the &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt; command. For example:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;git clone https://github.com/dancrossnyc/44ripd&lt;br /&gt;
cd 44ripd&lt;br /&gt;
make&lt;br /&gt;
doas install -c -o root -g wheel -m 555 44ripd /usr/local/sbin&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once installed, this can be run at boot by adding the following lines to &amp;lt;code&amp;gt;/etc/rc.local&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;if [ -x /usr/local/sbin/44ripd ]; then&lt;br /&gt;
        echo -n &#039; 44ripd&#039;&lt;br /&gt;
        route -T 44 exec /usr/local/sbin/44ripd -s0 -s1 -D 44 -T 23&lt;br /&gt;
fi&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that the &amp;lt;code&amp;gt;-s&amp;lt;/code&amp;gt; options instruct the daemon not to try and allocate the &amp;lt;code&amp;gt;gif0&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;gif1&amp;lt;/code&amp;gt; interfaces, as these are manually configured. The &amp;lt;code&amp;gt;-D&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;-T&amp;lt;/code&amp;gt; options set the routing domains for &#039;&#039;gif&#039;&#039; interfaces and their associated tunnels, respectively.&lt;br /&gt;
&lt;br /&gt;
=== Set the Default AMPRNet Tunnel and Route Manually ===&lt;br /&gt;
&lt;br /&gt;
While route information for the UCSD AMPRNet gateway is distributed in RIP44 packets and we could in theory only configure the default incoming tunnel and rely on 44ripd to set up a route to UCSD, this leads to a problem. Specifically, without an interface configured to the UCSD gateway, we cannot set a default route in our AMRPNet routing domain for the gateway. Since we rely on periodic route broadcasts from UCSD to set those routes, we would delay setting up our default route for an indeterminate amount of time (on the order of minutes).&lt;br /&gt;
&lt;br /&gt;
Thus, it is advised to explicitly configure the tunnel to UCSD at boot time along with the default route.&lt;br /&gt;
&lt;br /&gt;
=== Notes on 44ripd Implementation ===&lt;br /&gt;
&lt;br /&gt;
* 44ripd maintains a copy of the AMPRNet routing table in a modified PATRICIA trie (really a compressed radix tree).&lt;br /&gt;
* A similar table of tunnels is maintained.&lt;br /&gt;
* Tunnel interfaces are reference counted and garbage collected. A bitmap indicating which tunnels are in use is maintained.&lt;br /&gt;
* Routes are expired after receiving a RIP packet.&lt;br /&gt;
* The program is completely self-contained in the sense that it does not fork/exec external commands to configure tunnels or manipulate routes.  That is all done via ioctls or writing messages to a routing socket.&lt;br /&gt;
* 44ripd does not examine the state of the system or routing tables at startup to bootstrap its internal state, but arguably should.&lt;br /&gt;
* Bugs in 44ripd should be reported via Github issues.&lt;br /&gt;
* Exporting and/or parsing an encap file would be nice.&lt;br /&gt;
* Logging and error checking can always be improved.&lt;/div&gt;</summary>
		<author><name>Cross</name></author>
	</entry>
	<entry>
		<id>https://wiki.ampr.org/w/index.php?title=User:Cross&amp;diff=930</id>
		<title>User:Cross</title>
		<link rel="alternate" type="text/html" href="https://wiki.ampr.org/w/index.php?title=User:Cross&amp;diff=930"/>
		<updated>2021-11-10T01:33:14Z</updated>

		<summary type="html">&lt;p&gt;Cross: Correct callsign.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;My name is Dan Cross. I am an engineer at Oxide Computer Company. My call  sign is KZ2X and you can find out more about me on my personal web page: http://pub.gajendra.net/&lt;/div&gt;</summary>
		<author><name>Cross</name></author>
	</entry>
	<entry>
		<id>https://wiki.ampr.org/w/index.php?title=Setting_up_a_gateway_on_OpenBSD&amp;diff=926</id>
		<title>Setting up a gateway on OpenBSD</title>
		<link rel="alternate" type="text/html" href="https://wiki.ampr.org/w/index.php?title=Setting_up_a_gateway_on_OpenBSD&amp;diff=926"/>
		<updated>2021-06-30T02:17:14Z</updated>

		<summary type="html">&lt;p&gt;Cross: Minor grammar tweaks&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
[https://www.openbsd.org OpenBSD] is a mature Unix-like operating system that focuses on security and correctness. It features a flexible, robust, performant TCP/IP stack and a [https://www.openbsd.org/faq/pf/ highly configurable firewall]. This page describes how to configure a computer running OpenBSD as an AMPRNet router to transfer traffic between AMPRNet subnets and the Internet.&lt;br /&gt;
&lt;br /&gt;
OpenBSD natively supports [https://en.wikipedia.org/wiki/IP_in_IP IPENCAP (IP-IP)] tunnels through [https://man.openbsd.org/gif.4 &#039;&#039;gif&#039;&#039;(4)] pseudo-devices. Each &#039;&#039;gif&#039;&#039; device is a virtual network interface, synthesized by the operating system, that implements a point-to-point tunnel. Unlike Linux, OpenBSD requires a separate &#039;&#039;gif&#039;&#039; interface for each tunnel. An essentially arbitrary number of such interfaces can be created and it scales to the number required to route all of AMPRNet.&lt;br /&gt;
&lt;br /&gt;
One can manually configure &#039;&#039;gif&#039;&#039; tunnels and routes at the command line, or configure the system to establish tunnels and routes at boot time.&lt;br /&gt;
&lt;br /&gt;
We will describe how to set things up by way of example. Assume a system configuration that looks substantially similar to the following:&lt;br /&gt;
&lt;br /&gt;
* A dedicated static IP address to use as an endpoint for AMPRNet traffic.&lt;br /&gt;
* An ISP-provided router that is just a router; no NATing, no firewall.&lt;br /&gt;
* An OpenBSD computer with three ethernet interfaces. For example, using a Ubiquiti EdgeRouter 3 Lite:&lt;br /&gt;
*# cnmac0 is the external interface connected to the ISP&#039;s network (in this example, we use 23.30.150.141 routing to 23.30.150.142)&lt;br /&gt;
*# cnmac1 connects to an internal network (its configuration is irrelevant)&lt;br /&gt;
*# cnmac2 is the internal interface connected to the subnet (in this example, we use 44.44.107.1 routing for 44.44.107.0/24)&lt;br /&gt;
&lt;br /&gt;
Let us start by configuring a single tunnel and route to the AMPRNet gateway at UCSD:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;ifconfig gif1 create&lt;br /&gt;
ifconfig gif1 tunnel 23.30.150.141 169.228.34.84&lt;br /&gt;
ifconfig gif1 inet 44.44.107.1 netmask 255.255.255.255&lt;br /&gt;
route add -host 44.0.0.1 -link -iface gif1 -llinfo&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first command creates the interface, causing the kernel to synthesize it into existence. The second configures the tunnel itself: that is, the the IP addresses that will be put into the IPENCAP datagram that the tunnel creates: the first address is the &#039;&#039;local&#039;&#039; address, which will serve as the source address for the IPENCAP packet, while the second is the &#039;&#039;remote&#039;&#039; address, to which the packet will be sent. The third sets an IP address for the local endpoint of the interface: this exists solely so that traffic that is generated by the router, such as ICMP error messages (host or port unreachable, for example), have a valid source address. Note that despite the fact that this is a point-to-point interface, we do not specify the IP address of the remote end.&lt;br /&gt;
&lt;br /&gt;
The fourth and final command creates a host route and associates it with the tunnel interface. The &amp;lt;code&amp;gt;-link&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;-iface&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;-llinfo&amp;lt;/code&amp;gt; flags indicate that this is an interface route, and that traffic for the route should go directly to the given interface (&amp;lt;code&amp;gt;gif1&amp;lt;/code&amp;gt;) instead of identifying the gateway via an IP address. We can examine this route from the commandline. E.g.,&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;$ route -n show -inet | grep &#039;44\.0\.0\.1 &#039;&lt;br /&gt;
44.0.0.1           link#7             UHLSh      1        2     -     8 gif1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Consult the manual page for [https://man.openbsd.org/netstat.1 &#039;&#039;netstat&#039;&#039;(1)] for details on what the &amp;lt;code&amp;gt;UHLSh&amp;lt;/code&amp;gt; flags mean.&lt;br /&gt;
&lt;br /&gt;
We can repeat this process for each AMPRNet tunnel, creating interfaces and adding routes for each subnet.&lt;br /&gt;
&lt;br /&gt;
== Handling Encapsulated Inbound Traffic Without a Reciprocal Tunnel ==&lt;br /&gt;
&lt;br /&gt;
When an inbound IPENCAP datagram arrives on our external interface, the network stack in the OpenBSD kernel recognizes it by examining the protocol number in the IP header: IPENCAP is protocol number 4 (not to be confused with IP version 4). Any such packets are passed to the packet input function in the &#039;&#039;gif&#039;&#039; implementation, which searches all configured &#039;&#039;gif&#039;&#039; interfaces trying to match the configured tunnel source and destinations addresses with the corresponding addresses in the inbound packet. If such an interface is found, the packet is enqueued to the interface, which will strip the IPENCAP header and route the resulting &amp;quot;de-encapsulated&amp;quot; IP packet. This works for tunnels that are configured bidirectionally between any two sites. That is, if site A has a tunnel to site B, and B has a corresponding tunnel to A, they can send each other traffic.&lt;br /&gt;
&lt;br /&gt;
Now consider the case where site A has a tunnel configured to send traffic to site B, but B has no tunnel configured to A: in this case, the datagram arrives as before and is presented to the &#039;&#039;gif&#039;&#039; implementation, but the search above fails since B has no tunnel to A, so nothing matches the source &#039;&#039;and&#039;&#039; destination addresses on the incoming packet. In this case, the system might be responsible for routing such packets to another computer or network, so the packet is not decapsulated and processed. However, in an AMPRNet context, we very well may want to process that packet. Accordingly, the &#039;&#039;gif&#039;&#039; implementation has a mechanism for describing an interface that accepts encapsulated traffic from any source destined to a local address. If we configure a &#039;&#039;gif&#039;&#039; interface where the distant end of the &#039;&#039;tunnel&#039;&#039; set to &amp;lt;code&amp;gt;0.0.0.0&amp;lt;/code&amp;gt;, then any incoming datagram where the destination address is the same as the local address on the interface will be accepted, decapsulated and processed as before. Using this, we can set up an interface specifically for accepting traffic from systems to which we have not defined a tunnel:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;ifconfig gif0 create&lt;br /&gt;
ifconfig gif0 tunnel 23.30.150.141 0.0.0.0&lt;br /&gt;
ifconfig gif0 inet 44.44.107.1 255.255.255.255&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note the &amp;lt;code&amp;gt;0.0.0.0&amp;lt;/code&amp;gt; as the remote address in the &amp;lt;code&amp;gt;ifconfig tunnel&amp;lt;/code&amp;gt; command. Again, we set an interface address using our local AMPRNet router address purely for locally generated traffic.&lt;br /&gt;
&lt;br /&gt;
One this interface is configured, IPENCAP traffic from remote systems that have defined tunnels to us will flow, regardless of whether we have created a tunnel to them.&lt;br /&gt;
&lt;br /&gt;
== Policy-based Routing Using Routing Domains ==&lt;br /&gt;
&lt;br /&gt;
The configuration explored so far is sufficient to make connections to AMPRNet subnets we have manually configured tunnels for, but suffers from a number of deficiencies. In particular, the following two issues that we will discuss now.&lt;br /&gt;
&lt;br /&gt;
First, there is a problem with exchanging traffic with non-AMPRNet systems on the Internet. Presumably, these systems are not aware of AMPRNet tunneling, so traffic from them goes to the gateway at UCSD, where it will be encapsulated and sent through a tunnel to the external interface on our router. There, it will be decapsulated and delivered into our subnet. However, return traffic will be sent to the local router, but since the destination is generally not a tunnel, it will be sent via the default route, but with an AMPRNet source address. Since most ISPs will not pass AMPRNet traffic, the result will likely be lost before it reaches the destination. We may think it would be possible to work around that using a firewall rule to NAT the source address to something provided by our ISP, but even if the resulting datagram made it to the destination, for a protocol like TCP it would no longer match the 5-tuple for the connection, and would thus be lost.&lt;br /&gt;
&lt;br /&gt;
The second problem is reaching AMPRNet systems for which we have not configured a tunnel.  Without a tunnel, and thus a route, we cannot send traffic to those systems.&lt;br /&gt;
&lt;br /&gt;
We can solve both of these problems by sending all of our traffic through a tunnel interface to the UCSD gateway by default, e.g., by setting the default route:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;route add default 4.0.0.1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However this creates a new problem: how does the encapsulated traffic from the tunnel interface get sent to our ISP&#039;s gateway? We can add a host route for the UCSD gateway in our local routing table, but we have to do this for every tunnel, which is unwieldy. Further, connecting to our external interface becomes complicated: suppose someone &amp;lt;code&amp;gt;ping&amp;lt;/code&amp;gt;s our local router&#039;s external interface. Assuming we permit this, the response would be routed through the UCSD gateway tunnel, but even if the gateway passed arbitrary traffic back onto the Internet, the packet might be lost as upstream ISPs would refuse to route it and even if delivered, it wouldn&#039;t match the destination address of the original ICMP echo request packet anyway.&lt;br /&gt;
&lt;br /&gt;
The solution to all of these problems is to use [https://en.wikipedia.org/wiki/Policy-based_routing &#039;&#039;policy-based routing&#039;&#039;]. Specifically, we would like to make routing decisions based on the source IP address of our traffic. We might be able to do this with firewall rules, but the edge cases get complicated very quickly. Fortunately, there is another way: [https://man.openbsd.org/rdomain.4 routing domains].&lt;br /&gt;
&lt;br /&gt;
Routing domains in OpenBSD are a mechanism to isolate routing decisions from one another. Network interfaces are configured into exactly one routing domain, which has its own private set of routing tables. Those tables are isolated, but traffic can be passed between routing domains via firewall rules.&lt;br /&gt;
&lt;br /&gt;
In our example, we put our external and local AMPRNet gateway interfaces into separate routing domains: all of the &#039;&#039;gif&#039;&#039; interfaces and the local AMPRNet gateway interface can both be assigned to routing domain 44, while the external interface might be 23. Routing domain 0 is the default. Note that the numbers here are arbitrary, and we can choose any value below 256 that we like; these are chosen to match the first octet of our example addresses.&lt;br /&gt;
&lt;br /&gt;
The routing domain on an interface is set using the &amp;lt;code&amp;gt;rdomain&amp;lt;/code&amp;gt; parameter to &amp;lt;code&amp;gt;ifconfig&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;ifconfig cnmac0 rdomain 23&lt;br /&gt;
ifconfig gif0 rdomain 44&lt;br /&gt;
ifconfig gif1 rdomain 44&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We set the default route in the routing domain that owns our external interface to our ISP&#039;s router, while in the routing domain hosting our AMPRNet presence we can set it to the UCSD gateway:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;route -T 23 add default 23.30.150.242&lt;br /&gt;
route -T 44 add default 44.0.0.1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now traffic on our AMPRNet subnet will be routed through the UCSD gateway, while traffic on the external interface will be routed through our ISP&#039;s router.&lt;br /&gt;
&lt;br /&gt;
Another piece of functionality lets us dispense with much of the complexity of routing between domains: the tunnel assigned to a &#039;&#039;gif&#039;&#039; can be in a different routing domain than the interface itself. Going back to our example, if we place each of our &#039;&#039;gif&#039;&#039; interfaces into routing domain 44 then traffic routed out to or coming in from the tunnel will be routed with our AMPRNet-specific routing table. But if we place the tunnel on that interface into routing domain 23, then the encapsulated traffic that we send to and from the Internet (e.g., to other tunnel end points) will be routed in that domain, thus routing through our ISP&#039;s network. Critically, matching incoming datagrams to &#039;&#039;gif&#039;&#039; interfaces as described above happens in the routing domain associated with the tunnel, so inbound traffic coming through our external interface will be directed to the correct interface.&lt;br /&gt;
&lt;br /&gt;
We specify the routing domain of a tunnel via the &amp;lt;code&amp;gt;tunneldomain&amp;lt;/code&amp;gt; parameter to &amp;lt;code&amp;gt;ifconfig&amp;lt;/code&amp;gt; when configuring the route on an interface:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;ifconfig gif0 tunnel 23.30.150.141 0.0.0.0 tunneldomain 23&lt;br /&gt;
ifconfig gif1 tunnel 23.30.150.141 169.228.34.84 tunneldomain 23&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With this in place, routing works as expected for all of the cases mentioned above.&lt;br /&gt;
&lt;br /&gt;
== Persistent Configuration Across Router Restarts ==&lt;br /&gt;
&lt;br /&gt;
We now have enough information that we can set up tunnels between our router and arbitrary AMPRNet subnets. However, doing so manually is tedious and not particularly robust. We would like the system to automatically configure our tunnels and default routes at boot time. Fortunately, the OpenBSD startup code can do this easily. For each network interface &amp;lt;code&amp;gt;$if&amp;lt;/code&amp;gt; on the system, we can configure it automatically at boot time by putting configuration commands into the file &amp;lt;code&amp;gt;/etc/hostname.$if&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
There are four interfaces we have configured: the two ethernet interfaces for our external and AMPRNet networks, and the two &#039;&#039;gif&#039;&#039; interfaces with the default incoming tunnel and the tunnel to the UCSD gateway.  Thus, there are four files:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/etc/hostname.cnmac0&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;rdomain 23&lt;br /&gt;
inet 23.30.150.141 0xfffffff8&lt;br /&gt;
!ifconfig lo23 inet 127.0.0.1&lt;br /&gt;
!route -qn -T 23 add default 23.30.150.142&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/etc/hostname.cnmac2&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;rdomain 44&lt;br /&gt;
inet 44.44.107.1 255.255.255.0&lt;br /&gt;
!ifconfig lo44 inet 127.0.0.1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/etc/hostname.gif0&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;rdomain 44&lt;br /&gt;
tunnel 23.30.150.141 0.0.0.0 tunneldomain 23&lt;br /&gt;
inet 44.44.107.1 255.255.255.255&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/etc/hostname.gif1&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;tunnel 23.30.150.141 169.228.34.84 tunneldomain 23&lt;br /&gt;
inet 44.44.107.1 255.255.255.255&lt;br /&gt;
!route -qn -T 44 add 44.0.0.1/32 -link -iface gif1 -llinfo&lt;br /&gt;
!route -qn -T 44 add default 44.0.0.1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that each routing domain also has its own associated loopback interface, hence configuring &amp;lt;code&amp;gt;lo23&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;lo44&amp;lt;/code&amp;gt;. These interfaces are automatically created when the routing domain is created, but we configure them when we bring up the associated ethernet interfaces.&lt;br /&gt;
&lt;br /&gt;
We can examine the interfaces and separate routing tables to ensure that things are set up as expected:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;$ ifconfig cnmac0&lt;br /&gt;
cnmac0: flags=8843&amp;lt;UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST&amp;gt; rdomain 23 mtu 1500&lt;br /&gt;
        lladdr 44:d9:e7:9f:a7:64&lt;br /&gt;
        index 1 priority 0 llprio 3&lt;br /&gt;
        media: Ethernet autoselect (1000baseT full-duplex)&lt;br /&gt;
        status: active&lt;br /&gt;
        inet 23.30.150.141 netmask 0xfffffff8 broadcast 23.30.150.143&lt;br /&gt;
$ ifconfig cnmac2&lt;br /&gt;
cnmac2: flags=8843&amp;lt;UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST&amp;gt; rdomain 44 mtu 1500&lt;br /&gt;
        lladdr 44:d9:e7:9f:a7:66&lt;br /&gt;
        index 3 priority 0 llprio 3&lt;br /&gt;
        media: Ethernet autoselect (1000baseT full-duplex,master)&lt;br /&gt;
        status: active&lt;br /&gt;
        inet 44.44.107.1 netmask 0xffffff00 broadcast 44.44.107.255&lt;br /&gt;
$ ifconfig gif0&lt;br /&gt;
gif0: flags=8051&amp;lt;UP,POINTOPOINT,RUNNING,MULTICAST&amp;gt; rdomain 44 mtu 1280&lt;br /&gt;
        index 6 priority 0 llprio 3&lt;br /&gt;
        encap: txprio payload rxprio payload&lt;br /&gt;
        groups: gif&lt;br /&gt;
        tunnel: inet 23.30.150.141 -&amp;gt; 0.0.0.0 ttl 64 nodf ecn rdomain 23&lt;br /&gt;
        inet 44.44.107.1 --&amp;gt; 0.0.0.0 netmask 0xffffffff&lt;br /&gt;
$ ifconfig gif1&lt;br /&gt;
gif1: flags=8051&amp;lt;UP,POINTOPOINT,RUNNING,MULTICAST&amp;gt; rdomain 44 mtu 1280&lt;br /&gt;
        index 7 priority 0 llprio 3&lt;br /&gt;
        encap: txprio payload rxprio payload&lt;br /&gt;
        groups: gif&lt;br /&gt;
        tunnel: inet 23.30.150.141 -&amp;gt; 169.228.34.84 ttl 64 nodf ecn rdomain 23&lt;br /&gt;
        inet 44.44.107.1 --&amp;gt; 0.0.0.0 netmask 0xffffffff&lt;br /&gt;
$ route -T 23 -n show -inet&lt;br /&gt;
Routing tables&lt;br /&gt;
&lt;br /&gt;
Internet:&lt;br /&gt;
Destination        Gateway            Flags   Refs      Use   Mtu  Prio Iface&lt;br /&gt;
default            23.30.150.142      UGS        0    51126     -     8 cnmac0&lt;br /&gt;
23.30.150.136/29   23.30.150.141      UCn        1        7     -     4 cnmac0&lt;br /&gt;
23.30.150.141      44:d9:e7:9f:a7:64  UHLl       0    88377     -     1 cnmac0&lt;br /&gt;
23.30.150.142      4a:1d:70:de:c3:5a  UHLch      1      386     -     3 cnmac0&lt;br /&gt;
23.30.150.143      23.30.150.141      UHb        0        0     -     1 cnmac0&lt;br /&gt;
127.0.0.1          127.0.0.1          UHl        0        0 32768     1 lo23&lt;br /&gt;
$ route -T 44 -n show -inet&lt;br /&gt;
Routing tables&lt;br /&gt;
&lt;br /&gt;
Internet:&lt;br /&gt;
Destination        Gateway            Flags   Refs      Use   Mtu  Prio Iface&lt;br /&gt;
default            44.0.0.1           UGS        0    54718     -     8 gif1&lt;br /&gt;
44.0.0.1           link#7             UHLSh      1        2     -     8 gif1&lt;br /&gt;
44.44.107/24       44.44.107.1        UCn       16        4     -     4 cnmac2&lt;br /&gt;
44.44.107.1        44:d9:e7:9f:a7:66  UHLl       0     4825     -     1 cnmac2&lt;br /&gt;
44.44.107.255      44.44.107.1        UHb        0        0     -     1 cnmac2&lt;br /&gt;
127.0.0.1          127.0.0.1          UHl        0        0 32768     1 lo44&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Restricting Traffic with the [https://www.openbsd.org/faq/pf/ PF] Firewall ==&lt;br /&gt;
&lt;br /&gt;
All of these interfaces will fully integrate with the PF firewall software that comes with OpenBSD, and we can implement nearly arbitrary policies in our configuration.  For example, we might restrict traffic on the external interface to only ICMP messages and IPENCAP datagrams by setting the following rules in &amp;lt;code&amp;gt;/etc/pf.conf&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;# Constants&lt;br /&gt;
extif = &amp;quot;cnmac0&amp;quot;&lt;br /&gt;
extamprgate = &amp;quot;23.30.150.141&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Options&lt;br /&gt;
set skip on lo&lt;br /&gt;
set block-policy return&lt;br /&gt;
&lt;br /&gt;
block return    # block stateless traffic&lt;br /&gt;
pass            # establish keep-state&lt;br /&gt;
&lt;br /&gt;
# Normalize incoming packets.&lt;br /&gt;
match in all scrub (no-df random-id max-mss 1440)&lt;br /&gt;
&lt;br /&gt;
# By default, block everything.  We selectively override in subsequent rules.&lt;br /&gt;
block in on $extif&lt;br /&gt;
&lt;br /&gt;
# Pass 44net traffic&lt;br /&gt;
pass in on $extif inet proto ipencap from any to $extamprgate&lt;br /&gt;
&lt;br /&gt;
# Pass ping and ICMP unreachable messages on external interface&lt;br /&gt;
pass in on $extif inet proto icmp icmp-type echoreq code 0 keep state&lt;br /&gt;
pass in on $extif inet proto icmp icmp-type unreach keep state&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We can verify that these rules are in place as expected by querying the rule tables:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;# pfctl -sr -vv&lt;br /&gt;
@0 block return all&lt;br /&gt;
  [ Evaluations: 115977    Packets: 3776      Bytes: 168422      States: 0     ]&lt;br /&gt;
  [ Inserted: uid 0 pid 31812 State Creations: 0     ]&lt;br /&gt;
@1 pass all flags S/SA&lt;br /&gt;
  [ Evaluations: 115977    Packets: 242418    Bytes: 25899015    States: 253   ]&lt;br /&gt;
  [ Inserted: uid 0 pid 31812 State Creations: 102105]&lt;br /&gt;
@2 match in all scrub (no-df random-id max-mss 1440)&lt;br /&gt;
  [ Evaluations: 115977    Packets: 261105    Bytes: 31394491    States: 136   ]&lt;br /&gt;
  [ Inserted: uid 0 pid 31812 State Creations: 0     ]&lt;br /&gt;
@3 block return in on cnmac0 all&lt;br /&gt;
  [ Evaluations: 64726     Packets: 5925      Bytes: 325492      States: 0     ]&lt;br /&gt;
  [ Inserted: uid 0 pid 31812 State Creations: 0     ]&lt;br /&gt;
@4 pass in on cnmac0 inet proto icmp all icmp-type echoreq code 0&lt;br /&gt;
  [ Evaluations: 8149      Packets: 342       Bytes: 27424       States: 0     ]&lt;br /&gt;
  [ Inserted: uid 0 pid 31812 State Creations: 171   ]&lt;br /&gt;
@5 pass in on cnmac0 inet proto icmp all icmp-type unreach&lt;br /&gt;
  [ Evaluations: 308       Packets: 5         Bytes: 368         States: 0     ]&lt;br /&gt;
  [ Inserted: uid 0 pid 31812 State Creations: 0     ]&lt;br /&gt;
@6 pass in on cnmac0 inet proto ipencap from any to 23.30.150.141&lt;br /&gt;
  [ Evaluations: 8149      Packets: 126197    Bytes: 16538717    States: 5     ]&lt;br /&gt;
  [ Inserted: uid 0 pid 31812 State Creations: 2048  ]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A site can add more elaborate rules as desired.&lt;br /&gt;
&lt;br /&gt;
== Maintaining Mesh Routes with 44ripd ==&lt;br /&gt;
&lt;br /&gt;
The above shows how to set up AMPRNet tunnel interfaces, set routes to them, use routing domains for policy-based routing, and set firewall rules. However, so far all of these steps have been manual. This works for a handful of tunnels and routes, but there are hundreds of subnets AMPRNet in the AMPRNet mesh; maintaining all of these manually is not reasonable.&lt;br /&gt;
&lt;br /&gt;
However, Dan Cross (KZ2X) has written a daemon specific to OpenBSD called &amp;lt;code&amp;gt;44ripd&amp;lt;/code&amp;gt; that maintains tunnel and route information as distributed via the [https://wiki.ampr.org/wiki/RIP AMPRNet RIP] variant sent from &amp;lt;code&amp;gt;44.0.0.1&amp;lt;/code&amp;gt;. To use this, make sure that multicasting is enabled on the host by setting &amp;lt;code&amp;gt;multicast=YES&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;/etc/rc.conf.local&amp;lt;/code&amp;gt;, and then retrieve the 44ripd software from Github at https://github.com/dancrossnyc/44ripd. The software is built with the &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt; command. For example:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;git clone https://github.com/dancrossnyc/44ripd&lt;br /&gt;
cd 44ripd&lt;br /&gt;
make&lt;br /&gt;
doas install -c -o root -g wheel -m 555 44ripd /usr/local/sbin&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once installed, this can be run at boot by adding the following lines to &amp;lt;code&amp;gt;/etc/rc.local&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;if [ -x /usr/local/sbin/44ripd ]; then&lt;br /&gt;
        echo -n &#039; 44ripd&#039;&lt;br /&gt;
        route -T 44 exec /usr/local/sbin/44ripd -s0 -s1 -D 44 -T 23&lt;br /&gt;
fi&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that the &amp;lt;code&amp;gt;-s&amp;lt;/code&amp;gt; options instruct the daemon not to try and allocate the &amp;lt;code&amp;gt;gif0&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;gif1&amp;lt;/code&amp;gt; interfaces, as these are manually configured. The &amp;lt;code&amp;gt;-D&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;-T&amp;lt;/code&amp;gt; options set the routing domains for &#039;&#039;gif&#039;&#039; interfaces and their associated tunnels, respectively.&lt;br /&gt;
&lt;br /&gt;
=== Set the Default AMPRNet Tunnel and Route Manually ===&lt;br /&gt;
&lt;br /&gt;
While route information for the UCSD AMPRNet gateway is distributed in RIP44 packets and we could in theory only configure the default incoming tunnel and rely on 44ripd to set up a route to UCSD, this leads to a problem. Specifically, without an interface configured to the UCSD gateway, we cannot set a default route in our AMRPNet routing domain for the gateway. Since we rely on periodic route broadcasts from UCSD to set those routes, we would delay setting up our default route for an indeterminate amount of time (on the order of minutes).&lt;br /&gt;
&lt;br /&gt;
Thus, it is advised to explicitly configure the tunnel to UCSD at boot time along with the default route.&lt;br /&gt;
&lt;br /&gt;
=== Notes on 44ripd Implementation ===&lt;br /&gt;
&lt;br /&gt;
* 44ripd maintains a copy of the AMPRNet routing table in a modified PATRICIA trie (really a compressed radix tree).&lt;br /&gt;
* A similar table of tunnels is maintained.&lt;br /&gt;
* Tunnel interfaces are reference counted and garbage collected. A bitmap indicating which tunnels are in use is maintained.&lt;br /&gt;
* Routes are expired after receiving a RIP packet.&lt;br /&gt;
* The program is completely self-contained in the sense that it does not fork/exec external commands to configure tunnels or manipulate routes.  That is all done via ioctls or writing messages to a routing socket.&lt;br /&gt;
* 44ripd does not examine the state of the system or routing tables at startup to bootstrap its internal state, but arguably should.&lt;br /&gt;
* Bugs in 44ripd should be reported via Github issues.&lt;br /&gt;
* Exporting and/or parsing an encap file would be nice.&lt;br /&gt;
* Logging and error checking can always be improved.&lt;/div&gt;</summary>
		<author><name>Cross</name></author>
	</entry>
	<entry>
		<id>https://wiki.ampr.org/w/index.php?title=Setting_up_a_gateway_on_OpenBSD&amp;diff=925</id>
		<title>Setting up a gateway on OpenBSD</title>
		<link rel="alternate" type="text/html" href="https://wiki.ampr.org/w/index.php?title=Setting_up_a_gateway_on_OpenBSD&amp;diff=925"/>
		<updated>2021-06-16T13:00:16Z</updated>

		<summary type="html">&lt;p&gt;Cross: Mainly grammar and typographical errors fixed.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
[https://www.openbsd.org OpenBSD] is a mature Unix-like operating system that focuses on security and correctness. It features a flexible, robust, performant TCP/IP stack and a [https://www.openbsd.org/faq/pf/ highly configurable firewall]. This page describes how to configure a computer running OpenBSD as an AMPRNet router to transfer traffic between AMPRNet subnets and the Internet.&lt;br /&gt;
&lt;br /&gt;
OpenBSD natively supports [https://en.wikipedia.org/wiki/IP_in_IP IPENCAP (IP-IP)] tunnels through [https://man.openbsd.org/gif.4 &#039;&#039;gif&#039;&#039;(4)] pseudo-devices. Each &#039;&#039;gif&#039;&#039; device is a virtual network interface, synthesized by the operating system, that implements a point-to-point tunnel. Unlike Linux, OpenBSD requires a separate &#039;&#039;gif&#039;&#039; interface for each tunnel. An essentially arbitrary number of such interfaces can be created and it scales to the number required to route all of AMPRNet.&lt;br /&gt;
&lt;br /&gt;
One can manually configure &#039;&#039;gif&#039;&#039; tunnels and routes at the command line, or configure the system to establish tunnels and routes at boot time.&lt;br /&gt;
&lt;br /&gt;
We will describe how to set things up by way of example. Assume a system configuration that looks substantially similar to the following:&lt;br /&gt;
&lt;br /&gt;
* A dedicated static IP address to use as an endpoint for AMPRNet traffic.&lt;br /&gt;
* An ISP-provided router that is just a router; no NATing, no firewall.&lt;br /&gt;
* An OpenBSD computer with three ethernet interfaces. For example, using a Ubiquiti EdgeRouter 3 Lite:&lt;br /&gt;
*# cnmac0 is the external interface connected to the ISP&#039;s network (in this example, we use 23.30.150.141 routing to 23.30.150.142)&lt;br /&gt;
*# cnmac1 connects to an internal network (its configuration is irrelevant)&lt;br /&gt;
*# cnmac2 is the internal interface connected to the subnet (in this example, we use 44.44.107.1 routing for 44.44.107.0/24)&lt;br /&gt;
&lt;br /&gt;
Let us start by configuring a single tunnel and route to the AMPRNet gateway at UCSD:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;ifconfig gif1 create&lt;br /&gt;
ifconfig gif1 tunnel 23.30.150.141 169.228.34.84&lt;br /&gt;
ifconfig gif1 inet 44.44.107.1 netmask 255.255.255.255&lt;br /&gt;
route add -host 44.0.0.1 -link -iface gif1 -llinfo&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first command creates the interface, causing the kernel to synthesize it into existence. The second configures the tunnel itself: that is, the the IP addresses that will be put into the IPENCAP datagram that the tunnel creates: the first address is the &#039;&#039;local&#039;&#039; address, which will serve as the source address for the IPENCAP packet, while the second is the &#039;&#039;remote&#039;&#039; address, to which the packet will be sent. The third sets an IP address for the local endpoint of the interface: this exists solely so that traffic that is generated by the router, such as ICMP error messages (host or port unreachable, for example), have a valid source address. Note that despite the fact that this is a point-to-point interface, we do not specify the IP address of the remote end.&lt;br /&gt;
&lt;br /&gt;
The fourth and final command creates a host route and associates it with the tunnel interface. The &amp;lt;code&amp;gt;-link&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;-iface&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;-llinfo&amp;lt;/code&amp;gt; flags indicate that this is an interface route, and that traffic for the route should go directly to the given interface (&amp;lt;code&amp;gt;gif1&amp;lt;/code&amp;gt;) instead of identifying the gateway via an IP address. We can examine this route from the commandline. E.g.,&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;$ route -n show -inet | grep &#039;44\.0\.0\.1 &#039;&lt;br /&gt;
44.0.0.1           link#7             UHLSh      1        2     -     8 gif1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Consult the manual page for [https://man.openbsd.org/netstat.1 &#039;&#039;netstat&#039;&#039;(1)] for details on what the &amp;lt;code&amp;gt;UHLSh&amp;lt;/code&amp;gt; flags mean.&lt;br /&gt;
&lt;br /&gt;
We can repeat this process for each AMPRNet tunnel, creating interfaces and adding routes for each subnet.&lt;br /&gt;
&lt;br /&gt;
== Handling Encapsulated Inbound Traffic Without a Reciprocal Tunnel ==&lt;br /&gt;
&lt;br /&gt;
When an inbound IPENCAP datagram arrives on our external interface, the network stack in the OpenBSD kernel recognizes it by examining the protocol number in the IP header: IPENCAP is protocol number 4 (not to be confused with IP version 4). Any such packets are passed to the packet input function in the &#039;&#039;gif&#039;&#039; implementation, which searches all configured &#039;&#039;gif&#039;&#039; interfaces trying to match the configured tunnel source and destinations addresses with the corresponding addresses in the inbound packet. If such an interface is found, the packet is enqueued to the interface, which will strip the IPENCAP header and route the resulting &amp;quot;de-encapsulated&amp;quot; IP packet. This works for tunnels that are configured bidirectionally between any two sites. That is, if site A has a tunnel to site B, and B has a corresponding tunnel to A, they can send each other traffic.&lt;br /&gt;
&lt;br /&gt;
Now consider the case where site A has a tunnel configured to send traffic to site B, but B has no tunnel configured to A: in this case, the datagram arrives as before and is presented to the &#039;&#039;gif&#039;&#039; implementation, but the search above fails since B has no tunnel to A, so nothing matches the source &#039;&#039;and&#039;&#039; destination addresses on the incoming packet. In this case, the system might be responsible for routing such packets to another computer or network, so the packet is not decapsulated and processed. However, in an AMPRNet context, we very well may want to process that packet. Accordingly, the &#039;&#039;gif&#039;&#039; implementation has a mechanism for describing an interface that accepts encapsulated traffic from any source destined to a local address. If we configure a &#039;&#039;gif&#039;&#039; interface where the distant end of the &#039;&#039;tunnel&#039;&#039; set to &amp;lt;code&amp;gt;0.0.0.0&amp;lt;/code&amp;gt;, then any incoming datagram where the destination address is the same as the local address on the interface will be accepted, decapsulated and processed as before. Using this, we can set up an interface specifically for accepting traffic from systems to which we have not defined a tunnel:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;ifconfig gif0 create&lt;br /&gt;
ifconfig gif0 tunnel 23.30.150.141 0.0.0.0&lt;br /&gt;
ifconfig gif0 inet 44.44.107.1 255.255.255.255&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note the &amp;lt;code&amp;gt;0.0.0.0&amp;lt;/code&amp;gt; as the remote address in the &amp;lt;code&amp;gt;ifconfig tunnel&amp;lt;/code&amp;gt; command. Again, we set an interface address using our local AMPRNet router address purely for locally generated traffic.&lt;br /&gt;
&lt;br /&gt;
One this interface is configured, IPENCAP traffic from remote systems that have defined tunnels to us will flow, regardless of whether we have created a tunnel to them.&lt;br /&gt;
&lt;br /&gt;
== Policy-based Routing Using Routing Domains ==&lt;br /&gt;
&lt;br /&gt;
The configuration explored so far is sufficient to make connections to AMPRNet subnets we have manually configured tunnels for, but suffers from a number of deficiencies. In particular, the following two issues that we will discuss now.&lt;br /&gt;
&lt;br /&gt;
First, there is a problem with exchanging traffic with non-AMPRNet systems on the Internet. Presumably, these systems are not aware of AMPRNet tunneling, so traffic from them goes to the gateway at UCSD, where it will be encapsulated and sent through a tunnel to the external interface on our router. There, it will be decapsulated and delivered into our subnet. However, return traffic will be sent to the local router, but since the destination is generally not a tunnel, it will be sent via the default route, but with an AMPRNet source address. Since most ISPs will not pass AMPRNet traffic, the result will likely be lost before it reaches the destination. We may think it would be possible to work around that using a firewall rule to NAT the source address to something provided by our ISP, but even if the resulting datagram made it to the destination, for a protocol like TCP it would no longer match the 5-tuple for the connection, and would thus be lost.&lt;br /&gt;
&lt;br /&gt;
The second problem is reaching AMPRNet systems for which we have not configured a tunnel.  Without a tunnel, and thus a route, we cannot send traffic to those systems.&lt;br /&gt;
&lt;br /&gt;
We can solve both of these problems by sending all of our traffic through a tunnel interface to the UCSD gateway by default, e.g., by setting the default route:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;route add default 4.0.0.1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However this creates a new problem: how does the encapsulated traffic from the tunnel interface get sent to our ISP&#039;s gateway? We can add a host route for the UCSD gateway in our local routing table, but we have to do this for every tunnel, which is unwieldy. Further, connecting to our external interface becomes complicated: suppose someone &amp;lt;code&amp;gt;ping&amp;lt;/code&amp;gt;s our local router&#039;s external interface. Assuming we permit this, the response would be routed through the UCSD gateway tunnel, but even if the gateway passed arbitrary traffic back onto the Internet, the packet might be lost as upstream ISPs would refuse to route it and even if delivered, it wouldn&#039;t match the destination address of the original ICMP echo request packet anyway.&lt;br /&gt;
&lt;br /&gt;
The solution to all of these problems is to use [https://en.wikipedia.org/wiki/Policy-based_routing &#039;&#039;policy-based routing&#039;&#039;]. Specifically, we would like to make routing decisions based on the source IP address of our traffic. We might be able to do this with firewall rules, but the edge cases get complicated very quickly. Fortunately, there is another way: [https://man.openbsd.org/rdomain.4 routing domains].&lt;br /&gt;
&lt;br /&gt;
Routing domains in OpenBSD are a mechanism to isolate routing decisions from one another. Network interfaces are configured into exactly one routing domain, which has its own private set of routing tables. Those tables are isolated, but traffic can be passed between routing domains via firewall rules.&lt;br /&gt;
&lt;br /&gt;
In our example, we put our external and local AMPRNet gateway interfaces into separate routing domains: all of the &#039;&#039;gif&#039;&#039; interfaces and the local AMPRNet gateway interface can both be assigned to routing domain 44, while the external interface might be 23. Routing domain 0 is the default. Note that the numbers here are arbitrary, and we can choose any value below 256 that we like; these are chosen to match the first octet of our example addresses.&lt;br /&gt;
&lt;br /&gt;
The routing domain on an interface is set using the &amp;lt;code&amp;gt;rdomain&amp;lt;/code&amp;gt; parameter to &amp;lt;code&amp;gt;ifconfig&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;ifconfig cnmac0 rdomain 23&lt;br /&gt;
ifconfig gif0 rdomain 44&lt;br /&gt;
ifconfig gif1 rdomain 44&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We set the default route in the routing domain that owns our external interface to our ISP&#039;s router, while in the routing domain hosting our AMPRNet presence we can set it to the UCSD gateway:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;route -T 23 add default 23.30.150.242&lt;br /&gt;
route -T 44 add default 44.0.0.1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now traffic on our AMPRNet subnet will be routed through the UCSD gateway, while traffic on the external interface will be routed through our ISP&#039;s router.&lt;br /&gt;
&lt;br /&gt;
Another piece of functionality allows us to dispense with much of the complexity of routing between domains: the tunnel assigned to a &#039;&#039;gif&#039;&#039; can be in a different routing domain than the interface itself. Going back to our example, if we place each of our &#039;&#039;gif&#039;&#039; interfaces into routing domain 44 then traffic routed out to on coming in from the tunnel will be routed with our AMPRNet-specific routing table. But if we place the tunnel on that interface into routing domain 23, then the encapsulated traffic that we send to and from the Internet (e.g., to other tunnel end points) will be routed in that domain, thus routing through our ISP&#039;s network. Critically, matching incoming datagrams to &#039;&#039;gif&#039;&#039; interfaces as described above happens in the routing domain associated with the tunnel, so inbound traffic coming through our external interface will be directed to the correct interface.&lt;br /&gt;
&lt;br /&gt;
We specify the routing domain of a tunnel via the &amp;lt;code&amp;gt;tunneldomain&amp;lt;/code&amp;gt; parameter to &amp;lt;code&amp;gt;ifconfig&amp;lt;/code&amp;gt; when configuring the route on an interface:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;ifconfig gif0 tunnel 23.30.150.141 0.0.0.0 tunneldomain 23&lt;br /&gt;
ifconfig gif1 tunnel 23.30.150.141 169.228.34.84 tunneldomain 23&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With this in place, routing works as expected for all of the cases mentioned above.&lt;br /&gt;
&lt;br /&gt;
== Persistent Configuration Across Router Restarts ==&lt;br /&gt;
&lt;br /&gt;
We now have enough information that we can set up tunnels between our router and arbitrary AMPRNet subnets. However, doing so manually is tedious and not particularly robust. We would like the system to automatically configure our tunnels and default routes at boot time. Fortunately, the OpenBSD startup code can do this easily. For each network interface &amp;lt;code&amp;gt;$if&amp;lt;/code&amp;gt; on the system, we can configure it automatically at boot time by putting configuration commands into the file &amp;lt;code&amp;gt;/etc/hostname.$if&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
There are four interfaces we have configured: the two ethernet interfaces for our external and AMPRNet networks, and the two &#039;&#039;gif&#039;&#039; interfaces with the default incoming tunnel and the tunnel to the UCSD gateway.  Thus, there are four files:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/etc/hostname.cnmac0&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;rdomain 23&lt;br /&gt;
inet 23.30.150.141 0xfffffff8&lt;br /&gt;
!ifconfig lo23 inet 127.0.0.1&lt;br /&gt;
!route -qn -T 23 add default 23.30.150.142&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/etc/hostname.cnmac2&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;rdomain 44&lt;br /&gt;
inet 44.44.107.1 255.255.255.0&lt;br /&gt;
!ifconfig lo44 inet 127.0.0.1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/etc/hostname.gif0&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;rdomain 44&lt;br /&gt;
tunnel 23.30.150.141 0.0.0.0 tunneldomain 23&lt;br /&gt;
inet 44.44.107.1 255.255.255.255&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/etc/hostname.gif1&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;tunnel 23.30.150.141 169.228.34.84 tunneldomain 23&lt;br /&gt;
inet 44.44.107.1 255.255.255.255&lt;br /&gt;
!route -qn -T 44 add 44.0.0.1/32 -link -iface gif1 -llinfo&lt;br /&gt;
!route -qn -T 44 add default 44.0.0.1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that each routing domain also has its own associated loopback interface, hence configuring &amp;lt;code&amp;gt;lo23&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;lo44&amp;lt;/code&amp;gt;. These interfaces are automatically created when the routing domain is created, but we configure them when we bring up the associated ethernet interfaces.&lt;br /&gt;
&lt;br /&gt;
We can examine the interfaces and separate routing tables to ensure that things are set up as expected:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;$ ifconfig cnmac0&lt;br /&gt;
cnmac0: flags=8843&amp;lt;UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST&amp;gt; rdomain 23 mtu 1500&lt;br /&gt;
        lladdr 44:d9:e7:9f:a7:64&lt;br /&gt;
        index 1 priority 0 llprio 3&lt;br /&gt;
        media: Ethernet autoselect (1000baseT full-duplex)&lt;br /&gt;
        status: active&lt;br /&gt;
        inet 23.30.150.141 netmask 0xfffffff8 broadcast 23.30.150.143&lt;br /&gt;
$ ifconfig cnmac2&lt;br /&gt;
cnmac2: flags=8843&amp;lt;UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST&amp;gt; rdomain 44 mtu 1500&lt;br /&gt;
        lladdr 44:d9:e7:9f:a7:66&lt;br /&gt;
        index 3 priority 0 llprio 3&lt;br /&gt;
        media: Ethernet autoselect (1000baseT full-duplex,master)&lt;br /&gt;
        status: active&lt;br /&gt;
        inet 44.44.107.1 netmask 0xffffff00 broadcast 44.44.107.255&lt;br /&gt;
$ ifconfig gif0&lt;br /&gt;
gif0: flags=8051&amp;lt;UP,POINTOPOINT,RUNNING,MULTICAST&amp;gt; rdomain 44 mtu 1280&lt;br /&gt;
        index 6 priority 0 llprio 3&lt;br /&gt;
        encap: txprio payload rxprio payload&lt;br /&gt;
        groups: gif&lt;br /&gt;
        tunnel: inet 23.30.150.141 -&amp;gt; 0.0.0.0 ttl 64 nodf ecn rdomain 23&lt;br /&gt;
        inet 44.44.107.1 --&amp;gt; 0.0.0.0 netmask 0xffffffff&lt;br /&gt;
$ ifconfig gif1&lt;br /&gt;
gif1: flags=8051&amp;lt;UP,POINTOPOINT,RUNNING,MULTICAST&amp;gt; rdomain 44 mtu 1280&lt;br /&gt;
        index 7 priority 0 llprio 3&lt;br /&gt;
        encap: txprio payload rxprio payload&lt;br /&gt;
        groups: gif&lt;br /&gt;
        tunnel: inet 23.30.150.141 -&amp;gt; 169.228.34.84 ttl 64 nodf ecn rdomain 23&lt;br /&gt;
        inet 44.44.107.1 --&amp;gt; 0.0.0.0 netmask 0xffffffff&lt;br /&gt;
$ route -T 23 -n show -inet&lt;br /&gt;
Routing tables&lt;br /&gt;
&lt;br /&gt;
Internet:&lt;br /&gt;
Destination        Gateway            Flags   Refs      Use   Mtu  Prio Iface&lt;br /&gt;
default            23.30.150.142      UGS        0    51126     -     8 cnmac0&lt;br /&gt;
23.30.150.136/29   23.30.150.141      UCn        1        7     -     4 cnmac0&lt;br /&gt;
23.30.150.141      44:d9:e7:9f:a7:64  UHLl       0    88377     -     1 cnmac0&lt;br /&gt;
23.30.150.142      4a:1d:70:de:c3:5a  UHLch      1      386     -     3 cnmac0&lt;br /&gt;
23.30.150.143      23.30.150.141      UHb        0        0     -     1 cnmac0&lt;br /&gt;
127.0.0.1          127.0.0.1          UHl        0        0 32768     1 lo23&lt;br /&gt;
$ route -T 44 -n show -inet&lt;br /&gt;
Routing tables&lt;br /&gt;
&lt;br /&gt;
Internet:&lt;br /&gt;
Destination        Gateway            Flags   Refs      Use   Mtu  Prio Iface&lt;br /&gt;
default            44.0.0.1           UGS        0    54718     -     8 gif1&lt;br /&gt;
44.0.0.1           link#7             UHLSh      1        2     -     8 gif1&lt;br /&gt;
44.44.107/24       44.44.107.1        UCn       16        4     -     4 cnmac2&lt;br /&gt;
44.44.107.1        44:d9:e7:9f:a7:66  UHLl       0     4825     -     1 cnmac2&lt;br /&gt;
44.44.107.255      44.44.107.1        UHb        0        0     -     1 cnmac2&lt;br /&gt;
127.0.0.1          127.0.0.1          UHl        0        0 32768     1 lo44&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Restricting Traffic with the [https://www.openbsd.org/faq/pf/ PF] Firewall ==&lt;br /&gt;
&lt;br /&gt;
All of these interfaces will fully integrate with the PF firewall software that comes with OpenBSD, and we can implement nearly arbitrary policies in our configuration.  For example, we might restrict traffic on the external interface to only ICMP messages and IPENCAP datagrams by setting the following rules in &amp;lt;code&amp;gt;/etc/pf.conf&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;# Constants&lt;br /&gt;
extif = &amp;quot;cnmac0&amp;quot;&lt;br /&gt;
extamprgate = &amp;quot;23.30.150.141&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Options&lt;br /&gt;
set skip on lo&lt;br /&gt;
set block-policy return&lt;br /&gt;
&lt;br /&gt;
block return    # block stateless traffic&lt;br /&gt;
pass            # establish keep-state&lt;br /&gt;
&lt;br /&gt;
# Normalize incoming packets.&lt;br /&gt;
match in all scrub (no-df random-id max-mss 1440)&lt;br /&gt;
&lt;br /&gt;
# By default, block everything.  We selectively override in subsequent rules.&lt;br /&gt;
block in on $extif&lt;br /&gt;
&lt;br /&gt;
# Pass 44net traffic&lt;br /&gt;
pass in on $extif inet proto ipencap from any to $extamprgate&lt;br /&gt;
&lt;br /&gt;
# Pass ping and ICMP unreachable messages on external interface&lt;br /&gt;
pass in on $extif inet proto icmp icmp-type echoreq code 0 keep state&lt;br /&gt;
pass in on $extif inet proto icmp icmp-type unreach keep state&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We can verify that these rules are in place as expected by querying the rule tables:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;# pfctl -sr -vv&lt;br /&gt;
@0 block return all&lt;br /&gt;
  [ Evaluations: 115977    Packets: 3776      Bytes: 168422      States: 0     ]&lt;br /&gt;
  [ Inserted: uid 0 pid 31812 State Creations: 0     ]&lt;br /&gt;
@1 pass all flags S/SA&lt;br /&gt;
  [ Evaluations: 115977    Packets: 242418    Bytes: 25899015    States: 253   ]&lt;br /&gt;
  [ Inserted: uid 0 pid 31812 State Creations: 102105]&lt;br /&gt;
@2 match in all scrub (no-df random-id max-mss 1440)&lt;br /&gt;
  [ Evaluations: 115977    Packets: 261105    Bytes: 31394491    States: 136   ]&lt;br /&gt;
  [ Inserted: uid 0 pid 31812 State Creations: 0     ]&lt;br /&gt;
@3 block return in on cnmac0 all&lt;br /&gt;
  [ Evaluations: 64726     Packets: 5925      Bytes: 325492      States: 0     ]&lt;br /&gt;
  [ Inserted: uid 0 pid 31812 State Creations: 0     ]&lt;br /&gt;
@4 pass in on cnmac0 inet proto icmp all icmp-type echoreq code 0&lt;br /&gt;
  [ Evaluations: 8149      Packets: 342       Bytes: 27424       States: 0     ]&lt;br /&gt;
  [ Inserted: uid 0 pid 31812 State Creations: 171   ]&lt;br /&gt;
@5 pass in on cnmac0 inet proto icmp all icmp-type unreach&lt;br /&gt;
  [ Evaluations: 308       Packets: 5         Bytes: 368         States: 0     ]&lt;br /&gt;
  [ Inserted: uid 0 pid 31812 State Creations: 0     ]&lt;br /&gt;
@6 pass in on cnmac0 inet proto ipencap from any to 23.30.150.141&lt;br /&gt;
  [ Evaluations: 8149      Packets: 126197    Bytes: 16538717    States: 5     ]&lt;br /&gt;
  [ Inserted: uid 0 pid 31812 State Creations: 2048  ]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A site can add more elaborate rules as desired.&lt;br /&gt;
&lt;br /&gt;
== Maintaining Mesh Routes with 44ripd ==&lt;br /&gt;
&lt;br /&gt;
The above shows how to set up AMPRNet tunnel interfaces, set routes to them, use routing domains for policy-based routing, and set firewall rules. However, so far all of these steps have been manual. This works for a handful of tunnels and routes, but there are hundreds of subnets AMPRNet in the AMPRNet mesh; maintaining all of these manually is not reasonable.&lt;br /&gt;
&lt;br /&gt;
However, Dan Cross (KZ2X) has written a daemon specific to OpenBSD called &amp;lt;code&amp;gt;44ripd&amp;lt;/code&amp;gt; that maintains tunnel and route information as distributed via the [https://wiki.ampr.org/wiki/RIP AMPRNet RIP] variant sent from &amp;lt;code&amp;gt;44.0.0.1&amp;lt;/code&amp;gt;. To use this, make sure that multicasting is enabled on the host by setting &amp;lt;code&amp;gt;multicast=YES&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;/etc/rc.conf.local&amp;lt;/code&amp;gt;, and then retrieve the 44ripd software from Github at https://github.com/dancrossnyc/44ripd. The software is built with the &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt; command. For example:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;git clone https://github.com/dancrossnyc/44ripd&lt;br /&gt;
cd 44ripd&lt;br /&gt;
make&lt;br /&gt;
doas install -c -o root -g wheel -m 555 44ripd /usr/local/sbin&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once installed, this can be run at boot by adding the following lines to &amp;lt;code&amp;gt;/etc/rc.local&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;if [ -x /usr/local/sbin/44ripd ]; then&lt;br /&gt;
        echo -n &#039; 44ripd&#039;&lt;br /&gt;
        route -T 44 exec /usr/local/sbin/44ripd -s0 -s1 -D 44 -T 23&lt;br /&gt;
fi&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that the &amp;lt;code&amp;gt;-s&amp;lt;/code&amp;gt; options instruct the daemon not to try and allocate the &amp;lt;code&amp;gt;gif0&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;gif1&amp;lt;/code&amp;gt; interfaces, as these are manually configured. The &amp;lt;code&amp;gt;-D&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;-T&amp;lt;/code&amp;gt; options set the routing domains for &#039;&#039;gif&#039;&#039; interfaces and their associated tunnels, respectively.&lt;br /&gt;
&lt;br /&gt;
=== Set the Default AMPRNet Tunnel and Route Manually ===&lt;br /&gt;
&lt;br /&gt;
While route information for the UCSD AMPRNet gateway is distributed in RIP44 packets and we could in theory only configure the default incoming tunnel and rely on 44ripd to set up a route to UCSD, this leads to a problem. Specifically, without an interface configured to the UCSD gateway, we cannot set a default route in our AMRPNet routing domain for the gateway. Since we rely on periodic route broadcasts from UCSD to set those routes, we would delay setting up our default route for an indeterminate amount of time (on the order of minutes).&lt;br /&gt;
&lt;br /&gt;
Thus, it is advised to explicitly configure the tunnel to UCSD at boot time along with the default route.&lt;br /&gt;
&lt;br /&gt;
=== Notes on 44ripd Implementation ===&lt;br /&gt;
&lt;br /&gt;
* 44ripd maintains a copy of the AMPRNet routing table in a modified PATRICIA trie (really a compressed radix tree).&lt;br /&gt;
* A similar table of tunnels is maintained.&lt;br /&gt;
* Tunnel interfaces are reference counted and garbage collected. A bitmap indicating which tunnels are in use is maintained.&lt;br /&gt;
* Routes are expired after receiving a RIP packet.&lt;br /&gt;
* The program is completely self-contained in the sense that it does not fork/exec external commands to configure tunnels or manipulate routes.  That is all done via ioctls or writing messages to a routing socket.&lt;br /&gt;
* 44ripd does not examine the state of the system or routing tables at startup to bootstrap its internal state, but arguably should.&lt;br /&gt;
* Bugs in 44ripd should be reported via Github issues.&lt;br /&gt;
* Exporting and/or parsing an encap file would be nice.&lt;br /&gt;
* Logging and error checking can always be improved.&lt;/div&gt;</summary>
		<author><name>Cross</name></author>
	</entry>
	<entry>
		<id>https://wiki.ampr.org/w/index.php?title=Setting_up_a_gateway_on_OpenBSD&amp;diff=917</id>
		<title>Setting up a gateway on OpenBSD</title>
		<link rel="alternate" type="text/html" href="https://wiki.ampr.org/w/index.php?title=Setting_up_a_gateway_on_OpenBSD&amp;diff=917"/>
		<updated>2021-01-21T13:20:23Z</updated>

		<summary type="html">&lt;p&gt;Cross: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
[https://www.openbsd.org OpenBSD] is a mature Unix-like operating system that focuses on security and correctness. It features a flexible, robust, performant TCP/IP stack and a [https://www.openbsd.org/faq/pf/ highly configurable firewall]. This page describes how to configure a computer running OpenBSD as an AMPRNet router to transfer traffic between AMPRNet subnets and the Internet.&lt;br /&gt;
&lt;br /&gt;
OpenBSD natively supports [https://en.wikipedia.org/wiki/IP_in_IP IPENCAP (IP-IP)] tunnels through [https://man.openbsd.org/gif.4 &#039;&#039;gif&#039;&#039;(4)] pseudo-devices. Each &#039;&#039;gif&#039;&#039; device is a virtual network interface, synthesized by the operating system, that implements a point-to-point tunnel. Unlike Linux, OpenBSD requires a separate &#039;&#039;gif&#039;&#039; interface for each tunnel. An essentially arbitrary number of such interfaces can be created and it scales to the number required to route all of AMPRNet.&lt;br /&gt;
&lt;br /&gt;
One can manually configure &#039;&#039;gif&#039;&#039; tunnels and routes at the command line, or configure the system to establish tunnels and routes at boot time.&lt;br /&gt;
&lt;br /&gt;
We will describe how to set things up by way of example. Assume a system configuration that looks substantially similar to the following:&lt;br /&gt;
&lt;br /&gt;
* A dedicated static IP address to use as an endpoint for AMPRNet traffic.&lt;br /&gt;
* An ISP-provided router that is just a router; no NATing, no firewall.&lt;br /&gt;
* An OpenBSD computer with three ethernet interfaces. For example, using a Ubiquiti EdgeRouter 3 Lite:&lt;br /&gt;
*# cnmac0 is the external interface connected to the ISP&#039;s network (in this example, we use 23.30.150.141 routing to 23.30.150.142)&lt;br /&gt;
*# cnmac1 connects to an internal network (its configuration is irrelevant)&lt;br /&gt;
*# cnmac2 is the internal interface connected to the subnet (in this example, we use 44.44.107.1 routing for 44.44.107.0/24)&lt;br /&gt;
&lt;br /&gt;
Let us start by configuring a single tunnel and route to the AMPRNet gateway at UCSD:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;ifconfig gif1 create&lt;br /&gt;
ifconfig gif1 tunnel 23.30.150.141 169.228.34.84&lt;br /&gt;
ifconfig gif1 inet 44.44.107.1 netmask 255.255.255.255&lt;br /&gt;
route add -host 44.0.0.1 -link -iface gif1 -llinfo&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first command creates the interface, causing the kernel to synthesize it into existence. The second configures the tunnel itself: that is, the the IP addresses that will be put into the IPENCAP datagram that the tunnel creates: the first address is the &#039;&#039;local&#039;&#039; address, which will serve as the source address for the IPENCAP packet, while the second is the &#039;&#039;remote&#039;&#039; address, to which the packet will be sent. The third sets an IP address for the local endpoint of the interface: this exists solely so that traffic that is generated by the router, such as ICMP error messages (host or port unreachable, for example), have a valid source address. Note that despite the fact that this is a point-to-point interface, we do not specify the IP address of the remote end.&lt;br /&gt;
&lt;br /&gt;
The fourth and final command creates a host route and associates it with the tunnel interface. The &amp;lt;code&amp;gt;-link&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;-iface&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;-llinfo&amp;lt;/code&amp;gt; flags indicate that this is an interface route, and that traffic for the route should go directly to the given interface (&amp;lt;code&amp;gt;gif1&amp;lt;/code&amp;gt;) instead of identifying the gateway via an IP address. We can examine this route from the commandline. E.g.,&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;$ route -n show -inet | grep &#039;44\.0\.0\.1 &#039;&lt;br /&gt;
44.0.0.1           link#7             UHLSh      1        2     -     8 gif1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Consult the manual page for [https://man.openbsd.org/netstat.1 &#039;&#039;netstat&#039;&#039;(1)] for details on what the &amp;lt;code&amp;gt;UHLSh&amp;lt;/code&amp;gt; flags mean.&lt;br /&gt;
&lt;br /&gt;
We can repeat this process for each AMPRNet tunnel, creating interfaces and adding routes for each subnet.&lt;br /&gt;
&lt;br /&gt;
== Handling Encapsulated Inbound Traffic Without a Reciprocal Tunnel ==&lt;br /&gt;
&lt;br /&gt;
When an inbound IPENCAP datagram arrives on our external interface, the network stack in the OpenBSD kernel recognizes it by examining the protocol number in the IP header: IPENCAP is protocol number 4 (not to be confused with IP version 4). Any such packets are passed to the packet input function in the &#039;&#039;gif&#039;&#039; implementation, which searches all configured &#039;&#039;gif&#039;&#039; interfaces trying to find match the configured tunnel source and destinations addresses with the corresponding addresses in the inbound packet. If such an interface is found, the packet is enqueued to the interface, which will strip the IPENCAP header and route the resulting &amp;quot;de-encapsulated&amp;quot; IP packet. This works for tunnels that are configured bidirectionally between any two sites. That is, if site A has a tunnel to site B, and B has a corresponding tunnel to A, they can send each other traffic.&lt;br /&gt;
&lt;br /&gt;
Now consider the case where site A has a tunnel configured to send traffic to site B, but B has no tunnel configured to A: in this case, the datagram arrives as before and is presented to the &#039;&#039;gif&#039;&#039; implementation, but the search above fails since B has no tunnel to A, so nothing matches the source &#039;&#039;and&#039;&#039; destination addresses on the incoming packet. In this case, the system might be responsible for routing such packets to another computer or network, so the packet is not de-encapsulated and processed. However, in an AMPRNet context, we very well may want to process that packet. Accordingly, the &#039;&#039;gif&#039;&#039; implementation has a mechanism for describing an interface that accepts encapsulated traffic from any source destined to a local address. If we configure a &#039;&#039;gif&#039;&#039; interface where the distant end of the &#039;&#039;tunnel&#039;&#039; set to &amp;lt;code&amp;gt;0.0.0.0&amp;lt;/code&amp;gt;, then any incoming datagram where the destination address is the same as the local address on the interface, will be accepted and de-encapsulated and processed as before. Using this, we can set up an interface specifically for accepting traffic from systems to which we have not defined a tunnel:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;ifconfig gif0 create&lt;br /&gt;
ifconfig gif0 tunnel 23.30.150.141 0.0.0.0&lt;br /&gt;
ifconfig gif0 inet 44.44.107.1 255.255.255.255&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note the &amp;lt;code&amp;gt;0.0.0.0&amp;lt;/code&amp;gt; as the remote address in the &amp;lt;code&amp;gt;ifconfig tunnel&amp;lt;/code&amp;gt; command. Again, we set an interface address using our local AMPRNet router address purely for locally generated traffic.&lt;br /&gt;
&lt;br /&gt;
One this interface is configured, IPENCAP traffic from remote systems that have defined tunnels to us will flow, regardless of whether we have created a tunnel to them.&lt;br /&gt;
&lt;br /&gt;
== Policy-based Routing Using Routing Domains ==&lt;br /&gt;
&lt;br /&gt;
The configuration explored so far is sufficient to make connections to AMPRNet directly-configured AMPRNet subnets, but suffers from a number of deficiencies. In particular, there are two issues that we will discuss now.&lt;br /&gt;
&lt;br /&gt;
First, there is a problem with exchanging traffic with non-AMPRNet systems on the Internet. Presumably, these systems are not aware of AMPRNet tunneling, so traffic from them goes to the gateway at UCSD, where it will be encapsulated and sent through a tunnel to the external interface on our router. There, it will be de-encapsulated and delivered into our subnet. However, return traffic will be sent to the router, but since the destination is generally a tunnel, it will be sent via the default route, but from an AMPRNet source address. Since most ISPs will not pass AMPRNet traffic, the result will likely be lost before it reaches the destination. We may think it would be possible to work around that using a firewall rule to NAT the source address to something provided by our ISP, but even if the resulting datagram made it to the destination, for a protocol like TCP it would no longer match the 5-tuple for the connection, and would thus be lost.&lt;br /&gt;
&lt;br /&gt;
The second problem is how reaching AMPRNet systems for which we have not configured a tunnel.  Without a tunnel, and thus a route, we cannot send traffic to those systems.&lt;br /&gt;
&lt;br /&gt;
We can solve both of these problems by sending all of our traffic through a tunnel interface to the UCSD gateway by default, e.g., by setting the default route:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;route add default 4.0.0.1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, how does the encapsulated traffic from the tunnel interface get sent to our ISP&#039;s router? We can add a host route for the UCSD gateway in our local routing table, but we have to do this for every tunnel, which is unwieldy. Further, connecting to our external interface becomes complicated: suppose someone &amp;lt;code&amp;gt;ping&amp;lt;/code&amp;gt;s our external interface. Assuming we permit this, the response would be routed through the UCSD gateway tunnel, but even if the gateway passed arbitrary traffic back onto the Internet, the packet might be lost as upstream ISPs would refuse to route it.&lt;br /&gt;
&lt;br /&gt;
The solution to all of these problems is to use [https://en.wikipedia.org/wiki/Policy-based_routing &#039;&#039;policy-based routing&#039;&#039;]. Specifically, we would like to make routing decisions based on the source IP address of our traffic. We might be able to do this with firewall rules, but the edge cases get complicated very quickly. Fortunately, there is another way: [https://man.openbsd.org/rdomain.4 routing domains].&lt;br /&gt;
&lt;br /&gt;
Routing domains in OpenBSD are a mechanism to isolate routing decisions from one another. Network interfaces are configured into exactly one routing domain, which has its own private set of routing tables. Those tables are isolated, but traffic can be passed between routing domains via firewall rules.&lt;br /&gt;
&lt;br /&gt;
In our example, we put our external and local AMPRNet gateway interfaces into separate routing domains: all of the &#039;&#039;gif&#039;&#039; interfaces and the local AMPRNet gateway interface can both be assigned to routing domain 44, while the external interface might be 23. Routing domain 0 is the default. Note that the numbers here are arbitrary, and we can choose any value below 256 that we like; these are chosen to match the first octet of our example addresses.&lt;br /&gt;
&lt;br /&gt;
The routing domain on an interface is set using the &amp;lt;code&amp;gt;rdomain&amp;lt;/code&amp;gt; parameter to &amp;lt;code&amp;gt;ifconfig&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;ifconfig cnmac0 rdomain 23&lt;br /&gt;
ifconfig gif0 rdomain 44&lt;br /&gt;
ifconfig gif1 rdomain 44&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We set the default route in the routing domain that owns our external interface to our ISP&#039;s router, while in the routing domain hosting our AMPRNet presence we can set it to the UCSD gateway:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;route -T 23 add default 23.30.150.242&lt;br /&gt;
route -T 44 add default 44.0.0.1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now traffic on our AMPRNet subnet will be routed through the UCSD gateway, while traffic on the external interface will be routed through our ISP&#039;s router.&lt;br /&gt;
&lt;br /&gt;
Another piece of functionality allows us to dispense with much of the complexity of routing between domains: the tunnel assigned to a &#039;&#039;gif&#039;&#039; can be in a different routing domain than the interface itself. Going back to our example, if we place each of our &#039;&#039;gif&#039;&#039; interfaces into routing domain 44 then traffic routed out to on coming in from the tunnel will be routed with our AMPRNet-specific routing table. But if we place the tunnel on that interface into routing domain 23, then the encapsulated traffic that we send to and from the Internet (e.g., to other tunnel end points) will be routed in that domain, thus routing through our ISP&#039;s network. Critically, matching incoming datagrams to &#039;&#039;gif&#039;&#039; interfaces as described above happens in the routing domain associated with the tunnel, so inbound traffic coming through our external interface will be directed to the correct interface.&lt;br /&gt;
&lt;br /&gt;
We specify the routing domain of a tunnel via the &amp;lt;code&amp;gt;tunneldomain&amp;lt;/code&amp;gt; parameter to &amp;lt;code&amp;gt;ifconfig&amp;lt;/code&amp;gt; when configuring the route on an interface:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;ifconfig gif0 tunnel 23.30.150.141 0.0.0.0 tunneldomain 23&lt;br /&gt;
ifconfig gif1 tunnel 23.30.150.141 169.228.34.84 tunneldomain 23&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With this in place, routing works as expected for all of the cases mentioned above.&lt;br /&gt;
&lt;br /&gt;
== Persistent Configuration Across Router Restarts ==&lt;br /&gt;
&lt;br /&gt;
We now have enough information that we can set up tunnels between our router and arbitrary AMPRNet subnets. However, doing so manually is tedious and not particularly robust. We would like the system to automatically configure our tunnels and default routes at boot time. Fortunately, the OpenBSD startup code can do this easily. For each network interface &amp;lt;code&amp;gt;$if&amp;lt;/code&amp;gt; on the system, we can configure it automatically at boot time by putting configuration commands into the file &amp;lt;code&amp;gt;/etc/hostname.$if&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
There are four interfaces we have configured: the two ethernet interfaces for our external and AMPRNet networks, and the two &#039;&#039;gif&#039;&#039; interfaces with the default incoming tunnel and the tunnel to the UCSD gateway.  Thus, there are four files:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/etc/hostname.cnmac0&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;rdomain 23&lt;br /&gt;
inet 23.30.150.141 0xfffffff8&lt;br /&gt;
!ifconfig lo23 inet 127.0.0.1&lt;br /&gt;
!route -qn -T 23 add default 23.30.150.142&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/etc/hostname.cnmac2&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;rdomain 44&lt;br /&gt;
inet 44.44.107.1 255.255.255.0&lt;br /&gt;
!ifconfig lo44 inet 127.0.0.1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/etc/hostname.gif0&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;rdomain 44&lt;br /&gt;
tunnel 23.30.150.141 0.0.0.0 tunneldomain 23&lt;br /&gt;
inet 44.44.107.1 255.255.255.255&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/etc/hostname.gif1&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;tunnel 23.30.150.141 169.228.34.84 tunneldomain 23&lt;br /&gt;
inet 44.44.107.1 255.255.255.255&lt;br /&gt;
!route -qn -T 44 add 44.0.0.1/32 -link -iface gif1 -llinfo&lt;br /&gt;
!route -qn -T 44 add default 44.0.0.1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that each routing domain also has its own associated loopback interface, hence configuring &amp;lt;code&amp;gt;lo23&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;lo44&amp;lt;/code&amp;gt;. These interfaces are automatically created when the routing domain is created, but we configure them when we bring up the associated ethernet interfaces.&lt;br /&gt;
&lt;br /&gt;
We can examine the interfaces and separate routing tables to ensure that things are set up as expected:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;$ ifconfig cnmac0&lt;br /&gt;
cnmac0: flags=8843&amp;lt;UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST&amp;gt; rdomain 23 mtu 1500&lt;br /&gt;
        lladdr 44:d9:e7:9f:a7:64&lt;br /&gt;
        index 1 priority 0 llprio 3&lt;br /&gt;
        media: Ethernet autoselect (1000baseT full-duplex)&lt;br /&gt;
        status: active&lt;br /&gt;
        inet 23.30.150.141 netmask 0xfffffff8 broadcast 23.30.150.143&lt;br /&gt;
$ ifconfig cnmac2&lt;br /&gt;
cnmac2: flags=8843&amp;lt;UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST&amp;gt; rdomain 44 mtu 1500&lt;br /&gt;
        lladdr 44:d9:e7:9f:a7:66&lt;br /&gt;
        index 3 priority 0 llprio 3&lt;br /&gt;
        media: Ethernet autoselect (1000baseT full-duplex,master)&lt;br /&gt;
        status: active&lt;br /&gt;
        inet 44.44.107.1 netmask 0xffffff00 broadcast 44.44.107.255&lt;br /&gt;
$ ifconfig gif0&lt;br /&gt;
gif0: flags=8051&amp;lt;UP,POINTOPOINT,RUNNING,MULTICAST&amp;gt; rdomain 44 mtu 1280&lt;br /&gt;
        index 6 priority 0 llprio 3&lt;br /&gt;
        encap: txprio payload rxprio payload&lt;br /&gt;
        groups: gif&lt;br /&gt;
        tunnel: inet 23.30.150.141 -&amp;gt; 0.0.0.0 ttl 64 nodf ecn rdomain 23&lt;br /&gt;
        inet 44.44.107.1 --&amp;gt; 0.0.0.0 netmask 0xffffffff&lt;br /&gt;
$ ifconfig gif1&lt;br /&gt;
gif1: flags=8051&amp;lt;UP,POINTOPOINT,RUNNING,MULTICAST&amp;gt; rdomain 44 mtu 1280&lt;br /&gt;
        index 7 priority 0 llprio 3&lt;br /&gt;
        encap: txprio payload rxprio payload&lt;br /&gt;
        groups: gif&lt;br /&gt;
        tunnel: inet 23.30.150.141 -&amp;gt; 169.228.34.84 ttl 64 nodf ecn rdomain 23&lt;br /&gt;
        inet 44.44.107.1 --&amp;gt; 0.0.0.0 netmask 0xffffffff&lt;br /&gt;
$ route -T 23 -n show -inet&lt;br /&gt;
Routing tables&lt;br /&gt;
&lt;br /&gt;
Internet:&lt;br /&gt;
Destination        Gateway            Flags   Refs      Use   Mtu  Prio Iface&lt;br /&gt;
default            23.30.150.142      UGS        0    51126     -     8 cnmac0&lt;br /&gt;
23.30.150.136/29   23.30.150.141      UCn        1        7     -     4 cnmac0&lt;br /&gt;
23.30.150.141      44:d9:e7:9f:a7:64  UHLl       0    88377     -     1 cnmac0&lt;br /&gt;
23.30.150.142      4a:1d:70:de:c3:5a  UHLch      1      386     -     3 cnmac0&lt;br /&gt;
23.30.150.143      23.30.150.141      UHb        0        0     -     1 cnmac0&lt;br /&gt;
127.0.0.1          127.0.0.1          UHl        0        0 32768     1 lo23&lt;br /&gt;
$ route -T 44 -n show -inet&lt;br /&gt;
Routing tables&lt;br /&gt;
&lt;br /&gt;
Internet:&lt;br /&gt;
Destination        Gateway            Flags   Refs      Use   Mtu  Prio Iface&lt;br /&gt;
default            44.0.0.1           UGS        0    54718     -     8 gif1&lt;br /&gt;
44.0.0.1           link#7             UHLSh      1        2     -     8 gif1&lt;br /&gt;
44.44.107/24       44.44.107.1        UCn       16        4     -     4 cnmac2&lt;br /&gt;
44.44.107.1        44:d9:e7:9f:a7:66  UHLl       0     4825     -     1 cnmac2&lt;br /&gt;
44.44.107.255      44.44.107.1        UHb        0        0     -     1 cnmac2&lt;br /&gt;
127.0.0.1          127.0.0.1          UHl        0        0 32768     1 lo44&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Restricting Traffic with the [https://www.openbsd.org/faq/pf/ PF] Firewall ==&lt;br /&gt;
&lt;br /&gt;
All of these interfaces will fully integrate with the PF firewall software that comes with OpenBSD, and we can implement nearly arbitrary policies in our configuration.  For example, we might restrict traffic on the external interface to only ICMP messages and IPENCAP datagrams by setting the following rules in &amp;lt;code&amp;gt;/etc/pf.conf&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;# Constants&lt;br /&gt;
extif = &amp;quot;cnmac0&amp;quot;&lt;br /&gt;
extamprgate = &amp;quot;23.30.150.141&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Options&lt;br /&gt;
set skip on lo&lt;br /&gt;
set block-policy return&lt;br /&gt;
&lt;br /&gt;
block return    # block stateless traffic&lt;br /&gt;
pass            # establish keep-state&lt;br /&gt;
&lt;br /&gt;
# Normalize incoming packets.&lt;br /&gt;
match in all scrub (no-df random-id max-mss 1440)&lt;br /&gt;
&lt;br /&gt;
# By default, block everything.  We selectively override in subsequent rules.&lt;br /&gt;
block in on $extif&lt;br /&gt;
&lt;br /&gt;
# Pass 44net traffic&lt;br /&gt;
pass in on $extif inet proto ipencap from any to $extamprgate&lt;br /&gt;
&lt;br /&gt;
# Pass ping and ICMP unreachable messages on external interface&lt;br /&gt;
pass in on $extif inet proto icmp icmp-type echoreq code 0 keep state&lt;br /&gt;
pass in on $extif inet proto icmp icmp-type unreach keep state&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We can verify that these rules are in place as expected by querying the rule tables:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;# pfctl -sr -vv&lt;br /&gt;
@0 block return all&lt;br /&gt;
  [ Evaluations: 115977    Packets: 3776      Bytes: 168422      States: 0     ]&lt;br /&gt;
  [ Inserted: uid 0 pid 31812 State Creations: 0     ]&lt;br /&gt;
@1 pass all flags S/SA&lt;br /&gt;
  [ Evaluations: 115977    Packets: 242418    Bytes: 25899015    States: 253   ]&lt;br /&gt;
  [ Inserted: uid 0 pid 31812 State Creations: 102105]&lt;br /&gt;
@2 match in all scrub (no-df random-id max-mss 1440)&lt;br /&gt;
  [ Evaluations: 115977    Packets: 261105    Bytes: 31394491    States: 136   ]&lt;br /&gt;
  [ Inserted: uid 0 pid 31812 State Creations: 0     ]&lt;br /&gt;
@3 block return in on cnmac0 all&lt;br /&gt;
  [ Evaluations: 64726     Packets: 5925      Bytes: 325492      States: 0     ]&lt;br /&gt;
  [ Inserted: uid 0 pid 31812 State Creations: 0     ]&lt;br /&gt;
@4 pass in on cnmac0 inet proto icmp all icmp-type echoreq code 0&lt;br /&gt;
  [ Evaluations: 8149      Packets: 342       Bytes: 27424       States: 0     ]&lt;br /&gt;
  [ Inserted: uid 0 pid 31812 State Creations: 171   ]&lt;br /&gt;
@5 pass in on cnmac0 inet proto icmp all icmp-type unreach&lt;br /&gt;
  [ Evaluations: 308       Packets: 5         Bytes: 368         States: 0     ]&lt;br /&gt;
  [ Inserted: uid 0 pid 31812 State Creations: 0     ]&lt;br /&gt;
@6 pass in on cnmac0 inet proto ipencap from any to 23.30.150.141&lt;br /&gt;
  [ Evaluations: 8149      Packets: 126197    Bytes: 16538717    States: 5     ]&lt;br /&gt;
  [ Inserted: uid 0 pid 31812 State Creations: 2048  ]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A site can add more elaborate rules as desired.&lt;br /&gt;
&lt;br /&gt;
== Maintaining Mesh Routes with 44ripd ==&lt;br /&gt;
&lt;br /&gt;
The above shows how to set up AMPRNet tunnel interfaces, set routes to them, use routing domains for policy-based routing, and set firewall rules. However, so far all of these steps have been manual. This works for a handful of tunnels and routes, but there are hundreds of subnets AMPRNet in the AMPRNet mesh; maintaining all of these manually is not reasonable.&lt;br /&gt;
&lt;br /&gt;
However, Dan Cross (KZ2X) has written a daemon specific to OpenBSD called &amp;lt;code&amp;gt;44ripd&amp;lt;/code&amp;gt; that maintains tunnel and route information as distributed via the [https://wiki.ampr.org/wiki/RIP AMPRNet RIP] variant sent from &amp;lt;code&amp;gt;44.0.0.1&amp;lt;/code&amp;gt;. To use this, make sure that multicasting is enabled on the host by setting &amp;lt;code&amp;gt;multicast=YES&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;/etc/rc.conf.local&amp;lt;/code&amp;gt;, and then retrieve the 44ripd software from Github at https://github.com/dancrossnyc/44ripd. The software is built with the &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt; command. For example:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;git clone https://github.com/dancrossnyc/44ripd&lt;br /&gt;
cd 44ripd&lt;br /&gt;
make&lt;br /&gt;
doas install -c -o root -g wheel -m 555 44ripd /usr/local/sbin&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once installed, this can be run at boot by adding the following lines to &amp;lt;code&amp;gt;/etc/rc.local&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;if [ -x /usr/local/sbin/44ripd ]; then&lt;br /&gt;
        echo -n &#039; 44ripd&#039;&lt;br /&gt;
        route -T 44 exec /usr/local/sbin/44ripd -s0 -s1 -D 44 -T 23&lt;br /&gt;
fi&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that the &amp;lt;code&amp;gt;-s&amp;lt;/code&amp;gt; options instruct the daemon not to try and allocate the &amp;lt;code&amp;gt;gif0&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;gif1&amp;lt;/code&amp;gt; interfaces, as these are manually configured. The &amp;lt;code&amp;gt;-D&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;-T&amp;lt;/code&amp;gt; options set the routing domains for &#039;&#039;gif&#039;&#039; interfaces and their associated tunnels, respectively.&lt;br /&gt;
&lt;br /&gt;
=== Set the Default AMPRNet Tunnel and Route Manually ===&lt;br /&gt;
&lt;br /&gt;
While route information for the UCSD AMPRNet gateway is distributed in RIP44 packets and we could in theory only configure the default incoming tunnel and rely on 44ripd to set up a route to UCSD, this leads to a problem. Specifically, without an interface configured to the UCSD gateway, we cannot set a default route in our AMRPNet routing domain for the gateway. Since we rely on periodic route broadcasts from UCSD to set those routes, we would delay setting up our default route for an indeterminate amount of time (on the order of minutes).&lt;br /&gt;
&lt;br /&gt;
Thus, it is advised to explicitly configure the tunnel to UCSD at boot time along with the default route.&lt;br /&gt;
&lt;br /&gt;
=== Notes on 44ripd Implementation ===&lt;br /&gt;
&lt;br /&gt;
* 44ripd maintains a copy of the AMPRNet routing table in a modified PATRICIA trie (really a compressed radix tree).&lt;br /&gt;
* A similar table of tunnels is maintained.&lt;br /&gt;
* Tunnel interfaces are reference counted and garbage collected. A bitmap indicating which tunnels are in use is maintained.&lt;br /&gt;
* Routes are expired after receiving a RIP packet.&lt;br /&gt;
* The program is completely self-contained in the sense that it does not fork/exec external commands to configure tunnels or manipulate routes.  That is all done via ioctls or writing messages to a routing socket.&lt;br /&gt;
* 44ripd does not examine the state of the system or routing tables at startup to bootstrap its internal state, but arguably should.&lt;br /&gt;
* Bugs in 44ripd should be reported via Github issues.&lt;br /&gt;
* Exporting and/or parsing an encap file would be nice.&lt;br /&gt;
* Logging and error checking can always be improved.&lt;/div&gt;</summary>
		<author><name>Cross</name></author>
	</entry>
	<entry>
		<id>https://wiki.ampr.org/w/index.php?title=Setting_up_a_gateway_on_OpenBSD&amp;diff=916</id>
		<title>Setting up a gateway on OpenBSD</title>
		<link rel="alternate" type="text/html" href="https://wiki.ampr.org/w/index.php?title=Setting_up_a_gateway_on_OpenBSD&amp;diff=916"/>
		<updated>2021-01-11T17:45:07Z</updated>

		<summary type="html">&lt;p&gt;Cross: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
[https://www.openbsd.org OpenBSD] is a mature Unix-like operating system that focuses on security and correctness. It features a flexible, robust, performant TCP/IP stack and a [https://www.openbsd.org/faq/pf/ highly configurable firewall]. This page describes how to configure a computer running OpenBSD as an AMPRNet router to transfer traffic between AMPRNet subnets and the Internet.&lt;br /&gt;
&lt;br /&gt;
OpenBSD natively supports [https://en.wikipedia.org/wiki/IP_in_IP IPENCAP (IP-IP)] tunnels through [https://man.openbsd.org/gif.4 &#039;&#039;gif&#039;&#039;(4)] pseudo-devices. Each &#039;&#039;gif&#039;&#039; device is a virtual network interface, synthesized by the operating system, that implements a point-to-point tunnel. Unlike Linux, OpenBSD requires a separate &#039;&#039;gif&#039;&#039; interface for each tunnel. An essentially arbitrary number of such interfaces can be created and it scales to the number required to route all of AMPRNet.&lt;br /&gt;
&lt;br /&gt;
One can manually configure &#039;&#039;gif&#039;&#039; tunnels and routes at the command line, or configure the system to establish tunnels and routes at boot time.&lt;br /&gt;
&lt;br /&gt;
We will describe how to set things up by way of example. Assume a system configuration that looks substantially similar to the following:&lt;br /&gt;
&lt;br /&gt;
* A dedicated static IP address to use as an endpoint for AMPRNet traffic.&lt;br /&gt;
* An ISP-provided router that is just a router; no NATing, no firewall.&lt;br /&gt;
* An OpenBSD computer with three ethernet interfaces. For example, using a Ubiquiti EdgeRouter 3 Lite:&lt;br /&gt;
*# cnmac0 is the external interface connected to the ISP&#039;s network (in this example, we use 23.30.150.141 routing to 23.30.150.142)&lt;br /&gt;
*# cnmac1 connects to an internal network (its configuration is irrelevant)&lt;br /&gt;
*# cnmac2 is the internal interface connected to the subnet (in this example, we use 44.44.107.1 routing for 44.44.107.0/24)&lt;br /&gt;
&lt;br /&gt;
Let us start by configuring a single tunnel and route to the AMPRNet gateway at UCSD:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;ifconfig gif1 create&lt;br /&gt;
ifconfig gif1 tunnel 23.30.150.141 169.228.34.84&lt;br /&gt;
ifconfig gif1 inet 44.44.107.1 netmask 255.255.255.255&lt;br /&gt;
route add -host 44.0.0.1 -link -iface gif1 -llinfo&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first command creates the interface, causing the kernel to synthesize it into existence. The second configures the tunnel itself: that is, the the IP addresses that will be put into the IPENCAP datagram that the tunnel creates: the first address is the &#039;&#039;local&#039;&#039; address, which will serve as the source address for the IPENCAP packet, while the second is the &#039;&#039;remote&#039;&#039; address, to which the packet will be sent. The third sets an IP address for the local endpoint of the interface: this exists solely so that traffic that is generated by the router, such as ICMP error messages (host or port unreachable, for example), have a valid source address. Note that despite the fact that this is a point-to-point interface, we do not specify the IP address of the remote end.&lt;br /&gt;
&lt;br /&gt;
The fourth and final command creates a host route and associates it with the tunnel interface. The &amp;lt;code&amp;gt;-link&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;-iface&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;-llinfo&amp;lt;/code&amp;gt; flags indicate that this is an interface route, and that traffic for the route should go directly to the given interface (&amp;lt;code&amp;gt;gif1&amp;lt;/code&amp;gt;) instead of identifying the gateway via an IP address. We can examine this route from the commandline. E.g.,&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;$ route -n show -inet | grep &#039;44\.0\.0\.1 &#039;&lt;br /&gt;
44.0.0.1           link#7             UHLSh      1        2     -     8 gif1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Consult the manual page for [https://man.openbsd.org/netstat.1 &#039;&#039;netstat&#039;&#039;(1)] for details on what the &amp;lt;code&amp;gt;UHLSh&amp;lt;/code&amp;gt; flags mean.&lt;br /&gt;
&lt;br /&gt;
We can repeat this process for each AMPRNet tunnel, creating interfaces and adding routes for each subnet.&lt;br /&gt;
&lt;br /&gt;
== Handling Encapsulated Inbound Traffic Without a Reciprocal Tunnel ==&lt;br /&gt;
&lt;br /&gt;
When an inbound IPENCAP datagram arrives on our external interface, the network stack in the OpenBSD kernel recognizes it by examining the protocol number in the IP header: IPENCAP is protocol number 4 (not to be confused with IP version 4). Any such packets are passed to the packet input function in the &#039;&#039;gif&#039;&#039; implementation, which searches all configured &#039;&#039;gif&#039;&#039; interfaces trying to find match the configured tunnel source and destinations addresses with the corresponding addresses in the inbound packet. If such an interface is found, the packet is enqueued to the interface, which will strip the IPENCAP header and route the resulting &amp;quot;de-encapsulated&amp;quot; IP packet. This works for tunnels that are configured bidirectionally between any two sites. That is, if site A has a tunnel to site B, and B has a corresponding tunnel to A, they can send each other traffic.&lt;br /&gt;
&lt;br /&gt;
Now consider the case where site A has a tunnel configured to send traffic to site B, but B has no tunnel configured to A: in this case, the datagram arrives as before and is presented to the &#039;&#039;gif&#039;&#039; implementation, but the search above fails since B has no tunnel to A, so nothing matches the source &#039;&#039;and&#039;&#039; destination addresses on the incoming packet. In this case, the system might be responsible for routing such packets to another computer or network, so the packet is not de-encapsulated and processed. However, in an AMPRNet context, we very well may want to process that packet. Accordingly, the &#039;&#039;gif&#039;&#039; implementation has a mechanism for describing an interface that accepts encapsulated traffic from any source destined to a local address. If we configure a &#039;&#039;gif&#039;&#039; interface where the distant end of the &#039;&#039;tunnel&#039;&#039; set to &amp;lt;code&amp;gt;0.0.0.0&amp;lt;/code&amp;gt;, then any incoming datagram where the destination address is the same as the local address on the interface, will be accepted and de-encapsulated and processed as before. Using this, we can set up an interface specifically for accepting traffic from systems to which we have not defined a tunnel:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;ifconfig gif0 create&lt;br /&gt;
ifconfig gif0 tunnel 23.30.150.141 0.0.0.0&lt;br /&gt;
ifconfig gif0 inet 44.44.107.1 255.255.255.255&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note the &amp;lt;code&amp;gt;0.0.0.0&amp;lt;/code&amp;gt; as the remote address in the &amp;lt;code&amp;gt;ifconfig tunnel&amp;lt;/code&amp;gt; command. Again, we set an interface address using our local AMPRNet router address purely for locally generated traffic.&lt;br /&gt;
&lt;br /&gt;
One this interface is configured, IPENCAP traffic from remote systems that have defined tunnels to us will flow, regardless of whether we have created a tunnel to them.&lt;br /&gt;
&lt;br /&gt;
== Policy-based Routing Using Routing Domains ==&lt;br /&gt;
&lt;br /&gt;
The configuration explored so far is sufficient to make connections to AMPRNet directly-configured AMPRNet subnets, but suffers from a number of deficiencies. In particular, there are two issues that we will discuss now.&lt;br /&gt;
&lt;br /&gt;
First, there is a problem with exchanging traffic with non-AMPRNet systems on the Internet. Presumably, these systems are not aware of AMPRNet tunneling, so traffic from them goes to the gateway at UCSD, where it will be encapsulated and sent through a tunnel to the external interface on our router. There, it will be de-encapsulated and delivered into our subnet. However, return traffic will be sent to the router, but since the destination is generally a tunnel, it will be sent via the default route, but from an AMPRNet source address. Since most ISPs will not pass AMPRNet traffic, the result will likely be lost before it reaches the destination. We may think it would be possible to work around that using a firewall rule to NAT the source address to something provided by our ISP, but even if the resulting datagram made it to the destination, for a protocol like TCP it would no longer match the 5-tuple for the connection, and would thus be lost.&lt;br /&gt;
&lt;br /&gt;
The second problem is how reaching AMPRNet systems for which we have not configured a tunnel.  Without a tunnel, and thus a route, we cannot send traffic to those systems.&lt;br /&gt;
&lt;br /&gt;
We can solve both of these problems by sending all of our traffic through a tunnel interface to the UCSD gateway by default, e.g., by setting the default route:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;route add default 4.0.0.1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, how does the encapsulated traffic from the tunnel interface get sent to our ISP&#039;s router? We can add a host route for the UCSD gateway in our local routing table, but we have to do this for every tunnel, which is unwieldy. Further, connecting to our external interface becomes complicated: suppose someone &amp;lt;code&amp;gt;ping&amp;lt;/code&amp;gt;s our external interface. Assuming we permit this, the response would be routed through the UCSD gateway tunnel, but even if the gateway passed arbitrary traffic back onto the Internet, the packet might be lost as upstream ISPs would refuse to route it.&lt;br /&gt;
&lt;br /&gt;
The solution to all of these problems is to use [https://en.wikipedia.org/wiki/Policy-based_routing &#039;&#039;policy-based routing&#039;&#039;]. Specifically, we would like to make routing decisions based on the source IP address of our traffic. We might be able to do this with firewall rules, but the edge cases get complicated very quickly. Fortunately, there is another way: [https://man.openbsd.org/rdomain.4 routing domains].&lt;br /&gt;
&lt;br /&gt;
Routing domains in OpenBSD are a mechanism to isolate routing decisions from one another. Network interfaces are configured into exactly one routing domain, which has its own private set of routing tables. Those tables are isolated, but traffic can be passed between routing domains via firewall rules.&lt;br /&gt;
&lt;br /&gt;
In our example, we put our external and local AMPRNet gateway interfaces into separate routing domains: all of the &#039;&#039;gif&#039;&#039; interfaces and the local AMPRNet gateway interface can both be assigned to routing domain 44, while the external interface might be 23. Routing domain 0 is the default. Note that the numbers here are arbitrary, and we can choose any value below 256 that we like; these are chosen to match the first octet of our example addresses.&lt;br /&gt;
&lt;br /&gt;
The routing domain on an interface is set using the &amp;lt;code&amp;gt;rdomain&amp;lt;/code&amp;gt; parameter to &amp;lt;code&amp;gt;ifconfig&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;ifconfig cnmac0 rdomain 23&lt;br /&gt;
ifconfig gif0 rdomain 44&lt;br /&gt;
ifconfig gif1 rdomain 44&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We set the default route in the routing domain that owns our external interface to our ISP&#039;s router, while in the routing domain hosting our AMPRNet presence we can set it to the UCSD gateway:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;route -T 23 add default 23.30.150.242&lt;br /&gt;
route -T 44 add default 44.0.0.1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now traffic on our AMPRNet subnet will be routed through the UCSD gateway, while traffic on the external interface will be routed through our ISP&#039;s router.&lt;br /&gt;
&lt;br /&gt;
Another piece of functionality allows us to dispense with much of the complexity of routing between domains: the tunnel assigned to a &#039;&#039;gif&#039;&#039; can be in a different routing domain than the interface itself. Going back to our example, if we place each of our &#039;&#039;gif&#039;&#039; interfaces into routing domain 44 then traffic routed out to on coming in from the tunnel will be routed with our AMPRNet-specific routing table. But if we place the tunnel on that interface into routing domain 23, then the encapsulated traffic that we send to and from the Internet (e.g., to other tunnel end points) will be routed in that domain, thus routing through our ISP&#039;s network. Critically, matching incoming datagrams to &#039;&#039;gif&#039;&#039; interfaces as described above happens in the routing domain associated with the tunnel, so inbound traffic coming through our external interface will be directed to the correct interface.&lt;br /&gt;
&lt;br /&gt;
We specify the routing domain of a tunnel via the &amp;lt;code&amp;gt;tunneldomain&amp;lt;/code&amp;gt; parameter to &amp;lt;code&amp;gt;ifconfig&amp;lt;/code&amp;gt; when configuring the route on an interface:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;ifconfig gif0 tunnel 23.30.150.141 0.0.0.0 tunneldomain 23&lt;br /&gt;
ifconfig gif1 tunnel 23.30.150.141 169.228.34.84 tunneldomain 23&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With this in place, routing works as expected for all of the cases mentioned above.&lt;br /&gt;
&lt;br /&gt;
== Persistent Configuration Across Router Restarts ==&lt;br /&gt;
&lt;br /&gt;
We now have enough information that we can set up tunnels between our router and arbitrary AMPRNet subnets. However, doing so manually is tedious and not particularly robust. We would like the system to automatically configure our tunnels and default routes at boot time. Fortunately, the OpenBSD startup code can do this easily. For each network interface &amp;lt;code&amp;gt;$if&amp;lt;/code&amp;gt; on the system, we can configure it automatically at boot time by putting configuration commands into the file &amp;lt;code&amp;gt;/etc/hostname.$if&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
There are four interfaces we have configured: the two ethernet interfaces for our external and AMPRNet networks, and the two &#039;&#039;gif&#039;&#039; interfaces with the default incoming tunnel and the tunnel to the UCSD gateway.  Thus, there are four files:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/etc/hostname.cnmac0&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;rdomain 23&lt;br /&gt;
inet 23.30.150.141 0xfffffff8&lt;br /&gt;
!ifconfig lo23 inet 127.0.0.1&lt;br /&gt;
!route -qn -T 23 add default 23.30.150.142&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/etc/hostname.cnmac2&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;rdomain 44&lt;br /&gt;
inet 44.44.107.1 255.255.255.0&lt;br /&gt;
!ifconfig lo44 inet 127.0.0.1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/etc/hostname.gif0&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;rdomain 44&lt;br /&gt;
tunnel 23.30.150.141 0.0.0.0 tunneldomain 23&lt;br /&gt;
inet 44.44.107.1 255.255.255.255&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/etc/hostname.gif1&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;tunnel 23.30.150.141 169.228.34.84 tunneldomain 23&lt;br /&gt;
inet 44.44.107.1 255.255.255.255&lt;br /&gt;
!route -qn -T 44 add 44.0.0.1/32 -link -iface gif1 -llinfo&lt;br /&gt;
!route -qn -T 44 add default 44.0.0.1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that each routing domain also has its own associated loopback interface, hence configuring &amp;lt;code&amp;gt;lo23&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;lo44&amp;lt;/code&amp;gt;. These interfaces are automatically created when the routing domain is created, but we configure them when we bring up the associated ethernet interfaces.&lt;br /&gt;
&lt;br /&gt;
We can examine the interfaces and separate routing tables to ensure that things are set up as expected:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;$ ifconfig cnmac0&lt;br /&gt;
cnmac0: flags=8843&amp;lt;UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST&amp;gt; rdomain 23 mtu 1500&lt;br /&gt;
        lladdr 44:d9:e7:9f:a7:64&lt;br /&gt;
        index 1 priority 0 llprio 3&lt;br /&gt;
        media: Ethernet autoselect (1000baseT full-duplex)&lt;br /&gt;
        status: active&lt;br /&gt;
        inet 23.30.150.141 netmask 0xfffffff8 broadcast 23.30.150.143&lt;br /&gt;
$ ifconfig cnmac2&lt;br /&gt;
cnmac2: flags=8843&amp;lt;UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST&amp;gt; rdomain 44 mtu 1500&lt;br /&gt;
        lladdr 44:d9:e7:9f:a7:66&lt;br /&gt;
        index 3 priority 0 llprio 3&lt;br /&gt;
        media: Ethernet autoselect (1000baseT full-duplex,master)&lt;br /&gt;
        status: active&lt;br /&gt;
        inet 44.44.107.1 netmask 0xffffff00 broadcast 44.44.107.255&lt;br /&gt;
$ ifconfig gif0&lt;br /&gt;
gif0: flags=8051&amp;lt;UP,POINTOPOINT,RUNNING,MULTICAST&amp;gt; rdomain 44 mtu 1280&lt;br /&gt;
        index 6 priority 0 llprio 3&lt;br /&gt;
        encap: txprio payload rxprio payload&lt;br /&gt;
        groups: gif&lt;br /&gt;
        tunnel: inet 23.30.150.141 -&amp;gt; 0.0.0.0 ttl 64 nodf ecn rdomain 23&lt;br /&gt;
        inet 44.44.107.1 --&amp;gt; 0.0.0.0 netmask 0xffffffff&lt;br /&gt;
$ ifconfig gif1&lt;br /&gt;
gif1: flags=8051&amp;lt;UP,POINTOPOINT,RUNNING,MULTICAST&amp;gt; rdomain 44 mtu 1280&lt;br /&gt;
        index 7 priority 0 llprio 3&lt;br /&gt;
        encap: txprio payload rxprio payload&lt;br /&gt;
        groups: gif&lt;br /&gt;
        tunnel: inet 23.30.150.141 -&amp;gt; 169.228.34.84 ttl 64 nodf ecn rdomain 23&lt;br /&gt;
        inet 44.44.107.1 --&amp;gt; 0.0.0.0 netmask 0xffffffff&lt;br /&gt;
$ route -T 23 -n show -inet&lt;br /&gt;
Routing tables&lt;br /&gt;
&lt;br /&gt;
Internet:&lt;br /&gt;
Destination        Gateway            Flags   Refs      Use   Mtu  Prio Iface&lt;br /&gt;
default            23.30.150.142      UGS        0    51126     -     8 cnmac0&lt;br /&gt;
23.30.150.136/29   23.30.150.141      UCn        1        7     -     4 cnmac0&lt;br /&gt;
23.30.150.141      44:d9:e7:9f:a7:64  UHLl       0    88377     -     1 cnmac0&lt;br /&gt;
23.30.150.142      4a:1d:70:de:c3:5a  UHLch      1      386     -     3 cnmac0&lt;br /&gt;
23.30.150.143      23.30.150.141      UHb        0        0     -     1 cnmac0&lt;br /&gt;
127.0.0.1          127.0.0.1          UHl        0        0 32768     1 lo23&lt;br /&gt;
$ route -T 44 -n show -inet&lt;br /&gt;
Routing tables&lt;br /&gt;
&lt;br /&gt;
Internet:&lt;br /&gt;
Destination        Gateway            Flags   Refs      Use   Mtu  Prio Iface&lt;br /&gt;
default            44.0.0.1           UGS        0    54718     -     8 gif1&lt;br /&gt;
44.0.0.1           link#7             UHLSh      1        2     -     8 gif1&lt;br /&gt;
44.44.107/24       44.44.107.1        UCn       16        4     -     4 cnmac2&lt;br /&gt;
44.44.107.1        44:d9:e7:9f:a7:66  UHLl       0     4825     -     1 cnmac2&lt;br /&gt;
44.44.107.255      44.44.107.1        UHb        0        0     -     1 cnmac2&lt;br /&gt;
127.0.0.1          127.0.0.1          UHl        0        0 32768     1 lo44&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Restricting Traffic with the [https://www.openbsd.org/faq/pf/ PF] Firewall ==&lt;br /&gt;
&lt;br /&gt;
All of these interfaces will fully integrate with the PF firewall software that comes with OpenBSD, and we can implement nearly arbitrary policies in our configuration.  For example, we might restrict traffic on the external interface to only ICMP messages and IPENCAP datagrams by setting the following rules in &amp;lt;code&amp;gt;/etc/pf.conf&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;# Constants&lt;br /&gt;
extif = &amp;quot;cnmac0&amp;quot;&lt;br /&gt;
extamprgate = &amp;quot;23.30.150.141&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Options&lt;br /&gt;
set skip on lo&lt;br /&gt;
set block-policy return&lt;br /&gt;
&lt;br /&gt;
block return    # block stateless traffic&lt;br /&gt;
pass            # establish keep-state&lt;br /&gt;
&lt;br /&gt;
# Normalize incoming packets.&lt;br /&gt;
match in all scrub (no-df random-id max-mss 1440)&lt;br /&gt;
&lt;br /&gt;
# By default, block everything.  We selectively override in subsequent rules.&lt;br /&gt;
block in on $extif&lt;br /&gt;
&lt;br /&gt;
# Pass 44net traffic&lt;br /&gt;
pass in on $extif inet proto ipencap from any to $extamprgate&lt;br /&gt;
&lt;br /&gt;
# Pass ping and ICMP unreachable messages on external interface&lt;br /&gt;
pass in on $extif inet proto icmp icmp-type echoreq code 0 keep state&lt;br /&gt;
pass in on $extif inet proto icmp icmp-type unreach keep state&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We can verify that these rules are in place as expected by querying the rule tables:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;# pfctl -sr -vv&lt;br /&gt;
@0 block return all&lt;br /&gt;
  [ Evaluations: 115977    Packets: 3776      Bytes: 168422      States: 0     ]&lt;br /&gt;
  [ Inserted: uid 0 pid 31812 State Creations: 0     ]&lt;br /&gt;
@1 pass all flags S/SA&lt;br /&gt;
  [ Evaluations: 115977    Packets: 242418    Bytes: 25899015    States: 253   ]&lt;br /&gt;
  [ Inserted: uid 0 pid 31812 State Creations: 102105]&lt;br /&gt;
@2 match in all scrub (no-df random-id max-mss 1440)&lt;br /&gt;
  [ Evaluations: 115977    Packets: 261105    Bytes: 31394491    States: 136   ]&lt;br /&gt;
  [ Inserted: uid 0 pid 31812 State Creations: 0     ]&lt;br /&gt;
@3 block return in on cnmac0 all&lt;br /&gt;
  [ Evaluations: 64726     Packets: 5925      Bytes: 325492      States: 0     ]&lt;br /&gt;
  [ Inserted: uid 0 pid 31812 State Creations: 0     ]&lt;br /&gt;
@4 pass in on cnmac0 inet proto icmp all icmp-type echoreq code 0&lt;br /&gt;
  [ Evaluations: 8149      Packets: 342       Bytes: 27424       States: 0     ]&lt;br /&gt;
  [ Inserted: uid 0 pid 31812 State Creations: 171   ]&lt;br /&gt;
@5 pass in on cnmac0 inet proto icmp all icmp-type unreach&lt;br /&gt;
  [ Evaluations: 308       Packets: 5         Bytes: 368         States: 0     ]&lt;br /&gt;
  [ Inserted: uid 0 pid 31812 State Creations: 0     ]&lt;br /&gt;
@6 pass in on cnmac0 inet proto ipencap from any to 23.30.150.141&lt;br /&gt;
  [ Evaluations: 8149      Packets: 126197    Bytes: 16538717    States: 5     ]&lt;br /&gt;
  [ Inserted: uid 0 pid 31812 State Creations: 2048  ]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A site can add more elaborate rules as desired.&lt;br /&gt;
&lt;br /&gt;
== Maintaining Mesh Routes with 44ripd ==&lt;br /&gt;
&lt;br /&gt;
The above shows how to set up AMPRNet tunnel interfaces, set routes to them, use routing domains for policy-based routing, and set firewall rules. However, so far all of these steps have been manual. This works for a handful of tunnels and routes, but there are hundreds of subnets AMPRNet in the AMPRNet mesh; maintaining all of these manually is not reasonable.&lt;br /&gt;
&lt;br /&gt;
However, Dan Cross (KZ2X) has written a daemon specific to OpenBSD called &amp;lt;code&amp;gt;44ripd&amp;lt;/code&amp;gt; that maintains tunnel and route information as distributed via the [https://wiki.ampr.org/wiki/RIP AMPRNet RIP] variant sent from &amp;lt;code&amp;gt;44.0.0.1&amp;lt;/code. To use this, make sure that multicasting is enabled on the host by setting &amp;lt;code&amp;gt;multicast=YES&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;/etc/rc.conf.local&amp;lt;/code&amp;gt;, and then retrieve the 44ripd software from Github at https://github.com/dancrossnyc/44ripd. The software is built with the &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt; command. For example:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;git clone https://github.com/dancrossnyc/44ripd&lt;br /&gt;
cd 44ripd&lt;br /&gt;
make&lt;br /&gt;
doas install -c -o root -g wheel -m 555 44ripd /usr/local/sbin&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once installed, this can be run at boot by adding the following lines to &amp;lt;code&amp;gt;/etc/rc.local&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;if [ -x /usr/local/sbin/44ripd ]; then&lt;br /&gt;
        echo -n &#039; 44ripd&#039;&lt;br /&gt;
        route -T 44 exec /usr/local/sbin/44ripd -s0 -s1 -D 44 -T 23&lt;br /&gt;
fi&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that the &amp;lt;code&amp;gt;-s&amp;lt;/code&amp;gt; options instruct the daemon not to try and allocate the &amp;lt;code&amp;gt;gif0&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;gif1&amp;lt;/code&amp;gt; interfaces, as these are manually configured. The &amp;lt;code&amp;gt;-D&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;-T&amp;lt;/code&amp;gt; options set the routing domains for &#039;&#039;gif&#039;&#039; interfaces and their associated tunnels, respectively.&lt;br /&gt;
&lt;br /&gt;
=== Set the Default AMPRNet Tunnel and Route Manually ===&lt;br /&gt;
&lt;br /&gt;
While route information for the UCSD AMPRNet gateway is distributed in RIP44 packets and we could in theory only configure the default incoming tunnel and rely on 44ripd to set up a route to UCSD, this leads to a problem. Specifically, without an interface configured to the UCSD gateway, we cannot set a default route in our AMRPNet routing domain for the gateway. Since we rely on periodic route broadcasts from UCSD to set those routes, we would delay setting up our default route for an indeterminate amount of time (on the order of minutes).&lt;br /&gt;
&lt;br /&gt;
Thus, it is advised to explicitly configure the tunnel to UCSD at boot time along with the default route.&lt;br /&gt;
&lt;br /&gt;
=== Notes on 44ripd Implementation ===&lt;br /&gt;
&lt;br /&gt;
* 44ripd maintains a copy of the AMPRNet routing table in a modified PATRICIA trie (really a compressed radix tree).&lt;br /&gt;
* A similar table of tunnels is maintained.&lt;br /&gt;
* Tunnel interfaces are reference counted and garbage collected. A bitmap indicating which tunnels are in use is maintained.&lt;br /&gt;
* Routes are expired after receiving a RIP packet.&lt;br /&gt;
* The program is completely self-contained in the sense that it does not fork/exec external commands to configure tunnels or manipulate routes.  That is all done via ioctls or writing messages to a routing socket.&lt;br /&gt;
* 44ripd does not examine the state of the system or routing tables at startup to bootstrap its internal state, but arguably should.&lt;br /&gt;
* Bugs in 44ripd should be reported via Github issues.&lt;br /&gt;
* Exporting and/or parsing an encap file would be nice.&lt;br /&gt;
* Logging and error checking can always be improved.&lt;/div&gt;</summary>
		<author><name>Cross</name></author>
	</entry>
	<entry>
		<id>https://wiki.ampr.org/w/index.php?title=Setting_up_a_gateway_on_OpenBSD&amp;diff=915</id>
		<title>Setting up a gateway on OpenBSD</title>
		<link rel="alternate" type="text/html" href="https://wiki.ampr.org/w/index.php?title=Setting_up_a_gateway_on_OpenBSD&amp;diff=915"/>
		<updated>2021-01-11T17:32:22Z</updated>

		<summary type="html">&lt;p&gt;Cross: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
[https://www.openbsd.org OpenBSD] is a mature Unix-like operating system that focuses on security and correctness. It features a flexible, robust, performant TCP/IP stack and a [https://www.openbsd.org/faq/pf/ highly configurable firewall]. This page describes how to configure a computer running OpenBSD as an AMPRNet router to transfer traffic between AMPRNet subnets and the Internet.&lt;br /&gt;
&lt;br /&gt;
OpenBSD natively supports [https://en.wikipedia.org/wiki/IP_in_IP IPENCAP (IP-IP)] tunnels through [https://man.openbsd.org/gif.4 &#039;&#039;gif&#039;&#039;(4)] pseudo-devices. Each &#039;&#039;gif&#039;&#039; device is a virtual network interface, synthesized by the operating system, that implements a point-to-point tunnel. Unlike Linux, OpenBSD requires a separate &#039;&#039;gif&#039;&#039; interface for each tunnel. An essentially arbitrary number of such interfaces can be created and it scales to the number required to route all of AMPRNet.&lt;br /&gt;
&lt;br /&gt;
One can manually configure &#039;&#039;gif&#039;&#039; tunnels and routes at the command line, or configure the system to establish tunnels and routes at boot time.&lt;br /&gt;
&lt;br /&gt;
We will describe how to set things up by way of example. Assume a system configuration that looks substantially similar to the following:&lt;br /&gt;
&lt;br /&gt;
* A dedicated static IP address to use as an endpoint for AMPRNet traffic.&lt;br /&gt;
* An ISP-provided router that is just a router; no NATing, no firewall.&lt;br /&gt;
* An OpenBSD computer with three ethernet interfaces. For example, using a Ubiquiti EdgeRouter 3 Lite:&lt;br /&gt;
*# cnmac0 is the external interface connected to the ISP&#039;s network (in this example, we use 23.30.150.141 routing to 23.30.150.142)&lt;br /&gt;
*# cnmac1 connects to an internal network (its configuration is irrelevant)&lt;br /&gt;
*# cnmac2 is the internal interface connected to the subnet (in this example, we use 44.44.107.1 routing for 44.44.107.0/24)&lt;br /&gt;
&lt;br /&gt;
Let us start by configuring a single tunnel and route to the AMPRNet gateway at UCSD:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;ifconfig gif1 create&lt;br /&gt;
ifconfig gif1 tunnel 23.30.150.141 169.228.34.84&lt;br /&gt;
ifconfig gif1 inet 44.44.107.1 netmask 255.255.255.255&lt;br /&gt;
route add -host 44.0.0.1 -link -iface gif1 -llinfo&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first command creates the interface, causing the kernel to synthesize it into existence. The second configures the tunnel itself: that is, the the IP addresses that will be put into the IPENCAP datagram that the tunnel creates: the first address is the &#039;&#039;local&#039;&#039; address, which will serve as the source address for the IPENCAP packet, while the second is the &#039;&#039;remote&#039;&#039; address, to which the packet will be sent. The third sets an IP address for the local endpoint of the interface: this exists solely so that traffic that is generated by the router, such as ICMP error messages (host or port unreachable, for example), have a valid source address. Note that despite the fact that this is a point-to-point interface, we do not specify the IP address of the remote end.&lt;br /&gt;
&lt;br /&gt;
The fourth and final command creates a host route and associates it with the tunnel interface. The &amp;lt;code&amp;gt;-link&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;-iface&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;-llinfo&amp;lt;/code&amp;gt; flags indicate that this is an interface route, and that traffic for the route should go directly to the given interface (&amp;lt;code&amp;gt;gif1&amp;lt;/code&amp;gt;) instead of identifying the gateway via an IP address. We can examine this route from the commandline. E.g.,&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;$ route -n show -inet | grep &#039;44\.0\.0\.1 &#039;&lt;br /&gt;
44.0.0.1           link#7             UHLSh      1        2     -     8 gif1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Consult the manual page for [https://man.openbsd.org/netstat.1 &#039;&#039;netstat&#039;&#039;(1)] for details on what the &amp;lt;code&amp;gt;UHLSh&amp;lt;/code&amp;gt; flags mean.&lt;br /&gt;
&lt;br /&gt;
We can repeat this process for each AMPRNet tunnel, creating interfaces and adding routes for each subnet.&lt;br /&gt;
&lt;br /&gt;
== Handling Encapsulated Inbound Traffic Without a Reciprocal Tunnel ==&lt;br /&gt;
&lt;br /&gt;
When an inbound IPENCAP datagram arrives on our external interface, the network stack in the OpenBSD kernel recognizes it by examining the protocol number in the IP header: IPENCAP is protocol number 4 (not to be confused with IP version 4). Any such packets are passed to the packet input function in the &#039;&#039;gif&#039;&#039; implementation, which searches all configured &#039;&#039;gif&#039;&#039; interfaces trying to find match the configured tunnel source and destinations addresses with the corresponding addresses in the inbound packet. If such an interface is found, the packet is enqueued to the interface, which will strip the IPENCAP header and route the resulting &amp;quot;de-encapsulated&amp;quot; IP packet. This works for tunnels that are configured bidirectionally between any two sites. That is, if site A has a tunnel to site B, and B has a corresponding tunnel to A, they can send each other traffic.&lt;br /&gt;
&lt;br /&gt;
Now consider the case where site A has a tunnel configured to send traffic to site B, but B has no tunnel configured to A: in this case, the datagram arrives as before and is presented to the &#039;&#039;gif&#039;&#039; implementation, but the search above fails since B has no tunnel to A, so nothing matches the source &#039;&#039;and&#039;&#039; destination addresses on the incoming packet. In this case, the system might be responsible for routing such packets to another computer or network, so the packet is not de-encapsulated and processed. However, in an AMPRNet context, we very well may want to process that packet. Accordingly, the &#039;&#039;gif&#039;&#039; implementation has a mechanism for describing an interface that accepts encapsulated traffic from any source destined to a local address. If we configure a &#039;&#039;gif&#039;&#039; interface where the distant end of the &#039;&#039;tunnel&#039;&#039; set to &amp;lt;code&amp;gt;0.0.0.0&amp;lt;/code&amp;gt;, then any incoming datagram where the destination address is the same as the local address on the interface, will be accepted and de-encapsulated and processed as before. Using this, we can set up an interface specifically for accepting traffic from systems to which we have not defined a tunnel:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;ifconfig gif0 create&lt;br /&gt;
ifconfig gif0 tunnel 23.30.150.141 0.0.0.0&lt;br /&gt;
ifconfig gif0 inet 44.44.107.1 255.255.255.255&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note the &amp;lt;code&amp;gt;0.0.0.0&amp;lt;/code&amp;gt; as the remote address in the &amp;lt;code&amp;gt;ifconfig tunnel&amp;lt;/code&amp;gt; command. Again, we set an interface address using our local AMPRNet router address purely for locally generated traffic.&lt;br /&gt;
&lt;br /&gt;
One this interface is configured, IPENCAP traffic from remote systems that have defined tunnels to us will flow, regardless of whether we have created a tunnel to them.&lt;br /&gt;
&lt;br /&gt;
== Policy-based Routing Using Routing Domains ==&lt;br /&gt;
&lt;br /&gt;
The configuration explored so far is sufficient to make connections to AMPRNet directly-configured AMPRNet subnets, but suffers from a number of deficiencies. In particular, there are two issues that we will discuss now.&lt;br /&gt;
&lt;br /&gt;
First, there is a problem with exchanging traffic with non-AMPRNet systems on the Internet. Presumably, these systems are not aware of AMPRNet tunneling, so traffic from them goes to the gateway at UCSD, where it will be encapsulated and sent through a tunnel to the external interface on our router. There, it will be de-encapsulated and delivered into our subnet. However, return traffic will be sent to the router, but since the destination is generally a tunnel, it will be sent via the default route, but from an AMPRNet source address. Since most ISPs will not pass AMPRNet traffic, the result will likely be lost before it reaches the destination. We may think it would be possible to work around that using a firewall rule to NAT the source address to something provided by our ISP, but even if the resulting datagram made it to the destination, for a protocol like TCP it would no longer match the 5-tuple for the connection, and would thus be lost.&lt;br /&gt;
&lt;br /&gt;
The second problem is how reaching AMPRNet systems for which we have not configured a tunnel.  Without a tunnel, and thus a route, we cannot send traffic to those systems.&lt;br /&gt;
&lt;br /&gt;
We can solve both of these problems by sending all of our traffic through a tunnel interface to the UCSD gateway by default, e.g., by setting the default route:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;route add default 4.0.0.1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, how does the encapsulated traffic from the tunnel interface get sent to our ISP&#039;s router? We can add a host route for the UCSD gateway in our local routing table, but we have to do this for every tunnel, which is unwieldy. Further, connecting to our external interface becomes complicated: suppose someone &amp;lt;code&amp;gt;ping&amp;lt;/code&amp;gt;s our external interface. Assuming we permit this, the response would be routed through the UCSD gateway tunnel, but even if the gateway passed arbitrary traffic back onto the Internet, the packet might be lost as upstream ISPs would refuse to route it.&lt;br /&gt;
&lt;br /&gt;
The solution to all of these problems is to use [https://en.wikipedia.org/wiki/Policy-based_routing &#039;&#039;policy-based routing&#039;&#039;]. Specifically, we would like to make routing decisions based on the source IP address of our traffic. We might be able to do this with firewall rules, but the edge cases get complicated very quickly. Fortunately, there is another way: [https://man.openbsd.org/rdomain.4 routing domains].&lt;br /&gt;
&lt;br /&gt;
Routing domains in OpenBSD are a mechanism to isolate routing decisions from one another. Network interfaces are configured into exactly one routing domain, which has its own private set of routing tables. Those tables are isolated, but traffic can be passed between routing domains via firewall rules.&lt;br /&gt;
&lt;br /&gt;
In our example, we put our external and local AMPRNet gateway interfaces into separate routing domains: all of the &#039;&#039;gif&#039;&#039; interfaces and the local AMPRNet gateway interface can both be assigned to routing domain 44, while the external interface might be 23. Routing domain 0 is the default. Note that the numbers here are arbitrary, and we can choose any value below 256 that we like; these are chosen to match the first octet of our example addresses.&lt;br /&gt;
&lt;br /&gt;
The routing domain on an interface is set using the &amp;lt;code&amp;gt;rdomain&amp;lt;/code&amp;gt; parameter to &amp;lt;code&amp;gt;ifconfig&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;ifconfig cnmac0 rdomain 23&lt;br /&gt;
ifconfig gif0 rdomain 44&lt;br /&gt;
ifconfig gif1 rdomain 44&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We set the default route in the routing domain that owns our external interface to our ISP&#039;s router, while in the routing domain hosting our AMPRNet presence we can set it to the UCSD gateway:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;route -T 23 add default 23.30.150.242&lt;br /&gt;
route -T 44 add default 44.0.0.1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now traffic on our AMPRNet subnet will be routed through the UCSD gateway, while traffic on the external interface will be routed through our ISP&#039;s router.&lt;br /&gt;
&lt;br /&gt;
Another piece of functionality allows us to dispense with much of the complexity of routing between domains: the tunnel assigned to a &#039;&#039;gif&#039;&#039; can be in a different routing domain than the interface itself. Going back to our example, if we place each of our &#039;&#039;gif&#039;&#039; interfaces into routing domain 44 then traffic routed out to on coming in from the tunnel will be routed with our AMPRNet-specific routing table. But if we place the tunnel on that interface into routing domain 23, then the encapsulated traffic that we send to and from the Internet (e.g., to other tunnel end points) will be routed in that domain, thus routing through our ISP&#039;s network. Critically, matching incoming datagrams to &#039;&#039;gif&#039;&#039; interfaces as described above happens in the routing domain associated with the tunnel, so inbound traffic coming through our external interface will be directed to the correct interface.&lt;br /&gt;
&lt;br /&gt;
We specify the routing domain of a tunnel via the &amp;lt;code&amp;gt;tunneldomain&amp;lt;/code&amp;gt; parameter to &amp;lt;code&amp;gt;ifconfig&amp;lt;/code&amp;gt; when configuring the route on an interface:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;ifconfig gif0 tunnel 23.30.150.141 0.0.0.0 tunneldomain 23&lt;br /&gt;
ifconfig gif1 tunnel 23.30.150.141 169.228.34.84 tunneldomain 23&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With this in place, routing works as expected for all of the cases mentioned above.&lt;br /&gt;
&lt;br /&gt;
== Persistent Configuration Across Router Restarts ==&lt;br /&gt;
&lt;br /&gt;
We now have enough information that we can set up tunnels between our router and arbitrary AMPRNet subnets. However, doing so manually is tedious and not particularly robust. We would like the system to automatically configure our tunnels and default routes at boot time. Fortunately, the OpenBSD startup code can do this easily. For each network interface &amp;lt;code&amp;gt;$if&amp;lt;/code&amp;gt; on the system, we can configure it automatically at boot time by putting configuration commands into the file &amp;lt;code&amp;gt;/etc/hostname.$if&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
There are four interfaces we have configured: the two ethernet interfaces for our external and AMPRNet networks, and the two &#039;&#039;gif&#039;&#039; interfaces with the default incoming tunnel and the tunnel to the UCSD gateway.  Thus, there are four files:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/etc/hostname.cnmac0&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;rdomain 23&lt;br /&gt;
inet 23.30.150.141 0xfffffff8&lt;br /&gt;
!ifconfig lo23 inet 127.0.0.1&lt;br /&gt;
!route -qn -T 23 add default 23.30.150.142&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/etc/hostname.cnmac2&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;rdomain 44&lt;br /&gt;
inet 44.44.107.1 255.255.255.0&lt;br /&gt;
!ifconfig lo44 inet 127.0.0.1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/etc/hostname.gif0&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;rdomain 44&lt;br /&gt;
tunnel 23.30.150.141 0.0.0.0 tunneldomain 23&lt;br /&gt;
inet 44.44.107.1 255.255.255.255&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/etc/hostname.gif1&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;tunnel 23.30.150.141 169.228.34.84 tunneldomain 23&lt;br /&gt;
inet 44.44.107.1 255.255.255.255&lt;br /&gt;
!route -qn -T 44 add 44.0.0.1/32 -link -iface gif1 -llinfo&lt;br /&gt;
!route -qn -T 44 add default 44.0.0.1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that each routing domain also has its own associated loopback interface, hence configuring &amp;lt;code&amp;gt;lo23&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;lo44&amp;lt;/code&amp;gt;. These interfaces are automatically created when the routing domain is created, but we configure them when we bring up the associated ethernet interfaces.&lt;br /&gt;
&lt;br /&gt;
We can examine the interfaces and separate routing tables to ensure that things are set up as expected:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;$ ifconfig cnmac0&lt;br /&gt;
cnmac0: flags=8843&amp;lt;UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST&amp;gt; rdomain 23 mtu 1500&lt;br /&gt;
        lladdr 44:d9:e7:9f:a7:64&lt;br /&gt;
        index 1 priority 0 llprio 3&lt;br /&gt;
        media: Ethernet autoselect (1000baseT full-duplex)&lt;br /&gt;
        status: active&lt;br /&gt;
        inet 23.30.150.141 netmask 0xfffffff8 broadcast 23.30.150.143&lt;br /&gt;
$ ifconfig cnmac2&lt;br /&gt;
cnmac2: flags=8843&amp;lt;UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST&amp;gt; rdomain 44 mtu 1500&lt;br /&gt;
        lladdr 44:d9:e7:9f:a7:66&lt;br /&gt;
        index 3 priority 0 llprio 3&lt;br /&gt;
        media: Ethernet autoselect (1000baseT full-duplex,master)&lt;br /&gt;
        status: active&lt;br /&gt;
        inet 44.44.107.1 netmask 0xffffff00 broadcast 44.44.107.255&lt;br /&gt;
$ ifconfig gif0&lt;br /&gt;
gif0: flags=8051&amp;lt;UP,POINTOPOINT,RUNNING,MULTICAST&amp;gt; rdomain 44 mtu 1280&lt;br /&gt;
        index 6 priority 0 llprio 3&lt;br /&gt;
        encap: txprio payload rxprio payload&lt;br /&gt;
        groups: gif&lt;br /&gt;
        tunnel: inet 23.30.150.141 -&amp;gt; 0.0.0.0 ttl 64 nodf ecn rdomain 23&lt;br /&gt;
        inet 44.44.107.1 --&amp;gt; 0.0.0.0 netmask 0xffffffff&lt;br /&gt;
$ ifconfig gif1&lt;br /&gt;
gif1: flags=8051&amp;lt;UP,POINTOPOINT,RUNNING,MULTICAST&amp;gt; rdomain 44 mtu 1280&lt;br /&gt;
        index 7 priority 0 llprio 3&lt;br /&gt;
        encap: txprio payload rxprio payload&lt;br /&gt;
        groups: gif&lt;br /&gt;
        tunnel: inet 23.30.150.141 -&amp;gt; 169.228.34.84 ttl 64 nodf ecn rdomain 23&lt;br /&gt;
        inet 44.44.107.1 --&amp;gt; 0.0.0.0 netmask 0xffffffff&lt;br /&gt;
$ route -T 23 -n show -inet&lt;br /&gt;
Routing tables&lt;br /&gt;
&lt;br /&gt;
Internet:&lt;br /&gt;
Destination        Gateway            Flags   Refs      Use   Mtu  Prio Iface&lt;br /&gt;
default            23.30.150.142      UGS        0    51126     -     8 cnmac0&lt;br /&gt;
23.30.150.136/29   23.30.150.141      UCn        1        7     -     4 cnmac0&lt;br /&gt;
23.30.150.141      44:d9:e7:9f:a7:64  UHLl       0    88377     -     1 cnmac0&lt;br /&gt;
23.30.150.142      4a:1d:70:de:c3:5a  UHLch      1      386     -     3 cnmac0&lt;br /&gt;
23.30.150.143      23.30.150.141      UHb        0        0     -     1 cnmac0&lt;br /&gt;
127.0.0.1          127.0.0.1          UHl        0        0 32768     1 lo23&lt;br /&gt;
$ route -T 44 -n show -inet&lt;br /&gt;
Routing tables&lt;br /&gt;
&lt;br /&gt;
Internet:&lt;br /&gt;
Destination        Gateway            Flags   Refs      Use   Mtu  Prio Iface&lt;br /&gt;
default            44.0.0.1           UGS        0    54718     -     8 gif1&lt;br /&gt;
44.0.0.1           link#7             UHLSh      1        2     -     8 gif1&lt;br /&gt;
44.44.107/24       44.44.107.1        UCn       16        4     -     4 cnmac2&lt;br /&gt;
44.44.107.1        44:d9:e7:9f:a7:66  UHLl       0     4825     -     1 cnmac2&lt;br /&gt;
44.44.107.255      44.44.107.1        UHb        0        0     -     1 cnmac2&lt;br /&gt;
127.0.0.1          127.0.0.1          UHl        0        0 32768     1 lo44&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Restricting Traffic with the [https://www.openbsd.org/faq/pf/ PF] Firewall ==&lt;br /&gt;
&lt;br /&gt;
All of these interfaces will fully integrate with the PF firewall software that comes with OpenBSD, and we can implement nearly arbitrary policies in our configuration.  For example, we might restrict traffic on the external interface to only ICMP messages and IPENCAP datagrams by setting the following rules in &amp;lt;code&amp;gt;/etc/pf.conf&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;# Constants&lt;br /&gt;
extif = &amp;quot;cnmac0&amp;quot;&lt;br /&gt;
extamprgate = &amp;quot;23.30.150.141&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Options&lt;br /&gt;
set skip on lo&lt;br /&gt;
set block-policy return&lt;br /&gt;
&lt;br /&gt;
block return    # block stateless traffic&lt;br /&gt;
pass            # establish keep-state&lt;br /&gt;
&lt;br /&gt;
# Normalize incoming packets.&lt;br /&gt;
match in all scrub (no-df random-id max-mss 1440)&lt;br /&gt;
&lt;br /&gt;
# By default, block everything.  We selectively override in subsequent rules.&lt;br /&gt;
block in on $extif&lt;br /&gt;
&lt;br /&gt;
# Pass 44net traffic&lt;br /&gt;
pass in on $extif inet proto ipencap from any to $extamprgate&lt;br /&gt;
&lt;br /&gt;
# Pass ping and ICMP unreachable messages on external interface&lt;br /&gt;
pass in on $extif inet proto icmp icmp-type echoreq code 0 keep state&lt;br /&gt;
pass in on $extif inet proto icmp icmp-type unreach keep state&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We can verify that these rules are in place as expected by querying the rule tables:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;# pfctl -sr -vv&lt;br /&gt;
@0 block return all&lt;br /&gt;
  [ Evaluations: 115977    Packets: 3776      Bytes: 168422      States: 0     ]&lt;br /&gt;
  [ Inserted: uid 0 pid 31812 State Creations: 0     ]&lt;br /&gt;
@1 pass all flags S/SA&lt;br /&gt;
  [ Evaluations: 115977    Packets: 242418    Bytes: 25899015    States: 253   ]&lt;br /&gt;
  [ Inserted: uid 0 pid 31812 State Creations: 102105]&lt;br /&gt;
@2 match in all scrub (no-df random-id max-mss 1440)&lt;br /&gt;
  [ Evaluations: 115977    Packets: 261105    Bytes: 31394491    States: 136   ]&lt;br /&gt;
  [ Inserted: uid 0 pid 31812 State Creations: 0     ]&lt;br /&gt;
@3 block return in on cnmac0 all&lt;br /&gt;
  [ Evaluations: 64726     Packets: 5925      Bytes: 325492      States: 0     ]&lt;br /&gt;
  [ Inserted: uid 0 pid 31812 State Creations: 0     ]&lt;br /&gt;
@4 pass in on cnmac0 inet proto icmp all icmp-type echoreq code 0&lt;br /&gt;
  [ Evaluations: 8149      Packets: 342       Bytes: 27424       States: 0     ]&lt;br /&gt;
  [ Inserted: uid 0 pid 31812 State Creations: 171   ]&lt;br /&gt;
@5 pass in on cnmac0 inet proto icmp all icmp-type unreach&lt;br /&gt;
  [ Evaluations: 308       Packets: 5         Bytes: 368         States: 0     ]&lt;br /&gt;
  [ Inserted: uid 0 pid 31812 State Creations: 0     ]&lt;br /&gt;
@6 pass in on cnmac0 inet proto ipencap from any to 23.30.150.141&lt;br /&gt;
  [ Evaluations: 8149      Packets: 126197    Bytes: 16538717    States: 5     ]&lt;br /&gt;
  [ Inserted: uid 0 pid 31812 State Creations: 2048  ]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A site can add more elaborate rules as desired.&lt;br /&gt;
&lt;br /&gt;
== Maintaining Mesh Routes with 44ripd ==&lt;br /&gt;
&lt;br /&gt;
The above shows how to set up AMPRNet tunnel interfaces, set routes to them, use routing domains for policy-based routing, and set firewall rules. However, so far all of these steps have been manual. This works for a handful of tunnels and routes, but there are hundreds of subnets AMPRNet in the AMPRNet mesh; maintaining all of these manually is not reasonable.&lt;br /&gt;
&lt;br /&gt;
However, Dan Cross (KZ2X) has written a daemon specific to OpenBSD called &amp;lt;code&amp;gt;44ripd&amp;lt;/code&amp;gt; that maintains tunnel and route information as distributed via the [https://wiki.ampr.org/wiki/RIP AMPRNet RIP] variant sent from &amp;lt;code&amp;gt;44.0.0.1&amp;lt;/code. To use this, make sure that multicasting is enabled on the host by setting &amp;lt;code&amp;gt;multicast=YES&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;/etc/rc.conf.local&amp;lt;/code&amp;gt;, and then retrieve the 44ripd software from Github at https://github.com/dancrossnyc/44ripd. The software is built with the &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt; command. For example:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;git clone https://github.com/dancrossnyc/44ripd&lt;br /&gt;
cd 44ripd&lt;br /&gt;
make&lt;br /&gt;
doas install -c -o root -g wheel -m 555 44ripd /usr/local/sbin&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once installed, this can be run at boot by adding the following lines to &amp;lt;code&amp;gt;/etc/rc.local&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;if [ -x /usr/local/sbin/44ripd ]; then&lt;br /&gt;
        echo -n &#039; 44ripd&#039;&lt;br /&gt;
        route -T 44 exec /usr/local/sbin/44ripd -s0 -s1 -D 44 -T 23&lt;br /&gt;
fi&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that the &amp;lt;code&amp;gt;-s&amp;lt;/code&amp;gt; options instruct the daemon not to try and allocate the &amp;lt;code&amp;gt;gif0&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;gif1&amp;lt;/code&amp;gt; interfaces, as these are manually configured.&lt;br /&gt;
&lt;br /&gt;
=== Set the Default AMPRNet Tunnel and Route Manually ===&lt;br /&gt;
&lt;br /&gt;
While route information for the UCSD AMPRNet gateway is distributed in RIP44 packets and we could in theory only configure the default incoming tunnel and rely on 44ripd to set up a route to UCSD, this leads to a problem. Specifically, without an interface configured to the UCSD gateway, we cannot set a default route in our AMRPNet routing domain for the gateway. Since we rely on periodic route broadcasts from UCSD to set those routes, we would delay setting up our default route for an indeterminate amount of time (on the order of minutes).&lt;br /&gt;
&lt;br /&gt;
Thus, it is advised to explicitly configure the tunnel to UCSD at boot time along with the default route.&lt;br /&gt;
&lt;br /&gt;
=== Notes on 44ripd Implementation ===&lt;br /&gt;
&lt;br /&gt;
* 44ripd maintains a copy of the AMPRNet routing table in a modified PATRICIA trie (really a compressed radix tree).&lt;br /&gt;
* A similar table of tunnels is maintained.&lt;br /&gt;
* Tunnel interfaces are reference counted and garbage collected. A bitmap indicating which tunnels are in use is maintained.&lt;br /&gt;
* Routes are expired after receiving a RIP packet.&lt;br /&gt;
* The program is completely self-contained in the sense that it does not fork/exec external commands to configure tunnels or manipulate routes.  That is all done via ioctls or writing messages to a routing socket.&lt;br /&gt;
* 44ripd does not examine the state of the system or routing tables at startup to bootstrap its internal state, but arguably should.&lt;br /&gt;
* Bugs in 44ripd should be reported via Github issues.&lt;br /&gt;
* Exporting and/or parsing an encap file would be nice.&lt;br /&gt;
* Logging and error checking can always be improved.&lt;/div&gt;</summary>
		<author><name>Cross</name></author>
	</entry>
	<entry>
		<id>https://wiki.ampr.org/w/index.php?title=Announcing_your_allocation_directly&amp;diff=914</id>
		<title>Announcing your allocation directly</title>
		<link rel="alternate" type="text/html" href="https://wiki.ampr.org/w/index.php?title=Announcing_your_allocation_directly&amp;diff=914"/>
		<updated>2021-01-09T00:42:54Z</updated>

		<summary type="html">&lt;p&gt;Cross: Link to AMPRNet terms of service uses HTTPS, not HTTP.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;b&amp;gt;NOTE:&amp;lt;/b&amp;gt; Direct announcements of AMPRNet address allocations are usually reserved for larger regional or country wide networks. Please consult with your regional allocation coordinator and the AMPRNet network administrator to determine whether directly announcing your AMPRNet allocation is appropriate.&lt;br /&gt;
&lt;br /&gt;
To announce your allocation directly via your Internet Service Provider (ISP) you will need to:&lt;br /&gt;
&lt;br /&gt;
# Contact your ISP and ask them if they are willing to announce your AMPRNet allocation in accordance with the terms of the [https://www.ampr.org/terms-of-service/ AMPRNet Terms of Service and Acceptable Use].  Many ISPs won&#039;t do this, and others charge a significant amount for the service.&lt;br /&gt;
# Apply for your AMPRNet allocation via the [[Portal]].  Check the &amp;lt;b&amp;gt;Direct&amp;lt;/b&amp;gt; box to indicate that your connection will be using a direct announcement of the subnet (via the BGP protocol).&lt;br /&gt;
# Upon verification and approval, the AMPRNet administrator will provide authorization to your ISP allowing them to announce your allocation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;NOTE:&amp;lt;/b&amp;gt; How your ISP chooses to forward traffic for your AMPRNet allocation varies by ISP. You will have to work with them to set this up.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;NOTE:&amp;lt;/b&amp;gt; Upon approval, [[ARDC]] issues a no-cost lease for up to five years (renewable on request and providing the use case remains valid) for the subnet.  This includes a letter of authority that should be provided to your ISP. ARDC does &amp;lt;b&amp;gt;NOT&amp;lt;/b&amp;gt; [[SWIP]] subnet allocations.&lt;/div&gt;</summary>
		<author><name>Cross</name></author>
	</entry>
	<entry>
		<id>https://wiki.ampr.org/w/index.php?title=RIP&amp;diff=913</id>
		<title>RIP</title>
		<link rel="alternate" type="text/html" href="https://wiki.ampr.org/w/index.php?title=RIP&amp;diff=913"/>
		<updated>2021-01-08T17:13:50Z</updated>

		<summary type="html">&lt;p&gt;Cross: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Information about other AMPRNet [[gateway| gateways]] can now be received dynamically via modified [http://en.wikipedia.org/wiki/Routing_Information_Protocol RIPv2] advertisements. Previously, routes were obtained by creating a [[munge script]] that parsed [[Encap.txt]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= What&#039;s the difference? =&lt;br /&gt;
&lt;br /&gt;
There is a big difference in how the packets are processed.&lt;br /&gt;
&lt;br /&gt;
The regular RIPv2 sets a route to a specific subnet via the sender and &lt;br /&gt;
interface where the RIP broadcast was received on. The gateway &lt;br /&gt;
information is used only as an optimization element, in case a route &lt;br /&gt;
with to that gateway already exists so that the one with the lower &lt;br /&gt;
metric gets chosen.&lt;br /&gt;
&lt;br /&gt;
In our case, we use the RIP announcements to transport the subnet AND &lt;br /&gt;
gateway information.&lt;br /&gt;
&lt;br /&gt;
= Detailed description =&lt;br /&gt;
&lt;br /&gt;
So, assuming a point to multipoint interface, if there is let&#039;s say an &lt;br /&gt;
announcement 44.128.0.0/24 via 1.2.3.4 coming from 44.0.0.1 on the ipip0 &lt;br /&gt;
interface, regular RIPv2 would translate this to:&lt;br /&gt;
&lt;br /&gt;
44.128.0.0/24 via 44.0.0.1 if ipip0&lt;br /&gt;
&lt;br /&gt;
while ampr rip would translate this to:&lt;br /&gt;
&lt;br /&gt;
44.128.0.0/24 via 1.2.3.4 if ipip0&lt;br /&gt;
&lt;br /&gt;
In the first case, traffic to 44.128.0.0/24 is sent directly to the &lt;br /&gt;
gateway (the RIP sender), while in the second case it is encapsulated to &lt;br /&gt;
1.2.3.4.&lt;br /&gt;
&lt;br /&gt;
On a mikrotik router it even goes a step further:&lt;br /&gt;
it creates a ipip tunnel interface, ampr-1.2.3.4 to 1.2.3.4 and creates &lt;br /&gt;
a route&lt;br /&gt;
&lt;br /&gt;
44.128.0.0/24 via ampr-1.2.3.4&lt;br /&gt;
&lt;br /&gt;
This is the processing in the usual case, for 44 subnets having a 44net &lt;br /&gt;
gateway we assume that the gateway is published by BGP and is directly &lt;br /&gt;
reachable, so for a announcement like 44.128.0.0/24 via 44.128.0.1 there &lt;br /&gt;
are 2 route set:&lt;br /&gt;
&lt;br /&gt;
44.128.0.1 via default-gw  (which is autodetected), and&lt;br /&gt;
44.128.0.0/24 via 44.128.0.1 if ipip0 to do the encapsulation&lt;br /&gt;
&lt;br /&gt;
So, while the information structure in both cases conforms to the RIPv2 &lt;br /&gt;
specifications, its usage is completely different.&lt;br /&gt;
&lt;br /&gt;
= RIP44 Daemons =&lt;br /&gt;
&lt;br /&gt;
Two programs are available for GNU/Linux to utilize these updates:&lt;br /&gt;
&lt;br /&gt;
* [[ampr-ripd]], a C based routing daemon&lt;br /&gt;
* [[rip44d]], a PERL based routing daemon&lt;br /&gt;
&lt;br /&gt;
A program is also available for [https://www.openbsd.org/ OpenBSD]:&lt;br /&gt;
&lt;br /&gt;
* [https://github.com/dancrossnyc/44ripd 44ripd]&lt;br /&gt;
&lt;br /&gt;
= Availability/Compatibility =&lt;br /&gt;
&lt;br /&gt;
The RIP44 daemons have been tested and known to work on the following operating systems:&lt;br /&gt;
&lt;br /&gt;
* BSD&lt;br /&gt;
* OpenWRT/LEDE&lt;br /&gt;
* Raspbian&lt;br /&gt;
* Slackware Linux&lt;br /&gt;
* Ubuntu/Debian Linux&lt;br /&gt;
* Vyatta/VyOS&lt;br /&gt;
&lt;br /&gt;
= Non-RIP44 Workarounds =&lt;br /&gt;
&lt;br /&gt;
The devices below do not possess a known, end-user method to install additional software (i.e. ampr-ripd). Operators have developed scripts to parse inbound routing packets to make them compatible for usage on AMPRNet:&lt;br /&gt;
&lt;br /&gt;
* Cisco IOS (a separate machine must run the script) : look here http://wiki.ampr.org/wiki/Setting_up_a_gateway_on_Cisco_Routers  at the &amp;quot;Making the route commands automatically&amp;quot; section&lt;br /&gt;
* JunOS&lt;br /&gt;
* MikroTik : look here  http://www.yo2loj.ro/hamprojects/ at the &amp;quot;Mikrotik RIPv2 AMPR Gateway Setup Script 3.0&amp;quot;&lt;br /&gt;
* Ubiquiti OS&lt;br /&gt;
&lt;br /&gt;
= See Also =&lt;br /&gt;
&lt;br /&gt;
* [[startampr]] - a script that loads the routing daemon on boot on Linux server-type devices&lt;br /&gt;
* Instructions for [[setting up a gateway on Linux|setting up a tunnel gateway on Linux]]&lt;br /&gt;
* Instructions for [[setting up a gateway on OpenWRT|setting up a gateway on OpenWRT]]&lt;br /&gt;
* Instructions for [[setting up a gateway on OpenBSD|setting up a gateway on OpenBSD]]&lt;/div&gt;</summary>
		<author><name>Cross</name></author>
	</entry>
	<entry>
		<id>https://wiki.ampr.org/w/index.php?title=RIP&amp;diff=912</id>
		<title>RIP</title>
		<link rel="alternate" type="text/html" href="https://wiki.ampr.org/w/index.php?title=RIP&amp;diff=912"/>
		<updated>2021-01-08T17:12:20Z</updated>

		<summary type="html">&lt;p&gt;Cross: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Information about other AMPRNet [[gateway| gateways]] can now be received dynamically via modified [http://en.wikipedia.org/wiki/Routing_Information_Protocol RIPv2] advertisements. Previously, routes were obtained by creating a [[munge script]] that parsed [[Encap.txt]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= What&#039;s the difference? =&lt;br /&gt;
&lt;br /&gt;
There is a big difference in how the packets are processed.&lt;br /&gt;
&lt;br /&gt;
The regular RIPv2 sets a route to a specific subnet via the sender and &lt;br /&gt;
interface where the RIP broadcast was received on. The gateway &lt;br /&gt;
information is used only as an optimization element, in case a route &lt;br /&gt;
with to that gateway already exists so that the one with the lower &lt;br /&gt;
metric gets chosen.&lt;br /&gt;
&lt;br /&gt;
In our case, we use the RIP announcements to transport the subnet AND &lt;br /&gt;
gateway information.&lt;br /&gt;
&lt;br /&gt;
= Detailed description =&lt;br /&gt;
&lt;br /&gt;
So, assuming a point to multipoint interface, if there is let&#039;s say an &lt;br /&gt;
announcement 44.128.0.0/24 via 1.2.3.4 coming from 44.0.0.1 on the ipip0 &lt;br /&gt;
interface, regular RIPv2 would translate this to:&lt;br /&gt;
&lt;br /&gt;
44.128.0.0/24 via 44.0.0.1 if ipip0&lt;br /&gt;
&lt;br /&gt;
while ampr rip would translate this to:&lt;br /&gt;
&lt;br /&gt;
44.128.0.0/24 via 1.2.3.4 if ipip0&lt;br /&gt;
&lt;br /&gt;
In the first case, traffic to 44.128.0.0/24 is sent directly to the &lt;br /&gt;
gateway (the RIP sender), while in the second case it is encapsulated to &lt;br /&gt;
1.2.3.4.&lt;br /&gt;
&lt;br /&gt;
On a mikrotik router it even goes a step further:&lt;br /&gt;
it creates a ipip tunnel interface, ampr-1.2.3.4 to 1.2.3.4 and creates &lt;br /&gt;
a route&lt;br /&gt;
&lt;br /&gt;
44.128.0.0/24 via ampr-1.2.3.4&lt;br /&gt;
&lt;br /&gt;
This is the processing in the usual case, for 44 subnets having a 44net &lt;br /&gt;
gateway we assume that the gateway is published by BGP and is directly &lt;br /&gt;
reachable, so for a announcement like 44.128.0.0/24 via 44.128.0.1 there &lt;br /&gt;
are 2 route set:&lt;br /&gt;
&lt;br /&gt;
44.128.0.1 via default-gw  (which is autodetected), and&lt;br /&gt;
44.128.0.0/24 via 44.128.0.1 if ipip0 to do the encapsulation&lt;br /&gt;
&lt;br /&gt;
So, while the information structure in both cases conforms to the RIPv2 &lt;br /&gt;
specifications, its usage is completely different.&lt;br /&gt;
&lt;br /&gt;
= RIP44 Daemons =&lt;br /&gt;
&lt;br /&gt;
Two programs are available for GNU/Linux to utilize these updates:&lt;br /&gt;
&lt;br /&gt;
* [[ampr-ripd]], a C based routing daemon&lt;br /&gt;
* [[rip44d]], a PERL based routing daemon&lt;br /&gt;
&lt;br /&gt;
A program is also available for [https://www.openbsd.org/ OpenBSD]:&lt;br /&gt;
&lt;br /&gt;
* [https://github.com/dancrossnyc/44ripd 44ripd]&lt;br /&gt;
&lt;br /&gt;
= Availability/Compatibility =&lt;br /&gt;
&lt;br /&gt;
The RIP44 daemons have been tested and known to work on the following operating systems:&lt;br /&gt;
&lt;br /&gt;
* BSD&lt;br /&gt;
* OpenWRT/LEDE&lt;br /&gt;
* Raspbian&lt;br /&gt;
* Slackware Linux&lt;br /&gt;
* Ubuntu/Debian Linux&lt;br /&gt;
* Vyatta/VyOS&lt;br /&gt;
&lt;br /&gt;
= Non-RIP44 Workarounds =&lt;br /&gt;
&lt;br /&gt;
The devices below do not possess a known, end-user method to install additional software (i.e. ampr-ripd). Operators have developed scripts to parse inbound routing packets to make them compatible for usage on AMPRNet:&lt;br /&gt;
&lt;br /&gt;
* Cisco IOS (a separate machine must run the script) : look here http://wiki.ampr.org/wiki/Setting_up_a_gateway_on_Cisco_Routers  at the &amp;quot;Making the route commands automatically&amp;quot; section&lt;br /&gt;
* JunOS&lt;br /&gt;
* MikroTik : look here  http://www.yo2loj.ro/hamprojects/ at the &amp;quot;Mikrotik RIPv2 AMPR Gateway Setup Script 3.0&amp;quot;&lt;br /&gt;
* Ubiquiti OS&lt;br /&gt;
&lt;br /&gt;
= See Also =&lt;br /&gt;
&lt;br /&gt;
* [[startampr]] - a script that loads the routing daemon on boot on Linux server-type devices&lt;br /&gt;
* Instructions for [[setting up a gateway on Linux|setting up a tunnel gateway on Linux]]&lt;br /&gt;
* Instructions for [[setting up a gateway on OpenWRT|setting up a gateway on OpenWRT]]&lt;/div&gt;</summary>
		<author><name>Cross</name></author>
	</entry>
	<entry>
		<id>https://wiki.ampr.org/w/index.php?title=Setting_up_a_gateway_on_OpenBSD&amp;diff=911</id>
		<title>Setting up a gateway on OpenBSD</title>
		<link rel="alternate" type="text/html" href="https://wiki.ampr.org/w/index.php?title=Setting_up_a_gateway_on_OpenBSD&amp;diff=911"/>
		<updated>2021-01-08T17:10:34Z</updated>

		<summary type="html">&lt;p&gt;Cross: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
[https://www.openbsd.org OpenBSD] is a mature Unix-like operating system that focuses on security and correctness. It features a flexible, robust, performant TCP/IP stack and a [https://www.openbsd.org/faq/pf/ highly configurable firewall]. This page describes how to configure a computer running OpenBSD as an AMPRNet router to transfer traffic between AMPRNet subnets and the Internet.&lt;br /&gt;
&lt;br /&gt;
OpenBSD natively supports [https://en.wikipedia.org/wiki/IP_in_IP IPENCAP (IP-IP)] tunnels through [https://man.openbsd.org/gif.4 &#039;&#039;gif&#039;&#039;(4)] pseudo-devices. Each &#039;&#039;gif&#039;&#039; device is a virtual network interface, synthesized by the operating system, that implements a point-to-point tunnel. Unlike Linux, OpenBSD requires a separate &#039;&#039;gif&#039;&#039; interface for each tunnel. An essentially arbitrary number of such interfaces can be created and it scales to the number required to route all of AMPRNet.&lt;br /&gt;
&lt;br /&gt;
One can manually configure &#039;&#039;gif&#039;&#039; tunnels and routes at the command line, or configure the system to establish tunnels and routes at boot time.&lt;br /&gt;
&lt;br /&gt;
We will describe how to set things up by way of example. Assume a system configuration that looks substantially similar to the following:&lt;br /&gt;
&lt;br /&gt;
* A dedicated static IP address to use as an endpoint for AMPRNet traffic.&lt;br /&gt;
* An ISP-provided router that is just a router; no NATing, no firewall.&lt;br /&gt;
* An OpenBSD computer with three ethernet interfaces. For example, using a Ubiquiti EdgeRouter 3 Lite:&lt;br /&gt;
*# cnmac0 is the external interface connected to the ISP&#039;s network (in this example, we use 23.30.150.141 routing to 23.30.150.142)&lt;br /&gt;
*# cnmac1 connects to an internal network (its configuration is irrelevant)&lt;br /&gt;
*# cnmac2 is the internal interface connected to the subnet (in this example, we use 44.44.107.1 routing for 44.44.107.0/24)&lt;br /&gt;
&lt;br /&gt;
Let us start by configuring a single tunnel and route to the AMPRNet gateway at UCSD:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;ifconfig gif1 create&lt;br /&gt;
ifconfig gif1 tunnel 23.30.150.141 169.228.34.84&lt;br /&gt;
ifconfig gif1 inet 44.44.107.1 netmask 255.255.255.255&lt;br /&gt;
route add -host 44.0.0.1 -link -iface gif1 -llinfo&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first command creates the interface, causing the kernel to synthesize it into existence. The second configures the tunnel itself: that is, the the IP addresses that will be put into the IPENCAP datagram that the tunnel creates: the first address is the &#039;&#039;local&#039;&#039; address, which will serve as the source address for the IPENCAP packet, while the second is the &#039;&#039;remote&#039;&#039; address, to which the packet will be sent. The third sets an IP address for the local endpoint of the interface: this exists solely so that traffic that is generated by the router, such as ICMP error messages (host or port unreachable, for example), have a valid source address. Note that despite the fact that this is a point-to-point interface, we do not specify the IP address of the remote end.&lt;br /&gt;
&lt;br /&gt;
The fourth and final command creates a host route and associates it with the tunnel interface. The &amp;lt;code&amp;gt;-link&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;-iface&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;-llinfo&amp;lt;/code&amp;gt; flags indicate that this is an interface route, and that traffic for the route should go directly to the given interface (&amp;lt;code&amp;gt;gif1&amp;lt;/code&amp;gt;) instead of identifying the gateway via an IP address. We can examine this route from the commandline. E.g.,&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;$ route -n show -inet | grep &#039;44\.0\.0\.1 &#039;&lt;br /&gt;
44.0.0.1           link#7             UHLSh      1        2     -     8 gif1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Consult the manual page for [https://man.openbsd.org/netstat.1 &#039;&#039;netstat&#039;&#039;(1)] for details on what the &amp;lt;code&amp;gt;UHLSh&amp;lt;/code&amp;gt; flags mean.&lt;br /&gt;
&lt;br /&gt;
We can repeat this process for each AMPRNet tunnel, creating interfaces and adding routes for each subnet.&lt;br /&gt;
&lt;br /&gt;
== Handling Encapsulated Inbound Traffic Without a Reciprocal Tunnel ==&lt;br /&gt;
&lt;br /&gt;
When an inbound IPENCAP datagram arrives on our external interface, the network stack in the OpenBSD kernel recognizes it by examining the protocol number in the IP header: IPENCAP is protocol number 4 (not to be confused with IP version 4). Any such packets are passed to the packet input function in the &#039;&#039;gif&#039;&#039; implementation, which searches all configured &#039;&#039;gif&#039;&#039; interfaces trying to find match the configured tunnel source and destinations addresses with the corresponding addresses in the inbound packet. If such an interface is found, the packet is enqueued to the interface, which will strip the IPENCAP header and route the resulting &amp;quot;de-encapsulated&amp;quot; IP packet. This works for tunnels that are configured bidirectionally between any two sites. That is, if site A has a tunnel to site B, and B has a corresponding tunnel to A, they can send each other traffic.&lt;br /&gt;
&lt;br /&gt;
Now consider the case where site A has a tunnel configured to send traffic to site B, but B has no tunnel configured to A: in this case, the datagram arrives as before and is presented to the &#039;&#039;gif&#039;&#039; implementation, but the search above fails since B has no tunnel to A, so nothing matches the source &#039;&#039;and&#039;&#039; destination addresses on the incoming packet. In this case, the system might be responsible for routing such packets to another computer or network, so the packet is not de-encapsulated and processed. However, in an AMPRNet context, we very well may want to process that packet. Accordingly, the &#039;&#039;gif&#039;&#039; implementation has a mechanism for describing an interface that accepts encapsulated traffic from any source destined to a local address. If we configure a &#039;&#039;gif&#039;&#039; interface where the distant end of the &#039;&#039;tunnel&#039;&#039; set to &amp;lt;code&amp;gt;0.0.0.0&amp;lt;/code&amp;gt;, then any incoming datagram where the destination address is the same as the local address on the interface, will be accepted and de-encapsulated and processed as before. Using this, we can set up an interface specifically for accepting traffic from systems to which we have not defined a tunnel:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;ifconfig gif0 create&lt;br /&gt;
ifconfig gif0 tunnel 23.30.150.141 0.0.0.0&lt;br /&gt;
ifconfig gif0 inet 44.44.107.1 255.255.255.255&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note the &amp;lt;code&amp;gt;0.0.0.0&amp;lt;/code&amp;gt; as the remote address in the &amp;lt;code&amp;gt;ifconfig tunnel&amp;lt;/code&amp;gt; command. Again, we set an interface address using our local AMPRNet router address purely for locally generated traffic.&lt;br /&gt;
&lt;br /&gt;
One this interface is configured, IPENCAP traffic from remote systems that have defined tunnels to us will flow, regardless of whether we have created a tunnel to them.&lt;br /&gt;
&lt;br /&gt;
== Policy-based Routing Using Routing Domains ==&lt;br /&gt;
&lt;br /&gt;
The configuration explored so far is sufficient to make connections to AMPRNet directly-configured AMPRNet subnets, but suffers from a number of deficiencies. In particular, there are two issues that we will discuss now.&lt;br /&gt;
&lt;br /&gt;
First, there is a problem with exchanging traffic with non-AMPRNet systems on the Internet. Presumably, these systems are not aware of AMPRNet tunneling, so traffic from them goes to the gateway at UCSD, where it will be encapsulated and sent through a tunnel to the external interface on our router. There, it will be de-encapsulated and delivered into our subnet. However, return traffic will be sent to the router, but since the destination is generally a tunnel, it will be sent via the default route, but from an AMPRNet source address. Since most ISPs will not pass AMPRNet traffic, the result will likely be lost before it reaches the destination. We may think it would be possible to work around that using a firewall rule to NAT the source address to something provided by our ISP, but even if the resulting datagram made it to the destination, for a protocol like TCP it would no longer match the 5-tuple for the connection, and would thus be lost.&lt;br /&gt;
&lt;br /&gt;
The second problem is how reaching AMPRNet systems for which we have not configured a tunnel.  Without a tunnel, and thus a route, we cannot send traffic to those systems.&lt;br /&gt;
&lt;br /&gt;
We can solve both of these problems by sending all of our traffic through a tunnel interface to the UCSD gateway by default, e.g., by setting the default route:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;route add default 4.0.0.1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, how does the encapsulated traffic from the tunnel interface get sent to our ISP&#039;s router? We can add a host route for the UCSD gateway in our local routing table, but we have to do this for every tunnel, which is unwieldy. Further, connecting to our external interface becomes complicated: suppose someone &amp;lt;code&amp;gt;ping&amp;lt;/code&amp;gt;s our external interface. Assuming we permit this, the response would be routed through the UCSD gateway tunnel, but even if the gateway passed arbitrary traffic back onto the Internet, the packet might be lost as upstream ISPs would refuse to route it.&lt;br /&gt;
&lt;br /&gt;
The solution to all of these problems is to use [https://en.wikipedia.org/wiki/Policy-based_routing &#039;&#039;policy-based routing&#039;&#039;]. Specifically, we would like to make routing decisions based on the source IP address of our traffic. We might be able to do this with firewall rules, but the edge cases get complicated very quickly. Fortunately, there is another way: [https://man.openbsd.org/rdomain.4 routing domains].&lt;br /&gt;
&lt;br /&gt;
Routing domains in OpenBSD are a mechanism to isolate routing decisions from one another. Network interfaces are configured into exactly one routing domain, which has its own private set of routing tables. Those tables are isolated, but traffic can be passed between routing domains via firewall rules.&lt;br /&gt;
&lt;br /&gt;
In our example, we put our external and local AMPRNet gateway interfaces into separate routing domains: all of the &#039;&#039;gif&#039;&#039; interfaces and the local AMPRNet gateway interface can both be assigned to routing domain 44, while the external interface might be 23. Routing domain 0 is the default. Note that the numbers here are arbitrary, and we can choose any value below 256 that we like; these are chosen to match the first octet of our example addresses.&lt;br /&gt;
&lt;br /&gt;
The routing domain on an interface is set using the &amp;lt;code&amp;gt;rdomain&amp;lt;/code&amp;gt; parameter to &amp;lt;code&amp;gt;ifconfig&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;ifconfig cnmac0 rdomain 23&lt;br /&gt;
ifconfig gif0 rdomain 44&lt;br /&gt;
ifconfig gif1 rdomain 44&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We set the default route in the routing domain that owns our external interface to our ISP&#039;s router, while in the routing domain hosting our AMPRNet presence we can set it to the UCSD gateway:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;route -T 23 add default 23.30.150.242&lt;br /&gt;
route -T 44 add default 44.0.0.1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now traffic on our AMPRNet subnet will be routed through the UCSD gateway, while traffic on the external interface will be routed through our ISP&#039;s router.&lt;br /&gt;
&lt;br /&gt;
Another piece of functionality allows us to dispense with much of the complexity of routing between domains: the tunnel assigned to a &#039;&#039;gif&#039;&#039; can be in a different routing domain than the interface itself. Going back to our example, if we place each of our &#039;&#039;gif&#039;&#039; interfaces into routing domain 44 then traffic routed out to on coming in from the tunnel will be routed with our AMPRNet-specific routing table. But if we place the tunnel on that interface into routing domain 23, then the encapsulated traffic that we send to and from the Internet (e.g., to other tunnel end points) will be routed in that domain, thus routing through our ISP&#039;s network. Critically, matching incoming datagrams to &#039;&#039;gif&#039;&#039; interfaces as described above happens in the routing domain associated with the tunnel, so inbound traffic coming through our external interface will be directed to the correct interface.&lt;br /&gt;
&lt;br /&gt;
We specify the routing domain of a tunnel via the &amp;lt;code&amp;gt;tunneldomain&amp;lt;/code&amp;gt; parameter to &amp;lt;code&amp;gt;ifconfig&amp;lt;/code&amp;gt; when configuring the route on an interface:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;ifconfig gif0 tunnel 23.30.150.141 0.0.0.0 tunneldomain 23&lt;br /&gt;
ifconfig gif1 tunnel 23.30.150.141 169.228.34.84 tunneldomain 23&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With this in place, routing works as expected for all of the cases mentioned above.&lt;br /&gt;
&lt;br /&gt;
== Persistent Configuration Across Router Restarts ==&lt;br /&gt;
&lt;br /&gt;
We now have enough information that we can set up tunnels between our router and arbitrary AMPRNet subnets. However, doing so manually is tedious and not particularly robust. We would like the system to automatically configure our tunnels and default routes at boot time. Fortunately, the OpenBSD startup code can do this easily. For each network interface &amp;lt;code&amp;gt;$if&amp;lt;/code&amp;gt; on the system, we can configure it automatically at boot time by putting configuration commands into the file &amp;lt;code&amp;gt;/etc/hostname.$if&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
There are four interfaces we have configured: the two ethernet interfaces for our external and AMPRNet networks, and the two &#039;&#039;gif&#039;&#039; interfaces with the default incoming tunnel and the tunnel to the UCSD gateway.  Thus, there are four files:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/etc/hostname.cnmac0&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;rdomain 23&lt;br /&gt;
inet 23.30.150.141 0xfffffff8&lt;br /&gt;
!ifconfig lo23 inet 127.0.0.1&lt;br /&gt;
!route -qn -T 23 add default 23.30.150.142&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/etc/hostname.cnmac2&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;rdomain 44&lt;br /&gt;
inet 44.44.107.1 255.255.255.0&lt;br /&gt;
!ifconfig lo44 inet 127.0.0.1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/etc/hostname.gif0&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;rdomain 44&lt;br /&gt;
tunnel 23.30.150.141 0.0.0.0 tunneldomain 23&lt;br /&gt;
inet 44.44.107.1 255.255.255.255&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;/etc/hostname.gif1&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;tunnel 23.30.150.141 169.228.34.84 tunneldomain 23&lt;br /&gt;
inet 44.44.107.1 255.255.255.255&lt;br /&gt;
!route -qn -T 44 add 44.0.0.1/32 -link -iface gif1 -llinfo&lt;br /&gt;
!route -qn -T 44 add default 44.0.0.1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that each routing domain also has its own associated loopback interface, hence configuring &amp;lt;code&amp;gt;lo23&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;lo44&amp;lt;/code&amp;gt;. These interfaces are automatically created when the routing domain is created, but we configure them when we bring up the associated ethernet interfaces.&lt;br /&gt;
&lt;br /&gt;
We can examine the interfaces and separate routing tables to ensure that things are set up as expected:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;$ ifconfig cnmac0&lt;br /&gt;
cnmac0: flags=8843&amp;lt;UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST&amp;gt; rdomain 23 mtu 1500&lt;br /&gt;
        lladdr 44:d9:e7:9f:a7:64&lt;br /&gt;
        index 1 priority 0 llprio 3&lt;br /&gt;
        media: Ethernet autoselect (1000baseT full-duplex)&lt;br /&gt;
        status: active&lt;br /&gt;
        inet 23.30.150.141 netmask 0xfffffff8 broadcast 23.30.150.143&lt;br /&gt;
$ ifconfig cnmac2&lt;br /&gt;
cnmac2: flags=8843&amp;lt;UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST&amp;gt; rdomain 44 mtu 1500&lt;br /&gt;
        lladdr 44:d9:e7:9f:a7:66&lt;br /&gt;
        index 3 priority 0 llprio 3&lt;br /&gt;
        media: Ethernet autoselect (1000baseT full-duplex,master)&lt;br /&gt;
        status: active&lt;br /&gt;
        inet 44.44.107.1 netmask 0xffffff00 broadcast 44.44.107.255&lt;br /&gt;
$ ifconfig gif0&lt;br /&gt;
gif0: flags=8051&amp;lt;UP,POINTOPOINT,RUNNING,MULTICAST&amp;gt; rdomain 44 mtu 1280&lt;br /&gt;
        index 6 priority 0 llprio 3&lt;br /&gt;
        encap: txprio payload rxprio payload&lt;br /&gt;
        groups: gif&lt;br /&gt;
        tunnel: inet 23.30.150.141 -&amp;gt; 0.0.0.0 ttl 64 nodf ecn rdomain 23&lt;br /&gt;
        inet 44.44.107.1 --&amp;gt; 0.0.0.0 netmask 0xffffffff&lt;br /&gt;
$ ifconfig gif1&lt;br /&gt;
gif1: flags=8051&amp;lt;UP,POINTOPOINT,RUNNING,MULTICAST&amp;gt; rdomain 44 mtu 1280&lt;br /&gt;
        index 7 priority 0 llprio 3&lt;br /&gt;
        encap: txprio payload rxprio payload&lt;br /&gt;
        groups: gif&lt;br /&gt;
        tunnel: inet 23.30.150.141 -&amp;gt; 169.228.34.84 ttl 64 nodf ecn rdomain 23&lt;br /&gt;
        inet 44.44.107.1 --&amp;gt; 0.0.0.0 netmask 0xffffffff&lt;br /&gt;
$ route -T 23 -n show -inet&lt;br /&gt;
Routing tables&lt;br /&gt;
&lt;br /&gt;
Internet:&lt;br /&gt;
Destination        Gateway            Flags   Refs      Use   Mtu  Prio Iface&lt;br /&gt;
default            23.30.150.142      UGS        0    51126     -     8 cnmac0&lt;br /&gt;
23.30.150.136/29   23.30.150.141      UCn        1        7     -     4 cnmac0&lt;br /&gt;
23.30.150.141      44:d9:e7:9f:a7:64  UHLl       0    88377     -     1 cnmac0&lt;br /&gt;
23.30.150.142      4a:1d:70:de:c3:5a  UHLch      1      386     -     3 cnmac0&lt;br /&gt;
23.30.150.143      23.30.150.141      UHb        0        0     -     1 cnmac0&lt;br /&gt;
127.0.0.1          127.0.0.1          UHl        0        0 32768     1 lo23&lt;br /&gt;
$ route -T 44 -n show -inet&lt;br /&gt;
Routing tables&lt;br /&gt;
&lt;br /&gt;
Internet:&lt;br /&gt;
Destination        Gateway            Flags   Refs      Use   Mtu  Prio Iface&lt;br /&gt;
default            44.0.0.1           UGS        0    54718     -     8 gif1&lt;br /&gt;
44.0.0.1           link#7             UHLSh      1        2     -     8 gif1&lt;br /&gt;
44.44.107/24       44.44.107.1        UCn       16        4     -     4 cnmac2&lt;br /&gt;
44.44.107.1        44:d9:e7:9f:a7:66  UHLl       0     4825     -     1 cnmac2&lt;br /&gt;
44.44.107.255      44.44.107.1        UHb        0        0     -     1 cnmac2&lt;br /&gt;
127.0.0.1          127.0.0.1          UHl        0        0 32768     1 lo44&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Restricting Traffic with the [https://www.openbsd.org/faq/pf/ PF] Firewall ==&lt;br /&gt;
&lt;br /&gt;
All of these interfaces will fully integrate with the PF firewall software that comes with OpenBSD, and we can implement nearly arbitrary policies in our configuration.  For example, we might restrict traffic on the external interface to only ICMP messages and IPENCAP datagrams by setting the following rules in &amp;lt;code&amp;gt;/etc/pf.conf&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;# Constants&lt;br /&gt;
extif = &amp;quot;cnmac0&amp;quot;&lt;br /&gt;
extamprgate = &amp;quot;23.30.150.141&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Options&lt;br /&gt;
set skip on lo&lt;br /&gt;
set block-policy return&lt;br /&gt;
&lt;br /&gt;
block return    # block stateless traffic&lt;br /&gt;
pass            # establish keep-state&lt;br /&gt;
&lt;br /&gt;
# Normalize incoming packets.&lt;br /&gt;
match in all scrub (no-df random-id max-mss 1440)&lt;br /&gt;
&lt;br /&gt;
# By default, block everything.  We selectively override in subsequent rules.&lt;br /&gt;
block in on $extif&lt;br /&gt;
&lt;br /&gt;
# Pass 44net traffic&lt;br /&gt;
pass in on $extif inet proto ipencap from any to $extamprgate&lt;br /&gt;
&lt;br /&gt;
# Pass ping and ICMP unreachable messages on external interface&lt;br /&gt;
pass in on $extif inet proto icmp icmp-type echoreq code 0 keep state&lt;br /&gt;
pass in on $extif inet proto icmp icmp-type unreach keep state&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We can verify that these rules are in place as expected by querying the rule tables:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;# pfctl -sr -vv&lt;br /&gt;
@0 block return all&lt;br /&gt;
  [ Evaluations: 115977    Packets: 3776      Bytes: 168422      States: 0     ]&lt;br /&gt;
  [ Inserted: uid 0 pid 31812 State Creations: 0     ]&lt;br /&gt;
@1 pass all flags S/SA&lt;br /&gt;
  [ Evaluations: 115977    Packets: 242418    Bytes: 25899015    States: 253   ]&lt;br /&gt;
  [ Inserted: uid 0 pid 31812 State Creations: 102105]&lt;br /&gt;
@2 match in all scrub (no-df random-id max-mss 1440)&lt;br /&gt;
  [ Evaluations: 115977    Packets: 261105    Bytes: 31394491    States: 136   ]&lt;br /&gt;
  [ Inserted: uid 0 pid 31812 State Creations: 0     ]&lt;br /&gt;
@3 block return in on cnmac0 all&lt;br /&gt;
  [ Evaluations: 64726     Packets: 5925      Bytes: 325492      States: 0     ]&lt;br /&gt;
  [ Inserted: uid 0 pid 31812 State Creations: 0     ]&lt;br /&gt;
@4 pass in on cnmac0 inet proto icmp all icmp-type echoreq code 0&lt;br /&gt;
  [ Evaluations: 8149      Packets: 342       Bytes: 27424       States: 0     ]&lt;br /&gt;
  [ Inserted: uid 0 pid 31812 State Creations: 171   ]&lt;br /&gt;
@5 pass in on cnmac0 inet proto icmp all icmp-type unreach&lt;br /&gt;
  [ Evaluations: 308       Packets: 5         Bytes: 368         States: 0     ]&lt;br /&gt;
  [ Inserted: uid 0 pid 31812 State Creations: 0     ]&lt;br /&gt;
@6 pass in on cnmac0 inet proto ipencap from any to 23.30.150.141&lt;br /&gt;
  [ Evaluations: 8149      Packets: 126197    Bytes: 16538717    States: 5     ]&lt;br /&gt;
  [ Inserted: uid 0 pid 31812 State Creations: 2048  ]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A site can add more elaborate rules as desired.&lt;br /&gt;
&lt;br /&gt;
== Maintaining Mesh Routes with 44ripd ==&lt;br /&gt;
&lt;br /&gt;
The above shows how to set up AMPRNet tunnel interfaces, set routes to them, use routing domains for policy-based routing, and set firewall rules. However, so far all of these steps have been manual. This works for a handful of tunnels and routes, but there are hundreds of subnets AMPRNet in the AMPRNet mesh; maintaining all of these manually is not reasonable.&lt;br /&gt;
&lt;br /&gt;
However, Dan Cross (KZ2X) has written a daemon specific to OpenBSD called &amp;lt;code&amp;gt;44ripd&amp;lt;/code&amp;gt; that maintains tunnel and route information as distributed via the [https://wiki.ampr.org/wiki/RIP AMPRNet RIP] variant sent from &amp;lt;code&amp;gt;44.0.0.1&amp;lt;/code. To use this, make sure that multicasting is enabled on the host by setting &amp;lt;code&amp;gt;multicast=YES&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;/etc/rc.conf.local&amp;lt;/code&amp;gt;, and then retrieve the 44ripd software from Github at https://github.com/dancrossnyc/44ripd. The software is built with the &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt; command. For example:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;git clone https://github.com/dancrossnyc/44ripd&lt;br /&gt;
cd 44ripd&lt;br /&gt;
make&lt;br /&gt;
doas install -c -o root -g wheel -m 555 44ripd /usr/local/sbin&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once installed, this can be run at boot by adding the following lines to &amp;lt;code&amp;gt;/etc/rc.local&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;if [ -x /usr/local/sbin/44ripd ]; then&lt;br /&gt;
        echo -n &#039; 44ripd&#039;&lt;br /&gt;
        route -T 44 exec /usr/local/sbin/44ripd -s0 -s1 -D 44 -T 23&lt;br /&gt;
fi&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that the &amp;lt;code&amp;gt;-s&amp;lt;/code&amp;gt; options instruct the daemon not to try and allocate the &amp;lt;code&amp;gt;gif0&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;gif1&amp;lt;/code&amp;gt; interfaces, as these are manually configured.&lt;br /&gt;
&lt;br /&gt;
=== Set the Default AMPRNet Tunnel and Route Manually ===&lt;br /&gt;
&lt;br /&gt;
While route information for the UCSD AMPRNet gateway is distributed in RIP44 packets and we could in theory only configure the default incoming tunnel and rely on 44ripd to set up a route to UCSD, this leads to a problem. Specifically, without an interface configured to the UCSD gateway, we cannot set a default route in our AMRPNet routing domain for the gateway. Since we rely on periodic route broadcasts from UCSD to set those routes, we would delay setting up our default route for an indeterminate amount of time (on the order of minutes).&lt;br /&gt;
&lt;br /&gt;
Thus, it is advised to explicitly configure the tunnel to UCSD at boot time along with the default route.&lt;br /&gt;
&lt;br /&gt;
=== Notes on 44ripd Implementation ===&lt;br /&gt;
&lt;br /&gt;
* 44ripd maintains a copy of the AMPRNet routing table in a modified PATRICIA trie (really a compressed radix tree).&lt;br /&gt;
* A similar table of tunnels is maintained.&lt;br /&gt;
* Tunnel interfaces are reference counted and garbage collected. A bitmap indicating which tunnels are in use is maintained.&lt;br /&gt;
* Routes are expired after receiving a RIP packet.&lt;br /&gt;
* The program is completely self-contained in the sense that it does not fork/exec external commands to configure tunnels or manipulate routes.  That is all done via ioctls or writing messages to a routing socket.&lt;br /&gt;
* 44ripd does not examine the state of the system or routing tables at startup to bootstrap its internal state, but arguably should.&lt;br /&gt;
* Bugs in 44ripd should be reported via Github issues.&lt;br /&gt;
* Exporting and/or parsing an encap file would be nice.&lt;br /&gt;
* Logging and error checking can always be improved.&lt;/div&gt;</summary>
		<author><name>Cross</name></author>
	</entry>
	<entry>
		<id>https://wiki.ampr.org/w/index.php?title=Setting_up_a_gateway_on_OpenBSD&amp;diff=910</id>
		<title>Setting up a gateway on OpenBSD</title>
		<link rel="alternate" type="text/html" href="https://wiki.ampr.org/w/index.php?title=Setting_up_a_gateway_on_OpenBSD&amp;diff=910"/>
		<updated>2021-01-08T14:20:46Z</updated>

		<summary type="html">&lt;p&gt;Cross: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
[https://www.openbsd.org OpenBSD] is a mature Unix-like operating system that focuses on security and correctness. It features a flexible, robust, performant TCP/IP stack and a [https://www.openbsd.org/faq/pf/ highly configurable firewall]. This page describes how to configure a computer running OpenBSD as an AMPRNet router to transfer traffic between AMPRNet subnets and the Internet.&lt;br /&gt;
&lt;br /&gt;
OpenBSD natively supports [https://en.wikipedia.org/wiki/IP_in_IP IPENCAP (IP-IP)] tunnels through [https://man.openbsd.org/gif.4 &#039;&#039;gif&#039;&#039;(4)] pseudo-devices. Each &#039;&#039;gif&#039;&#039; device is a virtual network interface, synthesized by the operating system, that implements a point-to-point tunnel. Unlike Linux, OpenBSD requires a separate &#039;&#039;gif&#039;&#039; interface for each tunnel. An essentially arbitrary number of such interfaces can be created and it scales to the number required to route all of AMPRNet.&lt;br /&gt;
&lt;br /&gt;
One can manually configure &#039;&#039;gif&#039;&#039; tunnels and routes at the command line, or configure the system to establish tunnels and routes at boot time.&lt;br /&gt;
&lt;br /&gt;
We will describe how to set things up by way of example. Assume a system configuration that looks substantially similar to the following:&lt;br /&gt;
&lt;br /&gt;
* A dedicated static IP address to use as an endpoint for AMPRNet traffic.&lt;br /&gt;
* An ISP-provided router that is just a router; no NATing, no firewall.&lt;br /&gt;
* An OpenBSD computer with three ethernet interfaces. For example, using a Ubiquiti EdgeRouter 3 Lite:&lt;br /&gt;
*# cnmac0 is the external interface connected to the ISP&#039;s network (in this example, we use 23.30.150.141 routing to 23.30.150.142)&lt;br /&gt;
*# cnmac1 connects to an internal network (its configuration is irrelevant)&lt;br /&gt;
*# cnmac2 is the internal interface connected to the subnet (in this example, we use 44.44.107.1 routing for 44.44.107.0/24)&lt;br /&gt;
&lt;br /&gt;
Let us start by configuring a single tunnel and route to the AMPRNet gateway at UCSD:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;ifconfig gif1 create&lt;br /&gt;
ifconfig gif1 tunnel 23.30.150.141 169.228.34.84&lt;br /&gt;
ifconfig gif1 inet 44.44.107.1 netmask 255.255.255.255&lt;br /&gt;
route add -host 44.0.0.1 -link -iface gif1 -llinfo&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first command creates the interface, causing the kernel to synthesize it into existence. The second configures the tunnel itself: that is, the the IP addresses that will be put into the IPENCAP datagram that the tunnel creates: the first address is the &#039;&#039;local&#039;&#039; address, which will serve as the source address for the IPENCAP packet, while the second is the &#039;&#039;remote&#039;&#039; address, to which the packet will be sent. The third sets an IP address for the local endpoint of the interface: this exists solely so that traffic that is generated by the router, such as ICMP error messages (host or port unreachable, for example), have a valid source address. Note that despite the fact that this is a point-to-point interface, we do not specify the IP address of the remote end.&lt;br /&gt;
&lt;br /&gt;
The fourth and final command creates a host route and associates it with the tunnel interface. The &amp;lt;code&amp;gt;-link&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;-iface&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;-llinfo&amp;lt;/code&amp;gt; flags indicate that this is an interface route, and that traffic for the route should go directly to the given interface (&amp;lt;code&amp;gt;gif1&amp;lt;/code&amp;gt;) instead of identifying the gateway via an IP address. We can examine this route from the commandline. E.g.,&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;$ route -n show -inet | grep &#039;44\.0\.0\.1 &#039;&lt;br /&gt;
44.0.0.1           link#7             UHLSh      1        2     -     8 gif1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Consult the manual page for [https://man.openbsd.org/netstat.1 &#039;&#039;netstat&#039;&#039;(1)] for details on what the &amp;lt;code&amp;gt;UHLSh&amp;lt;/code&amp;gt; flags mean.&lt;br /&gt;
&lt;br /&gt;
We can repeat this process for each AMPRNet tunnel, creating interfaces and adding routes for each subnet.&lt;br /&gt;
&lt;br /&gt;
== Handling Encapsulated Inbound Traffic Without a Reciprocal Tunnel ==&lt;br /&gt;
&lt;br /&gt;
When an inbound IPENCAP datagram arrives on our external interface, the network stack in the OpenBSD kernel recognizes it by examining the protocol number in the IP header: IPENCAP is protocol number 4 (not to be confused with IP version 4). Any such packets are passed to the packet input function in the &#039;&#039;gif&#039;&#039; implementation, which searches all configured &#039;&#039;gif&#039;&#039; interfaces trying to find match the configured tunnel source and destinations addresses with the corresponding addresses in the inbound packet. If such an interface is found, the packet is enqueued to the interface, which will strip the IPENCAP header and route the resulting &amp;quot;de-encapsulated&amp;quot; IP packet. This works for tunnels that are configured bidirectionally between any two sites. That is, if site A has a tunnel to site B, and B has a corresponding tunnel to A, they can send each other traffic.&lt;br /&gt;
&lt;br /&gt;
Now consider the case where site A has a tunnel configured to send traffic to site B, but B has no tunnel configured to A: in this case, the datagram arrives as before and is presented to the &#039;&#039;gif&#039;&#039; implementation, but the search above fails since B has no tunnel to A, so nothing matches the source &#039;&#039;and&#039;&#039; destination addresses on the incoming packet. In this case, the system might be responsible for routing such packets to another computer or network, so the packet is not de-encapsulated and processed. However, in an AMPRNet context, we very well may want to process that packet. Accordingly, the &#039;&#039;gif&#039;&#039; implementation has a mechanism for describing an interface that accepts encapsulated traffic from any source destined to a local address. If we configure a &#039;&#039;gif&#039;&#039; interface where the distant end of the &#039;&#039;tunnel&#039;&#039; set to &amp;lt;code&amp;gt;0.0.0.0&amp;lt;/code&amp;gt;, then any incoming datagram where the destination address is the same as the local address on the interface, will be accepted and de-encapsulated and processed as before. Using this, we can set up an interface specifically for accepting traffic from systems to which we have not defined a tunnel:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;ifconfig gif0 create&lt;br /&gt;
ifconfig gif0 tunnel 23.30.150.141 0.0.0.0&lt;br /&gt;
ifconfig gif0 inet 44.44.107.1 255.255.255.255&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note the &amp;lt;code&amp;gt;0.0.0.0&amp;lt;/code&amp;gt; as the remote address in the &amp;lt;code&amp;gt;ifconfig tunnel&amp;lt;/code&amp;gt; command. Again, we set an interface address using our local AMPRNet router address purely for locally generated traffic.&lt;br /&gt;
&lt;br /&gt;
One this interface is configured, IPENCAP traffic from remote systems that have defined tunnels to us will flow, regardless of whether we have created a tunnel to them.&lt;br /&gt;
&lt;br /&gt;
== Policy-based Routing Using Routing Domains ==&lt;br /&gt;
&lt;br /&gt;
The configuration explored so far is sufficient to make connections to AMPRNet directly-configured AMPRNet subnets, but suffers from a number of deficiencies. In particular, there are two issues that we will discuss now.&lt;br /&gt;
&lt;br /&gt;
First, there is a problem with exchanging traffic with non-AMPRNet systems on the Internet. Presumably, these systems are not aware of AMPRNet tunneling, so traffic from them goes to the gateway at UCSD, where it will be encapsulated and sent through a tunnel to the external interface on our router. There, it will be de-encapsulated and delivered into our subnet. However, return traffic will be sent to the router, but since the destination is generally a tunnel, it will be sent via the default route, but from an AMPRNet source address. Since most ISPs will not pass AMPRNet traffic, the result will likely be lost before it reaches the destination. We may think it would be possible to work around that using a firewall rule to NAT the source address to something provided by our ISP, but even if the resulting datagram made it to the destination, for a protocol like TCP it would no longer match the 5-tuple for the connection, and would thus be lost.&lt;br /&gt;
&lt;br /&gt;
The second problem is how reaching AMPRNet systems for which we have not configured a tunnel.  Without a tunnel, and thus a route, we cannot send traffic to those systems.&lt;br /&gt;
&lt;br /&gt;
We can solve both of these problems by sending all of our traffic through a tunnel interface to the UCSD gateway by default, e.g., by setting the default route:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;route add default 4.0.0.1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, how does the encapsulated traffic from the tunnel interface get sent to our ISP&#039;s router? We can add a host route for the UCSD gateway in our local routing table, but we have to do this for every tunnel, which is unwieldy. Further, connecting to our external interface becomes complicated: suppose someone &amp;lt;code&amp;gt;ping&amp;lt;/code&amp;gt;s our external interface. Assuming we permit this, the response would be routed through the UCSD gateway tunnel, but even if the gateway passed arbitrary traffic back onto the Internet, the packet might be lost as upstream ISPs would refuse to route it.&lt;br /&gt;
&lt;br /&gt;
The solution to all of these problems is to use [https://en.wikipedia.org/wiki/Policy-based_routing &#039;&#039;policy-based routing&#039;&#039;]. Specifically, we would like to make routing decisions based on the source IP address of our traffic. We might be able to do this with firewall rules, but the edge cases get complicated very quickly. Fortunately, there is another way: [https://man.openbsd.org/rdomain.4 routing domains].&lt;br /&gt;
&lt;br /&gt;
Routing domains in OpenBSD are a mechanism to isolate routing decisions from one another. Network interfaces are configured into exactly one routing domain, which has its own private set of routing tables. Those tables are isolated, but traffic can be passed between routing domains via firewall rules.&lt;br /&gt;
&lt;br /&gt;
In our example, we put our external and local AMPRNet gateway interfaces into separate routing domains: all of the &#039;&#039;gif&#039;&#039; interfaces and the local AMPRNet gateway interface can both be assigned to routing domain 44, while the external interface might be 23. Routing domain 0 is the default. Note that the numbers here are arbitrary, and we can choose any value below 256 that we like; these are chosen to match the first octet of our example addresses.&lt;br /&gt;
&lt;br /&gt;
The routing domain on an interface is set using the &amp;lt;code&amp;gt;rdomain&amp;lt;/code&amp;gt; parameter to &amp;lt;code&amp;gt;ifconfig&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;ifconfig cnmac0 rdomain 23&lt;br /&gt;
ifconfig gif0 rdomain 44&lt;br /&gt;
ifconfig gif1 rdomain 44&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We set the default route in the routing domain that owns our external interface to our ISP&#039;s router, while in the routing domain hosting our AMPRNet presence we can set it to the UCSD gateway:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;route -T 23 add default 23.30.150.242&lt;br /&gt;
route -T 44 add default 44.0.0.1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now traffic on our AMPRNet subnet will be routed through the UCSD gateway, while traffic on the external interface will be routed through our ISP&#039;s router.&lt;br /&gt;
&lt;br /&gt;
Another piece of functionality allows us to dispense with much of the complexity of routing between domains: the tunnel assigned to a &#039;&#039;gif&#039;&#039; can be in a different routing domain than the interface itself. Going back to our example, if we place each of our &#039;&#039;gif&#039;&#039; interfaces into routing domain 44 then traffic routed out to on coming in from the tunnel will be routed with our AMPRNet-specific routing table. But if we place the tunnel on that interface into routing domain 23, then the encapsulated traffic that we send to and from the Internet (e.g., to other tunnel end points) will be routed in that domain, thus routing through our ISP&#039;s network. Critically, matching incoming datagrams to &#039;&#039;gif&#039;&#039; interfaces as described above happens in the routing domain associated with the tunnel, so inbound traffic coming through our external interface will be directed to the correct interface.&lt;br /&gt;
&lt;br /&gt;
We specify the routing domain of a tunnel via the &amp;lt;code&amp;gt;tunneldomain&amp;lt;/code&amp;gt; parameter to &amp;lt;code&amp;gt;ifconfig&amp;lt;/code&amp;gt; when configuring the route on an interface:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;ifconfig gif0 tunnel 23.30.150.141 0.0.0.0 tunneldomain 23&lt;br /&gt;
ifconfig gif1 tunnel 23.30.150.141 169.228.34.84 tunneldomain 23&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With this in place, routing works as expected for all of the cases mentioned above.&lt;br /&gt;
&lt;br /&gt;
== Persistent Configuration Across Router Restarts ==&lt;br /&gt;
&lt;br /&gt;
We now have enough information that we can set up tunnels between our router and arbitrary AMPRNet subnets. However, doing so manually is tedious and not particularly robust. We would like the system to automatically configure our tunnels and default routes at boot time. Fortunately, the OpenBSD startup code can do this easily. For each network interface &amp;lt;code&amp;gt;$if&amp;lt;/code&amp;gt; on the system, we can configure it automatically at boot time by putting configuration commands into the file &amp;lt;code&amp;gt;/etc/hostname.$if&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
There are four interfaces we have configured: the two ethernet interfaces for our external and AMPRNet networks, and the two &#039;&#039;gif&#039;&#039; interfaces with the default incoming tunnel and the tunnel to the UCSD gateway.  Thus, there are four files:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/etc/hostname.cnmac0&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;rdomain 23&lt;br /&gt;
inet 23.30.150.141 0xfffffff8&lt;br /&gt;
!ifconfig lo23 inet 127.0.0.1&lt;br /&gt;
!route -qn -T 23 add default 23.30.150.142&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/etc/hostname.cnmac2&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;rdomain 44&lt;br /&gt;
inet 44.44.107.1 255.255.255.0&lt;br /&gt;
!ifconfig lo44 inet 127.0.0.1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/etc/hostname.gif0&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;rdomain 44&lt;br /&gt;
tunnel 23.30.150.141 0.0.0.0 tunneldomain 23&lt;br /&gt;
inet 44.44.107.1 255.255.255.255&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;/etc/hostname.gif1&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;tunnel 23.30.150.141 169.228.34.84 tunneldomain 23&lt;br /&gt;
inet 44.44.107.1 255.255.255.255&lt;br /&gt;
!route -qn -T 44 add 44.0.0.1/32 -link -iface gif1 -llinfo&lt;br /&gt;
!route -qn -T 44 add default 44.0.0.1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that each routing domain also has its own associated loopback interface, hence configuring &amp;lt;code&amp;gt;lo23&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;lo44&amp;lt;/code&amp;gt;. These interfaces are automatically created when the routing domain is created, but we configure them when we bring up the associated ethernet interfaces.&lt;br /&gt;
&lt;br /&gt;
We can examine the interfaces and separate routing tables to ensure that things are set up as expected:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;$ ifconfig cnmac0&lt;br /&gt;
cnmac0: flags=8843&amp;lt;UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST&amp;gt; rdomain 23 mtu 1500&lt;br /&gt;
        lladdr 44:d9:e7:9f:a7:64&lt;br /&gt;
        index 1 priority 0 llprio 3&lt;br /&gt;
        media: Ethernet autoselect (1000baseT full-duplex)&lt;br /&gt;
        status: active&lt;br /&gt;
        inet 23.30.150.141 netmask 0xfffffff8 broadcast 23.30.150.143&lt;br /&gt;
$ ifconfig cnmac2&lt;br /&gt;
cnmac2: flags=8843&amp;lt;UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST&amp;gt; rdomain 44 mtu 1500&lt;br /&gt;
        lladdr 44:d9:e7:9f:a7:66&lt;br /&gt;
        index 3 priority 0 llprio 3&lt;br /&gt;
        media: Ethernet autoselect (1000baseT full-duplex,master)&lt;br /&gt;
        status: active&lt;br /&gt;
        inet 44.44.107.1 netmask 0xffffff00 broadcast 44.44.107.255&lt;br /&gt;
$ ifconfig gif0&lt;br /&gt;
gif0: flags=8051&amp;lt;UP,POINTOPOINT,RUNNING,MULTICAST&amp;gt; rdomain 44 mtu 1280&lt;br /&gt;
        index 6 priority 0 llprio 3&lt;br /&gt;
        encap: txprio payload rxprio payload&lt;br /&gt;
        groups: gif&lt;br /&gt;
        tunnel: inet 23.30.150.141 -&amp;gt; 0.0.0.0 ttl 64 nodf ecn rdomain 23&lt;br /&gt;
        inet 44.44.107.1 --&amp;gt; 0.0.0.0 netmask 0xffffffff&lt;br /&gt;
$ ifconfig gif1&lt;br /&gt;
gif1: flags=8051&amp;lt;UP,POINTOPOINT,RUNNING,MULTICAST&amp;gt; rdomain 44 mtu 1280&lt;br /&gt;
        index 7 priority 0 llprio 3&lt;br /&gt;
        encap: txprio payload rxprio payload&lt;br /&gt;
        groups: gif&lt;br /&gt;
        tunnel: inet 23.30.150.141 -&amp;gt; 169.228.34.84 ttl 64 nodf ecn rdomain 23&lt;br /&gt;
        inet 44.44.107.1 --&amp;gt; 0.0.0.0 netmask 0xffffffff&lt;br /&gt;
$ route -T 23 -n show -inet&lt;br /&gt;
Routing tables&lt;br /&gt;
&lt;br /&gt;
Internet:&lt;br /&gt;
Destination        Gateway            Flags   Refs      Use   Mtu  Prio Iface&lt;br /&gt;
default            23.30.150.142      UGS        0    51126     -     8 cnmac0&lt;br /&gt;
23.30.150.136/29   23.30.150.141      UCn        1        7     -     4 cnmac0&lt;br /&gt;
23.30.150.141      44:d9:e7:9f:a7:64  UHLl       0    88377     -     1 cnmac0&lt;br /&gt;
23.30.150.142      4a:1d:70:de:c3:5a  UHLch      1      386     -     3 cnmac0&lt;br /&gt;
23.30.150.143      23.30.150.141      UHb        0        0     -     1 cnmac0&lt;br /&gt;
127.0.0.1          127.0.0.1          UHl        0        0 32768     1 lo23&lt;br /&gt;
$ route -T 44 -n show -inet&lt;br /&gt;
Routing tables&lt;br /&gt;
&lt;br /&gt;
Internet:&lt;br /&gt;
Destination        Gateway            Flags   Refs      Use   Mtu  Prio Iface&lt;br /&gt;
default            44.0.0.1           UGS        0    54718     -     8 gif1&lt;br /&gt;
44.0.0.1           link#7             UHLSh      1        2     -     8 gif1&lt;br /&gt;
44.44.107/24       44.44.107.1        UCn       16        4     -     4 cnmac2&lt;br /&gt;
44.44.107.1        44:d9:e7:9f:a7:66  UHLl       0     4825     -     1 cnmac2&lt;br /&gt;
44.44.107.255      44.44.107.1        UHb        0        0     -     1 cnmac2&lt;br /&gt;
127.0.0.1          127.0.0.1          UHl        0        0 32768     1 lo44&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Restricting Traffic with the [ PF] Firewall ==&lt;br /&gt;
&lt;br /&gt;
All of these interfaces will fully integrate with the PF firewall software that comes with OpenBSD, and we can implement nearly arbitrary policies in our configuration.  For example, we might restrict traffic on the external interface to only ICMP messages and IPENCAP datagrams by setting the following rules in &amp;lt;code&amp;gt;/etc/pf.conf&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;# Constants&lt;br /&gt;
extif = &amp;quot;cnmac0&amp;quot;&lt;br /&gt;
extamprgate = &amp;quot;23.30.150.141&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Options&lt;br /&gt;
set skip on lo&lt;br /&gt;
set block-policy return&lt;br /&gt;
&lt;br /&gt;
block return    # block stateless traffic&lt;br /&gt;
pass            # establish keep-state&lt;br /&gt;
&lt;br /&gt;
# Normalize incoming packets.&lt;br /&gt;
match in all scrub (no-df random-id max-mss 1440)&lt;br /&gt;
&lt;br /&gt;
# By default, block everything.  We selectively override in subsequent rules.&lt;br /&gt;
block in on $extif&lt;br /&gt;
&lt;br /&gt;
# Pass 44net traffic&lt;br /&gt;
pass in on $extif inet proto ipencap from any to $extamprgate&lt;br /&gt;
&lt;br /&gt;
# Pass ping and ICMP unreachable messages on external interface&lt;br /&gt;
pass in on $extif inet proto icmp icmp-type echoreq code 0 keep state&lt;br /&gt;
pass in on $extif inet proto icmp icmp-type unreach keep state&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We can verify that these rules are in place as expected by querying the rule tables:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;# pfctl -sr -vv&lt;br /&gt;
@0 block return all&lt;br /&gt;
  [ Evaluations: 115977    Packets: 3776      Bytes: 168422      States: 0     ]&lt;br /&gt;
  [ Inserted: uid 0 pid 31812 State Creations: 0     ]&lt;br /&gt;
@1 pass all flags S/SA&lt;br /&gt;
  [ Evaluations: 115977    Packets: 242418    Bytes: 25899015    States: 253   ]&lt;br /&gt;
  [ Inserted: uid 0 pid 31812 State Creations: 102105]&lt;br /&gt;
@2 match in all scrub (no-df random-id max-mss 1440)&lt;br /&gt;
  [ Evaluations: 115977    Packets: 261105    Bytes: 31394491    States: 136   ]&lt;br /&gt;
  [ Inserted: uid 0 pid 31812 State Creations: 0     ]&lt;br /&gt;
@3 block return in on cnmac0 all&lt;br /&gt;
  [ Evaluations: 64726     Packets: 5925      Bytes: 325492      States: 0     ]&lt;br /&gt;
  [ Inserted: uid 0 pid 31812 State Creations: 0     ]&lt;br /&gt;
@4 pass in on cnmac0 inet proto icmp all icmp-type echoreq code 0&lt;br /&gt;
  [ Evaluations: 8149      Packets: 342       Bytes: 27424       States: 0     ]&lt;br /&gt;
  [ Inserted: uid 0 pid 31812 State Creations: 171   ]&lt;br /&gt;
@5 pass in on cnmac0 inet proto icmp all icmp-type unreach&lt;br /&gt;
  [ Evaluations: 308       Packets: 5         Bytes: 368         States: 0     ]&lt;br /&gt;
  [ Inserted: uid 0 pid 31812 State Creations: 0     ]&lt;br /&gt;
@6 pass in on cnmac0 inet proto ipencap from any to 23.30.150.141&lt;br /&gt;
  [ Evaluations: 8149      Packets: 126197    Bytes: 16538717    States: 5     ]&lt;br /&gt;
  [ Inserted: uid 0 pid 31812 State Creations: 2048  ]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A site can add more elaborate rules as desired.&lt;br /&gt;
&lt;br /&gt;
== Maintaining Mesh Routes with 44ripd ==&lt;br /&gt;
&lt;br /&gt;
The above shows how to set up AMPRNet tunnel interfaces, set routes to them, use routing domains for policy-based routing, and set firewall rules. However, so far all of these steps have been manual. This works for a handful of tunnels and routes, but there are hundreds of subnets AMPRNet in the AMPRNet mesh; maintaining all of these manually is not reasonable.&lt;br /&gt;
&lt;br /&gt;
However, Dan Cross (KZ2X) has written a daemon specific to OpenBSD called &amp;lt;code&amp;gt;44ripd&amp;lt;/code&amp;gt; that maintains tunnel and route information as distributed via the [https://wiki.ampr.org/wiki/RIP AMPRNet RIP] variant sent from &amp;lt;code&amp;gt;44.0.0.1&amp;lt;/code. To use this, make sure that multicasting is enabled on the host by setting &amp;lt;code&amp;gt;multicast=YES&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;/etc/rc.conf.local&amp;lt;/code&amp;gt;, and then retrieve the 44ripd software from Github at https://github.com/dancrossnyc/44ripd. The software is built with the &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt; command. For example:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;git clone https://github.com/dancrossnyc/44ripd&lt;br /&gt;
cd 44ripd&lt;br /&gt;
make&lt;br /&gt;
doas install -c -o root -g wheel -m 555 44ripd /usr/local/sbin&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once installed, this can be run at boot by adding the following lines to &amp;lt;code&amp;gt;/etc/rc.local&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;if [ -x /usr/local/sbin/44ripd ]; then&lt;br /&gt;
        echo -n &#039; 44ripd&#039;&lt;br /&gt;
        route -T 44 exec /usr/local/sbin/44ripd -s0 -s1 -D 44 -T 23&lt;br /&gt;
fi&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that the &amp;lt;code&amp;gt;-s&amp;lt;/code&amp;gt; options instruct the daemon not to try and allocate the &amp;lt;code&amp;gt;gif0&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;gif1&amp;lt;/code&amp;gt; interfaces, as these are manually configured.&lt;br /&gt;
&lt;br /&gt;
=== Set the Default AMPRNet Tunnel and Route Manually ===&lt;br /&gt;
&lt;br /&gt;
While route information for the UCSD AMPRNet gateway is distributed in RIP44 packets and we could in theory only configure the default incoming tunnel and rely on 44ripd to set up a route to UCSD, this leads to a problem. Specifically, without an interface configured to the UCSD gateway, we cannot set a default route in our AMRPNet routing domain for the gateway. Since we rely on periodic route broadcasts from UCSD to set those routes, we would delay setting up our default route for an indeterminate amount of time (on the order of minutes).&lt;br /&gt;
&lt;br /&gt;
Thus, it is advised to explicitly configure the tunnel to UCSD at boot time along with the default route.&lt;br /&gt;
&lt;br /&gt;
=== Notes on 44ripd Implementation ===&lt;br /&gt;
&lt;br /&gt;
* 44ripd maintains a copy of the AMPRNet routing table in a modified PATRICIA trie (really a compressed radix tree).&lt;br /&gt;
* A similar table of tunnels is maintained.&lt;br /&gt;
* Tunnel interfaces are reference counted and garbage collected. A bitmap indicating which tunnels are in use is maintained.&lt;br /&gt;
* Routes are expired after receiving a RIP packet.&lt;br /&gt;
* The program is completely self-contained in the sense that it does not fork/exec external commands to configure tunnels or manipulate routes.  That is all done via ioctls or writing messages to a routing socket.&lt;br /&gt;
* 44ripd does not examine the state of the system or routing tables at startup to bootstrap its internal state, but arguably should.&lt;br /&gt;
* Bugs in 44ripd should be reported via Github issues.&lt;br /&gt;
* Exporting and/or parsing an encap file would be nice.&lt;br /&gt;
* Logging and error checking can always be improved.&lt;/div&gt;</summary>
		<author><name>Cross</name></author>
	</entry>
	<entry>
		<id>https://wiki.ampr.org/w/index.php?title=Setting_up_a_gateway_on_OpenBSD&amp;diff=909</id>
		<title>Setting up a gateway on OpenBSD</title>
		<link rel="alternate" type="text/html" href="https://wiki.ampr.org/w/index.php?title=Setting_up_a_gateway_on_OpenBSD&amp;diff=909"/>
		<updated>2021-01-08T14:20:14Z</updated>

		<summary type="html">&lt;p&gt;Cross: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
[https://www.openbsd.org OpenBSD] is a mature Unix-like operating system that focuses on security and correctness. It features a flexible, robust, performant TCP/IP stack and a [https://www.openbsd.org/faq/pf/ highly configurable firewall]. This page describes how to configure a computer running OpenBSD as an AMPRNet router to transfer traffic between AMPRNet subnets and the Internet.&lt;br /&gt;
&lt;br /&gt;
OpenBSD natively supports [https://en.wikipedia.org/wiki/IP_in_IP IPENCAP (IP-IP)] tunnels through [https://man.openbsd.org/gif.4 &#039;&#039;gif&#039;&#039;(4)] pseudo-devices. Each &#039;&#039;gif&#039;&#039; device is a virtual network interface, synthesized by the operating system, that implements a point-to-point tunnel. Unlike Linux, OpenBSD requires a separate &#039;&#039;gif&#039;&#039; interface for each tunnel. An essentially arbitrary number of such interfaces can be created and it scales to the number required to route all of AMPRNet.&lt;br /&gt;
&lt;br /&gt;
One can manually configure &#039;&#039;gif&#039;&#039; tunnels and routes at the command line, or configure the system to establish tunnels and routes at boot time.&lt;br /&gt;
&lt;br /&gt;
We will describe how to set things up by way of example. Assume a system configuration that looks substantially similar to the following:&lt;br /&gt;
&lt;br /&gt;
* A dedicated static IP address to use as an endpoint for AMPRNet traffic.&lt;br /&gt;
* An ISP-provided router that is just a router; no NATing, no firewall.&lt;br /&gt;
* An OpenBSD computer with three ethernet interfaces. For example, using a Ubiquiti EdgeRouter 3 Lite:&lt;br /&gt;
*# cnmac0 is the external interface connected to the ISP&#039;s network (in this example, we use 23.30.150.141 routing to 23.30.150.142)&lt;br /&gt;
*# cnmac1 connects to an internal network (its configuration is irrelevant)&lt;br /&gt;
*# cnmac2 is the internal interface connected to the subnet (in this example, we use 44.44.107.1 routing for 44.44.107.0/24)&lt;br /&gt;
&lt;br /&gt;
Let us start by configuring a single tunnel and route to the AMPRNet gateway at UCSD:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;ifconfig gif1 create&lt;br /&gt;
ifconfig gif1 tunnel 23.30.150.141 169.228.34.84&lt;br /&gt;
ifconfig gif1 inet 44.44.107.1 netmask 255.255.255.255&lt;br /&gt;
route add -host 44.0.0.1 -link -iface gif1 -llinfo&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first command creates the interface, causing the kernel to synthesize it into existence. The second configures the tunnel itself: that is, the the IP addresses that will be put into the IPENCAP datagram that the tunnel creates: the first address is the &#039;&#039;local&#039;&#039; address, which will serve as the source address for the IPENCAP packet, while the second is the &#039;&#039;remote&#039;&#039; address, to which the packet will be sent. The third sets an IP address for the local endpoint of the interface: this exists solely so that traffic that is generated by the router, such as ICMP error messages (host or port unreachable, for example), have a valid source address. Note that despite the fact that this is a point-to-point interface, we do not specify the IP address of the remote end.&lt;br /&gt;
&lt;br /&gt;
The fourth and final command creates a host route and associates it with the tunnel interface. The &amp;lt;code&amp;gt;-link&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;-iface&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;-llinfo&amp;lt;/code&amp;gt; flags indicate that this is an interface route, and that traffic for the route should go directly to the given interface (&amp;lt;code&amp;gt;gif1&amp;lt;/code&amp;gt;) instead of identifying the gateway via an IP address. We can examine this route from the commandline. E.g.,&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;$ route -n show -inet | grep &#039;44\.0\.0\.1 &#039;&lt;br /&gt;
44.0.0.1           link#7             UHLSh      1        2     -     8 gif1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Consult the manual page for [https://man.openbsd.org/netstat.1 &#039;&#039;netstat&#039;&#039;(1)] for details on what the &amp;lt;code&amp;gt;UHLSh&amp;lt;/code&amp;gt; flags mean.&lt;br /&gt;
&lt;br /&gt;
We can repeat this process for each AMPRNet tunnel, creating interfaces and adding routes for each subnet.&lt;br /&gt;
&lt;br /&gt;
== Handling Encapsulated Inbound Traffic Without a Reciprocal Tunnel ==&lt;br /&gt;
&lt;br /&gt;
When an inbound IPENCAP datagram arrives on our external interface, the network stack in the OpenBSD kernel recognizes it by examining the protocol number in the IP header: IPENCAP is protocol number 4 (not to be confused with IP version 4). Any such packets are passed to the packet input function in the &#039;&#039;gif&#039;&#039; implementation, which searches all configured &#039;&#039;gif&#039;&#039; interfaces trying to find match the configured tunnel source and destinations addresses with the corresponding addresses in the inbound packet. If such an interface is found, the packet is enqueued to the interface, which will strip the IPENCAP header and route the resulting &amp;quot;de-encapsulated&amp;quot; IP packet. This works for tunnels that are configured bidirectionally between any two sites. That is, if site A has a tunnel to site B, and B has a corresponding tunnel to A, they can send each other traffic.&lt;br /&gt;
&lt;br /&gt;
Now consider the case where site A has a tunnel configured to send traffic to site B, but B has no tunnel configured to A: in this case, the datagram arrives as before and is presented to the &#039;&#039;gif&#039;&#039; implementation, but the search above fails since B has no tunnel to A, so nothing matches the source &#039;&#039;and&#039;&#039; destination addresses on the incoming packet. In this case, the system might be responsible for routing such packets to another computer or network, so the packet is not de-encapsulated and processed. However, in an AMPRNet context, we very well may want to process that packet. Accordingly, the &#039;&#039;gif&#039;&#039; implementation has a mechanism for describing an interface that accepts encapsulated traffic from any source destined to a local address. If we configure a &#039;&#039;gif&#039;&#039; interface where the distant end of the &#039;&#039;tunnel&#039;&#039; set to &amp;lt;code&amp;gt;0.0.0.0&amp;lt;/code&amp;gt;, then any incoming datagram where the destination address is the same as the local address on the interface, will be accepted and de-encapsulated and processed as before. Using this, we can set up an interface specifically for accepting traffic from systems to which we have not defined a tunnel:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;ifconfig gif0 create&lt;br /&gt;
ifconfig gif0 tunnel 23.30.150.141 0.0.0.0&lt;br /&gt;
ifconfig gif0 inet 44.44.107.1 255.255.255.255&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note the &amp;lt;code&amp;gt;0.0.0.0&amp;lt;/code&amp;gt; as the remote address in the &amp;lt;code&amp;gt;ifconfig tunnel&amp;lt;/code&amp;gt; command. Again, we set an interface address using our local AMPRNet router address purely for locally generated traffic.&lt;br /&gt;
&lt;br /&gt;
One this interface is configured, IPENCAP traffic from remote systems that have defined tunnels to us will flow, regardless of whether we have created a tunnel to them.&lt;br /&gt;
&lt;br /&gt;
== Policy-based Routing Using Routing Domains ==&lt;br /&gt;
&lt;br /&gt;
The configuration explored so far is sufficient to make connections to AMPRNet directly-configured AMPRNet subnets, but suffers from a number of deficiencies. In particular, there are two issues that we will discuss now.&lt;br /&gt;
&lt;br /&gt;
First, there is a problem with exchanging traffic with non-AMPRNet systems on the Internet. Presumably, these systems are not aware of AMPRNet tunneling, so traffic from them goes to the gateway at UCSD, where it will be encapsulated and sent through a tunnel to the external interface on our router. There, it will be de-encapsulated and delivered into our subnet. However, return traffic will be sent to the router, but since the destination is generally a tunnel, it will be sent via the default route, but from an AMPRNet source address. Since most ISPs will not pass AMPRNet traffic, the result will likely be lost before it reaches the destination. We may think it would be possible to work around that using a firewall rule to NAT the source address to something provided by our ISP, but even if the resulting datagram made it to the destination, for a protocol like TCP it would no longer match the 5-tuple for the connection, and would thus be lost.&lt;br /&gt;
&lt;br /&gt;
The second problem is how reaching AMPRNet systems for which we have not configured a tunnel.  Without a tunnel, and thus a route, we cannot send traffic to those systems.&lt;br /&gt;
&lt;br /&gt;
We can solve both of these problems by sending all of our traffic through a tunnel interface to the UCSD gateway by default, e.g., by setting the default route:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;route add default 4.0.0.1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, how does the encapsulated traffic from the tunnel interface get sent to our ISP&#039;s router? We can add a host route for the UCSD gateway in our local routing table, but we have to do this for every tunnel, which is unwieldy. Further, connecting to our external interface becomes complicated: suppose someone &amp;lt;code&amp;gt;ping&amp;lt;/code&amp;gt;s our external interface. Assuming we permit this, the response would be routed through the UCSD gateway tunnel, but even if the gateway passed arbitrary traffic back onto the Internet, the packet might be lost as upstream ISPs would refuse to route it.&lt;br /&gt;
&lt;br /&gt;
The solution to all of these problems is to use [https://en.wikipedia.org/wiki/Policy-based_routing &#039;&#039;policy-based routing&#039;&#039;]. Specifically, we would like to make routing decisions based on the source IP address of our traffic. We might be able to do this with firewall rules, but the edge cases get complicated very quickly. Fortunately, there is another way: [https://man.openbsd.org/rdomain.4 routing domains].&lt;br /&gt;
&lt;br /&gt;
Routing domains in OpenBSD are a mechanism to isolate routing decisions from one another. Network interfaces are configured into exactly one routing domain, which has its own private set of routing tables. Those tables are isolated, but traffic can be passed between routing domains via firewall rules.&lt;br /&gt;
&lt;br /&gt;
In our example, we put our external and local AMPRNet gateway interfaces into separate routing domains: all of the &#039;&#039;gif&#039;&#039; interfaces and the local AMPRNet gateway interface can both be assigned to routing domain 44, while the external interface might be 23. Routing domain 0 is the default. Note that the numbers here are arbitrary, and we can choose any value below 256 that we like; these are chosen to match the first octet of our example addresses.&lt;br /&gt;
&lt;br /&gt;
The routing domain on an interface is set using the &amp;lt;code&amp;gt;rdomain&amp;lt;/code&amp;gt; parameter to &amp;lt;code&amp;gt;ifconfig&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;ifconfig cnmac0 rdomain 23&lt;br /&gt;
ifconfig gif0 rdomain 44&lt;br /&gt;
ifconfig gif1 rdomain 44&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We set the default route in the routing domain that owns our external interface to our ISP&#039;s router, while in the routing domain hosting our AMPRNet presence we can set it to the UCSD gateway:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;route -T 23 add default 23.30.150.242&lt;br /&gt;
route -T 44 add default 44.0.0.1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now traffic on our AMPRNet subnet will be routed through the UCSD gateway, while traffic on the external interface will be routed through our ISP&#039;s router.&lt;br /&gt;
&lt;br /&gt;
Another piece of functionality allows us to dispense with much of the complexity of routing between domains: the tunnel assigned to a &#039;&#039;gif&#039;&#039; can be in a different routing domain than the interface itself. Going back to our example, if we place each of our &#039;&#039;gif&#039;&#039; interfaces into routing domain 44 then traffic routed out to on coming in from the tunnel will be routed with our AMPRNet-specific routing table. But if we place the tunnel on that interface into routing domain 23, then the encapsulated traffic that we send to and from the Internet (e.g., to other tunnel end points) will be routed in that domain, thus routing through our ISP&#039;s network. Critically, matching incoming datagrams to &#039;&#039;gif&#039;&#039; interfaces as described above happens in the routing domain associated with the tunnel, so inbound traffic coming through our external interface will be directed to the correct interface.&lt;br /&gt;
&lt;br /&gt;
We specify the routing domain of a tunnel via the &amp;lt;code&amp;gt;tunneldomain&amp;lt;/code&amp;gt; parameter to &amp;lt;code&amp;gt;ifconfig&amp;lt;/code&amp;gt; when configuring the route on an interface:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;ifconfig gif0 tunnel 23.30.150.141 0.0.0.0 tunneldomain 23&lt;br /&gt;
ifconfig gif1 tunnel 23.30.150.141 169.228.34.84 tunneldomain 23&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With this in place, routing works as expected for all of the cases mentioned above.&lt;br /&gt;
&lt;br /&gt;
== Persistent Configuration Across Router Restarts ==&lt;br /&gt;
&lt;br /&gt;
We now have enough information that we can set up tunnels between our router and arbitrary AMPRNet subnets. However, doing so manually is tedious and not particularly robust. We would like the system to automatically configure our tunnels and default routes at boot time. Fortunately, the OpenBSD startup code can do this easily. For each network interface &amp;lt;code&amp;gt;$if&amp;lt;/code&amp;gt; on the system, we can configure it automatically at boot time by putting configuration commands into the file &amp;lt;code&amp;gt;/etc/hostname.$if&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
There are four interfaces we have configured: the two ethernet interfaces for our external and AMPRNet networks, and the two &#039;&#039;gif&#039;&#039; interfaces with the default incoming tunnel and the tunnel to the UCSD gateway.  Thus, there are four files:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/etc/hostname.cnmac0&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;rdomain 23&lt;br /&gt;
inet 23.30.150.141 0xfffffff8&lt;br /&gt;
!ifconfig lo23 inet 127.0.0.1&lt;br /&gt;
!route -qn -T 23 add default 23.30.150.142&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/etc/hostname.cnmac2&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;rdomain 44&lt;br /&gt;
inet 44.44.107.1 255.255.255.0&lt;br /&gt;
!ifconfig lo44 inet 127.0.0.1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;/etc/hostname.gif0&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;rdomain 44&lt;br /&gt;
tunnel 23.30.150.141 0.0.0.0 tunneldomain 23&lt;br /&gt;
inet 44.44.107.1 255.255.255.255&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;/etc/hostname.gif1&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;tunnel 23.30.150.141 169.228.34.84 tunneldomain 23&lt;br /&gt;
inet 44.44.107.1 255.255.255.255&lt;br /&gt;
!route -qn -T 44 add 44.0.0.1/32 -link -iface gif1 -llinfo&lt;br /&gt;
!route -qn -T 44 add default 44.0.0.1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that each routing domain also has its own associated loopback interface, hence configuring &amp;lt;code&amp;gt;lo23&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;lo44&amp;lt;/code&amp;gt;. These interfaces are automatically created when the routing domain is created, but we configure them when we bring up the associated ethernet interfaces.&lt;br /&gt;
&lt;br /&gt;
We can examine the interfaces and separate routing tables to ensure that things are set up as expected:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;$ ifconfig cnmac0&lt;br /&gt;
cnmac0: flags=8843&amp;lt;UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST&amp;gt; rdomain 23 mtu 1500&lt;br /&gt;
        lladdr 44:d9:e7:9f:a7:64&lt;br /&gt;
        index 1 priority 0 llprio 3&lt;br /&gt;
        media: Ethernet autoselect (1000baseT full-duplex)&lt;br /&gt;
        status: active&lt;br /&gt;
        inet 23.30.150.141 netmask 0xfffffff8 broadcast 23.30.150.143&lt;br /&gt;
$ ifconfig cnmac2&lt;br /&gt;
cnmac2: flags=8843&amp;lt;UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST&amp;gt; rdomain 44 mtu 1500&lt;br /&gt;
        lladdr 44:d9:e7:9f:a7:66&lt;br /&gt;
        index 3 priority 0 llprio 3&lt;br /&gt;
        media: Ethernet autoselect (1000baseT full-duplex,master)&lt;br /&gt;
        status: active&lt;br /&gt;
        inet 44.44.107.1 netmask 0xffffff00 broadcast 44.44.107.255&lt;br /&gt;
$ ifconfig gif0&lt;br /&gt;
gif0: flags=8051&amp;lt;UP,POINTOPOINT,RUNNING,MULTICAST&amp;gt; rdomain 44 mtu 1280&lt;br /&gt;
        index 6 priority 0 llprio 3&lt;br /&gt;
        encap: txprio payload rxprio payload&lt;br /&gt;
        groups: gif&lt;br /&gt;
        tunnel: inet 23.30.150.141 -&amp;gt; 0.0.0.0 ttl 64 nodf ecn rdomain 23&lt;br /&gt;
        inet 44.44.107.1 --&amp;gt; 0.0.0.0 netmask 0xffffffff&lt;br /&gt;
$ ifconfig gif1&lt;br /&gt;
gif1: flags=8051&amp;lt;UP,POINTOPOINT,RUNNING,MULTICAST&amp;gt; rdomain 44 mtu 1280&lt;br /&gt;
        index 7 priority 0 llprio 3&lt;br /&gt;
        encap: txprio payload rxprio payload&lt;br /&gt;
        groups: gif&lt;br /&gt;
        tunnel: inet 23.30.150.141 -&amp;gt; 169.228.34.84 ttl 64 nodf ecn rdomain 23&lt;br /&gt;
        inet 44.44.107.1 --&amp;gt; 0.0.0.0 netmask 0xffffffff&lt;br /&gt;
$ route -T 23 -n show -inet&lt;br /&gt;
Routing tables&lt;br /&gt;
&lt;br /&gt;
Internet:&lt;br /&gt;
Destination        Gateway            Flags   Refs      Use   Mtu  Prio Iface&lt;br /&gt;
default            23.30.150.142      UGS        0    51126     -     8 cnmac0&lt;br /&gt;
23.30.150.136/29   23.30.150.141      UCn        1        7     -     4 cnmac0&lt;br /&gt;
23.30.150.141      44:d9:e7:9f:a7:64  UHLl       0    88377     -     1 cnmac0&lt;br /&gt;
23.30.150.142      4a:1d:70:de:c3:5a  UHLch      1      386     -     3 cnmac0&lt;br /&gt;
23.30.150.143      23.30.150.141      UHb        0        0     -     1 cnmac0&lt;br /&gt;
127.0.0.1          127.0.0.1          UHl        0        0 32768     1 lo23&lt;br /&gt;
$ route -T 44 -n show -inet&lt;br /&gt;
Routing tables&lt;br /&gt;
&lt;br /&gt;
Internet:&lt;br /&gt;
Destination        Gateway            Flags   Refs      Use   Mtu  Prio Iface&lt;br /&gt;
default            44.0.0.1           UGS        0    54718     -     8 gif1&lt;br /&gt;
44.0.0.1           link#7             UHLSh      1        2     -     8 gif1&lt;br /&gt;
44.44.107/24       44.44.107.1        UCn       16        4     -     4 cnmac2&lt;br /&gt;
44.44.107.1        44:d9:e7:9f:a7:66  UHLl       0     4825     -     1 cnmac2&lt;br /&gt;
44.44.107.255      44.44.107.1        UHb        0        0     -     1 cnmac2&lt;br /&gt;
127.0.0.1          127.0.0.1          UHl        0        0 32768     1 lo44&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Restricting Traffic with the [ PF] Firewall ==&lt;br /&gt;
&lt;br /&gt;
All of these interfaces will fully integrate with the PF firewall software that comes with OpenBSD, and we can implement nearly arbitrary policies in our configuration.  For example, we might restrict traffic on the external interface to only ICMP messages and IPENCAP datagrams by setting the following rules in &amp;lt;code&amp;gt;/etc/pf.conf&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;# Constants&lt;br /&gt;
extif = &amp;quot;cnmac0&amp;quot;&lt;br /&gt;
extamprgate = &amp;quot;23.30.150.141&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Options&lt;br /&gt;
set skip on lo&lt;br /&gt;
set block-policy return&lt;br /&gt;
&lt;br /&gt;
block return    # block stateless traffic&lt;br /&gt;
pass            # establish keep-state&lt;br /&gt;
&lt;br /&gt;
# Normalize incoming packets.&lt;br /&gt;
match in all scrub (no-df random-id max-mss 1440)&lt;br /&gt;
&lt;br /&gt;
# By default, block everything.  We selectively override in subsequent rules.&lt;br /&gt;
block in on $extif&lt;br /&gt;
&lt;br /&gt;
# Pass 44net traffic&lt;br /&gt;
pass in on $extif inet proto ipencap from any to $extamprgate&lt;br /&gt;
&lt;br /&gt;
# Pass ping and ICMP unreachable messages on external interface&lt;br /&gt;
pass in on $extif inet proto icmp icmp-type echoreq code 0 keep state&lt;br /&gt;
pass in on $extif inet proto icmp icmp-type unreach keep state&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We can verify that these rules are in place as expected by querying the rule tables:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;# pfctl -sr -vv&lt;br /&gt;
@0 block return all&lt;br /&gt;
  [ Evaluations: 115977    Packets: 3776      Bytes: 168422      States: 0     ]&lt;br /&gt;
  [ Inserted: uid 0 pid 31812 State Creations: 0     ]&lt;br /&gt;
@1 pass all flags S/SA&lt;br /&gt;
  [ Evaluations: 115977    Packets: 242418    Bytes: 25899015    States: 253   ]&lt;br /&gt;
  [ Inserted: uid 0 pid 31812 State Creations: 102105]&lt;br /&gt;
@2 match in all scrub (no-df random-id max-mss 1440)&lt;br /&gt;
  [ Evaluations: 115977    Packets: 261105    Bytes: 31394491    States: 136   ]&lt;br /&gt;
  [ Inserted: uid 0 pid 31812 State Creations: 0     ]&lt;br /&gt;
@3 block return in on cnmac0 all&lt;br /&gt;
  [ Evaluations: 64726     Packets: 5925      Bytes: 325492      States: 0     ]&lt;br /&gt;
  [ Inserted: uid 0 pid 31812 State Creations: 0     ]&lt;br /&gt;
@4 pass in on cnmac0 inet proto icmp all icmp-type echoreq code 0&lt;br /&gt;
  [ Evaluations: 8149      Packets: 342       Bytes: 27424       States: 0     ]&lt;br /&gt;
  [ Inserted: uid 0 pid 31812 State Creations: 171   ]&lt;br /&gt;
@5 pass in on cnmac0 inet proto icmp all icmp-type unreach&lt;br /&gt;
  [ Evaluations: 308       Packets: 5         Bytes: 368         States: 0     ]&lt;br /&gt;
  [ Inserted: uid 0 pid 31812 State Creations: 0     ]&lt;br /&gt;
@6 pass in on cnmac0 inet proto ipencap from any to 23.30.150.141&lt;br /&gt;
  [ Evaluations: 8149      Packets: 126197    Bytes: 16538717    States: 5     ]&lt;br /&gt;
  [ Inserted: uid 0 pid 31812 State Creations: 2048  ]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A site can add more elaborate rules as desired.&lt;br /&gt;
&lt;br /&gt;
== Maintaining Mesh Routes with 44ripd ==&lt;br /&gt;
&lt;br /&gt;
The above shows how to set up AMPRNet tunnel interfaces, set routes to them, use routing domains for policy-based routing, and set firewall rules. However, so far all of these steps have been manual. This works for a handful of tunnels and routes, but there are hundreds of subnets AMPRNet in the AMPRNet mesh; maintaining all of these manually is not reasonable.&lt;br /&gt;
&lt;br /&gt;
However, Dan Cross (KZ2X) has written a daemon specific to OpenBSD called &amp;lt;code&amp;gt;44ripd&amp;lt;/code&amp;gt; that maintains tunnel and route information as distributed via the [https://wiki.ampr.org/wiki/RIP AMPRNet RIP] variant sent from &amp;lt;code&amp;gt;44.0.0.1&amp;lt;/code. To use this, make sure that multicasting is enabled on the host by setting &amp;lt;code&amp;gt;multicast=YES&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;/etc/rc.conf.local&amp;lt;/code&amp;gt;, and then retrieve the 44ripd software from Github at https://github.com/dancrossnyc/44ripd. The software is built with the &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt; command. For example:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;git clone https://github.com/dancrossnyc/44ripd&lt;br /&gt;
cd 44ripd&lt;br /&gt;
make&lt;br /&gt;
doas install -c -o root -g wheel -m 555 44ripd /usr/local/sbin&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once installed, this can be run at boot by adding the following lines to &amp;lt;code&amp;gt;/etc/rc.local&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;if [ -x /usr/local/sbin/44ripd ]; then&lt;br /&gt;
        echo -n &#039; 44ripd&#039;&lt;br /&gt;
        route -T 44 exec /usr/local/sbin/44ripd -s0 -s1 -D 44 -T 23&lt;br /&gt;
fi&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that the &amp;lt;code&amp;gt;-s&amp;lt;/code&amp;gt; options instruct the daemon not to try and allocate the &amp;lt;code&amp;gt;gif0&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;gif1&amp;lt;/code&amp;gt; interfaces, as these are manually configured.&lt;br /&gt;
&lt;br /&gt;
=== Set the Default AMPRNet Route Manually ===&lt;br /&gt;
&lt;br /&gt;
While route information for the UCSD AMPRNet gateway is distributed in RIP44 packets and we could in theory only configure the default incoming tunnel and rely on 44ripd to set up a route to UCSD, this leads to a problem. Specifically, without an interface configured to the UCSD gateway, we cannot set a default route in our AMRPNet routing domain for the gateway. Since we rely on periodic route broadcasts from UCSD to set those routes, we would delay setting up our default route for an indeterminate amount of time (on the order of minutes).&lt;br /&gt;
&lt;br /&gt;
Thus, it is advised to explicitly configure the tunnel to UCSD at boot time along with the default route.&lt;br /&gt;
&lt;br /&gt;
=== Notes on 44ripd Implementation ===&lt;br /&gt;
&lt;br /&gt;
* 44ripd maintains a copy of the AMPRNet routing table in a modified PATRICIA trie (really a compressed radix tree).&lt;br /&gt;
* A similar table of tunnels is maintained.&lt;br /&gt;
* Tunnel interfaces are reference counted and garbage collected. A bitmap indicating which tunnels are in use is maintained.&lt;br /&gt;
* Routes are expired after receiving a RIP packet.&lt;br /&gt;
* The program is completely self-contained in the sense that it does not fork/exec external commands to configure tunnels or manipulate routes.  That is all done via ioctls or writing messages to a routing socket.&lt;br /&gt;
* 44ripd does not examine the state of the system or routing tables at startup to bootstrap its internal state, but arguably should.&lt;br /&gt;
* Bugs in 44ripd should be reported via Github issues.&lt;br /&gt;
* Exporting and/or parsing an encap file would be nice.&lt;br /&gt;
* Logging and error checking can always be improved.&lt;/div&gt;</summary>
		<author><name>Cross</name></author>
	</entry>
	<entry>
		<id>https://wiki.ampr.org/w/index.php?title=Setting_up_a_gateway_on_OpenBSD&amp;diff=908</id>
		<title>Setting up a gateway on OpenBSD</title>
		<link rel="alternate" type="text/html" href="https://wiki.ampr.org/w/index.php?title=Setting_up_a_gateway_on_OpenBSD&amp;diff=908"/>
		<updated>2021-01-08T03:35:48Z</updated>

		<summary type="html">&lt;p&gt;Cross: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
[https://www.openbsd.org OpenBSD] is a mature Unix-like operating system that focuses on security and correctness. It features a flexible, robust, performant TCP/IP stack and a [https://www.openbsd.org/faq/pf/ highly configurable firewall]. This page describes how to configure a computer running OpenBSD as an AMPRNet router to transfer traffic between AMPRNet subnets and the Internet.&lt;br /&gt;
&lt;br /&gt;
OpenBSD natively supports [https://en.wikipedia.org/wiki/IP_in_IP IPENCAP (IP-IP)] tunnels through [https://man.openbsd.org/gif.4 &#039;&#039;gif&#039;&#039;(4)] pseudo-devices. Each &#039;&#039;gif&#039;&#039; device is a virtual network interface, synthesized by the operating system, that implements a point-to-point tunnel. Unlike Linux, OpenBSD requires a separate &#039;&#039;gif&#039;&#039; interface for each tunnel. An essentially arbitrary number of such interfaces can be created and it scales to the number required to route all of AMPRNet.&lt;br /&gt;
&lt;br /&gt;
One can manually configure &#039;&#039;gif&#039;&#039; tunnels and routes at the command line, or configure the system to establish tunnels and routes at boot time.&lt;br /&gt;
&lt;br /&gt;
We will describe how to set things up by way of example. Assume a system configuration that looks substantially similar to the following:&lt;br /&gt;
&lt;br /&gt;
* A dedicated static IP address to use as an endpoint for AMPRNet traffic.&lt;br /&gt;
* An ISP-provided router that is just a router; no NATing, no firewall.&lt;br /&gt;
* An OpenBSD computer with three ethernet interfaces. For example, using a Ubiquiti EdgeRouter 3 Lite:&lt;br /&gt;
*# cnmac0 is the external interface connected to the ISP&#039;s network (in this example, we use 23.30.150.141 routing to 23.30.150.142)&lt;br /&gt;
*# cnmac1 connects to an internal network (its configuration is irrelevant)&lt;br /&gt;
*# cnmac2 is the internal interface connected to the subnet (in this example, we use 44.44.107.1 routing for 44.44.107.0/24)&lt;br /&gt;
&lt;br /&gt;
Let us start by configuring a single tunnel and route to the AMPRNet gateway at UCSD:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;ifconfig gif1 create&lt;br /&gt;
ifconfig gif1 tunnel 23.30.150.141 169.228.34.84&lt;br /&gt;
ifconfig gif1 inet 44.44.107.1 netmask 255.255.255.255&lt;br /&gt;
route add -host 44.0.0.1 -link -iface gif1 -llinfo&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first command creates the interface, causing the kernel to synthesize it into existence. The second configures the tunnel itself: that is, the the IP addresses that will be put into the IPENCAP datagram that the tunnel creates: the first address is the &#039;&#039;local&#039;&#039; address, which will serve as the source address for the IPENCAP packet, while the second is the &#039;&#039;remote&#039;&#039; address, to which the packet will be sent. The third sets an IP address for the local endpoint of the interface: this exists solely so that traffic that is generated by the router, such as ICMP error messages (host or port unreachable, for example), have a valid source address. Note that despite the fact that this is a point-to-point interface, we do not specify the IP address of the remote end. The fourth and final command creates a host route and associates it with the tunnel interface.&lt;br /&gt;
&lt;br /&gt;
We can repeat this process for each AMPRNet tunnel, creating interfaces and adding routes for each subnet.&lt;br /&gt;
&lt;br /&gt;
== Handling Encapsulated Inbound Traffic Without a Reciprocal Tunnel ==&lt;br /&gt;
&lt;br /&gt;
When an inbound IPENCAP datagram arrives on our external interface, the network stack in the OpenBSD kernel recognizes it by examining the protocol number in the IP header: IPENCAP is protocol number 4 (not to be confused with IP version 4). Any such packets are passed to the packet input function in the &#039;&#039;gif&#039;&#039; implementation, which searches all configured &#039;&#039;gif&#039;&#039; interfaces trying to find match the configured tunnel source and destinations addresses with the corresponding addresses in the inbound packet. If such an interface is found, the packet is enqueued to the interface, which will strip the IPENCAP header and route the resulting &amp;quot;de-encapsulated&amp;quot; IP packet. This works for tunnels that are configured bidirectionally between any two sites. That is, if site A has a tunnel to site B, and B has a corresponding tunnel to A, they can send each other traffic.&lt;br /&gt;
&lt;br /&gt;
Now consider the case where site A has a tunnel configured to send traffic to site B, but B has no tunnel configured to A: in this case, the datagram arrives as before and is presented to the &#039;&#039;gif&#039;&#039; implementation, but the search above fails since B has no tunnel to A, so nothing matches the source &#039;&#039;and&#039;&#039; destination addresses on the incoming packet. In this case, the system might be responsible for routing such packets to another computer or network, so the packet is not de-encapsulated and processed. However, in an AMPRNet context, we very well may want to process that packet. Accordingly, the &#039;&#039;gif&#039;&#039; implementation has a mechanism for describing an interface that accepts encapsulated traffic from any source destined to a local address. If we configure a &#039;&#039;gif&#039;&#039; interface where the distant end of the &#039;&#039;tunnel&#039;&#039; set to &amp;lt;code&amp;gt;0.0.0.0&amp;lt;/code&amp;gt;, then any incoming datagram where the destination address is the same as the local address on the interface, will be accepted and de-encapsulated and processed as before. Using this, we can set up an interface specifically for accepting traffic from systems to which we have not defined a tunnel:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;ifconfig gif0 create&lt;br /&gt;
ifconfig gif0 tunnel 23.30.150.141 0.0.0.0&lt;br /&gt;
ifconfig gif0 inet 44.44.107.1 255.255.255.255&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note the &amp;lt;code&amp;gt;0.0.0.0&amp;lt;/code&amp;gt; as the remote address in the &amp;lt;code&amp;gt;ifconfig tunnel&amp;lt;/code&amp;gt; command. Again, we set an interface address using our local AMPRNet router address purely for locally generated traffic.&lt;br /&gt;
&lt;br /&gt;
One this interface is configured, IPENCAP traffic from remote systems that have defined tunnels to us will flow, regardless of whether we have created a tunnel to them.&lt;br /&gt;
&lt;br /&gt;
== Policy-based Routing Using Routing Domains ==&lt;br /&gt;
&lt;br /&gt;
The configuration explored so far is sufficient to make connections to AMPRNet directly-configured AMPRNet subnets, but suffers from a number of deficiencies. In particular, there are two issues that we will discuss now.&lt;br /&gt;
&lt;br /&gt;
First, there is a problem with exchanging traffic with non-AMPRNet systems on the Internet. Presumably, these systems are not aware of AMPRNet tunneling, so traffic from them goes to the gateway at UCSD, where it will be encapsulated and sent through a tunnel to the external interface on our router. There, it will be de-encapsulated and delivered into our subnet. However, return traffic will be sent to the router, but since the destination is generally a tunnel, it will be sent via the default route, but from an AMPRNet source address. Since most ISPs will not pass AMPRNet traffic, the result will likely be lost before it reaches the destination. We may think it would be possible to work around that using a firewall rule to NAT the source address to something provided by our ISP, but even if the resulting datagram made it to the destination, for a protocol like TCP it would no longer match the 5-tuple for the connection, and would thus be lost.&lt;br /&gt;
&lt;br /&gt;
The second problem is how reaching AMPRNet systems for which we have not configured a tunnel.  Without a tunnel, and thus a route, we cannot send traffic to those systems.&lt;br /&gt;
&lt;br /&gt;
We can solve both of these problems by sending all of our traffic through a tunnel interface to the UCSD gateway by default, e.g., by setting the default route:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;route add default 4.0.0.1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, how does the encapsulated traffic from the tunnel interface get sent to our ISP&#039;s router? We can add a host route for the UCSD gateway in our local routing table, but we have to do this for every tunnel, which is unwieldy. Further, connecting to our external interface becomes complicated: suppose someone &amp;lt;code&amp;gt;ping&amp;lt;/code&amp;gt;s our external interface. Assuming we permit this, the response would be routed through the UCSD gateway tunnel, but even if the gateway passed arbitrary traffic back onto the Internet, the packet might be lost as upstream ISPs would refuse to route it.&lt;br /&gt;
&lt;br /&gt;
The solution to all of these problems is to use [https://en.wikipedia.org/wiki/Policy-based_routing &#039;&#039;policy-based routing&#039;&#039;]. Specifically, we would like to make routing decisions based on the source IP address of our traffic. We might be able to do this with firewall rules, but the edge cases get complicated very quickly. Fortunately, there is another way: [https://man.openbsd.org/rdomain.4 routing domains].&lt;br /&gt;
&lt;br /&gt;
Routing domains in OpenBSD are a mechanism to isolate routing decisions from one another. Network interfaces are configured into exactly one routing domain, which has its own private set of routing tables. Those tables are isolated, but traffic can be passed between routing domains via firewall rules.&lt;br /&gt;
&lt;br /&gt;
In our case, we can put external interface and our local AMPRNet gateway interface into separate routing domains: the &#039;&#039;gif&#039;&#039; interfaces and the local AMPRNet gateway interface can both be assigned to routing domain 44, while the external interface might be 23. 0 is the default. The numbers here are arbitrary (as long as the are less than 256), and these are chosen to match the first octet of our example addresses. In our example, we can set the default route in the routing domain that owns our external interface to our ISP&#039;s router, while in the routing domain hosting our AMPRNet presence we can set it to &amp;lt;code&amp;gt;44.0.0.1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
There is a additional piece of functionality that allows us to dispense with much of the complexity of routing between domains: the tunnel assigned to a &#039;&#039;gif&#039;&#039; can be in a different routing domain than the interface itself.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The solution was to set up a separate routing table in a different&lt;br /&gt;
routing domain specifically for AMPRNet traffic, and tie the two&lt;br /&gt;
together using firewall rules.  In the AMPRNet routing table, I&lt;br /&gt;
could set my default route to point to the UCSD gateway, so any&lt;br /&gt;
traffic sent from one of my 44.44.107.0/24 addresses that doesn&#039;t&lt;br /&gt;
match a route to a known tunnel gets forwarded through&lt;br /&gt;
amprgw.sysnet.ucsd.edu.  With that in place, I could ping my gateway&lt;br /&gt;
from random machines.  This must seem obvious to a lot of folks&lt;br /&gt;
here, but it took me a little while to figure out what was going&lt;br /&gt;
on.  Things are working now, however.&lt;br /&gt;
&lt;br /&gt;
So far I have encountered two other caveats: I decided to&lt;br /&gt;
configure two tunnel interfaces statically at boot time: &#039;gif0&#039;&lt;br /&gt;
goes to the UCSD tunnel, and &#039;gif1&#039; sets up a tunnel to N1URO for&lt;br /&gt;
his 44.88 net.  Under OpenBSD, I assumed that the natural way to&lt;br /&gt;
do this would be to add /etc/hostname.gif0 and /etc/hostname.gif1&lt;br /&gt;
files and this does in fact create the tunnels at boot time.  However,&lt;br /&gt;
traffic going out from my gateway doesn&#039;t seem to get sent through&lt;br /&gt;
the tunnels; I did not bother to track down exactly why, but I&lt;br /&gt;
believe it has to do with some kind of implicit ordering dependency&lt;br /&gt;
when initializing PF.  When I set up the separate routing domain,&lt;br /&gt;
it struck me that the language accepted by /etc/netstart in an&lt;br /&gt;
/etc/hostname.if file was not sufficiently rich to set up tunnels&lt;br /&gt;
in a routing domain, so I capitulated and just set up the static&lt;br /&gt;
interfaces from /etc/rc.local; imperfect but it works.&lt;br /&gt;
&lt;br /&gt;
The second caveat is that I seem to have tickled a kernel error&lt;br /&gt;
trying to set up an alias of a second IP address on my 44.44.107.1&lt;br /&gt;
NIC; I get a kernel panic due to an assertion failure.  It looks a&lt;br /&gt;
bug to me, but I haven&#039;t had the bandwidth to track it down.  In&lt;br /&gt;
the meanwhile, simply don&#039;t add aliases to interfaces in non-default&lt;br /&gt;
routing domains.&lt;br /&gt;
&lt;br /&gt;
The biggest piece missing was a daemon to handle receiving 44net RIP packets and use that data to maintain tunnels and routes.  I thought about porting one, but decided of write my own instead. It has been running for a few weeks now on my node and while it&#039;s still not quite &amp;quot;done&amp;quot; it seems to work well enough that I decided it was time to cast a somewhat a wider net and push it up to GitHub for comment from others.&lt;br /&gt;
&lt;br /&gt;
A couple of quick notes on implementation:&lt;br /&gt;
&lt;br /&gt;
# The program maintains a copy of the AMPRNet routing table in a modified PATRICIA trie (really a compressed radix tree). Routes are expired after receiving a RIP packet.&lt;br /&gt;
# A similar table of tunnels is maintained.&lt;br /&gt;
# Tunnel interfaces are reference counted and garbage collected. A bitmap indicating which tunnels are in use is maintained.&lt;br /&gt;
# The program is completely self-contained in the sense that I do not fork/exec external commands to e.g. configure tunnels or manipulate routes.  That is all done via ioctls or writing messages to a routing socket.&lt;br /&gt;
&lt;br /&gt;
There is more to do; I&#039;m sure there are a few bugs.  I&#039;d also like&lt;br /&gt;
to query the system state at startup to initialize the routing and&lt;br /&gt;
tunnel tables.  Exporting and/or parsing an encap file would be&lt;br /&gt;
nice.  Logging and error checking can, I&#039;m sure, be improved.&lt;br /&gt;
&lt;br /&gt;
It&#039;s about 1200 lines of non-comment code, compiles down to a 28K MIPS64 executable (stripped).  The code is at https://github.com/dancrossnyc/44ripd&lt;/div&gt;</summary>
		<author><name>Cross</name></author>
	</entry>
	<entry>
		<id>https://wiki.ampr.org/w/index.php?title=Setting_up_a_gateway_on_OpenBSD&amp;diff=907</id>
		<title>Setting up a gateway on OpenBSD</title>
		<link rel="alternate" type="text/html" href="https://wiki.ampr.org/w/index.php?title=Setting_up_a_gateway_on_OpenBSD&amp;diff=907"/>
		<updated>2021-01-08T00:12:38Z</updated>

		<summary type="html">&lt;p&gt;Cross: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://www.openbsd.org OpenBSD] is a mature Unix-like operating system that focuses on security and correctness. It features a flexible, robust, performant TCP/IP stack and a [https://www.openbsd.org/faq/pf/ highly configurable firewall]. This page describes how to configure a computer running OpenBSD as an AMPRNet router to transfer traffic between AMPRNet subnets and the Internet.&lt;br /&gt;
&lt;br /&gt;
OpenBSD natively supports [https://en.wikipedia.org/wiki/IP_in_IP IPENCAP (IP-IP)] tunnels through [https://man.openbsd.org/gif.4 &#039;&#039;gif&#039;&#039;(4)] pseudo-devices. Each &#039;&#039;gif&#039;&#039; device is a virtual network interface, synthesized by the operating system, that implements a point-to-point tunnel. Unlike Linux, OpenBSD requires a separate &#039;&#039;gif&#039;&#039; interface for each tunnel. An essentially arbitrary number of such interfaces can be created and it scales to the number required to route all of AMPRNet.&lt;br /&gt;
&lt;br /&gt;
One can manually configure &#039;&#039;gif&#039;&#039; tunnels and routes at the command line, or configure the system to establish tunnels and routes at boot time.&lt;br /&gt;
&lt;br /&gt;
We will describe how to set things up by way of example. Assume a system configuration that looks substantially similar to the following:&lt;br /&gt;
&lt;br /&gt;
* A dedicated static IP address to use as an endpoint for AMPRNet traffic.&lt;br /&gt;
* An ISP-provided router that is just a router; no NATing, no firewall.&lt;br /&gt;
* An OpenBSD computer with three ethernet interfaces. For example, using a Ubiquiti EdgeRouter 3 Lite:&lt;br /&gt;
*# cnmac0 is the external interface connected to the ISP&#039;s network (in this example, we use 23.30.150.141 routing to 23.30.150.142)&lt;br /&gt;
*# cnmac1 connects to an internal network (its configuration is irrelevant)&lt;br /&gt;
*# cnmac2 is the internal interface connected to the subnet (in this example, we use 44.44.107.1 routing for 44.44.107.0/24)&lt;br /&gt;
&lt;br /&gt;
Let us start by configuring a single tunnel to the AMPRNet gateway at UCSD:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;ifconfig gif0 create&lt;br /&gt;
ifconfig gif0 tunnel 23.30.150.141 169.228.34.84&lt;br /&gt;
ifconfig gif0 inet 44.44.107.1 netmask 255.255.255.255&lt;br /&gt;
route add 44.0.0.1 -link -iface gif0 -llinfo&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Once I had a tunnel up to UCSD, I found that I could ping my&lt;br /&gt;
44.44.107.1 machine from a host on my internal network, but not&lt;br /&gt;
from arbitrary machines.  This was interesting; it turns out that&lt;br /&gt;
hosts on my internal network get NAT&#039;ed to another IP address on&lt;br /&gt;
the small subnet I got from Comcast (through another, completely&lt;br /&gt;
separate router -- not comcast&#039;s router but another ERL).  What was&lt;br /&gt;
happening was that as I ping&#039;ed 44.44.107.1 from e.g. my laptop,&lt;br /&gt;
ICMP echo request packets got NAT&#039;ed to this other address and&lt;br /&gt;
routed over to amprgw.sysnet.ucsd.edu and tunneled back to the&lt;br /&gt;
external interface of my AMPRNet gateway.  The gateway accepted the&lt;br /&gt;
encapsulated ICMP echo requests (I have a PF rule that explicitly&lt;br /&gt;
allows ping) and forwarded them across the tunnel interface where&lt;br /&gt;
they were unencapsulated; the IP stack saw that the result was&lt;br /&gt;
addressed to an IP address on a local interface (i.e., they were&lt;br /&gt;
for the router) and generated an ICMP echo response packet with a&lt;br /&gt;
*source* address of 44.44.107.1 and a *destination* address of the&lt;br /&gt;
external address of my other router (that is, the address the ICMP&lt;br /&gt;
echo request was NAT&#039;ed to).  This matched the network route for&lt;br /&gt;
my local Comcats subnet and so my AMPRNet router realized it could&lt;br /&gt;
pass the packet back to my other router directly.  It did so and&lt;br /&gt;
the other router happily took the packet, matched it back through&lt;br /&gt;
the NAT back to the original requesting machine (my laptop) and&lt;br /&gt;
forwarded it: hence, I got my ping responses back.  But note that&lt;br /&gt;
the response was not going through the tunnel back to UCSD: it was&lt;br /&gt;
being routed directly through the external interface.&lt;br /&gt;
&lt;br /&gt;
Now consider what happens when I tried to ping 44.44.107.1 from&lt;br /&gt;
a different machine on some other network.  The ICMP echo request&lt;br /&gt;
packet gets routed through the UCSD gateway and tunneled back to&lt;br /&gt;
my gateway as before, but since responses don&#039;t go through back&lt;br /&gt;
through the tunnel, the response packet matches the default route&lt;br /&gt;
of my gateway and get&#039;s forwarded to comcast&#039;s router.  Comcast&lt;br /&gt;
would look at it, see that 44.44.107.1 wasn&#039;t on one of it&#039;s known&lt;br /&gt;
networks that it would route floor, and discard the response.  Oops.&lt;br /&gt;
&lt;br /&gt;
The solution was to set up a separate routing table in a different&lt;br /&gt;
routing domain specifically for AMPRNet traffic, and tie the two&lt;br /&gt;
together using firewall rules.  In the AMPRNet routing table, I&lt;br /&gt;
could set my default route to point to the UCSD gateway, so any&lt;br /&gt;
traffic sent from one of my 44.44.107.0/24 addresses that doesn&#039;t&lt;br /&gt;
match a route to a known tunnel gets forwarded through&lt;br /&gt;
amprgw.sysnet.ucsd.edu.  With that in place, I could ping my gateway&lt;br /&gt;
from random machines.  This must seem obvious to a lot of folks&lt;br /&gt;
here, but it took me a little while to figure out what was going&lt;br /&gt;
on.  Things are working now, however.&lt;br /&gt;
&lt;br /&gt;
So far I have encountered two other caveats: I decided to&lt;br /&gt;
configure two tunnel interfaces statically at boot time: &#039;gif0&#039;&lt;br /&gt;
goes to the UCSD tunnel, and &#039;gif1&#039; sets up a tunnel to N1URO for&lt;br /&gt;
his 44.88 net.  Under OpenBSD, I assumed that the natural way to&lt;br /&gt;
do this would be to add /etc/hostname.gif0 and /etc/hostname.gif1&lt;br /&gt;
files and this does in fact create the tunnels at boot time.  However,&lt;br /&gt;
traffic going out from my gateway doesn&#039;t seem to get sent through&lt;br /&gt;
the tunnels; I did not bother to track down exactly why, but I&lt;br /&gt;
believe it has to do with some kind of implicit ordering dependency&lt;br /&gt;
when initializing PF.  When I set up the separate routing domain,&lt;br /&gt;
it struck me that the language accepted by /etc/netstart in an&lt;br /&gt;
/etc/hostname.if file was not sufficiently rich to set up tunnels&lt;br /&gt;
in a routing domain, so I capitulated and just set up the static&lt;br /&gt;
interfaces from /etc/rc.local; imperfect but it works.&lt;br /&gt;
&lt;br /&gt;
The second caveat is that I seem to have tickled a kernel error&lt;br /&gt;
trying to set up an alias of a second IP address on my 44.44.107.1&lt;br /&gt;
NIC; I get a kernel panic due to an assertion failure.  It looks a&lt;br /&gt;
bug to me, but I haven&#039;t had the bandwidth to track it down.  In&lt;br /&gt;
the meanwhile, simply don&#039;t add aliases to interfaces in non-default&lt;br /&gt;
routing domains.&lt;br /&gt;
&lt;br /&gt;
The biggest piece missing was a daemon to handle receiving 44net RIP packets and use that data to maintain tunnels and routes.  I thought about porting one, but decided of write my own instead. It has been running for a few weeks now on my node and while it&#039;s still not quite &amp;quot;done&amp;quot; it seems to work well enough that I decided it was time to cast a somewhat a wider net and push it up to GitHub for comment from others.&lt;br /&gt;
&lt;br /&gt;
A couple of quick notes on implementation:&lt;br /&gt;
&lt;br /&gt;
# The program maintains a copy of the AMPRNet routing table in a modified PATRICIA trie (really a compressed radix tree). Routes are expired after receiving a RIP packet.&lt;br /&gt;
# A similar table of tunnels is maintained.&lt;br /&gt;
# Tunnel interfaces are reference counted and garbage collected. A bitmap indicating which tunnels are in use is maintained.&lt;br /&gt;
# The program is completely self-contained in the sense that I do not fork/exec external commands to e.g. configure tunnels or manipulate routes.  That is all done via ioctls or writing messages to a routing socket.&lt;br /&gt;
&lt;br /&gt;
There is more to do; I&#039;m sure there are a few bugs.  I&#039;d also like&lt;br /&gt;
to query the system state at startup to initialize the routing and&lt;br /&gt;
tunnel tables.  Exporting and/or parsing an encap file would be&lt;br /&gt;
nice.  Logging and error checking can, I&#039;m sure, be improved.&lt;br /&gt;
&lt;br /&gt;
It&#039;s about 1200 lines of non-comment code, compiles down to a 28K MIPS64 executable (stripped).  The code is at https://github.com/dancrossnyc/44ripd&lt;/div&gt;</summary>
		<author><name>Cross</name></author>
	</entry>
	<entry>
		<id>https://wiki.ampr.org/w/index.php?title=Setting_up_a_gateway_on_OpenBSD&amp;diff=906</id>
		<title>Setting up a gateway on OpenBSD</title>
		<link rel="alternate" type="text/html" href="https://wiki.ampr.org/w/index.php?title=Setting_up_a_gateway_on_OpenBSD&amp;diff=906"/>
		<updated>2021-01-08T00:11:27Z</updated>

		<summary type="html">&lt;p&gt;Cross: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://www.openbsd.org OpenBSD] is a mature Unix-like operating system that focuses on security and correctness. It features a flexible, robust, performant TCP/IP stack and a [https://www.openbsd.org/faq/pf/ highly configurable firewall]. This page describes how to configure a computer running OpenBSD as an AMPRNet router to transfer traffic between AMPRNet subnets and the Internet.&lt;br /&gt;
&lt;br /&gt;
OpenBSD natively supports [https://en.wikipedia.org/wiki/IP_in_IP IPENCAP (IP-IP)] tunnels through [https://man.openbsd.org/gif.4 &#039;&#039;gif&#039;&#039;(4)] pseudo-devices. Each &#039;&#039;gif&#039;&#039; device is a virtual network interface, synthesized by the operating system, that implements a point-to-point tunnel. Unlike Linux, OpenBSD requires a separate &#039;&#039;gif&#039;&#039; interface for each tunnel. An essentially arbitrary number of such interfaces can be created and it scales to the number required to route all of AMPRNet.&lt;br /&gt;
&lt;br /&gt;
One can manually configure &#039;&#039;gif&#039;&#039; tunnels and routes at the command line, or configure the system to establish tunnels and routes at boot time.&lt;br /&gt;
&lt;br /&gt;
We will describe how to set things up by way of example. Assume a system configuration that looks substantially similar to the following:&lt;br /&gt;
&lt;br /&gt;
* A dedicated static IP address to use as an endpoint for AMPRNet traffic.&lt;br /&gt;
* An ISP-provided router that is just a router; no NATing, no firewall.&lt;br /&gt;
* An OpenBSD computer with three ethernet interfaces. For example, using a Ubiquiti EdgeRouter 3 Lite:&lt;br /&gt;
*# cnmac0 is the external interface connected to the ISP&#039;s network (in this example, we use 23.30.150.141 routing to 23.30.150.142)&lt;br /&gt;
*# cnmac1 connects to an internal network (its configuration is irrelevant)&lt;br /&gt;
*# cnmac2 is the internal interface connected to the subnet (in this example, we use 44.44.107.1 routing for 44.44.107.0/24)&lt;br /&gt;
&lt;br /&gt;
Let us start by configuring a single tunnel to the AMPRNet gateway at UCSD:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;ifconfig gif0 create&lt;br /&gt;
ifconfig gif0 tunnel 23.30.150.141 169.228.34.84&lt;br /&gt;
ifconfig gif0 inet 44.44.107.1 netmask 255.255.255.255&lt;br /&gt;
route add 44.0.0.1 -link -iface gif0 -llinfo&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Once I had a tunnel up to UCSD, I found that I could ping my&lt;br /&gt;
44.44.107.1 machine from a host on my internal network, but not&lt;br /&gt;
from arbitrary machines.  This was interesting; it turns out that&lt;br /&gt;
hosts on my internal network get NAT&#039;ed to another IP address on&lt;br /&gt;
the small subnet I got from Comcast (through another, completely&lt;br /&gt;
separate router -- not comcast&#039;s router but another ERL).  What was&lt;br /&gt;
happening was that as I ping&#039;ed 44.44.107.1 from e.g. my laptop,&lt;br /&gt;
ICMP echo request packets got NAT&#039;ed to this other address and&lt;br /&gt;
routed over to amprgw.sysnet.ucsd.edu and tunneled back to the&lt;br /&gt;
external interface of my AMPRNet gateway.  The gateway accepted the&lt;br /&gt;
encapsulated ICMP echo requests (I have a PF rule that explicitly&lt;br /&gt;
allows ping) and forwarded them across the tunnel interface where&lt;br /&gt;
they were unencapsulated; the IP stack saw that the result was&lt;br /&gt;
addressed to an IP address on a local interface (i.e., they were&lt;br /&gt;
for the router) and generated an ICMP echo response packet with a&lt;br /&gt;
*source* address of 44.44.107.1 and a *destination* address of the&lt;br /&gt;
external address of my other router (that is, the address the ICMP&lt;br /&gt;
echo request was NAT&#039;ed to).  This matched the network route for&lt;br /&gt;
my local Comcats subnet and so my AMPRNet router realized it could&lt;br /&gt;
pass the packet back to my other router directly.  It did so and&lt;br /&gt;
the other router happily took the packet, matched it back through&lt;br /&gt;
the NAT back to the original requesting machine (my laptop) and&lt;br /&gt;
forwarded it: hence, I got my ping responses back.  But note that&lt;br /&gt;
the response was not going through the tunnel back to UCSD: it was&lt;br /&gt;
being routed directly through the external interface.&lt;br /&gt;
&lt;br /&gt;
Now consider what happens when I tried to ping 44.44.107.1 from&lt;br /&gt;
a different machine on some other network.  The ICMP echo request&lt;br /&gt;
packet gets routed through the UCSD gateway and tunneled back to&lt;br /&gt;
my gateway as before, but since responses don&#039;t go through back&lt;br /&gt;
through the tunnel, the response packet matches the default route&lt;br /&gt;
of my gateway and get&#039;s forwarded to comcast&#039;s router.  Comcast&lt;br /&gt;
would look at it, see that 44.44.107.1 wasn&#039;t on one of it&#039;s known&lt;br /&gt;
networks that it would route floor, and discard the response.  Oops.&lt;br /&gt;
&lt;br /&gt;
The solution was to set up a separate routing table in a different&lt;br /&gt;
routing domain specifically for AMPRNet traffic, and tie the two&lt;br /&gt;
together using firewall rules.  In the AMPRNet routing table, I&lt;br /&gt;
could set my default route to point to the UCSD gateway, so any&lt;br /&gt;
traffic sent from one of my 44.44.107.0/24 addresses that doesn&#039;t&lt;br /&gt;
match a route to a known tunnel gets forwarded through&lt;br /&gt;
amprgw.sysnet.ucsd.edu.  With that in place, I could ping my gateway&lt;br /&gt;
from random machines.  This must seem obvious to a lot of folks&lt;br /&gt;
here, but it took me a little while to figure out what was going&lt;br /&gt;
on.  Things are working now, however.&lt;br /&gt;
&lt;br /&gt;
So far I have encountered two other caveats: I decided to&lt;br /&gt;
configure two tunnel interfaces statically at boot time: &#039;gif0&#039;&lt;br /&gt;
goes to the UCSD tunnel, and &#039;gif1&#039; sets up a tunnel to N1URO for&lt;br /&gt;
his 44.88 net.  Under OpenBSD, I assumed that the natural way to&lt;br /&gt;
do this would be to add /etc/hostname.gif0 and /etc/hostname.gif1&lt;br /&gt;
files and this does in fact create the tunnels at boot time.  However,&lt;br /&gt;
traffic going out from my gateway doesn&#039;t seem to get sent through&lt;br /&gt;
the tunnels; I did not bother to track down exactly why, but I&lt;br /&gt;
believe it has to do with some kind of implicit ordering dependency&lt;br /&gt;
when initializing PF.  When I set up the separate routing domain,&lt;br /&gt;
it struck me that the language accepted by /etc/netstart in an&lt;br /&gt;
/etc/hostname.if file was not sufficiently rich to set up tunnels&lt;br /&gt;
in a routing domain, so I capitulated and just set up the static&lt;br /&gt;
interfaces from /etc/rc.local; imperfect but it works.&lt;br /&gt;
&lt;br /&gt;
The second caveat is that I seem to have tickled a kernel error&lt;br /&gt;
trying to set up an alias of a second IP address on my 44.44.107.1&lt;br /&gt;
NIC; I get a kernel panic due to an assertion failure.  It looks a&lt;br /&gt;
bug to me, but I haven&#039;t had the bandwidth to track it down.  In&lt;br /&gt;
the meanwhile, simply don&#039;t add aliases to interfaces in non-default&lt;br /&gt;
routing domains.&lt;br /&gt;
&lt;br /&gt;
The biggest piece missing was a daemon to handle receiving 44net RIP packets and use that data to maintain tunnels and routes.  I thought about porting one, but decided of write my own instead. It has been running for a few weeks now on my node and while it&#039;s still not quite &amp;quot;done&amp;quot; it seems to work well enough that I decided it was time to cast a somewhat a wider net and push it up to GitHub for comment from others.&lt;br /&gt;
&lt;br /&gt;
A couple of quick notes on implementation:&lt;br /&gt;
&lt;br /&gt;
# The program maintains a copy of the AMPRNet routing table in a modified PATRICIA trie (really a compressed radix tree). Routes are expired after receiving a RIP packet.&lt;br /&gt;
# A similar table of tunnels is maintained.&lt;br /&gt;
# Tunnel interfaces are reference counted and garbage collected. A bitmap indicating which tunnels are in use is maintained.&lt;br /&gt;
# The program is completely self-contained in the sense that I do not fork/exec external commands to e.g. configure tunnels or manipulate routes.  That is all done via ioctls or writing messages to a routing socket.&lt;br /&gt;
&lt;br /&gt;
There is more to do; I&#039;m sure there are a few bugs.  I&#039;d also like&lt;br /&gt;
to query the system state at startup to initialize the routing and&lt;br /&gt;
tunnel tables.  Exporting and/or parsing an encap file would be&lt;br /&gt;
nice.  Logging and error checking can, I&#039;m sure, be improved.&lt;br /&gt;
&lt;br /&gt;
It&#039;s about 1200 lines of non-comment code, compiles down to a 28K MIPS64 executable (stripped).  The code is at https://github.com/dancrossnyc/44ripd&lt;/div&gt;</summary>
		<author><name>Cross</name></author>
	</entry>
	<entry>
		<id>https://wiki.ampr.org/w/index.php?title=Setting_up_a_gateway_on_OpenBSD&amp;diff=905</id>
		<title>Setting up a gateway on OpenBSD</title>
		<link rel="alternate" type="text/html" href="https://wiki.ampr.org/w/index.php?title=Setting_up_a_gateway_on_OpenBSD&amp;diff=905"/>
		<updated>2021-01-08T00:09:07Z</updated>

		<summary type="html">&lt;p&gt;Cross: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://www.openbsd.org OpenBSD] is a mature Unix-like operating system that focuses on security and correctness. It features a flexible, robust, performant TCP/IP stack and a [https://www.openbsd.org/faq/pf/ highly configurable firewall]. This page describes how to configure a computer running OpenBSD as an AMPRNet router to transfer traffic between AMPRNet subnets and the Internet.&lt;br /&gt;
&lt;br /&gt;
OpenBSD natively supports [https://en.wikipedia.org/wiki/IP_in_IP IPENCAP (IP-IP)] tunnels through [https://man.openbsd.org/gif.4 &#039;&#039;gif&#039;&#039;(4)] pseudo-devices. Each &#039;&#039;gif&#039;&#039; device is a virtual network interface, synthesized by the operating system, that implements a point-to-point tunnel. Unlike Linux, OpenBSD requires a separate &#039;&#039;gif&#039;&#039; interface for each tunnel. An essentially arbitrary number of such interfaces can be created and it scales to the number required to route all of AMPRNet.&lt;br /&gt;
&lt;br /&gt;
One can manually configure &#039;&#039;gif&#039;&#039; tunnels and routes at the command line, or configure the system to establish tunnels and routes at boot time.&lt;br /&gt;
&lt;br /&gt;
We will describe how to set things up by way of example. Assume a system configuration that looks substantially similar to the following:&lt;br /&gt;
&lt;br /&gt;
# A dedicated static IP address to use as an endpoint for AMPRNet traffic.&lt;br /&gt;
# An ISP-provided router that is just a router; no NATing, no firewall.&lt;br /&gt;
# An OpenBSD computer with three ethernet interfaces. For example, using a Ubiquiti EdgeRouter 3 Lite:&lt;br /&gt;
## cnmac0 is the external interface connected to the ISP&#039;s network (in this example, we use 23.30.150.141 routing to 23.30.150.142)&lt;br /&gt;
## cnmac1 connects to an internal network (its configuration is irrelevant)&lt;br /&gt;
## cnmac2 is the internal interface connected to the subnet (in this example, we use 44.44.107.1 routing for 44.44.107.0/24)&lt;br /&gt;
&lt;br /&gt;
Let us start by configuring a single tunnel to the AMPRNet gateway at UCSD:&lt;br /&gt;
&lt;br /&gt;
ifconfig gif0 create&lt;br /&gt;
ifconfig gif0 tunnel 23.30.150.141 169.228.34.84&lt;br /&gt;
ifconfig gif0 inet 44.44.107.1 netmask 255.255.255.255&lt;br /&gt;
route add 44.0.0.1 -link -iface gif0 -llinfo&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Once I had a tunnel up to UCSD, I found that I could ping my&lt;br /&gt;
44.44.107.1 machine from a host on my internal network, but not&lt;br /&gt;
from arbitrary machines.  This was interesting; it turns out that&lt;br /&gt;
hosts on my internal network get NAT&#039;ed to another IP address on&lt;br /&gt;
the small subnet I got from Comcast (through another, completely&lt;br /&gt;
separate router -- not comcast&#039;s router but another ERL).  What was&lt;br /&gt;
happening was that as I ping&#039;ed 44.44.107.1 from e.g. my laptop,&lt;br /&gt;
ICMP echo request packets got NAT&#039;ed to this other address and&lt;br /&gt;
routed over to amprgw.sysnet.ucsd.edu and tunneled back to the&lt;br /&gt;
external interface of my AMPRNet gateway.  The gateway accepted the&lt;br /&gt;
encapsulated ICMP echo requests (I have a PF rule that explicitly&lt;br /&gt;
allows ping) and forwarded them across the tunnel interface where&lt;br /&gt;
they were unencapsulated; the IP stack saw that the result was&lt;br /&gt;
addressed to an IP address on a local interface (i.e., they were&lt;br /&gt;
for the router) and generated an ICMP echo response packet with a&lt;br /&gt;
*source* address of 44.44.107.1 and a *destination* address of the&lt;br /&gt;
external address of my other router (that is, the address the ICMP&lt;br /&gt;
echo request was NAT&#039;ed to).  This matched the network route for&lt;br /&gt;
my local Comcats subnet and so my AMPRNet router realized it could&lt;br /&gt;
pass the packet back to my other router directly.  It did so and&lt;br /&gt;
the other router happily took the packet, matched it back through&lt;br /&gt;
the NAT back to the original requesting machine (my laptop) and&lt;br /&gt;
forwarded it: hence, I got my ping responses back.  But note that&lt;br /&gt;
the response was not going through the tunnel back to UCSD: it was&lt;br /&gt;
being routed directly through the external interface.&lt;br /&gt;
&lt;br /&gt;
Now consider what happens when I tried to ping 44.44.107.1 from&lt;br /&gt;
a different machine on some other network.  The ICMP echo request&lt;br /&gt;
packet gets routed through the UCSD gateway and tunneled back to&lt;br /&gt;
my gateway as before, but since responses don&#039;t go through back&lt;br /&gt;
through the tunnel, the response packet matches the default route&lt;br /&gt;
of my gateway and get&#039;s forwarded to comcast&#039;s router.  Comcast&lt;br /&gt;
would look at it, see that 44.44.107.1 wasn&#039;t on one of it&#039;s known&lt;br /&gt;
networks that it would route floor, and discard the response.  Oops.&lt;br /&gt;
&lt;br /&gt;
The solution was to set up a separate routing table in a different&lt;br /&gt;
routing domain specifically for AMPRNet traffic, and tie the two&lt;br /&gt;
together using firewall rules.  In the AMPRNet routing table, I&lt;br /&gt;
could set my default route to point to the UCSD gateway, so any&lt;br /&gt;
traffic sent from one of my 44.44.107.0/24 addresses that doesn&#039;t&lt;br /&gt;
match a route to a known tunnel gets forwarded through&lt;br /&gt;
amprgw.sysnet.ucsd.edu.  With that in place, I could ping my gateway&lt;br /&gt;
from random machines.  This must seem obvious to a lot of folks&lt;br /&gt;
here, but it took me a little while to figure out what was going&lt;br /&gt;
on.  Things are working now, however.&lt;br /&gt;
&lt;br /&gt;
So far I have encountered two other caveats: I decided to&lt;br /&gt;
configure two tunnel interfaces statically at boot time: &#039;gif0&#039;&lt;br /&gt;
goes to the UCSD tunnel, and &#039;gif1&#039; sets up a tunnel to N1URO for&lt;br /&gt;
his 44.88 net.  Under OpenBSD, I assumed that the natural way to&lt;br /&gt;
do this would be to add /etc/hostname.gif0 and /etc/hostname.gif1&lt;br /&gt;
files and this does in fact create the tunnels at boot time.  However,&lt;br /&gt;
traffic going out from my gateway doesn&#039;t seem to get sent through&lt;br /&gt;
the tunnels; I did not bother to track down exactly why, but I&lt;br /&gt;
believe it has to do with some kind of implicit ordering dependency&lt;br /&gt;
when initializing PF.  When I set up the separate routing domain,&lt;br /&gt;
it struck me that the language accepted by /etc/netstart in an&lt;br /&gt;
/etc/hostname.if file was not sufficiently rich to set up tunnels&lt;br /&gt;
in a routing domain, so I capitulated and just set up the static&lt;br /&gt;
interfaces from /etc/rc.local; imperfect but it works.&lt;br /&gt;
&lt;br /&gt;
The second caveat is that I seem to have tickled a kernel error&lt;br /&gt;
trying to set up an alias of a second IP address on my 44.44.107.1&lt;br /&gt;
NIC; I get a kernel panic due to an assertion failure.  It looks a&lt;br /&gt;
bug to me, but I haven&#039;t had the bandwidth to track it down.  In&lt;br /&gt;
the meanwhile, simply don&#039;t add aliases to interfaces in non-default&lt;br /&gt;
routing domains.&lt;br /&gt;
&lt;br /&gt;
The biggest piece missing was a daemon to handle receiving 44net RIP packets and use that data to maintain tunnels and routes.  I thought about porting one, but decided of write my own instead. It has been running for a few weeks now on my node and while it&#039;s still not quite &amp;quot;done&amp;quot; it seems to work well enough that I decided it was time to cast a somewhat a wider net and push it up to GitHub for comment from others.&lt;br /&gt;
&lt;br /&gt;
A couple of quick notes on implementation:&lt;br /&gt;
&lt;br /&gt;
# The program maintains a copy of the AMPRNet routing table in a modified PATRICIA trie (really a compressed radix tree). Routes are expired after receiving a RIP packet.&lt;br /&gt;
# A similar table of tunnels is maintained.&lt;br /&gt;
# Tunnel interfaces are reference counted and garbage collected. A bitmap indicating which tunnels are in use is maintained.&lt;br /&gt;
# The program is completely self-contained in the sense that I do not fork/exec external commands to e.g. configure tunnels or manipulate routes.  That is all done via ioctls or writing messages to a routing socket.&lt;br /&gt;
&lt;br /&gt;
There is more to do; I&#039;m sure there are a few bugs.  I&#039;d also like&lt;br /&gt;
to query the system state at startup to initialize the routing and&lt;br /&gt;
tunnel tables.  Exporting and/or parsing an encap file would be&lt;br /&gt;
nice.  Logging and error checking can, I&#039;m sure, be improved.&lt;br /&gt;
&lt;br /&gt;
It&#039;s about 1200 lines of non-comment code, compiles down to a 28K MIPS64 executable (stripped).  The code is at https://github.com/dancrossnyc/44ripd&lt;/div&gt;</summary>
		<author><name>Cross</name></author>
	</entry>
	<entry>
		<id>https://wiki.ampr.org/w/index.php?title=Setting_up_a_gateway_on_OpenBSD&amp;diff=648</id>
		<title>Setting up a gateway on OpenBSD</title>
		<link rel="alternate" type="text/html" href="https://wiki.ampr.org/w/index.php?title=Setting_up_a_gateway_on_OpenBSD&amp;diff=648"/>
		<updated>2016-10-16T13:59:40Z</updated>

		<summary type="html">&lt;p&gt;Cross: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;TODO(Cross): Wordsmith this section&lt;br /&gt;
&lt;br /&gt;
This page describes how to configure a router running OpenBSD to transfer traffic between a 44Net subnet and the rest of the world.&lt;br /&gt;
&lt;br /&gt;
Assume a setup that looks substantially similar to the following:&lt;br /&gt;
&lt;br /&gt;
# A dedicated static IP address to use as an endpoint for 44net traffic.&lt;br /&gt;
# An ISP-provided router that is just a router; no NATing, no firewalling.&lt;br /&gt;
# An edge router OpenBSD with three ethernet interfaces. For example, using a Ubiquiti EdgeRouter Lite:&lt;br /&gt;
## cnmac0 is the external interface connected to the ISP&#039;s network&lt;br /&gt;
## cnmac1 connects to your internal network&lt;br /&gt;
## cnmac2 is your AMPRNet internal gateway to your subnet (in this example, we use 44.44.107.0/24)&lt;br /&gt;
&lt;br /&gt;
On OpenBSD, tunneling interfaces for IPENCAP are provided by &#039;gif&#039; pseudo-devices.  Unlike Linux, one creates a separate &#039;gif&#039; interface for each tunnel, but one can create an essentially arbitrary number of such interfaces. If there is a limit it is well above the number required for supporting the full AMPRNet mesh, so don&#039;t worry about scalability to the number of interfaces.&lt;br /&gt;
&lt;br /&gt;
On AMPRNet, the UCSD gateway *will not* pass traffic for an IP address that does not have a corresponding entry in the AMPR.ORG DNS domain.  Also, 44.0.0.1 does not respond to &#039;ping&#039; from 44/8 IP&#039;s. Caveat emptor as one tries to test: make sure you have DNS entries for your addresses and try pinging something other than 44.0.0.1 or you&#039;ll suffer contusions banging your head against a desk trying to figure out why nothing appears to work....&lt;br /&gt;
&lt;br /&gt;
Once I had a tunnel up to UCSD, I found that I could ping my&lt;br /&gt;
44.44.107.1 machine from a host on my internal network, but not&lt;br /&gt;
from arbitrary machines.  This was interesting; it turns out that&lt;br /&gt;
hosts on my internal network get NAT&#039;ed to another IP address on&lt;br /&gt;
the small subnet I got from Comcast (through another, completely&lt;br /&gt;
separate router -- not comcast&#039;s router but another ERL).  What was&lt;br /&gt;
happening was that as I ping&#039;ed 44.44.107.1 from e.g. my laptop,&lt;br /&gt;
ICMP echo request packets got NAT&#039;ed to this other address and&lt;br /&gt;
routed over to amprgw.sysnet.ucsd.edu and tunneled back to the&lt;br /&gt;
external interface of my AMPRNet gateway.  The gateway accepted the&lt;br /&gt;
encapsulated ICMP echo requests (I have a PF rule that explicitly&lt;br /&gt;
allows ping) and forwarded them across the tunnel interface where&lt;br /&gt;
they were unencapsulated; the IP stack saw that the result was&lt;br /&gt;
addressed to an IP address on a local interface (i.e., they were&lt;br /&gt;
for the router) and generated an ICMP echo response packet with a&lt;br /&gt;
*source* address of 44.44.107.1 and a *destination* address of the&lt;br /&gt;
external address of my other router (that is, the address the ICMP&lt;br /&gt;
echo request was NAT&#039;ed to).  This matched the network route for&lt;br /&gt;
my local Comcats subnet and so my AMPRNet router realized it could&lt;br /&gt;
pass the packet back to my other router directly.  It did so and&lt;br /&gt;
the other router happily took the packet, matched it back through&lt;br /&gt;
the NAT back to the original requesting machine (my laptop) and&lt;br /&gt;
forwarded it: hence, I got my ping responses back.  But note that&lt;br /&gt;
the response was not going through the tunnel back to UCSD: it was&lt;br /&gt;
being routed directly through the external interface.&lt;br /&gt;
&lt;br /&gt;
Now consider what happens when I tried to ping 44.44.107.1 from&lt;br /&gt;
a different machine on some other network.  The ICMP echo request&lt;br /&gt;
packet gets routed through the UCSD gateway and tunneled back to&lt;br /&gt;
my gateway as before, but since responses don&#039;t go through back&lt;br /&gt;
through the tunnel, the response packet matches the default route&lt;br /&gt;
of my gateway and get&#039;s forwarded to comcast&#039;s router.  Comcast&lt;br /&gt;
would look at it, see that 44.44.107.1 wasn&#039;t on one of it&#039;s known&lt;br /&gt;
networks that it would route floor, and discard the response.  Oops.&lt;br /&gt;
&lt;br /&gt;
The solution was to set up a separate routing table in a different&lt;br /&gt;
routing domain specifically for AMPRNet traffic, and tie the two&lt;br /&gt;
together using firewall rules.  In the AMPRNet routing table, I&lt;br /&gt;
could set my default route to point to the UCSD gateway, so any&lt;br /&gt;
traffic sent from one of my 44.44.107.0/24 addresses that doesn&#039;t&lt;br /&gt;
match a route to a known tunnel gets forwarded through&lt;br /&gt;
amprgw.sysnet.ucsd.edu.  With that in place, I could ping my gateway&lt;br /&gt;
from random machines.  This must seem obvious to a lot of folks&lt;br /&gt;
here, but it took me a little while to figure out what was going&lt;br /&gt;
on.  Things are working now, however.&lt;br /&gt;
&lt;br /&gt;
So far I have encountered two other caveats: I decided to&lt;br /&gt;
configure two tunnel interfaces statically at boot time: &#039;gif0&#039;&lt;br /&gt;
goes to the UCSD tunnel, and &#039;gif1&#039; sets up a tunnel to N1URO for&lt;br /&gt;
his 44.88 net.  Under OpenBSD, I assumed that the natural way to&lt;br /&gt;
do this would be to add /etc/hostname.gif0 and /etc/hostname.gif1&lt;br /&gt;
files and this does in fact create the tunnels at boot time.  However,&lt;br /&gt;
traffic going out from my gateway doesn&#039;t seem to get sent through&lt;br /&gt;
the tunnels; I did not bother to track down exactly why, but I&lt;br /&gt;
believe it has to do with some kind of implicit ordering dependency&lt;br /&gt;
when initializing PF.  When I set up the separate routing domain,&lt;br /&gt;
it struck me that the language accepted by /etc/netstart in an&lt;br /&gt;
/etc/hostname.if file was not sufficiently rich to set up tunnels&lt;br /&gt;
in a routing domain, so I capitulated and just set up the static&lt;br /&gt;
interfaces from /etc/rc.local; imperfect but it works.&lt;br /&gt;
&lt;br /&gt;
The second caveat is that I seem to have tickled a kernel error&lt;br /&gt;
trying to set up an alias of a second IP address on my 44.44.107.1&lt;br /&gt;
NIC; I get a kernel panic due to an assertion failure.  It looks a&lt;br /&gt;
bug to me, but I haven&#039;t had the bandwidth to track it down.  In&lt;br /&gt;
the meanwhile, simply don&#039;t add aliases to interfaces in non-default&lt;br /&gt;
routing domains.&lt;br /&gt;
&lt;br /&gt;
The biggest piece missing was a daemon to handle receiving 44net RIP packets and use that data to maintain tunnels and routes.  I thought about porting one, but decided of write my own instead. It has been running for a few weeks now on my node and while it&#039;s still not quite &amp;quot;done&amp;quot; it seems to work well enough that I decided it was time to cast a somewhat a wider net and push it up to GitHub for comment from others.&lt;br /&gt;
&lt;br /&gt;
A couple of quick notes on implementation:&lt;br /&gt;
&lt;br /&gt;
# The program maintains a copy of the AMPRNet routing table in a modified PATRICIA trie (really a compressed radix tree). Routes are expired after receiving a RIP packet.&lt;br /&gt;
# A similar table of tunnels is maintained.&lt;br /&gt;
# Tunnel interfaces are reference counted and garbage collected. A bitmap indicating which tunnels are in use is maintained.&lt;br /&gt;
# The program is completely self-contained in the sense that I do not fork/exec external commands to e.g. configure tunnels or manipulate routes.  That is all done via ioctls or writing messages to a routing socket.&lt;br /&gt;
&lt;br /&gt;
There is more to do; I&#039;m sure there are a few bugs.  I&#039;d also like&lt;br /&gt;
to query the system state at startup to initialize the routing and&lt;br /&gt;
tunnel tables.  Exporting and/or parsing an encap file would be&lt;br /&gt;
nice.  Logging and error checking can, I&#039;m sure, be improved.&lt;br /&gt;
&lt;br /&gt;
It&#039;s about 1200 lines of non-comment code, compiles down to a 28K MIPS64 executable (stripped).  The code is at https://github.com/dancrossnyc/44ripd&lt;/div&gt;</summary>
		<author><name>Cross</name></author>
	</entry>
	<entry>
		<id>https://wiki.ampr.org/w/index.php?title=Setting_up_a_gateway_on_OpenBSD&amp;diff=646</id>
		<title>Setting up a gateway on OpenBSD</title>
		<link rel="alternate" type="text/html" href="https://wiki.ampr.org/w/index.php?title=Setting_up_a_gateway_on_OpenBSD&amp;diff=646"/>
		<updated>2016-09-24T02:47:10Z</updated>

		<summary type="html">&lt;p&gt;Cross: More wiki-formatting.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;TODO(Cross): Wordsmith this section&lt;br /&gt;
&lt;br /&gt;
I am now successfully transferring traffic between my 44net subnet&lt;br /&gt;
(44.44.107.0/24) and the rest of the world using my OpenBSD-based&lt;br /&gt;
router.&lt;br /&gt;
&lt;br /&gt;
A quick recap of my setup:&lt;br /&gt;
1. I have a Comcast business class circuit.&lt;br /&gt;
2. I have a dedicated static IP address to use as an endpoint for 44net traffic.&lt;br /&gt;
3. My comcast router is just a router; no NATing, no firewalling.&lt;br /&gt;
4. My (non-comcast) edge router is a Ubiquiti EdgeRouter Lite running OpenBSD 5.9.  It has three ethernet interfaces:&lt;br /&gt;
   a. cnmac0 is the external interface connected to Comcast&#039;s network&lt;br /&gt;
   b. cnmac1 connects to my internal network&lt;br /&gt;
   c. cnmac2 is my internal gateway to 44.44.107.0/24.&lt;br /&gt;
&lt;br /&gt;
On OpenBSD, tunneling interfaces for IPENCAP are provided by&lt;br /&gt;
&#039;gif&#039; pseudo-devices.  Unlike Linux, it appears that one creates a&lt;br /&gt;
separate &#039;gif&#039; interface for each tunnel, but one seems able to&lt;br /&gt;
create an arbitrary number of such interfaces: I created a thousand&lt;br /&gt;
as a test.  I&#039;m sure there is a limit but it seems sufficiently&lt;br /&gt;
high that practically routing AMPRNet traffic won&#039;t run up against&lt;br /&gt;
it.  (Again, if someone knows of a different way to configure a&lt;br /&gt;
single &#039;gif&#039; interface so that it could support multiple tunnels,&lt;br /&gt;
I&#039;d be happy to know about it).  In other words, don&#039;t worry about&lt;br /&gt;
scalability because you are creating a separate &#039;gif&#039; interface for&lt;br /&gt;
each tunnel to another AMPRNet site.&lt;br /&gt;
&lt;br /&gt;
On AMPRNet, the UCSD gateway *will not* pass traffic for an&lt;br /&gt;
IP address that does not have a corresponding entry in the AMPR.ORG&lt;br /&gt;
domain.  Also, 44.0.0.1 does not respond to &#039;ping&#039; from 44/8 IP&#039;s.&lt;br /&gt;
Caveat emptor as one tries to test: make sure you have DNS entries&lt;br /&gt;
for your addresses and try pinging something other than 44.0.0.1&lt;br /&gt;
or you&#039;ll suffer contusions banging your head against a desk trying&lt;br /&gt;
to figure out why nothing appears to work....&lt;br /&gt;
&lt;br /&gt;
Once I had a tunnel up to UCSD, I found that I could ping my&lt;br /&gt;
44.44.107.1 machine from a host on my internal network, but not&lt;br /&gt;
from arbitrary machines.  This was interesting; it turns out that&lt;br /&gt;
hosts on my internal network get NAT&#039;ed to another IP address on&lt;br /&gt;
the small subnet I got from Comcast (through another, completely&lt;br /&gt;
separate router -- not comcast&#039;s router but another ERL).  What was&lt;br /&gt;
happening was that as I ping&#039;ed 44.44.107.1 from e.g. my laptop,&lt;br /&gt;
ICMP echo request packets got NAT&#039;ed to this other address and&lt;br /&gt;
routed over to amprgw.sysnet.ucsd.edu and tunneled back to the&lt;br /&gt;
external interface of my AMPRNet gateway.  The gateway accepted the&lt;br /&gt;
encapsulated ICMP echo requests (I have a PF rule that explicitly&lt;br /&gt;
allows ping) and forwarded them across the tunnel interface where&lt;br /&gt;
they were unencapsulated; the IP stack saw that the result was&lt;br /&gt;
addressed to an IP address on a local interface (i.e., they were&lt;br /&gt;
for the router) and generated an ICMP echo response packet with a&lt;br /&gt;
*source* address of 44.44.107.1 and a *destination* address of the&lt;br /&gt;
external address of my other router (that is, the address the ICMP&lt;br /&gt;
echo request was NAT&#039;ed to).  This matched the network route for&lt;br /&gt;
my local Comcats subnet and so my AMPRNet router realized it could&lt;br /&gt;
pass the packet back to my other router directly.  It did so and&lt;br /&gt;
the other router happily took the packet, matched it back through&lt;br /&gt;
the NAT back to the original requesting machine (my laptop) and&lt;br /&gt;
forwarded it: hence, I got my ping responses back.  But note that&lt;br /&gt;
the response was not going through the tunnel back to UCSD: it was&lt;br /&gt;
being routed directly through the external interface.&lt;br /&gt;
&lt;br /&gt;
Now consider what happens when I tried to ping 44.44.107.1 from&lt;br /&gt;
a different machine on some other network.  The ICMP echo request&lt;br /&gt;
packet gets routed through the UCSD gateway and tunneled back to&lt;br /&gt;
my gateway as before, but since responses don&#039;t go through back&lt;br /&gt;
through the tunnel, the response packet matches the default route&lt;br /&gt;
of my gateway and get&#039;s forwarded to comcast&#039;s router.  Comcast&lt;br /&gt;
would look at it, see that 44.44.107.1 wasn&#039;t on one of it&#039;s known&lt;br /&gt;
networks that it would route floor, and discard the response.  Oops.&lt;br /&gt;
&lt;br /&gt;
The solution was to set up a separate routing table in a different&lt;br /&gt;
routing domain specifically for AMPRNet traffic, and tie the two&lt;br /&gt;
together using firewall rules.  In the AMPRNet routing table, I&lt;br /&gt;
could set my default route to point to the UCSD gateway, so any&lt;br /&gt;
traffic sent from one of my 44.44.107.0/24 addresses that doesn&#039;t&lt;br /&gt;
match a route to a known tunnel gets forwarded through&lt;br /&gt;
amprgw.sysnet.ucsd.edu.  With that in place, I could ping my gateway&lt;br /&gt;
from random machines.  This must seem obvious to a lot of folks&lt;br /&gt;
here, but it took me a little while to figure out what was going&lt;br /&gt;
on.  Things are working now, however.&lt;br /&gt;
&lt;br /&gt;
So far I have encountered two other caveats: I decided to&lt;br /&gt;
configure two tunnel interfaces statically at boot time: &#039;gif0&#039;&lt;br /&gt;
goes to the UCSD tunnel, and &#039;gif1&#039; sets up a tunnel to N1URO for&lt;br /&gt;
his 44.88 net.  Under OpenBSD, I assumed that the natural way to&lt;br /&gt;
do this would be to add /etc/hostname.gif0 and /etc/hostname.gif1&lt;br /&gt;
files and this does in fact create the tunnels at boot time.  However,&lt;br /&gt;
traffic going out from my gateway doesn&#039;t seem to get sent through&lt;br /&gt;
the tunnels; I did not bother to track down exactly why, but I&lt;br /&gt;
believe it has to do with some kind of implicit ordering dependency&lt;br /&gt;
when initializing PF.  When I set up the separate routing domain,&lt;br /&gt;
it struck me that the language accepted by /etc/netstart in an&lt;br /&gt;
/etc/hostname.if file was not sufficiently rich to set up tunnels&lt;br /&gt;
in a routing domain, so I capitulated and just set up the static&lt;br /&gt;
interfaces from /etc/rc.local; imperfect but it works.&lt;br /&gt;
&lt;br /&gt;
The second caveat is that I seem to have tickled a kernel error&lt;br /&gt;
trying to set up an alias of a second IP address on my 44.44.107.1&lt;br /&gt;
NIC; I get a kernel panic due to an assertion failure.  It looks a&lt;br /&gt;
bug to me, but I haven&#039;t had the bandwidth to track it down.  In&lt;br /&gt;
the meanwhile, simply don&#039;t add aliases to interfaces in non-default&lt;br /&gt;
routing domains.&lt;br /&gt;
&lt;br /&gt;
The biggest piece missing was a daemon to handle receiving 44net&lt;br /&gt;
RIP packets and use that data to maintain tunnels and routes.  I&lt;br /&gt;
thought about porting one, but decided of write my own instead.&lt;br /&gt;
It has been running for a few weeks now on my node and while it&#039;s&lt;br /&gt;
still not quite &amp;quot;done&amp;quot; it seems to work well enough that I decided&lt;br /&gt;
it was time to cast a somewhat a wider net and push it up to&lt;br /&gt;
GitHub for comment from others.&lt;br /&gt;
&lt;br /&gt;
A couple of quick notes on implementation:&lt;br /&gt;
&lt;br /&gt;
1. The program maintains a copy of the AMPRNet routing table in a modified PATRICIA trie (really a compressed radix tree). Routes are expired after receiving a RIP packet.&lt;br /&gt;
2. A similar table of tunnels is maintained.&lt;br /&gt;
3. Tunnel interfaces are reference counted and garbage collected. A bitmap indicating which tunnels are in use is maintained.&lt;br /&gt;
4. The program is completely self-contained in the sense that I do not fork/exec external commands to e.g. configure tunnels or manipulate routes.  That is all done via ioctls or writing messages to a routing socket.&lt;br /&gt;
&lt;br /&gt;
There is more to do; I&#039;m sure there are a few bugs.  I&#039;d also like&lt;br /&gt;
to query the system state at startup to initialize the routing and&lt;br /&gt;
tunnel tables.  Exporting and/or parsing an encap file would be&lt;br /&gt;
nice.  Logging and error checking can, I&#039;m sure, be improved.&lt;br /&gt;
&lt;br /&gt;
It&#039;s about 1200 lines of non-comment code, compiles down to a 28K&lt;br /&gt;
MIPS64 executable (stripped).  The code is at&lt;br /&gt;
https://github.com/dancrossnyc/44ripd&lt;/div&gt;</summary>
		<author><name>Cross</name></author>
	</entry>
	<entry>
		<id>https://wiki.ampr.org/w/index.php?title=Setting_up_a_gateway_on_OpenBSD&amp;diff=645</id>
		<title>Setting up a gateway on OpenBSD</title>
		<link rel="alternate" type="text/html" href="https://wiki.ampr.org/w/index.php?title=Setting_up_a_gateway_on_OpenBSD&amp;diff=645"/>
		<updated>2016-09-24T02:46:11Z</updated>

		<summary type="html">&lt;p&gt;Cross: De-indent paragraphs so they aren&amp;#039;t interpreted as code by the Wiki&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;TODO(Cross): Wordsmith this section&lt;br /&gt;
&lt;br /&gt;
I am now successfully transferring traffic between my 44net subnet&lt;br /&gt;
(44.44.107.0/24) and the rest of the world using my OpenBSD-based&lt;br /&gt;
router.&lt;br /&gt;
&lt;br /&gt;
A quick recap of my setup:&lt;br /&gt;
1. I have a Comcast business class circuit.&lt;br /&gt;
2. I have a dedicated static IP address to use as an endpoint for&lt;br /&gt;
   44net traffic.&lt;br /&gt;
3. My comcast router is just a router; no NATing, no firewalling.&lt;br /&gt;
4. My (non-comcast) edge router is a Ubiquiti EdgeRouter Lite&lt;br /&gt;
   running OpenBSD 5.9.  It has three ethernet interfaces:&lt;br /&gt;
   a. cnmac0 is the external interface connected to Comcast&#039;s network&lt;br /&gt;
   b. cnmac1 connects to my internal network&lt;br /&gt;
   c. cnmac2 is my internal gateway to 44.44.107.0/24.&lt;br /&gt;
&lt;br /&gt;
On OpenBSD, tunneling interfaces for IPENCAP are provided by&lt;br /&gt;
&#039;gif&#039; pseudo-devices.  Unlike Linux, it appears that one creates a&lt;br /&gt;
separate &#039;gif&#039; interface for each tunnel, but one seems able to&lt;br /&gt;
create an arbitrary number of such interfaces: I created a thousand&lt;br /&gt;
as a test.  I&#039;m sure there is a limit but it seems sufficiently&lt;br /&gt;
high that practically routing AMPRNet traffic won&#039;t run up against&lt;br /&gt;
it.  (Again, if someone knows of a different way to configure a&lt;br /&gt;
single &#039;gif&#039; interface so that it could support multiple tunnels,&lt;br /&gt;
I&#039;d be happy to know about it).  In other words, don&#039;t worry about&lt;br /&gt;
scalability because you are creating a separate &#039;gif&#039; interface for&lt;br /&gt;
each tunnel to another AMPRNet site.&lt;br /&gt;
&lt;br /&gt;
On AMPRNet, the UCSD gateway *will not* pass traffic for an&lt;br /&gt;
IP address that does not have a corresponding entry in the AMPR.ORG&lt;br /&gt;
domain.  Also, 44.0.0.1 does not respond to &#039;ping&#039; from 44/8 IP&#039;s.&lt;br /&gt;
Caveat emptor as one tries to test: make sure you have DNS entries&lt;br /&gt;
for your addresses and try pinging something other than 44.0.0.1&lt;br /&gt;
or you&#039;ll suffer contusions banging your head against a desk trying&lt;br /&gt;
to figure out why nothing appears to work....&lt;br /&gt;
&lt;br /&gt;
Once I had a tunnel up to UCSD, I found that I could ping my&lt;br /&gt;
44.44.107.1 machine from a host on my internal network, but not&lt;br /&gt;
from arbitrary machines.  This was interesting; it turns out that&lt;br /&gt;
hosts on my internal network get NAT&#039;ed to another IP address on&lt;br /&gt;
the small subnet I got from Comcast (through another, completely&lt;br /&gt;
separate router -- not comcast&#039;s router but another ERL).  What was&lt;br /&gt;
happening was that as I ping&#039;ed 44.44.107.1 from e.g. my laptop,&lt;br /&gt;
ICMP echo request packets got NAT&#039;ed to this other address and&lt;br /&gt;
routed over to amprgw.sysnet.ucsd.edu and tunneled back to the&lt;br /&gt;
external interface of my AMPRNet gateway.  The gateway accepted the&lt;br /&gt;
encapsulated ICMP echo requests (I have a PF rule that explicitly&lt;br /&gt;
allows ping) and forwarded them across the tunnel interface where&lt;br /&gt;
they were unencapsulated; the IP stack saw that the result was&lt;br /&gt;
addressed to an IP address on a local interface (i.e., they were&lt;br /&gt;
for the router) and generated an ICMP echo response packet with a&lt;br /&gt;
*source* address of 44.44.107.1 and a *destination* address of the&lt;br /&gt;
external address of my other router (that is, the address the ICMP&lt;br /&gt;
echo request was NAT&#039;ed to).  This matched the network route for&lt;br /&gt;
my local Comcats subnet and so my AMPRNet router realized it could&lt;br /&gt;
pass the packet back to my other router directly.  It did so and&lt;br /&gt;
the other router happily took the packet, matched it back through&lt;br /&gt;
the NAT back to the original requesting machine (my laptop) and&lt;br /&gt;
forwarded it: hence, I got my ping responses back.  But note that&lt;br /&gt;
the response was not going through the tunnel back to UCSD: it was&lt;br /&gt;
being routed directly through the external interface.&lt;br /&gt;
&lt;br /&gt;
Now consider what happens when I tried to ping 44.44.107.1 from&lt;br /&gt;
a different machine on some other network.  The ICMP echo request&lt;br /&gt;
packet gets routed through the UCSD gateway and tunneled back to&lt;br /&gt;
my gateway as before, but since responses don&#039;t go through back&lt;br /&gt;
through the tunnel, the response packet matches the default route&lt;br /&gt;
of my gateway and get&#039;s forwarded to comcast&#039;s router.  Comcast&lt;br /&gt;
would look at it, see that 44.44.107.1 wasn&#039;t on one of it&#039;s known&lt;br /&gt;
networks that it would route floor, and discard the response.  Oops.&lt;br /&gt;
&lt;br /&gt;
The solution was to set up a separate routing table in a different&lt;br /&gt;
routing domain specifically for AMPRNet traffic, and tie the two&lt;br /&gt;
together using firewall rules.  In the AMPRNet routing table, I&lt;br /&gt;
could set my default route to point to the UCSD gateway, so any&lt;br /&gt;
traffic sent from one of my 44.44.107.0/24 addresses that doesn&#039;t&lt;br /&gt;
match a route to a known tunnel gets forwarded through&lt;br /&gt;
amprgw.sysnet.ucsd.edu.  With that in place, I could ping my gateway&lt;br /&gt;
from random machines.  This must seem obvious to a lot of folks&lt;br /&gt;
here, but it took me a little while to figure out what was going&lt;br /&gt;
on.  Things are working now, however.&lt;br /&gt;
&lt;br /&gt;
So far I have encountered two other caveats: I decided to&lt;br /&gt;
configure two tunnel interfaces statically at boot time: &#039;gif0&#039;&lt;br /&gt;
goes to the UCSD tunnel, and &#039;gif1&#039; sets up a tunnel to N1URO for&lt;br /&gt;
his 44.88 net.  Under OpenBSD, I assumed that the natural way to&lt;br /&gt;
do this would be to add /etc/hostname.gif0 and /etc/hostname.gif1&lt;br /&gt;
files and this does in fact create the tunnels at boot time.  However,&lt;br /&gt;
traffic going out from my gateway doesn&#039;t seem to get sent through&lt;br /&gt;
the tunnels; I did not bother to track down exactly why, but I&lt;br /&gt;
believe it has to do with some kind of implicit ordering dependency&lt;br /&gt;
when initializing PF.  When I set up the separate routing domain,&lt;br /&gt;
it struck me that the language accepted by /etc/netstart in an&lt;br /&gt;
/etc/hostname.if file was not sufficiently rich to set up tunnels&lt;br /&gt;
in a routing domain, so I capitulated and just set up the static&lt;br /&gt;
interfaces from /etc/rc.local; imperfect but it works.&lt;br /&gt;
&lt;br /&gt;
The second caveat is that I seem to have tickled a kernel error&lt;br /&gt;
trying to set up an alias of a second IP address on my 44.44.107.1&lt;br /&gt;
NIC; I get a kernel panic due to an assertion failure.  It looks a&lt;br /&gt;
bug to me, but I haven&#039;t had the bandwidth to track it down.  In&lt;br /&gt;
the meanwhile, simply don&#039;t add aliases to interfaces in non-default&lt;br /&gt;
routing domains.&lt;br /&gt;
&lt;br /&gt;
The biggest piece missing was a daemon to handle receiving 44net&lt;br /&gt;
RIP packets and use that data to maintain tunnels and routes.  I&lt;br /&gt;
thought about porting one, but decided of write my own instead.&lt;br /&gt;
It has been running for a few weeks now on my node and while it&#039;s&lt;br /&gt;
still not quite &amp;quot;done&amp;quot; it seems to work well enough that I decided&lt;br /&gt;
it was time to cast a somewhat a wider net and push it up to&lt;br /&gt;
GitHub for comment from others.&lt;br /&gt;
&lt;br /&gt;
A couple of quick notes on implementation:&lt;br /&gt;
&lt;br /&gt;
1. The program maintains a copy of the AMPRNet routing table in&lt;br /&gt;
   a modified PATRICIA trie (really a compressed radix tree).&lt;br /&gt;
   Routes are expired after receiving a RIP packet.&lt;br /&gt;
2. A similar table of tunnels is maintained.&lt;br /&gt;
3. Tunnel interfaces are reference counted and garbage collected.&lt;br /&gt;
   A bitmap indicating which tunnels are in use is&lt;br /&gt;
   maintained.&lt;br /&gt;
4. The program is completely self-contained in the sense that I&lt;br /&gt;
   do not fork/exec external commands to e.g. configure tunnels&lt;br /&gt;
   or manipulate routes.  That is all done via ioctls or writing&lt;br /&gt;
   messages to a routing socket.&lt;br /&gt;
&lt;br /&gt;
There is more to do; I&#039;m sure there are a few bugs.  I&#039;d also like&lt;br /&gt;
to query the system state at startup to initialize the routing and&lt;br /&gt;
tunnel tables.  Exporting and/or parsing an encap file would be&lt;br /&gt;
nice.  Logging and error checking can, I&#039;m sure, be improved.&lt;br /&gt;
&lt;br /&gt;
It&#039;s about 1200 lines of non-comment code, compiles down to a 28K&lt;br /&gt;
MIPS64 executable (stripped).  The code is at&lt;br /&gt;
https://github.com/dancrossnyc/44ripd&lt;/div&gt;</summary>
		<author><name>Cross</name></author>
	</entry>
	<entry>
		<id>https://wiki.ampr.org/w/index.php?title=Setting_up_a_gateway_on_OpenBSD&amp;diff=644</id>
		<title>Setting up a gateway on OpenBSD</title>
		<link rel="alternate" type="text/html" href="https://wiki.ampr.org/w/index.php?title=Setting_up_a_gateway_on_OpenBSD&amp;diff=644"/>
		<updated>2016-09-24T02:44:52Z</updated>

		<summary type="html">&lt;p&gt;Cross: Incorporate content from the mailing list. Next, I will massage this into a more useful page.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;TODO(Cross): Wordsmith this section&lt;br /&gt;
&lt;br /&gt;
Folks,&lt;br /&gt;
&lt;br /&gt;
    I just wanted to do a quick followup to this for the archives.&lt;br /&gt;
I am now successfully transferring traffic between my 44net subnet&lt;br /&gt;
(44.44.107.0/24) and the rest of the world using my OpenBSD-based&lt;br /&gt;
router.&lt;br /&gt;
&lt;br /&gt;
A quick recap of my setup:&lt;br /&gt;
1. I have a Comcast business class circuit.&lt;br /&gt;
2. I have a dedicated static IP address to use as an endpoint for&lt;br /&gt;
   44net traffic.&lt;br /&gt;
3. My comcast router is just a router; no NATing, no firewalling.&lt;br /&gt;
4. My (non-comcast) edge router is a Ubiquiti EdgeRouter Lite&lt;br /&gt;
   running OpenBSD 5.9.  It has three ethernet interfaces:&lt;br /&gt;
   a. cnmac0 is the external interface connected to Comcast&#039;s network&lt;br /&gt;
   b. cnmac1 connects to my internal network&lt;br /&gt;
   c. cnmac2 is my internal gateway to 44.44.107.0/24.&lt;br /&gt;
&lt;br /&gt;
    On OpenBSD, tunneling interfaces for IPENCAP are provided by&lt;br /&gt;
&#039;gif&#039; pseudo-devices.  Unlike Linux, it appears that one creates a&lt;br /&gt;
separate &#039;gif&#039; interface for each tunnel, but one seems able to&lt;br /&gt;
create an arbitrary number of such interfaces: I created a thousand&lt;br /&gt;
as a test.  I&#039;m sure there is a limit but it seems sufficiently&lt;br /&gt;
high that practically routing AMPRNet traffic won&#039;t run up against&lt;br /&gt;
it.  (Again, if someone knows of a different way to configure a&lt;br /&gt;
single &#039;gif&#039; interface so that it could support multiple tunnels,&lt;br /&gt;
I&#039;d be happy to know about it).  In other words, don&#039;t worry about&lt;br /&gt;
scalability because you are creating a separate &#039;gif&#039; interface for&lt;br /&gt;
each tunnel to another AMPRNet site.&lt;br /&gt;
&lt;br /&gt;
    On AMPRNet, the UCSD gateway *will not* pass traffic for an&lt;br /&gt;
IP address that does not have a corresponding entry in the AMPR.ORG&lt;br /&gt;
domain.  Also, 44.0.0.1 does not respond to &#039;ping&#039; from 44/8 IP&#039;s.&lt;br /&gt;
Caveat emptor as one tries to test: make sure you have DNS entries&lt;br /&gt;
for your addresses and try pinging something other than 44.0.0.1&lt;br /&gt;
or you&#039;ll suffer contusions banging your head against a desk trying&lt;br /&gt;
to figure out why nothing appears to work....&lt;br /&gt;
&lt;br /&gt;
    Once I had a tunnel up to UCSD, I found that I could ping my&lt;br /&gt;
44.44.107.1 machine from a host on my internal network, but not&lt;br /&gt;
from arbitrary machines.  This was interesting; it turns out that&lt;br /&gt;
hosts on my internal network get NAT&#039;ed to another IP address on&lt;br /&gt;
the small subnet I got from Comcast (through another, completely&lt;br /&gt;
separate router -- not comcast&#039;s router but another ERL).  What was&lt;br /&gt;
happening was that as I ping&#039;ed 44.44.107.1 from e.g. my laptop,&lt;br /&gt;
ICMP echo request packets got NAT&#039;ed to this other address and&lt;br /&gt;
routed over to amprgw.sysnet.ucsd.edu and tunneled back to the&lt;br /&gt;
external interface of my AMPRNet gateway.  The gateway accepted the&lt;br /&gt;
encapsulated ICMP echo requests (I have a PF rule that explicitly&lt;br /&gt;
allows ping) and forwarded them across the tunnel interface where&lt;br /&gt;
they were unencapsulated; the IP stack saw that the result was&lt;br /&gt;
addressed to an IP address on a local interface (i.e., they were&lt;br /&gt;
for the router) and generated an ICMP echo response packet with a&lt;br /&gt;
*source* address of 44.44.107.1 and a *destination* address of the&lt;br /&gt;
external address of my other router (that is, the address the ICMP&lt;br /&gt;
echo request was NAT&#039;ed to).  This matched the network route for&lt;br /&gt;
my local Comcats subnet and so my AMPRNet router realized it could&lt;br /&gt;
pass the packet back to my other router directly.  It did so and&lt;br /&gt;
the other router happily took the packet, matched it back through&lt;br /&gt;
the NAT back to the original requesting machine (my laptop) and&lt;br /&gt;
forwarded it: hence, I got my ping responses back.  But note that&lt;br /&gt;
the response was not going through the tunnel back to UCSD: it was&lt;br /&gt;
being routed directly through the external interface.&lt;br /&gt;
&lt;br /&gt;
    Now consider what happens when I tried to ping 44.44.107.1 from&lt;br /&gt;
a different machine on some other network.  The ICMP echo request&lt;br /&gt;
packet gets routed through the UCSD gateway and tunneled back to&lt;br /&gt;
my gateway as before, but since responses don&#039;t go through back&lt;br /&gt;
through the tunnel, the response packet matches the default route&lt;br /&gt;
of my gateway and get&#039;s forwarded to comcast&#039;s router.  Comcast&lt;br /&gt;
would look at it, see that 44.44.107.1 wasn&#039;t on one of it&#039;s known&lt;br /&gt;
networks that it would route floor, and discard the response.  Oops.&lt;br /&gt;
&lt;br /&gt;
    The solution was to set up a separate routing table in a different&lt;br /&gt;
routing domain specifically for AMPRNet traffic, and tie the two&lt;br /&gt;
together using firewall rules.  In the AMPRNet routing table, I&lt;br /&gt;
could set my default route to point to the UCSD gateway, so any&lt;br /&gt;
traffic sent from one of my 44.44.107.0/24 addresses that doesn&#039;t&lt;br /&gt;
match a route to a known tunnel gets forwarded through&lt;br /&gt;
amprgw.sysnet.ucsd.edu.  With that in place, I could ping my gateway&lt;br /&gt;
from random machines.  This must seem obvious to a lot of folks&lt;br /&gt;
here, but it took me a little while to figure out what was going&lt;br /&gt;
on.  Things are working now, however.&lt;br /&gt;
&lt;br /&gt;
    So far I have encountered two other caveats: I decided to&lt;br /&gt;
configure two tunnel interfaces statically at boot time: &#039;gif0&#039;&lt;br /&gt;
goes to the UCSD tunnel, and &#039;gif1&#039; sets up a tunnel to N1URO for&lt;br /&gt;
his 44.88 net.  Under OpenBSD, I assumed that the natural way to&lt;br /&gt;
do this would be to add /etc/hostname.gif0 and /etc/hostname.gif1&lt;br /&gt;
files and this does in fact create the tunnels at boot time.  However,&lt;br /&gt;
traffic going out from my gateway doesn&#039;t seem to get sent through&lt;br /&gt;
the tunnels; I did not bother to track down exactly why, but I&lt;br /&gt;
believe it has to do with some kind of implicit ordering dependency&lt;br /&gt;
when initializing PF.  When I set up the separate routing domain,&lt;br /&gt;
it struck me that the language accepted by /etc/netstart in an&lt;br /&gt;
/etc/hostname.if file was not sufficiently rich to set up tunnels&lt;br /&gt;
in a routing domain, so I capitulated and just set up the static&lt;br /&gt;
interfaces from /etc/rc.local; imperfect but it works.&lt;br /&gt;
&lt;br /&gt;
    The second caveat is that I seem to have tickled a kernel error&lt;br /&gt;
trying to set up an alias of a second IP address on my 44.44.107.1&lt;br /&gt;
NIC; I get a kernel panic due to an assertion failure.  It looks a&lt;br /&gt;
bug to me, but I haven&#039;t had the bandwidth to track it down.  In&lt;br /&gt;
the meanwhile, simply don&#039;t add aliases to interfaces in non-default&lt;br /&gt;
routing domains.&lt;br /&gt;
&lt;br /&gt;
The biggest piece missing was a daemon to handle receiving 44net&lt;br /&gt;
RIP packets and use that data to maintain tunnels and routes.  I&lt;br /&gt;
thought about porting one, but decided of write my own instead.&lt;br /&gt;
It has been running for a few weeks now on my node and while it&#039;s&lt;br /&gt;
still not quite &amp;quot;done&amp;quot; it seems to work well enough that I decided&lt;br /&gt;
it was time to cast a somewhat a wider net and push it up to&lt;br /&gt;
GitHub for comment from others.&lt;br /&gt;
&lt;br /&gt;
A couple of quick notes on implementation:&lt;br /&gt;
&lt;br /&gt;
1. The program maintains a copy of the AMPRNet routing table in&lt;br /&gt;
   a modified PATRICIA trie (really a compressed radix tree).&lt;br /&gt;
   Routes are expired after receiving a RIP packet.&lt;br /&gt;
2. A similar table of tunnels is maintained.&lt;br /&gt;
3. Tunnel interfaces are reference counted and garbage collected.&lt;br /&gt;
   A bitmap indicating which tunnels are in use is&lt;br /&gt;
   maintained.&lt;br /&gt;
4. The program is completely self-contained in the sense that I&lt;br /&gt;
   do not fork/exec external commands to e.g. configure tunnels&lt;br /&gt;
   or manipulate routes.  That is all done via ioctls or writing&lt;br /&gt;
   messages to a routing socket.&lt;br /&gt;
&lt;br /&gt;
There is more to do; I&#039;m sure there are a few bugs.  I&#039;d also like&lt;br /&gt;
to query the system state at startup to initialize the routing and&lt;br /&gt;
tunnel tables.  Exporting and/or parsing an encap file would be&lt;br /&gt;
nice.  Logging and error checking can, I&#039;m sure, be improved.&lt;br /&gt;
&lt;br /&gt;
It&#039;s about 1200 lines of non-comment code, compiles down to a 28K&lt;br /&gt;
MIPS64 executable (stripped).  The code is at&lt;br /&gt;
https://github.com/dancrossnyc/44ripd&lt;/div&gt;</summary>
		<author><name>Cross</name></author>
	</entry>
	<entry>
		<id>https://wiki.ampr.org/w/index.php?title=Setting_up_a_gateway_on_OpenBSD&amp;diff=643</id>
		<title>Setting up a gateway on OpenBSD</title>
		<link rel="alternate" type="text/html" href="https://wiki.ampr.org/w/index.php?title=Setting_up_a_gateway_on_OpenBSD&amp;diff=643"/>
		<updated>2016-09-24T02:13:57Z</updated>

		<summary type="html">&lt;p&gt;Cross: Setting up an AMPRNet Gateway on OpenBSD&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;TODO(Cross): Fill this section in&lt;/div&gt;</summary>
		<author><name>Cross</name></author>
	</entry>
	<entry>
		<id>https://wiki.ampr.org/w/index.php?title=Archive/Main_Page&amp;diff=642</id>
		<title>Archive/Main Page</title>
		<link rel="alternate" type="text/html" href="https://wiki.ampr.org/w/index.php?title=Archive/Main_Page&amp;diff=642"/>
		<updated>2016-09-24T02:13:20Z</updated>

		<summary type="html">&lt;p&gt;Cross: /* How to connect to AMPRNet */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Welcome to the AMPRNet Wiki.&lt;br /&gt;
&lt;br /&gt;
Since its allocation to Amateur Radio in the mid-1980&#039;s, Internet network 44 (44.0.0.0/8), known as the AMPRNet™, has been used by amateur radio operators to conduct scientific research and to experiment with digital communications over radio with a goal of advancing the state of the art of Amateur Radio networking, and to educate amateur radio operators in these techniques. - [http://www.ampr.org/ www.ampr.org]&lt;br /&gt;
__NOTOC__&lt;br /&gt;
== Starting points ==&lt;br /&gt;
* [[Quickstart]] guide for getting onto the [[AMPRNet]]&lt;br /&gt;
* Basic information about the [[AMPRNet]] and the [[ampr.org]] domain&lt;br /&gt;
* [[Services]] available on AMPRNet&lt;br /&gt;
* If you are looking to get an IP allocation within the 44/8 AMPRNet please read the [[Portal]] page.&lt;br /&gt;
* Frequently Asked Questions (FAQ) [[FAQ]]&lt;br /&gt;
&lt;br /&gt;
== How to connect to AMPRNet ==&lt;br /&gt;
&lt;br /&gt;
* Instructions for [[Setting up a gateway on Linux|setup a Linux gateway]]&lt;br /&gt;
* Instructions for [[Setting up a gateway on OpenBSD|setting up an OpenBSD gateway]]&lt;br /&gt;
* Instructions for [[setting up a gateway on Cisco Routers|setting up a  gateway on Cisco Routers]].&lt;br /&gt;
* Instructions for [[setting up a gateway on MikroTik Routers|setting up a  gateway on MikroTik Routers]].&lt;br /&gt;
* Instructions for [[setting up a gateway on OpenWRT|setting up a gateway on OpenWRT]].&lt;br /&gt;
* Instructions for [[setting up a gateway on Ubiquiti EdgeRouter|setting up a gateway on Ubiquiti EdgeRouter]].&lt;br /&gt;
* Instructions for [[announcing your allocation directly|directly announcing your allocation via your Internet Service Provider (ISP)]].&lt;br /&gt;
* Instructions for [[AMPRNet VPN|Accessing AMPRNet via VPN]] (experimental).&lt;br /&gt;
* &amp;lt;b&amp;gt;[[Why can&#039;t I just route my AMPRNet allocation directly myself ?]]&amp;lt;/b&amp;gt;&lt;br /&gt;
* If you already operate a [[gateway]] please ensure you have registered on the [[portal]] and &amp;quot;claimed&amp;quot; your [[gateway]].&lt;br /&gt;
&lt;br /&gt;
== Mailing List ==&lt;br /&gt;
To keep up-to-date on AMPRNet information please consider joining the [[44Net mailing list]].&lt;br /&gt;
&lt;br /&gt;
== Contribute! ==&lt;br /&gt;
If you wish to contribute to the wiki, please send an email to &amp;lt;tt&amp;gt;wiki (at) ampr.org&amp;lt;/tt&amp;gt; introducing yourself. Please specify your full name, amateur radio callsign and your preferred username. A login will then be created for you.&lt;br /&gt;
&lt;br /&gt;
== Terms of Service ==&lt;br /&gt;
Use of 44.0.0.0/8 address space and ampr.org DNS is governed by the following [http://www.ampr.org/wp-content/uploads/tos.txt Terms of Service]&lt;br /&gt;
&lt;br /&gt;
== All Pages ==&lt;br /&gt;
[http://wiki.ampr.org/wiki/Special:AllPages Here&#039;s a list of all pages currently on the AMPRNet Wiki]&lt;/div&gt;</summary>
		<author><name>Cross</name></author>
	</entry>
	<entry>
		<id>https://wiki.ampr.org/w/index.php?title=Talk:Ampr.org&amp;diff=625</id>
		<title>Talk:Ampr.org</title>
		<link rel="alternate" type="text/html" href="https://wiki.ampr.org/w/index.php?title=Talk:Ampr.org&amp;diff=625"/>
		<updated>2016-06-20T23:26:21Z</updated>

		<summary type="html">&lt;p&gt;Cross: Create the Talk:Ampr.org page.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Talk about [[Ampr.org]]&lt;/div&gt;</summary>
		<author><name>Cross</name></author>
	</entry>
	<entry>
		<id>https://wiki.ampr.org/w/index.php?title=Talk:Ampr.org&amp;diff=624</id>
		<title>Talk:Ampr.org</title>
		<link rel="alternate" type="text/html" href="https://wiki.ampr.org/w/index.php?title=Talk:Ampr.org&amp;diff=624"/>
		<updated>2016-06-20T23:25:03Z</updated>

		<summary type="html">&lt;p&gt;Cross: Created page with &amp;quot;Test&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Test&lt;/div&gt;</summary>
		<author><name>Cross</name></author>
	</entry>
	<entry>
		<id>https://wiki.ampr.org/w/index.php?title=User_talk:Cross&amp;diff=623</id>
		<title>User talk:Cross</title>
		<link rel="alternate" type="text/html" href="https://wiki.ampr.org/w/index.php?title=User_talk:Cross&amp;diff=623"/>
		<updated>2016-06-20T19:41:43Z</updated>

		<summary type="html">&lt;p&gt;Cross: Blanked the page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Cross</name></author>
	</entry>
	<entry>
		<id>https://wiki.ampr.org/w/index.php?title=User_talk:Kb3vwg&amp;diff=621</id>
		<title>User talk:Kb3vwg</title>
		<link rel="alternate" type="text/html" href="https://wiki.ampr.org/w/index.php?title=User_talk:Kb3vwg&amp;diff=621"/>
		<updated>2016-06-19T12:25:34Z</updated>

		<summary type="html">&lt;p&gt;Cross: I&amp;#039;m sorry, I still don&amp;#039;t understand your comment.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;I&#039;m not sure which edit you were referring to in the note you left on my talk:Cross page?&lt;br /&gt;
&lt;br /&gt;
I&#039;m sorry but I don&#039;t understand your comment. What about that edit were you referring to? You linked to an RFC that talks about CIDR for reverse DNS delegation and a non-AMPR case, but the edit was to a page specifically about AMPR and had nothing to do with reverse delegation.... The UCSD filter configuration is independent of all of that, right? Perhaps it would make more sense to move this conversation over to the http://wiki.ampr.org/wiki/User_talk:Ampr.org page?&lt;/div&gt;</summary>
		<author><name>Cross</name></author>
	</entry>
	<entry>
		<id>https://wiki.ampr.org/w/index.php?title=User:Cross&amp;diff=618</id>
		<title>User:Cross</title>
		<link rel="alternate" type="text/html" href="https://wiki.ampr.org/w/index.php?title=User:Cross&amp;diff=618"/>
		<updated>2016-06-18T22:22:53Z</updated>

		<summary type="html">&lt;p&gt;Cross: Created page with &amp;quot;My name is Dan Cross. I&amp;#039;m a software engineer; my call  sign is AC2OI. You can find out  more about me on my personal web page: http://pub.gajendra.net/&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;My name is Dan Cross. I&#039;m a software engineer; my call  sign is AC2OI. You can find out  more about me on my personal web page: http://pub.gajendra.net/&lt;/div&gt;</summary>
		<author><name>Cross</name></author>
	</entry>
	<entry>
		<id>https://wiki.ampr.org/w/index.php?title=User_talk:Kb3vwg&amp;diff=617</id>
		<title>User talk:Kb3vwg</title>
		<link rel="alternate" type="text/html" href="https://wiki.ampr.org/w/index.php?title=User_talk:Kb3vwg&amp;diff=617"/>
		<updated>2016-06-18T22:21:04Z</updated>

		<summary type="html">&lt;p&gt;Cross: Created page with &amp;quot;I&amp;#039;m not sure which edit you were referring to in the note you left on my talk:Cross page?&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;I&#039;m not sure which edit you were referring to in the note you left on my talk:Cross page?&lt;/div&gt;</summary>
		<author><name>Cross</name></author>
	</entry>
	<entry>
		<id>https://wiki.ampr.org/w/index.php?title=User_talk:Cross&amp;diff=616</id>
		<title>User talk:Cross</title>
		<link rel="alternate" type="text/html" href="https://wiki.ampr.org/w/index.php?title=User_talk:Cross&amp;diff=616"/>
		<updated>2016-06-18T22:19:40Z</updated>

		<summary type="html">&lt;p&gt;Cross: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;I&#039;m not sure this edit is totally relevant to the NON-AMPR Community, this is actually recommended under RFC 2317 (see https://tools.ietf.org/html/rfc2317), and is simply standard practice.&lt;br /&gt;
&lt;br /&gt;
I&#039;m not sure which edit you&#039;re referring to specifically; I only see a note on my talk:Cross page?&lt;/div&gt;</summary>
		<author><name>Cross</name></author>
	</entry>
	<entry>
		<id>https://wiki.ampr.org/w/index.php?title=Ampr.org&amp;diff=613</id>
		<title>Ampr.org</title>
		<link rel="alternate" type="text/html" href="https://wiki.ampr.org/w/index.php?title=Ampr.org&amp;diff=613"/>
		<updated>2016-06-17T19:34:56Z</updated>

		<summary type="html">&lt;p&gt;Cross: Mention that and entry in the AMPR.ORG domain is mandatory for the UCSD gateway to forward packets to an IP address.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;AMPR.ORG is the domain that is available for ham radio operators to register their [[AMPRNet]] network [https://en.wikipedia.org/wiki/Host_%28network%29 hosts], and for other ham radio related computer systems.&lt;br /&gt;
&lt;br /&gt;
Domain names in AMPR.ORG are available to any licensed [https://en.wikipedia.org/wiki/Amateur_radio_operator amateur radio operator] who is interested in advancing the art of ham radio digital communications. In most countries, there is a local coordinator who is responsible for assigning an address and updating the master hosts list. There is no formal organization, no membership requirements, and no dues. All of the work is done by volunteers as they have time to do it. Note that an IP address &#039;&#039;must&#039;&#039; be associated with a domain name in AMPR.ORG in order for the main gateway at UCSD to pass packets to it.&lt;br /&gt;
&lt;br /&gt;
If you are a ham who needs an address, contact your local coordinator. AMPR.ORG is not intended to be, and should not be used as, a substitute for buying a personal domain name. It&#039;s really there for ham radio use.&lt;br /&gt;
&lt;br /&gt;
= Updating the ampr.org DNS zone =&lt;br /&gt;
&lt;br /&gt;
... TODO: write up on how to formulate a good update request to the local coordinator.&lt;br /&gt;
&lt;br /&gt;
Contact your local coordinator to request an update of the zone. A list of coordinators can be found on the [[Portal]]:&lt;br /&gt;
&lt;br /&gt;
* [https://portal.ampr.org/networks.php https://portal.ampr.org/networks.php]&lt;/div&gt;</summary>
		<author><name>Cross</name></author>
	</entry>
	<entry>
		<id>https://wiki.ampr.org/w/index.php?title=Archive/Main_Page&amp;diff=612</id>
		<title>Archive/Main Page</title>
		<link rel="alternate" type="text/html" href="https://wiki.ampr.org/w/index.php?title=Archive/Main_Page&amp;diff=612"/>
		<updated>2016-06-17T19:32:05Z</updated>

		<summary type="html">&lt;p&gt;Cross: Link quickstart to main page.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Welcome to the AMPRNet Wiki.&lt;br /&gt;
&lt;br /&gt;
Since its allocation to Amateur Radio in the mid-1980&#039;s, Internet network 44 (44.0.0.0/8), known as the AMPRNet™, has been used by amateur radio operators to conduct scientific research and to experiment with digital communications over radio with a goal of advancing the state of the art of Amateur Radio networking, and to educate amateur radio operators in these techniques. - [http://www.ampr.org/ www.ampr.org]&lt;br /&gt;
__NOTOC__&lt;br /&gt;
== Starting points ==&lt;br /&gt;
* [[Quickstart]] guide for getting onto the [[AMPRNet]]&lt;br /&gt;
* Basic information about the [[AMPRNet]] and the [[ampr.org]] domain&lt;br /&gt;
* [[Services]] available on AMPRNet&lt;br /&gt;
* If you are looking to get an IP allocation within the 44/8 AMPRNet please read the [[Portal]] page.&lt;br /&gt;
* Frequently Asked Questions (FAQ) [[FAQ]]&lt;br /&gt;
&lt;br /&gt;
== How to connect to AMPRNet ==&lt;br /&gt;
&lt;br /&gt;
* Instructions for [[Setting up a gateway on Linux|setup a Linux gateway]]&lt;br /&gt;
* Instructions for [[setting up a gateway on Cisco Routers|setting up a  gateway on Cisco Routers]].&lt;br /&gt;
* Instructions for [[setting up a gateway on MikroTik Routers|setting up a  gateway on MikroTik Routers]].&lt;br /&gt;
* Instructions for [[setting up a gateway on OpenWRT|setting up a gateway on OpenWRT]].&lt;br /&gt;
* Instructions for [[setting up a gateway on Ubiquiti EdgeRouter|setting up a gateway on Ubiquiti EdgeRouter]].&lt;br /&gt;
* Instructions for [[announcing your allocation directly|directly announcing your allocation via your Internet Service Provider (ISP)]].&lt;br /&gt;
* Instructions for [[AMPRNet VPN|Accessing AMPRNet via VPN]] (experimental).&lt;br /&gt;
* &amp;lt;b&amp;gt;[[Why can&#039;t I just route my AMPRNet allocation directly myself ?]]&amp;lt;/b&amp;gt;&lt;br /&gt;
* If you already operate a [[gateway]] please ensure you have registered on the [[portal]] and &amp;quot;claimed&amp;quot; your [[gateway]].&lt;br /&gt;
&lt;br /&gt;
== Mailing List ==&lt;br /&gt;
To keep up-to-date on AMPRNet information please consider joining the [[44Net mailing list]].&lt;br /&gt;
&lt;br /&gt;
== Contribute! ==&lt;br /&gt;
If you wish to contribute to the wiki, please send an email to &amp;lt;tt&amp;gt;wiki (at) ampr.org&amp;lt;/tt&amp;gt; introducing yourself. Please specify your full name, amateur radio callsign and your preferred username. A login will then be created for you.&lt;br /&gt;
&lt;br /&gt;
== Terms of Service ==&lt;br /&gt;
Use of 44.0.0.0/8 address space and ampr.org DNS is governed by the following [http://www.ampr.org/tos.txt Terms of Service]&lt;br /&gt;
&lt;br /&gt;
== All Pages ==&lt;br /&gt;
[http://wiki.ampr.org/wiki/Special:AllPages Here&#039;s a list of all pages currently on the AMPRNet Wiki]&lt;/div&gt;</summary>
		<author><name>Cross</name></author>
	</entry>
	<entry>
		<id>https://wiki.ampr.org/w/index.php?title=Quickstart&amp;diff=611</id>
		<title>Quickstart</title>
		<link rel="alternate" type="text/html" href="https://wiki.ampr.org/w/index.php?title=Quickstart&amp;diff=611"/>
		<updated>2016-06-17T19:31:26Z</updated>

		<summary type="html">&lt;p&gt;Cross: Remove more elaborate heading.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;So you&#039;re a licensed amateur radio operator, you&#039;re interested in IP networking, and you want to combine the two. [[AMPRNet]] is for you. This Quickstart guide can help get you set up quickly.&lt;br /&gt;
&lt;br /&gt;
To get online with [[AMPRNet]], you will probably want to start with a tunnel connection to the rest of the network. You will need the following:&lt;br /&gt;
&lt;br /&gt;
# A router. This can be a specialized routing device, or a general purpose computer. It probably won&#039;t need a lot of compute power, so you can recycle an old PC or something similar.&lt;br /&gt;
# An Internet connection that gives you a stable IP address for the rest of the network to talk to you: [[AMPRnet]] tunnels pass 44/8 data between parts of the AMPR network by encapsulating them in non-44net Internet traffic. Static IP addresses are best for this, but IP addresses dynamically assigned to you by your ISP may work if they change infrequently.&lt;br /&gt;
&lt;br /&gt;
Once you have a machine to act as a router and a suitable network connection, do the following:&lt;br /&gt;
&lt;br /&gt;
# [https://portal.ampr.org/register.php Register] on the [[portal]].&lt;br /&gt;
# Request a network allocation from your regional coordinator.&lt;br /&gt;
## From the portal&#039;s [https://portal.ampr.org/networks.php networks] page, navigate to your country and region&#039;s network subpage.&lt;br /&gt;
## From the regional network page, request an allocation. Note, select only ONE of the connection options (Radio, Tunnel, or Direct). To start, you probably want to select &#039;Tunnel&#039;. For more information on requesting an allocation, see the wiki page on [[Requesting a block]].&lt;br /&gt;
# Once your allocation has been granted, [https://portal.ampr.org/gateways_manage.php register your gateway through the portal].&lt;br /&gt;
# Once your gateway has been registered, contact your regional coordinator to register DNS mappings for the hosts on your network. Note that the main tunnel router at UCSD will NOT pass traffic to an IP address unless that address is associated with a hostname in the [[Ampr.org|ampr.org]] DNS domain.&lt;br /&gt;
# Configure your router to act as a [[Gateway]] to the rest of the network.&lt;br /&gt;
&lt;br /&gt;
That&#039;s it! You now have a tunnel to the rest of the network. From here, you can connect devices via RF links, subnet your network if you like, and start exploring TCP/IP over amateur radio.&lt;br /&gt;
&lt;br /&gt;
== Next Steps ==&lt;br /&gt;
&lt;br /&gt;
Once you are connected, you should subscribe to the [[44Net mailing list]].&lt;/div&gt;</summary>
		<author><name>Cross</name></author>
	</entry>
</feed>