i2p: Add helper to modify the tunnel config

We will want to set the 'interface' property of certain tunnels to 0.0.0.0 and
the handle the rest with the firewall. This is just prep to do so.

Reviewed-by: Sunil Mohan Adapa <sunil@medhas.org>
This commit is contained in:
LoveIsGrief 2019-04-05 15:47:25 +02:00 committed by Sunil Mohan Adapa
parent 0018e14cab
commit eb28f47053
No known key found for this signature in database
GPG Key ID: 43EA1CFF0AA7C5F2
4 changed files with 391 additions and 0 deletions

View File

@ -0,0 +1,119 @@
# This file is part of FreedomBox.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
import os
import re
import augeas
I2P_CONF_DIR = '/var/lib/i2p/i2p-config'
FILE_TUNNEL_CONF = os.path.join(I2P_CONF_DIR, 'i2ptunnel.config')
TUNNEL_IDX_REGEX = re.compile(r'tunnel.(\d+).name$')
class TunnelEditor(object):
"""
:type aug: augeas.Augeas
"""
def __init__(self, conf_filename=None, idx=None):
self.conf_filename = conf_filename or FILE_TUNNEL_CONF
self.idx = idx
self.aug = None
@property
def lines(self):
if self.aug:
return self.aug.match('/files{}/*'.format(self.conf_filename))
else:
return []
def read_conf(self):
"""Return an instance of Augeaus for processing APT configuration."""
self.aug = augeas.Augeas(flags=augeas.Augeas.NO_LOAD +
augeas.Augeas.NO_MODL_AUTOLOAD)
self.aug.set('/augeas/load/Properties/lens', 'Properties.lns')
self.aug.set('/augeas/load/Properties/incl[last() + 1]', self.conf_filename)
self.aug.load()
return self
def write_conf(self):
self.aug.save()
return self
def set_tunnel_idx(self, name):
"""
Finds the index of the tunnel with the given name.
Chainable method.
:type name: basestring
"""
for prop in self.aug.match('/files{}/*'.format(self.conf_filename)):
match = TUNNEL_IDX_REGEX.search(prop)
if match and self.aug.get(prop) == name:
self.idx = int(match.group(1))
return self
raise ValueError('No tunnel with that name')
def calc_prop_path(self, tunnel_prop):
"""
Calculates the property name as found in the properties files
:type tunnel_prop: str
:rtype: basestring
"""
calced_prop_path = '/files{filepath}/tunnel.{idx}.{tunnel_prop}'.format(
idx=self.idx, tunnel_prop=tunnel_prop,
filepath=self.conf_filename
)
return calced_prop_path
def set_tunnel_prop(self, tunnel_prop, value):
"""
Updates a tunnel's property.
The idx has to be set and the property has to exist in the config file and belong to the tunnel's properties.
see calc_prop_path
Chainable method.
:param tunnel_prop:
:type tunnel_prop: str
:param value:
:type value: basestring | int
:return:
:rtype:
"""
if self.idx is None:
raise ValueError('Please init the tunnel index before calling this method')
calc_prop_path = self.calc_prop_path(tunnel_prop)
self.aug.set(calc_prop_path, value)
return self
def __getitem__(self, tunnel_prop):
ret = self.aug.get(self.calc_prop_path(tunnel_prop))
if ret is None:
raise KeyError('Unknown property {}'.format(tunnel_prop))
return ret
def __setitem__(self, tunnel_prop, value):
self.aug.set(self.calc_prop_path(tunnel_prop), value)

View File

@ -0,0 +1,16 @@
# This file is part of FreedomBox.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#

View File

@ -0,0 +1,192 @@
# NOTE: This I2P config file must use UTF-8 encoding
tunnel.0.description=HTTP proxy for browsing eepsites and the web
tunnel.0.interface=127.0.0.1
tunnel.0.listenPort=4444
tunnel.0.name=I2P HTTP Proxy
tunnel.0.option.i2cp.closeIdleTime=1800000
tunnel.0.option.i2cp.closeOnIdle=false
tunnel.0.option.i2cp.delayOpen=false
tunnel.0.option.i2cp.destination.sigType=EdDSA_SHA512_Ed25519
tunnel.0.option.i2cp.newDestOnResume=false
tunnel.0.option.i2cp.reduceIdleTime=900000
tunnel.0.option.i2cp.reduceOnIdle=true
tunnel.0.option.i2cp.reduceQuantity=1
tunnel.0.option.i2p.streaming.connectDelay=1000
tunnel.0.option.i2ptunnel.httpclient.SSLOutproxies=false.i2p
tunnel.0.option.i2ptunnel.httpclient.allowInternalSSL=true
tunnel.0.option.i2ptunnel.httpclient.jumpServers=http://stats.i2p/cgi-bin/jump.cgi?a=,http://no.i2p/jump/,http://i2pjump.i2p/jump/
tunnel.0.option.i2ptunnel.httpclient.sendAccept=false
tunnel.0.option.i2ptunnel.httpclient.sendReferer=false
tunnel.0.option.i2ptunnel.httpclient.sendUserAgent=false
tunnel.0.option.i2ptunnel.useLocalOutproxy=false
tunnel.0.option.inbound.backupQuantity=0
tunnel.0.option.inbound.length=3
tunnel.0.option.inbound.lengthVariance=0
tunnel.0.option.inbound.nickname=shared clients
tunnel.0.option.inbound.quantity=2
tunnel.0.option.outbound.backupQuantity=0
tunnel.0.option.outbound.length=3
tunnel.0.option.outbound.lengthVariance=0
tunnel.0.option.outbound.nickname=shared clients
tunnel.0.option.outbound.priority=10
tunnel.0.option.outbound.quantity=2
tunnel.0.option.outproxyAuth=false
tunnel.0.option.persistentClientKey=false
tunnel.0.option.sslManuallySet=true
tunnel.0.option.useSSL=false
tunnel.0.proxyList=false.i2p
tunnel.0.sharedClient=true
tunnel.0.startOnLoad=true
tunnel.0.type=httpclient
tunnel.1.description=IRC tunnel to access the Irc2P network
tunnel.1.i2cpHost=127.0.0.1
tunnel.1.i2cpPort=7654
tunnel.1.interface=127.0.0.1
tunnel.1.listenPort=6668
tunnel.1.name=Irc2P
tunnel.1.option.crypto.lowTagThreshold=14
tunnel.1.option.crypto.tagsToSend=20
tunnel.1.option.i2cp.closeIdleTime=1200000
tunnel.1.option.i2cp.closeOnIdle=true
tunnel.1.option.i2cp.delayOpen=true
tunnel.1.option.i2cp.destination.sigType=ECDSA_SHA256_P256
tunnel.1.option.i2cp.newDestOnResume=false
tunnel.1.option.i2cp.reduceIdleTime=600000
tunnel.1.option.i2cp.reduceOnIdle=true
tunnel.1.option.i2cp.reduceQuantity=1
tunnel.1.option.i2p.streaming.connectDelay=1000
tunnel.1.option.i2p.streaming.maxWindowSize=16
tunnel.1.option.inbound.length=3
tunnel.1.option.inbound.lengthVariance=0
tunnel.1.option.inbound.nickname=Irc2P
tunnel.1.option.outbound.length=3
tunnel.1.option.outbound.lengthVariance=0
tunnel.1.option.outbound.nickname=Irc2P
tunnel.1.option.outbound.priority=15
tunnel.1.sharedClient=false
tunnel.1.startOnLoad=true
tunnel.1.targetDestination=irc.00.i2p:6667,irc.postman.i2p:6667,irc.echelon.i2p:6667
tunnel.1.type=ircclient
tunnel.2.description=I2P Monotone Server
tunnel.2.i2cpHost=127.0.0.1
tunnel.2.i2cpPort=7654
tunnel.2.interface=127.0.0.1
tunnel.2.listenPort=8998
tunnel.2.name=mtn.i2p-projekt.i2p
tunnel.2.option.i2cp.destination.sigType=EdDSA_SHA512_Ed25519
tunnel.2.option.i2cp.reduceIdleTime=900000
tunnel.2.option.i2cp.reduceOnIdle=true
tunnel.2.option.i2cp.reduceQuantity=1
tunnel.2.option.inbound.backupQuantity=0
tunnel.2.option.inbound.length=3
tunnel.2.option.inbound.lengthVariance=0
tunnel.2.option.inbound.nickname=shared clients
tunnel.2.option.inbound.quantity=2
tunnel.2.option.outbound.backupQuantity=0
tunnel.2.option.outbound.length=3
tunnel.2.option.outbound.lengthVariance=0
tunnel.2.option.outbound.nickname=shared clients
tunnel.2.option.outbound.quantity=2
tunnel.2.sharedClient=true
tunnel.2.startOnLoad=false
tunnel.2.targetDestination=mtn.i2p-projekt.i2p:4691
tunnel.2.type=client
tunnel.3.description=My eepsite
tunnel.3.i2cpHost=127.0.0.1
tunnel.3.i2cpPort=7654
tunnel.3.name=I2P webserver
tunnel.3.option.i2cp.destination.sigType=7
tunnel.3.option.i2p.streaming.limitAction=http
tunnel.3.option.i2p.streaming.maxConcurrentStreams=20
tunnel.3.option.i2p.streaming.maxConnsPerDay=100
tunnel.3.option.i2p.streaming.maxConnsPerHour=40
tunnel.3.option.i2p.streaming.maxConnsPerMinute=10
tunnel.3.option.i2p.streaming.maxTotalConnsPerMinute=25
tunnel.3.option.inbound.length=3
tunnel.3.option.inbound.lengthVariance=0
tunnel.3.option.inbound.nickname=eepsite
tunnel.3.option.maxPosts=3
tunnel.3.option.maxTotalPosts=10
tunnel.3.option.outbound.length=3
tunnel.3.option.outbound.lengthVariance=0
tunnel.3.option.outbound.nickname=eepsite
tunnel.3.option.shouldBundleReplyInfo=false
tunnel.3.privKeyFile=eepsite/eepPriv.dat
tunnel.3.spoofedHost=mysite.i2p
tunnel.3.startOnLoad=false
tunnel.3.targetHost=127.0.0.1
tunnel.3.targetPort=7658
tunnel.3.type=httpserver
tunnel.4.description=smtp server
tunnel.4.i2cpHost=127.0.0.1
tunnel.4.i2cpPort=7654
tunnel.4.interface=127.0.0.1
tunnel.4.listenPort=7659
tunnel.4.name=smtp.postman.i2p
tunnel.4.option.i2cp.destination.sigType=EdDSA_SHA512_Ed25519
tunnel.4.option.i2cp.reduceIdleTime=900000
tunnel.4.option.i2cp.reduceOnIdle=true
tunnel.4.option.i2cp.reduceQuantity=1
tunnel.4.option.inbound.backupQuantity=0
tunnel.4.option.inbound.length=3
tunnel.4.option.inbound.lengthVariance=0
tunnel.4.option.inbound.nickname=shared clients
tunnel.4.option.inbound.quantity=2
tunnel.4.option.outbound.backupQuantity=0
tunnel.4.option.outbound.length=3
tunnel.4.option.outbound.lengthVariance=0
tunnel.4.option.outbound.nickname=shared clients
tunnel.4.option.outbound.quantity=2
tunnel.4.sharedClient=true
tunnel.4.startOnLoad=true
tunnel.4.targetDestination=smtp.postman.i2p:25
tunnel.4.type=client
tunnel.5.description=pop3 server
tunnel.5.i2cpHost=127.0.0.1
tunnel.5.i2cpPort=7654
tunnel.5.interface=127.0.0.1
tunnel.5.listenPort=7660
tunnel.5.name=pop3.postman.i2p
tunnel.5.option.i2cp.destination.sigType=EdDSA_SHA512_Ed25519
tunnel.5.option.i2cp.reduceIdleTime=900000
tunnel.5.option.i2cp.reduceOnIdle=true
tunnel.5.option.i2cp.reduceQuantity=1
tunnel.5.option.i2p.streaming.connectDelay=1000
tunnel.5.option.inbound.backupQuantity=0
tunnel.5.option.inbound.length=3
tunnel.5.option.inbound.lengthVariance=0
tunnel.5.option.inbound.nickname=shared clients
tunnel.5.option.inbound.quantity=2
tunnel.5.option.outbound.backupQuantity=0
tunnel.5.option.outbound.length=3
tunnel.5.option.outbound.lengthVariance=0
tunnel.5.option.outbound.nickname=shared clients
tunnel.5.option.outbound.quantity=2
tunnel.5.sharedClient=true
tunnel.5.startOnLoad=true
tunnel.5.targetDestination=pop.postman.i2p:110
tunnel.5.type=client
tunnel.6.description=HTTPS proxy for browsing eepsites and the web
tunnel.6.i2cpHost=127.0.0.1
tunnel.6.i2cpPort=7654
tunnel.6.interface=127.0.0.1
tunnel.6.listenPort=4445
tunnel.6.name=I2P HTTPS Proxy
tunnel.6.option.i2cp.reduceIdleTime=900000
tunnel.6.option.i2cp.reduceOnIdle=true
tunnel.6.option.i2cp.reduceQuantity=1
tunnel.6.option.i2p.streaming.connectDelay=1000
tunnel.6.option.inbound.backupQuantity=0
tunnel.6.option.inbound.length=3
tunnel.6.option.inbound.lengthVariance=0
tunnel.6.option.inbound.nickname=shared clients
tunnel.6.option.inbound.quantity=2
tunnel.6.option.outbound.backupQuantity=0
tunnel.6.option.outbound.length=3
tunnel.6.option.outbound.lengthVariance=0
tunnel.6.option.outbound.nickname=shared clients
tunnel.6.option.outbound.quantity=2
tunnel.6.proxyList=outproxy-tor.meeh.i2p
tunnel.6.sharedClient=true
tunnel.6.startOnLoad=true
tunnel.6.type=connectclient

View File

@ -0,0 +1,64 @@
# This file is part of FreedomBox.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
import unittest
from pathlib import Path
from plinth.modules.i2p.helpers import TunnelEditor
DATA_DIR = Path(__file__).parent / 'data'
TUNNEL_CONF_PATH = DATA_DIR / 'i2ptunnel.config'
TUNNEL_HTTP_NAME = 'I2P HTTP Proxy'
class TunnelEditorTests(unittest.TestCase):
def setUp(self):
self.editor = TunnelEditor(str(TUNNEL_CONF_PATH))
def test_reading_conf(self):
self.editor.read_conf()
self.assertGreater(len(self.editor.lines), 1)
def test_setting_idx(self):
self.editor.read_conf()
self.assertIsNone(self.editor.idx)
self.editor.set_tunnel_idx(TUNNEL_HTTP_NAME)
self.assertEqual(self.editor.idx, 0)
def test_setting_tunnel_props(self):
self.editor.read_conf()
self.editor.set_tunnel_idx('I2P HTTP Proxy')
interface = '0.0.0.0'
self.editor.set_tunnel_prop('interface', interface)
self.assertEqual(self.editor['interface'], interface)
def test_getting_inexistent_props(self):
self.editor.read_conf()
self.editor.idx = 0
self.assertRaises(KeyError, self.editor.__getitem__, 'blabla')
def test_setting_new_props(self):
self.editor.read_conf()
self.editor.idx = 0
value = 'lol'
prop = 'blablabla'
self.editor[prop] = value
self.assertEqual(self.editor[prop], value)
if __name__ == '__main__':
unittest.main()