#!/bin/bash ############################################################################### # # # IPFire.org - A linux based firewall # # Copyright (C) 2007-2024 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 . # # # ############################################################################### shopt -s nullglob NOW="$(date "+%Y-%m-%d-%H%M")" list_addons() { local file for file in /var/ipfire/backup/addons/includes/*; do if [ -f "${file}" ]; then basename "${file}" fi done return 0 } process_includes() { local include for include in $@; do local file while read -r file; do # Skip any empty line (which will include /) [ -n "${file}" ] || continue for file in /${file}; do if [ -e "${file}" ]; then echo "${file}" fi done done < "${include}" done | sort -u } make_backup() { local filename="${1}" shift # Backup all addons first local addon for addon in $(list_addons); do make_addon_backup "${addon}" done # Backup using global exclude/include definitions tar cvfz "${filename}" -C / \ --exclude-from="/var/ipfire/backup/exclude" \ --exclude-from="/var/ipfire/backup/exclude.user" \ $(process_includes "/var/ipfire/backup/include") \ $(process_includes "/var/ipfire/backup/include.user") \ "$@" return 0 } restore_backup() { local filename="${1}" # remove all openvpn certs to prevent old unusable # certificates being left in directory after a restore rm -f /var/ipfire/ovpn/certs/* # Extract backup if ! tar xvzpf "${filename}" -C / \ --exclude-from="/var/ipfire/backup/exclude" \ --exclude-from="/var/ipfire/backup/exclude.user" \ --force-local; then echo "Could not extract backup" >&2 return 1 fi # Restart syslogd, httpd and suricata in case we've just loaded old logs apachectl -k graceful /bin/kill -HUP `cat /var/run/suricata.pid 2> /dev/null` 2> /dev/null /bin/kill -HUP `cat /var/run/syslogd.pid 2> /dev/null` 2> /dev/null # remove wrong vnstat tag file rm -f /var/log/vnstat/tag # create dhcpcd user groupadd -g 52 dhcpcd useradd -c 'dhcpcd privsep user' \ -d /run/dhcpcd/chroot \ -g dhcpcd \ -s /bin/false \ -u 52 dhcpcd # Run converters # Outgoing Firewall if [ -d "/var/ipfire/outgoing" ]; then # Reset files local file for file in /var/ipfire/firewall/{config,outgoing} \ /var/ipfire/fwhosts/custom{hosts,groups,networks}; do : > "${file}" chown nobody:nobody "${file}" done # Run converter convert-outgoingfw # Remove old configuration rm -rf "/var/ipfire/outgoing" fi # External Access if [ -d "/var/ipfire/xtaccess" ]; then : > /var/ipfire/firewall/config chown nobody:nobody "/var/ipfire/firewall/config" # Run converter convert-xtaccess # Remove old configuration rm -rf "/var/ipfire/xtaccess" fi # DMZ Holes if [ -d "/var/ipfire/dmzholes" ] || [ -d "/var/ipfire/portfw" ]; then : > /var/ipfire/firewall/config chown nobody:nobody "/var/ipfire/firewall/config" # Run converter convert-dmz # Remove old configuration rm -rf "/var/ipfire/dmzholes" fi # Port Forwardings if [ -d "/var/ipfire/portfw" ]; then # Run converter convert-portfw # Remove old configuration rm -rf "/var/ipfire/portfw" fi # Convert location convert-to-location # Reload firewall firewallctrl # Snort to suricata converter. if [ -d "/var/ipfire/snort" ]; then # Run converter convert-snort # Remove old configuration directory. rm -rf "/var/ipfire/snort" fi # IDS multiple providers converter. if [ -e "/var/ipfire/suricata/rules-settings" ]; then # Run the converter convert-ids-multiple-providers fi # IDS backend converter. if [ -e "/var/ipfire/suricata/oinkmaster.conf" ]; then # Run the converter convert-ids-backend-files fi # Convert DNS settings convert-dns-settings # move nobeeps if exist [ -e "/var/ipfire/ppp/nobeeps" ] && mv /var/ipfire/ppp/nobeeps /var/ipfire/red/nobeeps # Replace previously used OpenVPN Diffie-Hellman parameter by ffdhe4096 sed -i 's|/var/ipfire/ovpn/ca/dh1024.pem|/etc/ssl/ffdhe4096.pem|' /var/ipfire/ovpn/server.conf /var/ipfire/ovpn/n2nconf/*/*.conf # Update OpenVPN CRL /etc/fcron.daily/openvpn-crl-updater # Update OpenVPN N2N Client Configs ## Add providers legacy default line to n2n client config files # Check if ovpnconfig exists and is not empty if [ -s /var/ipfire/ovpn/ovpnconfig ]; then # Identify all n2n connections for y in $(awk -F',' '/net/ { print $3 }' /var/ipfire/ovpn/ovpnconfig); do # Add the legacy option to all N2N client conf files if it does not already exist if [ $(grep -c "Open VPN Client Config" /var/ipfire/ovpn/n2nconf/${y}/${y}.conf) -eq 1 ] ; then if [ $(grep -c "providers legacy default" /var/ipfire/ovpn/n2nconf/${y}/${y}.conf) -eq 0 ] ; then echo "providers legacy default" >> /var/ipfire/ovpn/n2nconf/${y}/${y}.conf fi fi done fi #Update ovpnconfig to include pass or no-pass for old backup versions missing the entry # Check if ovpnconfig exists and is not empty if [ -s /var/ipfire/ovpn/ovpnconfig ]; then # Add blank line at top of ovpnconfig otherwise the first roadwarrior entry is treated like a blank line and missed out from update awk 'NR==1{print ""}1' /var/ipfire/ovpn/ovpnconfig > /var/ipfire/ovpn/tmp_file && mv /var/ipfire/ovpn/tmp_file /var/ipfire/ovpn/ovpnconfig # Make all N2N connections 'no-pass' since they do not use encryption awk '{FS=OFS=","} {if($5=="net") {$43="no-pass"; print $0}}' /var/ipfire/ovpn/ovpnconfig >> /var/ipfire/ovpn/ovpnconfig.new # Evaluate roadwarrior connection names for *.p12 files for y in $(awk -F',' '/host/ { print $3 }' /var/ipfire/ovpn/ovpnconfig); do # Sort all unencrypted roadwarriors out and set 'no-pass' in [43] index if [[ -n $(openssl pkcs12 -info -in /var/ipfire/ovpn/certs/${y}.p12 -noout -password pass:'' 2>&1 | grep 'Encrypted data') ]]; then awk -v var="$y" '{FS=OFS=","} {if($3==var) {$43="no-pass"; print $0}}' /var/ipfire/ovpn/ovpnconfig >> /var/ipfire/ovpn/ovpnconfig.new fi # Sort all encrypted roadwarriors out and set 'pass' in [43] index if [[ -n $(openssl pkcs12 -info -in /var/ipfire/ovpn/certs/${y}.p12 -noout -password pass:'' 2>&1 | grep 'verify error') ]]; then awk -v var="$y" '{FS=OFS=","} {if($3==var) {$43="pass"; print $0}}' /var/ipfire/ovpn/ovpnconfig >> /var/ipfire/ovpn/ovpnconfig.new fi done fi # Replace existing ovpnconfig with updated index mv /var/ipfire/ovpn/ovpnconfig.new /var/ipfire/ovpn/ovpnconfig # Set correct ownership chown nobody:nobody /var/ipfire/ovpn/ovpnconfig # Generate new HTTPS RSA key if the existing is too small KEYSIZE=$(openssl rsa -in /etc/httpd/server.key -text -noout | sed -n 's/Private-Key:\ (\(.*\)\ bit.*/\1/p') if [ $KEYSIZE \< 2048 ]; then openssl genrsa -out /etc/httpd/server.key 4096 &>/dev/null chmod 600 /etc/httpd/server.key sed "s/HOSTNAME/`hostname -f`/" < /etc/certparams | \ openssl req -new -key /etc/httpd/server.key \ -out /etc/httpd/server.csr &>/dev/null openssl x509 -req -days 999999 -sha256 \ -in /etc/httpd/server.csr \ -signkey /etc/httpd/server.key \ -out /etc/httpd/server.crt &>/dev/null fi # Remove any entry for ALIENVAULT or SPAMHAUS_EDROP from the ipblocklist modified file # and the associated ipblocklist files from the /var/lib/ipblocklist directory sed -i '/ALIENVAULT=/d' /var/ipfire/ipblocklist/modified sed -i '/SPAMHAUS_EDROP=/d' /var/ipfire/ipblocklist/modified if [ -e /var/lib/ipblocklist/ALIENVAULT.conf ]; then rm /var/lib/ipblocklist/ALIENVAULT.conf fi if [ -e /var/lib/ipblocklist/SPAMHAUS_EDROP.conf ]; then rm /var/lib/ipblocklist/SPAMHAUS_EDROP.conf fi return 0 } find_logfiles() { local filelist=( /var/log/logwatch/* /var/log/messages* /var/log/*.log /var/log/**/*.log ) echo "${filelist[@]}" } make_addon_backup() { local name="${1}" shift if [ ! -f "/var/ipfire/backup/addons/includes/${name}" ]; then echo "${name} does not have any backup includes" >&2 return 1 fi local filename="/var/ipfire/backup/addons/backup/${name}.ipf" tar cvzf "${filename}" \ $(process_includes "/var/ipfire/backup/addons/includes/${name}") } restore_addon_backup() { local name="${1}" if [ -d "/tmp/${name}.ipf" ]; then mv "/tmp/${name}.ipf" "/var/ipfire/backup/addons/backup/${name}.ipf" fi # Extract backup if ! tar xvzpf "/var/ipfire/backup/addons/backup/${name}.ipf" -C /; then echo "Could not extract backup" >&2 return 1 fi } main() { local command="${1}" shift case "${command}" in include) local filename="${1}" if [ -z "${filename}" ]; then filename="/var/ipfire/backup/${NOW}.ipf" fi make_backup "${filename}" $(find_logfiles) ;; exclude) local filename="${1}" if [ -z "${filename}" ]; then filename="/var/ipfire/backup/${NOW}.ipf" fi make_backup "${filename}" ;; restore) local filename="${1}" if [ -z "${filename}" ]; then filename="/tmp/restore.ipf" fi restore_backup "${filename}" ;; addonbackup) make_addon_backup "$@" ;; restoreaddon) restore_addon_backup "${1/.ipf/}" ;; iso) # Desired backup filename local filename="/var/ipfire/backup/${NOW}.ipf" if make_backup "${filename}"; then /usr/local/bin/backupiso "${NOW}" fi ;; makedirs) mkdir -p /var/ipfire/backup/addons/{backup,includes} ;; list) process_includes "/var/ipfire/backup/include" "/var/ipfire/backup/include.user" ;; /var/ipfire/backup/*.ipf|/var/ipfire/backup/addons/backup/*.ipf|/var/tmp/backupiso/*.iso) unlink "${command}" ;; *) echo "${0}: [include|exclude|restore|addonbackup |restoreaddon |iso]" >&2 return 2 ;; esac return $? } main "$@" || exit $?