diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..08c41b8
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,31 @@
+sites: clean info sites/ffhh-nowe sites/ffhh-ost sites/ffhh-sued sites/ffhh-west
+
+info: config/defaults.erb template/info.erb
+	erb -T- config/defaults.erb template/$@.erb >$@
+
+.PHONY: clean
+clean:
+	rm -rf sites
+	rm -f info
+
+sites/%: config/%.erb
+	mkdir -p $@
+	cd $@ && $(MAKE) -f ../../Makefile site SITE=$(@F)
+
+site: siteclean site.mk site.conf modules i18n
+
+.PHONY: siteclean
+siteclean:
+	rm -f site.mk site.conf modules
+
+modules:
+	erb -T- ../../config/defaults.erb ../../config/$(SITE).erb ../../template/$@.erb >$@
+
+site.conf:
+	erb -T- ../../config/defaults.erb ../../config/$(SITE).erb ../../template/$@.erb >$@
+
+site.mk:
+	erb -T- ../../config/defaults.erb ../../config/$(SITE).erb ../../template/$@.erb >$@
+
+i18n:
+	ln -s ../../i18n
diff --git a/README.md b/README.md
index d9e669a..59d578f 100644
--- a/README.md
+++ b/README.md
@@ -2,11 +2,15 @@
 
 	In the next two commands replace GLUON_VERSION and SITE_VERSION with the actual version numbers.
 	$ git clone -b GLUON_VERSION https://github.com/freifunk-gluon/gluon.git
-	$ git clone -b SITE_VERSION https://git.hamburg.ccc.de/freifunk/site-ffhh.git
+	$ git clone -b SITE_VERSION https://github.com/freifunkhamburg/site-ffhh.git
 	$ cd site-ffhh
 
-	To build the firmware into the subdirectory firmware:
+	To build all domains into the subdirectory firmware:
 	$ ./build.sh -g ../gluon -o firmware
+	To build a specific domain (for example ffhh-nowe) into the subdirectory firmware:
+	$ ./build.sh -g ../gluon -l ffhh-nowe -o firmware
+	To build two specific domains (for example ffhh-nowe and ffhh-sued) into the subdirectory firmware:
+	$ ./build.sh -g ../gluon -l ffhh-nowe,ffhh-sued -o firmware
 
 	The build.sh supports the argument -b if you wish to also build firmware images marked as broken in gluon.
 
@@ -15,27 +19,7 @@ Please see [the official Gluon repository](https://github.com/freifunk-gluon/glu
 
 #### Gluon versions used for specific Hamburg Freifunk Firmware builds
 
-- v2023.2.4.0: site-ffhh: v2023.2.4.0, gluon: v2023.2.4
-- v2023.2.2.1: site-ffhh: v2023.2.2.0, gluon: v2023.2.2 (add mediatek-filogic Routers)
-- v2023.2.2.0: site-ffhh: v2023.2.2.0, gluon: v2023.2.2
-- v2023.1.2.0: site-ffhh: v2023.1.2.0, gluon: v2023.1.2
-- v2022.1.4.0: site-ffhh: v2022.1.4.0, gluon: v2022.1.4
-- v2022.1.3.0: site-ffhh: v2022.1.3.0, gluon: v2022.1.3 (nur experimental verteilt)
-- v2021.1.2.0: site-ffhh: v2021.1.2.0, gluon: v2021.1.2
-- v2021.1.1.0: site-ffhh: v2021.1.1.0, gluon: v2021.1.1
-- v2020.2.3.0: site-ffhh: v2020.2.3.0, gluon: v2020.2.3
-- v2020.2.2.0: site-ffhh: v2020.2.2.0, gluon: v2020.2.2
-- v2020.1.4.0: site-ffhh: v2020.1.4.0, gluon: v2020.1.4
-- v2020.1.3.0: site-ffhh: v2020.1.3.0, gluon: v2020.1.3
-- v2019.1.2.0: site-ffhh: v2019.1.2.0, gluon: v2019.1.2
-- v2018.2.3.0: site-ffhh: v2018.2.3.0, gluon: v2018.2.3
-- v2018.2.1.0: site-ffhh: v2018.2.1.0, gluon: v2018.2.1
-- v2018.1.4.2: site-ffhh: v2018.1.4.2, gluon: v2018.1.4
-- v2018.1.4.1: site-ffhh: v2018.1.4.1, gluon: v2018.1.4
-- v2018.1.4.0: site-ffhh: v2018.1.4.0, gluon: v2018.1.4
-- v2018.1.3.0: site-ffhh: v2018.1.3.0, gluon: v2018.1.3
-- v2018.1.1.0: site-ffhh: v2018.1.1.0, gluon: v2018.1.1
-- v2018.1.0.0: site-ffhh: v2018.1.0.0, gluon: v2018.1 (never rolled out due to issues with the auto updater in gluon)
+- v2018.1.0.0: site-ffhh: v2018.1.0.0, gluon: v2018.1
 - 0.9.2: site-ffhh: v0.9.2, gluon: v2017.1.8
 - 0.9.1: site-ffhh: v0.9.1, gluon: v2017.1.5
 - 0.9.0: site-ffhh: 60f30382209ffc050baa82be9bad3622a1d88d5b, gluon: v2017.1.x (9295abcea7b016b0fe4b05c534ea0731b48ef593) (never rolled out due to 0.9.1)
diff --git a/build.conf b/build.conf
deleted file mode 100644
index 07358e1..0000000
--- a/build.conf
+++ /dev/null
@@ -1,5 +0,0 @@
-GLUON_RELEASE="v2023.2.4.0"
-targets="ath79-generic ath79-nand ath79-mikrotik bcm27xx-bcm2708 bcm27xx-bcm2709 ipq40xx-generic ipq40xx-mikrotik ipq806x-generic lantiq-xrx200 lantiq-xway mediatek-filogic mediatek-mt7622 mpc85xx-p1010 mpc85xx-p1020 ramips-mt7620 ramips-mt7621 ramips-mt76x8 rockchip-armv8 sunxi-cortexa7 x86-generic x86-geode x86-legacy x86-64"
-broken_images=(
-	'*dir*615*d*'
-)
diff --git a/build.sh b/build.sh
index 5647ba5..2f8f21a 100755
--- a/build.sh
+++ b/build.sh
@@ -2,17 +2,17 @@
 set -e
 
 function announce () {
-	echo '############################' "$@" >&2
+	echo '############################' $* >&2
 }
 function usage () {
 	echo "Usage: $0 -g GLUON_PATH" >&2
 	echo "       -g GLUON_PATH   Path to a checkout of the gluon repository." >&2
-	echo "       -t TARGETS      Comma separated list of gluon targets to build" >&2
-	echo "       -a              Automatically detect and build all targets." >&2
+	echo "       -l SITES        Comma separated list of sites to build" >&2
 	echo "       -o OUT_PATH     Path to the firmware output directory. Default: ${gluon_out}" >&2
 	echo "       -s SIGNATURE    Sign firmware with signature" >&2
-	echo "       -stable         Set GLUON_AUTOUPDATER_BRANCH=stable" >&2
+	echo "       -u UPLOADSCRIPT Run UPLOADSCRIPT after building. Will be run with one argument: $gluon_out/<GLUON_RELEASE>" >&2
 	echo "       -b              BROKEN=1" >&2
+	echo "       -m              Do not regenerate the sites" >&2
 	echo "       -v              verbose" >&2
 	echo "       -j JOBS         Run build with -jJOBS. Default: ${proc}" >&2
 }
@@ -22,15 +22,12 @@ gluon_out="${HOME}/firmware"
 
 while [ $# -gt 0 ]; do
 	case "$1" in
-		-a)
-			auto_targets=1
-			;;
 		-g)
 			gluon_path="$2"
 			shift
 			;;
-		-t)
-			build_targets="$2"
+		-l)
+			sites="$2"
 			shift
 			;;
 		-o)
@@ -41,12 +38,16 @@ while [ $# -gt 0 ]; do
 			signature="$2"
 			shift
 			;;
-		-stable)
-			export GLUON_AUTOUPDATER_BRANCH=stable
+		-u)
+			uploadscript="$2"
+			shift
 			;;
 		-b)
 			export BROKEN=1
 			;;
+		-m)
+			dont_make_sites=1
+			;;
 		-j)
 			proc="$2"
 			shift
@@ -55,7 +56,6 @@ while [ $# -gt 0 ]; do
 			verbose=V=s
 			;;
 		*)
-			echo ERROR: Failed to parse: "${1}" >&2
 			usage
 			exit 1
 			;;
@@ -68,71 +68,67 @@ if [ -z "$gluon_path" ]; then
 	exit 1
 fi
 
-gluon_path=$(realpath "$gluon_path")
-gluon_out=$(realpath "$gluon_out")
-site_path=$(realpath "$(dirname "${BASH_SOURCE[0]}")")
+gluon_path=$(realpath $gluon_path)
+gluon_out=$(realpath $gluon_out)
+site_path=$(realpath $(dirname $BASH_SOURCE))
 
-announce GLUON: "$gluon_path" >&2
-announce FFHH SITE PATH: "$site_path" >&2
+announce GLUON: $gluon_path >&2
+announce FFHH SITE PATH: $site_path >&2
 
-pushd "$site_path"
-# shellcheck source=/dev/null
-. ./build.conf
-GLUON_AUTOUPDATER_BRANCH="${GLUON_AUTOUPDATER_BRANCH:-experimental}"
-[ "${GLUON_AUTOUPDATER_BRANCH}" = "experimental" ] && GLUON_RELEASE="${GLUON_RELEASE}~exp${BUILD_DATE:-$(date +%Y%m%d)}"
+pushd $site_path
+if [ "$dont_make_sites" == "" ]; then
+	# Build the site repo and generate all site configs
+	announce Building site repo and reading data >&2
+	make
+fi
+. ./info
 export GLUON_RELEASE
-export GLUON_AUTOUPDATER_BRANCH
-export GLUON_SITEDIR="${site_path}"
-export GLUON_OUTPUTDIR="${gluon_out}/${GLUON_RELEASE}/${GLUON_AUTOUPDATER_BRANCH}"
+export GLUON_BRANCH
+# get the available sites...
+sites="$(echo "$sites" | sed -e 's_,_ _g')"
+if [ "$sites" == "" ]; then
+	for s in sites/*; do sites="${sites} ${s##*/}"; done
+fi
+announce Gluon will be built for the following sites:$sites >&2
+announce The following targets will be generated: $targets >&2
 popd
 
-announce GLUON Variables:
-env | egrep '^GLUON' | sort
-
 pushd "${gluon_path}"
 announce Starting make update...
-mkdir -p "${GLUON_OUTPUTDIR}"
-make update
-# Try to install patches. I wasn't able to figure out how patches in gluon/site/patches work.
-for p in "${site_path}"/patches/*.patch; do
-	if [ -e "$p" ] && [ ! -f "${gluon_path}/${p##*/}" ]; then
-		announce "Installing patch $p"
-		patch -p1 < "$p"
-		touch "${gluon_path}/${p##*/}"
+for s in $sites; do
+	export GLUON_SITEDIR="${site_path}/sites/${s}"
+	export GLUON_OUTPUTDIR="${gluon_out}/${GLUON_RELEASE}/${GLUON_BRANCH}/${s}"
+	rm -rf "${GLUON_OUTPUTDIR}"
+	mkdir -p "${GLUON_OUTPUTDIR}"
+	make update
+	# Try to install patches. I wasn't able to figure out how patches in gluon/site/patches work.
+	for p in ${site_path}/patches/*.patch; do
+		if [ -e "$p" -a ! -f "${gluon_path}/${p##*/}" ]; then
+			announce Installing patch $p
+			patch -p1 < $p
+			touch "${gluon_path}/${p##*/}"
+		fi
+	done
+	for t in $targets; do
+		announce make clean for $s/$t... >&2
+		make -j1 clean GLUON_TARGET=$t
+		announce Starting build for $s/$t... >&2
+		make -j$(nproc) GLUON_TARGET=$t $verbose
+	done
+	announce Building manifest...
+	make manifest
+	if [ -n "${signature}" ]; then
+		if [ "$GLUON_BRANCH" == "experimental" ]; then
+			announce Signing
+			"${gluon_path}/contrib/sign.sh" "${signature}" "${GLUON_OUTPUTDIR}/images/sysupgrade/experimental.manifest"
+		else
+			echo ERROR: can only sign experimental branch >&2
+			exit 1
+		fi
 	fi
 done
-
-if [ "$auto_targets" = "1" ]; then
-	# detect available targets
-	targets="$(make list-targets | sort | xargs)"
-else
-	# if a list of build targets has been supplied, only build those
-	targets="$(echo "${build_targets:-$targets}" | sed -e 's_,_ _g')"
-fi
-announce "The following targets will be generated: $targets" >&2
-
-for t in $targets; do
-	announce "Starting build for $t..." >&2
-	make "-j$(nproc)" "GLUON_TARGET=$t" $verbose
-done
-# Remove known-broken images
-# shellcheck disable=SC2154
-for broken_image in "${broken_images[@]}"; do
-	announce "Removing broken image ${broken_image}..."
-	find "${GLUON_OUTPUTDIR}/images" -iname "${broken_image}" \( -type f -o -type l \) -ls -exec rm -f {} \;
-done
-# Generate the images.list
-# shellcheck disable=SC2094
-( cd "${GLUON_OUTPUTDIR}/images" && ( echo "RELEASE=${GLUON_RELEASE}"; find . -type f ! -iname '*.manifest' ! -iname images.list; find . -type l ! -iname '*.manifest' ) | sed -e 's!^\./\(.*\)$!\1!' -e 's!/! !g' | sort > images.list )
-announce Building manifest...
-make manifest
-if [ -n "${signature}" ]; then
-	if [ "$GLUON_AUTOUPDATER_BRANCH" == "experimental" ]; then
-		announce Signing...
-		"${gluon_path}/contrib/sign.sh" "${signature}" "${GLUON_OUTPUTDIR}/images/sysupgrade/experimental.manifest"
-	else
-		echo ERROR: can only sign experimental branch >&2
-		exit 1
-	fi
-fi
 popd
+if [ -n "$uploadscript" ]; then
+		announce Starting upload. Executing: $uploadscript $gluon_out/$GLUON_RELEASE
+		"$uploadscript" "$gluon_out/$GLUON_RELEASE"
+fi
diff --git a/config/defaults.erb b/config/defaults.erb
new file mode 100644
index 0000000..686dc26
--- /dev/null
+++ b/config/defaults.erb
@@ -0,0 +1,75 @@
+<%
+gluon_branch = "stable"
+#gluon_branch = "experimental"
+gluon_release = "v2018.1.0.0"
+
+# Add the +exp and current date if this is an experimental release
+gluon_release += "~exp" + Time.new.strftime("%Y%m%d") if gluon_branch == "experimental"
+
+gluon_targets = %w(
+	ar71xx-generic
+	ar71xx-tiny
+	ar71xx-nand
+	brcm2708-bcm2708
+	brcm2708-bcm2709
+	mpc85xx-generic
+	ramips-mt7621
+	x86-generic
+	x86-geode
+	x86-64
+)
+
+# Add more targets if broken images are included...
+if ENV["BROKEN"]
+	gluon_targets += %w(
+		ar71xx-mikrotik
+		brcm2708-bcm2710
+		ipq806x
+		mvebu
+		ramips-mt7620
+		ramips-mt7628
+		ramips-rt305x
+		sunxi
+	)
+end
+gluon_targets.sort!.uniq!
+
+gluon_site_packages = %w(
+	gluon-autoupdater
+	gluon-config-mode-autoupdater
+	gluon-config-mode-core
+	gluon-config-mode-hostname
+	gluon-config-mode-mesh-vpn
+	gluon-ebtables-filter-multicast
+	gluon-ebtables-filter-ra-dhcp
+	gluon-ebtables-source-filter
+	gluon-mesh-batman-adv-15
+	gluon-mesh-vpn-fastd
+	gluon-radvd
+	gluon-respondd
+	gluon-setup-mode
+	gluon-status-page
+	gluon-web-admin
+	gluon-web-autoupdater
+	gluon-web-network
+	gluon-web-private-wifi
+	gluon-web-wifi-config
+	haveged
+	iptables
+	iwinfo
+)
+
+signing_keys = [
+		'ef73bc52b929fd11efce9a5c8f0b5463f1766bb995c8a0b3b6bcd7ba45b8b1e6', # leo
+		'3f0fc50d4e5c893f9f58f98874bd21080b93c28ff5e4d4946352cada1b4e6441', # andre
+		'1d37eacbd70f72730b1f5aba246a6a8eab100e2d45dda0163d9ad827f70f88d4', # gernot
+		'bd5a70d4c3df30eaa860d615c0e0526b0dda5bc60c09c20972bce4ffa7512659', # bjoern
+		'd9992853c0fe1a2e983cc222b6bd26e70d4fb2a53862ac099144e9e8142238d0', # daniel
+		'961495a04512e5ba1843fd3c216d8af6ef2fdb19f93055142803e2da26d670b9', # alexander
+		'ed6278f168f0382adf4f058cb9c31d8f1145abb968a8626045de7d6d87a0be40', # olli
+]
+signing_keys_experimental = [
+		'1a0112fe489860068480c611c5dc56196c2f1a645db651ea2ed19ae0f0e8e1d1', # 1.builder
+]
+
+-%>
diff --git a/config/ffhh-nowe.erb b/config/ffhh-nowe.erb
new file mode 100644
index 0000000..92b157d
--- /dev/null
+++ b/config/ffhh-nowe.erb
@@ -0,0 +1,41 @@
+<%
+site_name = 'Freifunk Hamburg Nordwest'
+site_code = 'ffhh-nowe'
+
+gluon_site_packages += %w( )
+
+prefix4 = '10.112.192.0/19'
+prefix6 = '2a03:2267:3::/64'
+
+next_node_ipv4 = '10.112.192.1'
+next_node_ipv6 = '2a03:2267:3::1'
+
+mtu = 1312
+
+gateways = {
+	"gateway01" => {
+		"key" => "aa88fb5cc3e729c124589e3714b817a505d809f381d9b3494040c382edfd4f3b",
+		"remotes" => [ '"gw01-new.hamburg.freifunk.net" port 10007' ]
+	},
+	"gateway02" => {
+		"key" => "462b4e21ab5eb0f9de687efd97252880c895ba55cc9cc0755a75347b0965b6e0",
+		"remotes" => [ '"gw02-new.hamburg.freifunk.net" port 10007' ]
+	},
+	"gateway03" => {
+		"key" => "e15295b86138ac490d611e4100f847ccfb7052d5091ded4659f25940be2c0546",
+		"remotes" => [ '"gw03-new.hamburg.freifunk.net" port 10007' ]
+	},
+	"gateway04" => {
+		"key" => "a00e092c236c3b56043fb3b5d0b3da3da08d8325fb18e7bae6ed035d50d50669",
+		"remotes" => [ '"gw04-new.hamburg.freifunk.net" port 10008' ]
+	},
+	"gateway05" => {
+		"key" => "291197d88a5ed510a62fec87f30d13315c1e031c62c927c23e1643a72796708f",
+		"remotes" => [ '"gw05-new.hamburg.freifunk.net" port 10008' ]
+	},
+	"gateway06" => {
+		"key" => "8d400e8a9db05b145c36583d46b4170f6b66d1e16177540f8a2f9f5ad0dc4c43",
+		"remotes" => [ '"gw06-new.hamburg.freifunk.net" port 10008' ]
+	},
+}
+-%>
diff --git a/config/ffhh-ost.erb b/config/ffhh-ost.erb
new file mode 100644
index 0000000..1cb7b72
--- /dev/null
+++ b/config/ffhh-ost.erb
@@ -0,0 +1,41 @@
+<%
+site_name = 'Freifunk Hamburg Ost'
+site_code = 'ffhh-ost'
+
+gluon_site_packages += %w( )
+
+prefix4 = '10.112.224.0/19'
+prefix6 = '2a03:2267:4::/64'
+
+next_node_ipv4 = '10.112.224.1'
+next_node_ipv6 = '2a03:2267:4::1'
+
+mtu = 1312
+
+gateways = {
+	"gateway01" => {
+		"key" => "aa88fb5cc3e729c124589e3714b817a505d809f381d9b3494040c382edfd4f3b",
+		"remotes" => [ '"gw01-new.hamburg.freifunk.net" port 10009' ]
+	},
+	"gateway02" => {
+		"key" => "462b4e21ab5eb0f9de687efd97252880c895ba55cc9cc0755a75347b0965b6e0",
+		"remotes" => [ '"gw02-new.hamburg.freifunk.net" port 10009' ]
+	},
+	"gateway03" => {
+		"key" => "e15295b86138ac490d611e4100f847ccfb7052d5091ded4659f25940be2c0546",
+		"remotes" => [ '"gw03-new.hamburg.freifunk.net" port 10009' ]
+	},
+	"gateway04" => {
+		"key" => "a00e092c236c3b56043fb3b5d0b3da3da08d8325fb18e7bae6ed035d50d50669",
+		"remotes" => [ '"gw04-new.hamburg.freifunk.net" port 10010' ]
+	},
+	"gateway05" => {
+		"key" => "291197d88a5ed510a62fec87f30d13315c1e031c62c927c23e1643a72796708f",
+		"remotes" => [ '"gw05-new.hamburg.freifunk.net" port 10010' ]
+	},
+	"gateway06" => {
+		"key" => "8d400e8a9db05b145c36583d46b4170f6b66d1e16177540f8a2f9f5ad0dc4c43",
+		"remotes" => [ '"gw06-new.hamburg.freifunk.net" port 10010' ]
+	},
+}
+-%>
diff --git a/config/ffhh-sued.erb b/config/ffhh-sued.erb
new file mode 100644
index 0000000..b970c9c
--- /dev/null
+++ b/config/ffhh-sued.erb
@@ -0,0 +1,41 @@
+<%
+site_name = 'Freifunk Hamburg Sued'
+site_code = 'ffhh-sued'
+
+gluon_site_packages += %w( )
+
+prefix4 = '10.112.64.0/19'
+prefix6 = '2a03:2267:1::/64'
+
+next_node_ipv4 = '10.112.64.1'
+next_node_ipv6 = '2a03:2267:1::1'
+
+mtu = 1312
+
+gateways = {
+	"gateway01" => {
+		"key" => "aa88fb5cc3e729c124589e3714b817a505d809f381d9b3494040c382edfd4f3b",
+		"remotes" => [ '"gw01-new.hamburg.freifunk.net" port 10003' ]
+	},
+	"gateway02" => {
+		"key" => "462b4e21ab5eb0f9de687efd97252880c895ba55cc9cc0755a75347b0965b6e0",
+		"remotes" => [ '"gw02-new.hamburg.freifunk.net" port 10003' ]
+	},
+	"gateway03" => {
+		"key" => "e15295b86138ac490d611e4100f847ccfb7052d5091ded4659f25940be2c0546",
+		"remotes" => [ '"gw03-new.hamburg.freifunk.net" port 10003' ]
+	},
+	"gateway04" => {
+		"key" => "fca88dd58316f4ab50d2a697123dddf4d0ba3aad52ddeb0ba7835cdbbeb60dbf",
+		"remotes" => [ '"gw04-new.hamburg.freifunk.net" port 10004' ]
+	},
+	"gateway05" => {
+		"key" => "84986658775167dff6918dc8e0529c4a4524cb1782849a80933ddb6d8c6bd3f5",
+		"remotes" => [ '"gw05-new.hamburg.freifunk.net" port 10004' ]
+	},
+	"gateway06" => {
+		"key" => "fb608aa75180ba88b4a3399a6498e68796d200afc1bfd275a0dcb903a31f39b6",
+		"remotes" => [ '"gw06-new.hamburg.freifunk.net" port 10004' ]
+	},
+}
+-%>
diff --git a/config/ffhh-west.erb b/config/ffhh-west.erb
new file mode 100644
index 0000000..b9775de
--- /dev/null
+++ b/config/ffhh-west.erb
@@ -0,0 +1,41 @@
+<%
+site_name = 'Freifunk Hamburg West'
+site_code = 'ffhh-west'
+
+gluon_site_packages += %w( )
+
+prefix4 = '10.112.96.0/19'
+prefix6 = '2a03:2267:2::/64'
+
+next_node_ipv4 = '10.112.96.1'
+next_node_ipv6 = '2a03:2267:2::1'
+
+mtu = 1312
+
+gateways = {
+	"gateway01" => {
+		"key" => "aa88fb5cc3e729c124589e3714b817a505d809f381d9b3494040c382edfd4f3b",
+		"remotes" => [ '"gw01-new.hamburg.freifunk.net" port 10005' ]
+	},
+	"gateway02" => {
+		"key" => "462b4e21ab5eb0f9de687efd97252880c895ba55cc9cc0755a75347b0965b6e0",
+		"remotes" => [ '"gw02-new.hamburg.freifunk.net" port 10005' ]
+	},
+	"gateway03" => {
+		"key" => "e15295b86138ac490d611e4100f847ccfb7052d5091ded4659f25940be2c0546",
+		"remotes" => [ '"gw03-new.hamburg.freifunk.net" port 10005' ]
+	},
+	"gateway04" => {
+		"key" => "a00e092c236c3b56043fb3b5d0b3da3da08d8325fb18e7bae6ed035d50d50669",
+		"remotes" => [ '"gw04-new.hamburg.freifunk.net" port 10006' ]
+	},
+	"gateway05" => {
+		"key" => "291197d88a5ed510a62fec87f30d13315c1e031c62c927c23e1643a72796708f",
+		"remotes" => [ '"gw05-new.hamburg.freifunk.net" port 10006' ]
+	},
+	"gateway06" => {
+		"key" => "8d400e8a9db05b145c36583d46b4170f6b66d1e16177540f8a2f9f5ad0dc4c43",
+		"remotes" => [ '"gw06-new.hamburg.freifunk.net" port 10006' ]
+	},
+}
+-%>
diff --git a/domains/ffhh_nowe.conf b/domains/ffhh_nowe.conf
deleted file mode 100644
index 4ecba48..0000000
--- a/domains/ffhh_nowe.conf
+++ /dev/null
@@ -1,75 +0,0 @@
-{
-	domain_names = {
-		ffhh_nowe = "Hamburg Nordwest",
-	},
-	domain_seed = '666668682D6E6F776548616D6275726748616D6275726748616D627572674861',
-
-	prefix4 = '10.112.192.0/19',
-	prefix6 = '2a03:2267:3::/64',
-
-	next_node = {
-		ip4 = '10.112.192.1',
-		ip6 = '2a03:2267:3::1',
-		mac = '16:41:95:40:f7:dc',
-	},
-
-	wifi24 = {
-		ap = {
-			ssid = "hamburg.freifunk.net",
-		},
-		mesh = {
-			id = '6668682D6E6F7765',
-		},
-	},
-
-	wifi5 = {
-		ap = {
-			ssid = "hamburg.freifunk.net",
-		},
-		mesh = {
-			id = '6668682D6E6F7765',
-		},
-	},
-
-	mesh = {
-		vxlan = false,
-		batman_adv = {
-			routing_algo = "BATMAN_IV",
-		},
-	},
-
-	mesh_vpn = {
-		fastd = {
-			groups = {
-				backbone = {
-					peers = {
-						gateway01 = {
-							remotes = { '"gw01-new.hamburg.freifunk.net" port 10007' },
-							key = 'aa88fb5cc3e729c124589e3714b817a505d809f381d9b3494040c382edfd4f3b',
-						},
-						gateway02 = {
-							remotes = { '"gw02-new.hamburg.freifunk.net" port 10007' },
-							key = '462b4e21ab5eb0f9de687efd97252880c895ba55cc9cc0755a75347b0965b6e0',
-						},
-						gateway03 = {
-							remotes = { '"gw03-new.hamburg.freifunk.net" port 10007' },
-							key = 'e15295b86138ac490d611e4100f847ccfb7052d5091ded4659f25940be2c0546',
-						},
-						gateway04 = {
-							remotes = { '"gw04-new.hamburg.freifunk.net" port 10008' },
-							key = 'a00e092c236c3b56043fb3b5d0b3da3da08d8325fb18e7bae6ed035d50d50669',
-						},
-						gateway05 = {
-							remotes = { '"gw05-new.hamburg.freifunk.net" port 10008' },
-							key = '291197d88a5ed510a62fec87f30d13315c1e031c62c927c23e1643a72796708f',
-						},
-						gateway06 = {
-							remotes = { '"gw06-new.hamburg.freifunk.net" port 10008' },
-							key = '8d400e8a9db05b145c36583d46b4170f6b66d1e16177540f8a2f9f5ad0dc4c43',
-						},
-					},
-				},
-			},
-		},
-	},
-}
diff --git a/domains/ffhh_ost.conf b/domains/ffhh_ost.conf
deleted file mode 100644
index 941b75d..0000000
--- a/domains/ffhh_ost.conf
+++ /dev/null
@@ -1,75 +0,0 @@
-{
-	domain_names = {
-		ffhh_ost  = "Hamburg Ost",
-	},
-	domain_seed = '666668682D6F737448616D6275726748616D6275726748616D6275726748616D',
-
-	prefix4 = '10.112.224.0/19',
-	prefix6 = '2a03:2267:4::/64',
-
-	next_node = {
-		ip4 = '10.112.224.1',
-		ip6 = '2a03:2267:4::1',
-		mac = '16:41:95:40:f7:dc',
-	},
-
-	wifi24 = {
-		ap = {
-			ssid = "hamburg.freifunk.net",
-		},
-		mesh = {
-			id = '666668682D6F7374',
-		},
-	},
-
-	wifi5 = {
-		ap = {
-			ssid = "hamburg.freifunk.net",
-		},
-		mesh = {
-			id = '666668682D6F7374',
-		},
-	},
-
-	mesh = {
-		vxlan = false,
-		batman_adv = {
-			routing_algo = "BATMAN_IV",
-		},
-	},
-
-	mesh_vpn = {
-		fastd = {
-			groups = {
-				backbone = {
-					peers = {
-						gateway01 = {
-							remotes = { '"gw01-new.hamburg.freifunk.net" port 10009' },
-							key = 'aa88fb5cc3e729c124589e3714b817a505d809f381d9b3494040c382edfd4f3b',
-						},
-						gateway02 = {
-							remotes = { '"gw02-new.hamburg.freifunk.net" port 10009' },
-							key = '462b4e21ab5eb0f9de687efd97252880c895ba55cc9cc0755a75347b0965b6e0',
-						},
-						gateway03 = {
-							remotes = { '"gw03-new.hamburg.freifunk.net" port 10009' },
-							key = 'e15295b86138ac490d611e4100f847ccfb7052d5091ded4659f25940be2c0546',
-						},
-						gateway04 = {
-							remotes = { '"gw04-new.hamburg.freifunk.net" port 10010' },
-							key = 'a00e092c236c3b56043fb3b5d0b3da3da08d8325fb18e7bae6ed035d50d50669',
-						},
-						gateway05 = {
-							remotes = { '"gw05-new.hamburg.freifunk.net" port 10010' },
-							key = '291197d88a5ed510a62fec87f30d13315c1e031c62c927c23e1643a72796708f',
-						},
-						gateway06 = {
-							key = '8d400e8a9db05b145c36583d46b4170f6b66d1e16177540f8a2f9f5ad0dc4c43',
-							remotes = { '"gw06-new.hamburg.freifunk.net" port 10010' },
-						},
-					},
-				},
-			},
-		},
-	},
-}
diff --git a/domains/ffhh_sued.conf b/domains/ffhh_sued.conf
deleted file mode 100644
index 1a6f31f..0000000
--- a/domains/ffhh_sued.conf
+++ /dev/null
@@ -1,75 +0,0 @@
-{
-	domain_names = {
-		ffhh_sued = "Hamburg Süd",
-	},
-	domain_seed = '666668682D7375656448616D6275726748616D6275726748616D627572674861',
-
-	prefix4 = '10.112.64.0/19',
-	prefix6 = '2a03:2267:1::/64',
-
-	next_node = {
-		ip4 = '10.112.64.1',
-		ip6 = '2a03:2267:1::1',
-		mac = '16:41:95:40:f7:dc',
-	},
-
-	wifi24 = {
-		ap = {
-			ssid = "hamburg.freifunk.net",
-		},
-		mesh = {
-			id = '6668682D73756564',
-		},
-	},
-
-	wifi5 = {
-		ap = {
-			ssid = "hamburg.freifunk.net",
-		},
-		mesh = {
-			id = '6668682D73756564',
-		},
-	},
-
-	mesh = {
-		vxlan = false,
-		batman_adv = {
-			routing_algo = "BATMAN_IV",
-		},
-	},
-
-	mesh_vpn = {
-		fastd = {
-			groups = {
-				backbone = {
-					peers = {
-						gateway01 = {
-							remotes = { '"gw01-new.hamburg.freifunk.net" port 10003' },
-							key = 'aa88fb5cc3e729c124589e3714b817a505d809f381d9b3494040c382edfd4f3b',
-						},
-						gateway02 = {
-							key = '462b4e21ab5eb0f9de687efd97252880c895ba55cc9cc0755a75347b0965b6e0',
-							remotes = { '"gw02-new.hamburg.freifunk.net" port 10003' },
-						},
-						gateway03 = {
-							remotes = { '"gw03-new.hamburg.freifunk.net" port 10003' },
-							key = 'e15295b86138ac490d611e4100f847ccfb7052d5091ded4659f25940be2c0546',
-						},
-						gateway04 = {
-							remotes = { '"gw04-new.hamburg.freifunk.net" port 10004' },
-							key = 'a00e092c236c3b56043fb3b5d0b3da3da08d8325fb18e7bae6ed035d50d50669',
-						},
-						gateway05 = {
-							remotes = { '"gw05-new.hamburg.freifunk.net" port 10004' },
-							key = '291197d88a5ed510a62fec87f30d13315c1e031c62c927c23e1643a72796708f',
-						},
-						gateway06 = {
-							remotes = { '"gw06-new.hamburg.freifunk.net" port 10004' },
-							key = '8d400e8a9db05b145c36583d46b4170f6b66d1e16177540f8a2f9f5ad0dc4c43',
-						},
-					},
-				},
-			},
-		},
-	},
-}
diff --git a/domains/ffhh_west.conf b/domains/ffhh_west.conf
deleted file mode 100644
index ca3c22a..0000000
--- a/domains/ffhh_west.conf
+++ /dev/null
@@ -1,75 +0,0 @@
-{
-	domain_names = {
-		ffhh_west = "Hamburg West",
-	},
-	domain_seed = '666668682D7765737448616D6275726748616D6275726748616D627572674861',
-
-	prefix4 = '10.112.96.0/19',
-	prefix6 = '2a03:2267:2::/64',
-
-	next_node = {
-		ip4 = '10.112.96.1',
-		ip6 = '2a03:2267:2::1',
-		mac = '16:41:95:40:f7:dc',
-	},
-
-	wifi24 = {
-		ap = {
-			ssid = "hamburg.freifunk.net",
-		},
-		mesh = {
-			id = '6668682D77657374',
-		},
-	},
-
-	wifi5 = {
-		ap = {
-			ssid = "hamburg.freifunk.net",
-		},
-		mesh = {
-			id = '6668682D77657374',
-		},
-	},
-
-	mesh = {
-		vxlan = false,
-		batman_adv = {
-			routing_algo = "BATMAN_IV",
-		},
-	},
-
-	mesh_vpn = {
-		fastd = {
-			groups = {
-				backbone = {
-					peers = {
-						gateway01 = {
-							remotes = { '"gw01-new.hamburg.freifunk.net" port 10005' },
-							key = 'aa88fb5cc3e729c124589e3714b817a505d809f381d9b3494040c382edfd4f3b',
-						},
-						gateway02 = {
-							key = '462b4e21ab5eb0f9de687efd97252880c895ba55cc9cc0755a75347b0965b6e0',
-							remotes = { '"gw02-new.hamburg.freifunk.net" port 10005' },
-						},
-						gateway03 = {
-							remotes = { '"gw03-new.hamburg.freifunk.net" port 10005' },
-							key = 'e15295b86138ac490d611e4100f847ccfb7052d5091ded4659f25940be2c0546',
-						},
-						gateway04 = {
-							remotes = { '"gw04-new.hamburg.freifunk.net" port 10006' },
-							key = 'a00e092c236c3b56043fb3b5d0b3da3da08d8325fb18e7bae6ed035d50d50669',
-						},
-						gateway05 = {
-							remotes = { '"gw05-new.hamburg.freifunk.net" port 10006' },
-							key = '291197d88a5ed510a62fec87f30d13315c1e031c62c927c23e1643a72796708f',
-						},
-						gateway06 = {
-							remotes = { '"gw06-new.hamburg.freifunk.net" port 10006' },
-							key = '8d400e8a9db05b145c36583d46b4170f6b66d1e16177540f8a2f9f5ad0dc4c43',
-						},
-					},
-				},
-			},
-		},
-	},
-}
diff --git a/i18n/de.po b/i18n/de.po
index 58dfb28..9119cd8 100644
--- a/i18n/de.po
+++ b/i18n/de.po
@@ -16,14 +16,6 @@ msgstr ""
 "Freifunk-Knoten. Fülle das folgende Formular deinen Vorstellungen "
 "entsprechend aus und sende es ab. "
 "Den unten anzugebenden Knotennamen kannst du beliebig wählen. Denke Dir also etwas schönes aus. Er ist der Name des Knotens im Netzwerk und hat nichts mit dem ausgestrahlten Netzwerknamen (SSID) zu tun. Letzterer ist immer hamburg.freifunk.net."
- 
-msgid "gluon-config-mode:domain"
-msgstr "Domäne" 
-
-msgid "gluon-config-mode:domain-select"
-msgstr ""
-"Hier kannst du Domäne auswählen, in dem sich dein Knoten befindet. "
-"Bitte bedenke, dass sich dein Knoten nur mit Routern in der gleichen Domäne verbinden kann."
 
 msgid "gluon-config-mode:pubkey"
 msgstr ""
diff --git a/i18n/en.po b/i18n/en.po
index f64501f..124cfba 100644
--- a/i18n/en.po
+++ b/i18n/en.po
@@ -19,15 +19,6 @@ msgstr ""
 "the network and has nothing to do with the broadcast network name (SSID). "
 "The latter is always hamburg.freifunk.net."
 
-msgid "gluon-config-mode:domain"
-msgstr "Domain" 
-
-msgid "gluon-config-mode:domain-select"
-msgstr ""
-"Here you have the possibility of selecting the mesh domain in which your node "
-"is placed. Please keep in mind that your router only connects with the nodes "
-"of the selected domain"
-
 msgid "gluon-config-mode:pubkey"
 msgstr ""
 "<p>This is the public key for your Freifunk node. You can only "
diff --git a/image-customization.lua b/image-customization.lua
deleted file mode 100644
index 79abeed..0000000
--- a/image-customization.lua
+++ /dev/null
@@ -1,36 +0,0 @@
-features({
-    'autoupdater',
-    'config-mode-domain-select',
-    'ebtables-filter-multicast',
-    'ebtables-filter-ra-dhcp',
-    'mesh-batman-adv-15',
-    'mesh-vpn-fastd',
-    'web-private-wifi',
-    'radv-filterd',
-    'respondd',
-    'status-page',
-    'web-advanced',
-    'web-wizard',
-})
-
-if not device_class('tiny') then
-    features({
-        'wireless-encryption-wpa3',
-    })
-end
-
-packages({
-    '-gluon-config-mode-geo-location',
-    '-gluon-config-mode-contact-info',
-    'gluon-ebtables-source-filter',
-    'gluon-web-mesh-vpn-fastd',
-    'iwinfo',
-})
-
-if target('x86') then
-    packages({
-        'nano',
-        'htop',
-        'ethtool',
-    })
-end
diff --git a/site.conf b/site.conf
deleted file mode 100644
index 04919a0..0000000
--- a/site.conf
+++ /dev/null
@@ -1,102 +0,0 @@
-{
-	hostname_prefix = 'GibMirEinenNamen',
-	config_mode = {
-		hostname = {
-			optional = false,
-			prefill = false,
-		},
-	},
-
-	site_name = 'Freifunk Hamburg',
-	site_code = 'ffhh',
-	default_domain = 'ffhh_nowe',
-
-	opkg = {
-		extra = {
-			modules = 'http://updates.hamburg.freifunk.net/multi/archive/%GR/packages/gluon-%GS-%GR/%S',
-		},
-	},
-
-	timezone = 'CET-1CEST,M3.5.0,M10.5.0/3', -- Europe/Berlin
-	ntp_servers = {'1.ntp.services.ffhh','2.ntp.services.ffhh','3.ntp.services.ffhh'},
-	regdom = 'DE',
-
-	wifi24 = {
-		channel = 1,
-
-		mesh = {
-			mcast_rate = 12000,
-		},
-	},
-
-	wifi5 = {
-		channel = 44,
-		outdoor_chanlist = "100-140",
-		mesh = {
-			mcast_rate = 12000,
-		},
-	},
-
-	mesh_vpn = {
-		enabled = true,
-		fastd = {
-			configurable = true,
-			mtu = 1312,
-			methods = {'salsa2012+umac'},
-			groups = {
-				backbone = {
-					limit = 1,
-				},
-			},
-		},
-		bandwidth_limit = {
-			enabled = false,
-			ingress = 8096,
-			egress = 1024,
-		},
-	},
-
-	autoupdater = {
-		branch = 'stable',
-		branches = {
-			stable = {
-				name = 'stable',
-				mirrors = {'http://updates-a.hamburg.freifunk.net/multi/stable/images/sysupgrade','http://updates-b.hamburg.freifunk.net/multi/stable/images/sysupgrade'},
-				good_signatures = 2,
-				pubkeys = {
-					'ef73bc52b929fd11efce9a5c8f0b5463f1766bb995c8a0b3b6bcd7ba45b8b1e6', -- leo
-					'3f0fc50d4e5c893f9f58f98874bd21080b93c28ff5e4d4946352cada1b4e6441', -- andre
-					'1d37eacbd70f72730b1f5aba246a6a8eab100e2d45dda0163d9ad827f70f88d4', -- gernot
-					'bd5a70d4c3df30eaa860d615c0e0526b0dda5bc60c09c20972bce4ffa7512659', -- bjoern
-					'd9992853c0fe1a2e983cc222b6bd26e70d4fb2a53862ac099144e9e8142238d0', -- daniel
-					'961495a04512e5ba1843fd3c216d8af6ef2fdb19f93055142803e2da26d670b9', -- alexander
-					'ed6278f168f0382adf4f058cb9c31d8f1145abb968a8626045de7d6d87a0be40', -- olli
-				},
-			},
-			beta = {
-				name = 'beta',
-				mirrors = {'http://updates-a.hamburg.freifunk.net/multi/stable/images/sysupgrade','http://updates-b.hamburg.freifunk.net/multi/stable/images/sysupgrade'},
-				good_signatures = 2,
-				pubkeys = {
-					'ef73bc52b929fd11efce9a5c8f0b5463f1766bb995c8a0b3b6bcd7ba45b8b1e6', -- leo
-					'3f0fc50d4e5c893f9f58f98874bd21080b93c28ff5e4d4946352cada1b4e6441', -- andre
-					'1d37eacbd70f72730b1f5aba246a6a8eab100e2d45dda0163d9ad827f70f88d4', -- gernot
-					'bd5a70d4c3df30eaa860d615c0e0526b0dda5bc60c09c20972bce4ffa7512659', -- bjoern
-					'd9992853c0fe1a2e983cc222b6bd26e70d4fb2a53862ac099144e9e8142238d0', -- daniel
-					'961495a04512e5ba1843fd3c216d8af6ef2fdb19f93055142803e2da26d670b9', -- alexander
-					'ed6278f168f0382adf4f058cb9c31d8f1145abb968a8626045de7d6d87a0be40', -- olli
-				},
-			},
-			experimental = {
-				name = 'experimental',
-				mirrors = {'http://updates-a.hamburg.freifunk.net/multi/experimental/images/sysupgrade','http://updates-b.hamburg.freifunk.net/multi/experimental/images/sysupgrade'},
-				good_signatures = 1,
-				pubkeys = {
-					'1a0112fe489860068480c611c5dc56196c2f1a645db651ea2ed19ae0f0e8e1d1', -- builder1/2
-				},
-			},
-		},
-	},
-
-	poe_passthrough = false,
-}
diff --git a/site.mk b/site.mk
deleted file mode 100644
index 45aa428..0000000
--- a/site.mk
+++ /dev/null
@@ -1,11 +0,0 @@
-GLUON_MULTIDOMAIN := 1
-GLUON_DEPRECATED := upgrade
-
-GLUON_AUTOUPDATER_ENABLED ?= 1
-
-GLUON_PRIORITY ?= 7
-
-# Region code required for some images; supported values: us eu
-GLUON_REGION ?= eu
-
-GLUON_LANGS ?= en de
diff --git a/template/info.erb b/template/info.erb
new file mode 100644
index 0000000..685d4a9
--- /dev/null
+++ b/template/info.erb
@@ -0,0 +1,3 @@
+GLUON_RELEASE="<%= gluon_release %>"
+GLUON_BRANCH="<%= gluon_branch %>"
+targets="<%= gluon_targets.join(" ") %>"
diff --git a/modules b/template/modules.erb
similarity index 56%
rename from modules
rename to template/modules.erb
index d1b67ac..6416262 100644
--- a/modules
+++ b/template/modules.erb
@@ -1,5 +1,5 @@
 GLUON_SITE_FEEDS='ffhh_packages'
 
-PACKAGES_FFHH_PACKAGES_REPO=https://github.com/freifunkhamburg/ffhh-packages.git
+PACKAGES_FFHH_PACKAGES_REPO=git://github.com/freifunkhamburg/ffhh-packages.git
 PACKAGES_FFHH_PACKAGES_COMMIT=ef9fcc1222f74c3c045b1450537a4b8b80efb56c
 
diff --git a/template/site.conf.erb b/template/site.conf.erb
new file mode 100644
index 0000000..a2a83f6
--- /dev/null
+++ b/template/site.conf.erb
@@ -0,0 +1,122 @@
+{
+	hostname_prefix = 'GibMirEinenNamen',
+	site_name = '<%= site_name %>',
+	site_code = '<%= site_code %>',
+	domain_seed = '<%= (site_code + ("Hamburg" * 7))[0..31].each_byte.map { |b| b.to_s(16) }.join.upcase %>',
+
+	opkg = {
+		lede = 'http://lede.opkg.services.ffhh/snapshots/packages/%A',
+		extra = {
+			modules = 'http://updates.hamburg.freifunk.net/%GS/stable/archive/modules/gluon-%GS-%GR/%S',
+		},
+	},
+
+	prefix4 = '<%= prefix4 %>',
+	prefix6 = '<%= prefix6 %>',
+
+	timezone = 'CET-1CEST,M3.5.0,M10.5.0/3', -- Europe/Berlin
+	ntp_servers = {'1.ntp.services.ffhh','2.ntp.services.ffhh','3.ntp.services.ffhh'},
+	regdom = 'DE',
+
+	mesh = {
+		vxlan = false,
+	},
+
+	wifi24 = {
+		channel = 1,
+
+		supported_rates = {6000, 9000, 12000, 18000, 24000, 36000, 48000, 54000},
+		basic_rate = {6000, 9000, 18000, 36000, 54000},
+
+		ap = {
+			ssid = 'hamburg.freifunk.net',
+		},
+		mesh = {
+			id = '<%= ("00000000" + site_code)[-8..-1].each_byte.map { |b| b.to_s(16) }.join.upcase %>',
+			mcast_rate = 12000,
+		},
+	},
+
+	wifi5 = {
+		channel = 44,
+		ap = {
+			ssid = 'hamburg.freifunk.net',
+		},
+		mesh = {
+			id = '<%= ("00000000" + site_code)[-8..-1].each_byte.map { |b| b.to_s(16) }.join.upcase %>',
+			mcast_rate = 12000,
+		},
+	},
+
+	next_node = {
+		ip4 = '<%= next_node_ipv4 %>',
+		ip6 = '<%= next_node_ipv6 %>',
+
+		mac = '16:41:95:40:f7:dc',
+	},
+
+	mesh_vpn = {
+		enabled = true,
+		mtu = <%= mtu %>,
+		fastd = {
+			configurable = true,
+			methods = {'salsa2012+umac'},
+			groups = {
+				backbone = {
+					limit = 1,
+					peers = {
+<% gateways.each_pair do | name, gw_data | -%>
+						<%= name %> = {
+							key = '<%= gw_data['key'] %>',
+							remotes = { '<%= gw_data['remotes'].join("', '") %>' },
+						},
+<% end -%>
+					},
+				},
+			},
+			},
+		bandwidth_limit = {
+			enabled = false,
+			ingress = 8096,
+			egress = 1024,
+		},
+	},
+
+	autoupdater = {
+		branch = '<%= gluon_branch %>',
+		branches = {
+			stable = {
+				name = 'stable',
+				mirrors = {'http://1.updates.services.ffhh/<%= site_code %>/stable/sysupgrade','http://2.updates.services.ffhh/<%= site_code %>/stable/sysupgrade'},
+				good_signatures = 2,
+				pubkeys = {
+<% signing_keys.each do | key | -%>
+					'<%= key %>',
+<% end -%>
+				},
+			},
+			beta = {
+				name = 'beta',
+				mirrors = {'http://1.updates.services.ffhh/<%= site_code %>/beta/sysupgrade','http://2.updates.services.ffhh/<%= site_code %>/beta/sysupgrade'},
+				good_signatures = 2,
+				pubkeys = {
+<% signing_keys.each do | key | -%>
+					'<%= key %>',
+<% end -%>
+				},
+			},
+			experimental = {
+				name = 'experimental',
+				mirrors = {'http://1.updates.services.ffhh/<%= site_code %>/experimental/sysupgrade','http://2.updates.services.ffhh/<%= site_code %>/experimental/sysupgrade'},
+				good_signatures = 1,
+				pubkeys = {
+<% signing_keys_experimental.each do | key | -%>
+					'<%= key %>',
+<% end -%>
+				},
+			},
+		},
+	},
+
+	poe_passthrough = false,
+}
diff --git a/template/site.mk.erb b/template/site.mk.erb
new file mode 100644
index 0000000..b5fa761
--- /dev/null
+++ b/template/site.mk.erb
@@ -0,0 +1,38 @@
+GLUON_SITE_PACKAGES :=<% gluon_site_packages.each do | p | -%>
+<%= " " + p -%>
+<% end -%>
+
+
+# EXTRA_SOFTWARE_TOOLS_01
+EXTRA_SOFTWARE_TOOLS_01 := \
+        nano \
+        htop \
+        ethtool
+
+# x86
+ifeq ($(GLUON_TARGET),x86-generic)
+GLUON_SITE_PACKAGES += \
+    $(EXTRA_SOFTWARE_TOOLS_01)
+endif
+
+# x86-64
+ifeq ($(GLUON_TARGET),x86-64)
+GLUON_SITE_PACKAGES += \
+    $(EXTRA_SOFTWARE_TOOLS_01)
+endif
+
+
+
+DEFAULT_GLUON_RELEASE := <%= gluon_release %>
+
+# Allow overriding the release number from the command line
+GLUON_RELEASE ?= $(DEFAULT_GLUON_RELEASE)
+
+GLUON_PRIORITY ?= 0
+
+# Region code required for some images; supported values: us eu
+GLUON_REGION ?= eu
+
+GLUON_ATH10K_MESH ?= 11s
+
+GLUON_LANGS ?= en de