diff --git a/elfinder_install_update.sh b/elfinder_install_update.sh new file mode 100644 index 0000000000000000000000000000000000000000..69123e950ab3fdf512e6c650822a1a8b8fbf4502 --- /dev/null +++ b/elfinder_install_update.sh @@ -0,0 +1,401 @@ +#!/bin/bash +# Name: elfinder_install_update.sh +# Description: Setup or update elFinder File Manager in ISPConfig web server. +# Author: Hj Ahmad Rasyid bin Hj Ismail +# BSD 3 License +# Updated on 20230919-103405 +# Should work on systems that were installed according to HowToForge's Perfect Server guides for auto/manual install + + +## SETUP / UPDATE ELFINDER AS ISPCONFIG FILE MANAGER + +# Always start working from /tmp folder, so no messing up +cd /tmp + +# Define latest elfinder source url, get its version and tar.gz file +ef_github_url=https://api.github.com/repos/Studio-42/elFinder/releases/latest +ef_latest_ver=$(curl -s $ef_github_url | grep "tag_name*" | cut -d : -f 2,3 | cut -d '"' -f2) +ef_tar_gz=https://github.com/Studio-42/elFinder/archive/$ef_latest_ver.tar.gz +# Define elfinder main & temp (extract) dir & temp log file +ef_main_dir=/usr/share/elfinder +ef_temp_dir=/tmp/elfinder +ef_temp_log=$ef_main_dir/ef-temp.log + +# Function to download and extract latest elFinder +get_elfinder () { + # Create elfinder main and temp dir, if they don't exist + if [ ! -d "$ef_temp_dir" ]; then mkdir -p $ef_temp_dir; fi + if [ ! -d "$ef_main_dir" ]; then mkdir -p $ef_main_dir; fi + # Go to the temp extract dir, get latest elfinder & extract it + cd $ef_temp_dir && wget -q --show-progress $ef_tar_gz && tar -xzf $ef_latest_ver.tar.gz --strip-components=1 + # Make elfinder open full in browser + sed -i "/defaultOpts/a \\\t\t\t\t\twidth: '100%',\n\t\t\t\t\theight: '99.7%',\n\t\t\t\t\tresizable: false," elfinder.html + # index.html is web server default, so symlink is preferred + ln -sf elfinder.html index.html + cp php/connector.minimal.php-dist php/connector.minimal.php + rm $ef_latest_ver.tar.gz +} + +# Function to setup elFinder or update (overwrite) +set_elfinder () { + if [ -d $ef_temp_dir ]; then + cp -R $ef_temp_dir/* $ef_main_dir + if [ ! -z "$ef_json" ]; then + echo -e "\n"$ef_exist" "$ef_setup_ver"\n"$ef_outdated" "$ef_latest_ver"." | tee $ef_temp_log + else + echo -e "\n"$ef_none" "$ef_latest_ver"." | tee $ef_temp_log + fi + else + echo "\n"$ef_failed"" + fi +} + +# Define elFinder setup / update messages +ef_word="filemanager" +ef_exist="elFinder $ef_word setup exists with version" +ef_uptodate="It is up-to-date. Neither new setup nor update is needed." +ef_outdated="This old setup has been updated to latest version" +ef_none="We've setup latest elFinder as none existed i.e. version" +ef_failed="Failed to download and setup / download elFinder $ef_word." + +# Run elFinder setup / update here if it is not up-to-date +if [ -d "$ef_main_dir" ]; then + ef_json=$ef_main_dir/package.json + if [ -f "$ef_json" ]; then + ef_setup_ver=$(grep -i "version" $ef_json | cut -d : -f 2,3 | cut -d '"' -f2) + if [[ "$ef_setup_ver" == "$ef_latest_ver" ]]; then + # Existing elFinder is up-to-date + echo -e "\n"$ef_exist" "$ef_latest_ver".\n"$ef_uptodate"" | tee $ef_temp_log + else + get_elfinder + set_elfinder + fi + else + get_elfinder + set_elfinder + fi +else + get_elfinder + set_elfinder +fi + +# Define filemanager folder and its backup, backup if needed, then force create its symlink +ef_fm_dir=/usr/share/$ef_word +ef_fm_bak=/usr/share/$ef_wordbak-$(date +"%Y%m%d-%H%M%S") +if [ -d $ef_fm_dir ]; then + # Backup then force symlink if folder exist but not empty and also not a link + if [ ! -z $ef_fm_dir ] || [ ! -L $ef_fm_dir ]; then cp -R $ef_fm_dir $ef_fm_bak; fi + ln -sf $ef_main_dir $ef_fm_dir +else + ln -sf $ef_main_dir $ef_fm_dir +fi + + +## ADD CONFIGS IF THEY DON'T EXIST IN VHOST & CONF FILES + +# Define conf folders, cat dummy files and other messages +ispc_conf_dir=/usr/local/ispconfig/server/conf +ispc_custom_dir=/usr/local/ispconfig/server/conf-custom +ispc_install_dir=/usr/local/ispconfig/server/conf-custom/install +ef_temp_conf=ef-temp.conf +ef_exist="Not overwriting as string ($ef_word) exists in the" +ef_added="Added elFinder $ef_word config successfully in the" +ef_reload="has been successfully reloaded." +ef_failed="configuration test failed." +ef_manual="Please double check and manually fix the vhost file(s), if needed." +ef_browse="Your may now try browsing the elfinder file manager at \nhttps://$(hostname -f):" +ef_nosupport="You are not on a supported ISPConfig web server!" +ef_old_setup="Previous setup could have set this up BUT who knows!?" +ef_oops="Something is wrong!" + +# Function to create, copy & symlink custom conf dir, file and/or sub install dir +set_custom_conf () { + # Create conf-custom directory if it doesn't exist + if [ ! -d $ispc_custom_dir ]; then mkdir -p $ispc_custom_dir; fi + # Copy the specified .vhost / .conf file from conf to conf-custom, if it doesn't exist + if [ ! -f $ispc_custom_dir/$master_vhost ]; then + cp $ispc_conf_dir/$master_vhost $ispc_custom_dir/ + # Check conf-custom/install directory + if [ ! -d $isp_cust_inst_dir ]; then + # Force symlink to install directory, if it doesn't exist + ln -sf $ispc_custom_dir $isp_cust_inst_dir + else + # Force symlink apps file from custom-conf to install directory + ln -sf $ispc_custom_dir/$master_vhost $isp_cust_inst_dir/ + fi + fi +} + +# Function to create nginx config +set_nginx_conf () { + cat <<"EOT" > $ef_temp_conf + + + ## ELFINDER FILE MANAGER CONFIG STARTS ## + + location /filemanager { + root /usr/share/; + index index.php index.html index.htm; + location ~ ^/filemanager/(.+\.php)$ { + try_files $uri =404; + root /usr/share/; + include /etc/nginx/fastcgi_params; + + # To access filemanager, create ftp users in ISPConfig UI + {use_tcp}fastcgi_pass 127.0.0.1:9000; + {use_socket}fastcgi_pass unix:{fpm_socket}; + fastcgi_index index.php; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_buffer_size 128k; + fastcgi_buffers 256 4k; + fastcgi_busy_buffers_size 256k; + fastcgi_temp_file_write_size 256k; + fastcgi_read_timeout 1200; + } + location ~* ^/filemanager/(.+\.(ogg|ogv|svg|svgz|eot|ttf|otf|woff|woff2|mp4|mp3|ttf|css|rss|atom|js|jpg|jpeg|gif|png|ico|html|xml|txt|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)(\?ver=[0-9.]+)?$) { + root /usr/share/; + access_log off; + log_not_found off; + expires max; + } + } + location /file { + rewrite ^/* /filemanager last; + } + + ## ELFINDER FILE MANAGER CONFIG STARTS ## + + +EOT +} + +# Function to add config in the custom-conf master file +add_master_conf () { + if grep -q $ef_word $master_vhost; then + echo -e "\n"$ef_exist" "$master_vhost" file.\n"$ef_old_setup"\n"$ef_manual"" + else + # First modify the conf vhost file and report result + sed -i "/$sm_search/e cat "$ef_temp_conf"" $master_vhost + if grep -q $ef_word $master_vhost; then echo -e "\n"$ef_added" "$master_vhost" file."; else echo -e "\n"$ef_oops" "$ef_manual"" && exit; fi + fi +} + +# Function to add config in the custom-conf target file +add_target_conf () { + # Then search for filemanager in the vhost / conf file, before we proceed further + if grep -q $ef_word $target_vhost; then + echo -e "\n"$ef_exist" "$target_base" file.\n"$ef_old_setup"\n"$ef_manual"\n" + # Finally, if it is safe, modify the vhost / conf file, with some edits for it to work + else + # Change for nginx only output to dev null + sed -i 's/{use_tcp}/#/g' $ef_temp_conf >/dev/null 2>&1 + phpfpm="\t\t\tfastcgi_pass unix:/var/lib/php$(php -v | head -n 1 | cut -d ' ' -f 2 | cut -f1-2 -d'.')-fpm/apps.sock" + sed -i "/{fpm_socket}/c\\"$phpfpm";" $ef_temp_conf >/dev/null 2>&1 + + # Change for both nginx and apache + sed -i "/$sm_search/e cat "$ef_temp_conf"" $target_vhost + if grep -q $ef_word $target_vhost; then echo -e "\n"$ef_added" "$target_base" file.\n"; else echo -e "\n"$ef_oops" "$ef_manual"\n" && exit; fi + fi + + # All modifications are done. Remove the unneeded files + rm -rf $ef_temp_conf $ef_temp_log $ef_temp_dir +} + +# Nginx write to custom and apps vhost files function +write_nginx_vhost () { + # Define nginx master & target files & edit string + master_vhost=nginx_apps.vhost.master + target_vhost=/etc/nginx/sites-available/apps.vhost + target_base=$(basename $target_vhost) + ef_port=$(grep -i "\*:" $target_vhost | cut -d : -f 2,3 | cut -d " " -f1) + sm_search="location \/squirrelmail" + + # Run custom conf function + set_custom_conf + + if [ -f $ispc_custom_dir/$master_vhost ]; then + # Go to the conf-custom folder + cd $ispc_custom_dir + + set_nginx_conf + add_master_conf + add_target_conf + + # Reload nginx if all good and report result + if nginx -t 2>/dev/null; then + systemctl reload nginx + echo -e "Nginx "$ef_reload"\n\n"$ef_browse""$ef_port"/$ef_word\n" + else + echo -e "Nginx "$ef_failed"\n\n"$ef_manual"\n" + fi + fi + +} + +# Function to create nginx config +set_apache_conf () { + tee $ef_temp_conf >/dev/null << END + +## ELFINDER FILE MANAGER ## + + + + Require all granted + + Order allow,deny + Allow from all + + + + +END +} + +# Function to create apache config 2 +set_apache_vhost () { + tee $ef_temp_conf >/dev/null << END + +## ELFINDER FILE MANAGER ## + + + Require all granted + + + +END +} + +# Function to download and extract latest elFinder +set_elfinder_conf () { + # Create basic filemanager config.file + ef_avail_dir=/etc/apache2/conf-available + ef_enabl_dir=/etc/apache2/conf-enabled + ef_fm_conf=$ef_word.conf + tee $ef_avail_dir/$ef_fm_conf >/dev/null << END +# elFinder default Apache configuration + +Alias /filemanager /usr/share/filemanager + + + Options FollowSymLinks + DirectoryIndex index.html + + AllowOverride All + + = 2.3> + Require all granted + + + + Order allow,deny + Allow from all + + + # Clear PHP settings of this website + # + # SetHandler None + # + + Require all granted + + + + + + + SetHandler php-fcgi + + + + + + + + SetHandler php-fcgi + + + + + Action php-fcgi /php-fcgi virtual + + + + + Header set Content-Security-Policy "script-src 'self' https://cdnjs.cloudflare.com/" + Header set Content-Security-Policy "img-src 'self'" + + + + AddType application/x-httpd-php .php + php_flag magic_quotes_gpc Off + php_flag track_vars On + php_flag register_globals Off + php_value include_path . + + + + + + SSLStaplingCache shmcb:/var/run/ocsp(128000) + +END + + if [ ! -f $ef_enabl_dir/$ef_fm_conf ]; then a2enconf $ef_word; fi +} + +# Apache write to custom and ispconfig vhost files function +write_apache_vhost () { + # Define custom and ispconfig vhost files + master_vhost=apache_ispconfig.conf.master + target_vhost=/etc/apache2/sites-available/ispconfig.conf + target_base=$(basename $target_vhost) + ef_port=$(grep -i "\*:" $target_vhost | cut -d : -f 2,3 | cut -d " " -f1) + sm_search="\/squirrelmail" + + # Run custom conf function + set_custom_conf + + if [ -f $ispc_custom_dir/$master_vhost ]; then + # Go to the conf-custom folder + cd $ispc_custom_dir + + set_apache_conf + add_master_conf + set_apache_vhost + add_target_conf + set_elfinder_conf + + # Reload apache2 if all good and report result + ispcvhost=/etc/apache2/sites-available/ispconfig.vhost + ef_port=$(grep -i "\*:" $ispcvhost | cut -d : -f 2,3 | cut -d " " -f1) + if AOUTPUT=$(/usr/sbin/apache2ctl -t 2>&1); then + systemctl reload apache2 + echo -e "Apache2 "$ef_reload"\n\n"$ef_browse""$ef_port"/$ef_word\n" + else + echo -e "Apache2 "$ef_failed"\n\n"$ef_manual"\n" + fi + fi +} + + +# For Debian, Ubuntu & derivatives +if apt-get -v >/dev/null 2>&1; then + # If web server is nginx, check and modify apps vhost accordingly + if [ $(dpkg-query -W -f='${Status}' nginx 2>/dev/null | grep -c "ok installed") -eq 1 ]; then + write_nginx_vhost + # If web server is apache2, check and modify ispconfig vhost accordingly + elif [ $(dpkg-query -W -f='${Status}' apache2 2>/dev/null | grep -c "ok installed") -eq 1 ]; then + write_apache_vhost + fi +# For Red Hat, Centos & derivatives +elif which yum &> /dev/null 2>&1; then + # If web server is nginx, check and modify apps vhost accordingly + if ( rpm -q nginx ); then + write_nginx_vhost + # If web server is apache2, check and modify ispconfig vhost accordingly + elif ( rpm -q httpd ); then + write_apache_vhost + fi +else + echo $ef_nosupport +fi