-#!/usr/bin/perl
+#!/bin/bash
###############################################################################
# #
# IPFire.org - A linux based firewall #
-# Copyright (C) 2007-2014 IPFire Team <info@ipfire.org> #
+# Copyright (C) 2007-2022 IPFire Team <info@ipfire.org> #
# #
# 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 #
# #
###############################################################################
-require '/var/ipfire/general-functions.pl';
-require "${General::swroot}/lang.pl";
-require "${General::swroot}/header.pl";
-use File::Path;
-my $debug = 1;
-my @include = "";
-my ($Sekunden, $Minuten, $Stunden, $Monatstag, $Monat, $Jahr, $Wochentag, $Jahrestag, $Sommerzeit) = localtime(time);
-$Jahr = $Jahr + 1900;$Monat = $Monat + 1;
-$Monat = sprintf("%02d", $Monat);
-$Monatstag = sprintf("%02d", $Monatstag);
-$Stunden = sprintf("%02d", $Stunden);
-$Minuten = sprintf("%02d", $Minuten);
-
-if (($ARGV[0] eq 'include') || ($ARGV[0] eq 'iso')) {
- &createinclude;
- my @files = `find / -name *.log* 2>/dev/null`;
- foreach (@files){
- push(@include,$_);
- }
- my @files = `find /var/log/ -name *messages* 2>/dev/null`;
- foreach (@files){
- push(@include,$_);
- }
- open(DATEI, ">/tmp/include") || die "Could not save temp include file";
- print DATEI @include;
- print "/var/log/messages";
- close(DATEI);
- system("tar -cvzf /var/ipfire/backup/$Jahr$Monat$Monatstag-$Stunden$Minuten.ipf --files-from='/tmp/include' --exclude-from='/var/ipfire/backup/exclude' --files-from='/var/ipfire/backup/include.user' --exclude-from='/var/ipfire/backup/exclude.user'");
- system("rm /tmp/include");
- if ($ARGV[0] eq 'iso') {
- system("/usr/local/bin/backupiso $Jahr$Monat$Monatstag-$Stunden$Minuten &");
- }
-}
-elsif ($ARGV[0] eq 'exclude') {
- &createinclude;
- open(DATEI, ">/tmp/include") || die "Could not save temp include file";
- print DATEI @include;
- close(DATEI);
- system("tar -cvzf /var/ipfire/backup/$Jahr$Monat$Monatstag-$Stunden$Minuten.ipf --files-from='/tmp/include' --exclude-from='/var/ipfire/backup/exclude' --files-from='/var/ipfire/backup/include.user' --exclude-from='/var/ipfire/backup/exclude.user'");
- system("rm /tmp/include");
-}
-elsif ($ARGV[0] eq 'restore') {
- system("cd / && tar -xvz -p -f /tmp/restore.ipf");
- #Here some converter scripts to correct old Backups (before core 65)
- system("/usr/sbin/ovpn-ccd-convert");
- #OUTGOINGFW CONVERTER
- if( -d "${General::swroot}/outgoing"){
- if( -f "${General::swroot}/firewall/config" ){
- unlink("${General::swroot}/firewall/config");
- system("touch ${General::swroot}/firewall/config");
- chown 99,99,"${General::swroot}/firewall/config";
- }
- if( -f "${General::swroot}/firewall/outgoing" ){
- unlink("${General::swroot}/firewall/outgoing");
- system("touch ${General::swroot}/firewall/outgoing");
- chown 99,99,"${General::swroot}/firewall/outgoing";
- }
- unlink("${General::swroot}/fwhosts/customgroups");
- unlink("${General::swroot}/fwhosts/customhosts");
- unlink("${General::swroot}/fwhosts/customgroups");
- unlink("${General::swroot}/fwhosts/customnetworks");
- unlink("${General::swroot}/fwhosts/customservicegrp");
- unlink("${General::swroot}/fwhosts/customnetworks");
- system("touch ${General::swroot}/fwhosts/customgroups");
- system("touch ${General::swroot}/fwhosts/customhosts");
- system("touch ${General::swroot}/fwhosts/customnetworks");
- system("touch ${General::swroot}/fwhosts/customservicegrp");
- #START CONVERTER "OUTGOINGFW"
- system("/usr/sbin/convert-outgoingfw");
- chown 99,99,"${General::swroot}/fwhosts/customgroups";
- chown 99,99,"${General::swroot}/fwhosts/customhosts";
- chown 99,99,"${General::swroot}/fwhosts/customnetworks";
- chown 99,99,"${General::swroot}/fwhosts/customservicegrp";
- #START CONVERTER "OUTGOINGFW"
- rmtree("${General::swroot}/outgoing");
- }
- #XTACCESS CONVERTER
- if( -d "${General::swroot}/xtaccess"){
- if( -f "${General::swroot}/firewall/input" ){
- unlink("${General::swroot}/firewall/input");
- system("touch ${General::swroot}/firewall/input");
- }
- #START CONVERTER "XTACCESS"
- system("/usr/sbin/convert-xtaccess");
- chown 99,99,"${General::swroot}/firewall/input";
- rmtree("${General::swroot}/xtaccess");
- }
- #DMZ-HOLES CONVERTER
- if( -d "${General::swroot}/dmzholes" || -d "${General::swroot}/portfw"){
- if( -f "${General::swroot}/firewall/config" ){
- unlink("${General::swroot}/firewall/config");
- system("touch ${General::swroot}/firewall/config");
- }
- #START CONVERTER "DMZ-HOLES"
- system("/usr/sbin/convert-dmz");
- chown 99,99,"${General::swroot}/firewall/config";
- rmtree("${General::swroot}/dmzholes");
- }
- #PORTFORWARD CONVERTER
- if( -d "${General::swroot}/portfw"){
- #START CONVERTER "PORTFW"
- system("/usr/sbin/convert-portfw");
- rmtree("${General::swroot}/portfw");
- }
- system("/usr/local/bin/firewallctrl");
-
- # Convert old OpenVPN CCD files (CN change, core 75).
- system("/usr/local/bin/convert-ovpn");
-}
-elsif ($ARGV[0] eq 'restoreaddon') {
- if ( -e "/tmp/$ARGV[1]" ){system("mv /tmp/$ARGV[1] /var/ipfire/backup/addons/backup/$ARGV[1]");}
- system("cd / && tar -xvz -p -f /var/ipfire/backup/addons/backup/$ARGV[1]");
+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
}
-elsif ($ARGV[0] eq 'cli') {
- system("tar -cvzf /var/ipfire/backup/$Jahr$Monat$Monatstag-$Stunden$Minuten-$ARGV[1].ipf --files-from='$ARGV[2]' --exclude-from='$ARGV[3]'");
+
+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
}
-elsif ($ARGV[0] eq 'addonbackup') {
- system("tar -cvzf /var/ipfire/backup/addons/backup/$ARGV[1].ipf --files-from='/var/ipfire/backup/addons/includes/$ARGV[1]'");
+
+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
}
-elsif ($ARGV[0] =~ /ipf$/ ) {
- system("rm /var/ipfire/backup/$ARGV[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"; 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
}
-elsif ($ARGV[0] =~ /iso$/ ) {
- system("rm /var/tmp/backupiso/$ARGV[0]");
+
+find_logfiles() {
+ local filelist=( /var/log/logwatch/* /var/log/messages* /var/log/*.log /var/log/**/*.log )
+
+ echo "${filelist[@]}"
}
-elsif ($ARGV[0] eq '') {
- printf "No argument given, please use <include><exclude><cli>\n"
+
+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}")
}
-elsif ($ARGV[0] eq 'makedirs') {
- system("mkdir -p /var/ipfire/backup/addons");
- system("mkdir -p /var/ipfire/backup/addons/backup");
- system("mkdir -p /var/ipfire/backup/addons/includes");
+
+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
}
-sub createinclude(){
-
- open(DATEI, "<${General::swroot}/backup/include") || die "Can not open include file";
- my @Zeilen = <DATEI>;
- close(DATEI);
-
- foreach (@Zeilen){
- chomp($_);
- my @files = `find $_ -maxdepth 0 2>/dev/null`;
- foreach (@files){
- push(@include,$_);
- }
- }
+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 <addon>|restoreaddon <addon>|iso]" >&2
+ return 2
+ ;;
+ esac
+
+ return $?
}
+
+main "$@" || exit $?