1 ## @defgroup on-service-relay Dienst-Weiterleitungen 2 # Beginn der Doku-Gruppe 5 ## für die Kompatibilität mit Firmware vor v0.5 6 ## falls mehr als ein GW-Dienst weitergereicht wird, wird dieser Port und die folgenden verwendet 7 SERVICE_RELAY_LOCAL_RELAY_PORT_START=5100
10 # Pruefung ob ein lokaler Port bereits fuer einen ugw-Dienst weitergeleitet wird 11 _is_local_service_relay_port_unused() {
15 [ -n
"$collisions" ] && trap
"" EXIT &&
return 1
16 # keine Kollision entdeckt
21 # Liefere den Port zurueck, der einer Dienst-Weiterleitung lokal zugewiesen wurde.
22 # Falls noch kein Port definiert ist, dann waehle einen neuen Port.
23 # Parameter: config_name
24 pick_local_service_relay_port() {
25 trap
'error_trap pick_local_service_relay_port "$*"' EXIT
26 local service_name=
"$1" 29 # falls unbelegt: suche einen unbenutzten lokalen Port
30 if [ -z
"$port" ]; then
31 port=
"$SERVICE_RELAY_LOCAL_RELAY_PORT_START" 32 until _is_local_service_relay_port_unused
"$port";
do 41 ## @fn update_relay_firewall_rules 42 ## @brief Erstelle die Liste aller Firewall-Regeln fuer Service-Relay-Weiterleitungen neu. 43 ## @details Diese Funktion wird als Teil des Firewall-Reload-Prozess und nach Service-Relay-Aenderungen 45 update_relay_firewall_rules() {
46 trap
'error_trap update_relay_firewall_rules "$*"' EXIT
52 local dnat_chain=
"on_service_relay_dnat" 53 local parent_dnat_chain=
"prerouting_${ZONE_MESH}_rule" 54 local tos_chain=
"on_service_relay_tos" 55 local parent_tos_chain=
"PREROUTING" 57 main_ip=$(get_main_ip)
58 # calculate the entries
for the
new rules
59 # We need to
do this in advance - otherwise it could happen, that DNS problems could cause
60 # invalid (i.e. missing) firewall rules. Only
if at least one valid rule is calculated,
61 # the rules are updated. 62 new_rules=$(
for service in $(
get_services | filter_relay_services);
do 63 is_service_relay_possible
"$service" ||
continue 69 # skip entries in
case of broken DNS resolution
70 [ -z
"$target_ip" ] &&
continue 71 echo
"$host $port $protocol $local_port $target_ip" 73 # do not apply changes, if there are no valid rules 74 [ -z
"$new_rules" ] &&
return 0
75 # neue Chains erzeugen 76 iptables -t nat --
new-chain
"$dnat_chain" 2>/dev/
null || iptables -t nat --flush
"$dnat_chain" 77 iptables -t
mangle --
new-chain
"$tos_chain" 2>/dev/
null || iptables -t
mangle --flush
"$tos_chain" 78 # Verweis auf die neue Chain erzeugen 79 iptables -t nat --check
"$parent_dnat_chain" -j
"$dnat_chain" 2>/dev/
null \
80 || iptables -t nat --insert
"$parent_dnat_chain" -j
"$dnat_chain" 81 iptables -t
mangle --check
"$parent_tos_chain" -j
"$tos_chain" 2>/dev/
null \
82 || iptables -t
mangle --insert
"$parent_tos_chain" -j
"$tos_chain" 83 # DNAT- und TOS-Chain fuellen 84 echo
"$new_rules" |
while read -r host port protocol local_port target_ip;
do 85 iptables -t nat -A
"$dnat_chain" --destination
"$main_ip" --protocol
"$protocol" --dport
"$local_port" \
86 -j DNAT --to-destination
"${target_ip}:${port}" 87 # falls on-openvpn vorhanden ist, wollen wir vermeiden, dass mesh-Tunnel ueber den Internet-Tunnel laufen 88 [ -z
"${TOS_NON_TUNNEL:-}" ] || iptables -t
mangle -A
"$tos_chain" --destination
"$main_ip" \
89 --protocol
"$protocol" --dport
"$local_port" -j TOS --
set-tos
"$TOS_NON_TUNNEL" 91 # Connection-Tracking-Tabelle flushen 92 # Sonst werden Aenderungen fuer bestehende Verbindungen nicht wirksam. 93 echo f >/proc/net/nf_conntrack
97 _get_service_relay_olsr_announcement_prefix() {
98 trap
'error_trap _get_service_relay_olsr_announcement_prefix "$*"' EXIT
99 local service_name=
"$1" 106 main_ip=$(get_main_ip)
109 service_type=
"${service_type#$RELAYABLE_SERVICE_PREFIX}" 112 port=$(pick_local_service_relay_port
"$service_name")
114 # announce the service 115 echo
"${scheme}://${main_ip}:${port}|${protocol}|${service_type}" 119 ## @fn get_service_relay_olsr_announcement() 120 ## @brief Ermittle den oder die OLSR-Nameservice-Announcements, die zu dem Dienst gehoeren. 121 get_service_relay_olsr_announcement() {
122 trap
'error_trap get_service_relay_olsr_announcement "$*"' EXIT
123 local service_name=
"$1" 124 local announce_unique
126 announce_unique=$(_get_service_relay_olsr_announcement_prefix
"$service_name")
127 uci_prefix=$(get_and_enable_olsrd_library_uci_prefix
"nameservice")
128 uci_get_list "${uci_prefix}.service" | awk
'{ if ($1 == "'"$announce_unique"'") print $0; }' 132 ## @fn announce_olsr_service_relay() 133 ## @brief Verkuende das lokale Relay eines öffentlichen Dienstes inkl. Geschwindigkeitsdaten via olsr nameservice. 134 ## @param service_name Name des zu veröffentlichenden Diensts 135 ## @attention Anschließend muss die uci-Sektion 'olsrd' committed werden. 136 announce_olsr_service_relay() {
137 trap
'error_trap announce_olsr_service_relay "$*"' EXIT
138 local service_name=
"$1" 140 local service_details
141 service_unique=$(_get_service_relay_olsr_announcement_prefix
"$service_name")
142 # das
'service_name'-Detail wird fuer die anschliessende Beraeumung (firewall-Regeln usw.) verwendet
143 # nur nicht-leere Attribute werden geschrieben 144 service_details=$(
while read -r
key value;
do [ -z
"$value" ] &&
continue; echo
"$key:$value";
done <<EOF
151 # Zeilenumbrueche durch Leerzeichen ersetzen, abschliessendes Leerzeichen entfernen
152 service_details=$(echo
"$service_details" | tr
'\n' ' ' | sed
's/ $//')
153 # loesche alte Dienst-Announcements mit demselben Prefix 157 uci_prefix=$(get_and_enable_olsrd_library_uci_prefix
"nameservice")
158 # shellcheck disable=SC2034
159 get_service_relay_olsr_announcement
"$service_name" |
while read -r this_unique this_details;
do 160 # der Wert ist bereits korrekt - wir koennen abbrechen 161 [
"$this_details" =
"$service_details" ] &&
break 162 # der Wert ist falsch: loeschen und am Ende neu hinzufuegen 163 msg_debug "Deleting outdated service-relay announcement: $service_unique $this_details" 164 uci_delete_list "${uci_prefix}.service" "$service_unique $this_details" 166 # falls keine Treffer gibt, fuegen wir ein neues Announcement hinzu 167 if [ -z
"$(get_service_relay_olsr_announcement "$service_name
")" ]; then
168 msg_debug "Adding new service-relay announcement: $service_unique $service_details" 169 uci_add_list "${uci_prefix}.service" "$service_unique $service_details" 174 ## @fn get_olsr_relay_service_name_from_description() 175 ## @brief Ermittle den Dienstnamen, der zu einer olsr-Relay-Service-Definition gehoert. 176 get_olsr_relay_service_name_from_description() {
177 trap
'error_trap get_olsr_relay_service_name_from_description "$*"' EXIT
178 local service_description=
"$1" 182 fields=$(echo
"$service_description" | parse_olsr_service_descriptions)
183 port=$(echo
"$fields" | cut -f 4)
184 service_type=$(echo
"$fields" | cut -f 1)
189 # olsr-Nameservice-Beschreibungen entfernen falls der dazugehoerige Dienst nicht mehr relay-tauglich ist
190 deannounce_unused_olsr_service_relays() {
191 # wir erwarten einen ausführbaren Testnamen 192 local test_for_activity=
"$1" 193 local service_description
196 uci_prefix=$(get_and_enable_olsrd_library_uci_prefix
"nameservice")
197 uci_get_list "${uci_prefix}.service" |
while read -r service_description;
do 198 # unbenutzte Eintraege entfernen 199 service_name=$(get_olsr_relay_service_name_from_description
"$service_description")
200 # falls es den Dienst noch gibt: ist er immer noch aktiv?
201 [ -n
"$service_name" ] &&
"$test_for_activity" "$service_name" &&
continue 208 ## @fn is_service_relay_possible()
209 ## @brief Pruefe ob ein Relay-Dienst aktiviert (nicht "disabled") ist und ob das WAN-Routing korrekt ist. 210 is_service_relay_possible() {
211 trap
'error_trap is_service_relay_possible "$*"' EXIT
212 local service_name=
"$1" 216 uci_is_true
"$disabled" && trap
"" EXIT &&
return 1
218 uci_is_false
"$wan_routing" && trap
"" EXIT &&
return 1
223 ## @fn update_service_relay_status() 224 ## @brief Pruefe regelmaessig, ob Weiterleitungen für alle bekannten durchgereichten Diensten existieren. 225 ## @details Fehlende Weiterleitungen oder olsr-Announcements werden angelegt. 227 trap
'error_trap update_service_relay_status "$*"' EXIT
231 for service_name in $(
get_services | filter_relay_services);
do 232 # WAN-Routing pruefen und aktualisieren 235 is_service_relay_possible
"$service_name" ||
continue 236 announce_olsr_service_relay
"$service_name" 238 update_relay_firewall_rules
239 deannounce_unused_olsr_service_relays is_service_relay_possible
241 deannounce_unused_olsr_service_relays
false 247 ## @fn filter_relay_services() 248 ## @brief Filtere aus einer Reihe eingehender Dienste diejenigen heraus, die als Dienst-Relay fungieren. 249 ## @details Die Dienst-Namen werden über die Standardeingabe gelesen und an die Standardausgabe 250 ## weitergeleitet, falls es sich um einen Relay-Dienst handelt. 251 filter_relay_services() {
253 while read -r service_name;
do 254 [ -z
"$(get_service_value "$service_name
" "local_relay_port
")" ] || echo
"$service_name" 258 # Ende der Doku-Gruppe set eu case in on usergw on function update_on_usergw_status on function update_service_relay_status
get_services(service_type)
Liefere alle Dienste zurueck, die dem angegebenen Typ zugeordnet sind. Falls kein Typ angegben wird...
set_service_value()
Setzen eines oder mehrerer Werte fuer einen Dienst. Je nach Schluesselname wird der Inhalt in die per...
uci_add_list(uci_path, new_item)
Füge einen neuen Wert zu einer UCI-Liste hinzu und achte dabei auf Einmaligkeit.
filter_services_by_value(key, value)
set eu grep root::etc shadow exit if command v chpasswd dev null
uci_delete_list(uci_path, value)
Lösche ein Element einer UCI-Liste.
uci_get_list(uci_path)
Liefere alle einzelnen Elemente einer UCI-Liste zurück.
filter_routable_addresses()
Filtere aus einer Menge von Ziel-IPs diejenigen heraus, für die eine passende Routing-Regel existiert...
msg_debug(message)
Debug-Meldungen ins syslog schreiben.
get_service_value(key, default)
Auslesen eines Werts aus der Service-Datenbank.
is_service_routed_via_wan(service_name)
Pruefe ob der Verkehr zum Anbieter des Diensts über ein WAN-Interface verlaufen würde.
set eu for table in filter nat mangle
is_on_module_installed_and_enabled(module)
Pruefe ob ein Modul sowohl installiert, als auch aktiv ist.