Skip to content

Commit

Permalink
Merge pull request #142 from SmithChart/ffbs-parker-nodeconfig
Browse files Browse the repository at this point in the history
Add ffbs-mesh-vpn-parker
  • Loading branch information
SmithChart authored Feb 9, 2025
2 parents 37e175e + 4f321ed commit 375fa1c
Show file tree
Hide file tree
Showing 33 changed files with 1,179 additions and 0 deletions.
26 changes: 26 additions & 0 deletions ffbs-mesh-vpn-parker/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
include $(TOPDIR)/rules.mk

PKG_NAME:=ffbs-mesh-vpn-parker
PKG_VERSION:=1

PKG_MAINTAINER:=Chris Fiege <[email protected]>
PKG_LICENSE:=MIT

PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)

include $(TOPDIR)/../package/gluon.mk

define Package/ffbs-mesh-vpn-parker
TITLE:=Automatic node configuration for parker networks
DEPENDS:=+gluon-core +libgluonutil +gluon-mesh-vpn-core +kmod-wireguard +wireguard-tools +luaposix +usign +gluon-radv-filterd +gluon-ebtables-filter-ra-dhcp +ffbs-parker-nextnode +ffbs-parker-respondd
PROVIDES:=ffbs-parker-nodeconfig
endef

define Package/ffbs-mesh-vpn-parker/description
This package is the central component for parker-based network.
It downloads a configuration for a node.
It keeps track of the node's connectivity and changes the state as needed.
endef

$(eval $(call BuildPackageGluon,ffbs-mesh-vpn-parker))

36 changes: 36 additions & 0 deletions ffbs-mesh-vpn-parker/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
ffbs-mesh-vpn-parker
======================

This is the core package of [gluon-parker](https://github.com/ffbs/gluon-parker),
a Gluon fork that uses routing between the nodes
(aka. Router devices) and the infrastructure.
It is currently in use at Freifunk Braunschweig.
Other communities are interested in adopting it as well.

This package installs the `nodeconfig` and `noderoute` services together
with a set of new firewall-rules.

The core services are:

* **Nodeconfig**:
This service downloads and validates a node configuration from
the concentrators and applies it.
* **Noderoute**:
The service automatically chooses a default route from the available
Wireshark concentrator connections.

They have their corresponding services in `/etc/init.d/` and are usually quite verbose
in `logread`.
This package also takes care of generating the WireGuard Keypair for the node.

site.conf
---------

This package relies on the following parameters in your `site.conf`:

```json
parker = {
config_server = "config.yourcommunity.net",
config_pubkey = "<Your usign config signing pubkey>",
},
```
4 changes: 4 additions & 0 deletions ffbs-mesh-vpn-parker/check_site.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
need_string({ "parker", "config_server" })
need_string({ "parker", "config_pubkey" })
need_string_array({'ntp_servers'})
need_number({ "mesh_vpn", "parker", "mtu" })
3 changes: 3 additions & 0 deletions ffbs-mesh-vpn-parker/files/etc/config/parker
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@

config nodeconfig 'nodeconfig'
option config_server 'config.community.example'
21 changes: 21 additions & 0 deletions ffbs-mesh-vpn-parker/files/etc/init.d/nodeconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/bin/sh /etc/rc.common
# SC2034,SC2154: /etc/rc.common imports this script and uses variables defined here
# shellcheck disable=SC2034,SC2154
# shellcheck shell="busybox sh"

START=99

USE_PROCD=1
PROG='/usr/bin/gluon-wan /usr/sbin/nodeconfig.sh'

start_service() {
sleep 30
logger -t nodeconfig:init.d Starting Service
procd_open_instance
procd_set_param command "$PROG"
procd_set_param respawn
procd_set_param stderr 0
#procd_set_param limits core="unlimited" #TODO set ulimit
procd_set_param pidfile /var/run/nodeconfig.pid
procd_close_instance
}
20 changes: 20 additions & 0 deletions ffbs-mesh-vpn-parker/files/etc/init.d/noderoute
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/bin/sh /etc/rc.common
# SC2034,SC2154: /etc/rc.common imports this script and uses variables defined here
# shellcheck disable=SC2034,SC2154
# shellcheck shell="busybox sh"

START=99

USE_PROCD=1

start_service() {
sleep 30
logger -t noderoute:init.d Starting Service
procd_open_instance
procd_set_param command /usr/sbin/noderoute.sh
procd_set_param respawn
procd_set_param stderr 0
#procd_set_param stdout 1
procd_set_param pidfile /var/run/noderoute.pid
procd_close_instance
}
2 changes: 2 additions & 0 deletions ffbs-mesh-vpn-parker/files/etc/sysctl.d/40-parker.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# override setting from 31-gluon-mesh-batman-adv.conf
net.ipv6.conf.br-client.forwarding=1
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
chain('PARKER_RADV', 'RETURN')
rule 'FORWARD -p IPv6 -i bat0 --ip6-protocol ipv6-icmp --ip6-icmp-type router-advertisement -j PARKER_RADV'
Empty file.
Empty file.
Empty file.
36 changes: 36 additions & 0 deletions ffbs-mesh-vpn-parker/files/lib/gluon/upgrade/111-network-parker
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#!/usr/bin/lua

local uci = require('simple-uci').cursor()

uci:section('network', 'rule', 'wan_lookup', {
mark = '0x01/0x01',
lookup = 1,
})
uci:section('network', 'route', 'wan_unreachable', {
type = 'unreachable',
interface = 'loopback',
target = '0.0.0.0',
netmask = '0',
table = 1,
metric = 65535,
})

uci:section('network', 'route', 'client_unreachable', {
type = 'unreachable',
interface = 'loopback',
target = '0.0.0.0',
netmask = '0',
metric = 65535,
})
uci:section('network', 'route6', 'client6_unreachable', {
type = 'unreachable',
interface = 'loopback',
target = '::/0',
gateway = '::',
metric = 65535,
})

-- place ipv4 wan routes into table 1
uci:set('network', 'wan', 'ip4table', 1)

uci:save('network')
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/usr/bin/lua

local uci = require('simple-uci').cursor()

-- The mesh_respondd_siteprefix and mesh_respondd_extraprefix[0-9]+ rules
-- do not make sense in the context of parker as there are no prefix4
-- and prefix6 attributes anymore.
uci:delete('firewall', 'rule', 'mesh_respondd_siteprefix')
uci:delete_all('firewall', 'rule', function(rule)
return rule['.name']:find('^mesh_respondd_extraprefix')
end)

uci:save('firewall')
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/bin/sh

# create an interface to allow the node to
# get a ipv6 address on br-client

uci set network.client6=interface
uci set network.client6.ifname='br-client'
uci set network.client6.proto='dhcpv6'
uci set network.client6.sourcefilter='0'
uci set network.client6.peerdns='0'
uci set network.client6.reqprefix='no'

# allow client to get an ipv4 address by default
uci set network.client.proto='dhcp'

uci commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/sh
uci del_list dhcp.@dnsmasq[0].notinterface='wg_c*'
uci add_list dhcp.@dnsmasq[0].notinterface='wg_c*'
uci commit dhcp
101 changes: 101 additions & 0 deletions ffbs-mesh-vpn-parker/files/lib/gluon/upgrade/904-parker-firewall
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
#!/bin/sh

# this script adds rules needed for parker to the
# gluon firewall-setup.

# allow dhcpv4 on br-client
uci set firewall.mesh_dhcpv4_parker='rule'
uci set firewall.mesh_dhcpv4_parker.dest_port=67
uci set firewall.mesh_dhcpv4_parker.src='mesh'
uci set firewall.mesh_dhcpv4_parker.target='ACCEPT'
uci set firewall.mesh_dhcpv4_parker.proto='udp'
uci set firewall.mesh_dhcpv4_parker.family='ipv4'

# allow dns on br-client
uci set firewall.mesh_dns_parker='rule'
uci set firewall.mesh_dns_parker.dest_port=53
uci set firewall.mesh_dns_parker.src='mesh'
uci set firewall.mesh_dns_parker.target='ACCEPT'
uci set firewall.mesh_dns_parker.proto='tcpudp'

# allow ICMPv4 on br-client
uci set firewall.mesh_ICMPv4_parker='rule'
uci set firewall.mesh_ICMPv4_parker.icmp_type='echo-request'
uci set firewall.mesh_ICMPv4_parker.src='mesh'
uci set firewall.mesh_ICMPv4_parker.family='ipv4'
uci set firewall.mesh_ICMPv4_parker.target='ACCEPT'
uci set firewall.mesh_ICMPv4_parker.proto='icmp'

# allow ICMPv4 on vpn_parker
uci set firewall.vpn_parker_ICMPv4_parker='rule'
uci set firewall.vpn_parker_ICMPv4_parker.icmp_type='echo-request'
uci set firewall.vpn_parker_ICMPv4_parker.src='vpn_parker'
uci set firewall.vpn_parker_ICMPv4_parker.family='ipv4'
uci set firewall.vpn_parker_ICMPv4_parker.target='ACCEPT'
uci set firewall.vpn_parker_ICMPv4_parker.proto='icmp'

# add a zone for all the wc_c+ -interfaces
uci set firewall.vpn_parker='zone'
uci set firewall.vpn_parker.device='wg_c+'
uci set firewall.vpn_parker.input='REJECT'
uci set firewall.vpn_parker.output='ACCEPT'
uci set firewall.vpn_parker.forward='REJECT'
uci set firewall.vpn_parker.name='vpn_parker'
uci set firewall.vpn_parker.mtu_fix='1'

# allow forwarding between br-client and wg_c+ -interfaces
uci set firewall.mesh_vpn_parker='forwarding'
uci set firewall.mesh_vpn_parker.src='mesh'
uci set firewall.mesh_vpn_parker.dest='vpn_parker'

uci set firewall.vpn_parker_mesh='forwarding'
uci set firewall.vpn_parker_mesh.src='vpn_parker'
uci set firewall.vpn_parker_mesh.dest='mesh'

# allow respondd to be reached from mesh and vpn_parker
uci set firewall.respondd_mesh_parker=rule
uci set firewall.respondd_mesh_parker.dest_port='1001'
uci set firewall.respondd_mesh_parker.name='respondd_mesh_parker'
uci set firewall.respondd_mesh_parker.target='ACCEPT'
uci set firewall.respondd_mesh_parker.proto='udp'
uci set firewall.respondd_mesh_parker.src='mesh'

uci set firewall.respondd_vpn_parker_mesh=rule
uci set firewall.respondd_vpn_parker_mesh.dest_port='1001'
uci set firewall.respondd_vpn_parker_mesh.name='respondd_vpn_parker_mesh'
uci set firewall.respondd_vpn_parker_mesh.target='ACCEPT'
uci set firewall.respondd_vpn_parker_mesh.proto='udp'
uci set firewall.respondd_vpn_parker_mesh.src='vpn_parker'

# allow ICMPv6 from vpn_parker
uci set firewall.vpn_parker_ICMPv6_in_parker=rule
uci set firewall.vpn_parker_ICMPv6_in_parker.icmp_type='echo-request'
uci set firewall.vpn_parker_ICMPv6_in_parker.src='vpn_parker'
uci set firewall.vpn_parker_ICMPv6_in_parker.limit='1000/sec'
uci set firewall.vpn_parker_ICMPv6_in_parker.family='ipv6'
uci set firewall.vpn_parker_ICMPv6_in_parker.target='ACCEPT'
uci set firewall.vpn_parker_ICMPv6_in_parker.proto='icmp'

# allow SSH via tunnel
uci set firewall.vpn_parker_ssh=rule
uci set firewall.vpn_parker_ssh.dest_port='22'
uci set firewall.vpn_parker_ssh.src='vpn_parker'
uci set firewall.vpn_parker_ssh.name='vpn_parker_ssh'
uci set firewall.vpn_parker_ssh.target='ACCEPT'
uci set firewall.vpn_parker_ssh.proto='tcp'

# allow HTTP via tunnel
uci set firewall.vpn_parker_http=rule
uci set firewall.vpn_parker_http.dest_port='80'
uci set firewall.vpn_parker_http.src='vpn_parker'
uci set firewall.vpn_parker_http.name='vpn_parker_ssh'
uci set firewall.vpn_parker_http.target='ACCEPT'
uci set firewall.vpn_parker_http.proto='tcp'

# skip wan table rules created by netifd with prio 20000
uci set network.wan_skip=rule
uci set network.wan_skip.priority=15000
uci set network.wan_skip.lookup=main
uci set network.wan6_skip=rule6
uci set network.wan6_skip.priority=15000
uci set network.wan6_skip.lookup=main
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/bin/sh

uci set firewall.@defaults[0].input='ACCEPT'
uci set firewall.@defaults[0].output='ACCEPT'
uci set firewall.@defaults[0].forward='ACCEPT'
uci set firewall.@zone[0].input='ACCEPT'
uci set firewall.@zone[0].output='ACCEPT'
uci set firewall.@zone[0].forward='ACCEPT'
uci set firewall.@zone[1].input='REJECT'
uci set firewall.@zone[1].output='ACCEPT'
uci set firewall.@zone[1].forward='ACCEPT'
uci set firewall.loc_client.input='ACCEPT'
uci set firewall.loc_client.forward='ACCEPT'
uci set firewall.loc_client.output='ACCEPT'

uci commit firewall
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/etc/parker/wg-*
39 changes: 39 additions & 0 deletions ffbs-mesh-vpn-parker/files/usr/bin/status
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#!/bin/sh
# shellcheck shell="busybox sh"

tmpdir=/tmp/ff-Ohb0ba0u/

brief_interface() {
# shellcheck disable=SC2046
echo $(ip a show dev "$1" | grep state | awk '{print $9}') $(ip a show dev "$1" | grep inet | awk '{ print $2}')
}

echo -n 'gluon model: '; cat /tmp/sysinfo/model
echo -n 'gluon release: '; cat /lib/gluon/release
echo -n 'uname: '; uname -a
echo -n 'autoupdater: '
if [ "$(uci get autoupdater.settings.enabled)" = "1" ]; then echo "enabled ($(uci get autoupdater.settings.branch))"; else echo "disabled"; fi
echo -n 'uptime: '; uptime
echo -n 'available memory: '; awk '( $1 == "MemAvailable:" ) { printf("%.1f MiB\n", $2/1024) }' /proc/meminfo
echo -n 'available flash: '; df -h / | awk '( $6 == "/" ) { print $4 " " $5 }'

if ip a | grep -q "br-setup"; then

echo 'Node in setup mode'

else

echo -n 'batman gateway mode: '; batctl gw_mode
echo -n 'batman neighbours: '; batctl n -H | wc -l
echo -n 'uplink status: '; brief_interface 'br-wan'
echo -n 'mesh status: '; brief_interface 'br-client'
echo -n 'nodeconfig: '; cat /tmp/nodeconfig-report; echo
echo -n 'vpn status: '; if uci show gluon.mesh_vpn.enabled | grep -q '1' ; then echo enabled; else echo disabled; fi
echo 'dhcp clients:'
awk '{ printf(" %-32s %s %-16s %ds left\n", $4, $2, $3, $1-systime()) }' /tmp/dhcp.leases | sort
echo 'wireguard handshakes:'
wg show all latest-handshakes | awk '{ printf(" %-8s %8ds ago\n", $1, systime()-$3) }'
if [ ! -e ${tmpdir}/nodeconfig-successful ]; then echo !!! nodeconfig-serice did not yet run. Give the node some more time to start up.; fi
if [ ! -e ${tmpdir}/noderoute-successful ]; then echo !!! noderoute-serice did not yet run. Give the node some more time to start up.; fi
fi

Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/bin/sh

# shellcheck source=/dev/null
. /lib/gluon/autoupdater/lib.sh

start_enabled nodeconfig
start_enabled noderoute
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/bin/sh

# shellcheck source=/dev/null
. /lib/gluon/autoupdater/lib.sh

stop nodeconfig
stop noderoute
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/sh

# shellcheck source=/dev/null
. /lib/gluon/autoupdater/lib.sh

stop log
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/sh

# shellcheck source=/dev/null
. /lib/gluon/autoupdater/lib.sh

ip link del dev wg_c1
ip link del dev wg_c2
ip link del dev wg_c3
1 change: 1 addition & 0 deletions ffbs-mesh-vpn-parker/files/usr/lib/micron.d/drop_caches
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0 3 * * * /usr/sbin/drop_caches.sh
6 changes: 6 additions & 0 deletions ffbs-mesh-vpn-parker/files/usr/sbin/drop_caches.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/sh

LOGGER="logger -s -t drop_caches.sh"
$LOGGER Dropping caches.

echo 3 > /proc/sys/vm/drop_caches
Loading

0 comments on commit 375fa1c

Please sign in to comment.