On Wednesday, January 14th, 2026 at 10:23 PM, Stuart Henderson
<[email protected]> wrote:
>
> On 2026/01/14 21:50, [email protected] wrote:
>
> > You're right that other ports like net/tor have patches like that. But is
> > this a good enough reason to just copy and paste? My point was that there's
> > no practical benefit to set i2pd's working directory as /var/i2pd instead
> > of /var/lib/i2pd. On the contrary, there's a potential drawback, also on
> > the practical level: the risk of confusing some users. The trade-off here
> > is style and consistency on the one side vs. practicality on the other.
>
>
> /var/lib isn't very openbsd-ish, is only used by 3 ports, and IIR
> there's a backburner proposal to symlink /var/lib -> /var/db if we
>
> can figure out how to get things moved out the way without breakking
> updates too badly. So if we can get these files moved it would be a
> good step on the way to that.
OK, I was not aware of that.
> > You're right that the web interface definitely adds some attack surface.
> > But what's the threat model exactly? The web interface allows "any user on
> > the system", let's say a malicious user, to shut down the daemon, namely
> > enables a denial-of-service attack. This malicious user could also access
> > private information, like your router identity or the B32 addresses of your
> > tunnels. That's probably what you mean by "deanonymizing you"... But bear
> > in mind that "any user on the system" can easily get the machine's IP
> > address anyway, which is usually what you want to conceal. And even with
> > the web interface disabled, any local user could also access i2pd's
> > configuration files, which are world-readable by default and can include
> > some private information (encrypted LeaseSets keys in
> > /etc/i2pd/tunnels.conf for example).
>
>
> That sounds like a good argument to use mode 750 for /etc/i2pd..
Right, that's a good idea.
> > On the other hand, the web interface can be very useful to control and
> > monitor the i2pd daemon. It's impossible to know what proportion of i2pd
> > users rely on this feature, but my guess is that it is widely used, hence
> > the i2pd developers enabled it by default.
> >
> > In any case, we can also add a note to the README warning users about the
> > risks associated with the web interface.
>
>
> OpenBSD policy would usually be to disable potentially risky things
> by default and let people enable them if they want rather than hope
> they actually read pkg-readme (a lot of users seem not to).
Fair point.
Let's explain that in the README anyway, in case users wonder why the web
interface doesn't work 😅
Here's the patch I came up with, taking into account your remarks and David's
proposals:
- /var/i2pd is set as working directory instead of /var/lib/i2pd
- logs are sent to syslogd by default
- HTTP interface is disabled by default
- /etc/i2pd is mode 750, and the config files within this directory are mode 640
Lightly tested on amd64 for now. The port builds fine, all tests are still
passing, and it seems to run just fine, as far as I tested.
I hope it will be OK like that.
Index: Makefile
===================================================================
RCS file: /cvs/ports/net/i2pd/Makefile,v
diff -u -p -r1.31 Makefile
--- Makefile 12 Nov 2025 02:13:09 -0000 1.31
+++ Makefile 15 Jan 2026 02:05:35 -0000
@@ -3,6 +3,7 @@ COMMENT = client for the I2P anonymous n
GH_ACCOUNT = PurpleI2P
GH_PROJECT = i2pd
GH_TAGNAME = 2.58.0
+REVISION = 0
CATEGORIES = net
HOMEPAGE = https://i2pd.website
Index: patches/patch-contrib_i2pd_conf
===================================================================
RCS file: patches/patch-contrib_i2pd_conf
diff -N patches/patch-contrib_i2pd_conf
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ patches/patch-contrib_i2pd_conf 15 Jan 2026 02:05:35 -0000
@@ -0,0 +1,41 @@
+Index: contrib/i2pd.conf
+--- contrib/i2pd.conf.orig
++++ contrib/i2pd.conf
+@@ -8,16 +8,16 @@
+
+ ## Tunnels config file
+ ## Default: ~/.i2pd/tunnels.conf or /var/lib/i2pd/tunnels.conf
+-# tunconf = /var/lib/i2pd/tunnels.conf
++tunconf = /etc/i2pd/tunnels.conf
+
+ ## Tunnels config files path
+ ## Use that path to store separated tunnels in different config files.
+ ## Default: ~/.i2pd/tunnels.d or /var/lib/i2pd/tunnels.d
+-# tunnelsdir = /var/lib/i2pd/tunnels.d
++tunnelsdir = /etc/i2pd/tunnels.d
+
+ ## Path to certificates used for verifying .su3, families
+ ## Default: ~/.i2pd/certificates or /var/lib/i2pd/certificates
+-# certsdir = /var/lib/i2pd/certificates
++certsdir = /etc/i2pd/certificates
+
+ ## Where to write pidfile (default: /run/i2pd.pid, not used in Windows)
+ # pidfile = /run/i2pd.pid
+@@ -30,7 +30,7 @@
+ ## * stdout - print log entries to stdout
+ ## * file - log entries to a file
+ ## * syslog - use syslog, see man 3 syslog
+-# log = file
++log = syslog
+ ## Path to logfile (default: autodetect)
+ # logfile = /var/log/i2pd/i2pd.log
+ ## Log messages above this level (debug, info, *warn, error, critical, none)
+@@ -118,7 +118,7 @@
+ [http]
+ ## Web Console settings
+ ## Enable the Web Console (default: true)
+-# enabled = true
++enabled = false
+ ## Address and port service will listen on (default: 127.0.0.1:7070)
+ # address = 127.0.0.1
+ # port = 7070
Index: pkg/PLIST
===================================================================
RCS file: /cvs/ports/net/i2pd/pkg/PLIST,v
diff -u -p -r1.17 PLIST
--- pkg/PLIST 12 Nov 2025 02:13:09 -0000 1.17
+++ pkg/PLIST 15 Jan 2026 02:05:35 -0000
@@ -1,5 +1,5 @@
@newgroup _i2pd:838
-@newuser _i2pd:838:838::i2pd account:${LOCALSTATEDIR}/lib/i2pd:/sbin/nologin
+@newuser _i2pd:838:838::i2pd account:${LOCALSTATEDIR}/i2pd:/sbin/nologin
@rcscript ${RCDIR}/i2pd
@bin bin/i2pd
include/i2pd/
@@ -69,14 +69,16 @@ include/i2pd/util.h
include/i2pd/version.h
@static-lib lib/libi2pd.a
@static-lib lib/libi2pdclient.a
+@mode 0750
@owner _i2pd
@group _i2pd
@sample ${SYSCONFDIR}/i2pd/
-@sample ${LOCALSTATEDIR}/lib/i2pd/
-@sample ${LOCALSTATEDIR}/lib/i2pd/certificates/
-@sample ${LOCALSTATEDIR}/lib/i2pd/certificates/family/
-@sample ${LOCALSTATEDIR}/lib/i2pd/certificates/reseed/
-@sample ${LOCALSTATEDIR}/lib/i2pd/certificates/router/
+@mode
+@sample ${LOCALSTATEDIR}/i2pd/
+@sample ${LOCALSTATEDIR}/i2pd/certificates/
+@sample ${LOCALSTATEDIR}/i2pd/certificates/family/
+@sample ${LOCALSTATEDIR}/i2pd/certificates/reseed/
+@sample ${LOCALSTATEDIR}/i2pd/certificates/router/
@owner
@group
@static-lib lib/libi2pdlang.a
@@ -87,127 +89,131 @@ share/examples/i2pd/certificates/family/
share/examples/i2pd/certificates/family/gostcoin.crt
@owner _i2pd
@group _i2pd
-@sample ${LOCALSTATEDIR}/lib/i2pd/certificates/family/gostcoin.crt
+@sample ${LOCALSTATEDIR}/i2pd/certificates/family/gostcoin.crt
@owner
@group
share/examples/i2pd/certificates/family/i2p-dev.crt
@owner _i2pd
@group _i2pd
-@sample ${LOCALSTATEDIR}/lib/i2pd/certificates/family/i2p-dev.crt
+@sample ${LOCALSTATEDIR}/i2pd/certificates/family/i2p-dev.crt
@owner
@group
share/examples/i2pd/certificates/family/i2pd-dev.crt
@owner _i2pd
@group _i2pd
-@sample ${LOCALSTATEDIR}/lib/i2pd/certificates/family/i2pd-dev.crt
+@sample ${LOCALSTATEDIR}/i2pd/certificates/family/i2pd-dev.crt
@owner
@group
share/examples/i2pd/certificates/family/mca2-i2p.crt
@owner _i2pd
@group _i2pd
-@sample ${LOCALSTATEDIR}/lib/i2pd/certificates/family/mca2-i2p.crt
+@sample ${LOCALSTATEDIR}/i2pd/certificates/family/mca2-i2p.crt
@owner
@group
share/examples/i2pd/certificates/family/stormycloud.crt
@owner _i2pd
@group _i2pd
-@sample ${LOCALSTATEDIR}/lib/i2pd/certificates/family/stormycloud.crt
+@sample ${LOCALSTATEDIR}/i2pd/certificates/family/stormycloud.crt
@owner
@group
share/examples/i2pd/certificates/family/volatile.crt
@owner _i2pd
@group _i2pd
-@sample ${LOCALSTATEDIR}/lib/i2pd/certificates/family/volatile.crt
+@sample ${LOCALSTATEDIR}/i2pd/certificates/family/volatile.crt
@owner
@group
share/examples/i2pd/certificates/reseed/
@owner _i2pd
@group _i2pd
-@sample ${LOCALSTATEDIR}/lib/
+@sample ${LOCALSTATEDIR}/
@owner
@group
share/examples/i2pd/certificates/reseed/acetone_at_mail.i2p.crt
@owner _i2pd
@group _i2pd
-@sample ${LOCALSTATEDIR}/lib/i2pd/certificates/reseed/acetone_at_mail.i2p.crt
+@sample ${LOCALSTATEDIR}/i2pd/certificates/reseed/acetone_at_mail.i2p.crt
@owner
@group
share/examples/i2pd/certificates/reseed/admin_at_stormycloud.org.crt
@owner _i2pd
@group _i2pd
-@sample ${LOCALSTATEDIR}/lib/i2pd/certificates/reseed/admin_at_stormycloud.org.crt
+@sample ${LOCALSTATEDIR}/i2pd/certificates/reseed/admin_at_stormycloud.org.crt
@owner
@group
share/examples/i2pd/certificates/reseed/creativecowpat_at_mail.i2p.crt
@owner _i2pd
@group _i2pd
-@sample ${LOCALSTATEDIR}/lib/i2pd/certificates/reseed/creativecowpat_at_mail.i2p.crt
+@sample ${LOCALSTATEDIR}/i2pd/certificates/reseed/creativecowpat_at_mail.i2p.crt
@owner
@group
share/examples/i2pd/certificates/reseed/echelon3_at_mail.i2p.crt
@owner _i2pd
@group _i2pd
-@sample ${LOCALSTATEDIR}/lib/i2pd/certificates/reseed/echelon3_at_mail.i2p.crt
+@sample ${LOCALSTATEDIR}/i2pd/certificates/reseed/echelon3_at_mail.i2p.crt
@owner
@group
share/examples/i2pd/certificates/reseed/hankhill19580_at_gmail.com.crt
@owner _i2pd
@group _i2pd
-@sample ${LOCALSTATEDIR}/lib/i2pd/certificates/reseed/hankhill19580_at_gmail.com.crt
+@sample ${LOCALSTATEDIR}/i2pd/certificates/reseed/hankhill19580_at_gmail.com.crt
@owner
@group
share/examples/i2pd/certificates/reseed/i2p-reseed_at_mk16.de.crt
@owner _i2pd
@group _i2pd
-@sample ${LOCALSTATEDIR}/lib/i2pd/certificates/reseed/i2p-reseed_at_mk16.de.crt
+@sample ${LOCALSTATEDIR}/i2pd/certificates/reseed/i2p-reseed_at_mk16.de.crt
@owner
@group
share/examples/i2pd/certificates/reseed/igor_at_novg.net.crt
@owner _i2pd
@group _i2pd
-@sample ${LOCALSTATEDIR}/lib/i2pd/certificates/reseed/igor_at_novg.net.crt
+@sample ${LOCALSTATEDIR}/i2pd/certificates/reseed/igor_at_novg.net.crt
@owner
@group
share/examples/i2pd/certificates/reseed/lazygravy_at_mail.i2p.crt
@owner _i2pd
@group _i2pd
-@sample ${LOCALSTATEDIR}/lib/i2pd/certificates/reseed/lazygravy_at_mail.i2p.crt
+@sample ${LOCALSTATEDIR}/i2pd/certificates/reseed/lazygravy_at_mail.i2p.crt
@owner
@group
share/examples/i2pd/certificates/reseed/orignal_at_mail.i2p.crt
@owner _i2pd
@group _i2pd
-@sample ${LOCALSTATEDIR}/lib/i2pd/certificates/reseed/orignal_at_mail.i2p.crt
+@sample ${LOCALSTATEDIR}/i2pd/certificates/reseed/orignal_at_mail.i2p.crt
@owner
@group
share/examples/i2pd/certificates/reseed/r4sas-reseed_at_mail.i2p.crt
@owner _i2pd
@group _i2pd
-@sample ${LOCALSTATEDIR}/lib/i2pd/certificates/reseed/r4sas-reseed_at_mail.i2p.crt
+@sample ${LOCALSTATEDIR}/i2pd/certificates/reseed/r4sas-reseed_at_mail.i2p.crt
@owner
@group
share/examples/i2pd/certificates/reseed/rambler_at_mail.i2p.crt
@owner _i2pd
@group _i2pd
-@sample ${LOCALSTATEDIR}/lib/i2pd/certificates/reseed/rambler_at_mail.i2p.crt
+@sample ${LOCALSTATEDIR}/i2pd/certificates/reseed/rambler_at_mail.i2p.crt
@owner
@group
share/examples/i2pd/certificates/reseed/reseed_at_diva.exchange.crt
@owner _i2pd
@group _i2pd
-@sample ${LOCALSTATEDIR}/lib/i2pd/certificates/reseed/reseed_at_diva.exchange.crt
+@sample ${LOCALSTATEDIR}/i2pd/certificates/reseed/reseed_at_diva.exchange.crt
@owner
@group
share/examples/i2pd/i2pd.conf
+@mode 0640
@owner _i2pd
@group _i2pd
@sample ${SYSCONFDIR}/i2pd/i2pd.conf
+@mode
@owner
@group
share/examples/i2pd/tunnels.conf
+@mode 0640
@owner _i2pd
@group _i2pd
@sample ${SYSCONFDIR}/i2pd/tunnels.conf
+@mode
@owner
@group
share/examples/login.conf.d/i2pd
Index: pkg/README
===================================================================
RCS file: /cvs/ports/net/i2pd/pkg/README,v
diff -u -p -r1.4 README
--- pkg/README 16 Apr 2024 15:22:32 -0000 1.4
+++ pkg/README 15 Jan 2026 02:05:35 -0000
@@ -24,3 +24,48 @@ and also edit /etc/login.conf.d/i2pd:
:openfiles-cur=8192:\
:openfiles-max=8192:\
:tc=daemon:
+
+
+The HTTP interface
+==================
+
+On OpenBSD, i2pd's HTTP interface is disabled by default, because it
+allows any user on the system to perform actions on the daemon, such
+as shutting it down, or access private data, such as the router
+identity and the tunnels' B32 addresses.
+
+If you want to use this interface anyway, you can reenable it in
+/etc/i2pd/i2pd.conf under the [http] section.
+
+
+Graceful shutdown
+=================
+
+It is good practice to shutdown the i2pd daemon gracefully, to avoid
+immediatly severing all connections, which would disconnect all
+your peers and affect the overall operation of the I2P network.
+
+You can initiate a graceful shutdown without the HTTP interface by
+sending a signal to the i2pd daemon like this:
+
+ kill -INT $(cat /var/i2pd/i2pd.pid)
+
+When it shuts down gracefully, the i2pd daemon waits for all transit
+tunnels to expire, which usually takes 10 minutes.
+
+
+Logging
+=======
+
+By default, the OpenBSD port of ${PKGSTEM} sends its log messages to
+syslogd(8), which writes them to the /var/log/daemon file.
+
+The default log level of ${PKGSTEM} ("warn") can be very verbose. You
+may want to reduce this log verbosity by changing the "loglevel"
+parameter in /etc/i2pd/i2pd.conf.
+
+If you want log messages to be written to another file, e.g.
+/var/i2pd/i2pd.log, you can change the "log" and "logfile" parameters
+in /etc/i2pd/i2pd.conf. To have this log file rotated automatically,
+see `man 8 newsyslog.conf`, and please take into account that the i2pd
+daemon should be restarted gracefully at each rotation.
Index: pkg/i2pd.rc
===================================================================
RCS file: /cvs/ports/net/i2pd/pkg/i2pd.rc,v
diff -u -p -r1.4 i2pd.rc
--- pkg/i2pd.rc 11 Mar 2022 19:46:04 -0000 1.4
+++ pkg/i2pd.rc 15 Jan 2026 02:05:35 -0000
@@ -2,7 +2,7 @@
daemon="${TRUEPREFIX}/bin/i2pd --daemon"
daemon_user="_i2pd"
-daemon_flags="--service --datadir=${LOCALSTATEDIR}/lib/i2pd --conf=${SYSCONFDIR}/i2pd/i2pd.conf --tunconf=${SYSCONFDIR}/i2pd/tunnels.conf --tunnelsdir=${SYSCONFDIR}/i2pd/tunnels.d"
+daemon_flags="--service --datadir=${LOCALSTATEDIR}/i2pd --conf=${SYSCONFDIR}/i2pd/i2pd.conf --tunconf=${SYSCONFDIR}/i2pd/tunnels.conf --tunnelsdir=${SYSCONFDIR}/i2pd/tunnels.d --certsdir=${LOCALSTATEDIR}/i2pd/certificates"
. /etc/rc.d/rc.subr