From b38c595f405ec99113828be5639b586f22fb7e79 Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Sat, 23 Mar 2024 14:39:30 +0100 Subject: [PATCH] openvpn: Add an initscript for N2N connections Signed-off-by: Michael Tremer --- config/rootfiles/common/aarch64/initscripts | 4 + config/rootfiles/common/riscv64/initscripts | 4 + config/rootfiles/common/x86_64/initscripts | 4 + lfs/initscripts | 3 + src/initscripts/system/openvpn-n2n | 333 ++++++++++++++++++++ 5 files changed, 348 insertions(+) create mode 100644 src/initscripts/system/openvpn-n2n diff --git a/config/rootfiles/common/aarch64/initscripts b/config/rootfiles/common/aarch64/initscripts index c93c0ee4c..4405fada7 100644 --- a/config/rootfiles/common/aarch64/initscripts +++ b/config/rootfiles/common/aarch64/initscripts @@ -70,6 +70,7 @@ etc/rc.d/init.d/networking/red.up/99-fireinfo etc/rc.d/init.d/networking/red.up/99-pakfire-update etc/rc.d/init.d/networking/wpa_supplicant.exe etc/rc.d/init.d/ntp +etc/rc.d/init.d/openvpn-n2n etc/rc.d/init.d/openvpn-rw etc/rc.d/init.d/pakfire etc/rc.d/init.d/partresize @@ -101,6 +102,7 @@ etc/rc.d/rc0.d/K01grub-btrfsd #etc/rc.d/rc0.d/K01vdradmin etc/rc.d/rc0.d/K08fcron etc/rc.d/rc0.d/K10openvpn-rw +etc/rc.d/rc0.d/K11openvpn-n2n etc/rc.d/rc0.d/K28apache etc/rc.d/rc0.d/K30sshd etc/rc.d/rc0.d/K47setclock @@ -138,6 +140,7 @@ etc/rc.d/rc3.d/S30sshd etc/rc.d/rc3.d/S32apache etc/rc.d/rc3.d/S40fcron etc/rc.d/rc3.d/S50openvpn-rw +etc/rc.d/rc3.d/S51openvpn-n2n etc/rc.d/rc3.d/S98rc.local etc/rc.d/rc3.d/S99grub-btrfsd #etc/rc.d/rc3.d/S99imspetor @@ -150,6 +153,7 @@ etc/rc.d/rc6.d/K01grub-btrfsd #etc/rc.d/rc6.d/K01vdradmin etc/rc.d/rc6.d/K08fcron etc/rc.d/rc6.d/K10openvpn-rw +etc/rc.d/rc6.d/K11openvpn-n2n etc/rc.d/rc6.d/K28apache etc/rc.d/rc6.d/K30sshd etc/rc.d/rc6.d/K47setclock diff --git a/config/rootfiles/common/riscv64/initscripts b/config/rootfiles/common/riscv64/initscripts index 67735581b..ebc51f092 100644 --- a/config/rootfiles/common/riscv64/initscripts +++ b/config/rootfiles/common/riscv64/initscripts @@ -70,6 +70,7 @@ etc/rc.d/init.d/networking/red.up/99-fireinfo etc/rc.d/init.d/networking/red.up/99-pakfire-update etc/rc.d/init.d/networking/wpa_supplicant.exe etc/rc.d/init.d/ntp +etc/rc.d/init.d/openvpn-n2n etc/rc.d/init.d/openvpn-rw etc/rc.d/init.d/pakfire etc/rc.d/init.d/partresize @@ -100,6 +101,7 @@ etc/rc.d/rc0.d/K01grub-btrfsd #etc/rc.d/rc0.d/K01vdradmin etc/rc.d/rc0.d/K08fcron etc/rc.d/rc0.d/K10openvpn-rw +etc/rc.d/rc0.d/K11openvpn-n2n etc/rc.d/rc0.d/K28apache etc/rc.d/rc0.d/K30sshd etc/rc.d/rc0.d/K47setclock @@ -137,6 +139,7 @@ etc/rc.d/rc3.d/S30sshd etc/rc.d/rc3.d/S32apache etc/rc.d/rc3.d/S40fcron etc/rc.d/rc3.d/S50openvpn-rw +etc/rc.d/rc3.d/S51openvpn-n2n etc/rc.d/rc3.d/S98rc.local etc/rc.d/rc3.d/S99grub-btrfsd #etc/rc.d/rc3.d/S99imspetor @@ -149,6 +152,7 @@ etc/rc.d/rc6.d/K01grub-btrfsd #etc/rc.d/rc6.d/K01vdradmin etc/rc.d/rc6.d/K08fcron etc/rc.d/rc6.d/K10openvpn-rw +etc/rc.d/rc6.d/K11openvpn-n2n etc/rc.d/rc6.d/K28apache etc/rc.d/rc6.d/K30sshd etc/rc.d/rc6.d/K47setclock diff --git a/config/rootfiles/common/x86_64/initscripts b/config/rootfiles/common/x86_64/initscripts index 67735581b..ebc51f092 100644 --- a/config/rootfiles/common/x86_64/initscripts +++ b/config/rootfiles/common/x86_64/initscripts @@ -70,6 +70,7 @@ etc/rc.d/init.d/networking/red.up/99-fireinfo etc/rc.d/init.d/networking/red.up/99-pakfire-update etc/rc.d/init.d/networking/wpa_supplicant.exe etc/rc.d/init.d/ntp +etc/rc.d/init.d/openvpn-n2n etc/rc.d/init.d/openvpn-rw etc/rc.d/init.d/pakfire etc/rc.d/init.d/partresize @@ -100,6 +101,7 @@ etc/rc.d/rc0.d/K01grub-btrfsd #etc/rc.d/rc0.d/K01vdradmin etc/rc.d/rc0.d/K08fcron etc/rc.d/rc0.d/K10openvpn-rw +etc/rc.d/rc0.d/K11openvpn-n2n etc/rc.d/rc0.d/K28apache etc/rc.d/rc0.d/K30sshd etc/rc.d/rc0.d/K47setclock @@ -137,6 +139,7 @@ etc/rc.d/rc3.d/S30sshd etc/rc.d/rc3.d/S32apache etc/rc.d/rc3.d/S40fcron etc/rc.d/rc3.d/S50openvpn-rw +etc/rc.d/rc3.d/S51openvpn-n2n etc/rc.d/rc3.d/S98rc.local etc/rc.d/rc3.d/S99grub-btrfsd #etc/rc.d/rc3.d/S99imspetor @@ -149,6 +152,7 @@ etc/rc.d/rc6.d/K01grub-btrfsd #etc/rc.d/rc6.d/K01vdradmin etc/rc.d/rc6.d/K08fcron etc/rc.d/rc6.d/K10openvpn-rw +etc/rc.d/rc6.d/K11openvpn-n2n etc/rc.d/rc6.d/K28apache etc/rc.d/rc6.d/K30sshd etc/rc.d/rc6.d/K47setclock diff --git a/lfs/initscripts b/lfs/initscripts index 4f0e915a6..89cfeb111 100644 --- a/lfs/initscripts +++ b/lfs/initscripts @@ -98,6 +98,7 @@ $(TARGET) : ln -sf ../init.d/fcron /etc/rc.d/rc0.d/K08fcron ln -sf ../init.d/apache /etc/rc.d/rc0.d/K28apache ln -sf ../init.d/openvpn-rw /etc/rc.d/rc0.d/K10openvpn-rw + ln -sf ../init.d/openvpn-n2n /etc/rc.d/rc0.d/K11openvpn-n2n ln -sf ../init.d/sshd /etc/rc.d/rc0.d/K30sshd ln -sf ../init.d/setclock /etc/rc.d/rc0.d/K47setclock ln -sf ../init.d/cyrus-sasl /etc/rc.d/rc0.d/K49cyrus-sasl @@ -132,6 +133,7 @@ $(TARGET) : ln -sf ../init.d/apache /etc/rc.d/rc3.d/S32apache ln -sf ../init.d/fcron /etc/rc.d/rc3.d/S40fcron ln -sf ../init.d/openvpn-rw /etc/rc.d/rc3.d/S50openvpn-rw + ln -sf ../init.d/openvpn-n2n /etc/rc.d/rc3.d/S51openvpn-n2n ln -sf ../../sysconfig/rc.local /etc/rc.d/rc3.d/S98rc.local ln -sf ../init.d/grub-btrfsd /etc/rc.d/rc3.d/S99grub-btrfsd ln -sf ../init.d/imspetor /etc/rc.d/rc3.d/S99imspetor @@ -144,6 +146,7 @@ $(TARGET) : ln -sf ../init.d/vdradmin /etc/rc.d/rc6.d/K01vdradmin ln -sf ../init.d/fcron /etc/rc.d/rc6.d/K08fcron ln -sf ../init.d/openvpn-rw /etc/rc.d/rc6.d/K10openvpn-rw + ln -sf ../init.d/openvpn-n2n /etc/rc.d/rc6.d/K11openvpn-n2n ln -sf ../init.d/apache /etc/rc.d/rc6.d/K28apache ln -sf ../init.d/sshd /etc/rc.d/rc6.d/K30sshd ln -sf ../init.d/setclock /etc/rc.d/rc6.d/K47setclock diff --git a/src/initscripts/system/openvpn-n2n b/src/initscripts/system/openvpn-n2n new file mode 100644 index 000000000..ee98078af --- /dev/null +++ b/src/initscripts/system/openvpn-n2n @@ -0,0 +1,333 @@ +#!/bin/sh +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007-2022 IPFire Team # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU 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 General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see . # +# # +############################################################################### + +. /etc/sysconfig/rc +. ${rc_functions} + +# Include network functions +. /etc/init.d/networking/functions.network + +update_firewall_rules() { + local id + local enabled + local name + local x3 + local type + local x5 + local x6 + local role + local x8 + local local_subnet + local x10 + local x11 + local x12 + local x13 + local x14 + local x15 + local x16 + local x17 + local x18 + local x19 + local x20 + local x21 + local x22 + local x23 + local x24 + local x25 + local x26 + local x27 + local transfer_subnet + local proto + local port + local rest + + local transfer_address + local local_address + + # Flush the block chain + iptables -F OVPNBLOCK + + # Flush the NAT chain + iptables -t nat -F OVPNNAT + + local IFS=',' + + # Read all connections + while read -r id enabled name x3 type x5 x6 role x8 local_subnet x10 \ + x11 x12 x13 x14 x15 x16 x17 x18 x19 x20 x21 x22 x23 x24 x25 \ + x26 x27 transfer_subnet proto port rest; do + # Skip all disabled connections + if [ "${enabled}" != "on" ]; then + continue + fi + + # Skip all connections that are not of type 'net' + if [ "${type}" != "net" ]; then + continue + fi + + # Open port + iptables -A OVPNINPUTN2N -p "${proto}" --dport "${port}" -j ACCEPT + + # Block all communication from transfer networks + iptables -A OVPNBLOCK -s "${transfer_subnet}" -j DROP + + # Calculate NAT addresses + transfer_address="$(calculate_transfer_address "${transfer_subnet}" "${role}")" + local_address="$(calculate_local_address "${local_subnet}")" + + # NAT all outgoing connections away from the transfer net + if [ -n "${transfer_address}" -a -n "${local_address}" ]; then + iptables -t nat -A OVPNNAT -s "${transfer_address}" \ + -j SNAT --to-source "${local_address}" + fi + done < /var/ipfire/ovpn/ovpnconfig +} + +calculate_transfer_address() { + local network="${1}" + local role="${2}" + + local address="$(network_get_address "${network}")" + local netmask="$(network_get_netmask "${network}")" + + # Convert everything to binary + address="$(ip2bin "${address}")" + netmask="$(ip2bin "${netmask}")" + + # Make sure the address is the first address of the network + (( address &= netmask )) + + case "${role}" in + server) + (( address += 1 )) + ;; + + client) + (( address += 2 )) + ;; + + # Exit on any invalid role + *) + return 1 + ;; + esac + + # Return the address + bin2ip "${address}" +} + +calculate_local_address() { + local network="${1}" + + local addresses=( + # GREEN + "${GREEN_ADDRESS}" + + # BLUE + "${BLUE_ADDRESS}" + + # ORANGE + "${ORANGE_ADDRESS}" + ) + + local address + for address in "${addresses[@]}"; do + if network_address_in_network "${address}" "${network}"; then + echo "${address}" + return 0 + fi + done + + return 1 +} + +all_connections() { + local command="${1}" + shift + + local id + local enabled + local name + local x3 + local type + local rest + + local IFS=, + + # Read all connections + while read -r id enabled name x3 type rest; do + # Filter for all connections that of type 'net' + case "${type}" in + net) + # Check if the connection is in the filter list + if [ $# -gt 0 ]; then + local found=0 + + local n + for n in $@; do + if [ "${name}" = "${n}" ]; then + found=1 + break + fi + done + + # Skip this connection if not found + if [ "${found}" -eq 0 ]; then + continue + fi + fi + + # Run the command + "${command}" "${name}" + ;; + esac + done < /var/ipfire/ovpn/ovpnconfig +} + +start_connections() { + local connection + local failed=0 + + for connection in $@; do + start "${connection}" || failed=1 + done + + return "${failed}" +} + +start() { + local name="${1}" + + local id + local enabled + local _name + local rest + + local IFS=, + + # Read the connection + while read -r id enabled _name rest; do + if [ "${name}" = "${_name}" ]; then + if [ "${enabled}" = "on" ]; then + break + + # Log an error if the connection is not enabled + else + boot_mesg "OpenVPN N2N connection '${name}' is not enabled" "${WARNING}" + echo_warning + + return 0 + fi + fi + done < /var/ipfire/ovpn/ovpnconfig + + # Create path to the configuration file + local config="/var/ipfire/ovpn/n2nconf/${name}/${name}.conf" + + # Check if the connection exists + if [ ! -r "${config}" ]; then + boot_mesg "OpenVPN N2N connection '${name}' does not exist" "${FAILURE}" + echo_failure + + return 1 + fi + + boot_mesg "Starting OpenVPN N2N connection '${name}'..." + + PIDFILE="/var/run/${name}n2n.pid" \ + loadproc /usr/sbin/openvpn --config "${config}" +} + +stop() { + local name="${1}" + + boot_mesg "Stopping OpenVPN N2N connection '${name}'..." + + PIDFILE="/var/run/${name}n2n.pid" \ + killproc /usr/sbin/openvpn +} + +reload() { + local name="${1}" + + boot_mesg "Reloading OpenVPN N2N connection '${name}'..." + + PIDFILE="/var/run/${name}n2n.pid" \ + reloadproc /usr/sbin/openvpn +} + +status() { + local name="${1}" + + local pidlist + + PIDFILE="/var/run/${name}n2n.pid" getpids "/usr/bin/openvpn" + + if [ -n "${pidlist}" ]; then + echo -e "${INFO}Connection '${name}' is running with Process ID(s) ${pidlist}.${NORMAL}" + else + echo -e "${INFO}Connection '${name}' is not running.${NORMAL}" + return 1 + fi +} + +case "${1}" in + start) + # Update all firewall rules + update_firewall_rules + + # Start all connections + all_connections start "${@:2}" + ;; + + stop) + # Update all firewall rules + update_firewall_rules + + # Stop all connections + all_connections stop "${@:2}" + ;; + + reload) + # Update all firewall rules + update_firewall_rules + + # Reload all connections + all_connections reload "${@:2}" + ;; + + restart) + ${0} stop + sleep 1 + ${0} start + ;; + + status) + # Show the status of all connections + all_connections status "${@:2}" + ;; + + *) + echo "Usage: ${0} {start|stop|reload|restart|status}" + exit 1 + ;; +esac -- 2.39.5