├── README.md ├── apache ├── README.md └── nginx-apache-fix-ips.sh ├── api ├── API_list.md └── README.md ├── core ├── README.md ├── update_evolution.sh └── updateda.sh ├── email ├── README.md ├── clear_majordomo_digest.sh └── transip_mail_domains.sh ├── hooks ├── README.md ├── hooks_post.md └── hooks_pre.md ├── letsencrypt ├── README.md ├── autoletsencrypt.sh ├── autoletsencrypt.sh.patch ├── autoletsencrypt_mail.sh ├── fix_le_caroot.sh ├── letsencrypt_poralix-1.0.18.patch ├── letsencrypt_poralix-1.0.8.patch ├── letsencrypt_poralix.patch ├── letsencrypt_poralix.sh └── poralix_patch_chain.sh ├── misc ├── README.md ├── da_domains.sh └── private_html_symlink.sh ├── nginx ├── README.md ├── build_nginx ├── build_nginx2 └── nginx_reverse │ ├── conf │ └── nginx-defaults.conf~TLSv1.3 │ ├── configure.nginx~openssl-1.1.1 │ └── configure.nginx~openssl-3.0.0 ├── openssl ├── README.md ├── openssl.install-1.0.1-primary.sh └── openssl.install-1.0.2-primary.sh ├── php ├── README.md ├── bulk_run_php.sh ├── change_domain_phpver.sh ├── php-extension.sh └── test_sockets_ssl.php ├── rspamd └── rspamd2-statistic-sqlite.conf ├── sftp ├── proftpd.conf └── proftpd.sftp.conf ├── ssl ├── README.md └── install_server_wide_cert.sh ├── webapps └── rainloop.install.sh └── webserver-errors ├── 400.shtml ├── 401.shtml ├── 403.shtml ├── 404.shtml ├── 500.shtml └── README.md /README.md: -------------------------------------------------------------------------------- 1 |

Directadmin

2 | 3 | # directadmin-utils 4 | 5 | A set of scripts for using on Directadmin servers with CustomBuild 2 or as self-standing solutions. 6 | If you need custom installation or support please feel free to request it here or on our site https://www.poralix.com/ 7 | 8 | # Structure 9 | 10 | **./nginx/build_nginx** - A script to install either stable or mainline version of NGINX with custombuild2. 11 | 12 | - A version number of NGINX mainline is taken from NGINX's trac site. 13 | - A version number of NGINX stable is taken from the official NGINX's repository for CentOS 7 14 | 15 | **./nginx/build_nginx2** - A script to install a mainline version of NGINX with custombuild2. 16 | A version number of NGINX mainline is taken from versions.txt of Directadmin. 17 | 18 | # Installation of script for NGINX mainline 19 | 20 | for version 1: 21 | 22 | ``` 23 | cd /usr/local/directadmin/custombuild/ 24 | wget https://raw.githubusercontent.com/poralix/directadmin-utils/master/nginx/build_nginx -O /usr/local/directadmin/custombuild/build_nginx 25 | chmod 755 ./build_nginx 26 | ./build_nginx 27 | ``` 28 | 29 | for version 2: 30 | 31 | ``` 32 | cd /usr/local/directadmin/custombuild/ 33 | wget https://raw.githubusercontent.com/poralix/directadmin-utils/master/nginx/build_nginx2 -O /usr/local/directadmin/custombuild/build_nginx2 34 | chmod 755 ./build_nginx2 35 | ./build_nginx2 36 | ``` 37 | 38 | # NGINX 1.13.x with TLSv1.3 and Directadmin 39 | 40 | Instructions: https://help.poralix.com/articles/nginx-with-tlsv1.3-on-directadmin-server 41 | 42 | # Update Directadmin from beta / stable channel per needs 43 | 44 | ./core/updateda.sh 45 | 46 | ``` 47 | cd /root/ 48 | wget https://raw.githubusercontent.com/poralix/directadmin-utils/master/core/updateda.sh 49 | chmod 755 updateda.sh 50 | ./updateda.sh beta 51 | ``` 52 | -------------------------------------------------------------------------------- /apache/README.md: -------------------------------------------------------------------------------- 1 | # Script nginx-apache-fix-ips.sh: 2 | 3 | A script to add all IPs from Directadmin config into Apache 4 | to address a bug with detecting a real IP in Apache behind Nginx 5 | A bug introduced since Apache 2.4.33. It fails to read IPs from the file, as per instruction: 6 | 7 | ``` 8 | RemoteIPInternalProxyList /usr/local/directadmin/data/admin/ip.list 9 | ``` 10 | 11 | # Installation guide: 12 | 13 | ``` 14 | cd ~ 15 | wget -O nginx-apache-fix-ips.sh https://raw.githubusercontent.com/poralix/directadmin-utils/master/apache/nginx-apache-fix-ips.sh 16 | chmod 755 nginx-apache-fix-ips.sh 17 | ./nginx-apache-fix-ips.sh 18 | ``` 19 | -------------------------------------------------------------------------------- /apache/nginx-apache-fix-ips.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # ======================================================================== 3 | # 4 | # A script to add all IPs from Directadmin config into Apache 5 | # to address a bug with detecting a real IP in Apache behind Nginx 6 | # A bug introduced since Apache 2.4.33 7 | # It fails to read IPs from the file, as per instruction: 8 | # RemoteIPInternalProxyList /usr/local/directadmin/data/admin/ip.list 9 | # 10 | # ======================================================================== 11 | # Written by Alex S Grebenschikov # poralix.com (support@poralix.com) 12 | # Created: Mon Mar 26 14:43:17 +07 2018 13 | # Last modified: Mon Mar 26 14:43:17 +07 2018 14 | # 15 | 16 | RESTART_APACHE=0; 17 | 18 | add_ip() 19 | { 20 | local IP=$1; 21 | egrep -q "^RemoteIPInternalProxy.*${IP}(|\ )$" "/etc/httpd/conf/extra/httpd-nginx.conf"; 22 | if [ "$?" -ne "0" ]; 23 | then 24 | RESTART_APACHE=1; 25 | echo "[OK] Adding IP ${IP} into Apache's config"; 26 | echo "RemoteIPInternalProxy ${IP}" >> "/etc/httpd/conf/extra/httpd-nginx.conf"; 27 | else 28 | echo "[NOTICE] IP ${IP} already exists in Apache's config. Skipping..."; 29 | fi; 30 | } 31 | 32 | if [ ! -e "/etc/httpd/conf/extra/httpd-nginx.conf" ]; then 33 | echo "Do you realy use NGINX-Apache?"; 34 | exit 1; 35 | fi; 36 | 37 | if [ ! -e "/usr/local/directadmin/data/admin/ip.list" ]; then 38 | echo "Is that really a server with Directadmin?"; 39 | exit 2; 40 | fi; 41 | 42 | for IP in `cat /usr/local/directadmin/data/admin/ip.list | sort | uniq`; 43 | do 44 | add_ip ${IP}; 45 | done; 46 | 47 | [ "${RESTART_APACHE}" == "1" ] && service httpd restart; 48 | 49 | exit 0; 50 | -------------------------------------------------------------------------------- /api/API_list.md: -------------------------------------------------------------------------------- 1 | - CMD_API_ACCOUNT_ADMIN 2 | - CMD_API_ACCOUNT_RESELLER 3 | - CMD_API_ACCOUNT_USER 4 | - CMD_API_ADDITIONAL_DOMAINS 5 | - CMD_API_ADMIN_BACKUP 6 | - CMD_API_ADMIN_BACKUP_MODIFY 7 | - CMD_API_ADMIN_FILE_EDITOR 8 | - CMD_API_ADMIN_STATS 9 | - CMD_API_ALL_USER_USAGE 10 | - CMD_API_BANDWIDTH_BREAKDOWN 11 | - CMD_API_BRUTE_FORCE_MONITOR 12 | - CMD_API_CHANGE_DOMAIN 13 | - CMD_API_CHANGE_EMAIL_PASSWORD 14 | - CMD_API_CHANGE_FTP_PASSWORD 15 | - CMD_API_CHANGE_INFO 16 | - CMD_API_COMMENTS 17 | - CMD_API_CRON_JOBS 18 | - CMD_API_CUSTOM_HTTPD 19 | - CMD_API_DATABASES 20 | - CMD_API_DB_USER 21 | - CMD_API_DB_USER_PRIVS 22 | - CMD_API_DIRECTADMIN_CONF 23 | - CMD_API_DNS_ADMIN 24 | - CMD_API_DNS_ADMIN?domain= 25 | - CMD_API_DNS_CONTROL 26 | - CMD_API_DNS_MX 27 | - CMD_API_DOMAIN 28 | - CMD_API_DOMAIN_OWNERS 29 | - CMD_API_DOMAIN_POINTER 30 | - CMD_API_DU_BREAKDOWN 31 | - CMD_API_EDIT_USER_MESSAGE 32 | - CMD_API_EMAIL_ACCOUNT_QUOTA 33 | - CMD_API_EMAIL_ACCOUNT_VACATION 34 | - CMD_API_EMAIL_AUTH 35 | - CMD_API_EMAIL_AUTORESPONDER 36 | - CMD_API_EMAIL_AUTORESPONDER_CREATE 37 | - CMD_API_EMAIL_AUTORESPONDER_MODIFY 38 | - CMD_API_EMAIL_CATCH_ALL 39 | - CMD_API_EMAIL_FILTER 40 | - CMD_API_EMAIL_FORWARDER 41 | - CMD_API_EMAIL_FORWARDERS 42 | - CMD_API_EMAIL_LIST 43 | - CMD_API_EMAIL_POP 44 | - CMD_API_EMAIL_USAGE 45 | - CMD_API_EMAIL_VACATION 46 | - CMD_API_EMAIL_VACATION_MODIFY 47 | - CMD_API_EXEC 48 | - CMD_API_FILE_MANAGER 49 | - CMD_API_FRONTPAGE 50 | - CMD_API_FTP 51 | - CMD_API_FTP_SETTINGS 52 | - CMD_API_FTP_SHOW 53 | - CMD_API_GET_SESSION 54 | - CMD_API_HANDLERS 55 | - CMD_API_IP_CONFIG 56 | - CMD_API_IP_MANAGER 57 | - CMD_API_IP_MANAGER_DETAILS 58 | - CMD_API_LICENSE 59 | - CMD_API_LOAD_AVERAGE 60 | - CMD_API_LOGIN_KEYS 61 | - CMD_API_LOGIN_TEST 62 | - CMD_API_MAIL_QUEUE 63 | - CMD_API_MANAGE_RESELLER_PACKAGES 64 | - CMD_API_MANAGE_USER_PACKAGES 65 | - CMD_API_MODIFY_RESELLER 66 | - CMD_API_MODIFY_USER 67 | - CMD_API_MOVE_USERS 68 | - CMD_API_MULTI_SERVER 69 | - CMD_API_NAME_SERVER 70 | - CMD_API_NGINX_TEMPLATES 71 | - CMD_API_NGINX_TEMPLATES_ADMIN 72 | - CMD_API_OWNERS_OWNER 73 | - CMD_API_PACKAGES_RESELLER 74 | - CMD_API_PACKAGES_USER 75 | - CMD_API_PASSWD 76 | - CMD_API_PERL_MODULES 77 | - CMD_API_PHP_SAFE_MODE 78 | - CMD_API_PLUGINS_ADMIN 79 | - CMD_API_POP 80 | - CMD_API_PROCESS_MONITOR 81 | - CMD_API_PROTECTED_DIRECTORIES 82 | - CMD_API_PUBLIC_STATS 83 | - CMD_API_REBOOT 84 | - CMD_API_REDIRECT 85 | - CMD_API_RESELLER_HISTORY 86 | - CMD_API_RESELLER_STATS 87 | - CMD_API_RESEND_EMAIL 88 | - CMD_API_SECURITY_QUESTIONS 89 | - CMD_API_SELECT_USERS 90 | - CMD_API_SERVICE 91 | - CMD_API_SHOW_ADMINS 92 | - CMD_API_SHOW_ALL_USERS 93 | - CMD_API_SHOW_DOMAINS 94 | - CMD_API_SHOW_RESELLER_IPS 95 | - CMD_API_SHOW_RESELLERS 96 | - CMD_API_SHOW_SERVICES 97 | - CMD_API_SHOW_USER_CONFIG 98 | - CMD_API_SHOW_USER_DOMAINS 99 | - CMD_API_SHOW_USERS 100 | - CMD_API_SHOW_USER_USAGE 101 | - CMD_API_SITE_BACKUP 102 | - CMD_API_SKINS 103 | - CMD_API_SPAMASSASSIN 104 | - CMD_API_SSH_KEYS 105 | - CMD_API_SSL 106 | - CMD_API_SUBDOMAIN 107 | - CMD_API_SUBDOMAIN_BANDWIDTH 108 | - CMD_API_SUBDOMAINS 109 | - CMD_API_SYSTEM_INFO 110 | - CMD_API_TEMPLATE_DIFF 111 | - CMD_API_TICKET 112 | - CMD_API_TICKET_CREATE 113 | - CMD_API_TICKET_MANAGE 114 | - CMD_API_TWOSTEP_AUTH 115 | - CMD_API_USER_BACKUP 116 | - CMD_API_USER_BACKUP_MODIFY 117 | - CMD_API_USER_EXISTS 118 | - CMD_API_USER_HISTORY 119 | - CMD_API_USER_PASSWD 120 | - CMD_API_VERIFY_PASSWORD 121 | -------------------------------------------------------------------------------- /api/README.md: -------------------------------------------------------------------------------- 1 | # Directadmin API 2 | 3 | In computer programming, an application programming interface (API) is a set of subroutine definitions, 4 | communication protocols, and tools for building software. In general terms, it is a set of clearly 5 | defined methods of communication among various components. 6 | 7 | DirectAdmin support API and here you can find a full list of API commands: 8 | 9 | - [List of DirectAdmin API commands](API_list.md) 10 | 11 | # Additional information 12 | 13 | - [DirectAdmin API: Integrate your product with DirectAdmin](https://www.directadmin.com/api.html) 14 | - [Documentaion on API commands](https://www.directadmin.com/search_versions.php?help=no&versions=yes&query=CMD_API_) 15 | -------------------------------------------------------------------------------- /core/README.md: -------------------------------------------------------------------------------- 1 | # A simple script to update Directadmin from beta/stable channel per your needs: 2 | 3 | **updateda.sh** 4 | 5 | # Installation 6 | 7 | Install it: 8 | 9 | ``` 10 | cd /root/ 11 | wget https://raw.githubusercontent.com/poralix/directadmin-utils/master/core/updateda.sh 12 | chmod 755 updateda.sh 13 | ``` 14 | 15 | # Usage 16 | 17 | Run to install a pre-release version of Directadmin: 18 | 19 | ``` 20 | ./updateda.sh beta 21 | ``` 22 | 23 | Run to install a stable version of Directadmin: 24 | 25 | ``` 26 | ./updateda.sh stable 27 | ``` 28 | 29 | The script will try and auto-detect UID and LID. If it fails then you will need to run 30 | the script with options --lid=1234 and --uid=567 31 | 32 | ``` 33 | ./updateda.sh beta --lid=1234 --uid=567 34 | ``` 35 | 36 | or 37 | 38 | ``` 39 | ./updateda.sh stable --lid=1234 --uid=567 40 | ``` 41 | 42 | where you will need to use 43 | 44 | - a real License ID instead of 1234 45 | - a real Client ID instead of 567 46 | 47 | You can find License ID and Client ID on a page "Licensing/Updates" in Directadmin at admin level. 48 | 49 | # Override OS 50 | 51 | run the command to list supported OS with codes: 52 | 53 | ``` 54 | ./updateda.sh list_os 55 | ``` 56 | 57 | Example of usage: 58 | 59 | ``` 60 | ./updateda.sh beta --os=c9 61 | ``` 62 | 63 | you can find codes for OS below. 64 | 65 | # Supported OS with their codes 66 | 67 | ``` 68 | ==================== ====== 69 | RedHat Code 70 | ==================== ====== 71 | RedHat_7.2 a1 72 | RedHat_7.3 a2 73 | RedHat_8.0 a3 74 | RedHat_9.0 a4 75 | ==================== ====== 76 | Fedora Code 77 | ==================== ====== 78 | Fedora_1.0 b1 79 | Fedora_3 b2 80 | Fedora_4 b3 81 | Fedora_5 b4 82 | Fedora_7 b5 83 | Fedora_9 b6 84 | ==================== ====== 85 | CentOS Code 86 | ==================== ====== 87 | ES_3.0 c1 88 | ES_4.0 c2 89 | ES_4.4 c3 90 | ES_4.1_64 c4 91 | ES_5.0 c5 92 | ES_5.0_64 c6 93 | ES_6.0 c7 94 | ES_6.0_64 c8 95 | ES_7.0_64 c9 96 | ==================== ====== 97 | FreeBSD Code 98 | ==================== ====== 99 | FreeBSD_4.8 d1 100 | FreeBSD_5.1 d2 101 | FreeBSD_5.3 d3 102 | FreeBSD_6.0 d4 103 | FreeBSD_7.0 d5 104 | FreeBSD_7.1_64 d6 105 | FreeBSD_8.0_64 d7 106 | FreeBSD_9.1_32 d8 107 | FreeBSD_9.0_64 d9 108 | FreeBSD_11.0_64 d10 109 | ==================== ====== 110 | Debian Code 111 | ==================== ====== 112 | Debian_3.1 e1 113 | Debian_5 e2 114 | Debian_5_64 e3 115 | Debian_6 e4 116 | Debian_6_64 e5 117 | Debian_7 e6 118 | Debian_7_64 e7 119 | Debian_8_64 e8 120 | Debian_9_64 e9 121 | ``` 122 | 123 | # History of changes 124 | 125 | - Version: 0.5-beta (Thu Jun 27 10:19:12 +07 2019): An new action `save_os` is now added. It will add `os_override` in directadmin.conf 126 | - Version: 0.4-beta (Tue May 22 12:53:02 +07 2018): Read LID/UID from Directadmin binary, other fixes 127 | - Version: 0.3 (Wed Mar 14 17:49:04 +07 2018): added detection of os_override in directadmin 128 | -------------------------------------------------------------------------------- /core/update_evolution.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ################################# 3 | # Update Evolution Demo Skin 4 | # by Poralix 5 | ################################# 6 | 7 | echo "Evolution skin is now shipped with DirectAdmin. Do not use the script!"; 8 | exit 1; 9 | 10 | update_skin() 11 | { 12 | DIR="/usr/local/directadmin/data/skins/evolution"; 13 | [ -d "${DIR}" ] || mkdir -p "${DIR}"; 14 | cd "${DIR}"; 15 | wget -O evolution.tar.gz http://demo.directadmin.com/download/evolution.tar.gz; 16 | tar -xzf evolution.tar.gz; 17 | chown -R diradmin:diradmin "${DIR}"; 18 | } 19 | 20 | update_script() 21 | { 22 | wget -O /root/updateda.sh https://raw.githubusercontent.com/poralix/directadmin-utils/master/core/updateda.sh; 23 | chmod 755 /root/updateda.sh; 24 | } 25 | 26 | update_binary() 27 | { 28 | /root/updateda.sh beta; 29 | service directadmin restart; 30 | } 31 | 32 | if [ "$1" == "-v" ] || [ "$1" == "-V" ]; then 33 | [ -x "/root/updateda.sh" ] || update_script; 34 | update_binary; 35 | update_skin; 36 | else 37 | [ -x "/root/updateda.sh" ] || update_script >/dev/null 2>&1; 38 | update_binary >/dev/null 2>&1; 39 | update_skin >/dev/null 2>&1; 40 | fi; 41 | 42 | exit 0; 43 | -------------------------------------------------------------------------------- /core/updateda.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ################################################################################ 3 | # # 4 | # A script to update Directadmin from official channels # 5 | # Based on: # 6 | # https://docs.directadmin.com/directadmin/general-usage/updating-da.html # 7 | # # 8 | ################################################################################ 9 | # # 10 | # Version: 0.1 (Fri Mar 10 00:01:19 +07 2023) # 11 | # Last modified: Fri Mar 10 00:01:19 +07 2023 # 12 | # Site: www.poralix.com E-mail: support@poralix.com # 13 | # # 14 | ################################################################################ 15 | 16 | usage() 17 | { 18 | echo " 19 | Usage: 20 | $0 21 | 22 | Channels: 23 | 'alpha', 'beta', 'current', 'stable' or EOL channels: 'freebsd', 'rhel6', 'debian8', 'debian9' 24 | "; 25 | } 26 | 27 | # can be one of: alpha, beta, current, stable or EOL channels: freebsd, rhel6, debian8, debian9 28 | CHANNEL=""; 29 | 30 | case "${1}" in 31 | alpha|beta|current|stable|freebsd|rhel6|debian8|debian9) 32 | CHANNEL="${1}"; 33 | echo "Going to install DirectAdmin from a ${CHANNEL} channel"; 34 | ;; 35 | --help|--usage) 36 | usage; 37 | exit 0; 38 | ;; 39 | *) 40 | usage; 41 | exit 1; 42 | ;; 43 | esac; 44 | 45 | # can be: linux_amd64, linux_arm64, freebsd_amd64 46 | OS_SLUG="linux_amd64"; 47 | 48 | # can be commit hash literal value if you want specific build to be installed 49 | COMMIT=$(dig +short -t txt "$CHANNEL-version.directadmin.com" | sed 's|.*commit=\([0-9a-f]*\).*|\1|') #'; 50 | 51 | # creates download package name from the variables above 52 | FILE="directadmin_${COMMIT}_${OS_SLUG}.tar.gz"; 53 | 54 | test -f "/root/${FILE}" && rm -f "/root/${FILE}"; 55 | 56 | # downloads given directadmin build into /root dir 57 | curl --location --progress-bar --connect-timeout 10 "https://download.directadmin.com/${FILE}" --output "/root/${FILE}"; 58 | 59 | if [ -f "/root/${FILE}" ]; 60 | then 61 | # extracts downloaded package to /usr/local/directadmin 62 | tar -xzf "/root/${FILE}" -C /usr/local/directadmin && rm -f "/root/${FILE}"; 63 | 64 | # runs post-upgrade permission fix step 65 | /usr/local/directadmin/directadmin permissions || true; 66 | 67 | # runs other post upgrade fixes 68 | /usr/local/directadmin/scripts/update.sh; 69 | 70 | # restarts directadmin 71 | service directadmin restart; 72 | else 73 | echo "Failed to download a file"; 74 | fi; 75 | 76 | # print out a version 77 | /usr/local/directadmin/directadmin version; 78 | 79 | exit 0; 80 | -------------------------------------------------------------------------------- /email/README.md: -------------------------------------------------------------------------------- 1 | # Content 2 | 3 | - clear_majordomo_digest.sh: A script for Majordomo Mailings Lists Digest and Archives clearing 4 | - transip_mail_domains.sh: A auto-listing script adds domains for sending over TransIP Mail Service 5 | 6 | # Script transip_mail_domains.sh: 7 | 8 | The script runs DNS tests for all hosted domains and adds a domain into a list of domains emails from which should be sent over TransIP Mail Service. 9 | 10 | For DirectAdmin servers which use TransIP Mail Service as a SMTP relay. 11 | Exim should be configured to use TransIP Mail Service first. 12 | The script DOES NOT change Exim's configuration. You should do it first. 13 | The script DOES NOT change DNS records. You should do it first. 14 | 15 | Installation: 16 | 17 | ``` 18 | cd /usr/local/directadmin/scripts/custom/ 19 | wget -O transip_mail_domains.sh https://raw.githubusercontent.com/poralix/directadmin-utils/master/email/transip_mail_domains.sh 20 | chmod 750 ./transip_mail_domains.sh 21 | ``` 22 | 23 | Usage: 24 | 25 | ``` 26 | cd /usr/local/directadmin/scripts/custom/ 27 | ./transip_mail_domains.sh --help 28 | ``` 29 | 30 | Options: 31 | 32 | ``` 33 | --run - Run the tests 34 | 35 | --test-spf - Enable SPF test 36 | --test-dkim - Enable DKIM test 37 | --test-all - Enable SPF/DKIM tests 38 | 39 | --key= - If specified should contain a value for x-transip-mail-auth. 40 | This is the value which can be found in TransIP dashboard. 41 | TransIP requires this to be added for every domain. 42 | 43 | If omitted the script won't verify the value of the record 44 | in DNS. Any value will give a positive result. 45 | 46 | --debug - Print DEBUG output 47 | --verbose - Do a verbose output 48 | 49 | --dry-run - Do selected tests without writing changes to a file 50 | ``` 51 | 52 | # Author: 53 | 54 | Alex Grebenschikov, www.poralix.com 55 | -------------------------------------------------------------------------------- /email/clear_majordomo_digest.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #---------------------------------------------------------------------- 3 | # Description: Majordomo Mailings Lists Digest and Archives clearing 4 | # Author: Alexey S Grebenshchikov (support@poralix.com) 5 | # Last modified: Wed May 23 00:14:53 +07 2018 6 | # Created at: Wed Oct 22 15:40:22 NOVST 2008 7 | # 8 | #---------------------------------------------------------------------- 9 | # Versions: 10 | # 0.2 $ Wed May 23 00:14:53 +07 2018 11 | #---------------------------------------------------------------------- 12 | 13 | main() 14 | { 15 | VIRTUAL_DIR="/etc/virtual"; 16 | for i in `ls ${VIRTUAL_DIR}`; 17 | do 18 | if [ -d "${VIRTUAL_DIR}/${i}" ]; 19 | then 20 | # STEP 1 21 | DIGESTS_DIR="${VIRTUAL_DIR}/${i}/majordomo/digests"; 22 | if [ -d "${DIGESTS_DIR}" ]; 23 | then 24 | for j in `ls ${DIGESTS_DIR}`; 25 | do 26 | echo "[`date`] Clearing ${DIGESTS_DIR}/${j}/"; 27 | find ${DIGESTS_DIR}/${j} -mtime +2 -type f -exec rm {} \; 28 | done; 29 | fi; 30 | 31 | # STEP 2 32 | ARCHIVES_DIR="${VIRTUAL_DIR}/${i}/majordomo/lists"; 33 | if [ -d "${ARCHIVES_DIR}" ]; 34 | then 35 | for j in `ls ${ARCHIVES_DIR} | grep "\-digest.archive"` 36 | do 37 | echo "[`date`] Clearing ${ARCHIVES_DIR}/${j}/"; 38 | find ${ARCHIVES_DIR}/${j} -mtime +2 -type f -exec rm {} \; 39 | done; 40 | fi; 41 | fi; 42 | done; 43 | } 44 | 45 | #/var/log/majordomo_clear_digest.log 46 | main; 47 | 48 | exit 0; 49 | -------------------------------------------------------------------------------- /email/transip_mail_domains.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #---------------------------------------------------------------------- 3 | # Description: A script for auto-listing domains for sending 4 | # over TransIP Mail Service 5 | # For DirectAdmin servers which use TransIP Mail Service 6 | # Exim should be configured to use TransIP Mail Service first! 7 | # The script DOES NOT change Exim's configuration. You should do it! 8 | # The script DOES NOT change DNS records. You should do it first 9 | # Contact Poralix if you want us to configure Exim for you. 10 | #---------------------------------------------------------------------- 11 | # Author: Alex Grebenschikov, www.poralix.com 12 | # Created at: Sat Jan 22 08:40:23 CET 2022 13 | # Last modified: Sat Jan 22 13:08:47 CET 2022 14 | # Version: 0.2 $ Sat Jan 22 13:08:47 CET 2022 15 | #---------------------------------------------------------------------- 16 | # Copyright (c) 2022 Alex Grebenschikov, www.poralix.com 17 | #---------------------------------------------------------------------- 18 | 19 | ####################################################################################### 20 | ## # 21 | ## MIT License # 22 | ## # 23 | ## Copyright (c) 2016 Alex Grebenschikov, Poralix, www.poralix.com # 24 | ## # 25 | ## Permission is hereby granted, free of charge, to any person obtaining a copy # 26 | ## of this software and associated documentation files (the "Software"), to deal # 27 | ## in the Software without restriction, including without limitation the rights # 28 | ## to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # 29 | ## copies of the Software, and to permit persons to whom the Software is # 30 | ## furnished to do so, subject to the following conditions: # 31 | ## # 32 | ## The above copyright notice and this permission notice shall be included in all # 33 | ## copies or substantial portions of the Software. # 34 | ## # 35 | ## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # 36 | ## IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # 37 | ## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # 38 | ## AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # 39 | ## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # 40 | ## OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # 41 | ## SOFTWARE. # 42 | ## # 43 | ####################################################################################### 44 | 45 | 46 | # Configure section: 47 | #---------------------------------------------------------------------- 48 | EXCLUDED_LIST="/etc/virtual/domains_relay_transip.excluded"; 49 | LIST_FILE="/etc/virtual/domains_relay_transip"; 50 | DOMAINS_FILE="/etc/virtual/domains"; 51 | DNS_RESOLVER="1.1.1.1"; 52 | SEARCH_RECORD="x-transip-mail-auth"; 53 | DEBUG=0; 54 | VERBOSE=0; 55 | DRY_RUN=0; 56 | AUTH_KEY=""; 57 | 58 | TEST_AUTH=1; 59 | TEST_SPF=0; 60 | TEST_DKIM=0; 61 | 62 | RUN=0; 63 | #---------------------------------------------------------------------- 64 | 65 | do_usage() 66 | { 67 | echo " 68 | # =========================================================================== # 69 | # The auto-listing script adds domains for sending over TransIP Mail Service # 70 | # For DirectAdmin servers which use TransIP Mail Service as a SMTP relay # 71 | # Exim should be configured to use TransIP Mail Service first # 72 | # The script DOES NOT change Exim's configuration. You should do it first # 73 | # The script DOES NOT change DNS records. You should do it first # 74 | # Author: Alex Grebenschikov, www.poralix.com # 75 | # =========================================================================== # 76 | 77 | Usage: 78 | 79 | ${0} 80 | 81 | Options: 82 | 83 | --run - Run the tests 84 | 85 | --test-spf - Enable SPF test 86 | --test-dkim - Enable DKIM test 87 | --test-all - Enable SPF/DKIM tests 88 | 89 | --key= - If specified should contain a value for x-transip-mail-auth. 90 | This is the value which can be found in TransIP dashboard. 91 | TransIP requires this to be added for every domain. 92 | 93 | If omitted the script won't verify the value of the record 94 | in DNS. Any value will give a positive result. 95 | 96 | --debug - Print DEBUG output 97 | --verbose - Do a verbose output 98 | 99 | --dry-run - Do selected tests without writing changes to a file 100 | 101 | Important: 102 | 103 | You can add excluded domains in the file ${EXCLUDED_LIST} 104 | Verified domains will be added in the file ${LIST_FILE} 105 | Nothing else gets changed by the script. 106 | 107 | 108 | The script uses remote DNS resolver ${DNS_RESOLVER}. 109 | Make sure the server's firewall does not block connections to it. 110 | 111 | Copyright: 112 | 113 | (c) 2022 Alex Grebenschikov, www.poralix.com 114 | 115 | License: 116 | 117 | MIT License 118 | "; 119 | exit 0; 120 | } 121 | 122 | c_echo() 123 | { 124 | [ "${VERBOSE}" == "1" ] && echo "${1}"; 125 | } 126 | 127 | do_add_domain() 128 | { 129 | if [ "${DRY_RUN}" == "1" ]; then 130 | DRY_RUN_DOMAINS="${1}\n${DRY_RUN_DOMAINS}"; 131 | else 132 | echo "${1}" >> "${LIST_FILE}.new"; 133 | fi; 134 | } 135 | 136 | for ARG in $@; 137 | do 138 | case "${ARG}" in 139 | --debug) 140 | DEBUG=1; 141 | ;; 142 | --key=*) 143 | AUTH_KEY=$(echo ${ARG} | cut -d= -f2); 144 | ;; 145 | --verbose) 146 | VERBOSE=1; 147 | ;; 148 | --dry-run) 149 | DRY_RUN=1; 150 | ;; 151 | --test-spf) 152 | TEST_SPF=1; 153 | ;; 154 | --test-dkim) 155 | TEST_DKIM=1; 156 | ;; 157 | --test-all) 158 | TEST_AUTH=1; 159 | TEST_SPF=1; 160 | TEST_DKIM=1; 161 | ;; 162 | --run) 163 | RUN=1; 164 | ;; 165 | --help|--usage|*) 166 | do_usage; 167 | ;; 168 | esac; 169 | done; 170 | 171 | [ -z "$1" ] && do_usage; 172 | 173 | DOMAINS=""; 174 | 175 | [ -h "${LIST_FILE}" ] && echo "[ERROR] The ${LIST_FILE} is a symbolic link. Terminating..." && exit 1; 176 | [ ! -s "${DOMAINS_FILE}" ] && echo "[ERROR] Could not find a list of domains. Terminating..." && exit 2; 177 | 178 | [ -s "${LIST_FILE}" ] && cp -p "${LIST_FILE}" "${LIST_FILE}.old"; 179 | [ -f "${LIST_FILE}.new" ] && rm -f "${LIST_FILE}.new"; 180 | 181 | touch "${LIST_FILE}.new"; 182 | chmod 600 "${LIST_FILE}.new"; 183 | 184 | AUTH_OK_DOMAINS=""; 185 | SPF_OK_DOMAINS=""; 186 | DKIM_OK_DOMAINS=""; 187 | FOUND_OK_DOMAINS=""; 188 | DRY_RUN_DOMAINS=""; 189 | 190 | c_echo "STEP 1: Testing ${SEARCH_RECORD} record"; 191 | c_echo "===================================================================="; 192 | 193 | for DOMAIN in $(cat "${DOMAINS_FILE}" | sort | uniq); 194 | do 195 | c_echo "[OK] Processing ${DOMAIN}"; 196 | 197 | [ "${DEBUG}" == "1" ] && set -x; 198 | 199 | if [ -z "${AUTH_KEY}" ]; then 200 | CHECK_AUTH_RECORD=$(dig +short TXT "${SEARCH_RECORD}.${DOMAIN}" @${DNS_RESOLVER} | xargs); 201 | else 202 | CHECK_AUTH_RECORD=$(dig +short TXT "${SEARCH_RECORD}.${DOMAIN}" @${DNS_RESOLVER} | grep "${AUTH_KEY}"); 203 | fi; 204 | 205 | if [ -z "${CHECK_AUTH_RECORD}" ]; then 206 | c_echo "[WARNING] Domain ${DOMAIN} is not configured to use TransIP mail service. AUTH record is missing."; 207 | else 208 | c_echo "[INFO][${DOMAIN}] Found a value ${CHECK_AUTH_RECORD} for ${SEARCH_RECORD}.${DOMAIN} in DNS."; 209 | AUTH_OK_DOMAINS="${AUTH_OK_DOMAINS} ${DOMAIN}"; 210 | fi; 211 | 212 | [ "${DEBUG}" == "1" ] && set +x; 213 | c_echo "--------------------------------------------------------------------"; 214 | done; 215 | 216 | # SHOULD WE TEST SPF? 217 | if [ "${TEST_SPF}" == "1" ]; then 218 | c_echo ""; 219 | c_echo "STEP 2: Testing SPF record"; 220 | c_echo "===================================================================="; 221 | 222 | if [ -n "${AUTH_OK_DOMAINS}" ]; then 223 | TEST_DOMAINS="${AUTH_OK_DOMAINS}"; 224 | else 225 | TEST_DOMAINS=$(cat "${DOMAINS_FILE}" | sort | uniq); 226 | fi; 227 | 228 | for DOMAIN in ${TEST_DOMAINS}; 229 | do 230 | CHECK_SPF_RECORD=$(dig +short TXT "${DOMAIN}" @${DNS_RESOLVER} | grep -o " include:_spf.transip.email "); 231 | 232 | if [ -z "${CHECK_SPF_RECORD}" ]; then 233 | c_echo "[WARNING] Domain ${DOMAIN} is not configured to use TransIP mail service. SPF record is bad."; 234 | else 235 | c_echo "[INFO][${DOMAIN}] Found a string ${CHECK_SPF_RECORD// /} in SPF record for ${DOMAIN} in DNS."; 236 | SPF_OK_DOMAINS="${SPF_OK_DOMAINS} ${DOMAIN}"; 237 | fi; 238 | c_echo "--------------------------------------------------------------------"; 239 | done; 240 | fi; 241 | 242 | # SHOULD WE TEST DKIM? 243 | if [ "${TEST_DKIM}" == "1" ]; then 244 | c_echo ""; 245 | c_echo "STEP 3: Testing DKIM record"; 246 | c_echo "===================================================================="; 247 | 248 | if [ -n "${SPF_OK_DOMAINS}" ]; then 249 | TEST_DOMAINS="${SPF_OK_DOMAINS}"; 250 | elif [ -n "${AUTH_OK_DOMAINS}" ]; then 251 | TEST_DOMAINS="${AUTH_OK_DOMAINS}"; 252 | else 253 | TEST_DOMAINS=$(cat "${DOMAINS_FILE}" | sort | uniq); 254 | fi; 255 | 256 | for DOMAIN in ${TEST_DOMAINS}; 257 | do 258 | CHECK_DKIM_A_RECORD=$(dig +short CNAME "transip-A._domainkey.${DOMAIN}" @${DNS_RESOLVER} | grep "_dkim-A.transip.email"); 259 | CHECK_DKIM_B_RECORD=$(dig +short CNAME "transip-B._domainkey.${DOMAIN}" @${DNS_RESOLVER} | grep "_dkim-B.transip.email"); 260 | CHECK_DKIM_C_RECORD=$(dig +short CNAME "transip-C._domainkey.${DOMAIN}" @${DNS_RESOLVER} | grep "_dkim-C.transip.email"); 261 | 262 | if [ -z "${CHECK_DKIM_A_RECORD}" ] || [ -z "${CHECK_DKIM_B_RECORD}" ] || [ -z "${CHECK_DKIM_C_RECORD}" ]; then 263 | c_echo "[WARNING] Domain ${DOMAIN} is not configured to use TransIP mail service. DKIM record is bad."; 264 | else 265 | c_echo "[INFO][${DOMAIN}] Found DKIM record ${CHECK_DKIM_A_RECORD} for ${DOMAIN} in DNS."; 266 | c_echo "[INFO][${DOMAIN}] Found DKIM record ${CHECK_DKIM_B_RECORD} for ${DOMAIN} in DNS."; 267 | c_echo "[INFO][${DOMAIN}] Found DKIM record ${CHECK_DKIM_C_RECORD} for ${DOMAIN} in DNS."; 268 | DKIM_OK_DOMAINS="${DKIM_OK_DOMAINS} ${DOMAIN}"; 269 | fi; 270 | c_echo "--------------------------------------------------------------------"; 271 | done; 272 | fi; 273 | 274 | if [ "${TEST_DKIM}" == "1" ]; then 275 | FOUND_OK_DOMAINS="${DKIM_OK_DOMAINS}"; 276 | elif [ "${TEST_DKIM}" == "0" ] && [ "${TEST_SPF}" == "1" ]; then 277 | FOUND_OK_DOMAINS="${SPF_OK_DOMAINS}"; 278 | elif [ "${TEST_DKIM}" == "0" ] && [ "${TEST_SPF}" == "0" ]; then 279 | FOUND_OK_DOMAINS="${AUTH_OK_DOMAINS}"; 280 | fi; 281 | 282 | if [ -n "${FOUND_OK_DOMAINS}" ]; then 283 | 284 | c_echo ""; 285 | c_echo "STEP 4: Completing the list of domains"; 286 | c_echo "===================================================================="; 287 | 288 | for DOMAIN in ${FOUND_OK_DOMAINS}; 289 | do 290 | if [ -s "${EXCLUDED_LIST}" ]; then 291 | c_echo "[INFO] Found ${EXCLUDED_LIST}"; 292 | CHECK_EXCLUDED=$(grep "^${DOMAIN}$" "${EXCLUDED_LIST}"); 293 | if [ -z "${CHECK_EXCLUDED}" ]; then 294 | do_add_domain "${DOMAIN}"; 295 | else 296 | c_echo "[WARNING] Skipping domain ${DOMAIN}, as it is listed in ${EXCLUDED_LIST}" 297 | fi; 298 | else 299 | do_add_domain "${DOMAIN}"; 300 | fi; 301 | c_echo "--------------------------------------------------------------------"; 302 | done; 303 | else 304 | echo "[WARNING] None of the hosted domains is configured for sending over TransIP"; 305 | fi; 306 | 307 | if [ "${DRY_RUN}" == "0" ]; then 308 | 309 | if [ -f "${LIST_FILE}.new" ]; then 310 | cat "${LIST_FILE}.new" > "${LIST_FILE}"; 311 | rm -f "${LIST_FILE}.new"; 312 | fi; 313 | 314 | chown root:mail "${LIST_FILE}"; 315 | chmod 640 "${LIST_FILE}"; 316 | 317 | echo -e "\n\n===================================================================="; 318 | echo " Listed the following domains in ${LIST_FILE}"; 319 | echo "===================================================================="; 320 | cat "${LIST_FILE}" 321 | echo -e "===================================================================="; 322 | wc -l "${LIST_FILE}"; 323 | echo -e "\n"; 324 | else 325 | echo -e "\n\n================================================================================"; 326 | echo " Found the following domains to be listed in ${LIST_FILE}"; 327 | echo "================================================================================"; 328 | echo -n -e "${DRY_RUN_DOMAINS}" | sort | grep -v "$^"; 329 | echo -e "================================================================================"; 330 | echo -n -e "${DRY_RUN_DOMAINS}" | grep -v "$^" | wc -l; 331 | echo -e "\n"; 332 | fi; 333 | 334 | exit 0; 335 | -------------------------------------------------------------------------------- /hooks/README.md: -------------------------------------------------------------------------------- 1 | # Directadmin hooks: custom PRE and POST action scripts 2 | 3 | Directadmin allows to run custom scripts before and after a certain action performed by the control panel. 4 | So called hooks, or hookable events are custom PRE and POST action scripts. Here you can find a list of all custom scripts. 5 | 6 | The hook scripts: 7 | 8 | - [PRE action hooks are executed before an action in DirectAdmin](hooks_pre.md) 9 | - [POST action hooks are executed after an action in DirectAdmin](hooks_post.md) 10 | 11 | # Additional information 12 | 13 | - [Ability to pass custom variables to pre/post.sh scripts from GET/POST](https://www.directadmin.com/features.php?id=1780) 14 | - [Tool that will run custom scripts for base features](https://www.directadmin.com/features.php?id=183) 15 | -------------------------------------------------------------------------------- /hooks/hooks_post.md: -------------------------------------------------------------------------------- 1 | - all_backups_post.sh 2 | - all_post.sh 3 | - all_restores_post.sh 4 | - autoresponder_set_post.sh 5 | - check_letsencrypt_expiries_post.sh 6 | - check_partitions_notice_post.sh 7 | - cron_set_post.sh 8 | - database_create_post.sh 9 | - database_delete_post.sh 10 | - database_user_create_post.sh 11 | - database_user_destroy_post.sh 12 | - database_user_password_change_post.sh 13 | - dkim_create_post.sh 14 | - dns_create_post.sh 15 | - dns_delete_post.sh 16 | - dns_raw_save_post.sh 17 | - dnssec_sign_post.sh 18 | - dns_write_post.sh 19 | - domain_change_post.sh 20 | - domain_create_post.sh 21 | - domain_destroy_post.sh 22 | - domain_modify_post.sh 23 | - domain_pointer_create_post.sh 24 | - domain_pointer_destroy_post.sh 25 | - email_change_pass_post.sh 26 | - email_create_post.sh 27 | - email_destroy_post.sh 28 | - email_filter_write_post.sh 29 | - file_manager_upload_post.sh 30 | - forwarder_create_post.sh 31 | - forwarder_delete_post.sh 32 | - ftp_delete_post.sh 33 | - ip_change_post.sh 34 | - ipsconf_write_post.sh 35 | - letsencrypt_post.sh 36 | - load_spike_notice_post.sh 37 | - named_action_post.sh 38 | - openlitespeed_ips_conf_write_post.sh 39 | - openlitespeed_listeners_write_post.sh 40 | - overusage_notice_post.sh 41 | - public_html_link_set_post.sh 42 | - reseller_modify_post.sh 43 | - spam_script_chmod_0_post.sh 44 | - ssl_save_post.sh 45 | - subdomain_create_post.sh 46 | - subdomain_destroy_post.sh 47 | - tally_post.sh 48 | - tally_rotation_post.sh 49 | - tally_user_post.sh 50 | - taskq_dns_post.sh 51 | - update_post.sh 52 | - user_activate_post.sh 53 | - user_backup_post.sh 54 | - user_create_post.sh 55 | - user_destroy_post.sh 56 | - user_httpd_write_post.sh 57 | - user_info_modify_post.sh 58 | - user_modify_post.sh 59 | - user_password_change_post.sh 60 | - user_restore_fail_post.sh 61 | - user_restore_post.sh 62 | - user_suspend_post.sh 63 | - vacation_set_post.sh 64 | -------------------------------------------------------------------------------- /hooks/hooks_pre.md: -------------------------------------------------------------------------------- 1 | - all_backups_pre.sh 2 | - all_pre.sh 3 | - autoresponder_delete_pre.sh 4 | - autoresponder_set_pre.sh 5 | - backup_save_pre.sh 6 | - brute_force_notify_pre.sh 7 | - cron_set_pre.sh 8 | - database_create_pre.sh 9 | - database_delete_pre.sh 10 | - database_user_password_change_pre.sh 11 | - domain_change_pre.sh 12 | - domain_create_pre.sh 13 | - domain_destroy_pre.sh 14 | - domain_modify_pre.sh 15 | - domain_pointer_create_pre.sh 16 | - domain_pointer_destroy_pre.sh 17 | - email_change_pass_pre.sh 18 | - email_create_pre.sh 19 | - email_destroy_pre.sh 20 | - email_filter_write_pre.sh 21 | - filemanager_pre.sh 22 | - forwarder_create_pre.sh 23 | - forwarder_delete_pre.sh 24 | - ip_change_pre.sh 25 | - letsencrypt_pre.sh 26 | - load_spike_notice_pre.sh 27 | - lost_password_pre.sh 28 | - overusage_notice_pre.sh 29 | - public_html_link_set_pre.sh 30 | - reseller_destroy_pre.sh 31 | - reseller_modify_pre.sh 32 | - sendmail_pre.sh 33 | - session_destroy_pre.sh 34 | - ssl_save_pre.sh 35 | - subdomain_create_pre.sh 36 | - subdomain_destroy_pre.sh 37 | - tally_pre.sh 38 | - user_activate_pre.sh 39 | - user_backup_compress_pre.sh 40 | - user_backup_pre.sh 41 | - user_create_pre.sh 42 | - user_destroy_pre.sh 43 | - user_httpd_write_pre.sh 44 | - user_modify_pre.sh 45 | - user_password_change_pre.sh 46 | - user_restore_pre.sh 47 | - user_suspend_pre.sh 48 | - vacation_set_pre.sh 49 | -------------------------------------------------------------------------------- /letsencrypt/README.md: -------------------------------------------------------------------------------- 1 | # A script to force Let's Encrypt to use DST Root CA X3 2 | 3 | Here is a patch for Let's Encrypt script from DirectAdmin to force it to use "DST Root CA X3" instead of "ISRG Root X1" when issuing SSL certificates. 4 | 5 | For installation run as root: 6 | 7 | ``` 8 | mkdir -p /usr/local/directadmin/custombuild/custom/hooks/letsencrypt/post/ 9 | cd /usr/local/directadmin/custombuild/custom/hooks/letsencrypt/post/ 10 | wget -O poralix_patch_chain.sh https://raw.githubusercontent.com/poralix/directadmin-utils/master/letsencrypt/poralix_patch_chain.sh 11 | chmod 750 poralix_patch_chain.sh 12 | /usr/local/directadmin/custombuild/build letsencrypt 13 | ``` 14 | 15 | 16 | # let's encrypt patch for VERSION=1.0.18 letsencrypt.sh 17 | 18 | Having 10-20-30... domains (and more) in ca.san_config is a challenge to get them verified at once. This patch will give you a re-try on challenge verification. 19 | 20 | # Install 21 | 22 | ``` 23 | cd /usr/local/directadmin/scripts 24 | cp -p letsencrypt.sh letsencrypt_poralix.sh 25 | wget -O ./letsencrypt_poralix.patch https://raw.githubusercontent.com/poralix/directadmin-utils/master/letsencrypt/letsencrypt_poralix.patch 26 | patch ./letsencrypt_poralix.sh -i letsencrypt_poralix.patch 27 | ``` 28 | 29 | # Example: 30 | 31 | ``` 32 | Getting challenge for mail.poralix.com from acme-server... 33 | Challenge error: HTTP/1.1 100 Continue 34 | Expires: Tue, 11 Apr 2017 04:21:31 GMT 35 | Cache-Control: max-age=0, no-cache, no-store 36 | Pragma: no-cache 37 | 38 | HTTP/1.1 500 Internal Server Error 39 | Server: AkamaiGHost 40 | Mime-Version: 1.0 41 | Content-Type: text/html 42 | Content-Length: 176 43 | Expires: Tue, 11 Apr 2017 04:21:31 GMT 44 | Cache-Control: max-age=0, no-cache, no-store 45 | Pragma: no-cache 46 | Date: Tue, 11 Apr 2017 04:21:31 GMT 47 | Connection: close 48 | 49 | Error 50 | An error occurred while processing your request.

51 | Reference #179.8c346d68.1491884491.2960089 52 | . 53 | 54 | Do you want to retry (yes/no): yes 55 | Waiting for domain verification... 56 | Challenge is valid. 57 | ``` 58 | 59 | That's it! 60 | -------------------------------------------------------------------------------- /letsencrypt/autoletsencrypt.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | VERSION=1.2 3 | WELLKNOWN_PATH="/var/www/html/.well-known/acme-challenge" 4 | TIMESTAMP=`date +%s` 5 | CURL=/usr/local/bin/curl 6 | if [ ! -x ${CURL} ]; then 7 | CURL=/usr/bin/curl 8 | fi 9 | 10 | challenge_check() { 11 | if [ ! -d ${WELLKNOWN_PATH} ]; then 12 | mkdir -p ${WELLKNOWN_PATH} 13 | fi 14 | touch ${WELLKNOWN_PATH}/letsencrypt_${TIMESTAMP} 15 | #Checking if http://www.domain.com/.well-known/acme-challenge/letsencrypt_${TIMESTAMP} is available 16 | if ! ${CURL} ${CURL_OPTIONS} -k -I -L -X GET http://${1}/.well-known/acme-challenge/letsencrypt_${TIMESTAMP} 2>/dev/null | grep -m1 -q 'HTTP.*200'; then 17 | echo 1 18 | else 19 | echo 0 20 | fi 21 | rm -f ${WELLKNOWN_PATH}/letsencrypt_${TIMESTAMP} 22 | } 23 | 24 | for u in `ls /usr/local/directadmin/data/users`; do 25 | { 26 | for d in `cat /usr/local/directadmin/data/users/$u/domains.list`; do 27 | { 28 | if [ ! -e /usr/local/directadmin/data/users/$u/domains/$d.cert ] && [ -s /usr/local/directadmin/data/users/$u/domains/$d.conf ]; then 29 | CHALLENGE_TEST=`challenge_check $d` 30 | if [ ${CHALLENGE_TEST} -ne 1 ]; then 31 | CHALLENGE_TEST2=`challenge_check www.$d` 32 | if [ ${CHALLENGE_TEST2} -ne 1 ]; then 33 | /usr/local/directadmin/scripts/letsencrypt.sh request ${d} 4096 34 | else 35 | /usr/local/directadmin/scripts/letsencrypt.sh request_single ${d} 4096 36 | fi 37 | fi 38 | fi 39 | if [ -e /usr/local/directadmin/data/users/$u/domains/$d.cert ]; then 40 | REWRITE=false 41 | if ! grep -m1 -q '^ssl=ON' /usr/local/directadmin/data/users/$u/domains/$d.conf; then 42 | perl -pi -e 's|^ssl\=OFF|ssl=ON|g' /usr/local/directadmin/data/users/$u/domains/$d.conf 43 | REWRITE=true 44 | fi 45 | if ! grep -m1 -q '^SSLCACertificateFile=' /usr/local/directadmin/data/users/$u/domains/$d.conf; then 46 | perl -pi -e "s|^UseCanonicalName=|SSLCACertificateFile=/usr/local/directadmin/data/users/$u/domains/$d.cacert\nSSLCertificateFile=/usr/local/directadmin/data/users/$u/domains/$d.cert\nSSLCertificateKeyFile=/usr/local/directadmin/data/users/$u/domains/$d.key\nUseCanonicalName=|g" /usr/local/directadmin/data/users/$u/domains/$d.conf 47 | REWRITE=true 48 | fi 49 | if ${REWRITE}; then 50 | echo "action=rewrite&value=httpd&user=$u" >> /usr/local/directadmin/data/task.queue 51 | fi 52 | fi 53 | } 54 | done; 55 | } 56 | done; 57 | exit 0 58 | -------------------------------------------------------------------------------- /letsencrypt/autoletsencrypt.sh.patch: -------------------------------------------------------------------------------- 1 | --- autoletsencrypt.sh 2018-07-05 05:29:48.000000000 +0700 2 | +++ autoletsencrypt_mail.sh 2019-01-12 15:06:06.000000000 +0700 3 | @@ -1,5 +1,23 @@ 4 | #!/bin/sh 5 | -VERSION=1.2 6 | +VERSION=1.2.patched 7 | +############################################################################### 8 | +# # 9 | +# Automatically setup LetsEncrypt SSL for *all* domains # 10 | +# that do not currently have a certificate # 11 | +# # 12 | +############################################################################### 13 | +# # 14 | +# Original script written by Directadmin # 15 | +# https://help.directadmin.com/item.php?id=675 # 16 | +# http://files.directadmin.com/services/all/letsencrypt/autoletsencrypt.sh # 17 | +# # 18 | +############################################################################### 19 | +# # 20 | +# Patched by Poralix to add mail subdomain into certs # 21 | +# Last modified: Sat Jan 12 15:04:00 +07 2019 (support@poralix.com) # 22 | +# # 23 | +############################################################################### 24 | + 25 | WELLKNOWN_PATH="/var/www/html/.well-known/acme-challenge" 26 | TIMESTAMP=`date +%s` 27 | CURL=/usr/local/bin/curl 28 | @@ -29,7 +47,10 @@ 29 | CHALLENGE_TEST=`challenge_check $d` 30 | if [ ${CHALLENGE_TEST} -ne 1 ]; then 31 | CHALLENGE_TEST2=`challenge_check www.$d` 32 | - if [ ${CHALLENGE_TEST2} -ne 1 ]; then 33 | + CHALLENGE_TEST3=`challenge_check mail.$d` 34 | + if [ ${CHALLENGE_TEST2} -ne 1 ] && [ ${CHALLENGE_TEST3} -ne 1 ]; then 35 | + /usr/local/directadmin/scripts/letsencrypt.sh request ${d},www.${d},mail.${d} 4096 36 | + elif [ ${CHALLENGE_TEST2} -ne 1 ]; then 37 | /usr/local/directadmin/scripts/letsencrypt.sh request ${d} 4096 38 | else 39 | /usr/local/directadmin/scripts/letsencrypt.sh request_single ${d} 4096 40 | -------------------------------------------------------------------------------- /letsencrypt/autoletsencrypt_mail.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | VERSION=1.2.patched 3 | ############################################################################### 4 | # # 5 | # Automatically setup LetsEncrypt SSL for *all* domains # 6 | # that do not currently have a certificate # 7 | # # 8 | ############################################################################### 9 | # # 10 | # Original script written by Directadmin # 11 | # https://help.directadmin.com/item.php?id=675 # 12 | # http://files.directadmin.com/services/all/letsencrypt/autoletsencrypt.sh # 13 | # # 14 | ############################################################################### 15 | # # 16 | # Patched by Poralix to add mail subdomain into certs # 17 | # Last modified: Sat Jan 12 15:04:00 +07 2019 (support@poralix.com) # 18 | # # 19 | ############################################################################### 20 | 21 | WELLKNOWN_PATH="/var/www/html/.well-known/acme-challenge" 22 | TIMESTAMP=`date +%s` 23 | CURL=/usr/local/bin/curl 24 | if [ ! -x ${CURL} ]; then 25 | CURL=/usr/bin/curl 26 | fi 27 | 28 | challenge_check() { 29 | if [ ! -d ${WELLKNOWN_PATH} ]; then 30 | mkdir -p ${WELLKNOWN_PATH} 31 | fi 32 | touch ${WELLKNOWN_PATH}/letsencrypt_${TIMESTAMP} 33 | #Checking if http://www.domain.com/.well-known/acme-challenge/letsencrypt_${TIMESTAMP} is available 34 | if ! ${CURL} ${CURL_OPTIONS} -k -I -L -X GET http://${1}/.well-known/acme-challenge/letsencrypt_${TIMESTAMP} 2>/dev/null | grep -m1 -q 'HTTP.*200'; then 35 | echo 1 36 | else 37 | echo 0 38 | fi 39 | rm -f ${WELLKNOWN_PATH}/letsencrypt_${TIMESTAMP} 40 | } 41 | 42 | for u in `ls /usr/local/directadmin/data/users`; do 43 | { 44 | for d in `cat /usr/local/directadmin/data/users/$u/domains.list`; do 45 | { 46 | if [ ! -e /usr/local/directadmin/data/users/$u/domains/$d.cert ] && [ -s /usr/local/directadmin/data/users/$u/domains/$d.conf ]; then 47 | CHALLENGE_TEST=`challenge_check $d` 48 | if [ ${CHALLENGE_TEST} -ne 1 ]; then 49 | CHALLENGE_TEST2=`challenge_check www.$d` 50 | CHALLENGE_TEST3=`challenge_check mail.$d` 51 | if [ ${CHALLENGE_TEST2} -ne 1 ] && [ ${CHALLENGE_TEST3} -ne 1 ]; then 52 | /usr/local/directadmin/scripts/letsencrypt.sh request ${d},www.${d},mail.${d} 4096 53 | elif [ ${CHALLENGE_TEST2} -ne 1 ]; then 54 | /usr/local/directadmin/scripts/letsencrypt.sh request ${d} 4096 55 | else 56 | /usr/local/directadmin/scripts/letsencrypt.sh request_single ${d} 4096 57 | fi 58 | fi 59 | fi 60 | if [ -e /usr/local/directadmin/data/users/$u/domains/$d.cert ]; then 61 | REWRITE=false 62 | if ! grep -m1 -q '^ssl=ON' /usr/local/directadmin/data/users/$u/domains/$d.conf; then 63 | perl -pi -e 's|^ssl\=OFF|ssl=ON|g' /usr/local/directadmin/data/users/$u/domains/$d.conf 64 | REWRITE=true 65 | fi 66 | if ! grep -m1 -q '^SSLCACertificateFile=' /usr/local/directadmin/data/users/$u/domains/$d.conf; then 67 | perl -pi -e "s|^UseCanonicalName=|SSLCACertificateFile=/usr/local/directadmin/data/users/$u/domains/$d.cacert\nSSLCertificateFile=/usr/local/directadmin/data/users/$u/domains/$d.cert\nSSLCertificateKeyFile=/usr/local/directadmin/data/users/$u/domains/$d.key\nUseCanonicalName=|g" /usr/local/directadmin/data/users/$u/domains/$d.conf 68 | REWRITE=true 69 | fi 70 | if ${REWRITE}; then 71 | echo "action=rewrite&value=httpd&user=$u" >> /usr/local/directadmin/data/task.queue 72 | fi 73 | fi 74 | } 75 | done; 76 | } 77 | done; 78 | exit 0 79 | -------------------------------------------------------------------------------- /letsencrypt/fix_le_caroot.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # A SCRIPT TO REWRITE EXPIRED LET'S ENCRYPT CAROOT CERTIFICATE 4 | # ===================================================================== 5 | # Solving the error: 6 | # depth=3 O = Digital Signature Trust Co., CN = DST Root CA X3 7 | # verify error:num=10:certificate has expired 8 | # notAfter=Sep 30 14:01:15 2021 GMT 9 | # ===================================================================== 10 | # Writen by Alex S Grebenschikov $ Sun Oct 3 21:20:59 +07 2021 11 | # www.poralix.com 12 | # ===================================================================== 13 | 14 | print_cert() 15 | { 16 | echo '-----BEGIN CERTIFICATE----- 17 | MIIFFjCCAv6gAwIBAgIRAJErCErPDBinU/bWLiWnX1owDQYJKoZIhvcNAQELBQAw 18 | TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh 19 | cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMjAwOTA0MDAwMDAw 20 | WhcNMjUwOTE1MTYwMDAwWjAyMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3Mg 21 | RW5jcnlwdDELMAkGA1UEAxMCUjMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK 22 | AoIBAQC7AhUozPaglNMPEuyNVZLD+ILxmaZ6QoinXSaqtSu5xUyxr45r+XXIo9cP 23 | R5QUVTVXjJ6oojkZ9YI8QqlObvU7wy7bjcCwXPNZOOftz2nwWgsbvsCUJCWH+jdx 24 | sxPnHKzhm+/b5DtFUkWWqcFTzjTIUu61ru2P3mBw4qVUq7ZtDpelQDRrK9O8Zutm 25 | NHz6a4uPVymZ+DAXXbpyb/uBxa3Shlg9F8fnCbvxK/eG3MHacV3URuPMrSXBiLxg 26 | Z3Vms/EY96Jc5lP/Ooi2R6X/ExjqmAl3P51T+c8B5fWmcBcUr2Ok/5mzk53cU6cG 27 | /kiFHaFpriV1uxPMUgP17VGhi9sVAgMBAAGjggEIMIIBBDAOBgNVHQ8BAf8EBAMC 28 | AYYwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMBIGA1UdEwEB/wQIMAYB 29 | Af8CAQAwHQYDVR0OBBYEFBQusxe3WFbLrlAJQOYfr52LFMLGMB8GA1UdIwQYMBaA 30 | FHm0WeZ7tuXkAXOACIjIGlj26ZtuMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcw 31 | AoYWaHR0cDovL3gxLmkubGVuY3Iub3JnLzAnBgNVHR8EIDAeMBygGqAYhhZodHRw 32 | Oi8veDEuYy5sZW5jci5vcmcvMCIGA1UdIAQbMBkwCAYGZ4EMAQIBMA0GCysGAQQB 33 | gt8TAQEBMA0GCSqGSIb3DQEBCwUAA4ICAQCFyk5HPqP3hUSFvNVneLKYY611TR6W 34 | PTNlclQtgaDqw+34IL9fzLdwALduO/ZelN7kIJ+m74uyA+eitRY8kc607TkC53wl 35 | ikfmZW4/RvTZ8M6UK+5UzhK8jCdLuMGYL6KvzXGRSgi3yLgjewQtCPkIVz6D2QQz 36 | CkcheAmCJ8MqyJu5zlzyZMjAvnnAT45tRAxekrsu94sQ4egdRCnbWSDtY7kh+BIm 37 | lJNXoB1lBMEKIq4QDUOXoRgffuDghje1WrG9ML+Hbisq/yFOGwXD9RiX8F6sw6W4 38 | avAuvDszue5L3sz85K+EC4Y/wFVDNvZo4TYXao6Z0f+lQKc0t8DQYzk1OXVu8rp2 39 | yJMC6alLbBfODALZvYH7n7do1AZls4I9d1P4jnkDrQoxB3UqQ9hVl3LEKQ73xF1O 40 | yK5GhDDX8oVfGKF5u+decIsH4YaTw7mP3GFxJSqv3+0lUFJoi5Lc5da149p90Ids 41 | hCExroL1+7mryIkXPeFM5TgO9r0rvZaBFOvV2z0gp35Z0+L4WPlbuEjN/lxPFin+ 42 | HlUjr8gRsI3qfJOQFy/9rKIJR0Y/8Omwt/8oTWgy1mdeHmmjk7j1nYsvC9JSQ6Zv 43 | MldlTTKB3zhThV1+XWYp6rjd5JW1zbVWEkLNxE7GJThEUG3szgBVGP7pSWTUTsqX 44 | nLRbwHOoq7hHwg== 45 | -----END CERTIFICATE-----'; 46 | } 47 | 48 | 49 | for DOM in $(cat /etc/virtual/domainowners | cut -d\: -f1); 50 | do 51 | USER=$(grep ^${DOM}: /etc/virtual/domainowners | awk '{print $2}'); 52 | if [ -f "/usr/local/directadmin/data/users/${USER}/domains/${DOM}.cert.creation_time" ]; 53 | then 54 | echo "Updating ${DOM} owned by ${USER}"; 55 | print_cert > "/usr/local/directadmin/data/users/${USER}/domains/${DOM}.cacert"; 56 | cat "/usr/local/directadmin/data/users/${USER}/domains/${DOM}.cert" "/usr/local/directadmin/data/users/${USER}/domains/${DOM}.cacert" > "/usr/local/directadmin/data/users/${USER}/domains/${DOM}.cert.combined"; 57 | fi; 58 | done; 59 | 60 | cd /usr/local/directadmin/custombuild/; 61 | ./build rewrite_confs; 62 | 63 | exit; 64 | -------------------------------------------------------------------------------- /letsencrypt/letsencrypt_poralix-1.0.18.patch: -------------------------------------------------------------------------------- 1 | --- /usr/local/directadmin/scripts/letsencrypt.sh 2017-11-15 23:43:21.000000000 +0700 2 | +++ /usr/local/directadmin/scripts/letsencrypt_poralix.sh 2017-11-16 15:09:26.000000000 +0700 3 | @@ -443,6 +443,16 @@ 4 | echo "Getting challenge for ${single_domain} from acme-server..." 5 | send_signed_request "normal" "${API}/acme/new-authz" '{"resource": "new-authz", "identifier": {"type": "dns", "value": "'"${single_domain}"'"}}' 6 | 7 | + # poralix 8 | + if [ "${HTTP_STATUS}" -ne 201 ] ; then 9 | + sleep 1; 10 | + ERROR500=$(echo ${RESPONSE} | grep -c 'HTTP/1.1 500 Internal Server Error'); 11 | + if [ "${ERROR500}" -ne 0 ]; then 12 | + echo "Error 500 occured in authz request: ${RESPONSE}. Trying once again..."; 13 | + send_signed_request "normal" "${API}/acme/new-authz" '{"resource": "new-authz", "identifier": {"type": "dns", "value": "'"${single_domain}"'"}}'; 14 | + fi; 15 | + fi; 16 | + 17 | #Account has a key for let's encrypt, but it's not registered 18 | if [ "${HTTP_STATUS}" -eq 403 ] ; then 19 | echo "User let's encrypt key has been found, but not registered. Registering..." 20 | @@ -535,6 +545,14 @@ 21 | echo "Challenge is ${CHALLENGE_STATUS}. Details: ${CHALLENGE_DETAIL}. Exiting..." 22 | exit 1 23 | fi 24 | + 25 | + # poralix 26 | + echo -n "Sleep some "; 27 | + for n in `seq 1 5`; do 28 | + sleep 1; 29 | + echo -n '.'; 30 | + done; 31 | + echo ''; 32 | } 33 | done 34 | 35 | -------------------------------------------------------------------------------- /letsencrypt/letsencrypt_poralix-1.0.8.patch: -------------------------------------------------------------------------------- 1 | --- /usr/local/directadmin/scripts/letsencrypt.sh 2017-03-28 19:07:21.000000000 +1300 2 | +++ /usr/local/directadmin/scripts/letsencrypt_poralix.sh 2017-04-11 16:28:31.278336745 +1200 3 | @@ -494,10 +494,26 @@ 4 | 5 | send_signed_request "normal" "${CHALLENGE_URI}" "{\"resource\": \"challenge\", \"keyAuthorization\": \"${KEYAUTH}\"}" 6 | 7 | - if [ ${HTTP_STATUS} -ne 202 ] ; then 8 | - echo "Challenge error: ${RESPONSE}. Exiting..." 9 | - exit 1 10 | - fi 11 | + while [ ${HTTP_STATUS} -ne 202 ] ; do 12 | + echo "Challenge error: ${RESPONSE}." 13 | + echo ""; 14 | + echo -n "Do you want to retry (yes/no): " 15 | + while read yesno; 16 | + do 17 | + case "${yesno}" in 18 | + yes|y) 19 | + send_signed_request "normal" "${CHALLENGE_URI}" "{\"resource\": \"challenge\", \"keyAuthorization\": \"${KEYAUTH}\"}" 20 | + break; 21 | + ;; 22 | + no|n) 23 | + exit 1; 24 | + ;; 25 | + *) 26 | + echo -n "Do you want to retry (yes/no): " 27 | + ;; 28 | + esac; 29 | + done; 30 | + done 31 | 32 | echo "Waiting for domain verification..." 33 | while [ "${CHALLENGE_STATUS}" = "pending" ]; do 34 | @@ -515,6 +531,13 @@ 35 | echo "Challenge is ${CHALLENGE_STATUS}. Details: ${CHALLENGE_DETAIL}. Exiting..." 36 | exit 1 37 | fi 38 | + 39 | + echo -n "Sleep some "; 40 | + for n in `seq 1 5`; do 41 | + sleep 1; 42 | + echo -n '.'; 43 | + done; 44 | + echo ''; 45 | } 46 | done 47 | 48 | -------------------------------------------------------------------------------- /letsencrypt/letsencrypt_poralix.patch: -------------------------------------------------------------------------------- 1 | letsencrypt_poralix-1.0.18.patch -------------------------------------------------------------------------------- /letsencrypt/letsencrypt_poralix.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | #VERSION=1.0.18 3 | # This script is written by Martynas Bendorius and DirectAdmin 4 | # It is used to create/renew let's encrypt certificate for a domain 5 | # Official DirectAdmin webpage: http://www.directadmin.com 6 | # Usage: 7 | # ./letsencrypt.sh 8 | MYUID=`/usr/bin/id -u` 9 | if [ "${MYUID}" != 0 ]; then 10 | echo "You require Root Access to run this script"; 11 | exit 0; 12 | fi 13 | 14 | DEFAULT_KEY_SIZE="" 15 | 16 | if [ $# -lt 2 ]; then 17 | echo "Usage:"; 18 | echo "$0 request|request_single|renew|revoke ()"; 19 | echo "you gave #$#: $0 $1 $2 $3"; 20 | echo "Multiple comma separated domains, owned by the same user, can be used for a certificate request" 21 | exit 0; 22 | elif [ $# -lt 3 ]; then 23 | #No key size specified, assign default one 24 | DEFAULT_KEY_SIZE=4096 25 | fi 26 | DA_BIN=/usr/local/directadmin/directadmin 27 | if [ ! -s ${DA_BIN} ]; then 28 | echo "Unable to find DirectAdmin binary /usr/local/directadmin/directadmin. Exiting..." 29 | exit 1 30 | fi 31 | 32 | #Staging/development 33 | #API_URI="acme-staging.api.letsencrypt.org" 34 | API_URI="acme-v01.api.letsencrypt.org" 35 | API="https://${API_URI}" 36 | LICENSE="https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf" 37 | LICENSE_NEW=$(curl -I -s https://acme-v01.api.letsencrypt.org/terms | (grep Location: || true) | awk -F ': ' '{print $2}' | tr -d '\n\r') 38 | if [ "$(echo "$LICENSE_NEW" | cut -c1-4)" == "http" ]; then 39 | LICENSE=$LICENSE_NEW 40 | fi 41 | 42 | CHALLENGETYPE="http-01" 43 | LICENSE_KEY_MIN_DATE=1470383674 44 | 45 | CURL=/usr/local/bin/curl 46 | if [ ! -x ${CURL} ]; then 47 | CURL=/usr/bin/curl 48 | fi 49 | 50 | CURL_OPTIONS="--connect-timeout 15 -k" 51 | 52 | OS=`uname` 53 | 54 | OPENSSL=/usr/bin/openssl 55 | TIMESTAMP=`date +%s` 56 | 57 | LETSENCRYPT_OPTION=`${DA_BIN} c | grep '^letsencrypt=' | cut -d= -f2` 58 | ACCESS_GROUP_OPTION=`${DA_BIN} c | grep '^secure_access_group=' | cut -d= -f2` 59 | FILE_CHOWN="diradmin:diradmin" 60 | FILE_CHMOD="640" 61 | if [ "${ACCESS_GROUP_OPTION}" != "" ]; then 62 | FILE_CHOWN="diradmin:${ACCESS_GROUP_OPTION}" 63 | fi 64 | 65 | #Encode data using base64 with URL-safe chars 66 | base64_encode() { 67 | ${OPENSSL} base64 -e | tr -d '\n\r' | tr "+/" "-_" | tr -d '= ' 68 | } 69 | 70 | TASKQ=/usr/local/directadmin/data/task.queue 71 | 72 | #Send signed request 73 | send_signed_request() { 74 | REQ_TYPE="${1}" 75 | URL="${2}" 76 | PAYLOAD="${3}" 77 | 78 | #Use base64 for the payload 79 | PAYLOAD64="`echo -n \"${PAYLOAD}\" | base64_encode`" 80 | 81 | #Get nonce from acme-server 82 | FULL_NONCE="`${CURL} ${CURL_OPTIONS} --silent -I ${API}/directory`" 83 | NONCE="`echo \"${FULL_NONCE}\" | grep '^Replay-Nonce:' | cut -d' ' -f2 | tr -d '\n\r'`" 84 | if [ "${NONCE}" = "" ]; then 85 | echo "Nonce is empty. Exiting. dig output of ${API_URI}: " 86 | dig ${API_URI} +short 87 | echo "Full nonce request output:" 88 | echo "${FULL_NONCE}" 89 | exit 1 90 | fi 91 | 92 | #Create header without nonce, use thumbprint 93 | HEADER="{\"alg\": \"RS256\", \"jwk\": ${FOR_THUMBPRINT}}" 94 | 95 | #Create header with nonce encode as base64 96 | PROTECTED="{\"nonce\": \"${NONCE}\", \"alg\": \"RS256\", \"jwk\": ${FOR_THUMBPRINT}}" 97 | 98 | PROTECTED64="`echo -n ${PROTECTED} | base64_encode`" 99 | 100 | SIGN64="`echo -n \"${PROTECTED64}.${PAYLOAD64}\" | ${OPENSSL} dgst -sha256 -sign \"${LETSENCRYPT_ACCOUNT_KEY}\" | base64_encode`" 101 | 102 | #Form the BODY to send 103 | BODY="{\"header\": ${HEADER}, \"protected\": \"${PROTECTED64}\", \"payload\": \"${PAYLOAD64}\", \"signature\": \"${SIGN64}\"}" 104 | 105 | #Send the BODY, save the response 106 | if [ "${REQ_TYPE}" = "cert" ]; then 107 | CERT64="`${CURL} ${CURL_OPTIONS} --silent -X POST --data \"${BODY}\" \"${URL}\" | ${OPENSSL} base64 -e`" 108 | else 109 | RESPONSE="`${CURL} ${CURL_OPTIONS} -i --silent -X POST --data \"${BODY}\" \"${URL}\"`" 110 | 111 | if [ "${RESPONSE}" = "" ]; then 112 | echo "Response is empty. Command:" 113 | echo "${CURL} ${CURL_OPTIONS} -i --silent -X POST --data \"${BODY}\" \"${URL}\"" 114 | echo "Exiting..." 115 | exit 1 116 | fi 117 | #HTTP status code 118 | HTTP_STATUS=`echo "${RESPONSE}" | grep -v 'HTTP.*100 Continue' | grep -m1 'HTTP.*' | awk '{print $2}'` 119 | fi 120 | } 121 | 122 | #Check if private key matches certificate 123 | 124 | checkPrivPubMatch() { 125 | PRIV="${1}" 126 | PUB="${2}" 127 | if [ -f "${PRIV}" ] && [ -f "${PUB}" ]; then 128 | MD5SUMPRIVMOD=`openssl rsa -noout -modulus -in ${PRIV}| openssl md5` 129 | MD5SUMPUBMOD=`openssl x509 -noout -modulus -in ${PUB} | openssl md5` 130 | if [ "${MD5SUMPRIVMOD}" = "${MD5SUMPUBMOD}" ]; then 131 | echo 0 132 | else 133 | echo 1 134 | fi 135 | else 136 | echo 2 137 | fi 138 | } 139 | 140 | ACTION=$1 141 | IS_SINGLE=false 142 | if [ "$1" = "request_single" ]; then 143 | IS_SINGLE=true 144 | ACTION=request 145 | fi 146 | 147 | DOMAIN=$2 148 | if [ "${DEFAULT_KEY_SIZE}" = "" ]; then 149 | KEY_SIZE=$3 150 | else 151 | KEY_SIZE=${DEFAULT_KEY_SIZE} 152 | fi 153 | CSR_CF_FILE=$4 154 | DOCUMENT_ROOT=$5 155 | #We need the domain to match in /etc/virtual/domainowners, if we use grep -F, we cannot use any regex'es including ^ 156 | 157 | DOMAINARR_IN_USE=false 158 | if echo "${DOMAIN}" | grep -m1 -q ","; then 159 | DOMAINARR_IN_USE=true 160 | fi 161 | DOMAINARR=`echo "${DOMAIN}" | perl -p0 -e "s/,/ /g"` 162 | 163 | FOUNDDOMAIN=0 164 | for TDOMAIN in ${DOMAINARR} 165 | do 166 | DOMAIN=${TDOMAIN} 167 | 168 | DOMAIN_ESCAPED="`echo ${DOMAIN} | perl -p0 -e 's#\.#\\\.#g'`" 169 | 170 | if grep -m1 -q "^${DOMAIN_ESCAPED}:" /etc/virtual/domainowners; then 171 | USER=`grep -m1 "^${DOMAIN_ESCAPED}:" /etc/virtual/domainowners | cut -d' ' -f2` 172 | HOSTNAME=0 173 | FOUNDDOMAIN=1 174 | break 175 | elif grep -m1 -q "^${DOMAIN_ESCAPED}$" /etc/virtual/domains; then 176 | USER="root" 177 | if ${DA_BIN} c | grep -m1 -q "^servername=${DOMAIN_ESCAPED}\$"; then 178 | echo "Setting up certificate for a hostname: ${DOMAIN}" 179 | HOSTNAME=1 180 | FOUNDDOMAIN=1 181 | break 182 | else 183 | echo "Domain exists in /etc/virtual/domains, but is not set as a hostname in DirectAdmin. Unable to find 'servername=${DOMAIN}' in the output of '/usr/local/directadmin/directadmin c'. Exiting..." 184 | #exit 1 185 | fi 186 | else 187 | echo "Domain does not exist on the system. Unable to find ${DOMAIN} in /etc/virtual/domainowners. Exiting..." 188 | #exit 1 189 | fi 190 | done 191 | 192 | if [ ${FOUNDDOMAIN} -eq 0 ]; then 193 | echo "no valid domain found - exiting" 194 | exit 1 195 | fi 196 | 197 | if [ ${KEY_SIZE} -ne 2048 ] && [ ${KEY_SIZE} -ne 4096 ]; then 198 | echo "Wrong key size. It must be 2048 or 4096. Exiting..." 199 | exit 1 200 | fi 201 | 202 | if [ "${CSR_CF_FILE}" != "" ] && [ ! -s ${CSR_CF_FILE} ]; then 203 | echo "CSR config file ${CSR_CF_FILE} passed but does not exist or is empty." 204 | ls -la ${CSR_CF_FILE} 205 | exit 1 206 | fi 207 | 208 | EMAIL="${USER}@${DOMAIN}" 209 | 210 | DA_USERDIR="/usr/local/directadmin/data/users/${USER}" 211 | DA_CONFDIR="/usr/local/directadmin/conf" 212 | HOSTNAME_DIR="/var/www/html" 213 | 214 | if [ ! -d "${DA_USERDIR}" ] && [ "${HOSTNAME}" -eq 0 ]; then 215 | echo "${DA_USERDIR} not found, exiting..." 216 | exit 1 217 | elif [ ! -d "${DA_CONFDIR}" ] && [ "${HOSTNAME}" -eq 1 ]; then 218 | echo "${DA_CONFDIR} not found, exiting..." 219 | exit 1 220 | fi 221 | 222 | if [ "${HOSTNAME}" -eq 0 ]; then 223 | LETSENCRYPT_ACCOUNT_KEY="${DA_USERDIR}/letsencrypt.key" 224 | KEY="${DA_USERDIR}/domains/${DOMAIN}.key" 225 | CERT="${DA_USERDIR}/domains/${DOMAIN}.cert" 226 | CACERT="${DA_USERDIR}/domains/${DOMAIN}.cacert" 227 | CSR="${DA_USERDIR}/domains/${DOMAIN}.csr" 228 | SAN_CONFIG="${DA_USERDIR}/domains/${DOMAIN}.san_config" 229 | if [ "${DOCUMENT_ROOT}" != "" ]; then 230 | DOMAIN_DIR="${DOCUMENT_ROOT}" 231 | elif ${DA_BIN} c | grep -m1 -q '^letsencrypt=2$'; then 232 | USER_HOMEDIR="`grep -m1 \"^${USER}:\" /etc/passwd | cut -d: -f6`" 233 | DOMAIN_DIR="${USER_HOMEDIR}/domains/${DOMAIN}/public_html" 234 | else 235 | DOMAIN_DIR="${HOSTNAME_DIR}" 236 | fi 237 | WELLKNOWN_PATH="${DOMAIN_DIR}/.well-known/acme-challenge" 238 | else 239 | LETSENCRYPT_ACCOUNT_KEY="${DA_CONFDIR}/letsencrypt.key" 240 | KEY=`${DA_BIN} c |grep ^cakey= | cut -d= -f2` 241 | CERT=`${DA_BIN} c |grep ^cacert= | cut -d= -f2` 242 | CACERT=`${DA_BIN} c |grep ^carootcert= | cut -d= -f2` 243 | if [ "${CACERT}" = "" ]; then 244 | CACERT="${DA_CONFDIR}/carootcert.pem" 245 | fi 246 | CSR="${DA_CONFDIR}/ca.csr" 247 | SAN_CONFIG="${DA_CONFDIR}/ca.san_config" 248 | DOMAIN_DIR="${HOSTNAME_DIR}" 249 | WELLKNOWN_PATH="${DOMAIN_DIR}/.well-known/acme-challenge" 250 | fi 251 | 252 | challenge_check() { 253 | if [ ! -d ${WELLKNOWN_PATH} ]; then 254 | mkdir -p ${WELLKNOWN_PATH} 255 | fi 256 | touch ${WELLKNOWN_PATH}/letsencrypt_${TIMESTAMP} 257 | chown webapps:webapps ${WELLKNOWN_PATH}/letsencrypt_${TIMESTAMP} 258 | #Checking if http://www.domain.com/.well-known/acme-challenge/letsencrypt_${TIMESTAMP} is available 259 | if ! ${CURL} ${CURL_OPTIONS} -I -L -X GET http://${1}/.well-known/acme-challenge/letsencrypt_${TIMESTAMP} 2>/dev/null | grep -m1 -q 'HTTP.*200'; then 260 | echo 1 261 | else 262 | echo 0 263 | fi 264 | rm -f ${WELLKNOWN_PATH}/letsencrypt_${TIMESTAMP} 265 | } 266 | 267 | if [ "${CSR_CF_FILE}" != "" ] && [ -s ${CSR_CF_FILE} ]; then 268 | if grep -q -m1 '^emailAddress' ${CSR_CF_FILE}; then 269 | EMAIL="`grep '^emailAddress' ${CSR_CF_FILE} | awk '{print $3}'`" 270 | fi 271 | elif [ "${CSR_CF_FILE}" = "" ] && [ -s ${SAN_CONFIG} ]; then 272 | if grep -q -m1 '^emailAddress' ${SAN_CONFIG}; then 273 | EMAIL="`grep '^emailAddress' ${SAN_CONFIG} | awk '{print $3}'`" 274 | fi 275 | fi 276 | 277 | #It could be a symlink, so we use -e 278 | if [ ! -e "${DOMAIN_DIR}" ]; then 279 | echo "${DOMAIN_DIR} does not exist. Exiting..." 280 | exit 1 281 | fi 282 | 283 | #ensure the letsencrypt.key is new enough 284 | if [ -s "${LETSENCRYPT_ACCOUNT_KEY}" ]; then 285 | if [ "${OS}" = "FreeBSD" ]; then 286 | STAT_CMD="/usr/bin/stat -f %m ${LETSENCRYPT_ACCOUNT_KEY}" 287 | else 288 | STAT_CMD="/usr/bin/stat --printf %Y ${LETSENCRYPT_ACCOUNT_KEY}" 289 | fi 290 | 291 | LAST_CHANGED=`${STAT_CMD} 2>/dev/null` 292 | if [ "${LAST_CHANGED}" = "" ]; then 293 | echo "Unable to get last modification time from key using:"; 294 | echo "${STAT_CMD}"; 295 | ${STAT_CMD} 296 | else 297 | #got a number, hopfully. 298 | 299 | if [ "${LAST_CHANGED}" -lt "${LICENSE_KEY_MIN_DATE}" ]; then 300 | echo "${LETSENCRYPT_ACCOUNT_KEY} was older than recent license agreement. Deleting it, and creating a new one"; 301 | rm -f ${LETSENCRYPT_ACCOUNT_KEY} 302 | fi 303 | fi 304 | fi 305 | 306 | #Create account KEY if it does not exist 307 | OLD_KEY=1 308 | if [ ! -s "${LETSENCRYPT_ACCOUNT_KEY}" ]; then 309 | echo "Generating ${KEY_SIZE} bit RSA key for let's encrypt account..." 310 | echo "openssl genrsa ${KEY_SIZE} > \"${LETSENCRYPT_ACCOUNT_KEY}\"" 311 | ${OPENSSL} genrsa ${KEY_SIZE} > "${LETSENCRYPT_ACCOUNT_KEY}" 312 | chown diradmin:diradmin ${LETSENCRYPT_ACCOUNT_KEY} 313 | chmod 600 ${LETSENCRYPT_ACCOUNT_KEY} 314 | OLD_KEY=0 315 | fi 316 | 317 | #We use perl here to convert HEX to BIN 318 | PUBLIC_EXPONENT64=`${OPENSSL} rsa -in "${LETSENCRYPT_ACCOUNT_KEY}" -noout -text | grep "^publicExponent:" | awk '{print $3}' | cut -d'(' -f2 | cut -d')' -f1 | tr -d '\r\n' | tr -d 'x' | perl -n0 -e 's/([0-9a-f]{2})/print chr hex $1/gie' | base64_encode` 319 | PUBLIC_MODULUS64=`${OPENSSL} rsa -in "${LETSENCRYPT_ACCOUNT_KEY}" -noout -modulus | cut -d'=' -f2 | perl -n0 -e 's/([0-9a-f]{2})/print chr hex $1/gie' | base64_encode` 320 | 321 | FOR_THUMBPRINT="{\"e\": \"${PUBLIC_EXPONENT64}\", \"kty\": \"RSA\", \"n\": \"${PUBLIC_MODULUS64}\"}" 322 | HAS_SHA_256=`${OPENSSL} help 2>&1 | grep -c sha256` 323 | if [ "${HAS_SHA_256}" -gt 0 ]; then 324 | THUMBPRINT=`echo -n "${FOR_THUMBPRINT}" | tr -d ' ' | ${OPENSSL} sha256 -binary | base64_encode` 325 | else 326 | THUMBPRINT=`echo -n "${FOR_THUMBPRINT}" | tr -d ' ' | ${OPENSSL} sha -sha256 -binary | base64_encode` 327 | fi 328 | 329 | #Register the new key with the acme-server 330 | if [ ${OLD_KEY} -eq 0 ]; then 331 | send_signed_request "normal" "${API}/acme/new-reg" '{"resource": "new-reg", "contact":["'"mailto:${EMAIL}"'"], "agreement": "'"${LICENSE}"'"}' 332 | if [ "${HTTP_STATUS}" = "" ] || [ "${HTTP_STATUS}" -eq 201 ] ; then 333 | echo "Account has been registered." 334 | elif [ "${HTTP_STATUS}" -eq 409 ] ; then 335 | echo "Account is already registered." 336 | else 337 | echo "Account registration error. Response: ${RESPONSE}." 338 | exit 1 339 | fi 340 | fi 341 | 342 | if [ "${ACTION}" = "revoke" ]; then 343 | if [ ! -e ${CERT} ]; then 344 | echo "Certificate ${CERT} does not exist, there is nothing to revoke." 345 | exit 1 346 | fi 347 | DER64="`${OPENSSL} x509 -in ${CERT} -inform PEM -outform DER | base64_encode`" 348 | send_signed_request "normal" "${API}/acme/revoke-cert" '{"resource": "revoke-cert", "certificate": "'"${DER64}"'"}' 349 | if [ "${HTTP_STATUS}" = "" ] || [ "${HTTP_STATUS}" -eq 200 ] ; then 350 | echo "Certificate has been successfully revoked." 351 | else 352 | echo "Certificate revocation error. Response: ${RESPONSE}." 353 | exit 1 354 | fi 355 | exit 0 356 | fi 357 | 358 | #Overwrite san_config file if csr_cf_file path is different 359 | if [ "${CSR_CF_FILE}" != "" ] && [ "${CSR_CF_FILE}" != "${SAN_CONFIG}" ]; then 360 | cp -f ${CSR_CF_FILE} ${SAN_CONFIG} 361 | fi 362 | 363 | #For multi-domains (www and non-www one) 364 | SAN="" 365 | 366 | if [ -s ${SAN_CONFIG} ] && ! ${DOMAINARR_IN_USE} && ! ${IS_SINGLE}; then 367 | SAN="`cat \"${SAN_CONFIG}\" | grep '^subjectAltName=' | cut -d= -f2`" 368 | elif [ "${HOSTNAME}" -eq 0 ]; then 369 | if ${DOMAINARR_IN_USE} || ${IS_SINGLE}; then 370 | SAN="" 371 | for TDOMAIN in ${DOMAINARR} 372 | do 373 | CHALLENGE_TEST=`challenge_check ${TDOMAIN}` 374 | if [ ${CHALLENGE_TEST} -ne 1 ]; then 375 | SAN="${SAN}, DNS:${TDOMAIN}" 376 | else 377 | echo "skipping ${TDOMAIN} challenge test failed" 378 | fi 379 | done 380 | SAN=`echo ${SAN} | grep -o -E "DNS:(.*)"` 381 | elif ! echo "${DOMAIN}" | grep -q "^www\."; then 382 | #We have a domain without www., add www domain to to SAN too 383 | SAN="DNS:${DOMAIN}, DNS:www.${DOMAIN}" 384 | else 385 | #We have a domain with www., drop www and add it to SAN too 386 | DOMAIN2=`echo ${DOMAIN} | perl -p0 -e 's#^www.##'` 387 | SAN="DNS:${DOMAIN2}, DNS:www.${DOMAIN2}" 388 | fi 389 | else 390 | #For hostname, we add www, mail, ftp, pop, smtp to the SAN 391 | if ${DOMAINARR_IN_USE} || ${IS_SINGLE}; then 392 | SAN="" 393 | for TDOMAIN in ${DOMAINARR} 394 | do 395 | SAN="${SAN}, DNS:${TDOMAIN}" 396 | done 397 | SAN=`echo ${SAN} | egrep -o "DNS:(.*)"` 398 | else 399 | 400 | if ! echo "${DOMAIN}" | grep -q "^www\."; then 401 | #We have a domain without www., add www domain to to SAN too 402 | MAIN_HOST=${DOMAIN} 403 | else 404 | #We have a domain with www., drop www and add it to SAN too 405 | DOMAIN2=`echo ${DOMAIN} | perl -p0 -e 's#^www.##'` 406 | MAIN_HOST=${DOMAIN2} 407 | fi 408 | SAN="DNS:${MAIN_HOST}" 409 | for A in www mail ftp pop smtp; do 410 | { 411 | H=${A}.${MAIN_HOST} 412 | CHALLENGE_TEST=`challenge_check ${H}` 413 | if [ ${CHALLENGE_TEST} -eq 1 ]; then 414 | echo "${H} was skipped due to unreachable http://${H}/.well-known/acme-challenge/letsencrypt_${TIMESTAMP} file. Not adding to san_config"; 415 | else 416 | SAN="${SAN}, DNS:${H}" 417 | fi 418 | }; 419 | done; 420 | fi 421 | fi 422 | 423 | DOMAINS="`echo ${SAN} | tr -d '\",' | perl -p0 -e 's#DNS:##g'`" 424 | CN_DOMAIN=${DOMAIN} 425 | if ! echo "${DOMAINS}" | grep -m1 -q "DNS:${DOMAIN},"; then 426 | CN_DOMAIN="`echo ${SAN} | cut -d':' -f2 | cut -d',' -f1`" 427 | fi 428 | if [ "${CN_DOMAIN}" = "" ]; then 429 | CN_DOMAIN=${DOMAIN} 430 | fi 431 | 432 | #Create san_config 433 | if [ ! -s ${SAN_CONFIG} ] || ${DOMAINARR_IN_USE} || ${IS_SINGLE}; then 434 | echo "[ req_distinguished_name ]" > ${SAN_CONFIG} 435 | echo "CN = ${CN_DOMAIN}" >> ${SAN_CONFIG} 436 | echo "[ req ]" >> ${SAN_CONFIG} 437 | echo "distinguished_name = req_distinguished_name" >> ${SAN_CONFIG} 438 | echo "[SAN]" >> ${SAN_CONFIG} 439 | echo "subjectAltName=${SAN}" >> ${SAN_CONFIG} 440 | fi 441 | 442 | chown diradmin:diradmin ${SAN_CONFIG} 443 | chmod 600 ${SAN_CONFIG} 444 | 445 | #For each of the domains, we need to verify them 446 | for single_domain in ${DOMAINS}; do { 447 | # Connect to the acme-server to get a new challenge token to verify the domain 448 | echo "Getting challenge for ${single_domain} from acme-server..." 449 | send_signed_request "normal" "${API}/acme/new-authz" '{"resource": "new-authz", "identifier": {"type": "dns", "value": "'"${single_domain}"'"}}' 450 | 451 | # poralix 452 | if [ "${HTTP_STATUS}" -ne 201 ] ; then 453 | sleep 1; 454 | ERROR500=$(echo ${RESPONSE} | grep -c 'HTTP/1.1 500 Internal Server Error'); 455 | if [ "${ERROR500}" -ne 0 ]; then 456 | echo "Error 500 occured in authz request: ${RESPONSE}. Trying once again..."; 457 | send_signed_request "normal" "${API}/acme/new-authz" '{"resource": "new-authz", "identifier": {"type": "dns", "value": "'"${single_domain}"'"}}'; 458 | fi; 459 | fi; 460 | 461 | #Account has a key for let's encrypt, but it's not registered 462 | if [ "${HTTP_STATUS}" -eq 403 ] ; then 463 | echo "User let's encrypt key has been found, but not registered. Registering..." 464 | send_signed_request "normal" "${API}/acme/new-reg" '{"resource": "new-reg", "contact":["'"mailto:${EMAIL}"'"], "agreement": "'"${LICENSE}"'"}' 465 | if [ "${HTTP_STATUS}" = "" ] || [ "${HTTP_STATUS}" -eq 201 ] ; then 466 | echo "Account has been registered." 467 | elif [ "${HTTP_STATUS}" -eq 409 ] ; then 468 | echo "Account is already registered." 469 | else 470 | echo "Account registration error. Response: ${RESPONSE}." 471 | exit 1 472 | fi 473 | 474 | echo "Getting challenge for ${DOMAIN} from acme-server..." 475 | send_signed_request "normal" "${API}/acme/new-authz" '{"resource": "new-authz", "identifier": {"type": "dns", "value": "'"${single_domain}"'"}}' 476 | fi 477 | 478 | if [ "${HTTP_STATUS}" -ne 201 ] ; then 479 | echo "new-authz error: ${RESPONSE}. Exiting..." 480 | exit 1 481 | fi 482 | 483 | CHALLENGE="`echo "${RESPONSE}" | awk '/\"type\": \"http-01\"/,/}/'`" 484 | 485 | CHALLENGE_TOKEN="`echo \"${CHALLENGE}\" | tr ',' '\n' | grep -m1 '\"token\":' | cut -d'\"' -f4`" 486 | CHALLENGE_URI="`echo \"${CHALLENGE}\" | tr ',' '\n' | grep -m1 '\"uri\":' | cut -d'\"' -f4`" 487 | CHALLENGE_STATUS="`echo \"${CHALLENGE}\" | tr ',' '\n' | grep -m1 '\"status\":' | cut -d'\"' -f4`" 488 | 489 | KEYAUTH="${CHALLENGE_TOKEN}.${THUMBPRINT}" 490 | 491 | if [ "${DOMAIN_DIR}" = "/var/www/html" ]; then 492 | mkdir -p ${WELLKNOWN_PATH} 493 | chown webapps:webapps ${HOSTNAME_DIR}/.well-known 494 | chown webapps:webapps ${WELLKNOWN_PATH} 495 | fi 496 | 497 | if [ ! -d "${WELLKNOWN_PATH}" ]; then 498 | echo "Cannot find ${WELLKNOWN_PATH}. Create this path, ensure it's chowned to the User."; 499 | exit 1; 500 | fi 501 | 502 | echo "${KEYAUTH}" > "${WELLKNOWN_PATH}/${CHALLENGE_TOKEN}" 503 | 504 | chown webapps:webapps "${WELLKNOWN_PATH}/${CHALLENGE_TOKEN}" 505 | 506 | #Checking if challenge will be reachable 507 | CHALLENGE_TEST=`challenge_check ${single_domain}` 508 | if [ ${CHALLENGE_TEST} -eq 1 ]; then 509 | echo "Error: http://${single_domain}/.well-known/acme-challenge/letsencrypt_${TIMESTAMP} is not reachable. Aborting the script." 510 | echo "dig output for ${single_domain}:" 511 | dig ${single_domain} +short 512 | if [ ${LETSENCRYPT_OPTION} -eq 1 ]; then 513 | echo "Please make sure /.well-known alias is setup in WWW server." 514 | else 515 | echo "Please make sure .htaccess or WWW server is not preventing access to /.well-known folder." 516 | fi 517 | exit 1 518 | fi 519 | 520 | send_signed_request "normal" "${CHALLENGE_URI}" "{\"resource\": \"challenge\", \"keyAuthorization\": \"${KEYAUTH}\"}" 521 | 522 | if [ ${HTTP_STATUS} -ne 202 ] ; then 523 | echo -n "Challenge error: ${RESPONSE}. Trying again..." 524 | for n in `seq 1 5`; do 525 | sleep 1; 526 | echo -n '.'; 527 | done; 528 | echo ""; 529 | send_signed_request "normal" "${CHALLENGE_URI}" "{\"resource\": \"challenge\", \"keyAuthorization\": \"${KEYAUTH}\"}" 530 | fi 531 | 532 | if [ ${HTTP_STATUS} -ne 202 ] ; then 533 | echo "Challenge error: ${RESPONSE}. Exiting..." 534 | exit 1 535 | fi 536 | 537 | echo "Waiting for domain verification..." 538 | while [ "${CHALLENGE_STATUS}" = "pending" ]; do 539 | sleep 1 540 | FULL_CHALLENGE_STATUS="`${CURL} ${CURL_OPTIONS} --silent -X GET \"${CHALLENGE_URI}\"`" 541 | CHALLENGE_STATUS="`echo ${FULL_CHALLENGE_STATUS} | tr ',' '\n' | grep -m1 '\"status\":' | cut -d'\"' -f4`" 542 | CHALLENGE_DETAIL="`echo ${FULL_CHALLENGE_STATUS} | tr ',' '\n' | grep -m1 '\"detail\":' | cut -d'\"' -f4`" 543 | done 544 | 545 | rm -f "${WELLKNOWN_PATH}/${CHALLENGE_TOKEN}" 546 | 547 | if [ "${CHALLENGE_STATUS}" = "valid" ]; then 548 | echo "Challenge is valid." 549 | else 550 | echo "Challenge is ${CHALLENGE_STATUS}. Details: ${CHALLENGE_DETAIL}. Exiting..." 551 | exit 1 552 | fi 553 | 554 | # poralix 555 | echo -n "Sleep some "; 556 | for n in `seq 1 5`; do 557 | sleep 1; 558 | echo -n '.'; 559 | done; 560 | echo ''; 561 | } 562 | done 563 | 564 | #Create domain key, also generate CSR for the domain 565 | echo "Generating ${KEY_SIZE} bit RSA key for ${DOMAIN}..." 566 | echo "openssl genrsa ${KEY_SIZE} > \"${KEY}.new\"" 567 | ${OPENSSL} genrsa ${KEY_SIZE} > "${KEY}.new" 568 | 569 | ${OPENSSL} req -new -sha256 -key "${KEY}.new" -subj "/CN=${CN_DOMAIN}" -reqexts SAN -config "${SAN_CONFIG}" -out "${CSR}" 570 | 571 | #Request certificate from let's encrypt 572 | DER64="`${OPENSSL} req -in ${CSR} -outform DER | base64_encode`" 573 | 574 | send_signed_request "cert" "${API}/acme/new-cert" "{\"resource\": \"new-cert\", \"csr\": \"${DER64}\"}" 575 | 576 | SIZE_OF_CERT64="`echo ${CERT64} | wc -c`" 577 | #It's likely text encoded if there are less than 500 chars, so we have a JSON response 578 | if [ ${SIZE_OF_CERT64} -lt 500 ]; then 579 | echo "Size of certificate response is smaller than 500 characters, it means something went wrong. Printing response..." 580 | echo "${CERT64}" | ${OPENSSL} enc -base64 -d | grep -o '"detail": "[^,]*"' 581 | echo "" 582 | exit 1 583 | fi 584 | 585 | echo "-----BEGIN CERTIFICATE-----" > ${CERT}.new 586 | echo "${CERT64}" >> ${CERT}.new 587 | echo "-----END CERTIFICATE-----" >> ${CERT}.new 588 | 589 | ${OPENSSL} x509 -text < ${CERT}.new > /dev/null 590 | if [ $? -ne 0 ]; then 591 | echo "Certificate error in ${CERT}. Exiting..." 592 | /bin/rm -f ${KEY}.new ${CERT}.new 593 | exit 1 594 | fi 595 | 596 | getCacert() { 597 | CACERT64=`${CURL} -k --silent -X GET "${API}/acme/issuer-cert" | ${OPENSSL} base64 -e` 598 | SIZE_OF_CACERT64="`echo ${CERT64} | wc -c`" 599 | if [ ${SIZE_OF_CACERT64} -gt 500 ]; then 600 | echo "-----BEGIN CERTIFICATE-----" > ${CACERT}.new 601 | echo "${CACERT64}" >> ${CACERT}.new 602 | echo "-----END CERTIFICATE-----" >> ${CACERT}.new 603 | fi 604 | } 605 | 606 | getCacert 607 | CACERT_LINES=`cat ${CACERT}.new | wc -l` 608 | if [ ${CACERT_LINES} -lt 4 ]; then 609 | echo "Unable to retrieve CA root cert. Retrying..." 610 | getCacert 611 | fi 612 | 613 | CACERT_LINES=`cat ${CACERT}.new | wc -l` 614 | if [ ${CACERT_LINES} -lt 4 ]; then 615 | echo "Retry for CA root cert failed." 616 | if [ -s ${CACERT} ]; then 617 | echo "Using old CA root certificate ${CACERT}." 618 | rm -f ${CACERT}.new 619 | else 620 | echo "Exiting.." 621 | exit 1 622 | fi 623 | fi 624 | 625 | echo -n "Checking Certificate Private key match... " 626 | CHECKPRIVPUBRES=`checkPrivPubMatch ${KEY}.new ${CERT}.new` 627 | if [ $CHECKPRIVPUBRES -ne 1 ]; then 628 | echo "Match!" 629 | else 630 | echo "!!!Certificate mismatch" 631 | exit 1 632 | fi 633 | 634 | #everything went well, move the new files. 635 | /bin/mv -f ${KEY}.new ${KEY} 636 | /bin/mv -f ${CERT}.new ${CERT} 637 | if [ -s ${CACERT}.new ]; then 638 | /bin/mv -f ${CACERT}.new ${CACERT} 639 | fi 640 | if [ ! -s ${CACERT} ]; then 641 | echo "-----BEGIN CERTIFICATE----- 642 | MIIEkjCCA3qgAwIBAgIQCgFBQgAAAVOFc2oLheynCDANBgkqhkiG9w0BAQsFADA/ 643 | MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT 644 | DkRTVCBSb290IENBIFgzMB4XDTE2MDMxNzE2NDA0NloXDTIxMDMxNzE2NDA0Nlow 645 | SjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUxldCdzIEVuY3J5cHQxIzAhBgNVBAMT 646 | GkxldCdzIEVuY3J5cHQgQXV0aG9yaXR5IFgzMIIBIjANBgkqhkiG9w0BAQEFAAOC 647 | AQ8AMIIBCgKCAQEAnNMM8FrlLke3cl03g7NoYzDq1zUmGSXhvb418XCSL7e4S0EF 648 | q6meNQhY7LEqxGiHC6PjdeTm86dicbp5gWAf15Gan/PQeGdxyGkOlZHP/uaZ6WA8 649 | SMx+yk13EiSdRxta67nsHjcAHJyse6cF6s5K671B5TaYucv9bTyWaN8jKkKQDIZ0 650 | Z8h/pZq4UmEUEz9l6YKHy9v6Dlb2honzhT+Xhq+w3Brvaw2VFn3EK6BlspkENnWA 651 | a6xK8xuQSXgvopZPKiAlKQTGdMDQMc2PMTiVFrqoM7hD8bEfwzB/onkxEz0tNvjj 652 | /PIzark5McWvxI0NHWQWM6r6hCm21AvA2H3DkwIDAQABo4IBfTCCAXkwEgYDVR0T 653 | AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwfwYIKwYBBQUHAQEEczBxMDIG 654 | CCsGAQUFBzABhiZodHRwOi8vaXNyZy50cnVzdGlkLm9jc3AuaWRlbnRydXN0LmNv 655 | bTA7BggrBgEFBQcwAoYvaHR0cDovL2FwcHMuaWRlbnRydXN0LmNvbS9yb290cy9k 656 | c3Ryb290Y2F4My5wN2MwHwYDVR0jBBgwFoAUxKexpHsscfrb4UuQdf/EFWCFiRAw 657 | VAYDVR0gBE0wSzAIBgZngQwBAgEwPwYLKwYBBAGC3xMBAQEwMDAuBggrBgEFBQcC 658 | ARYiaHR0cDovL2Nwcy5yb290LXgxLmxldHNlbmNyeXB0Lm9yZzA8BgNVHR8ENTAz 659 | MDGgL6AthitodHRwOi8vY3JsLmlkZW50cnVzdC5jb20vRFNUUk9PVENBWDNDUkwu 660 | Y3JsMB0GA1UdDgQWBBSoSmpjBH3duubRObemRWXv86jsoTANBgkqhkiG9w0BAQsF 661 | AAOCAQEA3TPXEfNjWDjdGBX7CVW+dla5cEilaUcne8IkCJLxWh9KEik3JHRRHGJo 662 | uM2VcGfl96S8TihRzZvoroed6ti6WqEBmtzw3Wodatg+VyOeph4EYpr/1wXKtx8/ 663 | wApIvJSwtmVi4MFU5aMqrSDE6ea73Mj2tcMyo5jMd6jmeWUHK8so/joWUoHOUgwu 664 | X4Po1QYz+3dszkDqMp4fklxBwXRsW10KXzPMTZ+sOPAveyxindmjkW8lGy+QsRlG 665 | PfZ+G6Z6h7mjem0Y+iWlkYcV4PIWL1iwBi8saCbGS5jN2p8M+X+Q7UNKEkROb3N6 666 | KOqkqm57TH2H3eDJAkSnh6/DNFu0Qg== 667 | -----END CERTIFICATE-----" > ${CACERT} 668 | fi 669 | date +%s > ${CERT}.creation_time 670 | 671 | cat ${CERT} ${CACERT} > ${CERT}.combined 672 | 673 | chown ${FILE_CHOWN} ${KEY} ${CERT} ${CERT}.combined ${CACERT} ${CSR} ${CERT}.creation_time 674 | chmod ${FILE_CHMOD} ${KEY} ${CERT} ${CERT}.combined ${CACERT} ${CSR} ${CERT}.creation_time 675 | 676 | #Change exim, apache/nginx certs 677 | if [ "${HOSTNAME}" -eq 1 ]; then 678 | echo "DirectAdmin certificate has been setup." 679 | 680 | #Exim 681 | echo "Setting up cert for Exim..." 682 | EXIMKEY="/etc/exim.key" 683 | EXIMCERT="/etc/exim.cert" 684 | cp -f ${KEY} ${EXIMKEY} 685 | cat ${CERT} ${CACERT} > ${EXIMCERT} 686 | chown mail:mail ${EXIMKEY} ${EXIMCERT} 687 | chmod 600 ${EXIMKEY} ${EXIMCERT} 688 | 689 | echo "action=exim&value=restart" >> ${TASKQ} 690 | echo "action=dovecot&value=restart" >> ${TASKQ} 691 | 692 | #Apache 693 | echo "Setting up cert for WWW server..." 694 | if [ -d /etc/httpd/conf/ssl.key ] && [ -d /etc/httpd/conf/ssl.crt ]; then 695 | APACHEKEY="/etc/httpd/conf/ssl.key/server.key" 696 | APACHECERT="/etc/httpd/conf/ssl.crt/server.crt" 697 | APACHECACERT="/etc/httpd/conf/ssl.crt/server.ca" 698 | APACHECERTCOMBINED="${APACHECERT}.combined" 699 | cp -f ${KEY} ${APACHEKEY} 700 | cp -f ${CERT} ${APACHECERT} 701 | cp -f ${CACERT} ${APACHECACERT} 702 | cat ${APACHECERT} ${APACHECACERT} > ${APACHECERTCOMBINED} 703 | chown root:root ${APACHEKEY} ${APACHECERT} ${APACHECACERT} ${APACHECERTCOMBINED} 704 | chmod 600 ${APACHEKEY} ${APACHECERT} ${APACHECACERT} ${APACHECERTCOMBINED} 705 | 706 | echo "action=httpd&value=restart" >> ${TASKQ} 707 | fi 708 | 709 | #Nginx 710 | if [ -d /etc/nginx/ssl.key ] && [ -d /etc/nginx/ssl.crt ]; then 711 | NGINXKEY="/etc/nginx/ssl.key/server.key" 712 | NGINXCERT="/etc/nginx/ssl.crt/server.crt" 713 | NGINXCACERT="/etc/nginx/ssl.crt/server.ca" 714 | NGINXCERTCOMBINED="${NGINXCERT}.combined" 715 | cp -f ${KEY} ${NGINXKEY} 716 | cp -f ${CERT} ${NGINXCERT} 717 | cp -f ${CACERT} ${NGINXCACERT} 718 | cat ${NGINXCERT} ${NGINXCACERT} > ${NGINXCERTCOMBINED} 719 | chown root:root ${NGINXKEY} ${NGINXCERT} ${NGINXCACERT} ${NGINXCERTCOMBINED} 720 | chmod 600 ${NGINXKEY} ${NGINXCERT} ${NGINXCACERT} ${NGINXCERTCOMBINED} 721 | 722 | echo "action=nginx&value=restart" >> ${TASKQ} 723 | fi 724 | 725 | #FTP 726 | echo "Setting up cert for FTP server..." 727 | cat ${KEY} ${CERT} ${CACERT} > /etc/pure-ftpd.pem 728 | chmod 600 /etc/pure-ftpd.pem 729 | chown root:root /etc/pure-ftpd.pem 730 | 731 | if /usr/local/directadmin/directadmin c | grep -m1 -q "^pureftp=1\$"; then 732 | echo "action=pure-ftpd&value=restart" >> ${TASKQ} 733 | else 734 | echo "action=proftpd&value=restart" >> ${TASKQ} 735 | fi 736 | 737 | echo "action=directadmin&value=restart" >> ${TASKQ} 738 | 739 | echo "The services will be restarted in about 1 minute via the dataskq." 740 | fi 741 | 742 | echo "Certificate for ${DOMAIN} has been created successfully!" 743 | exit 0 744 | -------------------------------------------------------------------------------- /letsencrypt/poralix_patch_chain.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #---------------------------------------------------------------------- 3 | # Description: A script to force Let's Encrypt to use DST Root CA X3 4 | #---------------------------------------------------------------------- 5 | # Author: Alex Grebenschikov, www.poralix.com 6 | # Created at: Fri Dec 16 17:45:36 +07 2022 7 | # Last modified: Fri Dec 16 17:45:36 +07 2022 8 | # Version: 0.1 $ Fri Dec 16 17:45:36 +07 2022 9 | #---------------------------------------------------------------------- 10 | # Copyright (c) 2022 Alex Grebenschikov, www.poralix.com 11 | 12 | # INSTALLATION: 13 | # ===================================================================== 14 | # RUN AS ROOT: 15 | # ===================================================================== 16 | # mkdir -p /usr/local/directadmin/custombuild/custom/hooks/letsencrypt/post/ 17 | # cd /usr/local/directadmin/custombuild/custom/hooks/letsencrypt/post/ 18 | # 19 | # COPY/MOVE FILE TO THE CREATED FOLDER AND RUN: 20 | # 21 | # wget -O poralix_patch_chain.sh https://raw.githubusercontent.com/poralix/directadmin-utils/master/letsencrypt/poralix_patch_chain.sh 22 | # chmod 750 poralix_patch_chain.sh 23 | # /usr/local/directadmin/custombuild/build letsencrypt 24 | # 25 | 26 | echo ""; 27 | echo "Running patch script from Poralix:"; 28 | echo ""; 29 | 30 | set -x; 31 | \cp -fp /usr/local/directadmin/scripts/letsencrypt.sh{,~orig}; 32 | perl -pi -e "s/ISRG Root X1/DST Root CA X3/" /usr/local/directadmin/scripts/letsencrypt.sh; 33 | -------------------------------------------------------------------------------- /misc/README.md: -------------------------------------------------------------------------------- 1 | # A script to manage private_html directories on Directadmin servers # 2 | 3 | - private_html_symlink.sh 4 | 5 | ``` 6 | Usage ./private_html_symlink.sh 7 | --list=all - list private_html status for all domains 8 | --list=dirs - list only domains with static folder for private_html 9 | --list=links - list only domains with symlink for private_html 10 | --list=no - list only domains without private_html at all 11 | 12 | --create-symlink=dirs - Replace directory private_html with a symlink 13 | --create-symlink=no - Create symlink private_html where it does not exist 14 | ``` 15 | 16 | # A script to list DirectAdmin domains 17 | 18 | - da_domains.sh 19 | 20 | ``` 21 | Description: 22 | This is a script to list directadmin domains with a requested from 23 | DNS additional information. 24 | 25 | Usage: 26 | ./da_domains.sh 27 | 28 | Options: 29 | --domains - just list domains without DNS queries 30 | --ns - list domains with their nameservers 31 | --mx - list domains with their MX records 32 | --ip4 - list domains with their IPv4 33 | --ip6 - list domains with their IPv6 34 | ``` 35 | 36 | -------------------------------------------------------------------------------- /misc/da_domains.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #---------------------------------------------------------------------- 3 | # Description: A script for listing all domains from DirectAdmin 4 | #---------------------------------------------------------------------- 5 | # Author: Alex Grebenschikov, www.poralix.com 6 | # Created at: Mon Oct 31 13:21:06 +07 2022 7 | # Last modified: Fri Dec 16 17:27:30 +07 2022 8 | # Version: 0.2.1 $ Mon Nov 21 11:44:46 +07 2022 9 | #---------------------------------------------------------------------- 10 | # Copyright (c) 2022 Alex Grebenschikov, www.poralix.com 11 | #---------------------------------------------------------------------- 12 | 13 | DNS_RESOLVER="1.1.1.1"; 14 | 15 | die() 16 | { 17 | echo $1; 18 | exit $2; 19 | } 20 | 21 | usage() 22 | { 23 | echo "#---------------------------------------------------------------------- 24 | # Copyright (c) 2022 Alex Grebenschikov, www.poralix.com 25 | #---------------------------------------------------------------------- 26 | 27 | Description: 28 | This is a script to list directadmin domains with a requested from 29 | DNS additional information. 30 | 31 | Usage: 32 | $0 33 | 34 | Options: 35 | --domains - just list domains without DNS queries 36 | --ns - list domains with their nameservers 37 | --mx - list domains with their MX records 38 | --ip4 - list domains with their IPv4 39 | --ip6 - list domains with their IPv6 40 | "; 41 | exit 0; 42 | } 43 | 44 | domains() 45 | { 46 | for DOM in $(awk -F: {'print $1'} /etc/virtual/domainowners | sort | uniq); do echo - $DOM; done 47 | } 48 | 49 | nameservers() 50 | { 51 | for DOM in $(awk -F: {'print $1'} /etc/virtual/domainowners | sort | uniq); do echo - $DOM: $(dig +short NS "@${DNS_RESOLVER}" "${DOM}" | sort | xargs); done 52 | } 53 | 54 | ip4() 55 | { 56 | for DOM in $(awk -F: {'print $1'} /etc/virtual/domainowners | sort | uniq); do echo - $DOM: $(dig +short A "@${DNS_RESOLVER}" "${DOM}" | sort | xargs); done 57 | } 58 | 59 | ip6() 60 | { 61 | for DOM in $(awk -F: {'print $1'} /etc/virtual/domainowners | sort | uniq); do echo - $DOM: $(dig +short AAAA "@${DNS_RESOLVER}" "${DOM}" | sort | xargs); done 62 | } 63 | 64 | mx() 65 | { 66 | for DOM in $(awk -F: {'print $1'} /etc/virtual/domainowners | sort | uniq); do echo - $DOM: $(dig +short MX "@${DNS_RESOLVER}" "${DOM}" | sort | xargs); done 67 | } 68 | 69 | run_cmd() 70 | { 71 | case $1 in 72 | domains) 73 | domains; 74 | ;; 75 | nameservers) 76 | nameservers; 77 | ;; 78 | ip4) 79 | ip4; 80 | ;; 81 | ip6) 82 | ip6; 83 | ;; 84 | mx) 85 | mx; 86 | ;; 87 | usage|*) 88 | usage; 89 | ;; 90 | esac; 91 | } 92 | 93 | test -e "/etc/virtual/domainowners" || die "Error: Not a directadmin server?" 1; 94 | 95 | RUN=""; 96 | 97 | for CMD in $@ 98 | do 99 | case $CMD in 100 | --only-domains|--domains) 101 | RUN="domains"; 102 | ;; 103 | --ns) 104 | RUN="nameservers"; 105 | ;; 106 | --ip4) 107 | RUN="ip4"; 108 | ;; 109 | --ip6) 110 | RUN="ip6"; 111 | ;; 112 | --mx) 113 | RUN="mx"; 114 | ;; 115 | --help) 116 | RUN="usage"; 117 | ;; 118 | esac; 119 | done; 120 | 121 | run_cmd "${RUN}"; 122 | 123 | exit 0; 124 | -------------------------------------------------------------------------------- /misc/private_html_symlink.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | ####################################################################################### 3 | # # 4 | # A script to manage private_html directories on Directadmin servers # 5 | # # 6 | ####################################################################################### 7 | # # 8 | # Version: 0.1 (Thu Aug 31 18:12:01 +07 2017) # 9 | # Written by: Alex S Grebenschikov (zEitEr) # 10 | # Site: www.poralix.com E-mail: support@poralix.com # 11 | # # 12 | ####################################################################################### 13 | ####################################################################################### 14 | ## # 15 | ## MIT License # 16 | ## # 17 | ## Copyright (c) 2016 Alex S Grebenschikov (www.poralix.com) # 18 | ## # 19 | ## Permission is hereby granted, free of charge, to any person obtaining a copy # 20 | ## of this software and associated documentation files (the "Software"), to deal # 21 | ## in the Software without restriction, including without limitation the rights # 22 | ## to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # 23 | ## copies of the Software, and to permit persons to whom the Software is # 24 | ## furnished to do so, subject to the following conditions: # 25 | ## # 26 | ## The above copyright notice and this permission notice shall be included in all # 27 | ## copies or substantial portions of the Software. # 28 | ## # 29 | ## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # 30 | ## IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # 31 | ## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # 32 | ## AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # 33 | ## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # 34 | ## OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # 35 | ## SOFTWARE. # 36 | ## # 37 | ####################################################################################### 38 | 39 | function usage() 40 | { 41 | echo " 42 | ###################################################################################### 43 | # A script to manage private_html directories on Directadmin servers # 44 | # Written by: Alex S Grebenschikov (zEitEr) # 45 | ###################################################################################### 46 | 47 | Usage $0 48 | --list - list private_html status for all domains 49 | --list-dirs - list only domains with static folder for private_html 50 | --list-links - list only domains with symlink for private_html 51 | --list-no - list only domains without private_html at all 52 | 53 | --create-symlink=dirs - Replace directory private_html with a symlink 54 | --create-symlink=no - Create symlink private_html where it does not exist 55 | "; 56 | } 57 | 58 | function doList() 59 | { 60 | for DH in `ls -d1 /home/*/domains/*/ 2>/dev/null | egrep -v "/shared/|/suspended/|/default/|/sharedip/" | sort`; 61 | do 62 | DOMAIN=$(echo ${DH} | cut -d\/ -f5); 63 | if [ -L "${DH}/private_html" ]; then 64 | [ "${1}" == "links" ] && echo "[S] Domain ${DOMAIN} has private_html symlink in ${DH}"; 65 | elif [ -d "${DH}/private_html" ]; then 66 | [ "${1}" == "dirs" ] && echo "[D] Domain ${DOMAIN} has private_html folder in ${DH}"; 67 | else 68 | [ "${1}" == "no" ] && echo "[-] Domain ${DOMAIN} has no private_html folder in ${DH}"; 69 | fi; 70 | done; 71 | } 72 | 73 | function doCreateSymlink() 74 | { 75 | for DH in `ls -d1 /home/*/domains/*/ 2>/dev/null | egrep -v "/shared/|/suspended/|/default/|/sharedip/" | sort`; 76 | do 77 | USER=$(echo ${DH} | cut -d\/ -f3); 78 | DOMAIN=$(echo ${DH} | cut -d\/ -f5); 79 | 80 | if [ -L "${DH}/private_html" ]; then 81 | { 82 | [ "${1}" == "links" ] && echo "[-] Skipping domain ${DOMAIN}"; 83 | } 84 | elif [ -d "${DH}/private_html" ]; then 85 | { 86 | if [ "${1}" == "dirs" ]; then 87 | { 88 | mv "${DH}/private_html" "${DH}/private_html.old"; 89 | echo "[+] Moved existing private_html to private_html.old for domain ${DOMAIN}"; 90 | ln -s public_html ${DH}/private_html; 91 | echo "[+] Created symlink to public_html for domain ${DOMAIN} under ${DH}"; 92 | chown -h ${USER}:${USER} ${DH}/private_html; 93 | } 94 | fi; 95 | } 96 | else 97 | { 98 | if [ "${1}" == "no" ]; then 99 | { 100 | ln -s public_html ${DH}/private_html; 101 | chown -h ${USER}:${USER} ${DH}/private_html; 102 | echo "[+] Created symlink to public_html for domain ${DOMAIN} under ${DH}"; 103 | } 104 | fi; 105 | } 106 | fi; 107 | done; 108 | } 109 | 110 | case "${1}" in 111 | --list=all|--list) 112 | doList dirs; 113 | doList links; 114 | doList no; 115 | ;; 116 | --list=dirs|--list-dirs) 117 | doList dirs; 118 | ;; 119 | --list=links|--list-links) 120 | doList links; 121 | ;; 122 | --list=no|--list-no) 123 | doList no; 124 | ;; 125 | --create-symlink=dirs) 126 | doCreateSymlink dirs; 127 | ;; 128 | --create-symlink=no) 129 | doCreateSymlink no; 130 | ;; 131 | *) 132 | usage; 133 | ;; 134 | esac; 135 | 136 | exit 0; 137 | -------------------------------------------------------------------------------- /nginx/README.md: -------------------------------------------------------------------------------- 1 | # directadmin-utils 2 | 3 | A set of scripts for using on Directadmin servers with CustomBuild 2 or as self-standing solutions. 4 | If you need custom installation or support please feel free to request it here or on our site http://www.poralix.com/ 5 | 6 | # Structure 7 | 8 | **./nginx/build_nginx** - A script to install either stable or mainline version of NGINX with custombuild2. 9 | 10 | - A version number of NGINX mainline is taken from NGINX's trac site. 11 | - A version number of NGINX stable is taken from the official NGINX's repository for CentOS 7 12 | 13 | **./nginx/build_nginx2** - A script to install a mainline version of NGINX with custombuild2. 14 | A version number of NGINX mainline is taken from versions.txt of Directadmin. 15 | 16 | # Installation of script for NGINX mainline 17 | 18 | for version 1: 19 | 20 | ``` 21 | cd /usr/local/directadmin/custombuild/ 22 | wget https://raw.githubusercontent.com/poralix/directadmin-utils/master/nginx/build_nginx -O /usr/local/directadmin/custombuild/build_nginx 23 | chmod 755 ./build_nginx 24 | ./build_nginx 25 | ``` 26 | 27 | for version 2: 28 | 29 | ``` 30 | cd /usr/local/directadmin/custombuild/ 31 | wget https://raw.githubusercontent.com/poralix/directadmin-utils/master/nginx/build_nginx2 -O /usr/local/directadmin/custombuild/build_nginx2 32 | chmod 755 ./build_nginx2 33 | ./build_nginx2 34 | ``` 35 | 36 | # NGINX 1.13.x with TLSv1.3 and Directadmin 37 | 38 | Instructions: https://help.poralix.com/articles/nginx-with-tlsv1.3-on-directadmin-server 39 | -------------------------------------------------------------------------------- /nginx/build_nginx: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | ####################################################################################### 3 | # # 4 | # A script to install a mainline/stable version of NGINX with custombuild2 # 5 | # A version number of NGINX mainline is taken from NGINX's trac site # 6 | # # 7 | ####################################################################################### 8 | # # 9 | # Version: 0.4.1 (Fri Dec 16 13:08:32 +07 2022) # 10 | # Written by: Alex S Grebenschikov (zEitEr) # 11 | # Site: www.poralix.com E-mail: support@poralix.com # 12 | # # 13 | ####################################################################################### 14 | ####################################################################################### 15 | ## # 16 | ## MIT License # 17 | ## # 18 | ## Copyright (c) 2016-2022 Alex S Grebenschikov (www.poralix.com) # 19 | ## # 20 | ## Permission is hereby granted, free of charge, to any person obtaining a copy # 21 | ## of this software and associated documentation files (the "Software"), to deal # 22 | ## in the Software without restriction, including without limitation the rights # 23 | ## to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # 24 | ## copies of the Software, and to permit persons to whom the Software is # 25 | ## furnished to do so, subject to the following conditions: # 26 | ## # 27 | ## The above copyright notice and this permission notice shall be included in all # 28 | ## copies or substantial portions of the Software. # 29 | ## # 30 | ## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # 31 | ## IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # 32 | ## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # 33 | ## AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # 34 | ## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # 35 | ## OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # 36 | ## SOFTWARE. # 37 | ## # 38 | ####################################################################################### 39 | 40 | function usage() 41 | { 42 | 43 | echo "########################################################################"; 44 | echo "# #"; 45 | echo "# A script to install either a mainline or stable version of NGINX #"; 46 | echo "# for Directadmin Custombuild2 #"; 47 | echo "# A version of NGINX mainline will be installed by default #"; 48 | echo "# Version: 0.4.1 (Fri Dec 16 13:08:32 +07 2022) #"; 49 | echo "# Written by: Alex S Grebenschikov (zEitEr) #"; 50 | echo "# #"; 51 | echo "########################################################################"; 52 | echo ""; 53 | echo "Usage:"; 54 | echo " $0 versions - to update information of available mainline version "; 55 | echo " $0 download - to download the latest available mainline version "; 56 | echo " $0 install - to download and install the latest mainline version"; 57 | echo " $0 cron - to run with cron (no installation is done here)"; 58 | echo " $0 set-cron - to install a cron-task to run 'cron --${BRANCH}' nightly"; 59 | echo ""; 60 | echo "Branches (optional):" 61 | echo " --mainline - (default value) actively developed, includes new features"; 62 | echo " --stable - stabe version, recieves only bug-fixes"; 63 | } 64 | 65 | function update_versions() 66 | { 67 | update_version_stable; 68 | update_version_mainline; 69 | 70 | cd /usr/local/directadmin/custombuild; 71 | cat "custom_versions.txt" | grep -Ev "^nginx:|^nginx_stable:|^nginx_mainline:|^$" > "custom_versions.txt.new"; 72 | 73 | if [ "${BRANCH}" == "mainline" ]; then 74 | NGINX_VER="${NGINX_VER_MAINLINE}"; 75 | else 76 | NGINX_VER="${NGINX_VER_STABLE}"; 77 | fi; 78 | 79 | [ -n "${NGINX_VER_MAINLINE}" ] && echo "nginx_mainline:${NGINX_VER_MAINLINE}:" >> custom_versions.txt.new; 80 | [ -n "${NGINX_VER_STABLE}" ] && echo "nginx_stable:${NGINX_VER_STABLE}:" >> custom_versions.txt.new; 81 | [ -n "${NGINX_VER}" ] && echo "nginx:${NGINX_VER}:" >> "custom_versions.txt.new"; 82 | 83 | mv -f "custom_versions.txt.new" "custom_versions.txt"; 84 | } 85 | 86 | function update_version_mainline() 87 | { 88 | VERSIONS_FILES=""; 89 | VERSIONS_FILES="${VERSIONS_FILES} https://raw.githubusercontent.com/nginx/nginx/master/.hgtags"; # GitHub 90 | VERSIONS_FILES="${VERSIONS_FILES} https://trac.nginx.org/nginx/export/HEAD/nginx/.hgtags"; # TRAC 91 | VERSIONS_FILES="${VERSIONS_FILES} https://hg.nginx.org/nginx/raw-file/tip/.hgtags"; # Official Mercurial Mirror 92 | 93 | # Version number of installed NGINX 94 | NGINX_INSTALLED_VER=$(nginx -v 2>&1 | cut -d\/ -f2); 95 | 96 | for VERSIONS_FILE in ${VERSIONS_FILES}; 97 | do 98 | { 99 | NGINX_VER_MAINLINE=$(wget -q ${VERSIONS_FILE} -O - | tail -1 | cut -d\- -f2 | grep -o '[0-9]*\.[0-9]*\.[0-9]*'); 100 | [ -n "${NGINX_VER_MAINLINE}" ] && break; 101 | } 102 | done; 103 | } 104 | 105 | function update_version_stable() 106 | { 107 | # Version number of installed NGINX 108 | NGINX_INSTALLED_VER=$(nginx -v 2>&1 | cut -d\/ -f2); 109 | NGINX_VER_STABLE=$(/bin/curl -s http://nginx.org/packages/centos/7/x86_64/RPMS/ | grep -o "nginx-[0-9]*\.[0-9]*\.[0-9]*-[0-9]*\.el7[_0-9]*\.ngx.x86_64.rpm" | cut -d\- -f2 | sort --version-sort | tail -1); 110 | 111 | } 112 | 113 | function show_versions() 114 | { 115 | echo "Latest stable version of Nginx: ${NGINX_VER_STABLE} ${SELECTED_STABLE}"; 116 | echo "Latest mainline version of Nginx: ${NGINX_VER_MAINLINE} ${SELECTED_MAINLINE}"; 117 | echo "Installed version of Nginx: ${NGINX_INSTALLED_VER}"; 118 | } 119 | 120 | function download_nginx() 121 | { 122 | cd /usr/local/directadmin/custombuild; 123 | wget https://nginx.org/download/nginx-${NGINX_VER}.tar.gz -O nginx-${NGINX_VER}.tar.gz; 124 | } 125 | 126 | function install_nginx() 127 | { 128 | cd /usr/local/directadmin/custombuild; 129 | ./build update; 130 | 131 | # Custombuild ignores downloaded packages, and tries to download them again 132 | # so we need to patch it to use already downloaded package 133 | perl -pi -e 's|safeDownloadWithMove "\$\{CWD\}/nginx-|#safeDownloadWithMove "\$\{CWD\}/nginx-|' /usr/local/directadmin/custombuild/build; 134 | perl -pi -e 's|safeDownloadWithMove "\$\{WORKDIR\}/nginx-|#safeDownloadWithMove "\$\{WORKDIR\}/nginx-|' /usr/local/directadmin/custombuild/build; 135 | 136 | ./build nginx; 137 | 138 | # Bring custombuild script back to the original view after we completed nginx installation 139 | perl -pi -e 's|#safeDownloadWithMove "\$\{CWD\}/nginx-|safeDownloadWithMove "\$\{CWD\}/nginx-|' /usr/local/directadmin/custombuild/build; 140 | perl -pi -e 's|#safeDownloadWithMove "\$\{WORKDIR\}/nginx-|safeDownloadWithMove "\$\{WORKDIR\}/nginx-|' /usr/local/directadmin/custombuild/build; 141 | } 142 | 143 | function set_cron() 144 | { 145 | cd /usr/local/directadmin/custombuild/ 146 | wget https://raw.githubusercontent.com/poralix/directadmin-utils/master/nginx/build_nginx -O ./build_nginx 147 | chmod 755 ./build_nginx 148 | 149 | touch /etc/cron.d/0build_nginx; 150 | chmod 644 /etc/cron.d/0build_nginx; 151 | echo "21 4 * * * root /usr/local/directadmin/custombuild/build_nginx cron --${BRANCH}" > /etc/cron.d/0build_nginx; 152 | } 153 | 154 | BRANCH="mainline"; 155 | SELECTED_MAINLINE="(selected)"; 156 | SELECTED_STABLE=""; 157 | 158 | for arg in $@; 159 | do 160 | case ${arg} in 161 | --stable) 162 | BRANCH="stable"; 163 | SELECTED_MAINLINE=""; 164 | SELECTED_STABLE="(selected)"; 165 | ;; 166 | --mainline|*) 167 | BRANCH="mainline"; 168 | SELECTED_MAINLINE="(selected)"; 169 | SELECTED_STABLE=""; 170 | ;; 171 | esac; 172 | done; 173 | 174 | case "$1" in 175 | "download") 176 | update_versions; 177 | download_nginx; 178 | ;; 179 | "cron") 180 | update_versions >/dev/null 2>&1; 181 | download_nginx >/dev/null 2>&1; 182 | ;; 183 | "versions") 184 | update_versions; 185 | show_versions; 186 | ;; 187 | "install") 188 | update_versions; 189 | download_nginx; 190 | install_nginx; 191 | ;; 192 | "set-cron") 193 | set_cron; 194 | ;; 195 | *) 196 | usage; 197 | ;; 198 | esac; 199 | 200 | exit 0; 201 | -------------------------------------------------------------------------------- /nginx/build_nginx2: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | ####################################################################################### 3 | # # 4 | # A script to install a mainline version of NGINX with custombuild2 # 5 | # A version number of NGINX mainline is taken from versions.txt # 6 | # # 7 | ####################################################################################### 8 | # # 9 | # Version: 2.0 (Tue Oct 4 17:06:49 +07 2016) # 10 | # Written by: Alex S Grebenschikov (zEitEr) # 11 | # Site: www.poralix.com E-mail: support@poralix.com # 12 | # # 13 | # # 14 | ####################################################################################### 15 | ####################################################################################### 16 | ## # 17 | ## MIT License # 18 | ## # 19 | ## Copyright (c) 2016 Alex S Grebenschikov (www.poralix.com) # 20 | ## # 21 | ## Permission is hereby granted, free of charge, to any person obtaining a copy # 22 | ## of this software and associated documentation files (the "Software"), to deal # 23 | ## in the Software without restriction, including without limitation the rights # 24 | ## to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # 25 | ## copies of the Software, and to permit persons to whom the Software is # 26 | ## furnished to do so, subject to the following conditions: # 27 | ## # 28 | ## The above copyright notice and this permission notice shall be included in all # 29 | ## copies or substantial portions of the Software. # 30 | ## # 31 | ## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # 32 | ## IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # 33 | ## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # 34 | ## AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # 35 | ## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # 36 | ## OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # 37 | ## SOFTWARE. # 38 | ## # 39 | ####################################################################################### 40 | 41 | 42 | function read_yes_no() 43 | { 44 | if [ "$1" = "-y" -o "$1" = "y" ]; then 45 | { 46 | yesno="y"; 47 | echo "y"; 48 | echo "Skipping...as -y was given"; 49 | } 50 | elif [ "$1" = "-n" -o "$1" = "n" ]; then 51 | { 52 | yesno="n"; 53 | echo "n"; 54 | echo "Terminating...as -n was given"; 55 | exit 1; 56 | } 57 | fi; 58 | 59 | if [ "$yesno" = "" ]; then 60 | { 61 | while read yesno; 62 | do 63 | { 64 | if [ "$yesno" = "y" ]; then break; 65 | elif [ "$yesno" = "n" ]; then echo "Terminating..."; exit 1; 66 | else echo -n "${ask_text}"; fi; 67 | } 68 | done; 69 | } 70 | fi; 71 | } 72 | 73 | echo "#######################################################################"; 74 | echo "# #"; 75 | echo "# A script to install a mainline version of NGINX with custombuild2 #"; 76 | echo "# A version number of NGINX mainline is taken from versions.txt #"; 77 | echo "# Version: 2.0 (Tue Oct 4 17:06:49 +07 2016) #"; 78 | echo "# Written by: Alex S Grebenschikov (zEitEr) #"; 79 | echo "# #"; 80 | echo "#######################################################################"; 81 | echo ""; 82 | 83 | cd /usr/local/directadmin/custombuild || exit 1; 84 | NGINX_VER=`grep ^nginx_mainline: versions.txt | cut -d\: -f2`; 85 | NGINX_MD5=`grep ^nginx_mainline: versions.txt | cut -d\: -f3`; 86 | NGINX_VER_INSTALLED=`nginx -v 2>&1 | grep 'nginx version' | cut -d\/ -f2`; 87 | 88 | ask_text="Do you want to build NGINX? (y/n): "; 89 | 90 | echo "Latest version of NGINX mainline: ${NGINX_VER}"; 91 | echo "Installed version of NGINX: ${NGINX_VER_INSTALLED}"; 92 | echo ""; 93 | echo -n "${ask_text}"; 94 | 95 | [ -e "custom_versions.txt" ] || touch custom_versions.txt; 96 | cat custom_versions.txt | grep -Ev "^nginx:|^$" > custom_versions.txt.new; 97 | mv -f custom_versions.txt.new custom_versions.txt; 98 | echo "nginx:${NGINX_VER}:${NGINX_MD5}" >> custom_versions.txt; 99 | 100 | read_yes_no ${1}; 101 | 102 | [ -e "nginx-${NGINX_VER}.tar.gz" ] || wget https://nginx.org/download/nginx-${NGINX_VER}.tar.gz -O nginx-${NGINX_VER}.tar.gz; 103 | ./build update > /dev/null 2>&1; 104 | ./build nginx; 105 | 106 | exit 0; 107 | -------------------------------------------------------------------------------- /nginx/nginx_reverse/conf/nginx-defaults.conf~TLSv1.3: -------------------------------------------------------------------------------- 1 | default_type application/octet-stream; 2 | tcp_nopush on; 3 | tcp_nodelay on; 4 | sendfile on; 5 | 6 | log_format bytes '$bytes_sent $request_length'; 7 | 8 | keepalive_timeout 15; 9 | types_hash_max_size 2048; 10 | 11 | disable_symlinks if_not_owner from=$document_root; 12 | 13 | server_tokens off; 14 | 15 | client_max_body_size 1024m; 16 | client_body_buffer_size 128k; 17 | 18 | server_names_hash_bucket_size 128; 19 | server_names_hash_max_size 10240; 20 | 21 | ssl_dhparam /etc/nginx/ssl.crt/dhparams.pem; 22 | 23 | ssl_session_cache shared:SSL:10m; 24 | ssl_session_timeout 5m; 25 | 26 | # https://mozilla.github.io/server-side-tls/ssl-config-generator/ intermediate configuration. 27 | ssl_protocols TLSv1.2 TLSv1.3; 28 | ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256; 29 | ssl_prefer_server_ciphers on; 30 | 31 | include /etc/nginx/nginx-directoryindex.conf; 32 | -------------------------------------------------------------------------------- /nginx/nginx_reverse/configure.nginx~openssl-1.1.1: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Customized by Poralix.com to build NGINX with support of TLSv1.3 4 | # Last modified: Thu Dec 30 12:01:29 +07 2021 5 | # 6 | 7 | OPENSSL_VER="1.1.1m"; 8 | OPENSSL_URL="https://www.openssl.org/source/openssl-${OPENSSL_VER}.tar.gz"; 9 | 10 | OPENSSL_NAME="openssl_tls_1_3.tar.gz"; 11 | wget ${OPENSSL_URL} -O ${OPENSSL_NAME}; 12 | 13 | [ -f "${OPENSSL_NAME}" ] && tar -zxvf ${OPENSSL_NAME}; 14 | PWD=$(pwd); 15 | OPENSSL_DIR=$(find ${PWD} -type d -name openssl-${OPENSSL_VER}\*); 16 | 17 | ./configure \ 18 | "--user=nginx" \ 19 | "--group=nginx" \ 20 | "--prefix=/usr" \ 21 | "--sbin-path=/usr/sbin" \ 22 | "--conf-path=/etc/nginx/nginx.conf" \ 23 | "--pid-path=/var/run/nginx.pid" \ 24 | "--http-log-path=/var/log/nginx/access_log" \ 25 | "--error-log-path=/var/log/nginx/error_log" \ 26 | "--without-mail_imap_module" \ 27 | "--without-mail_smtp_module" \ 28 | "--with-http_ssl_module" \ 29 | "--with-http_realip_module" \ 30 | "--with-http_stub_status_module" \ 31 | "--with-http_gzip_static_module" \ 32 | "--with-http_dav_module" \ 33 | "--with-http_v2_module" \ 34 | "--with-http_image_filter_module" \ 35 | "--with-openssl=${OPENSSL_DIR}" \ 36 | "--with-openssl-opt=enable-tls1_3" \ 37 | "--add-module=../ngx_cache_purge" \ 38 | "--with-cc-opt='-D FD_SETSIZE=32768'" 39 | -------------------------------------------------------------------------------- /nginx/nginx_reverse/configure.nginx~openssl-3.0.0: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Customized by Poralix.com to build NGINX with support of TLSv1.3 4 | # Last modified: Tue Nov 5 08:03:38 CET 2024 5 | # 6 | 7 | # CentOS: 8 | # yum -y install perl-IPC-Cmd gd-devel 9 | 10 | # Debian 11 | # apt -y install libgd-dev 12 | 13 | # Dependences 14 | # 15 | # - libgd-dev/gd-devel is required for http_image_filter_module 16 | 17 | # OpenSSL versions: 18 | # 19 | # openssl-3.3.2.tar.gz 17652kB 03 Sep 2024 13:58 20 | # openssl-3.2.3.tar.gz 17346kB 03 Sep 2024 13:59 21 | # openssl-3.1.7.tar.gz 15317kB 03 Sep 2024 13:59 22 | # openssl-3.0.15.tar.gz 14959kB 03 Sep 2024 14:02 23 | 24 | OPENSSL_VER="3.0.15"; 25 | OPENSSL_NAME="openssl_tls_1_3.tar.gz"; 26 | WITH_OPENSSL=""; 27 | 28 | if [ -f "/root/.custombuild_nginx_openssl" ]; 29 | then 30 | OPENSSL_VER=$(head -1 "/root/.custombuild_nginx_openssl"); 31 | echo "[INFO] Found OpenSSL version ${OPENSSL_VER} in /root/.custombuild_nginx_openssl"; 32 | elif [ -f "/usr/local/directadmin/custombuild/custom_nginx_openssl.txt" ]; 33 | then 34 | OPENSSL_VER=$(head -1 "/usr/local/directadmin/custombuild/custom_nginx_openssl.txt"); 35 | echo "[INFO] Found OpenSSL version ${OPENSSL_VER} in /usr/local/directadmin/custombuild/custom_nginx_openssl.txt"; 36 | fi; 37 | 38 | 39 | WGET_CMD="/usr/bin/wget"; 40 | WGET_OPTIONS=""; 41 | grep -q -c "CentOS release 6" /etc/redhat-release && WGET_OPTIONS="${WGET_OPTIONS} --no-check-certificate"; 42 | 43 | if [ -n "${OPENSSL_VER}" ]; 44 | then 45 | #OPENSSL_URL="https://www.openssl.org/source/openssl-${OPENSSL_VER}.tar.gz"; 46 | OPENSSL_URL="https://github.com/openssl/openssl/releases/download/openssl-${OPENSSL_VER}/openssl-${OPENSSL_VER}.tar.gz"; 47 | "${WGET_CMD}" ${WGET_OPTIONS} "${OPENSSL_URL}" -O "${OPENSSL_NAME}"; RETVAL=$?; 48 | fi; 49 | 50 | if [ -f "${OPENSSL_NAME}" ] && [ "${RETVAL}" = "0" ]; 51 | then 52 | tar -zxvf ${OPENSSL_NAME}; 53 | PWD=$(pwd); 54 | OPENSSL_DIR=$(find "${PWD}" -type d -name "openssl-${OPENSSL_VER}"\*); 55 | [ -d "${OPENSSL_DIR}" ] && WITH_OPENSSL="--with-openssl=${OPENSSL_DIR} --with-openssl-opt=enable-tls1_3"; 56 | fi; 57 | 58 | [ -d ./static_modules/modsecurity-nginx ] && modsec_module="--add-module=static_modules/modsecurity-nginx" || modsec_module="" 59 | 60 | # ignore gcc-14 issues 61 | export CFLAGS="${CFLAGS} -fpermissive" 62 | 63 | ./configure \ 64 | "--user=nginx" \ 65 | "--group=nginx" \ 66 | "--prefix=/usr" \ 67 | "--sbin-path=/usr/sbin" \ 68 | "--conf-path=/etc/nginx/nginx.conf" \ 69 | "--pid-path=/var/run/nginx.pid" \ 70 | "--http-log-path=/var/log/nginx/access_log" \ 71 | "--error-log-path=/var/log/nginx/error_log" \ 72 | "--without-mail_imap_module" \ 73 | "--without-mail_smtp_module" \ 74 | "--with-http_ssl_module" \ 75 | "--with-http_realip_module" \ 76 | "--with-http_stub_status_module" \ 77 | "--with-http_gzip_static_module" \ 78 | "--with-http_dav_module" \ 79 | "--with-http_v2_module" \ 80 | "--with-http_image_filter_module" ${WITH_OPENSSL} \ 81 | "--add-module=static_modules/ngx_cache_purge" \ 82 | ${modsec_module} \ 83 | "--with-cc-opt='-D FD_SETSIZE=32768'" 84 | -------------------------------------------------------------------------------- /openssl/README.md: -------------------------------------------------------------------------------- 1 | # OpenSSL 2 | 3 | A script to update OpenSSL version on CentOS servers to the latest 1.0.2 version. 4 | 5 | ``` 6 | cd /usr/local/directadmin/scripts/ 7 | wget https://raw.githubusercontent.com/poralix/directadmin-utils/master/openssl/openssl.install-1.0.2-primary.sh -O openssl.install-1.0.2-primary.sh 8 | chmod 755 openssl.install-1.0.2-primary.sh 9 | ./openssl.install-1.0.2-primary.sh 10 | ``` 11 | 12 | 13 | A script to update OpenSSL version on CentOS servers to the latest 1.0.1 version. 14 | 15 | ``` 16 | cd /usr/local/directadmin/scripts/ 17 | wget https://raw.githubusercontent.com/poralix/directadmin-utils/master/openssl/openssl.install-1.0.1-primary.sh -O openssl.install-1.0.1-primary.sh 18 | chmod 755 openssl.install-1.0.1-primary.sh 19 | ./openssl.install-1.0.1-primary.sh 20 | ``` 21 | 22 | # Lock the rpm-package: 23 | 24 | ``` 25 | yum -y install yum-plugin-versionlock 26 | yum versionlock openssl-* 27 | ``` 28 | 29 | to keep the openssl version away from rpm/yum updates. 30 | 31 | # Error building curl 7.54.0 on Directadmin server against OpenSSL 1.0.2 32 | 33 | Related: https://help.poralix.com/articles/error-building-curl-7.54.0-on-directadmin-with-openssl-1.0.2 34 | -------------------------------------------------------------------------------- /openssl/openssl.install-1.0.1-primary.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # by Alex Grebenschikov (www.poralix.com) 4 | # 5 | VER="1.0.1"; 6 | INSTALL_TO="/usr"; 7 | 8 | URL="https://www.openssl.org/source/old/${VER}/openssl-${VER}u.tar.gz" 9 | DIR_TO="/usr/local/src"; 10 | SAVE_TO="${DIR_TO}/openssl-${VER}-latest.tar.gz"; 11 | 12 | wget ${URL} -O ${SAVE_TO}; 13 | tar -zxvf ${SAVE_TO} -C ${DIR_TO}; 14 | 15 | cd ${DIR_TO}; 16 | DIR=`ls -1d openssl-${VER}*/ | tail -1`; 17 | cd ${DIR}; 18 | 19 | ./config --prefix=${INSTALL_TO} no-ssl2 no-ssl3 zlib-dynamic -fPIC shared; 20 | make depend && make install; 21 | 22 | c=`grep "${INSTALL_TO}/lib" /etc/ld.so.conf -c`; 23 | if [ "${c}" == "0" ]; then 24 | echo "${INSTALL_TO}/lib" >> /etc/ld.so.conf; 25 | fi; 26 | ldconfig 27 | 28 | exit 0; 29 | -------------------------------------------------------------------------------- /openssl/openssl.install-1.0.2-primary.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # by Alex Grebenschikov (www.poralix.com) 4 | # 5 | VER="1.0.2"; 6 | INSTALL_TO="/usr"; 7 | 8 | URL="https://www.openssl.org/source/openssl-${VER}-latest.tar.gz"; 9 | DIR_TO="/usr/local/src"; 10 | SAVE_TO="${DIR_TO}/openssl-${VER}-latest.tar.gz"; 11 | 12 | wget ${URL} -O ${SAVE_TO}; 13 | tar -zxvf ${SAVE_TO} -C ${DIR_TO}; 14 | 15 | cd ${DIR_TO}; 16 | DIR=`ls -1d openssl-${VER}*/ | tail -1`; 17 | cd ${DIR}; 18 | 19 | ./config --prefix=${INSTALL_TO} no-ssl2 no-ssl3 zlib-dynamic -fPIC shared; 20 | make depend && make install; 21 | 22 | c=`grep "${INSTALL_TO}/lib" /etc/ld.so.conf -c`; 23 | if [ "${c}" == "0" ]; then 24 | echo "${INSTALL_TO}/lib" >> /etc/ld.so.conf; 25 | fi; 26 | ldconfig 27 | 28 | exit 0; 29 | -------------------------------------------------------------------------------- /php/README.md: -------------------------------------------------------------------------------- 1 | # Scripts for operations with PHP 2 | 3 | - php-extension.sh 4 | - bulk_run_php.sh 5 | - change_domain_phpver.sh 6 | - test_sockets_ssl.php 7 | 8 | 9 | # Description of php-extension.sh 10 | 11 | A script to install/update/remove PECL extension for installed by CustomBuild 2.x PHP versions 12 | 13 | Written by: Alex Grebenschikov (support@poralix.com) 14 | 15 | **IMPORTANT**: mod_php is not supported at the moment 16 | 17 | ``` 18 | Usage: 19 | 20 | ./php-extension.sh [] 21 | 22 | Supported commands: 23 | 24 | install - to install PECL extension 25 | remove - to remove PECL extension 26 | status - show a status of PECL extension for a PHP version 27 | version - show a PECL extension version installed 28 | selfupdate - update this script from GitHub 29 | 30 | Supported options: 31 | 32 | --ver=VER - to install a specified version of an 33 | extension 34 | 35 | --beta - to install a beta version of an extension 36 | 37 | --php=VER - to install extension for one PHP version 38 | digits only (only one version at a time): 39 | 52, 53, 54, 55, 56, 70, 71, 72, 73, 74, 80, 40 | 81, 82, 83 etc 41 | 42 | --verbose - show messages from configure/make operations 43 | 44 | ``` 45 | 46 | # Description of bulk_run_php.sh 47 | 48 | A script to run code with all existing PHP versions installed by CustomBuild 2.x 49 | 50 | ``` 51 | Usage: 52 | ./bulk_run_php.sh 53 | 54 | Built-in commands: 55 | versions - to list installed PHP versions 56 | full-versions - to show installed PHP versions 57 | build - to re-install all installed versions (expert mode is used) 58 | update - to update all installed versions (expert mode is used) 59 | --ini - to show loaded ini files for PHP 60 | 61 | Build all (beta): 62 | DO NOT use it for mod_php!!! 63 | you can specify: suphp, fastcgi, php-fpm to force the mode 64 | 65 | Update all (beta): 66 | DO NOT use it for mod_php!!! 67 | you can specify: suphp, fastcgi, php-fpm to force the mode 68 | 69 | Other commands: 70 | You can run any other command supported by PHP, 71 | run 72 | php --help 73 | or 74 | ./bulk_run_php.sh --help 75 | to see a list of the options. 76 | ``` 77 | 78 | # Description of change_domain_phpver.sh 79 | 80 | The script can be used to show which PHP version is set for a domain in Directadmin. 81 | 82 | You can use the script to change PHP version for a domain from pre-installed with Custombuild 2.0. 83 | 84 | Example of usage: 85 | 86 | ``` 87 | # ./change_domain_phpver.sh domain.com 88 | Domain domain.com found and is owned by the user userbob 89 | Currently used: (no values mean defaults) 90 | php1_select: 5.3 as suphp (2) 91 | php2_select: 5.6 as suphp (1) 92 | PHP Versions: 93 | 1 stands for PHP (default): 5.6 as suphp 94 | 2 stands for PHP (additional): 5.3 as suphp 95 | You did not specified new version, terminating here... 96 | ``` 97 | 98 | Run 99 | 100 | ``` 101 | ./change_domain_phpver.sh domain.com 2 102 | ``` 103 | 104 | to set the second PHP version as a default for the domain.com (in our case it's PHP 5.3). 105 | 106 | Run 107 | 108 | ``` 109 | ./change_domain_phpver.sh domain.com 1 110 | ``` 111 | 112 | to set the primary PHP version as a default for the domain.com (in our case it's PHP 5.6). 113 | 114 | # Description of test_sockets_ssl.php 115 | 116 | A simple PHP-script to test connections to a remote host with and/or without TLS/SSL. 117 | 118 | Run under Document Root via HTTP/HTTPS or in a console: 119 | 120 | ``` 121 | # php test_sockets_ssl.php 122 |

123 | Connection to imap.gmail.com:993 without SSL  FAILED
124 | Connection to imap.gmail.com:993 with SSL  FAILED
125 | Connection to smtp.gmail.com:25 without SSL  FAILED
126 | Connection to smtp.gmail.com:25 with SSL  OK
127 | Connection to smtp.gmail.com:465 without SSL  FAILED
128 | Connection to smtp.gmail.com:465 with SSL  FAILED
129 | Connection to smtp.gmail.com:587 without SSL  FAILED
130 | Connection to smtp.gmail.com:587 with SSL  OK
131 | 
132 | ``` 133 | -------------------------------------------------------------------------------- /php/bulk_run_php.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # ===================================================== 3 | # A script to run code with PHP versions 4 | # installed by CustomBuild 2.x 5 | # ===================================================== 6 | # Written by Alex Grebenschikov(support@poralix.com) 7 | # ===================================================== 8 | # versions: 0.4-beta $ Tue May 15 16:47:43 +07 2018 9 | # 0.3-beta $ Tue May 15 14:15:13 +07 2018 10 | # 0.2-beta $ Mon Dec 26 14:32:03 +07 2016 11 | # 0.1-beta $ Tue Mar 17 12:40:51 NOVT 2015 12 | # ===================================================== 13 | #set -x 14 | 15 | LANG=C; 16 | CMD=""; 17 | PHPVER=""; 18 | BN="`tput -Txterm bold`" 19 | BF="`tput -Txterm sgr0`" 20 | 21 | do_usage() 22 | { 23 | echo " 24 | # ===================================================== 25 | # A script to run code with PHP versions 26 | # installed by CustomBuild 2.x 27 | # ===================================================== 28 | # Written by Alex Grebenschikov(support@poralix.com) 29 | # ===================================================== 30 | 31 | Usage: 32 | $0 33 | 34 | Built-in commands: 35 | versions - to list installed PHP versions 36 | full-versions - to show installed PHP versions 37 | build - to re-install all installed versions (expert mode is used) 38 | update - to update all installed versions (expert mode is used) 39 | --ini - to show loaded ini files for PHP 40 | 41 | Build all (beta): 42 | DO NOT use it for mod_php!!! 43 | you can specify: suphp, fastcgi, php-fpm to force the mode 44 | 45 | Update all (beta): 46 | DO NOT use it for mod_php!!! 47 | you can specify: suphp, fastcgi, php-fpm to force the mode 48 | 49 | Other commands: 50 | You can run any other command supported by PHP, 51 | run 52 | php --help 53 | or 54 | $0 --help 55 | to see a list of the options. 56 | "; 57 | } 58 | 59 | # Do the version investigation and update if it's requested 60 | do_versions() 61 | { 62 | PHP_MODE="${1}"; 63 | PHP_DIR=`dirname ${PHP}`; 64 | IVER=`${PHP} -v 2>&1 | grep ^PHP.*built | awk '{print $2}'`; 65 | IVER_xx=`echo ${IVER} | awk -F '.' '{print $1$2}'`; 66 | IVER_xdx=`echo ${IVER} | awk -F '.' '{print $1"."$2}'`; 67 | AVER=`grep ^php${IVER_xx}: /usr/local/directadmin/custombuild/versions.txt | cut -d\: -f2`; 68 | 69 | DETECTED=0; # 0 - none, 1 - custombuild, 2 - autodetected 70 | RELEASE_VERSION=''; 71 | 72 | OPTIONS_CONF="/usr/local/directadmin/custombuild/options.conf"; 73 | if [ -z "${PHP_MODE}" ]; then 74 | c=$(egrep -c -m1 "^php[1,2]_release=${IVER_xdx}" "${OPTIONS_CONF}"); 75 | if [ "${c}" == "1" ]; then 76 | RELEASE_VERSION=$(egrep "^php[0-9]_release=${IVER_xdx}" "${OPTIONS_CONF}" | cut -d\_ -f1); 77 | PHP_MODE=$(grep "${RELEASE_VERSION}_mode" "${OPTIONS_CONF}" | cut -d\= -f2); 78 | DETECTED=1; 79 | fi; 80 | fi; 81 | 82 | if [ -z "${PHP_MODE}" ]; then 83 | PHP_MODE="mod_php"; 84 | if [ -e "${PHP_DIR}/lsphp" ]; then 85 | PHP_MODE="lsphp"; 86 | DETECTED=2; 87 | elif [ -e "/usr/local/php${IVER_xx}/etc/php-fpm.conf" ]; then 88 | PHP_MODE="php-fpm"; 89 | DETECTED=2; 90 | elif [ -e "/usr/local/safe-bin/fcgid${IVER_xx}.sh" ]; then 91 | PHP_MODE="fastcgi"; 92 | DETECTED=2; 93 | elif [ -e "/usr/local/suphp/sbin/suphp" ]; then 94 | PHP_MODE="suphp"; 95 | DETECTED=2; 96 | fi; 97 | fi; 98 | 99 | UPDATE=""; 100 | echo ""; 101 | if [ -n "${AVER}" ]; then 102 | echo "Latest version of PHP ${IVER_xdx}: ${BN}${AVER}${BF}"; 103 | if [ "${AVER}" != "${IVER}" ]; then 104 | UPDATE="${BN}Update is available${BF}"; 105 | UPDATE="${UPDATE}\nTo update run: ${BN}cd /usr/local/directadmin/custombuild && ./build php_expert ${IVER_xdx} ${PHP_MODE}${BF}"; 106 | else 107 | UPDATE="To re-install run: ${BN}cd /usr/local/directadmin/custombuild && ./build php_expert ${IVER_xdx} ${PHP_MODE}${BF}"; 108 | fi; 109 | else 110 | echo "Latest version of PHP ${IVER_xdx}: N/A"; 111 | fi; 112 | case ${DETECTED} in 113 | 0) 114 | DETECTED_LANG="not found"; 115 | ;; 116 | 1) 117 | DETECTED_LANG="found in custombuild as ${RELEASE_VERSION}"; 118 | ;; 119 | 2) 120 | DETECTED_LANG="auto detection"; 121 | ;; 122 | esac; 123 | echo "Installed version of PHP ${IVER_xdx}: ${BN}${IVER}${BF} as ${BN}${PHP_MODE}${BF} (${DETECTED_LANG})"; 124 | echo "Installed into ${BN}${PHP}${BF}"; 125 | [ -n "${UPDATE}" ] && echo -e "${UPDATE}"; 126 | } 127 | 128 | # Call to PHP for version number 129 | do_full_versions() 130 | { 131 | ${PHP} -v 2>&1 | grep ^PHP; 132 | } 133 | 134 | # Call to custombuild 135 | do_update() 136 | { 137 | cd /usr/local/directadmin/custombuild && ./build php_expert ${IVER_xdx} ${PHP_MODE}; 138 | } 139 | 140 | # Build all installed PHP versions 141 | do_build_all() 142 | { 143 | do_versions >/dev/null 2>&1; 144 | if [ "${PHP_MODE}" != "mod_php" ]; then 145 | 146 | if [ -n "${1}" ]; then 147 | case "${1}" in 148 | suphp|fastcgi|php-fpm) 149 | PHP_MODE="${1}"; 150 | ;; 151 | *) 152 | ;; 153 | esac; 154 | fi; 155 | 156 | echo "Re-installing version of PHP ${IVER_xdx}: ${BN}${IVER}${BF} as ${BN}${PHP_MODE}${BF}"; 157 | echo "Installed into ${BN}${PHP}${BF}"; 158 | echo "Will run /usr/local/directadmin/custombuild && ./build php_expert ${IVER_xdx} ${PHP_MODE}"; 159 | do_update ${PHP_MODE}; 160 | echo ""; 161 | else 162 | echo "DON'T USE THE SCRIPT FOR UPDATING PHP INSTALLED AS mod_PHP"; 163 | fi; 164 | } 165 | 166 | # Update all installed PHP versions 167 | do_update_all() 168 | { 169 | do_versions >/dev/null 2>&1; 170 | if [ "${AVER}" != "${IVER}" ]; then 171 | if [ "${PHP_MODE}" != "mod_php" ]; then 172 | 173 | if [ -n "${1}" ]; then 174 | case "${1}" in 175 | suphp|fastcgi|php-fpm) 176 | PHP_MODE="${1}"; 177 | ;; 178 | *) 179 | ;; 180 | esac; 181 | fi; 182 | 183 | echo "Updating version of PHP ${IVER_xdx}: ${BN}${IVER}${BF} as ${BN}${PHP_MODE}${BF}"; 184 | echo "Installed into ${BN}${PHP}${BF}"; 185 | echo "Will run /usr/local/directadmin/custombuild && ./build php_expert ${IVER_xdx} ${PHP_MODE}"; 186 | do_update ${PHP_MODE}; 187 | echo ""; 188 | else 189 | echo "DON'T USE THE SCRIPT FOR UPDATING PHP INSTALLED AS mod_PHP"; 190 | fi; 191 | fi; 192 | } 193 | 194 | do_other() 195 | { 196 | echo "${BN}Running for ${PHPVER}${BF}"; 197 | ${PHP} $@; 198 | echo ""; 199 | } 200 | 201 | if [ ! -x "/usr/local/directadmin/directadmin" ]; then 202 | echo "Directadmin not found! Terminating..."; 203 | exit 1; 204 | fi; 205 | 206 | if [ -z "$1" ]; 207 | then 208 | do_usage; 209 | exit 2; 210 | else 211 | CMD=$1; 212 | fi; 213 | 214 | for PHP in `ls -1 /usr/local/php*/bin/php | egrep "\/php[0-9]{2}\/bin" | sort -n`; 215 | do 216 | PHPVER=`echo ${PHP} | cut -d\/ -f4`; 217 | 218 | case "${CMD}" in 219 | versions|version) 220 | do_versions; 221 | ;; 222 | full-versions|full-version) 223 | do_full_versions; 224 | ;; 225 | build) 226 | do_build_all $2; 227 | ;; 228 | update) 229 | do_update_all $2; 230 | ;; 231 | *) 232 | do_other $@; 233 | ;; 234 | esac; 235 | done; 236 | 237 | echo ""; 238 | 239 | exit 0; 240 | -------------------------------------------------------------------------------- /php/change_domain_phpver.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # A script to change domain's PHP version in console 4 | # ====================================================== 5 | # Written by Alex s Grebenschikov (support@poralix.com) 6 | # Version: 0.1-beta $ Mon Dec 14 00:50:41 NOVT 2015 7 | # ====================================================== 8 | 9 | BN="`tput -Txterm bold`" 10 | BF="`tput -Txterm sgr0`" 11 | 12 | do_show_phpver() 13 | { 14 | if [ "$1" == "1" ]; 15 | then 16 | echo "${BN}${php_release[1]}${BF} as ${BN}${php_mode[1]}${BF}"; 17 | elif [ "$1" == "2" ]; 18 | then 19 | echo "${BN}${php_release[2]}${BF} as ${BN}${php_mode[2]}${BF}"; 20 | else 21 | echo ""; 22 | fi; 23 | } 24 | 25 | do_versions() 26 | { 27 | echo -e "\t${BN}1${BF} stands for PHP (default): `do_show_phpver 1`"; 28 | echo -e "\t${BN}2${BF} stands for PHP (additional): `do_show_phpver 2`"; 29 | } 30 | 31 | do_usage() 32 | { 33 | echo "#######################################################"; 34 | echo "# Written by Alex S Grebenschikov #"; 35 | echo "#######################################################"; 36 | echo "Usage ${BN}$0 [<1|2>]${BF}"; 37 | echo "PHP Versions (if omitted will show current settings): "; 38 | do_versions; 39 | exit 0; 40 | } 41 | 42 | data=`grep "^php[1,2]_" /usr/local/directadmin/custombuild/options.conf`; 43 | php_release[1]=`echo $data | grep -o php1_release=[^\ ]* | cut -d\= -f2` 44 | php_mode[1]=`echo $data | grep -o php1_mode=[^\ ]* | cut -d\= -f2` 45 | php_release[2]=`echo $data | grep -o php2_release=[^\ ]* | cut -d\= -f2` 46 | php_mode[2]=`echo $data | grep -o php2_mode=[^\ ]* | cut -d\= -f2` 47 | 48 | if [ -z "$1" ]; 49 | then 50 | do_usage; 51 | else 52 | DOMAIN=$1; 53 | fi; 54 | 55 | DO_NOT_CHANGE=0; 56 | 57 | if [ -n "$2" ]; 58 | then 59 | if [ "$2" == "1" ]; 60 | then 61 | PHP1_VER=$2; 62 | PHP2_VER=2; 63 | elif [ "$2" == "2" ]; 64 | then 65 | PHP1_VER=$2; 66 | PHP2_VER=1; 67 | else 68 | do_usage; 69 | fi; 70 | else 71 | DO_NOT_CHANGE=1 72 | fi; 73 | 74 | DCF=`ls -1 /usr/local/directadmin/data/users/*/domains/${DOMAIN}.conf 2>&1 | head -1`; 75 | 76 | if [ ! -f "${DCF}" ]; 77 | then 78 | echo "[ERROR] Domain ${BN}${DOMAIN}${BF} does not seem to exist on the server!"; 79 | exit 1; 80 | fi; 81 | 82 | owner=`echo ${DCF} | cut -d\/ -f7` 83 | 84 | echo "Domain ${BN}${DOMAIN}${BF} found and is owned by the user ${BN}${owner}${BF}"; 85 | 86 | data=`grep "^php[1,2]_select=" ${DCF}`; 87 | php1_select=`echo $data | grep -o php1_select=[^\ ]* | cut -d\= -f2` 88 | php2_select=`echo $data | grep -o php2_select=[^\ ]* | cut -d\= -f2` 89 | 90 | echo "Currently used: (no values mean defaults)"; 91 | echo -e "\tphp1_select: `do_show_phpver ${php1_select}` (${php1_select})"; 92 | echo -e "\tphp2_select: `do_show_phpver ${php2_select}` (${php2_select})"; 93 | echo "PHP Versions: "; 94 | do_versions; 95 | 96 | if [ "${DO_NOT_CHANGE}" == "1" ]; 97 | then 98 | echo "You did not specified new version, terminating here..."; 99 | exit 0; 100 | fi; 101 | 102 | if [ -z ${php1_select} ] && [ -z ${php2_select} ]; 103 | then 104 | echo "php1_select=${PHP1_VER}" >> ${DCF}; 105 | echo "php2_select=${PHP2_VER}" >> ${DCF}; 106 | else 107 | TF=`mktemp`; 108 | cat ${DCF}| grep -v "^php[1,2]_select=" > ${TF}; 109 | cat ${TF} > ${DCF}; 110 | echo "php1_select=${PHP1_VER}" >> ${DCF}; 111 | echo "php2_select=${PHP2_VER}" >> ${DCF}; 112 | rm -f ${TF}; 113 | fi; 114 | 115 | echo "Rewriting virtual host...."; 116 | echo "action=rewrite&value=httpd&user=${owner}" >> /usr/local/directadmin/data/task.queue 117 | /usr/local/directadmin/dataskq 118 | /usr/local/directadmin/dataskq 119 | echo "Finished..."; 120 | 121 | exit 0; 122 | -------------------------------------------------------------------------------- /php/php-extension.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # ====================================================== 3 | # 4 | # A script to install/update/remove PHP extensions 5 | # for all installed by CustomBuild 2.x PHP versions 6 | # Written by Alex Grebenschikov (support@poralix.com) 7 | # 8 | # ====================================================== 9 | # Version: 0.17.4-beta $ Wed May 7 18:21:48 +07 2025 10 | # Created: 0.2-beta $ Tue Mar 17 12:40:51 NOVT 2015 11 | # ====================================================== 12 | # 13 | #set -x 14 | 15 | PWD="$(pwd)"; 16 | WORKDIR="/usr/local/src"; 17 | LANG=C; 18 | FILE=""; 19 | EXT=""; 20 | BN="$(tput -Txterm bold)" 21 | BF="$(tput -Txterm sgr0)" 22 | 23 | redirect_cmd() 24 | { 25 | if [ "${QUIET}" == "1" ]; 26 | then 27 | "$@" > /dev/null 2>&1; 28 | else 29 | "$@"; 30 | fi; 31 | return "$?"; 32 | } 33 | 34 | verify_php_version() 35 | { 36 | local loc_php_version loc_pecl_bin; 37 | loc_php_version="${1}"; 38 | 39 | if [ -n "${loc_php_version}" ]; 40 | then 41 | { 42 | if [ ! -d "/usr/local/php${loc_php_version}/" ] || [ ! -f "/usr/local/php${loc_php_version}/bin/php" ]; 43 | then 44 | { 45 | echo "${BN}[ERROR] PHP version php${loc_php_version} was not found!${BF}"; 46 | exit 2; 47 | } 48 | fi; 49 | 50 | loc_pecl_bin="/usr/local/php${loc_php_version}/bin/pecl"; 51 | if [ ! -x "${loc_pecl_bin}" ]; then 52 | echo "${BN}[ERROR] PECL for PHP version php${loc_php_version} was not found!${BF}"; 53 | exit 2; 54 | fi; 55 | } 56 | fi; 57 | } 58 | 59 | find_extension_version() 60 | { 61 | local loc_php_version loc_php_dotver; 62 | loc_php_version="${1:?}"; 63 | loc_php_dotver=$(echo "${loc_php_version}" | egrep -o '(5|7|8|9)[0-9]+' | sed 's/\(.\)\(.\)/\1.\2/'); #' 64 | 65 | if [ -z "${EXT_VERSION}" ]; 66 | then 67 | { 68 | case "${loc_php_version}" in 69 | 52|53|54|55|56) 70 | case "${EXT}" in 71 | apcu) 72 | EXT_VERSION_LEGACY="4.0.11"; 73 | ;; 74 | igbinary) 75 | EXT_VERSION_LEGACY="2.0.8"; 76 | ;; 77 | redis) 78 | EXT_VERSION_LEGACY="3.1.6"; 79 | ;; 80 | *) 81 | EXT_VERSION_LEGACY=""; 82 | ;; 83 | esac; 84 | ;; 85 | 70|71|72|73) 86 | case "${EXT}" in 87 | redis) 88 | EXT_VERSION_LEGACY="5.3.7"; 89 | ;; 90 | *) 91 | EXT_VERSION_LEGACY=""; 92 | ;; 93 | esac; 94 | ;; 95 | *) 96 | case "${EXT}" in 97 | redis) 98 | EXT_VERSION_LEGACY=""; 99 | if [ "${IS_CENTOS_7}" == "1" ]; 100 | then 101 | { 102 | EXT_VERSION_LEGACY="5.3.7"; 103 | } 104 | fi; 105 | ;; 106 | *) 107 | EXT_VERSION_LEGACY=""; 108 | ;; 109 | esac; 110 | ;; 111 | esac; 112 | } 113 | fi; 114 | test -n "${EXT_VERSION_LEGACY}" && echo "${BN}[OK] Using legacy version=${EXT_VERSION_LEGACY} for extension=${EXT} for PHP ${loc_php_dotver}${BF}"; 115 | test -z "${EXT_VERSION_LEGACY}" && echo "${BN}[OK] Using default version for extension=${EXT} for PHP ${loc_php_dotver}${BF}"; 116 | } 117 | 118 | do_install_sourceguardian() 119 | { 120 | if [ "${SOURCEGUARDIAN_INSTALLED}" == "1" ]; 121 | then 122 | echo "${BN}[OK] Already installed sourceguardian loaders${BF}"; 123 | return 0; 124 | fi; 125 | 126 | echo "${BN}[OK] Going to download sourceguardian loaders${BF}"; 127 | mkdir -p "${SOURCEGUARDIAN_DIR}"; 128 | cd "${SOURCEGUARDIAN_DIR}" && curl -s https://www.sourceguardian.com/loaders/download/loaders.linux-x86_64.tar.gz --output "${SOURCEGUARDIAN_DIR}/loaders.linux-x86_64.tar.gz"; 129 | if [ "$?" == "0" ] && [ -f "${SOURCEGUARDIAN_DIR}/loaders.linux-x86_64.tar.gz" ]; 130 | then 131 | { 132 | echo "${BN}[OK] Unpacking sourceguardian loaders to ${SOURCEGUARDIAN_DIR}${BF}"; 133 | cd "${SOURCEGUARDIAN_DIR}" && tar -xzf "${SOURCEGUARDIAN_DIR}/loaders.linux-x86_64.tar.gz"; 134 | if [ "$?" == "0" ]; 135 | then 136 | { 137 | SOURCEGUARDIAN_INSTALLED=1; 138 | rm -f "${SOURCEGUARDIAN_DIR}/loaders.linux-x86_64.tar.gz"; 139 | } 140 | else 141 | { 142 | SOURCEGUARDIAN_INSTALLED=0; 143 | echo "${BN}[ERROR] Failed to unpack sourceguardian loaders${BF}"; 144 | exit 1; 145 | } 146 | fi; 147 | } 148 | else 149 | { 150 | SOURCEGUARDIAN_INSTALLED=0; 151 | echo "${BN}[ERROR] Failed to download sourceguardian loaders${BF}"; 152 | exit 1; 153 | } 154 | fi; 155 | } 156 | 157 | do_usage() 158 | { 159 | echo " 160 | # ============================================================ # 161 | # A script to install/update/remove PHP extensions # 162 | # for all installed by CustomBuild 2.x PHP versions # 163 | # ============================================================ # 164 | # IMPORTANT: DirectAdmin servers are only supported # 165 | # ============================================================ # 166 | # Written by Alex Grebenschikov(support@poralix.com) # 167 | # Version: 0.17.4-beta $ Wed May 7 18:21:48 +07 2025 # 168 | # ============================================================ # 169 | 170 | Usage: 171 | 172 | $0 [] 173 | 174 | Supported commands: 175 | 176 | install - to install PECL extension 177 | remove - to remove PECL extension 178 | status - show a status of PECL extension for a PHP version 179 | version - show a PECL extension version installed 180 | selfupdate - update this script from GitHub 181 | 182 | Supported options: 183 | 184 | --ver=VER - to install a specified version of an 185 | extension 186 | 187 | --beta - to install a beta version of an extension 188 | 189 | --php=VER - to install extension for one PHP version 190 | digits only (only one version at a time): 191 | 52, 53, 54, 55, 56, 70, 71, 72, 73, 74, 80, 192 | 81, 82, 83, 84 etc 193 | 194 | --verbose - show messages from configure/make operations 195 | "; 196 | 197 | exit 1; 198 | } 199 | 200 | do_disable_extension_in_da() 201 | { 202 | local loc_php_version loc_php_da_ini_file; 203 | loc_php_version="${1:?}"; 204 | loc_php_da_ini_file="/usr/local/php${loc_php_version}/lib/php.conf.d/10-directadmin.ini"; 205 | if grep -q "^php_${EXT}=yes$" /usr/local/directadmin/custombuild/options.conf; 206 | then 207 | echo "${BN}[OK] Disabling ${EXT} for PHP in DirectAdmin CustomBuild${BF}"; 208 | /usr/local/directadmin/directadmin build set php_${EXT} no; 209 | else 210 | if grep -q "^php_${EXT}=no$" /usr/local/directadmin/custombuild/options.conf; 211 | then 212 | echo "${BN}[NOTICE] ${EXT} for PHP is already disabled in DirectAdmin CustomBuild${BF}"; 213 | else 214 | echo "${BN}[NOTICE] ${EXT} for PHP is not managed by DirectAdmin CustomBuild${BF}"; 215 | fi; 216 | fi; 217 | if grep -q "^extension=${EXT}.so$" "${loc_php_da_ini_file}"; 218 | then 219 | echo "${BN}[OK] Disabling ${EXT} in PHP ${loc_php_version} installed by DirectAdmin CustomBuild${BF}"; 220 | perl -pi -e "s/^extension=${EXT}.so//" "${loc_php_da_ini_file}"; 221 | fi; 222 | } 223 | 224 | do_update() 225 | { 226 | local loc_php_version loc_php_bindir loc_pecl_bin loc_phpize_bin loc_php_dotver loc_configure_options loc_extension_dir; 227 | loc_php_version="${1:?}"; 228 | loc_php_bindir="/usr/local/php${loc_php_version}/bin"; 229 | loc_pecl_bin="/usr/local/php${loc_php_version}/bin/pecl"; 230 | loc_phpize_bin="/usr/local/php${loc_php_version}/bin/phpize"; 231 | loc_php_dotver=$(echo "${loc_php_version}" | egrep -o '(5|7|8|9)[0-9]+' | sed 's/\(.\)\(.\)/\1.\2/'); #' 232 | loc_extension_dir=$("/usr/local/php${loc_php_version}/bin/php" -i 2>&1 | grep "^extension_dir" | awk '{print $3}'); 233 | loc_configure_options=''; 234 | 235 | case "${EXT}" in 236 | redis) 237 | loc_configure_options="--enable-redis-lzf"; 238 | test -e /usr/include/zstd.h && loc_configure_options="${loc_configure_options} --enable-redis-zstd"; 239 | test -e "${loc_extension_dir}/igbinary.so" && loc_configure_options="${loc_configure_options} --enable-redis-igbinary"; 240 | ;; 241 | igbinary) 242 | loc_configure_options=""; 243 | ;; 244 | *) 245 | loc_configure_options=''; 246 | ;; 247 | esac; 248 | 249 | if [ -x "${loc_phpize_bin}" ]; 250 | then 251 | { 252 | EXT_FULL="${EXT}"; 253 | if [ -z "${EXT_VERSION_LEGACY}" ]; 254 | then 255 | { 256 | if [ "${BETA}" == "1" ]; then 257 | EXT_FULL="${EXT}-beta"; 258 | elif [ -n "${EXT_VERSION}" ]; then 259 | EXT_FULL="${EXT}-${EXT_VERSION}"; 260 | fi; 261 | } 262 | else 263 | { 264 | EXT_FULL="${EXT}-${EXT_VERSION_LEGACY}"; 265 | } 266 | fi; 267 | 268 | tmpdir=$(mktemp -d "${WORKDIR}/tmp.XXXXXXXXXX"); 269 | tmpfile=$(mktemp "${WORKDIR}/tmp.XXXXXXXXXX"); 270 | 271 | echo "${BN}[OK] Updating ${loc_pecl_bin}${BF}"; 272 | redirect_cmd "${loc_pecl_bin}" channel-update pecl.php.net; 273 | echo "${BN}[OK] Downloading ${EXT_FULL} for PHP ${loc_php_dotver}${BF}"; 274 | "${loc_pecl_bin}" download "${EXT_FULL}" 2>&1 | tee "${tmpfile}"; 275 | FILE=$(grep "^File" "${tmpfile}" | grep downloaded | cut -d\ -f2); 276 | rm -f "${tmpfile}"; 277 | 278 | if [ -f "${FILE}" ]; 279 | then 280 | { 281 | echo "${BN}[OK] Going to install extension ${EXT} for PHP ${loc_php_dotver}${BF}"; 282 | 283 | cd "${WORKDIR}"; 284 | rm -rfv "${tmpdir:?}"/*; 285 | tar -zxf "${FILE}" --directory="${tmpdir}"; 286 | DIR=$(find "${tmpdir}/${EXT}"* -type d | head -1); 287 | if [ -d "${DIR}" ]; 288 | then 289 | { 290 | cd "${DIR}"; 291 | echo "${BN}[OK] Configuring ${EXT_FULL} for PHP ${loc_php_dotver}${BF}"; 292 | redirect_cmd "${loc_phpize_bin}"; 293 | redirect_cmd ./configure ${loc_configure_options} "--with-php-config=${loc_php_bindir}/php-config"; 294 | RETVAL=$?; 295 | if [ "${RETVAL}" == "0" ]; 296 | then 297 | { 298 | echo "${BN}[OK] Compiling ${EXT_FULL} for PHP ${loc_php_dotver}${BF}"; 299 | redirect_cmd make && redirect_cmd make install; 300 | RETVAL=$?; 301 | if [ "${RETVAL}" == "0" ]; 302 | then 303 | { 304 | echo "${BN}[OK] Installation of ${EXT} for PHP ${loc_php_dotver} completed!${BF}"; 305 | do_disable_extension_in_da "${loc_php_version}"; 306 | } 307 | else 308 | { 309 | echo "${BN}[ERROR] Installation of ${EXT} for PHP ${loc_php_dotver} failed${BF}"; 310 | } 311 | fi; 312 | echo -ne '\007'; 313 | } 314 | else 315 | { 316 | echo "${BN}[ERROR] Configure of ${EXT} for PHP ${loc_php_dotver} failed${BF}"; 317 | } 318 | fi; 319 | cd "${WORKDIR}"; 320 | } 321 | fi; 322 | } 323 | else 324 | { 325 | echo "${BN}[ERROR] Failed to download extension file of ${EXT} for PHP ${loc_php_dotver}${BF}"; 326 | } 327 | fi; 328 | } 329 | else 330 | { 331 | echo "ERROR! Executable ${loc_phpize_bin} not found!"; 332 | exit 1; 333 | } 334 | fi; 335 | rm -rf "${tmpdir}"; 336 | } 337 | 338 | do_update_ini() 339 | { 340 | local loc_php_version loc_php_dotver loc_extension_dir loc_php_inidir loc_php_inifile loc_inifile; 341 | loc_php_version="${1:?}"; 342 | loc_php_dotver=$(echo "${loc_php_version}" | egrep -o '(5|7|8|9)[0-9]+' | sed 's/\(.\)\(.\)/\1.\2/'); #' 343 | loc_extension_dir=$("/usr/local/php${loc_php_version}/bin/php" -i 2>&1 | grep "^extension_dir" | awk '{print $3}'); 344 | 345 | loc_php_inidir="/usr/local/php${1}/lib/php.conf.d"; 346 | test -d "${loc_php_inidir}" || mkdir -p "${loc_php_inidir}"; 347 | 348 | loc_inifile=${2:-custom}; 349 | loc_php_inifile="${loc_php_inidir}/99-${loc_inifile}.ini"; 350 | test -f "${loc_php_inifile}" || loc_php_inifile="${loc_php_inidir}/90-${loc_inifile}.ini"; 351 | 352 | if [ "${EXT}" == "sourceguardian" ]; 353 | then 354 | { 355 | if [ -f "${SOURCEGUARDIAN_DIR}/ixed.${loc_php_dotver}.lin" ]; 356 | then 357 | { 358 | echo "${BN}[OK] Found ${EXT}. Enabling the extension in ${loc_php_inifile}${BF}"; 359 | echo "; Created by $0 script" > "${loc_php_inifile}"; 360 | echo "[sourceguardian]" >> "${loc_php_inifile}"; 361 | echo "zend_extension=${SOURCEGUARDIAN_DIR}/ixed.${loc_php_dotver}.lin" >> "${loc_php_inifile}"; 362 | } 363 | else 364 | { 365 | echo "${BN}[WARNING] Could not found ${EXT}. Removing the extension from ${loc_php_inifile}${BF}"; 366 | rm -f "${loc_php_inifile}"; 367 | } 368 | fi; 369 | } 370 | else 371 | { 372 | case "${EXT}" in 373 | xdebug) 374 | ROW="zend_extension=${EXT}.so"; 375 | ;; 376 | *) 377 | ROW="extension=${EXT}.so"; 378 | ;; 379 | esac; 380 | 381 | if [ -f "${loc_extension_dir}/${EXT}.so" ]; 382 | then 383 | { 384 | echo "${BN}[OK] Found ${EXT}.so. Enabling the extension in ${loc_php_inifile}${BF}"; 385 | grep -m1 -q "^${ROW}" "${loc_php_inifile}" >/dev/null 2>&1 || echo "${ROW}" >> "${loc_php_inifile}"; 386 | "/usr/local/php${1}/bin/php" -i 2>&1 | grep -i "^${EXT}" | grep -v 'Configure Command' | head -3; 387 | } 388 | else 389 | { 390 | while read -r INI_FILE; 391 | do 392 | echo "${BN}[WARNING] Could not find ${loc_extension_dir}/${EXT}.so. Removing extension from ${INI_FILE}${BF}"; 393 | grep -m1 -q "^${ROW}" "${INI_FILE}" && perl -pi -e "s#^${ROW}\n##" "${INI_FILE}"; 394 | grep -m1 -q "^${ROW}" "${INI_FILE}" && perl -pi -e "s#^${ROW}##" "${INI_FILE}"; 395 | done < <(find "${loc_php_inidir}/"*.ini); 396 | } 397 | fi; 398 | } 399 | fi; 400 | unset INI_FILE; 401 | unset ROW; 402 | } 403 | 404 | do_remove() 405 | { 406 | local loc_php_versions loc_php_version loc_extension_dir loc_extension_file loc_php_dotver; 407 | 408 | if [ -n "${PVN}" ]; then 409 | { 410 | loc_php_versions="${PVN}"; 411 | } 412 | else 413 | { 414 | loc_php_versions=$(find /usr/local/php*/bin/php | sort -n | egrep -o '(5|7|8|9)[0-9]+' | xargs); #' 415 | } 416 | fi; 417 | 418 | for loc_php_version in ${loc_php_versions}; 419 | do 420 | { 421 | verify_php_version "${loc_php_version}"; 422 | loc_php_dotver=$(echo "${loc_php_version}" | egrep -o '(5|7|8|9)[0-9]+' | sed 's/\(.\)\(.\)/\1.\2/'); #' 423 | loc_extension_dir=$("/usr/local/php${loc_php_version}/bin/php" -i 2>&1 | grep "^extension_dir" | awk '{print $3}'); 424 | loc_extension_file="${loc_extension_dir}/${EXT}.so"; 425 | 426 | if [ "${EXT}" == "sourceguardian" ]; 427 | then 428 | { 429 | loc_extension_file="${SOURCEGUARDIAN_DIR}/ixed.${loc_php_dotver}.lin"; 430 | 431 | if [ -f "${loc_extension_file}" ]; 432 | then 433 | { 434 | rm -f "${loc_extension_file}"; 435 | echo "${BN}[OK] The extension ${EXT} for PHP ${loc_php_dotver} found! Removing it...${BF}"; 436 | } 437 | else 438 | { 439 | echo "${BN}[Warning] The extension ${EXT} for PHP ${loc_php_dotver} not found! Nothing to disable...${BF}"; 440 | } 441 | fi; 442 | 443 | do_update_ini "${loc_php_version}" "${EXT}" >/dev/null 2>&1; 444 | } 445 | else 446 | { 447 | if [ -f "${loc_extension_file}" ]; 448 | then 449 | { 450 | rm -f "${loc_extension_file}"; 451 | echo "${BN}[OK] The extension ${EXT} for PHP ${loc_php_dotver} found! Removing it...${BF}"; 452 | } 453 | else 454 | { 455 | echo "${BN}[Warning] The extension ${EXT} for PHP ${loc_php_dotver} not found! Nothing to disable...${BF}"; 456 | } 457 | fi; 458 | 459 | do_update_ini "${loc_php_version}" >/dev/null 2>&1; 460 | } 461 | fi; 462 | 463 | do_restart_webserver "${loc_php_version}"; 464 | } 465 | done; 466 | } 467 | 468 | do_install_single() 469 | { 470 | local loc_php_version; 471 | loc_php_version=${1:?}; 472 | 473 | if [ "${EXT}" == "sourceguardian" ]; 474 | then 475 | { 476 | do_install_sourceguardian; 477 | do_update_ini "${loc_php_version}" sourceguardian; 478 | } 479 | else 480 | { 481 | find_extension_version "${loc_php_version}"; 482 | do_update "${loc_php_version}"; 483 | do_update_ini "${loc_php_version}"; 484 | } 485 | fi; 486 | } 487 | 488 | do_install() 489 | { 490 | local loc_php_version loc_php_dotver; 491 | loc_php_version=${1}; 492 | 493 | cd "${WORKDIR}"; 494 | 495 | if [ -z "${loc_php_version}" ]; 496 | then 497 | { 498 | while read -r PHPIZE 499 | do 500 | { 501 | loc_php_version=$(echo "${PHPIZE}" | grep -o "[0-9]*"); 502 | loc_php_dotver=$(echo "${loc_php_version}" | egrep -o '(5|7|8|9)[0-9]+' | sed 's/\(.\)\(.\)/\1.\2/'); #' 503 | verify_php_version "${loc_php_version}"; 504 | echo "${BN}[OK] Started with PHP ${loc_php_dotver}${BF}"; 505 | do_install_single "${loc_php_version}"; 506 | do_restart_webserver "${loc_php_version}"; 507 | echo "${BN}[OK] Finished with PHP ${loc_php_dotver}${BF}"; 508 | echo; sleep 1; 509 | } 510 | done < <(find /usr/local/php*/bin/phpize); 511 | } 512 | else 513 | { 514 | loc_php_dotver=$(echo "${loc_php_version}" | egrep -o '(5|7|8|9)[0-9]+' | sed 's/\(.\)\(.\)/\1.\2/'); #' 515 | verify_php_version "${loc_php_version}"; 516 | echo "${BN}[OK] Started with PHP ${loc_php_dotver}${BF}"; 517 | do_install_single "${loc_php_version}"; 518 | do_restart_webserver "${loc_php_version}"; 519 | echo "${BN}[OK] Finished with PHP ${loc_php_dotver}${BF}"; 520 | } 521 | fi; 522 | 523 | test -d "${PWD}" && cd "${PWD}"; 524 | } 525 | 526 | do_status() 527 | { 528 | local loc_php_versions loc_php_version loc_extension_dir loc_extension_file loc_php_dotver; 529 | 530 | if [ -n "${PVN}" ]; then 531 | { 532 | loc_php_versions="${PVN}"; 533 | } 534 | else 535 | { 536 | loc_php_versions=$(find /usr/local/php*/bin/php | sort -n | egrep -o '(5|7|8|9)[0-9]+' | xargs); #' 537 | } 538 | fi; 539 | 540 | for loc_php_version in ${loc_php_versions}; 541 | do 542 | { 543 | verify_php_version "${loc_php_version}"; 544 | loc_php_dotver=$(echo "${loc_php_version}" | egrep -o '(5|7|8|9)[0-9]+' | sed 's/\(.\)\(.\)/\1.\2/'); #' 545 | loc_extension_dir=$("/usr/local/php${loc_php_version}/bin/php" -i 2>&1 | grep "^extension_dir" | awk '{print $3}'); 546 | loc_extension_file="${loc_extension_dir}/${EXT}.so"; 547 | 548 | if [ "${EXT}" == "sourceguardian" ]; 549 | then 550 | { 551 | loc_extension_file="${SOURCEGUARDIAN_DIR}/ixed.${loc_php_dotver}.lin"; 552 | 553 | if [ -f "${loc_extension_file}" ]; 554 | then 555 | { 556 | echo "${BN}[OK] The extension file ${loc_extension_file} for PHP ${loc_php_dotver} found!${BF}"; 557 | 558 | IS_ENABLED=$("/usr/local/php${loc_php_version}/bin/php" -m | grep -m1 -i "^${EXT}$"); 559 | 560 | if [ -n "${IS_ENABLED}" ]; then 561 | { 562 | echo "${BN}[OK]${BF} The extension ${BN}${EXT}${BF} for ${BN}PHP ${loc_php_dotver}${BF} seems to be enabled!"; 563 | OLD_IFS="${IFS}"; IFS=$'\n'; 564 | while read -r ROW 565 | do 566 | echo "[PHP ${loc_php_dotver}] ${ROW}"; 567 | done < <("/usr/local/php${loc_php_version}/bin/php" -i | grep -i "^${EXT}"); 568 | IFS="${OLD_IFS}"; 569 | echo ""; 570 | } 571 | else 572 | { 573 | echo "${BN}[WARNING]${BF} The extension ${BN}${EXT}${BF} is probably not enabled for ${BN}PHP ${loc_php_dotver}${BF}! I did not detect it."; 574 | } 575 | fi; 576 | 577 | unset IS_ENABLED; 578 | } 579 | else 580 | { 581 | echo "${BN}[Warning] The extension file ${loc_extension_file} for PHP ${loc_php_dotver} not found${BF}"; 582 | } 583 | fi; 584 | } 585 | else 586 | { 587 | if [ -f "${loc_extension_file}" ]; 588 | then 589 | { 590 | IS_ENABLED=$("/usr/local/php${loc_php_version}/bin/php" -m | grep -m1 -i "^${EXT}$"); 591 | 592 | if [ -n "${IS_ENABLED}" ]; then 593 | { 594 | echo "${BN}[OK]${BF} The extension ${BN}${EXT}${BF} for ${BN}PHP ${loc_php_dotver}${BF} seems to be enabled!"; 595 | OLD_IFS="${IFS}"; IFS=$'\n'; 596 | while read -r ROW 597 | do 598 | echo "[PHP ${loc_php_dotver}] ${ROW}"; 599 | done < <("/usr/local/php${loc_php_version}/bin/php" -i | grep -i "^${EXT}"); 600 | IFS="${OLD_IFS}"; 601 | echo ""; 602 | } 603 | else 604 | { 605 | echo "${BN}[WARNING]${BF} The extension ${BN}${EXT}${BF} is probably not enabled for ${BN}PHP ${loc_php_dotver}${BF}! I did not detect it."; 606 | } 607 | fi; 608 | 609 | unset IS_ENABLED; 610 | } 611 | else 612 | { 613 | echo "${BN}[Warning]${BF} The extension ${BN}${EXT}${BF} for ${BN}PHP ${loc_php_dotver}${BF} not found!"; 614 | } 615 | fi; 616 | } 617 | fi; 618 | } 619 | done; 620 | } 621 | 622 | do_restart_webserver() 623 | { 624 | local loc_php_version loc_php_dotver loc_php_instance loc_php_mode_default loc_php_mode loc_webserver; 625 | loc_php_version=${1:?}; 626 | loc_php_dotver=$(echo "${loc_php_version}" | egrep -o '(5|7|8|9)[0-9]+' | sed 's/\(.\)\(.\)/\1.\2/'); #' 627 | loc_php_instance=$(grep "^php[1-9]_release=${loc_php_dotver}" /usr/local/directadmin/custombuild/options.conf | cut -d_ -f1); 628 | 629 | if [ -n "${loc_php_instance}" ]; then 630 | { 631 | loc_php_mode_default=$(grep "^php1_mode=" /usr/local/directadmin/custombuild/options.conf | cut -d= -f2); 632 | loc_php_mode=$(grep "^${loc_php_instance}_mode=" /usr/local/directadmin/custombuild/options.conf | cut -d= -f2); 633 | loc_php_mode=${loc_php_mode:-$loc_php_mode_default}; 634 | 635 | if [ "${loc_php_mode}" == "php-fpm" ]; then 636 | { 637 | echo "${BN}[INFO]${BF} Going to restart PHP-FPM ${loc_php_dotver}!"; 638 | do_restart_service "php-fpm${loc_php_version}"; 639 | } 640 | elif [ "${loc_php_mode}" == "lsphp" ]; then 641 | { 642 | echo "${BN}[INFO]${BF} Going to reload PHP ${loc_php_dotver} instances (${loc_php_mode})!"; 643 | killall lsphp; 644 | } 645 | else 646 | { 647 | echo "${BN}[INFO]${BF} Going to restart a webserver for PHP ${loc_php_dotver} (${loc_php_mode})!"; 648 | loc_webserver=$(grep ^webserver= /usr/local/directadmin/custombuild/options.conf | cut -d= -f2); 649 | 650 | case "${loc_webserver}" in 651 | nginx_apache|apache) 652 | do_restart_service "httpd"; 653 | ;; 654 | openlitespeed|litespeed) 655 | do_restart_service "litespeed"; 656 | ;; 657 | nginx) 658 | do_restart_service "nginx"; 659 | ;; 660 | esac; 661 | } 662 | fi; 663 | } 664 | else 665 | { 666 | echo "${BN}[Warning]${BF} The PHP version ${BN}${loc_php_dotver}${BF} isn't managed by DirectAdmin!"; 667 | } 668 | fi; 669 | } 670 | 671 | do_restart_service() 672 | { 673 | local loc_service; 674 | loc_service=${1:?}; 675 | echo "${BN}[INFO]${BF} Restarting ${loc_service}!"; 676 | 677 | if [ -e "/bin/systemctl" ]; then 678 | { 679 | /bin/systemctl restart "${loc_service}.service"; 680 | } 681 | else 682 | { 683 | /sbin/service "${loc_service}" restart; 684 | } 685 | fi; 686 | } 687 | 688 | do_update_script() 689 | { 690 | local loc_temp_file; 691 | echo "${BN}[INFO]${BF} Updating the script $0 from the official repository!"; 692 | echo "${BN}[INFO]${BF} HOME: https://github.com/poralix/directadmin-utils/!"; 693 | loc_temp_file=$(mktemp); 694 | if [ -f "${loc_temp_file}" ]; 695 | then 696 | curl -Ss "https://raw.githubusercontent.com/poralix/directadmin-utils/refs/heads/master/php/php-extension.sh" --output "${loc_temp_file}"; 697 | if [ "$?" == "0" ]; 698 | then 699 | cat "${loc_temp_file}" > "${SCRIPT}"; 700 | chmod 750 "${SCRIPT}"; 701 | echo "${BN}[INFO]${BF} Script updated OK!"; 702 | rm -f "${loc_temp_file}"; 703 | exit 0; 704 | else 705 | echo "${BN}[ERROR]${BF} Failed to update the script!"; 706 | fi; 707 | rm -f "${loc_temp_file}"; 708 | else 709 | echo "${BN}[ERROR]${BF} Failed to update the script!"; 710 | fi; 711 | exit 1; 712 | } 713 | 714 | SCRIPT="${0}"; 715 | CMD="${1}"; 716 | EXT="${2}"; 717 | PVN=""; 718 | BETA=""; 719 | QUIET="1"; 720 | IS_CENTOS_7=$(grep -c -m1 'VERSION="7' /etc/os-release); 721 | SOURCEGUARDIAN_DIR="/usr/local/sourceguardian"; 722 | 723 | [ -n "${CMD}" ] || do_usage; 724 | 725 | for ARG in "$@"; 726 | do 727 | case "${ARG}" in 728 | --beta) 729 | BETA=1; 730 | ;; 731 | --php=*) 732 | PVN=$(echo "${ARG}" | cut -d= -f2 | egrep -o '^(5|7|8)[0-9]+'); #' 733 | [ -z "${PVN}" ] && do_usage; 734 | ;; 735 | --ver=*) 736 | EXT_VERSION=$(echo "${ARG}" | cut -d= -f2); 737 | [ -z "${EXT_VERSION}" ] && do_usage; 738 | ;; 739 | --verbose) 740 | QUIET=0; 741 | ;; 742 | esac; 743 | done; 744 | 745 | if [ -n "${BETA}" ] && [ -n "${EXT_VERSION}" ]; then 746 | echo "Can not use --beta and --ver= together at the same time..."; 747 | exit 2; 748 | fi; 749 | 750 | case "${CMD}" in 751 | install) 752 | [ -n "${EXT}" ] || do_usage; 753 | do_install "${PVN}"; 754 | ;; 755 | remove) 756 | [ -n "${EXT}" ] || do_usage; 757 | BETA=0; 758 | do_remove; 759 | ;; 760 | status) 761 | [ -n "${EXT}" ] || do_usage; 762 | BETA=0; 763 | do_status; 764 | ;; 765 | version) 766 | [ -n "${EXT}" ] || do_usage; 767 | BETA=0; 768 | do_status | grep -i 'version'; 769 | ;; 770 | selfupdate) 771 | do_update_script; 772 | ;; 773 | *) 774 | BETA=0; 775 | do_usage; 776 | ;; 777 | esac; 778 | 779 | exit 0; 780 | -------------------------------------------------------------------------------- /php/test_sockets_ssl.php: -------------------------------------------------------------------------------- 1 | [993], 12 | "smtp.gmail.com" => [25, 465, 587], 13 | ]; 14 | 15 | if ($debug) { 16 | error_reporting(E_ALL); 17 | ini_set('display_errors', 1); 18 | } else { 19 | error_reporting(0); 20 | ini_set('display_errors', 0); 21 | } 22 | 23 | print "
\n";
24 | foreach ($hosts as $host => $ports)
25 | {
26 |     foreach ($ports as $port)
27 |     {
28 |         if ($test_nonssl)
29 |         {
30 |             print "Connection to $host:$port without SSL  ";
31 |             if (!($fp = fsockopen($host, $port, $errno, $errstr, 30))) 
32 |             {
33 |                 fclose($fp);
34 |                 print "OK";
35 |             }
36 |             else
37 |             {
38 |                 print "FAILED";
39 |             }
40 |             print "\n";
41 |         }
42 |         if ($test_ssl)
43 |         {
44 |             print "Connection to $host:$port with SSL  ";
45 |             if (!($fp = fsockopen("ssl://".$host, $port, $errno, $errstr, 30)))
46 |             {
47 |                 fclose($fp);
48 |                 print "OK";
49 |             }
50 |             else
51 |             {
52 |                 print "FAILED";
53 |             }
54 |             print "\n";
55 |         }
56 |     }
57 | }
58 | print "
\n"; 59 | 60 | exit(0); 61 | 62 | -------------------------------------------------------------------------------- /rspamd/rspamd2-statistic-sqlite.conf: -------------------------------------------------------------------------------- 1 | # Rspamd statistic setup 2 | # Pre-built files could be loaded from: 3 | # http://rspamd.com/rspamd_statistics/bayes.spam.sqlite 4 | # - and - 5 | # http://rspamd.com/rspamd_statistics/bayes.ham.sqlite 6 | 7 | classifier "bayes" { 8 | tokenizer { 9 | name = "osb"; 10 | } 11 | cache { 12 | path = "${DBDIR}/learn_cache.sqlite"; 13 | } 14 | min_tokens = 11; 15 | backend = "sqlite3"; 16 | languages_enabled = true; 17 | min_learns = 200; 18 | 19 | statfile { 20 | symbol = "BAYES_HAM"; 21 | path = "${DBDIR}/bayes.ham.sqlite"; 22 | spam = false; 23 | } 24 | statfile { 25 | symbol = "BAYES_SPAM"; 26 | path = "${DBDIR}/bayes.spam.sqlite"; 27 | spam = true; 28 | } 29 | learn_condition =<= 0.95 42 | else 43 | cl = 'ham' 44 | in_class = prob <= 0.05 45 | end 46 | 47 | if in_class then 48 | return false,string.format('already in class %s; probability %.2f%%', 49 | cl, math.abs((prob - 0.5) * 200.0)) 50 | end 51 | end 52 | end 53 | 54 | return true 55 | end 56 | EOD 57 | 58 | } 59 | 60 | -------------------------------------------------------------------------------- /sftp/proftpd.conf: -------------------------------------------------------------------------------- 1 | # modified by Poralix 2 | 3 | ServerName "ProFTPd" 4 | ServerType standalone 5 | 6 | Port 0 7 | PassivePorts 35000 35999 8 | UseReverseDNS off 9 | TimesGMT off 10 | TimeoutLogin 120 11 | TimeoutIdle 600 12 | TimeoutNoTransfer 900 13 | TimeoutStalled 3600 14 | 15 | ScoreboardFile /var/run/proftpd/proftpd.pid 16 | 17 | TransferLog /var/log/proftpd/xferlog.legacy 18 | LogFormat default "%h %l %u %t \"%r\" %s %b" 19 | LogFormat auth "%v [%P] %h %t \"%r\" %s" 20 | LogFormat write "%h %l %u %t \"%r\" %s %b" 21 | 22 | #DON'T modify this log format. Its used by DirectAdmin to determine user usage 23 | LogFormat userlog "%u %b %m %a" 24 | ExtendedLog /var/log/proftpd/|SERVER_IP|.bytes WRITE,READ userlog 25 | 26 | AuthUserFile /etc/proftpd.passwd 27 | DefaultServer on 28 | AuthOrder mod_auth_file.c 29 | 30 | #AuthPAM off 31 | 32 | 33 | 34 | Port 21 35 | TLSEngine on 36 | TLSLog /var/log/proftpd/proftpd.tls.log 37 | TLSProtocol TLSv1 TLSv1.1 TLSv1.2 38 | TLSCipherSuite HIGH:MEDIUM:+TLSv1 39 | TLSVerifyClient off 40 | TLSRequired off 41 | 42 | #Certificates 43 | TLSRSACertificateFile /etc/exim.cert 44 | TLSRSACertificateKeyFile /etc/exim.key 45 | TLSCertificateChainFile /etc/exim.cacert 46 | #TLSCACertificateFile /etc/ftpd/root.cert.pem 47 | 48 | TLSCipherSuite HIGH:MEDIUM:+TLSv1:!SSLv2:+SSLv3 49 | 50 | AuthUserFile /etc/proftpd.passwd 51 | AuthOrder mod_auth_file.c 52 | 53 | 54 | 55 | 56 | PassivePorts 35000 35999 57 | DeferWelcome on 58 | 59 | RequireValidShell no 60 | 61 | DefaultRoot ~ 62 | DirFakeUser on ftp 63 | DirFakeGroup on ftp 64 | 65 | User ftp 66 | Group ftp 67 | #UserAlias anonymous ftp 68 | 69 | AllowStoreRestart on 70 | AllowRetrieveRestart on 71 | 72 | #ListOptions -a 73 | 74 | Umask 022 75 | DisplayLogin welcome.msg 76 | DisplayChdir readme 77 | AllowOverwrite yes 78 | #IdentLookups off 79 | ExtendedLog /var/log/proftpd/access.log WRITE,READ write 80 | ExtendedLog /var/log/proftpd/auth.log AUTH auth 81 | 82 | # 83 | # Paranoia logging level.... 84 | # 85 | #ExtendedLog /var/log/proftpd/paranoid.log ALL default 86 | 87 | 88 | Include /etc/proftpd.sftp.conf 89 | -------------------------------------------------------------------------------- /sftp/proftpd.sftp.conf: -------------------------------------------------------------------------------- 1 | # modified by Poralix 2 | 3 | 4 | 5 | # The SFTP configuration 6 | Port 2121 7 | 8 | SFTPEngine on 9 | AuthUserFile /etc/proftpd.passwd 10 | #AuthOrder mod_auth_file.c 11 | 12 | ExtendedLog /var/log/proftpd/|SERVER_IP|.bytes WRITE,READ userlog 13 | 14 | SFTPLog /var/log/proftpd/sftp.log 15 | SFTPHostKey /etc/ssh/ssh_host_ed25519_key 16 | SFTPHostKey /etc/ssh/ssh_host_ecdsa_key 17 | SFTPHostKey /etc/ssh/ssh_host_rsa_key 18 | SFTPHostKey /etc/ssh/ssh_host_dsa_key 19 | SFTPAuthorizedUserKeys file:~/.sftp/authorized_keys 20 | 21 | MaxLoginAttempts 6 22 | 23 | SFTPClientMatch ".*WS_FTP.*" channelWindowSize 1GB #WS_FTP initial window size 24 | SFTPClientMatch ".*ClientSftp" sftpProtocolVersion 3 #CuteFTPPro8 25 | SFTPClientMatch ".*WinSCP.*" sftpProtocolVersion 3 #upload/download fix for WinSCP 26 | SFTPClientMatch ".*SecureBlackbox.*" sftpProtocolVersion 3 27 | SFTPClientMatch "1.0" sftpProtocolVersion 3 channelWindowSize 1GB 28 | SFTPClientMatch ".*J2SSH_Maverick.*" channelWindowSize 1GB 29 | SFTPClientMatch ".*WeOnlyDo.*" sftpProtocolVersion 3 channelWindowSize 1GB 30 | SFTPClientMatch ".*EldoS.SSHBlackbox.3.*" sftpProtocolVersion 3 channelWindowSize 1GB 31 | SFTPClientMatch ".*IP.Works.*" channelWindowSize 1GB 32 | 33 | 34 | -------------------------------------------------------------------------------- /ssl/README.md: -------------------------------------------------------------------------------- 1 | # Script install_server_wide_cert.sh 2 | 3 | This script is written to be used on a directadmin powered server and can 4 | be used to do a quick installation of a SSL cert/key for server-wide usage 5 | i.e. SSL cert used by default (on hostname) in Apache/Nginx, Exim/Dovecot. 6 | 7 | # Installation 8 | 9 | ``` 10 | cd /usr/local/directadmin/scripts/custom 11 | wget -O ./install_server_wide_cert.sh https://raw.githubusercontent.com/poralix/directadmin-utils/master/ssl/install_server_wide_cert.sh 12 | chmod 700 ./install_server_wide_cert.sh 13 | ``` 14 | 15 | # Usage 16 | 17 | ``` 18 | cd /usr/local/directadmin/scripts/custom 19 | ./install_server_wide_cert.sh [] 20 | ``` 21 | 22 | - PATH_TO_CERT - a full or relative path to a CERT you want to install 23 | - PATH_TO_KEY - a full or relative path to a KEY you want to install 24 | - PATH_TO_CACERT - a full or relative path to a CACERT you want to install 25 | 26 | # CACERT 27 | 28 | The cacerts file is a collection of trusted certificate authority (CA) certificates. They are Intermediate/chain certificates. 29 | 30 | # Author 31 | 32 | Alex S Grebenschikov 33 | -------------------------------------------------------------------------------- /ssl/install_server_wide_cert.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # ============================================================================ 3 | # This script is written to be used on a directadmin powered server and can 4 | # be used to do a quick installation of a SSL cert/key for server-wide usage 5 | # i.e. SSL cert used by default (on hostname) in Apache/Nginx, Exim/Dovecot. 6 | # ============================================================================ 7 | # IMPORTANT: Written and tested on CentOS 6.x, 7.x only 8 | # ============================================================================ 9 | # Written by: Alex S Grebenschikov (support@poralix.com) 10 | # Copyright: 2015-2022 Alex S Grebenschikov 11 | # Created at: Wed 28 Oct 2015 17:14:32 NOVT 12 | # Last modified: Mon Oct 10 18:24:44 +07 2022 13 | # Version: 0.8 $ Mon Oct 10 18:24:44 +07 2022 14 | # 0.7 $ Wed Aug 31 12:58:29 +07 2022 15 | # 0.6 $ Wed May 26 13:14:23 +07 2021 16 | # 0.5 $ Mon May 17 21:51:45 +07 2021 17 | # 0.4 $ Tue Apr 27 18:40:46 +07 2021 18 | # 0.3 $ Tue Apr 27 00:33:34 +07 2021 19 | # 0.2 $ Thu Jun 29 09:36:58 +07 2017 20 | # 0.1 $ Wed 28 Oct 2015 17:14:53 NOVT 21 | # ============================================================================ 22 | # 23 | 24 | # A LIST OF SERVICES YOU WANT A CERT TO BE INSTALLED FOR 25 | SERVICES=""; 26 | SERVICES="${SERVICES} directadmin"; 27 | SERVICES="${SERVICES} apache"; 28 | SERVICES="${SERVICES} nginx"; 29 | SERVICES="${SERVICES} litespeed"; 30 | SERVICES="${SERVICES} openlitespeed"; 31 | SERVICES="${SERVICES} exim"; 32 | SERVICES="${SERVICES} dovecot"; 33 | 34 | # ============================================================================ 35 | # DO NOT CHANGE ANYTHING BELLOW 36 | # ============================================================================ 37 | 38 | BOLD="$(tput -Txterm bold)"; 39 | RED="$(tput -Txterm setaf 1)"; 40 | GREEN="$(tput -Txterm setaf 2)"; 41 | RESET="$(tput -Txterm sgr0)"; 42 | OPENSSL='/usr/bin/openssl'; 43 | 44 | die() 45 | { 46 | echo "$1"; 47 | exit $2; 48 | } 49 | 50 | do_restart() 51 | { 52 | echo; 53 | if [ -x "/bin/systemctl" ] || [ -x "/usr/bin/systemctl" ]; then 54 | echo "${GREEN}[OK]${RESET} ${BOLD}Restarting service $1${RESET}"; 55 | systemctl restart $1; 56 | elif [ -x "/etc/init.d/$1" ]; then 57 | echo "${GREEN}[OK]${RESET} ${BOLD}Restarting service $1${RESET}"; 58 | /etc/init.d/$1 restart; 59 | else 60 | echo "${RED}[WARNING]${RESET} You need to restart $1 manually in order to changes to take effect!"; 61 | fi; 62 | } 63 | 64 | do_cert_exim_dovecot() 65 | { 66 | echo "${GREEN}[OK]${RESET} ${BOLD}Installing cert/key for Exim and Dovecot${RESET}"; 67 | COMBCERTTO="/etc/exim.cert"; 68 | KEYTO="/etc/exim.key"; 69 | cp -v ${PCERT} ${COMBCERTTO}; 70 | cp -v ${PKEY} ${KEYTO}; 71 | if [ -f "${PCACERT}" ]; then 72 | echo "" >> ${COMBCERTTO}; 73 | cat ${PCACERT} >> ${COMBCERTTO}; 74 | fi; 75 | chmod -v 600 ${KEYTO} ${COMBCERTTO}; 76 | chown -v mail ${KEYTO} ${COMBCERTTO}; 77 | chgrp -v mail ${KEYTO} ${COMBCERTTO}; 78 | do_restart exim; 79 | do_restart dovecot; 80 | echo; 81 | } 82 | 83 | do_cert_httpd() 84 | { 85 | CACERTTO="/etc/httpd/conf/ssl.crt/server.ca"; 86 | CERTTO="/etc/httpd/conf/ssl.crt/server.crt"; 87 | COMBCERTTO="/etc/httpd/conf/ssl.crt/server.crt.combined"; 88 | KEYTO="/etc/httpd/conf/ssl.key/server.key"; 89 | cp -v ${PCERT} ${CERTTO}; 90 | cp -v ${PCERT} ${COMBCERTTO}; 91 | cp -v ${PKEY} ${KEYTO}; 92 | if [ -f "${PCACERT}" ]; then 93 | cp -v ${PCACERT} ${CACERTTO}; 94 | echo "" >> ${COMBCERTTO}; 95 | cat ${PCACERT} >> ${COMBCERTTO}; 96 | fi; 97 | chmod -v 600 ${CERTTO} ${KEYTO} ${CACERTTO} ${COMBCERTTO}; 98 | chown -v root ${CERTTO} ${KEYTO} ${CACERTTO} ${COMBCERTTO}; 99 | chgrp -v root ${CERTTO} ${KEYTO} ${CACERTTO} ${COMBCERTTO}; 100 | } 101 | 102 | do_cert_openlitespeed() 103 | { 104 | c=$(echo ${SERVICES} | grep -c "\ openlitespeed"); 105 | if [ "${c}" -eq "0" ]; then 106 | echo "${RED}[WARNING]${RESET} ${BOLD}Skipping installation of cert/key for OpenLiteSpeed${RESET}"; 107 | else 108 | echo "${GREEN}[OK]${RESET} ${BOLD}Installing cert/key for OpenLiteSpeed${RESET}"; 109 | CACERTTO="/usr/local/lsws/ssl.crt/server.ca"; 110 | CERTTO="/usr/local/lsws/ssl.crt/server.crt"; 111 | COMBCERTTO="/usr/local/lsws//ssl.crt/server.crt.combined"; 112 | KEYTO="/usr/local/lsws/ssl.key/server.key"; 113 | cp -v ${PCERT} ${CERTTO}; 114 | cp -v ${PCERT} ${COMBCERTTO}; 115 | cp -v ${PKEY} ${KEYTO}; 116 | if [ -f "${PCACERT}" ]; then 117 | cp -v ${PCACERT} ${CACERTTO}; 118 | echo "" >> ${COMBCERTTO}; 119 | cat ${PCACERT} >> ${COMBCERTTO}; 120 | fi; 121 | chmod -v 600 ${CERTTO} ${KEYTO} ${CACERTTO} ${COMBCERTTO}; 122 | chown -v root ${CERTTO} ${KEYTO} ${CACERTTO} ${COMBCERTTO}; 123 | chgrp -v root ${CERTTO} ${KEYTO} ${CACERTTO} ${COMBCERTTO}; 124 | do_cert_httpd; 125 | do_restart litespeed; 126 | fi; 127 | echo; 128 | } 129 | 130 | do_cert_litespeed() 131 | { 132 | c=$(echo ${SERVICES} | grep -c "\ litespeed"); 133 | if [ "${c}" -eq "0" ]; then 134 | echo "${RED}[WARNING]${RESET} ${BOLD}Skipping installation of cert/key for Litespeed${RESET}"; 135 | else 136 | echo "${GREEN}[OK]${RESET} ${BOLD}Installing cert/key for Litespeed${RESET}"; 137 | do_cert_httpd; 138 | do_restart litespeed; 139 | fi; 140 | echo; 141 | } 142 | 143 | do_cert_apache() 144 | { 145 | c=$(echo ${SERVICES} | grep -c "\ apache"); 146 | if [ "${c}" -eq "0" ]; then 147 | echo "${RED}[WARNING]${RESET} ${BOLD}Skipping installation of cert/key for Apache${RESET}"; 148 | else 149 | echo "${GREEN}[OK]${RESET} ${BOLD}Installing cert/key for Apache${RESET}"; 150 | do_cert_httpd; 151 | do_restart httpd; 152 | fi; 153 | echo; 154 | } 155 | 156 | do_cert_nginx() 157 | { 158 | c=$(echo ${SERVICES} | grep -c "\ apache"); 159 | if [ "${c}" -eq "0" ]; then 160 | echo "${RED}[WARNING]${RESET} ${BOLD}Skipping installation of cert/key for NGINX${RESET}"; 161 | else 162 | echo "${GREEN}[OK]${RESET} ${BOLD}Installing cert/key for NGINX${RESET}"; 163 | CACERTTO="/etc/nginx/ssl.crt/server.ca"; 164 | CERTTO="/etc/nginx/ssl.crt/server.crt"; 165 | COMBCERTTO="/etc/nginx/ssl.crt/server.crt.combined"; 166 | KEYTO="/etc/nginx/ssl.key/server.key"; 167 | cp -v ${PCERT} ${CERTTO}; 168 | cp -v ${PCERT} ${COMBCERTTO}; 169 | cp -v ${PKEY} ${KEYTO}; 170 | if [ -f "${PCACERT}" ]; then 171 | cp -v ${PCACERT} ${CACERTTO}; 172 | echo "" >> ${COMBCERTTO}; 173 | cat ${PCACERT} >> ${COMBCERTTO}; 174 | fi; 175 | chmod -v 600 ${CERTTO} ${KEYTO} ${CACERTTO} ${COMBCERTTO}; 176 | chown -v root ${CERTTO} ${KEYTO} ${CACERTTO} ${COMBCERTTO}; 177 | chgrp -v root ${CERTTO} ${KEYTO} ${CACERTTO} ${COMBCERTTO}; 178 | do_restart nginx; 179 | fi; 180 | echo; 181 | } 182 | 183 | do_cert_directadmin() 184 | { 185 | echo "${GREEN}[OK]${RESET} ${BOLD}Installing cert/key for Directadmin${RESET}"; 186 | CERTTO="/usr/local/directadmin/conf/cacert.pem"; 187 | KEYTO="/usr/local/directadmin/conf/cakey.pem"; 188 | CACERTTO=""; 189 | cp -v "${PCERT}" "${CERTTO}"; 190 | cp -v "${PKEY}" "${KEYTO}"; 191 | if [ -f "${PCACERT}" ]; then 192 | CACERTTO="/usr/local/directadmin/conf/carootcert.pem"; 193 | cp -v "${PCACERT}" "${CACERTTO}"; 194 | fi; 195 | chmod -v 600 ${CERTTO} ${KEYTO} ${CACERTTO}; 196 | chown -v diradmin:diradmin ${CERTTO} ${KEYTO} ${CACERTTO}; 197 | killall -9 directadmin; 198 | do_restart directadmin; 199 | echo; 200 | } 201 | 202 | do_cert_pureftpd() 203 | { 204 | echo "${GREEN}[OK]${RESET} ${BOLD}Installing cert/key for PureFTPd${RESET}"; 205 | COMBO_CERT_TO="/etc/pure-ftpd.pem"; 206 | cat ${PCERT} ${PKEY} > ${COMBO_CERT_TO}; 207 | [ -f "${PCACERT}" ] && cat ${PCACERT} >> ${COMBO_CERT_TO}; 208 | chmod -v 600 ${COMBO_CERT_TO}; 209 | chown -v 0:0 ${COMBO_CERT_TO}; 210 | do_restart pure-ftpd; 211 | echo; 212 | } 213 | 214 | do_print_copyright() 215 | { 216 | echo "=========================================================================="; 217 | echo " ${BOLD}Written by Alex Grebenschikov (support@poralix.com), 2015-2022${RESET}"; 218 | echo "=========================================================================="; 219 | } 220 | 221 | do_print_usage() 222 | { 223 | echo ""; 224 | echo "Usage: ${BOLD}${0} []${RESET}"; 225 | echo ""; 226 | echo " ============================================================================"; 227 | echo " This script is written to be used on a directadmin powered server and can"; 228 | echo " be used to do a quick installation of a SSL cert/key for server-wide usage"; 229 | echo " i.e. SSL cert used by default (on hostname) in Apache/Nginx, Exim/Dovecot."; 230 | echo " ============================================================================"; 231 | echo ""; 232 | echo " PATH_TO_CERT - a full or relative path to a CERT you want to install"; 233 | echo " PATH_TO_KEY - a full or relative path to a KEY you want to install"; 234 | echo " PATH_TO_CACERT - a full or relative path to a CACERT you want to install"; 235 | echo ""; 236 | echo " ============================================================================"; 237 | echo ""; 238 | echo " Copyright (c) 2015-2022 Alex S Grebenschikov (support@poralix.com)"; 239 | echo ""; 240 | exit 1; 241 | } 242 | 243 | do_validate_cert() 244 | { 245 | CCERT="$1"; 246 | ${OPENSSL} x509 -noout -pubkey -in ${CCERT} >/dev/null 2>&1; 247 | RES=$?; 248 | echo "[INFO] Validating CERT ${BOLD}${CCERT}${RESET}"; 249 | if [ "${RES}" -gt "0" ]; then 250 | echo "${RED}[ERROR]${RESET} File ${CCERT} is not a valid CERT"; 251 | exit 1; 252 | else 253 | HCERT=$(${OPENSSL} x509 -noout -pubkey -in ${CCERT} 2>&1 | ${OPENSSL} md5 | awk '{print $2}'); 254 | echo "${GREEN}[OK]${RESET} The cert md5 hash: ${BOLD}${HCERT}${RESET}"; 255 | fi; 256 | echo; 257 | } 258 | 259 | do_validate_key() 260 | { 261 | CKEY="$1"; 262 | ${OPENSSL} pkey -pubout -in ${CKEY} >/dev/null 2>&1; 263 | RES=$?; 264 | echo "[INFO] Validating CERT ${BOLD}${CKEY}${RESET}"; 265 | if [ "${RES}" -gt "0" ]; then 266 | echo "${RED}[ERROR]${RESET} File ${CKEY} is not a valid KEY"; 267 | exit 1; 268 | else 269 | HKEY=$(${OPENSSL} pkey -pubout -in ${CKEY} 2>&1 | ${OPENSSL} md5 | awk '{print $2}'); 270 | echo "${GREEN}[OK]${RESET} The key md5 hash: ${BOLD}${HKEY}${RESET}"; 271 | fi; 272 | echo; 273 | } 274 | 275 | # PRINT USAGE 276 | [ "$#" -lt "2" ] && do_print_usage; 277 | 278 | # SET PARAMS 279 | PCERT="$1"; 280 | PKEY="$2"; 281 | 282 | [ -d "/usr/local/directadmin/" ] || die "${RED}[ERROR]${RESET} DirectAdmin is not installed here. Terminating..." 1; 283 | [ -f "/usr/local/directadmin/custombuild/options.conf" ] || die "${RED}[ERROR]${RESET} CustomBuild is not installed here. Terminating..." 2; 284 | 285 | do_print_copyright; 286 | do_validate_cert "${PCERT}"; 287 | do_validate_key "${PKEY}"; 288 | 289 | if [ "${HKEY}" == "${HCERT}" ]; then 290 | echo "${GREEN}[OK]${RESET} CERT and KEY match each other!"; 291 | echo; 292 | else 293 | echo "${RED}[ERROR]${RESET} CERT and KEY do not match each other!"; 294 | exit 1; 295 | fi; 296 | 297 | if [ -n "$3" ] && [ -f "$3" ]; then 298 | PCACERT="$3"; 299 | echo "[INFO] You provided CACERT ${BOLD}${PCACERT}${RESET}"; 300 | do_validate_cert "${PCACERT}"; 301 | fi; 302 | 303 | # DIRECTADMIN 304 | c=$(echo ${SERVICES} | grep -c directadmin); 305 | [ "$c" -eq "1" ] && do_cert_directadmin; 306 | 307 | WEBSERVER=$(grep ^webserver= /usr/local/directadmin/custombuild/options.conf | awk -F= '{print $2}'); 308 | 309 | case "${WEBSERVER}" in 310 | apache) 311 | # APACHE 312 | do_cert_apache; 313 | ;; 314 | nginx) 315 | # NGINX 316 | do_cert_nginx; 317 | ;; 318 | nginx_apache) 319 | # NGINX + APACHE 320 | do_cert_apache; 321 | do_cert_nginx; 322 | ;; 323 | litespeed) 324 | # LITESPEED 325 | do_cert_litespeed; 326 | ;; 327 | openlitespeed) 328 | # OPENLITESPEED 329 | do_cert_openlitespeed; 330 | ;; 331 | esac; 332 | 333 | # EXIM 334 | c=$(echo ${SERVICES} | grep -c exim); 335 | if [ "$c" -eq "1" ]; then 336 | do_cert_exim_dovecot; 337 | else 338 | c=$(echo ${SERVICES} | grep -c dovecot); 339 | [ "$c" -eq "1" ] && do_cert_exim_dovecot; 340 | fi; 341 | 342 | # PureFTPd 343 | c=$(grep -c ^ftpd=pureftpd /usr/local/directadmin/custombuild/options.conf); 344 | if [ "${c}" -eq "1" ]; then 345 | do_cert_pureftpd; 346 | fi; 347 | 348 | exit 0; 349 | -------------------------------------------------------------------------------- /webapps/rainloop.install.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | ############################################################################# 3 | # 4 | # A script to install/upgrade Rainloop on Directadmin server 5 | # Written by Alex S Grebenschikov (support@poralix.com) 6 | # Version: v.0.2.1 $ Thu Aug 1 18:56:02 +07 2019 7 | # 8 | # Versions: 9 | # - v.0.2.1 $ Thu Aug 1 18:56:02 +07 2019 10 | # - v.0.2.0 $ Thu Aug 9 16:00:01 +07 2018 11 | # - v.0.1.1 $ Tue Aug 8 10:45:20 +07 2017 12 | # - v.0.1 $ Wed Jul 12 15:49:10 +07 2017 13 | # 14 | # TO DO: 15 | # - autoconfigure new installation 16 | # 17 | ############################################################################# 18 | # set -x 19 | 20 | #URL="https://www.rainloop.net/repository/webmail/rainloop-community-latest.zip"; 21 | #SOURCE="rainloop-community-latest.zip" 22 | URL="https://www.rainloop.net/repository/webmail/rainloop-latest.zip"; 23 | SOURCE="rainloop-latest.zip" 24 | MYSQL_DB="da_rainloop"; 25 | MYSQL_USER="da_rainloop"; 26 | MYSQL_HOST="localhost"; 27 | MYSQL_PASSWORD=""; 28 | MYSQL_ACCESS_HOST="localhost"; 29 | 30 | die() 31 | { 32 | echo "$1"; exit $2; 33 | } 34 | 35 | genpass() 36 | { 37 | tr -cd 'a-zA-Z0-9' < /dev/urandom 2>/dev/null | head -c${1:-`perl -le 'print int rand(7) + 10'`} 38 | } 39 | 40 | genhtaccess() 41 | { 42 | HTAF="/var/www/html/rainloop/data/.htaccess"; 43 | if [ -f "${HTAF}" ]; then 44 | echo "[OK] Found ${HTAF} file. Make sure it blocks access to the data folder over HTTP/HTTPS (Apache and NGINX/Apache only)..."; 45 | grep -m1 -q "^Deny from all" "${HTAF}" || echo -e "\nDeny from all" >> "${HTAF}"; 46 | else 47 | echo "[OK] Creating ${HTAF} file to block access to the data folder over HTTP/HTTPS (Apache and NGINX/Apache only)..."; 48 | touch "${HTAF}"; 49 | chown webapps:webapps "${HTAF}"; 50 | echo "Deny from all" > "${HTAF}"; 51 | echo "" >> "${HTAF}"; 52 | echo " Options -Indexes" >> "${HTAF}"; 53 | echo "" >> "${HTAF}"; 54 | fi; 55 | } 56 | 57 | MYSQL="/usr/local/bin/mysql"; 58 | [ -x "${MYSQL}" ] || MYSQL="/usr/bin/mysql"; 59 | [ -x "${MYSQL}" ] || die "Could not find MySQL bin! Terminating..." 1; 60 | MYSQL_OPT="--defaults-extra-file=/usr/local/directadmin/conf/my.cnf"; 61 | [ -f "/usr/local/directadmin/conf/my.cnf" ] || die "Could find MySQL settings for Directadmin! Terminating..." 1; 62 | 63 | # DOWNLOAD SOURCE FILE 64 | cd /var/www/html || die "Directory /var/www/html does not exist! Terminating..." 1; 65 | wget -O "${SOURCE}" "${URL}"; 66 | 67 | # UNPACK SOURCE FILE 68 | [ -s "${SOURCE}" ] || die "Download failed or file is corrupted! Terminating..." 1; 69 | [ -x "/usr/bin/unzip" ] || die "Unzip is not installed on your server! Terminating..."; 70 | /usr/bin/unzip -o "${SOURCE}" -d rainloop; 71 | 72 | # GENERATE HTACCESS FILE 73 | genhtaccess; 74 | 75 | # SET CORRECT PERMISSIONS 76 | [ -d "/var/www/html/rainloop" ] || die "Rainloop failed to unpack! Terminating..."; 77 | echo "[OK] Setting correct permissions on folders of RainLoop..."; 78 | find /var/www/html/rainloop/ -type d -exec chmod 755 {} \; 79 | echo "[OK] Setting correct permissions on files of RainLoop..."; 80 | find /var/www/html/rainloop/ -type f -exec chmod 644 {} \; 81 | echo "[OK] Settings correct owner of RainLoop files and folders..."; 82 | chown -R webapps:webapps /var/www/html/rainloop/; 83 | 84 | # PROTECT DATA FOLDER 85 | echo "[OK] Protecting RainLoop data files and folders..."; 86 | chmod 700 /var/www/html/rainloop/data; 87 | 88 | # UPDATE ALIASES WITH CUSTOMBUILD 89 | [ -d "/usr/local/directadmin/custombuild" ] || die "CustomBuild not found! Terminating..."; 90 | [ -d "/usr/local/directadmin/custombuild/custom/" ] || mkdir "/usr/local/directadmin/custombuild/custom/" 91 | [ -f "/usr/local/directadmin/custombuild/custom/webapps.list" ] || touch "/usr/local/directadmin/custombuild/custom/webapps.list"; 92 | c=$(grep -c "rainloop=rainloop" /usr/local/directadmin/custombuild/custom/webapps.list); 93 | if [ "$c" == "0" ]; then 94 | echo "[OK] Updating web-server configuration for RainLoop..."; 95 | echo "rainloop=rainloop" >> /usr/local/directadmin/custombuild/custom/webapps.list; 96 | cd /usr/local/directadmin/custombuild; 97 | ./build rewrite_confs; 98 | fi; 99 | 100 | # CREATE MYSQL DB 101 | if [ ! -f "/var/www/html/rainloop/data/INSTALLED" ]; then 102 | ${MYSQL} ${MYSQL_OPT} -e "USE ${MYSQL_DB};" --host=${MYSQL_HOST} 2>/dev/null; 103 | RETVAL=$?; 104 | 105 | echo ""; 106 | echo "[OK] Go to http://$(hostname)/rainloop/?admin to complete and configure installation!"; 107 | echo " Default username/password for admin access:"; 108 | echo " - admin"; 109 | echo " - 12345"; 110 | 111 | if [ "${RETVAL}" == "1" ]; then 112 | MYSQL_PASSWORD=$(genpass 16); 113 | ${MYSQL} ${MYSQL_OPT} -e "CREATE DATABASE ${MYSQL_DB};" --host=${MYSQL_HOST} 2>&1; 114 | ${MYSQL} ${MYSQL_OPT} -e "GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP,ALTER,LOCK TABLES,INDEX ON ${MYSQL_DB}.* TO '${MYSQL_USER}'@'${MYSQL_ACCESS_HOST}' IDENTIFIED BY '${MYSQL_PASSWORD}';" --host=${MYSQL_HOST} 2>&1; 115 | echo ""; 116 | echo "[OK] Database created: "; 117 | echo " - MySQL user: ${MYSQL_USER}"; 118 | echo " - MySQL password: ${MYSQL_PASSWORD}"; 119 | echo " - MySQL DB name: ${MYSQL_DB}"; 120 | echo " - MySQL host: ${MYSQL_HSOT}"; 121 | fi; 122 | 123 | die "[OK] Installation completed!" 0; 124 | fi; 125 | 126 | # EXIT 127 | echo ""; 128 | die "[OK] Upgrade completed!" 0; 129 | -------------------------------------------------------------------------------- /webserver-errors/400.shtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 400 Bad Request 9 | 10 | 11 |

Bad Request

12 | There was an error in your request. 13 |
14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | -------------------------------------------------------------------------------- /webserver-errors/401.shtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 401 Authorization Required 9 | 10 | 11 |

Authorization Required

12 | This server could not verify that you are authorized to access the document requested. Either you supplied the wrong credentials (e.g., bad password), or your browser doesn't understand how to supply the credentials required. 13 |
14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | -------------------------------------------------------------------------------- /webserver-errors/403.shtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 403 Forbidden 9 | 10 | 11 |

Forbidden

12 | You don't have permission to access on this server. 13 |
14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | -------------------------------------------------------------------------------- /webserver-errors/404.shtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 404 Not Found 9 | 10 | 11 |

Not Found

12 | The requested URL was not found on this server. 13 |
14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | -------------------------------------------------------------------------------- /webserver-errors/500.shtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 500 Internal Server Error 9 | 10 | 11 |

Internal Server Error

12 | The server encountered an internal error or misconfiguration and was unable to complete your request 13 |
14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | -------------------------------------------------------------------------------- /webserver-errors/README.md: -------------------------------------------------------------------------------- 1 | # Webserver errors 2 | 3 | Files with errors adapted for modile devices: 4 | 5 | - 400.shtml - 400 Bad Request 6 | - 401.shtml - 401 Authorization Required 7 | - 403.shtml - 403 Forbidden 8 | - 404.shtml - 404 Not Found 9 | - 500.shtml - 500 Internal Server Error 10 | 11 | Default webserver errors when shown on a mobile device screen have too small fonts. 12 | It is fixed in the listed files. 13 | --------------------------------------------------------------------------------