| Title: Using the I2P network with OpenBSD and NixOS | |
| Author: Solène | |
| Date: 20 June 2021 | |
| Tags: i2p tor openbsd nixos networking | |
| Description: | |
| # Introduction | |
| In this text I will explain what is the I2P network and how to provide | |
| a service over I2P on OpenBSD and how to use to connect to an I2P | |
| service from NixOS. | |
| # I2P | |
| This acronym stands for Invisible Internet Project and is a network | |
| over the network (Internet). It is quite an old project from 2003 and | |
| is considered stable and reliable. The idea of I2P is to build a | |
| network of relays (people running an i2p daemon) to make tunnels from a | |
| client to a server, but a single TCP session (or UDP) between a client | |
| and a server could use many tunnels of n hops across relays. | |
| Basically, when you start your I2P service, the program will get some | |
| information about the relays available and prepare many tunnels in | |
| advance that will be used to reach a destination when you connect. | |
| Some benefits from I2P network: | |
| * your network is reliable because it doesn't take care of operator | |
| peering | |
| * your network is secure because packets are encrypted, and you can | |
| even use usual encryption to reach your remote services (TLS, SSH) | |
| * provides privacy because nobody can tell where you are connecting to | |
| * can prevent against habits tracking (if you also relay data to | |
| participate to i2p, bandwidth allocated is used at 100% all the time, | |
| and any traffic you do over I2P can't be discriminated from standard | |
| relay!) | |
| * can only allow declared I2P nodes to access a server if you don't | |
| want anyone to connect to a port you expose | |
| It is possible to host a website on I2P (by exposing your web server | |
| port), it is called an eepsite and can be accessed using the SOCKs | |
| proxy provided by your I2P daemon. I never played with them though but | |
| this is a thing and you may be interested into looking more in depth. | |
| I2P project and I2P implementation (java) page | |
| i2pd project (a recent C++ implementation that I use for this tutorial) | |
| Wikipedia page about I2P | |
| # I2P vs Tor | |
| Obviously, many people would question why not using Tor which seems | |
| similar. While I2P can seem very close to Tor hidden services, the | |
| implementation is really different. Tor is designed to reach the | |
| outside while I2P is meant to build a reliable and anonymous network. | |
| When started, Tor creates a path of relays named a Circuit that will | |
| remain static for an approximate duration of 12 hours, everything you | |
| do over Tor will pass through this circuit (usually 3 relays), on the | |
| other hand I2P creates many tunnels all the time with a very low | |
| lifespan. Small difference, I2P can relay UDP protocol while Tor only | |
| supports TCP. | |
| Tor is very widespread and using a tor hidden service for hosting a | |
| private website (if you don't have a public IP or a domain name for | |
| example) would be better to reach an audience, I2P is not very well | |
| known and that's partially why I'm writing this. It is a fantastic | |
| piece of software and only require more users. | |
| Relays in I2P doesn't have any weight and can be seen as a huge P2P | |
| network while Tor network is built using scores (consensus) of relaying | |
| servers depending of their throughput and availability. Fastest and | |
| most reliable relays will be elected as "Guard server" which are entry | |
| points to the Tor network. | |
| I've been running a test over 10 hours to compare bandwidth usage of | |
| I2P and Tor to keep a tunnel / hidden service available (they have not | |
| been used). Please note that relaying/transit were desactivated so | |
| it's only the uploaded data in order to keep the service working. | |
| * I2P sent 55.47 MB of data in 114 430 packets. Total / 10 hours = 1.58 | |
| kB/s average. | |
| * Tor sent 6.98 MB of data in 14 759 packets. Total / 10 hours = 0.20 | |
| kB/s average. | |
| Tor was a lot more bandwidth efficient than I2P for the same task: | |
| keeping the network access (tor or i2p) alive. | |
| # Quick explanation about how it works | |
| There are three components in an I2P usage. | |
| - a computer running an I2P daemon configured with tunnels servers (to | |
| expose a TCP/UDP port from this machine, not necessarily from localhost | |
| though) | |
| - a computer running an I2P daemon configured with tunnel client (with | |
| information that match the server tunnel) | |
| - computers running I2P and allowing relay, they will receive data from | |
| other I2P daemons and pass the encrypted packets. They are the core of | |
| the network. | |
| In this text we will use an OpenBSD system to share its localhost ssh | |
| access over I2P and a NixOS client to reach the OpenBSD ssh port. | |
| # OpenBSD | |
| The setup is quite simple, we will use i2pd and not the i2p java | |
| program. | |
| ```shell commands | |
| pkg_add i2pd | |
| # read /usr/local/share/doc/pkg-readmes/i2pd for open files limits | |
| cat <<EOF > /etc/i2pd/tunnels.conf | |
| [SSH] | |
| type = server | |
| port = 22 | |
| host = 127.0.0.1 | |
| keys = ssh.dat | |
| EOF | |
| rcctl enable i2pd | |
| rcctl start i2pd | |
| ``` | |
| You can edit the file /etc/i2pd/i2pd.conf to uncomment the line | |
| "notransit = true" if you don't want to relay. I would encourage | |
| people to contribute to the network by relaying packets but this would | |
| require some explanations about a nice tuning to limit the bandwidth | |
| correctly. If you disable transit, you won't participate into the | |
| network but I2P won't use any CPU and virtually no data if your tunnel | |
| is in use. | |
| Visit http://localhost:7070/ for the admin interface and check the menu | |
| "I2P Tunnels", you should see a line "SSH => " with a long address | |
| ending by .i2p with :22 added to it. This is the address of your | |
| tunnel on I2P, we will need it (without the :22) to configure the | |
| client. | |
| # Nixos | |
| As usual, on NixOS we will only configure the | |
| /etc/nixos/configuration.nix file to declare the service and its | |
| configuration. | |
| We will name the tunnel "ssh-solene" and use the destination seen on | |
| the administration interface on the OpenBSD server and expose that port | |
| to 127.0.0.1:2222 on our NixOS box. | |
| ```nixos configuration file | |
| services.i2pd.enable = true; | |
| services.i2pd.notransit = true; | |
| services.i2pd.outTunnels = { | |
| ssh-solene = { | |
| enable = true; | |
| name = "ssh"; | |
| destination = "gajcbkoosoztqklad7kosh226tlt5wr2srr2tm4zbcadulxw2o5a.b32.i2p… | |
| address = "127.0.0.1"; | |
| port = 2222; | |
| }; | |
| }; | |
| ``` | |
| Now you can use "nixos-rebuild switch" as root to apply changes. | |
| Note that the equivalent NixOS configuration for any other OS would | |
| look like that for any I2P setup in the file "tunnel.conf" (on OpenBSD | |
| it would be in /etc/i2pd/tunnels.conf). | |
| ```i2pd tunnels.conf | |
| [ssh-solene] | |
| type = client | |
| address = 127.0.0.1 # optional, default is 127.0.0.1 | |
| port = 2222 | |
| destination = gajcbkoosoztqklad7kosh226tlt5wr2srr2tm4zbcadulxw2o5a.b32.i2p | |
| ``` | |
| # Test the setup | |
| From the NixOS client you should be able to run "ssh -p 2222 localhost" | |
| and get access to the OpenBSD ssh server. | |
| Both systems have a http://localhost:7070/ interface because it's a | |
| default setting that is not bad (except if you have multiple people who | |
| can access the box). | |
| # Conclusion | |
| I2P is a nice way to share services on a reliable and privacy friendly | |
| network, it may not be fast but shouldn't drop you when you need it. | |
| Because it can easily bypass NAT or dynamic IP it's perfectly fine for | |
| a remote system you need to access when you can use NAT or VPN. |