└── README.md /README.md: -------------------------------------------------------------------------------- 1 | # NetworkRecipes 2 | 3 | ## Introduction 4 | 5 | Many of these examples are assuming a dedicated gateway machine. This could be your grid's file server, or it could be a dedicated gateway box that has extra Ethernet adapters installed and booting as a diskless cpu server. 6 | 7 | Some of these examples make use of the /cfg directory. This deirectory is checked by the default configuration script in /rc/bin/cpurc for machine specific configuration. In many of these examples, *gate* is used as the name of the gateway machine. To add additional configuration files for your gateway machine, add a directory with the same name as your gateway machine. Into that directory, create files and be sure to make them executable. These files are not found in /cfg by default, and must be added. Other options include; 8 | 9 | + cpurc 10 | 11 | This is ran fairly early from /rc/bin/cpurc and is useful to set up things that will be called from later parts of the default configuration. 12 | 13 | + cpustart 14 | 15 | This is called at the end of the default cpurc, so this is used to do more configuration after all the defaults have been done. 16 | 17 | + namespace 18 | 19 | This is used to add additional things to the default namespace on this machine. It is called at the end of the default namespace recipe found in /lib/namespace. 20 | 21 | + service/ 22 | 23 | This is a directory that functions like /rc/bin/service/. The files must be named in a specific way for the system to run listen(8) at the specific port and protocol. Keep in mind that this service directory will be ran in place of, and _not_ in addition to, the default /rc/bin/service/ scripts. 24 | 25 | ### Warning 26 | 27 | Another thing to be cafeful of, which depends on the font being used to render this text, is the distinction between the kernel devices '#l' and '#I'. The first is a lower case L, and those are for the Ethernet interface, see; ether(3). The second is a upper case i, and that is for the IP stack interface, see; ip(3). Some fonts make it hard to tell the two letter apart. Additionally, be aware of the TLS device '#a', which may need to be included in any custom /net directory for TLS connections to function properly; see tls(3). 28 | 29 | There are also Connection Service and DNS, which are usually posted to /srv and mounted from there, see; ndb(8). In some of these examples, it will show running the 'nbd/cs' and 'nbd/dns' commands for configuration. If CS an DNS have already been setup for a given side of a gateway, you may be able to just run 'mount -a /srv/cs /net.alt' and 'mount -a /srv/dns /net.alt'. If CS and DNS aren't configured properly or mounted properly, 'ip/ping' by sysname or domain name will fail. In cases where the -x flag is used, like 'ndb/cd -x net.alt -f /lib/outside', the /srv post produced will be '/srv/dns_net.alt'. 30 | 31 | ## Plan9 style imported interface: 32 | 33 | This is the classic idea of importing an outside facing networking interface into the namespace of a process that needs access to the outside world. In this scenario you would have a closed network for the 9Front machines. One of the machines, *gate*, has 2 Ethernet ports and is running as a cpu server. 34 | 35 | + ether0 = inside network 36 | + ether1 = outside network 37 | 38 | This assumes ether0 is the default network interace configured at boot. The second Ethernet port (#l1) and a second IP stack (#I1) will be added to /net.alt. It will then be configured via DHCP by what ever assigns addresses on the outside network. Next, add Connection Service (ndb/cs) and DNS (ndb/dns), using the -x flag to specify that this is a network stack in /net.alt, rather than the default /net (see; ndb(8)). Finally, srvfs is used to package all this up and place it in /srv so that it can be mounted into a namespace. 39 | 40 | The following demonstrates this as a script placed in /cfg/gate, and will be ran from /cfg/gate/cpustart. To make it so that this outside network stack always appears in /net.alt on *gate*, the a mount is included in /cfg/gate/namespace. 41 | 42 | ### /cfg/gate/mknet1 43 | 44 | #!/bin/rc 45 | rfork 46 | bind '#l1' /net.alt 47 | bind -a '#I1' /net.alt 48 | ip/ipconfig -x /net.alt ether /net.alt/ether1 49 | ndb/cs -x /net.alt 50 | ndb/dns -x /net.alt 51 | srvfs -p 666 outside.net /net.alt 52 | 53 | ### /cfg/gate/cpustart 54 | 55 | #!/bin/rc 56 | /cfg/gate/mknet4 57 | 58 | ### /cfg/gate/naemspace 59 | 60 | mount -ac /srv/net1 /net.alt 61 | 62 | 63 | ## Moody's NAT: 64 | 65 | This is taken from instructions found here: https://posixcafe.org/blogs/2024/01/04/0/ 66 | 67 | In this case, ether0 (#l0) is assumed to be configured at boot to be the standard cpu server interface, where the machine can be called with rcpu(1). 68 | 69 | This will setup ether1 (#l1) as the inside port to be used as the gateway. The inside network is using 198.168.2.0, and the gateway port will be set to 192.168.2.1. The outside interface will be ether2 (#l2), and will use DHCP to be configured by the outside network. Each interface will use it's own IP stack (#I1 and #I2). 70 | 71 | In this setup, the configuration is done in a script called *mknat* and will be called by /cfg/gate/cpustart. 72 | 73 | ### /cfg/gate/mknat 74 | 75 | #!/bin/rc 76 | rfork 77 | # /net set up for inside connection 78 | bind '#I1' /net 79 | bind -a '#l1' /net 80 | 81 | # /net.alt setup for outside connection 82 | bind '#I2' /net.alt 83 | bind -a '#l2' /net.alt 84 | 85 | x=/net.alt 86 | o=/net 87 | <$x/ipifc/clone { 88 | # Read the new interface number 89 | xi=$x/ipifc/`{read} 90 | 91 | # Write in to the ctl file of the newly created interface to configure it 92 | >$xi/ctl { 93 | # This is a packet interface 94 | echo bind pkt 95 | 96 | # Our ip is 192.168.69.3/24 and we only allow remote connections from 192.168.69.2 97 | echo add 192.168.69.3 255.255.255.255 192.168.69.2 98 | 99 | # Route packets to others 100 | echo iprouting 1 101 | 102 | # Now create a new interface on the inside IP stack 103 | <$o/ipifc/clone { 104 | oi=$o/ipifc/`{read} 105 | >$oi/ctl { 106 | # Hook up this device to the outside IP stack device 107 | echo bind netdev $xi/data 108 | 109 | # Our ip is 192.168.69.2/24 and we only allow remote connections from 192.168.69.3 110 | echo add 192.168.69.2 255.255.255.0 192.168.69.3 111 | echo iprouting 1 112 | } 113 | } 114 | } 115 | } 116 | 117 | # Configure our route table for both the inside and outside IP stacks 118 | # Arguments are: target mask nexthop interface(addressed by IP) 119 | echo add 192.168.2.0 255.255.255.0 192.168.69.2 192.168.69.3 > $x/iproute 120 | echo add 0.0.0.0 /96 192.168.69.3 192.168.69.2 > $o/iproute 121 | 122 | # Do DHCP on the external interface. -x tells us which 123 | # IP stack to use. -t tells us that we are doing NAT 124 | # and to configure the route table as such. NAT is implemented 125 | # as just a route table flag. 126 | ip/ipconfig -x /net.alt -t ether /net.alt/ether2 127 | 128 | # Configure a static IP on our internal interface, which will 129 | # act as a gateway for our internal network. 130 | ip/ipconfig ether /net/ether1 192.168.2.1 255.255.255.0 131 | 132 | # Package up these namespaces 133 | srvfs -p 644 nat-out /net.alt 134 | srvfs -p 644 nat-in /net 135 | 136 | This script can then be set to run automaticaly at boot. 137 | 138 | ### /cfg/gate/cpustart 139 | 140 | #!/bin/rc 141 | /cfg/gate/mknat 142 | 143 | An entry for the gateway as ipgw will need to be added to /lib/ndb/local so that the other systems inside the grid know where the gateway is and to automatically forward outbound traffic there. 144 | 145 | ### /lib/ndb/local 146 | 147 | ... 148 | ipgw=192.168.2.1 149 | ... 150 | 151 | 152 | 153 | ## Basic Tunnel: 154 | 155 | This is taken from: https://9lab.org/plan9/tunnel/ 156 | 157 | This could be used to create a connection between your home 9Front system and a VPS running 9Front. This has the upside of being both very simple to do, and is initiated by your local system, rather than something running on the remote system that could be exploited. 158 | 159 | From the home system, run the command; 160 | 161 | inside% rexport -s inside.9lab.home / outside.9lab.org & 162 | 163 | This will send a /srv post to outside.9lab.org, which will appear there as /srv/inside.9lab.home . In this case it is sending everything from the root directory on down. So the entire namespace that rexport was ran in. 164 | 165 | On the remote system, run the command; 166 | 167 | outside% mount /srv/inside.9lab.home /n/inside.9lab.home 168 | 169 | Running this on the remote system would mean that everything in / on the local system can now be read from /n/inside.9lab.home/ . 170 | 171 | The local system's /net can then be mounted and accessed in the remote system, allowing for use of rcpu. 172 | 173 | outside% bind /n/inside.9lab.home/net /net.alt 174 | outside% rcpu -h /net.alt/tcp!inside.9lab.home 175 | 176 | 177 | 178 | ## Fancy Tunnel: 179 | 180 | In this case a virtual Ethernet interface (#l5) will be created and bridged to an unused physical Ethernet interface (#l3). That virtual interface can then be sent via rexport to a remote system and mounted there. The remote machine will then be directly accessable through 10.0.0.99 on the local grid. On this machine, there is 1 on board Ethernet port for ether0, and a 4 port Ethernet PCIe card for ether1-4. So ether5 would be the first '#l' that wouldn't be associated whith a physical Ethernet device. 181 | 182 | First, set up the unused ether3 (#l3) as the trunk end of of a bridge (#B1). 183 | 184 | ### /cfg/gate/mknet3 185 | 186 | #!/bin/rc 187 | rfork 188 | bind '#B1' /net 189 | bind -a '#l3' /net 190 | echo 'bind ether trunk 0 /net/ether3' >/net/bridge1/ctl 191 | srvfs -p 666 net4 /net 192 | 193 | Next, configure ether5 (#l5) as a virtual interface (sink) and give it a MAC address (cafe42000005). Then hook is at port1 on the same bridge (#B1). Add an IP stack (#I5), run ip/ipconfig to give it address 10.0.0.99. CS and DNS can be set up by just using the existing inside grid ones mounted from /srv/cs and /srv/dns. Finally, post this setup to /srv. 194 | 195 | ### /cfg/gate/mknet5 196 | 197 | #!/bin/rc 198 | rfork 199 | bind -a '#B1' /net 200 | bind '#l5:sink ea=cafe42000005' /net.alt 201 | echo 'bind ether port1 0 /net.alt/ether5' >/net/bridge1/ctl 202 | bind -a '#I5' /net.alt 203 | ip/ipconfig -x /net.alt -g 10.0.0.1 ether /net.alt/ether5 10.0.0.105 255.255.255.0 204 | mount -a /srv/cs /net.alt 205 | mount -a /srv/dns /net.alt 206 | srvfs -p 666 net5 /net.alt 207 | 208 | On the inside machine, run; 209 | 210 | gate% mount /srv/net5 /n/net5 211 | gate% rexport -s net5 /n/net5 outside.com 212 | 213 | On the outside machine, run; 214 | 215 | outside% mount /srv/net5 /n/net5 216 | outside% bind -b /n/net5 /net 217 | 218 | Since this is using a virtual Ethernet interface bridged to a physical interface, more virtual one can be added which will share that physical interface. Just use another '#ln', '#In'. MAC and IP address, and port number on the bridge. 219 | 220 | ### /cfg/gate/mknet6 221 | 222 | #!/bin/rc 223 | rfork 224 | bind -a '#B1' /net 225 | bind '#l6:sink ea=cafe42000006' /net.alt 226 | echo 'bind ether port2 0 /net.alt/ether6' >/net/bridge1/ctl 227 | bind -a '#I6' /net.alt 228 | ip/ipconfig -x /net.alt -g 10.0.0.1 ether /net.alt/ether5 10.0.0.106 255.255.255.0 229 | mount -a /srv/cs /net.alt 230 | mount -a /srv/dns /net.alt 231 | srvfs -p 666 net6 /net.alt 232 | 233 | 234 | The interface exported as *net5* allow the remote machine to ping and connect to systems inside the local network from 10.0.0.105. For the remote system to answer rcpu and other connection, the remote system will need to run listen on that interface, see; listen(8). 235 | 236 | For listen to work properly, it must have a namespace which includes this net5 interface. This can be passed as a file to listen with the -n flag. What needs to be included is; 237 | 238 | mount /srv/net5 /net.alt 239 | 240 | Since you may not want this in every namespace by default, you can make another namespace recipe, like /lib/namespace.for.net5, copy in all the contents of /lib/namespace and add the line for mount /srv/net5. This can then be added to the listen command. 241 | 242 | aux/listen -q -d $serviced -n /lib/namespace.for.net5 /net.alt/tcp 243 | 244 | This will run the standard services from /rc/bin/service. To add authentication, add the auth services, and auth/keyfs may be required to get the keys in the namespace; 245 | 246 | auth/keyfs -wp -m /mnt/keys /adm/keys 247 | aux/listen -q -t /rc/bin/service.auth -d $serviced -n /lib/namespace.for.net5 /net.alt/tcp 248 | 249 | When crossing authdom boundries, entries for those systems may need to be added to /lib/ndb/local, common, or additional ndb files, so that an auth server is specified. 250 | 251 | 252 | --------------------------------------------------------------------------------