Opennet Firmware
openvpn.sh
gehe zur Dokumentation dieser Datei
1 ## @defgroup openvpn OpenVPN (allgemein)
2 ## @brief Vorbereitung, Konfiguration und Prüfung von VPN-Verbindungen (z.B. für Nutzertunnel oder UGW).
3 # Beginn der openvpn-Doku-Gruppe
4 ## @{
5 
6 
7 OPENVPN_CONFIG_BASEDIR=/var/etc/openvpn
8 
9 
10 ## @fn enable_openvpn_service()
11 ## @brief Erzeuge eine funktionierende openvpn-Konfiguration (Datei + UCI).
12 ## @param service_name Name eines Dienstes
13 ## @details Die Konfigurationsdatei wird erzeugt und eine openvpn-uci-Konfiguration wird angelegt.
14 ## Falls zu diesem openvpn-Dienst kein Zertifikat oder kein Schlüssel gefunden wird, dann passiert nichts.
16  trap 'error_trap enable_openvpn_service "$*"' EXIT
17  local service_name="$1"
18  local config_file="$OPENVPN_CONFIG_BASEDIR/${service_name}.conf"
19  if ! openvpn_service_has_certificate_and_key "$service_name"; then
20  msg_info "Refuse to enable openvpn server ('$service_name'): missing key or certificate"
21  trap "" EXIT && return 1
22  fi
23  local uci_prefix="openvpn.$service_name"
24  # zukuenftige config-Datei referenzieren
25  update_vpn_config "$service_name" "$config_file"
26  # zuvor ankuendigen, dass zukuenftig diese uci-Konfiguration an dem Dienst haengt
27  service_add_uci_dependency "$service_name" "$uci_prefix"
28  # lege die uci-Konfiguration an und aktiviere sie
29  uci set "${uci_prefix}=openvpn"
30  uci set "${uci_prefix}.enabled=1"
31  uci set "${uci_prefix}.config=$config_file"
32  apply_changes openvpn
33 }
34 
35 
36 ## @fn update_vpn_config()
37 ## @brief Schreibe eine openvpn-Konfigurationsdatei.
38 ## @param service_name Name eines Dienstes
40  trap 'error_trap update_vpn_config "$*"' EXIT
41  local service_name="$1"
42  local config_file="$2"
43  service_add_file_dependency "$service_name" "$config_file"
44  # Konfigurationsdatei neu schreiben
45  mkdir -p "$(dirname "$config_file")"
46  get_openvpn_config "$service_name" >"$config_file"
47 }
48 
49 
50 ## @fn disable_openvpn_service()
51 ## @brief Löschung einer openvpn-Verbindung
52 ## @param service_name Name eines Dienstes
53 ## @details Die UCI-Konfiguration, sowie alle anderen mit der Verbindung verbundenen Elemente werden entfernt.
54 ## Die openvpn-Verbindung bleibt bestehen, bis zum nächsten Aufruf von 'apply_changes openvpn'.
56  trap 'error_trap disable_openvpn_service "$*"' EXIT
57  local service_name="$1"
58  # Abbruch, falls es keine openvpn-Instanz gibt
59  [ -z "$(uci_get "openvpn.$service_name")" ] && return 0
60  # openvpn wird automatisch neugestartet
61  cleanup_service_dependencies "$service_name"
62  # nach einem reboot sind eventuell die dependencies verlorengegangen - also loeschen wir manuell
63  uci_delete "openvpn.$service_name"
64 }
65 
66 
67 ## @fn get_openvpn_service_state()
68 ## @brief Prüfe ob eine openvpn-Verbindung besteht bzw. im Aufbau ist.
69 ## @param service_name Name eines Dienstes
70 ## @details Die Prüfung wird anhand der PID-Datei und der Gültigkeit der enthaltenen PID vorgenommen.
71 ## @returns "active", "connecting" oder einen leeren String (unbekannt, bzw. keine Verbindung).
73  trap 'error_trap get_openvpn_service_state "$*"' EXIT
74  local service_name="$1"
75  local pid_file
76  # existiert ein VPN-Eintrag?
77  [ -z "$(uci_get "openvpn.$service_name")" ] && return
78  # gibt es einen Verweis auf eine passende PID-Datei?
79  pid_file=$(get_openvpn_service_pid_file "$service_name")
80  if check_pid_file "$pid_file" "openvpn"; then
81  # Die "openvpn_established_indicator_file"-Variable wird vom up/down-Skript erzeugt.
82  # Die Variable verweist ebenfalls auf eine Datei mit der PID. Dies erlaubt die Unterscheidung
83  # einer Verbindung im Aufbau (bzw. in der Phase einer wiederholten Ablehnung) von einer
84  # beiderseits akzeptierten Datenverbindung. Dies ist insbesondere fuer die mesh-VPN-Verbindungen
85  # sinnvoll, da hier mehr Toleranz beim Verbindungsaufbau sinnvoll ist.
86  if check_pid_file "$(get_service_value "$service_name" "openvpn_established_indicator_file")" "openvpn"; then
87  echo -n "active"
88  else
89  echo -n "connecting"
90  fi
91  else
92  true
93  fi
94 }
95 
96 
97 ## @fn _change_openvpn_config_setting()
98 ## @brief Ändere eine Einstellung in einer openvpn-Konfigurationsdatei.
99 ## @param config_file Name der Konfigurationsdatei.
100 ## @param config_key Name der openvpn-Einstellung.
101 ## @param config_value Neuer Inhalt der Einstellung - die Einstellung wird gelöscht, falls dieser Parameter fehlt oder leer ist.
102 ## @attention OpenVPN-Optionen ohne Parameter (z.B. --mtu-test) können nicht mittels dieser Funktion gesetzt werden.
104  local config_file="$1"
105  local config_key="$2"
106  local config_value="${3:-}"
107  sed -i "/^$config_key"'[\t ]/d' "$config_file"
108  [ -n "$config_value" ] && echo "$config_key $config_value" >>"$config_file"
109  return 0
110 }
111 
112 
113 ## @fn get_openvpn_config()
114 ## @brief liefere openvpn-Konfiguration eines Dienstes zurück
115 ## @param service_name Name eines Dienstes
117  trap 'error_trap get_openvpn_config "$*"' EXIT
118  local service_name="$1"
119  local remote
120  local port
121  local protocol
122  local template_file
123  local pid_file
124  local proxy_service_type
125  local relayed_service
126  remote=$(get_service_value "$service_name" "host")
127  port=$(get_service_value "$service_name" "port")
128  # Falls es sich um einen relay-Dienst handelt, koennen wir uns leider nicht mit uns selbst verbinden,
129  # da die firewall-redirect-Regeln keine "device"-Quelle kennen (anstelle des ueblichen "on_mesh").
130  if [ "$remote" = "$(get_main_ip)" ]; then
131  proxy_service_type="$RELAYABLE_SERVICE_PREFIX$(get_service_value "$service_name" "service")"
132  relayed_service=$(get_services "$proxy_service_type" | filter_services_by_value "local_relay_port" "$port")
133  if [ -n "$relayed_service" ]; then
134  # Hostname und Port ersetzen
135  remote=$(get_service_value "$relayed_service" "host")
136  port=$(get_service_value "$relayed_service" "port")
137  else
138  msg_info "Failed to use locally relayed service for openvpn - trying to continue, anyway."
139  fi
140  fi
141  protocol=$(get_service_value "$service_name" "protocol")
142  template_file=$(get_openvpn_service_template_filename "$service_name")
143  pid_file=$(get_openvpn_service_pid_file "$service_name")
144  # schreibe die Konfigurationsdatei
145  echo "# automatically generated by $0"
146  echo "remote $remote $port $protocol"
147  echo "writepid $pid_file"
148  cat "$template_file"
149  # sicherstellen, dass die Konfigurationsdatei mit einem Zeilenumbruch endet (fuer "echo >> ...")
150  echo
151 }
152 
153 
154 ## @fn verify_vpn_connection()
155 ## @brief Prüfe einen VPN-Verbindungsaufbau
156 ## @param service_name Name eines Dienstes
157 ## @param key [optional] Schluesseldatei: z.B. $VPN_DIR/on_aps.key
158 ## @param cert [optional] Zertifikatsdatei: z.B. $VPN_DIR/on_aps.crt
159 ## @returns Exitcode=0 falls die Verbindung aufgebaut werden konnte
161  trap 'error_trap verify_vpn_connection "$*"' EXIT
162  local service_name="$1"
163  local key_file="${2:-}"
164  local cert_file="${3:-}"
165  local config_file
166  local log_file
167  local file_opts
168  config_file=$(mktemp -t "VERIFY-${service_name}-XXXXXXX")
169  log_file=$(get_service_log_filename "$service_name" "openvpn" "verify")
170  # wir benoetigen die template-Datei fuer das Erzeugen der Basis-Konfiguration
171  msg_debug "start vpn test of $service_name"
172  # erstelle die config-Datei
173  (
174  # filtere Einstellungen heraus, die wir ueberschreiben wollen
175  # nie die echte PID-Datei ueberschreiben (falls ein Prozess laeuft)
176  get_openvpn_config "$service_name"
177 
178  # some openvpn options:
179  # ifconfig-noexec: we do not want to configure a device (and mess up routing tables)
180  # route-noexec: keinerlei Routen hinzufuegen
181  echo "ifconfig-noexec"
182  echo "route-noexec"
183 
184  # some timing options:
185  # inactive: close connection after 15s without traffic
186  # ping-exit: close connection after 15s without a ping from the other side (which is probably disabled)
187  echo "inactive 15 1000000"
188  echo "ping-exit 15"
189 
190  # other options:
191  # verb: verbose level 3 is required for the TLS messages
192  # nice: testing is not too important
193  # resolv-retry: fuer ipv4/ipv6-Tests sollten wir mehrere Versuche zulassen
194  echo "verb 4"
195  echo "nice 3"
196  echo "resolv-retry 3"
197 
198  # prevent a real connection (otherwise we may break our current vpn tunnel):
199  # tls-exit: stop immediately after tls handshake failure
200  # remote-cert-tls: enforce a connection against a server certificate (instead of peer-to-peer)
201  echo "tls-exit"
202  echo "remote-cert-tls server"
203 
204  ) >"$config_file"
205 
206  # kein Netzwerkinterface erzeugen
207  _change_openvpn_config_setting "$config_file" "dev" "null"
208  # keine PID-Datei anlegen
209  _change_openvpn_config_setting "$config_file" "writepid" ""
210  # keine Netzwerkkonfiguration via up/down
211  _change_openvpn_config_setting "$config_file" "up" ""
212  _change_openvpn_config_setting "$config_file" "down" ""
213  # TLS-Pruefung immer fehlschlagen lassen
214  _change_openvpn_config_setting "$config_file" "tls-verify" "/bin/false"
215  # Log-Datei anlegen
216  _change_openvpn_config_setting "$config_file" "log" "$log_file"
217 
218  # nur fuer tcp-Verbindungen (ipv4/ipv6)
219  # connect-retry: Sekunden Wartezeit zwischen Versuchen
220  # connect-retry-max: Anzahl moeglicher Wiederholungen
221  if grep -q "^remote.*tcp" "$config_file"; then
222  {
223  echo "connect-retry 1"
224  echo "connect-retry-max 1"
225  } >>"$config_file"
226  fi
227 
228  # Short timeout for connections (default: 120s) - otherwise the 45s timeout below allows
229  # only _one_ attempt. But we need at least two in order to try IPv4 and IPv6 connections.
230  echo "connect-timeout 12" >>"$config_file"
231 
232  # Schluessel und Zertifikate bei Bedarf austauschen
233  [ -n "$key_file" ] && \
234  _change_openvpn_config_setting "$config_file" "key" "$key_file"
235  [ -n "$cert_file" ] && \
236  _change_openvpn_config_setting "$config_file" "cert" "$cert_file"
237 
238  # Aufbau der VPN-Verbindung bis zum Timeout oder bis zum Verbindungsabbruch via "tls-exit" (/bin/false)
239  # Die Begrenzung durch "timeout" scheint für "unreachable" IPv6-Ziele notwendig zu sein.
240  # Andernfalls wartet der Prozess ewig.
241  timeout 45s openvpn --config "$config_file" || true
242  # read the additional options from the config file (for debug purposes)
243  file_opts=$(grep -v "^$" "$config_file" | grep -v "^#" | sed 's/^/--/' | tr '\n' ' ')
244  rm -f "$config_file"
245  if [ -e "$log_file" ]; then
246  grep -q "Initial packet" "$log_file" && return 0
247  msg_debug "openvpn test failed: openvpn $file_opts"
248  else
249  # Die Log-Datei sollte nur dann fehlen, wenn die openvpn-Konfiguration defekt ist
250  # und somit den Start von openvpn verhindert.
251  msg_error "openvpn test failed unexpectedly: configuration error?"
252  fi
253  trap "" EXIT && return 1
254 }
255 
256 
257 ## @fn openvpn_service_has_certificate_and_key()
258 ## @brief Prüfe ob das Zertifikat eines openvpn-basierten Diensts existiert.
259 ## @returns exitcode=0 falls das Zertifikat existiert
260 ## @details Falls der Ort der Zertifikatsdatei nicht zweifelsfrei ermittelt
261 ## werden kann, dann liefert die Funktion "wahr" zurück.
263  local service_name="$1"
264  local cert_file
265  local key_file
266  local config_template
267  config_template=$(get_service_value "$service_name" "template")
268  # im Zweifelsfall (kein Template gefunden) liefern wir "wahr"
269  [ -z "$config_template" ] && return 0
270  # Verweis auf lokale config-Datei (keine uci-basierte Konfiguration)
271  if [ -e "$config_template" ]; then
272  cert_file=$(_get_file_dict_value "cert" "$config_template")
273  key_file=$(_get_file_dict_value "key" "$config_template")
274  else
275  # im Zweifelsfall: liefere "wahr"
276  return 0
277  fi
278  # das Zertifikat scheint irgendwie anders konfiguriert zu sein - im Zeifelsfall: OK
279  if [ -z "$cert_file" ] || [ -z "$key_file" ]; then
280  return 0
281  elif [ -e "$cert_file" ] && [ -e "$key_file" ]; then
282  # alle relevanten Dateien existieren
283  return 0
284  else
285  trap "" EXIT && return 1
286  fi
287 }
288 
289 
290 ## @fn has_openvpn_credentials_by_template()
291 ## @brief Prüft, ob der Nutzer bereits einen Schlüssel und ein Zertifikat angelegt hat.
292 ## @param template_file Name einer openvpn-Konfigurationsdatei (oder einer Vorlage). Aus dieser Datei werden "cert"- und "key"-Werte entnommen.
293 ## @returns Liefert "wahr", falls Schlüssel und Zertifikat vorhanden sind oder falls in irgendeiner Form Unklarheit besteht.
295  trap 'error_trap has_openvpn_credentials_by_template "$*"' EXIT
296  local template_file="$1"
297  local cert_file
298  local key_file
299  local base_dir
300  cert_file=$(_get_file_dict_value "cert" "$template_file")
301  key_file=$(_get_file_dict_value "key" "$template_file")
302  # Pruefe, ob eine "cd"-Direktive enthalten ist - vervollständige damit relative Pfade
303  base_dir=$(_get_file_dict_value "cd" "$template_file")
304  [ -n "$base_dir" ] && [ "${cert_file:0:1}" != "/" ] && cert_file="$base_dir/$cert_file"
305  [ -n "$base_dir" ] && [ "${key_file:0:1}" != "/" ] && key_file="$base_dir/$key_file"
306  # im Zweifel: liefere "wahr"
307  if [ -z "$key_file" ] || [ -z "$cert_file" ]; then
308  return 0
309  elif [ -e "$key_file" ] && [ -e "$cert_file" ]; then
310  # beide Dateien existieren
311  return 0
312  else
313  trap "" EXIT && return 1
314  fi
315 }
316 
317 
318 ## @fn log_openvpn_events_and_disconnect_if_requested()
319 ## @brief Allgemeines Ereignisbehandlung fuer openvpn-Verbindungen: Logging und eventuell Dienst-Bereinigung (nur für "down").
320 ## @details Alle Informationen (bis auf das Log-Ziel) werden aus den Umgebungsvariablen gezogen, die openvpn in
321 ## seinen Ereignisskripten setzt.
323  local log_target="$1"
324  # die config-Datei enthaelt den Dienst-Namen
325  local service_name
326  local pid_file
327  local established_indicator_file
328  local service_type
329  local service_host
330  local now
331  local same_host_service
332  # die folgenden Variablen stammen aus der OpenVPN-Umgebung
333  config=${config:-}
334  script_type=${script_type:-}
335  remote_1=${remote_1:-}
336  remote_port_1=${remote_port_1:-}
337  daemon_start_time=${daemon_start_time:-}
338  # es geht los ...
339  service_name=$(basename "${config%.conf}")
340  pid_file=$(get_openvpn_service_pid_file "$service_name")
341  established_indicator_file=$(get_service_value "$service_name" "openvpn_established_indicator_file")
342  if [ -z "$established_indicator_file" ] && [ -n "$pid_file" ]; then
343  established_indicator_file="${pid_file}.established"
344  set_service_value "$service_name" "openvpn_established_indicator_file" "$established_indicator_file"
345  fi
346  case "$script_type" in
347  up)
348  append_to_custom_log "$log_target" "up" "Connecting to ${remote_1}:${remote_port_1}"
349  [ -n "$pid_file" ] && cat "$pid_file" >"$established_indicator_file"
350  true
351  ;;
352  down)
353  # der openwrt-Build von openvpn setzt wohl leider nicht die "time_duration"-Umgebungsvariable
354  [ -z "${time_duration:-}" ] && time_duration=$(($(date +%s) - daemon_start_time))
355  # Verbindungsverlust durch fehlende openvpn-Pings?
356  if [ "${signal:-}" = "ping-restart" ]; then
357  service_type=$(get_service_value "$service_name" "service")
358  service_host=$(get_service_value "$service_name" "host")
359  now=$(get_uptime_minutes)
360  append_to_custom_log "$log_target" "down" \
361  "Lost connection with ${remote_1}:${remote_port_1} after ${time_duration}s"
362  # alle Verbindungen derselben Art zu diesem Host als unklar definieren
363  for same_host_service in $(get_services "$service_type" \
364  | filter_services_by_value "host" "$service_host"); do
365  set_service_value "$same_host_service" "status" ""
366  set_service_value "$same_host_service" "status_timestamp" "$now"
367  done
368  disable_openvpn_service "$service_name"
369  [ -n "$pid_file" ] && rm -f "$pid_file"
370  [ -n "$established_indicator_file" ] && rm -f "$established_indicator_file"
371  true
372  else
373  append_to_custom_log "$log_target" "down" \
374  "Closing connection with ${remote_1}:${remote_port_1} after ${time_duration}s"
375  fi
376  ;;
377  *)
378  append_to_custom_log "$log_target" "other" "${remote_1}:${remote_port_1}"
379  ;;
380  esac
381 }
382 
383 
384 ## @fn get_openvpn_service_pid_file()
385 ## @param Name eines Diensts
386 ## @brief PID-Datei für diesen Dienst ausgeben.
388  local service_name="$1"
389  echo "/var/run/${service_name}.pid"
390 }
391 
392 
393 ## @fn get_openvpn_service_template_filename()
394 ## @param Name des Diensts
395 ## @brief Dateiname der Konfigurationsvorlage dieses Diensts ausgeben.
397  trap 'error_trap get_openvpn_service_template_filename "$*"' EXIT
398  local service_name="$1"
399  local service_type
400  service_type=$(get_service_value "$service_name" "service")
401  # Diese Stelle ist hier eigentlich falsch, da sie Kenntnisse und Variablen
402  # vorraussetzt, die nicht in "on-core" definiert sind.
403  # Aufgrund der Wiederverwendung der generischen
404  # "run_cyclic_service_tests"-Funktion ist eine Separierung dieser Auswahl
405  # jedoch leider nur mit großem Aufwand möglich.
406  if [ "$service_type" = "gw" ]; then
407  echo "$MIG_OPENVPN_CONFIG_TEMPLATE_FILE"
408  elif [ "$service_type" = "mesh" ]; then
409  echo "$MESH_OPENVPN_CONFIG_TEMPLATE_FILE"
410  else
411  msg_error "unknown service type for openvpn config preparation: $service_type"
412  trap "" EXIT && return 1
413  fi
414 }
415 
416 
417 ## @fn openvpn_get_mtu()
418 ## @brief Ermittle die MTU auf dem Weg zum Anbieter des Diensts.
419 ## @details The output can be easily parsed via 'cut'. Even the full status output of openvpn is safe for parsing since potential tabulator characters are removed.
420 ## @returns One line consisting of five fields separated by tab characters is returned (tried_to_remote real_to_remote tried_from_remote real_from_remote full_status_output). Failed tests are indicated by an empty result.
421 openvpn_get_mtu() {
422  # TODO: dies ist ein (schlechter) Workaround für einen Fehler der MTU-Prüfung seit OpenVPN v2.4
423  # siehe https://dev.opennet-initiative.de/ticket/210 und https://community.openvpn.net/openvpn/ticket/1103
424  printf '%d\t%d\t%d\t%d\t%s' 1520 1520 1493 1494 "Empirical MTU test completed [Tried,Actual] local->remote=[1520,1520] remote->local=[1493,1493]"
425  return
426 
427  trap 'error_trap openvpn_get_mtu "$*"' EXIT
428  local service_name="$1"
429  local config_file
430  local pid_file
431  local log_file
432  local host
433  config_file=$(mktemp -t "MTU-${service_name}-XXXXXXX")
434  pid_file="$(mktemp)"
435  log_file="$(get_service_log_filename "$service_name" "openvpn" "mtu")"
436  host=$(get_service_value "$service_name" "host")
437 
438  (
439  get_openvpn_config "$service_name"
440  # kein Netzwerk konfigurieren
441  echo "ifconfig-noexec"
442  echo "route-noexec"
443  ) >"$config_file"
444 
445  # kein Netzwerkinterface, keine pid-Datei
446  _change_openvpn_config_setting "$config_file" "dev" "null"
447  _change_openvpn_config_setting "$config_file" "writepid" "$pid_file"
448 
449  # Log-Datei anlegen
450  _change_openvpn_config_setting "$config_file" "log" "$log_file"
451  _change_openvpn_config_setting "$config_file" "verb" "4"
452 
453  # keine Skripte
454  _change_openvpn_config_setting "$config_file" "up" ""
455  _change_openvpn_config_setting "$config_file" "down" ""
456 
457  openvpn --mtu-test --config "$config_file" 2>&1 &
458  # warte auf den Startvorgang
459  sleep 3
460  local wait_loops=40
461  local pid
462  pid=$(cat "$pid_file" 2>/dev/null || true)
463  local mtu_out
464  local mtu_out_filtered
465  while [ "$wait_loops" -gt 0 ]; do
466  # keine Fehlermeldungen (-s) falls die Log-Datei noch nicht existiert
467  mtu_out=$(grep -s "MTU test completed" "$log_file" || true)
468  # for example
469  # Thu Jul 3 22:23:01 2014 NOTE: Empirical MTU test completed [Tried,Actual] local->remote=[1573,1573] remote->local=[1573,1573]
470  if [ -n "$mtu_out" ]; then
471  # Ausgabe der vier Zahlen getrennt durch Tabulatoren
472  mtu_out_filtered="$(echo "$mtu_out" | tr '[' ',' | tr ']' ',')"
473  # Leider koennen wir nicht alle Felder auf einmal ausgeben (tab-getrennt),
474  # da das busybox-cut nicht den --output-delimiter unterstützt.
475  echo "$mtu_out_filtered" | cut -d , -f 5 | tr '\n' '\t'
476  echo "$mtu_out_filtered" | cut -d , -f 6 | tr '\n' '\t'
477  echo "$mtu_out_filtered" | cut -d , -f 8 | tr '\n' '\t'
478  echo "$mtu_out_filtered" | cut -d , -f 9 | tr '\n' '\t'
479  # wir ersetzen alle eventuell vorhandenen Tabulatoren in der Statusausgabe - zur Vereinfachung des Parsers
480  echo -n "$mtu_out" | tr '\t' ' '
481  break
482  elif [ -z "$pid" ] || [ ! -d "/proc/$pid" ]; then
483  msg_info "Failed to verify MTU resctrictions for '$host'"
484  break
485  fi
486  sleep 10
487  wait_loops=$((wait_loops - 1))
488  done
489  # sicherheitshalber brechen wir den Prozess ab und loeschen alle Dateien
490  kill "$pid" >/dev/null 2>&1 || true
491  rm -f "$config_file" "$pid_file"
492  # ist der Zaehler abgelaufen?
493  [ "$wait_loops" -eq 0 ] && msg_info "Timeout for openvpn_get_mtu '$host' - aborting."
494  return 0
495 }
496 
497 
498 ## @fn cleanup_stale_openvpn_services()
499 ## @brief Beräumung liegengebliebener openvpn-Konfigurationen, sowie Deaktivierung funktionsunfähiger Verbindungen.
500 ## @details Verwaiste openvpn-Konfigurationen können aus zwei Grunden auftreten:
501 ## 1) nach einem reboot wurde nicht die zuletzt aktive openvpn-Verbindung ausgewählt - somit
502 ## bleibt der vorher aktive uci-Konfigurationseintrag erhalten
503 ## 2) ein VPN-Verbindungsaufbau scheitert und hinterlässt einen uci-Eintrag, eine PID-Datei,
504 ## jedoch keinen laufenden Prozess
505 ## Achtung: falls eine Verbindung sich gerade im Aufbau befindet, wird ihre Konfiguration
506 ## ebenfalls entfernt. Diese Funktion sollte also nur in ausgewählten Situation
507 ## aufgerufen werden (nach einem Reboot und nach einem Verbindungsabbruch).
509  trap 'error_trap cleanup_stale_openvpn_services "$*"' EXIT
510  local service_name
511  local config_file
512  local pid_file
513  local uci_prefix
514  for uci_prefix in $(find_all_uci_sections "openvpn" "openvpn"); do
515  config_file=$(uci_get "${uci_prefix}.config")
516  # Keine config-Datei? Keine von uns verwaltete Konfiguration ...
517  [ -z "$config_file" ] && continue
518  service_name="${uci_prefix#openvpn.}"
519  # Es scheint sich um eine von uns verwaltete Verbindung zu handeln.
520  pid_file=$(get_openvpn_service_pid_file "$service_name")
521  # Falls die config-Datei oder die pid-Datei fehlt, dann ist es ein reboot-Fragment. Wir löschen die Überreste.
522  if [ ! -e "$config_file" ] || [ ! -e "$pid_file" ]; then
523  msg_info "Removing a reboot-fragment of a previously used openvpn connection: $service_name"
524  disable_openvpn_service "$service_name"
525  elif check_pid_file "$pid_file" "openvpn"; then
526  # Prozess läuft - alles gut
527  true
528  else
529  # Falls die PID-Datei existiert, jedoch veraltet ist (kein dazugehöriger Prozess läuft), dann
530  # schlug der Verbindungsaufbau fehlt (siehe "tls-exit" und "single-session").
531  # Wir markieren die Verbindung als kaputt.
532  msg_info "Marking a possibly interrupted openvpn connection as broken: $service_name"
533  set_service_value "$service_name" "status" "n"
534  disable_openvpn_service "$service_name"
535  fi
536  done
537  apply_changes openvpn
538 }
539 
540 # Ende der openvpn-Doku-Gruppe
541 ## @}
uci_delete(uci_path)
Lösche ein UCI-Element.
Definition: uci.sh:46
get_service_log_filename()
Ermittle den Namen der Log-Datei für diesen Dienst. Zusätzliche Details (z.B. "openvpn mtu"...
Definition: services.sh:136
get_services(service_type)
Liefere alle Dienste zurueck, die dem angegebenen Typ zugeordnet sind. Falls kein Typ angegben wird...
Definition: services.sh:68
_change_openvpn_config_setting(config_file, config_key, config_value)
Ändere eine Einstellung in einer openvpn-Konfigurationsdatei.
Definition: openvpn.sh:32
openvpn_get_mtu()
Ermittle die MTU auf dem Weg zum Anbieter des Diensts.
Definition: openvpn.sh:72
append_to_custom_log(log_name, event)
Hänge eine neue Nachricht an ein spezfisches Protokoll an.
Definition: core.sh:29
cleanup_stale_openvpn_services()
Beräumung liegengebliebener openvpn-Konfigurationen, sowie Deaktivierung funktionsunfähiger Verbindun...
Definition: openvpn.sh:83
get_openvpn_config(service_name)
liefere openvpn-Konfiguration eines Dienstes zurück
Definition: openvpn.sh:36
update_vpn_config(service_name)
Schreibe eine openvpn-Konfigurationsdatei.
Definition: openvpn.sh:13
set_service_value()
Setzen eines oder mehrerer Werte fuer einen Dienst. Je nach Schluesselname wird der Inhalt in die per...
Definition: services.sh:79
_get_file_dict_value(key)
Auslesen eines Werts aus einem Schlüssel/Wert-Eingabestrom.
Definition: core.sh:85
log_openvpn_events_and_disconnect_if_requested()
Allgemeines Ereignisbehandlung fuer openvpn-Verbindungen: Logging und eventuell Dienst-Bereinigung (n...
Definition: openvpn.sh:59
get_openvpn_service_pid_file(Name)
PID-Datei für diesen Dienst ausgeben.
Definition: openvpn.sh:63
filter_services_by_value(key, value)
Definition: services.sh:74
set eu grep root::etc shadow exit if command v chpasswd dev null
Definition: on-password:12
msg_info(message)
Informationen und Fehlermeldungen ins syslog schreiben.
Definition: core.sh:15
openvpn_service_has_certificate_and_key()
Prüfe ob das Zertifikat eines openvpn-basierten Diensts existiert.
Definition: openvpn.sh:49
get_openvpn_service_state(service_name)
Prüfe ob eine openvpn-Verbindung besteht bzw. im Aufbau ist.
Definition: openvpn.sh:25
enable_openvpn_service()
Erzeuge eine funktionierende openvpn-Konfiguration (Datei + UCI, service_name).
Definition: openvpn.sh:9
msg_debug(message)
Debug-Meldungen ins syslog schreiben.
Definition: core.sh:9
get_openvpn_service_template_filename(Name)
Dateiname der Konfigurationsvorlage dieses Diensts ausgeben.
Definition: openvpn.sh:67
set eu on function print_services services log for dir in etc on services d var on services volatile d
Definition: services:13
get_service_value(key, default)
Auslesen eines Werts aus der Service-Datenbank.
Definition: services.sh:86
verify_vpn_connection(service_name, key, cert)
Prüfe einen VPN-Verbindungsaufbau.
Definition: openvpn.sh:43
msg_error(message)
Die Fehlermeldungen werden in die Standard-Fehlerausgabe und ins syslog geschrieben.
Definition: core.sh:22
done
Definition: core.sh:85
has_openvpn_credentials_by_template(template_file)
Prüft, ob der Nutzer bereits einen Schlüssel und ein Zertifikat angelegt hat.
Definition: openvpn.sh:54
disable_openvpn_service(service_name)
Löschung einer openvpn-Verbindung.
Definition: openvpn.sh:19