Transparent I2P tunneling

These notes are to setup an I2P FreeNAS jail to transparently tunnel .i2p traffic using a Ubiquiti EdgeRouter ER-X

Huge kudos to these notes that got me moving in the right direction:

This is the logical flow of what we are going to setup. Pictures really help the understanding.

As I have an EdgeRouter ER-X the instructions will cover what you need to configure on this device in terms of the router setup

Setup DNSMASQ on server to catch .i2p DNS requests return the IP as the domain lookup


Test it out. Any domain ending in .i2p will return the IP

# dig @ hello.i2p

; <<>> DiG 9.9.4-RedHat-9.9.4-51.el7 <<>> @ hello.i2p
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 8423
;; flags: qr aa rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;hello.i2p.                     IN      A

hello.i2p.              0       IN      A

;; Query time: 0 msec
;; WHEN: Tue Dec 19 02:13:21 UTC 2017
;; MSG SIZE  rcvd: 43

We need to configure a NAT rule to redirect our traffic to the server running the privoxy/i2p software.

ubnt@ubnt# show service nat
 nat {
     rule 1 {
         description i2p
         destination {
             port 80
         inbound-interface switch0
         inside-address {
             port 8118
         log disable
         protocol tcp
         source {
             group {
                 address-group !I2P_EXCLUDE
         type destination
     rule 5001 {
         description "masquerade for WAN"
         outbound-interface eth0
         type masquerade
     rule 5002 {
         description "hairpin for i2p"
         destination {
             port 8118
         log disable
         outbound-interface switch0
         protocol tcp
         source {
         type masquerade

ubnt@ubnt# show firewall group
 address-group I2P_EXCLUDE {
     description "exclude these IP address from being routed via i2p proxy"

We will end up with a NAT configuration like this:

With the following firewall rule.

I run i2p and privoxy inside a FreeNAS jail so these instructions reflect this.

Follow the instructions to setup the I2P jail

Now the I2P jail is setup we need install the privoxy for transparent routing. The jail does not install privoxy.

Install privoxy into the jail and forward .i2p domain name requests to the router.

# pkg install privoxy

Allow it to autostart edit /etc/rc.conf


We need to pre-create this

# mkdir /var/run/privoxy
# chown privoxy:privoxy /var/run/privoxy

Start Privoxy manually to create the necessary config files run:

# /usr/local/etc/rc.d/privoxy forcestart

This will create the file /usr/local/etc/privoxy/config

That is hokey. You have to run it to create the config file so you can edit it ?

Edit the configuration file

accept-intercepted-requests 1
forward .i2p

Restart after making those changes

/usr/local/etc/rc.d/privoxy restart
2019/06/25 22:37 · 0 Linkbacks

Setting up Opengrok in a FreeNAS 11.2 iocage jail

Create storage dataset's for GROK

Create a jail for GROK

Setup jail mount points for src and data. You need to stop the jail to add mount points and then restart afterwards.

  • /mnt/u03/opengrok/src → /var/opengrok/src
  • /mnt/u03/opengrok/data → /var/opengrok/data

Find the JAIL and open a shell

root@ale[~]# jls
   JID  IP Address      Hostname                      Path
     1                  plex                          /mnt/u02/iocage/jails/plex/root
     2                  bind                          /mnt/u02/iocage/jails/bind/root
     5                  beer                          /mnt/u02/iocage/jails/beer/root
     6                  grok                          /mnt/u02/iocage/jails/grok/root
root@ale[~]# jexec 6 /bin/sh

Install opengrok and git. To generate the history caches from GIT based repositories we need the git command line tool.

# pkg install -y opengrok git

# pkg info opengrok
Name           : opengrok
Version        : 1.0
Installed on   : Tue May 14 09:04:03 2019 EDT
Origin         : devel/opengrok
Architecture   : FreeBSD:11:*
Prefix         : /usr/local
Categories     : devel java
Licenses       : APACHE20, CDDL
Maintainer     :
WWW            :
Comment        : Fast and powerful code search and cross-reference engine
Options        :
        DOCS           : on
        RESIN3         : off
        TOMCAT6        : off
        TOMCAT7        : off
        TOMCAT8        : on
        TOMCAT85       : off
Annotations    :
        repo_type      : binary
        repository     : FreeBSD
Flat size      : 20.5MiB
Description    :
OpenGrok is a fast source code search and cross reference engine.
It helps you search, cross-reference and navigate your source tree.  It can
understand various program file formats and version control histories like
Mercurial, Git, SCCS, RCS, CVS, Subversion, Teamware, ClearCase, Perforce
and Bazaar.  In other words it lets you grok (profoundly understand) the
open source, hence the name OpenGrok.  It is written in Java.


This installs tomcat8 we need to autostart this.

# ls /usr/local/etc/rc.d

Enable for auto start /etc/rc.conf

echo tomcat8_enable="YES" >>/etc/rc.conf

and start it

service tomcat8 start

This should fire up with an error. That's OK as we have not indexed anything the error will disappear after indexing.

Make a directory

mkdir /var/opengrok/etc

Create a helper script and run it.

cat <<EOF >~/opengrok-index
opengrok -c /usr/local/bin/exctags -s /var/opengrok/src -d /var/opengrok/data -H -P -S -G -W /var/opengrok/etc/configuration.xml
service tomcat8 restart
chmod a+x ~/opengrok-index

The -U parameter only takes host:port and it assumes the WEBAPP is called /source which means the indexer can't tell the running opengrok to reload. So restart tomcat as part of the index run. A minor wart.

Making opengrok the default webapp and use port 80

Moving tomcat from port 8080 to port 80 Edit /usr/local/apache-tomcat-8.0/conf/server.xml file and replace 8080 with 80

    <Connector port="80" protocol="HTTP/1.1"
               redirectPort="8443" />

Make opengrok the default web application by adding a <Context> tag inside <Host>

      <Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">

        <Context path="" docBase="/usr/local/apache-tomcat-8.0/webapps/opengrok">
2019/06/25 00:00 · 0 Linkbacks

Setting up MoinMoin in a FreeNAS 11.2 iocage jail

Create a jail and attach the storage into the JAIL at this location: /usr/local/www/wiki/data

Login to the jail and install moin this version will do nicely.

# pkg search moin
moinmoin-1.9.10                Easy to use, full-featured and extensible wiki software package

Install MoinMoin and run the recommend steps installing from a package.

# pkg install -y moinmoin

Setup for WSGI

export MOINSCRIPT="moin.wsgi"
export MOINDIR="/usr/local/share/moin"
export MOINDEST="/usr/local/www/wiki"
export CGIUSER="www"
export CGIGROUP="www"
mkdir -p ${MOINDEST}/data
mkdir -p ${MOINDEST}/underlay
cp -R ${MOINDIR}/data ${MOINDEST}
cp -R ${MOINDIR}/underlay ${MOINDEST}
chmod -R u+rw,go-ws ${MOINDEST}/data
install -m 0555 ${MOINDIR}/config/ ${MOINDEST}
test -z "${MOINSCRIPT}" || \
        install -m 0555 ${MOINDIR}/server/${MOINSCRIPT} ${MOINDEST}

Based very closely around *

Install nginx and uwsgi server

pkg install -y nginx uwsgi

Replace /usr/local/etc/nginx/nginx.conf with

worker_processes  1;

events {
    worker_connections  1024;

http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;

    keepalive_timeout  65;

    server {
            listen 80;
            server_name wiki.local;

            location / {
                    uwsgi_pass unix:/var/run/moin.sock;
                    include uwsgi_params;

            location ~ ^/moin_static[0-9]+/(.*) {                    
                    alias  /usr/local/lib/python2.7/site-packages/MoinMoin/web/static/htdocs/$1;


NOTE: Its important to access the server by a DNS name in the nginx.conf file that resolves to the jail IP. Not doing this will result in the NGINX server not being able to correctly lookup the static content.

Append to /etc/rc.conf



Create /usr/local/www/wiki/uwsgi.ini

socket = /var/run/moin.sock
chmod-socket = 660
chdir = /usr/local/www/wiki
wsgi-file = moin.wsgi
workers = 3
max-requests = 200
harakiri = 30

Allow anybody to edit anything and for them to create their own account.

Add the acl_rights_default entries and uncomment page_front_page and actions_superuser.


class Config(multiconfig.DefaultConfig):
    # Critical setup  ---------------------------------------------------
    # Directory containing THIS wikiconfig:
    wikiconfig_dir = os.path.abspath(os.path.dirname(__file__))
    acl_rights_default = u"All:read,write,delete,revert,admin"
    page_front_page = u'FrontPage'
    actions_superuser = multiconfig.DefaultConfig.actions_superuser[:]

Start it up

service uwsgi start
service ngnix start

Speeding up searching by enabling xapian

pkg install xapian-core py27-xapian


    xapian_search = True
    xapian_stemming = True


service uwsgi restart

You can check to see if its enabled by navigating to SystemInfo

Grab the plugin: and install the file into /usr/local/www/wiki/data/plugin/parser/

File with all modification presented below:

Install additional packages into the jail:

  • plotutils → supplies pic2plot
  • ImageMagick7-nox11 → supplied convert
pkg update -f
pkg install plotutils
pkg install ImageMagick7-nox11

We need to edit the source code to adjust where the required utilities are installed.

pic2plot path change

             # Launch pic2plot => postscript
            os.system ('/usr/local/bin/pic2plot -T ps "%s" > "%s" 2>"%s"' % (pic, ps, err))

The convert program would not run with just the path to the program. The path /usr/local/bin has to be in the PATH env var.

            # Run the postprocessing/conversion chain
            cmd = 'PATH=$PATH:/usr/local/bin convert -density %dx%d "%s" "%s"' % (opt_percent, opt_percent, ps, pngpath)

Enabling the alternative format specification

The src code was modified to include the alt= switch so that original and alternative could be supported in the wiki.

*** 804,813 ****
--- 804,815 ----
          opt_dbg  = False
          opt_help = None
          opt_percent = 100
+         opt_alt = False
          for (key, val) in self.attrs.items ():
              val = val [1:-1]
              if   key == 'debug':   opt_dbg  = int (val)
              elif key == 'help':    opt_help = val
+             elif key == 'alt':     opt_alt = True
              elif key == 'percent': opt_percent = int (val)
                  self.request.write (formatter.rawHTML ("""
*** 845,851 ****
          lines = raw.split ('\n')

          # alternate syntax support
!         lines = self._convert_from_alternate_1 (lines)

          # debug ? post-print
          if opt_dbg==2:
--- 847,854 ----
          lines = raw.split ('\n')

          # alternate syntax support
!         if opt_alt:
!            lines = self._convert_from_alternate_1 (lines)

          # debug ? post-print
          if opt_dbg==2:

Using the alternate format to draw diagrams

{{{#!umlsequence alt=1
S : s:Switch
P : p:Pump
S -> P run()
S -> P stop()

The original syntax

# Object definition
# Message exchange
# Object lifeline completion

2019/06/24 23:50 · 0 Linkbacks

Chrome randomly shows pink purple letters

Chrome updated itself to 69.0.3497.100 (Official Build) (64-bit) and ever since then I have experienced text that has random pink, purple and blue highlights.


This was corrected by entering chrome:⁄⁄settings into the chrome address area and then searching for hardware acceleration and disabling it.


2018/10/11 18:28 · 0 Linkbacks

CCB request completed with an error

FreeNAS server was randomly crashing:

(da0:umass-sim0:0:0:0): Retrying command
(da0:umass-sim0:0:0:0): WRITE(10). CDB: 2a 00 00 24 26 9d 00 00 10 00
(da0:umass-sim0:0:0:0): CAM status: CCB request completed with an error
(da0:umass-sim0:0:0:0): Error 5, Retries exhausted
root@freenas:/mnt/data #

The USB drive is causing this.

root@wine:~ # usbconfig
ugen0.1: <Intel EHCI root HUB> at usbus0, cfg=0 md=HOST spd=HIGH (480Mbps) pwr=SAVE (0mA)
ugen1.1: <Intel EHCI root HUB> at usbus1, cfg=0 md=HOST spd=HIGH (480Mbps) pwr=SAVE (0mA)
ugen1.2: <vendor 0x8087 product 0x0024> at usbus1, cfg=0 md=HOST spd=HIGH (480Mbps) pwr=SAVE (0mA)
ugen0.2: <vendor 0x8087 product 0x0024> at usbus0, cfg=0 md=HOST spd=HIGH (480Mbps) pwr=SAVE (0mA)
ugen0.3: <SanDisk Cruzer Blade> at usbus0, cfg=0 md=HOST spd=HIGH (480Mbps) pwr=ON (224mA)

root@wine:~ # usbconfig -u 0 -a 3 dump_device_desc
ugen0.3: <SanDisk Cruzer Blade> at usbus0, cfg=0 md=HOST spd=HIGH (480Mbps) pwr=ON (224mA)

  bLength = 0x0012
  bDescriptorType = 0x0001
  bcdUSB = 0x0210
  bDeviceClass = 0x0000  <Probed by interface class>
  bDeviceSubClass = 0x0000
  bDeviceProtocol = 0x0000
  bMaxPacketSize0 = 0x0040
  idVendor = 0x0781
  idProduct = 0x5567
  bcdDevice = 0x0100
  iManufacturer = 0x0001  <SanDisk>
  iProduct = 0x0002  <Cruzer Blade>
  iSerialNumber = 0x0003  <4C531001561109121142>
  bNumConfigurations = 0x0001

Switched to a different USB stick and the problem went away.

Lesson: Not all USB sticks are created equally.

2018/05/28 14:43 · 0 Linkbacks

Older entries >>