feat:添加openlitespeed到列表

This commit is contained in:
okxlin 2023-08-13 00:53:00 +08:00
parent 8f95460c95
commit 90b7d4dabe
59 changed files with 6108 additions and 2 deletions

View File

@ -0,0 +1,6 @@
CONTAINER_NAME="openlitespeed"
DATA_PATH="./data"
PANEL_APP_PORT_CONSOLE="40113"
PANEL_APP_PORT_HTTP="80"
PANEL_APP_PORT_HTTPS="443"
TIME_ZONE="Asia/Shanghai"

View File

@ -0,0 +1,40 @@
additionalProperties:
formFields:
- default: 80
edit: true
envKey: PANEL_APP_PORT_HTTP
labelEn: HTTP Port
labelZh: HTTP端口
required: true
rule: paramPort
type: number
- default: 443
edit: true
envKey: PANEL_APP_PORT_HTTPS
labelEn: HTTPS Port
labelZh: HTTPS端口
required: true
rule: paramPort
type: number
- default: 40113
edit: true
envKey: PANEL_APP_PORT_CONSOLE
labelEn: Console Port
labelZh: 控制台端口
required: true
rule: paramPort
type: number
- default: ./data
disabled: true
envKey: DATA_PATH
labelEn: Data folder path
labelZh: 数据文件夹路径
required: true
type: text
- default: Asia/Shanghai
edit: true
envKey: TIME_ZONE
labelEn: Time zone
labelZh: 时区
required: true
type: text

View File

@ -0,0 +1,293 @@
#!/usr/bin/env bash
EMAIL=''
NO_EMAIL=''
DOMAIN=''
INSTALL=''
UNINSTALL=''
TYPE=0
CONT_NAME='litespeed'
ACME_SRC='https://raw.githubusercontent.com/Neilpang/acme.sh/master/acme.sh'
EPACE=' '
RENEW=''
RENEW_ALL=''
FORCE=''
REVOKE=''
REMOVE=''
echow(){
FLAG=${1}
shift
echo -e "\033[1m${EPACE}${FLAG}\033[0m${@}"
}
help_message(){
case ${1} in
"1")
echo 'You will need to install acme script at the first time.'
echo 'Please run acme.sh --install --email example@example.com'
;;
"2")
echo -e "\033[1mOPTIONS\033[0m"
echow '-D, --domain [DOMAIN_NAME]'
echo "${EPACE}${EPACE}Example: acme.sh --domain example.com"
echo "${EPACE}${EPACE}will auto detect and apply for both example.com and www.example.com domains."
echow '-H, --help'
echo "${EPACE}${EPACE}Display help and exit."
echo -e "\033[1m Only for the First time\033[0m"
echow '--install --email [EMAIL_ADDR]'
echo "${EPACE}${EPACE}Will install ACME with the Email provided"
echow '-r, --renew'
echo "${EPACE}${EPACE}Renew a specific domain with -D or --domain parameter if posibile. To force renew, use -f parameter."
echow '-R, --renew-all'
echo "${EPACE}${EPACE}Renew all domains if possible. To force renew, use -f parameter."
echow '-f, -F, --force'
echo "${EPACE}${EPACE}Force renew for a specific domain or all domains."
echow '-v, --revoke'
echo "${EPACE}${EPACE}Revoke a domain."
echow '-V, --remove'
echo "${EPACE}${EPACE}Remove a domain."
exit 0
;;
"3")
echo 'Please run acme.sh --domain [DOMAIN_NAME] to apply certificate'
exit 0
;;
esac
}
check_input(){
if [ -z "${1}" ]; then
help_message 2
fi
}
domain_filter(){
if [ -z "${1}" ]; then
help_message 3
fi
DOMAIN="${1}"
DOMAIN="${DOMAIN#http://}"
DOMAIN="${DOMAIN#https://}"
DOMAIN="${DOMAIN#ftp://}"
DOMAIN="${DOMAIN#scp://}"
DOMAIN="${DOMAIN#scp://}"
DOMAIN="${DOMAIN#sftp://}"
DOMAIN=${DOMAIN%%/*}
}
email_filter(){
CKREG="^[a-z0-9!#\$%&'*+/=?^_\`{|}~-]+(\.[a-z0-9!#$%&'*+/=?^_\`{|}~-]+)*@([a-z0-9]([a-z0-9-]*[a-z0-9])?\.)+[a-z0-9]([a-z0-9-]*[a-z0-9])?\$"
if [[ "${1}" =~ ${CKREG} ]] ; then
echo -e "[O] The E-mail \033[32m${1}\033[0m is valid."
else
echo -e "[X] The E-mail \e[31m${1}\e[39m is invalid"
exit 1
fi
}
cert_hook(){
echo '[Start] Adding ACME hook'
docker compose exec ${CONT_NAME} su -s /bin/bash -c "certhookctl.sh"
echo '[End] Adding ACME hook'
}
www_domain(){
CHECK_WWW=$(echo ${1} | cut -c1-4)
if [[ ${CHECK_WWW} == www. ]] ; then
DOMAIN=$(echo ${1} | cut -c 5-)
else
DOMAIN=${1}
fi
WWW_DOMAIN="www.${DOMAIN}"
}
domain_verify(){
curl -Is http://${DOMAIN}/ | grep -i LiteSpeed > /dev/null 2>&1
if [ ${?} = 0 ]; then
echo -e "[O] The domain name \033[32m${DOMAIN}\033[0m is accessible."
TYPE=1
curl -Is http://${WWW_DOMAIN}/ | grep -i LiteSpeed > /dev/null 2>&1
if [ ${?} = 0 ]; then
echo -e "[O] The domain name \033[32m${WWW_DOMAIN}\033[0m is accessible."
TYPE=2
else
echo -e "[!] The domain name ${WWW_DOMAIN} is inaccessible."
fi
else
echo -e "[X] The domain name \e[31m${DOMAIN}\e[39m is inaccessible, please verify."
exit 1
fi
}
install_acme(){
echo '[Start] Install ACME'
if [ "${1}" = 'true' ]; then
docker compose exec litespeed su -c "cd; wget ${ACME_SRC}; chmod 755 acme.sh; \
./acme.sh --install --cert-home ~/.acme.sh/certs; \
rm ~/acme.sh"
elif [ "${2}" != '' ]; then
email_filter "${2}"
docker compose exec litespeed su -c "cd; wget ${ACME_SRC}; chmod 755 acme.sh; \
./acme.sh --install --cert-home ~/.acme.sh/certs --accountemail ${2}; \
rm ~/acme.sh"
else
help_message 1
exit 1
fi
echo '[End] Install ACME'
}
uninstall_acme(){
echo '[Start] Uninstall ACME'
docker compose exec ${CONT_NAME} su -c "~/.acme.sh/acme.sh --uninstall"
echo '[End] Uninstall ACME'
exit 0
}
check_acme(){
echo '[Start] Checking ACME'
docker compose exec ${CONT_NAME} su -c "test -f /root/.acme.sh/acme.sh"
if [ ${?} != 0 ]; then
install_acme "${NO_EMAIL}" "${EMAIL}"
cert_hook
help_message 3
fi
echo '[End] Checking ACME'
}
lsws_restart(){
docker compose exec ${CONT_NAME} su -c '/usr/local/lsws/bin/lswsctrl restart >/dev/null'
}
doc_root_verify(){
if [ "${DOC_ROOT}" = '' ]; then
DOC_PATH="/var/www/vhosts/${1}/html"
else
DOC_PATH="${DOC_ROOT}"
fi
docker compose exec ${CONT_NAME} su -c "[ -e ${DOC_PATH} ]"
if [ ${?} -eq 0 ]; then
echo -e "[O] The document root folder \033[32m${DOC_PATH}\033[0m does exist."
else
echo -e "[X] The document root folder \e[31m${DOC_PATH}\e[39m does not exist!"
exit 1
fi
}
install_cert(){
echo '[Start] Apply Lets Encrypt Certificate'
if [ ${TYPE} = 1 ]; then
docker compose exec ${CONT_NAME} su -c "/root/.acme.sh/acme.sh --issue -d ${1} -w ${DOC_PATH}"
elif [ ${TYPE} = 2 ]; then
docker compose exec ${CONT_NAME} su -c "/root/.acme.sh/acme.sh --issue -d ${1} -d www.${1} -w ${DOC_PATH}"
else
echo 'unknown Type!'
exit 2
fi
echo '[End] Apply Lets Encrypt Certificate'
}
renew_acme(){
echo '[Start] Renew ACME'
if [ "${FORCE}" = 'true' ]; then
docker compose exec ${CONT_NAME} su -c "~/.acme.sh/acme.sh --renew --domain ${1} --force"
else
docker compose exec ${CONT_NAME} su -c "~/.acme.sh/acme.sh --renew --domain ${1}"
fi
echo '[End] Renew ACME'
lsws_restart
}
renew_all_acme(){
echo '[Start] Renew all ACME'
if [ "${FORCE}" = 'true' ]; then
docker compose exec ${CONT_NAME} su -c "~/.acme.sh/acme.sh --renew-all --force"
else
docker compose exec ${CONT_NAME} su -c "~/.acme.sh/acme.sh --renew-all"
fi
echo '[End] Renew all ACME'
lsws_restart
}
revoke(){
echo '[Start] Revoke a domain'
docker compose exec ${CONT_NAME} su -c "~/.acme.sh/acme.sh --revoke --domain ${1}"
echo '[End] Revoke a domain'
lsws_restart
}
remove(){
echo '[Start] Remove a domain'
docker compose exec ${CONT_NAME} su -c "~/.acme.sh/acme.sh --remove --domain ${1}"
echo '[End] Remove a domain'
lsws_restart
}
main(){
if [ "${RENEW_ALL}" = 'true' ]; then
renew_all_acme
exit 0
elif [ "${RENEW}" = 'true' ]; then
renew_acme ${DOMAIN}
exit 0
elif [ "${REVOKE}" = 'true' ]; then
revoke ${DOMAIN}
exit 0
elif [ "${REMOVE}" = 'true' ]; then
remove ${DOMAIN}
exit 0
fi
check_acme
domain_filter ${DOMAIN}
www_domain ${DOMAIN}
domain_verify
doc_root_verify ${DOMAIN}
install_cert ${DOMAIN}
lsws_restart
}
check_input ${1}
while [ ! -z "${1}" ]; do
case ${1} in
-[hH] | -help | --help)
help_message 2
;;
-[dD] | -domain | --domain) shift
check_input "${1}"
DOMAIN="${1}"
;;
-[iI] | --install )
INSTALL=true
;;
-[uU] | --uninstall )
UNINSTALL=true
uninstall_acme
;;
-[fF] | --force )
FORCE=true
;;
-[r] | --renew )
RENEW=true
;;
-[R] | --renew-all )
RENEW_ALL=true
;;
-[v] | --revoke )
REVOKE=true
;;
-[V] | --remove )
REMOVE=true
;;
-[eE] | --email ) shift
check_input "${1}"
EMAIL="${1}"
;;
*)
help_message 2
;;
esac
shift
done
main

View File

@ -0,0 +1,60 @@
#!/usr/bin/env bash
APP_NAME=''
DOMAIN=''
EPACE=' '
echow(){
FLAG=${1}
shift
echo -e "\033[1m${EPACE}${FLAG}\033[0m${@}"
}
help_message(){
echo -e "\033[1mOPTIONS\033[0m"
echow '-A, --app [app_name] -D, --domain [DOMAIN_NAME]'
echo "${EPACE}${EPACE}Example: appinstall.sh -A wordpress -D example.com"
echo "${EPACE}${EPACE}Will install WordPress CMS under the example.com domain"
echow '-H, --help'
echo "${EPACE}${EPACE}Display help and exit."
exit 0
}
check_input(){
if [ -z "${1}" ]; then
help_message
exit 1
fi
}
app_download(){
docker compose exec litespeed su -c "appinstallctl.sh --app ${1} --domain ${2}"
bash bin/webadmin.sh -r
exit 0
}
main(){
app_download ${APP_NAME} ${DOMAIN}
}
check_input ${1}
while [ ! -z "${1}" ]; do
case ${1} in
-[hH] | -help | --help)
help_message
;;
-[aA] | -app | --app) shift
check_input "${1}"
APP_NAME="${1}"
;;
-[dD] | -domain | --domain) shift
check_input "${1}"
DOMAIN="${1}"
;;
*)
help_message
;;
esac
shift
done
main

View File

@ -0,0 +1,660 @@
#!/bin/bash
DEFAULT_VH_ROOT='/var/www/vhosts'
VH_DOC_ROOT=''
VHNAME=''
APP_NAME=''
DOMAIN=''
WWW_UID=''
WWW_GID=''
WP_CONST_CONF=''
PUB_IP=$(curl -s http://checkip.amazonaws.com)
DB_HOST='mysql'
PLUGINLIST="litespeed-cache.zip"
THEME='twentytwenty'
EPACE=' '
echow(){
FLAG=${1}
shift
echo -e "\033[1m${EPACE}${FLAG}\033[0m${@}"
}
help_message(){
echo -e "\033[1mOPTIONS\033[0m"
echow '-A, -app [wordpress] -D, --domain [DOMAIN_NAME]'
echo "${EPACE}${EPACE}Example: appinstallctl.sh --app wordpress --domain example.com"
echow '-H, --help'
echo "${EPACE}${EPACE}Display help and exit."
exit 0
}
check_input(){
if [ -z "${1}" ]; then
help_message
exit 1
fi
}
linechange(){
LINENUM=$(grep -n "${1}" ${2} | cut -d: -f 1)
if [ -n "${LINENUM}" ] && [ "${LINENUM}" -eq "${LINENUM}" ] 2>/dev/null; then
sed -i "${LINENUM}d" ${2}
sed -i "${LINENUM}i${3}" ${2}
fi
}
ck_ed(){
if [ ! -f /bin/ed ]; then
echo "Install ed package.."
apt-get install ed -y > /dev/null 2>&1
fi
}
ck_unzip(){
if [ ! -f /usr/bin/unzip ]; then
echo "Install unzip package.."
apt-get install unzip -y > /dev/null 2>&1
fi
}
get_owner(){
WWW_UID=$(stat -c "%u" ${DEFAULT_VH_ROOT})
WWW_GID=$(stat -c "%g" ${DEFAULT_VH_ROOT})
if [ ${WWW_UID} -eq 0 ] || [ ${WWW_GID} -eq 0 ]; then
WWW_UID=1000
WWW_GID=1000
echo "Set owner to ${WWW_UID}"
fi
}
get_db_pass(){
if [ -f ${DEFAULT_VH_ROOT}/${1}/.db_pass ]; then
SQL_DB=$(grep -i Database ${VH_ROOT}/.db_pass | awk -F ':' '{print $2}' | tr -d '"')
SQL_USER=$(grep -i Username ${VH_ROOT}/.db_pass | awk -F ':' '{print $2}' | tr -d '"')
SQL_PASS=$(grep -i Password ${VH_ROOT}/.db_pass | awk -F ':' '{print $2}' | tr -d '"')
else
echo 'db pass file can not locate, skip wp-config pre-config.'
fi
}
set_vh_docroot(){
if [ "${VHNAME}" != '' ]; then
VH_ROOT="${DEFAULT_VH_ROOT}/${VHNAME}"
VH_DOC_ROOT="${DEFAULT_VH_ROOT}/${VHNAME}/html"
WP_CONST_CONF="${VH_DOC_ROOT}/wp-content/plugins/litespeed-cache/data/const.default.ini"
elif [ -d ${DEFAULT_VH_ROOT}/${1}/html ]; then
VH_ROOT="${DEFAULT_VH_ROOT}/${1}"
VH_DOC_ROOT="${DEFAULT_VH_ROOT}/${1}/html"
WP_CONST_CONF="${VH_DOC_ROOT}/wp-content/plugins/litespeed-cache/data/const.default.ini"
else
echo "${DEFAULT_VH_ROOT}/${1}/html does not exist, please add domain first! Abort!"
exit 1
fi
}
check_sql_native(){
local COUNTER=0
local LIMIT_NUM=100
until [ "$(curl -v mysql:3306 2>&1 | grep -i 'native\|Connected')" ]; do
echo "Counter: ${COUNTER}/${LIMIT_NUM}"
COUNTER=$((COUNTER+1))
if [ ${COUNTER} = 10 ]; then
echo '--- MySQL is starting, please wait... ---'
elif [ ${COUNTER} = ${LIMIT_NUM} ]; then
echo '--- MySQL is timeout, exit! ---'
exit 1
fi
sleep 1
done
}
install_wp_plugin(){
for PLUGIN in ${PLUGINLIST}; do
wget -q -P ${VH_DOC_ROOT}/wp-content/plugins/ https://downloads.wordpress.org/plugin/${PLUGIN}
if [ ${?} = 0 ]; then
ck_unzip
unzip -qq -o ${VH_DOC_ROOT}/wp-content/plugins/${PLUGIN} -d ${VH_DOC_ROOT}/wp-content/plugins/
else
echo "${PLUGINLIST} FAILED to download"
fi
done
rm -f ${VH_DOC_ROOT}/wp-content/plugins/*.zip
}
set_htaccess(){
if [ ! -f ${VH_DOC_ROOT}/.htaccess ]; then
touch ${VH_DOC_ROOT}/.htaccess
fi
cat << EOM > ${VH_DOC_ROOT}/.htaccess
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
EOM
}
get_theme_name(){
THEME_NAME=$(grep WP_DEFAULT_THEME ${VH_DOC_ROOT}/wp-includes/default-constants.php | grep -v '!' | awk -F "'" '{print $4}')
echo "${THEME_NAME}" | grep 'twenty' >/dev/null 2>&1
if [ ${?} = 0 ]; then
THEME="${THEME_NAME}"
fi
}
set_lscache(){
cat << EOM > "${WP_CONST_CONF}"
;
; This is the predefined default LSCWP configuration file
;
; All the keys and values please refer \`src/const.cls.php\`
;
; Comments start with \`;\`
;
;; -------------------------------------------------- ;;
;; -------------- General ----------------- ;;
;; -------------------------------------------------- ;;
; O_AUTO_UPGRADE
auto_upgrade = false
; O_API_KEY
api_key = ''
; O_SERVER_IP
server_ip = ''
; O_NEWS
news = false
;; -------------------------------------------------- ;;
;; -------------- Cache ----------------- ;;
;; -------------------------------------------------- ;;
cache-priv = true
cache-commenter = true
cache-rest = true
cache-page_login = true
cache-favicon = true
cache-resources = true
cache-browser = false
cache-mobile = false
cache-mobile_rules = 'Mobile
Android
Silk/
Kindle
BlackBerry
Opera Mini
Opera Mobi'
cache-exc_useragents = ''
cache-exc_cookies = ''
cache-exc_qs = ''
cache-exc_cat = ''
cache-exc_tag = ''
cache-force_uri = ''
cache-force_pub_uri = ''
cache-priv_uri = ''
cache-exc = ''
cache-exc_roles = ''
cache-drop_qs = 'fbclid
gclid
utm*
_ga'
cache-ttl_pub = 604800
cache-ttl_priv = 1800
cache-ttl_frontpage = 604800
cache-ttl_feed = 604800
; O_CACHE_TTL_REST
cache-ttl_rest = 604800
cache-ttl_browser = 31557600
cache-login_cookie = ''
cache-vary_group = ''
cache-ttl_status = '403 3600
404 3600
500 3600'
;; -------------------------------------------------- ;;
;; -------------- Purge ----------------- ;;
;; -------------------------------------------------- ;;
; O_PURGE_ON_UPGRADE
purge-upgrade = true
; O_PURGE_STALE
purge-stale = true
purge-post_all = false
purge-post_f = true
purge-post_h = true
purge-post_p = true
purge-post_pwrp = true
purge-post_a = true
purge-post_y = false
purge-post_m = true
purge-post_d = false
purge-post_t = true
purge-post_pt = true
purge-timed_urls = ''
purge-timed_urls_time = ''
purge-hook_all = 'switch_theme
wp_create_nav_menu
wp_update_nav_menu
wp_delete_nav_menu
create_term
edit_terms
delete_term
add_link
edit_link
delete_link'
;; -------------------------------------------------- ;;
;; -------------- ESI ----------------- ;;
;; -------------------------------------------------- ;;
; O_ESI
esi = false
; O_ESI_CACHE_ADMBAR
esi-cache_admbar = true
; O_ESI_CACHE_COMMFORM
esi-cache_commform = true
; O_ESI_NONCE
esi-nonce = 'stats_nonce
subscribe_nonce'
;; -------------------------------------------------- ;;
;; -------------- Utilities ----------------- ;;
;; -------------------------------------------------- ;;
util-heartbeat = true
util-instant_click = false
util-check_advcache = true
util-no_https_vary = false
;; -------------------------------------------------- ;;
;; -------------- Debug ----------------- ;;
;; -------------------------------------------------- ;;
; O_DEBUG_DISABLE_ALL
debug-disable_all = false
; O_DEBUG
debug = false
; O_DEBUG_IPS
debug-ips = '127.0.0.1'
; O_DEBUG_LEVEL
debug-level = false
; O_DEBUG_FILESIZE
debug-filesize = 3
; O_DEBUG_COOKIE
debug-cookie = false
; O_DEBUG_COLLAPS_QS
debug-collaps_qs = false
; O_DEBUG_INC
debug-inc = ''
; O_DEBUG_EXC
debug-exc = ''
;; -------------------------------------------------- ;;
;; -------------- DB Optm ----------------- ;;
;; -------------------------------------------------- ;;
; O_DB_OPTM_REVISIONS_MAX
db_optm-revisions_max = 0
; O_DB_OPTM_REVISIONS_AGE
db_optm-revisions_age = 0
;; -------------------------------------------------- ;;
;; -------------- HTML Optm ----------------- ;;
;; -------------------------------------------------- ;;
; O_OPTM_CSS_MIN
optm-css_min = false
optm-css_inline_min = false
; O_OPTM_CSS_COMB
optm-css_comb = false
optm-css_comb_priority = false
; O_OPTM_CSS_HTTP2
optm-css_http2 = false
optm-css_exc = ''
; O_OPTM_JS_MIN
optm-js_min = false
optm-js_inline_min = false
; O_OPTM_JS_COMB
optm-js_comb = false
optm-js_comb_priority = false
; O_OPTM_JS_HTTP2
optm-js_http2 = false
; O_OPTM_EXC_JQ
optm-js_exc = ''
optm-ttl = 604800
optm-html_min = false
optm-qs_rm = false
optm-ggfonts_rm = false
; O_OPTM_CSS_ASYNC
optm-css_async = false
; O_OPTM_CCSS_GEN
optm-ccss_gen = true
; O_OPTM_CCSS_ASYNC
optm-ccss_async = true
; O_OPTM_CSS_ASYNC_INLINE
optm-css_async_inline = true
; O_OPTM_CSS_FONT_DISPLAY
optm-css_font_display = false
; O_OPTM_JS_DEFER
optm-js_defer = false
; O_OPTM_JS_INLINE_DEFER
optm-js_inline_defer = false
optm-emoji_rm = false
optm-exc_jq = true
optm-ggfonts_async = false
optm-max_size = 2
optm-rm_comment = false
optm-exc_roles = ''
optm-ccss_con = ''
optm-js_defer_exc = ''
; O_OPTM_DNS_PREFETCH
optm-dns_prefetch = ''
; O_OPTM_DNS_PREFETCH_CTRL
optm-dns_prefetch_ctrl = false
optm-exc = ''
; O_OPTM_CCSS_SEP_POSTTYPE
optm-ccss_sep_posttype = ''
; O_OPTM_CCSS_SEP_URI
optm-ccss_sep_uri = ''
;; -------------------------------------------------- ;;
;; -------------- Object Cache ----------------- ;;
;; -------------------------------------------------- ;;
object = true
object-kind = false
;object-host = 'localhost'
object-host = '/var/www/memcached.sock'
;object-port = 11211
cache_object_port = ''
object-life = 360
object-persistent = true
object-admin = true
object-transients = true
object-db_id = 0
object-user = ''
object-pswd = ''
object-global_groups = 'users
userlogins
usermeta
user_meta
site-transient
site-options
site-lookup
blog-lookup
blog-details
rss
global-posts
blog-id-cache'
object-non_persistent_groups = 'comment
counts
plugins
wc_session_id'
;; -------------------------------------------------- ;;
;; -------------- Discussion ----------------- ;;
;; -------------------------------------------------- ;;
; O_DISCUSS_AVATAR_CACHE
discuss-avatar_cache = false
; O_DISCUSS_AVATAR_CRON
discuss-avatar_cron = false
; O_DISCUSS_AVATAR_CACHE_TTL
discuss-avatar_cache_ttl = 604800
;; -------------------------------------------------- ;;
;; -------------- Media ----------------- ;;
;; -------------------------------------------------- ;;
; O_MEDIA_LAZY
media-lazy = false
; O_MEDIA_LAZY_PLACEHOLDER
media-lazy_placeholder = ''
; O_MEDIA_PLACEHOLDER_RESP
media-placeholder_resp = false
; O_MEDIA_PLACEHOLDER_RESP_COLOR
media-placeholder_resp_color = '#cfd4db'
; O_MEDIA_PLACEHOLDER_RESP_GENERATOR
media-placeholder_resp_generator = false
; O_MEDIA_PLACEHOLDER_RESP_SVG
media-placeholder_resp_svg = '<svg xmlns="http://www.w3.org/2000/svg" width="{width}" height="{height}" viewBox="0 0 {width} {height}"><rect width="100%" height="100%" fill="{color}"/></svg>'
; O_MEDIA_PLACEHOLDER_LQIP
media-placeholder_lqip = false
; O_MEDIA_PLACEHOLDER_LQIP_QUAL
media-placeholder_lqip_qual = 4
; O_MEDIA_PLACEHOLDER_RESP_ASYNC
media-placeholder_resp_async = true
; O_MEDIA_IFRAME_LAZY
media-iframe_lazy = false
; O_MEDIA_LAZYJS_INLINE
media-lazyjs_inline = false
; O_MEDIA_LAZY_EXC
media-lazy_exc = ''
; O_MEDIA_LAZY_CLS_EXC
media-lazy_cls_exc = ''
; O_MEDIA_LAZY_PARENT_CLS_EXC
media-lazy_parent_cls_exc = ''
; O_MEDIA_IFRAME_LAZY_CLS_EXC
media-iframe_lazy_cls_exc = ''
; O_MEDIA_IFRAME_LAZY_PARENT_CLS_EXC
media-iframe_lazy_parent_cls_exc = ''
; O_MEDIA_LAZY_URI_EXC
media-lazy_uri_exc = ''
;; -------------------------------------------------- ;;
;; -------------- Image Optm ----------------- ;;
;; -------------------------------------------------- ;;
img_optm-auto = false
img_optm-cron = true
img_optm-ori = true
img_optm-rm_bkup = false
img_optm-webp = false
img_optm-lossless = false
img_optm-exif = false
img_optm-webp_replace = false
img_optm-webp_attr = 'img.src
div.data-thumb
img.data-src
div.data-large_image
img.retina_logo_url
div.data-parallax-image
video.poster'
img_optm-webp_replace_srcset = false
img_optm-jpg_quality = 82
;; -------------------------------------------------- ;;
;; -------------- Crawler ----------------- ;;
;; -------------------------------------------------- ;;
crawler = false
crawler-inc_posts = true
crawler-inc_pages = true
crawler-inc_cats = true
crawler-inc_tags = true
crawler-exc_cpt = ''
crawler-order_links = 'date_desc'
crawler-usleep = 500
crawler-run_duration = 400
crawler-run_interval = 600
crawler-crawl_interval = 302400
crawler-threads = 3
crawler-timeout = 30
crawler-load_limit = 1
; O_CRAWLER_SITEMAP
crawler-sitemap = ''
; O_CRAWLER_DROP_DOMAIN
crawler-drop_domain = true
crawler-roles = ''
crawler-cookies = ''
;; -------------------------------------------------- ;;
;; -------------- Misc ----------------- ;;
;; -------------------------------------------------- ;;
; O_MISC_HTACCESS_FRONT
misc-htaccess_front = ''
; O_MISC_HTACCESS_BACK
misc-htaccess_back = ''
; O_MISC_HEARTBEAT_FRONT
misc-heartbeat_front = false
; O_MISC_HEARTBEAT_FRONT_TTL
misc-heartbeat_front_ttl = 60
; O_MISC_HEARTBEAT_BACK
misc-heartbeat_back = false
; O_MISC_HEARTBEAT_BACK_TTL
misc-heartbeat_back_ttl = 60
; O_MISC_HEARTBEAT_EDITOR
misc-heartbeat_editor = false
; O_MISC_HEARTBEAT_EDITOR_TTL
misc-heartbeat_editor_ttl = 15
;; -------------------------------------------------- ;;
;; -------------- CDN ----------------- ;;
;; -------------------------------------------------- ;;
cdn = false
cdn-ori = ''
cdn-ori_dir = ''
cdn-exc = ''
cdn-remote_jq = false
cdn-quic = false
cdn-quic_email = ''
cdn-quic_key = ''
cdn-cloudflare = false
cdn-cloudflare_email = ''
cdn-cloudflare_key = ''
cdn-cloudflare_name = ''
cdn-cloudflare_zone = ''
; \`cdn-mapping\` needs to be put in the end with a section tag
;; -------------------------------------------------- ;;
;; -------------- CDN 2 ----------------- ;;
;; -------------------------------------------------- ;;
; <------------ CDN Mapping Example BEGIN -------------------->
; Need to keep the section tag \`[cdn-mapping]\` before list.
;
; NOTE 1) Need to set all child options to make all resources to be replaced without missing.
; NOTE 2) \`url[n]\` option must have to enable the row setting of \`n\`.
; NOTE 3) This section needs to be put in the end of this .ini file
;
; To enable the 2nd mapping record by default, please remove the \`;;\` in the related lines.
[cdn-mapping]
url[0] = ''
inc_js[0] = true
inc_css[0] = true
inc_img[0] = true
filetype[0] = '.aac
.css
.eot
.gif
.jpeg
.js
.jpg
.less
.mp3
.mp4
.ogg
.otf
.pdf
.png
.svg
.ttf
.woff'
;;url[1] = 'https://2nd_CDN_url.com/'
;;filetype[1] = '.webm'
; <------------ CDN Mapping Example END ------------------>
EOM
THEME_PATH="${VH_DOC_ROOT}/wp-content/themes/${THEME}"
if [ ! -f ${THEME_PATH}/functions.php ]; then
cat >> "${THEME_PATH}/functions.php" <<END
<?php
require_once( WP_CONTENT_DIR.'/../wp-admin/includes/plugin.php' );
\$path = 'litespeed-cache/litespeed-cache.php' ;
if (!is_plugin_active( \$path )) {
activate_plugin( \$path ) ;
rename( __FILE__ . '.bk', __FILE__ );
}
END
elif [ ! -f ${THEME_PATH}/functions.php.bk ]; then
cp ${THEME_PATH}/functions.php ${THEME_PATH}/functions.php.bk
ck_ed
ed ${THEME_PATH}/functions.php << END >>/dev/null 2>&1
2i
require_once( WP_CONTENT_DIR.'/../wp-admin/includes/plugin.php' );
\$path = 'litespeed-cache/litespeed-cache.php' ;
if (!is_plugin_active( \$path )) {
activate_plugin( \$path ) ;
rename( __FILE__ . '.bk', __FILE__ );
}
.
w
q
END
fi
}
preinstall_wordpress(){
if [ "${VHNAME}" != '' ]; then
get_db_pass ${VHNAME}
else
get_db_pass ${DOMAIN}
fi
if [ ! -f ${VH_DOC_ROOT}/wp-config.php ] && [ -f ${VH_DOC_ROOT}/wp-config-sample.php ]; then
cp ${VH_DOC_ROOT}/wp-config-sample.php ${VH_DOC_ROOT}/wp-config.php
NEWDBPWD="define('DB_PASSWORD', '${SQL_PASS}');"
linechange 'DB_PASSWORD' ${VH_DOC_ROOT}/wp-config.php "${NEWDBPWD}"
NEWDBPWD="define('DB_USER', '${SQL_USER}');"
linechange 'DB_USER' ${VH_DOC_ROOT}/wp-config.php "${NEWDBPWD}"
NEWDBPWD="define('DB_NAME', '${SQL_DB}');"
linechange 'DB_NAME' ${VH_DOC_ROOT}/wp-config.php "${NEWDBPWD}"
#NEWDBPWD="define('DB_HOST', '${PUB_IP}');"
NEWDBPWD="define('DB_HOST', '${DB_HOST}');"
linechange 'DB_HOST' ${VH_DOC_ROOT}/wp-config.php "${NEWDBPWD}"
elif [ -f ${VH_DOC_ROOT}/wp-config.php ]; then
echo "${VH_DOC_ROOT}/wp-config.php already exist, exit !"
exit 1
else
echo 'Skip!'
exit 2
fi
}
app_wordpress_dl(){
if [ ! -f "${VH_DOC_ROOT}/wp-config.php" ] && [ ! -f "${VH_DOC_ROOT}/wp-config-sample.php" ]; then
wp core download \
--allow-root \
--quiet
else
echo 'wordpress already exist, abort!'
exit 1
fi
}
change_owner(){
if [ "${VHNAME}" != '' ]; then
chown -R ${WWW_UID}:${WWW_GID} ${DEFAULT_VH_ROOT}/${VHNAME}
else
chown -R ${WWW_UID}:${WWW_GID} ${DEFAULT_VH_ROOT}/${DOMAIN}
fi
}
main(){
set_vh_docroot ${DOMAIN}
get_owner
cd ${VH_DOC_ROOT}
if [ "${APP_NAME}" = 'wordpress' ] || [ "${APP_NAME}" = 'wp' ]; then
check_sql_native
app_wordpress_dl
preinstall_wordpress
install_wp_plugin
set_htaccess
get_theme_name
set_lscache
change_owner
exit 0
else
echo "APP: ${APP_NAME} not support, exit!"
exit 1
fi
}
check_input ${1}
while [ ! -z "${1}" ]; do
case ${1} in
-[hH] | -help | --help)
help_message
;;
-[aA] | -app | --app) shift
check_input "${1}"
APP_NAME="${1}"
;;
-[dD] | -domain | --domain) shift
check_input "${1}"
DOMAIN="${1}"
;;
-vhname | --vhname) shift
VHNAME="${1}"
;;
*)
help_message
;;
esac
shift
done
main

View File

@ -0,0 +1,18 @@
#!/bin/bash
BOTCRON='/var/spool/cron/crontabs/root'
cert_hook(){
grep 'acme' ${BOTCRON} >/dev/null
if [ ${?} = 0 ]; then
grep 'lswsctrl' ${BOTCRON} >/dev/null
if [ ${?} = 0 ]; then
echo 'Hook already exist, skip!'
else
sed -i 's/--cron/--cron --renew-hook "\/usr\/local\/lsws\/bin\/lswsctrl restart"/g' ${BOTCRON}
fi
else
echo "[X] ${BOTCRON} does not exist, please check it later!"
fi
}
cert_hook

View File

@ -0,0 +1,160 @@
#!/usr/bin/env bash
CK_RESULT=''
LSDIR='/usr/local/lsws'
LS_HTTPD_CONF="${LSDIR}/conf/httpd_config.xml"
OLS_HTTPD_CONF="${LSDIR}/conf/httpd_config.conf"
EPACE=' '
echow(){
FLAG=${1}
shift
echo -e "\033[1m${EPACE}${FLAG}\033[0m${@}"
}
help_message(){
echo -e "\033[1mOPTIONS\033[0m"
echow '-A, --add [DOMAIN_NAME]'
echo "${EPACE}${EPACE}Will add domain to listener and creat a virtual host from template"
echow '-D, --del [DOMAIN_NAME]'
echo "${EPACE}${EPACE}Will delete domain from listener"
echow '-H, --help'
echo "${EPACE}${EPACE}Display help."
}
check_lsv(){
if [ -f ${LSDIR}/bin/openlitespeed ]; then
LSV='openlitespeed'
elif [ -f ${LSDIR}/bin/litespeed ]; then
LSV='lsws'
else
echo 'Version not exist, abort!'
exit 1
fi
}
dot_escape(){
ESCAPE=$(echo ${1} | sed 's/\./\\./g')
}
check_duplicate(){
CK_RESULT=$(grep -E "${1}" ${2})
}
fst_match_line(){
FIRST_LINE_NUM=$(grep -n -m 1 ${1} ${2} | awk -F ':' '{print $1}')
}
fst_match_after(){
FIRST_NUM_AFTER=$(tail -n +${1} ${2} | grep -n -m 1 ${3} | awk -F ':' '{print $1}')
}
lst_match_line(){
fst_match_after ${1} ${2} ${3}
LAST_LINE_NUM=$((${FIRST_LINE_NUM}+${FIRST_NUM_AFTER}-1))
}
check_input(){
if [ -z "${1}" ]; then
help_message
exit 1
fi
}
check_www(){
CHECK_WWW=$(echo ${1} | cut -c1-4)
if [[ ${CHECK_WWW} == www. ]] ; then
echo 'www domain shoudnt be passed!'
exit 1
fi
}
www_domain(){
check_www ${1}
WWW_DOMAIN=$(echo www.${1})
}
add_ls_domain(){
fst_match_line 'docker.xml</templateFile>' ${LS_HTTPD_CONF}
NEWNUM=$((FIRST_LINE_NUM+2))
sed -i "${NEWNUM}i \ \ \ \ \ \ <member>\n \ \ \ \ \ \ \ <vhName>${DOMAIN}</vhName>\n \ \ \ \ \ \ \ <vhDomain>${DOMAIN},${WWW_DOMAIN}</vhDomain>\n \ \ \ \ \ \ </member>" ${LS_HTTPD_CONF}
}
add_ols_domain(){
perl -0777 -p -i -e 's/(vhTemplate docker \{[^}]+)\}*(^.*listeners.*$)/\1$2
member '${DOMAIN}' {
vhDomain '${DOMAIN},${WWW_DOMAIN}'
}/gmi' ${OLS_HTTPD_CONF}
}
add_domain(){
check_lsv
dot_escape ${1}
DOMAIN=${ESCAPE}
www_domain ${1}
if [ "${LSV}" = 'lsws' ]; then
check_duplicate "vhDomain.*${DOMAIN}" ${LS_HTTPD_CONF}
if [ "${CK_RESULT}" != '' ]; then
echo "# It appears the domain already exist! Check the ${LS_HTTPD_CONF} if you believe this is a mistake!"
exit 1
fi
elif [ "${LSV}" = 'openlitespeed' ]; then
check_duplicate "member.*${DOMAIN}" ${OLS_HTTPD_CONF}
if [ "${CK_RESULT}" != '' ]; then
echo "# It appears the domain already exist! Check the ${OLS_HTTPD_CONF} if you believe this is a mistake!"
exit 1
fi
fi
add_ls_domain
add_ols_domain
}
del_ls_domain(){
fst_match_line "<vhName>*${1}" ${LS_HTTPD_CONF}
FIRST_LINE_NUM=$((FIRST_LINE_NUM-1))
lst_match_line ${FIRST_LINE_NUM} ${LS_HTTPD_CONF} '</member>'
sed -i "${FIRST_LINE_NUM},${LAST_LINE_NUM}d" ${LS_HTTPD_CONF}
}
del_ols_domain(){
fst_match_line ${1} ${OLS_HTTPD_CONF}
lst_match_line ${FIRST_LINE_NUM} ${OLS_HTTPD_CONF} '}'
sed -i "${FIRST_LINE_NUM},${LAST_LINE_NUM}d" ${OLS_HTTPD_CONF}
}
del_domain(){
check_lsv
dot_escape ${1}
DOMAIN=${ESCAPE}
if [ "${LSV}" = 'lsws' ]; then
check_duplicate "vhDomain.*${DOMAIN}" ${LS_HTTPD_CONF}
if [ "${CK_RESULT}" = '' ]; then
echo "# Domain non-exist! Check the ${LS_HTTPD_CONF} if you believe this is a mistake!"
exit 1
fi
elif [ "${LSV}" = 'openlitespeed' ]; then
check_duplicate "member.*${DOMAIN}" ${OLS_HTTPD_CONF}
if [ "${CK_RESULT}" = '' ]; then
echo "# Domain non-exist! Check the ${OLS_HTTPD_CONF} if you believe this is a mistake!"
exit 1
fi
fi
del_ls_domain ${1}
del_ols_domain ${1}
}
check_input ${1}
while [ ! -z "${1}" ]; do
case ${1} in
-[hH] | -help | --help)
help_message
;;
-[aA] | -add | --add) shift
add_domain ${1}
;;
-[dD] | -del | --del | --delete) shift
del_domain ${1}
;;
*)
help_message
;;
esac
shift
done

View File

@ -0,0 +1,236 @@
#!/bin/bash
LSDIR='/usr/local/lsws'
OWASP_DIR="${LSDIR}/conf/owasp"
RULE_FILE='modsec_includes.conf'
LS_HTTPD_CONF="${LSDIR}/conf/httpd_config.xml"
OLS_HTTPD_CONF="${LSDIR}/conf/httpd_config.conf"
EPACE=' '
OWASP_V='3.3.4'
echow(){
FLAG=${1}
shift
echo -e "\033[1m${EPACE}${FLAG}\033[0m${@}"
}
help_message(){
echo -e "\033[1mOPTIONS\033[0m"
echow '-E, --enable'
echo "${EPACE}${EPACE}Will Enable mod_secure module with latest OWASP version of rules"
echow '-D, --disable'
echo "${EPACE}${EPACE}Will Disable mod_secure module with latest OWASP version of rules"
echow '-H, --help'
echo "${EPACE}${EPACE}Display help and exit."
exit 0
}
check_lsv(){
if [ -f ${LSDIR}/bin/openlitespeed ]; then
LSV='openlitespeed'
elif [ -f ${LSDIR}/bin/litespeed ]; then
LSV='lsws'
else
echo 'Version not exist, abort!'
exit 1
fi
}
check_input(){
if [ -z "${1}" ]; then
help_message
exit 1
fi
}
mk_owasp_dir(){
if [ -d ${OWASP_DIR} ] ; then
rm -rf ${OWASP_DIR}
fi
mkdir -p ${OWASP_DIR}
if [ ${?} -ne 0 ] ; then
echo "Unable to create directory: ${OWASP_DIR}, exit!"
exit 1
fi
}
fst_match_line(){
FIRST_LINE_NUM=$(grep -n -m 1 "${1}" ${2} | awk -F ':' '{print $1}')
}
fst_match_after(){
FIRST_NUM_AFTER=$(tail -n +${1} ${2} | grep -n -m 1 ${3} | awk -F ':' '{print $1}')
}
lst_match_line(){
fst_match_after ${1} ${2} ${3}
LAST_LINE_NUM=$((${FIRST_LINE_NUM}+${FIRST_NUM_AFTER}-1))
}
enable_ols_modsec(){
grep 'module mod_security {' ${OLS_HTTPD_CONF} >/dev/null 2>&1
if [ ${?} -eq 0 ] ; then
echo "Already configured for modsecurity."
else
echo 'Enable modsecurity'
sed -i "s=module cache=module mod_security {\nmodsecurity on\
\nmodsecurity_rules \`\nSecRuleEngine On\n\`\nmodsecurity_rules_file \
${OWASP_DIR}/${RULE_FILE}\n ls_enabled 1\n}\
\n\nmodule cache=" ${OLS_HTTPD_CONF}
fi
}
enable_ls_modsec(){
grep '<enableCensorship>1</enableCensorship>' ${LS_HTTPD_CONF} >/dev/null 2>&1
if [ ${?} -eq 0 ] ; then
echo "LSWS already configured for modsecurity"
else
echo 'Enable modsecurity'
sed -i \
"s=<enableCensorship>0</enableCensorship>=<enableCensorship>1</enableCensorship>=" ${LS_HTTPD_CONF}
sed -i \
"s=</censorshipControl>=</censorshipControl>\n\
<censorshipRuleSet>\n\
<name>ModSec</name>\n\
<enabled>1</enabled>\n\
<ruleSet>include ${OWASP_DIR}/modsec_includes.conf</ruleSet>\n\
</censorshipRuleSet>=" ${LS_HTTPD_CONF}
fi
}
enable_modsec(){
if [ "${LSV}" = 'lsws' ]; then
enable_ls_modsec
elif [ "${LSV}" = 'openlitespeed' ]; then
enable_ols_modsec
fi
}
disable_ols_modesec(){
grep 'module mod_security {' ${OLS_HTTPD_CONF} >/dev/null 2>&1
if [ ${?} -eq 0 ] ; then
echo 'Disable modsecurity'
fst_match_line 'module mod_security' ${OLS_HTTPD_CONF}
lst_match_line ${FIRST_LINE_NUM} ${OLS_HTTPD_CONF} '}'
sed -i "${FIRST_LINE_NUM},${LAST_LINE_NUM}d" ${OLS_HTTPD_CONF}
else
echo 'Already disabled for modsecurity'
fi
}
disable_ls_modesec(){
grep '<enableCensorship>0</enableCensorship>' ${LS_HTTPD_CONF}
if [ ${?} -eq 0 ] ; then
echo 'Already disabled for modsecurity'
else
echo 'Disable modsecurity'
sed -i \
"s=<enableCensorship>1</enableCensorship>=<enableCensorship>0</enableCensorship>=" ${LS_HTTPD_CONF}
fst_match_line 'censorshipRuleSet' ${LS_HTTPD_CONF}
lst_match_line ${FIRST_LINE_NUM} ${LS_HTTPD_CONF} '/censorshipRuleSet'
sed -i "${FIRST_LINE_NUM},${LAST_LINE_NUM}d" ${LS_HTTPD_CONF}
fi
}
disable_modsec(){
check_lsv
if [ "${LSV}" = 'lsws' ]; then
disable_ls_modesec
elif [ "${LSV}" = 'openlitespeed' ]; then
disable_ols_modesec
fi
}
install_unzip(){
if [ ! -f /usr/bin/unzip ]; then
echo 'Install Unzip'
apt update >/dev/null 2>&1
apt-get install unzip -y >/dev/null 2>&1
fi
}
install_owasp(){
cd ${OWASP_DIR}
echo 'Download OWASP rules'
wget -q https://github.com/coreruleset/coreruleset/archive/refs/tags/v${OWASP_V}.zip
unzip -qq v${OWASP_V}.zip
rm -f v${OWASP_V}.zip
mv coreruleset-* owasp-modsecurity-crs
}
configure_owasp(){
echo 'Config OWASP rules.'
cd ${OWASP_DIR}
echo "include modsecurity.conf
include owasp-modsecurity-crs/crs-setup.conf
include owasp-modsecurity-crs/rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf
include owasp-modsecurity-crs/rules/REQUEST-901-INITIALIZATION.conf
include owasp-modsecurity-crs/rules/REQUEST-903.9001-DRUPAL-EXCLUSION-RULES.conf
include owasp-modsecurity-crs/rules/REQUEST-903.9002-WORDPRESS-EXCLUSION-RULES.conf
include owasp-modsecurity-crs/rules/REQUEST-903.9003-NEXTCLOUD-EXCLUSION-RULES.conf
include owasp-modsecurity-crs/rules/REQUEST-903.9004-DOKUWIKI-EXCLUSION-RULES.conf
include owasp-modsecurity-crs/rules/REQUEST-903.9005-CPANEL-EXCLUSION-RULES.conf
include owasp-modsecurity-crs/rules/REQUEST-903.9006-XENFORO-EXCLUSION-RULES.conf
include owasp-modsecurity-crs/rules/REQUEST-905-COMMON-EXCEPTIONS.conf
include owasp-modsecurity-crs/rules/REQUEST-910-IP-REPUTATION.conf
include owasp-modsecurity-crs/rules/REQUEST-911-METHOD-ENFORCEMENT.conf
include owasp-modsecurity-crs/rules/REQUEST-912-DOS-PROTECTION.conf
include owasp-modsecurity-crs/rules/REQUEST-913-SCANNER-DETECTION.conf
include owasp-modsecurity-crs/rules/REQUEST-920-PROTOCOL-ENFORCEMENT.conf
include owasp-modsecurity-crs/rules/REQUEST-921-PROTOCOL-ATTACK.conf
include owasp-modsecurity-crs/rules/REQUEST-930-APPLICATION-ATTACK-LFI.conf
include owasp-modsecurity-crs/rules/REQUEST-931-APPLICATION-ATTACK-RFI.conf
include owasp-modsecurity-crs/rules/REQUEST-932-APPLICATION-ATTACK-RCE.conf
include owasp-modsecurity-crs/rules/REQUEST-933-APPLICATION-ATTACK-PHP.conf
include owasp-modsecurity-crs/rules/REQUEST-934-APPLICATION-ATTACK-NODEJS.conf
include owasp-modsecurity-crs/rules/REQUEST-941-APPLICATION-ATTACK-XSS.conf
include owasp-modsecurity-crs/rules/REQUEST-942-APPLICATION-ATTACK-SQLI.conf
include owasp-modsecurity-crs/rules/REQUEST-943-APPLICATION-ATTACK-SESSION-FIXATION.conf
include owasp-modsecurity-crs/rules/REQUEST-944-APPLICATION-ATTACK-JAVA.conf
include owasp-modsecurity-crs/rules/REQUEST-949-BLOCKING-EVALUATION.conf
include owasp-modsecurity-crs/rules/RESPONSE-950-DATA-LEAKAGES.conf
include owasp-modsecurity-crs/rules/RESPONSE-951-DATA-LEAKAGES-SQL.conf
include owasp-modsecurity-crs/rules/RESPONSE-952-DATA-LEAKAGES-JAVA.conf
include owasp-modsecurity-crs/rules/RESPONSE-953-DATA-LEAKAGES-PHP.conf
include owasp-modsecurity-crs/rules/RESPONSE-954-DATA-LEAKAGES-IIS.conf
include owasp-modsecurity-crs/rules/RESPONSE-959-BLOCKING-EVALUATION.conf
include owasp-modsecurity-crs/rules/RESPONSE-980-CORRELATION.conf
include owasp-modsecurity-crs/rules/RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf">modsec_includes.conf
echo "SecRuleEngine On">modsecurity.conf
cd ${OWASP_DIR}/owasp-modsecurity-crs
if [ -f crs-setup.conf.example ]; then
mv crs-setup.conf.example crs-setup.conf
fi
cd ${OWASP_DIR}/owasp-modsecurity-crs/rules
if [ -f REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf.example ]; then
mv REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf.example REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf
fi
if [ -f RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf.example ]; then
mv RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf.example RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf
fi
}
main_owasp(){
mk_owasp_dir
install_unzip
install_owasp
configure_owasp
check_lsv
enable_modsec
}
check_input ${1}
while [ ! -z "${1}" ]; do
case ${1} in
-[hH] | -help | --help)
help_message
;;
-[eE] | -enable | --enable)
main_owasp
;;
-[dD] | -disable | --disable)
disable_modsec
;;
*)
help_message
;;
esac
shift
done

View File

@ -0,0 +1,84 @@
#!/bin/bash
LSDIR='/usr/local/lsws'
EPACE=' '
echow(){
FLAG=${1}
shift
echo -e "\033[1m${EPACE}${FLAG}\033[0m${@}"
}
help_message(){
echo -e "\033[1mOPTIONS\033[0m"
echow '-S, --serial [YOUR_SERIAL|TRIAL]'
echo "${EPACE}${EPACE}Will apply and register the serial to LSWS."
echow '-H, --help'
echo "${EPACE}${EPACE}Display help and exit."
exit 0
}
check_input(){
if [ -z "${1}" ]; then
help_message
exit 1
fi
}
backup_old(){
if [ -f ${1} ] && [ ! -f ${1}_old ]; then
mv ${1} ${1}_old
fi
}
detect_ols(){
if [ -e ${LSDIR}/bin/openlitespeed ]; then
echo '[X] Detect OpenLiteSpeed, abort!'
exit 1
fi
}
apply_serial(){
detect_ols
check_input ${1}
echo ${1} | grep -i 'trial' >/dev/null
if [ ${?} = 0 ]; then
echo 'Apply Trial License'
if [ ! -e ${LSDIR}/conf/serial.no ] && [ ! -e ${LSDIR}/conf/license.key ]; then
rm -f ${LSDIR}/conf/trial.key*
wget -P ${LSDIR}/conf -q http://license.litespeedtech.com/reseller/trial.key
echo 'Apply trial finished'
else
echo "Please backup and remove your existing license, apply abort!"
exit 1
fi
else
echo "Apply Serial number: ${1}"
backup_old ${LSDIR}/conf/serial.no
backup_old ${LSDIR}/conf/license.key
backup_old ${LSDIR}/conf/trial.key
echo "${1}" > ${LSDIR}/conf/serial.no
${LSDIR}/bin/lshttpd -r
if [ -f ${LSDIR}/conf/license.key ]; then
echo '[O] Apply success'
else
echo '[X] Apply failed, please check!'
exit 1
fi
fi
}
check_input ${1}
while [ ! -z "${1}" ]; do
case ${1} in
-[hH] | -help | --help)
help_message
;;
-[sS] | -serial | --serial) shift
apply_serial "${1}"
;;
*)
help_message
;;
esac
shift
done

View File

@ -0,0 +1,158 @@
#!/usr/bin/env bash
source .env
DOMAIN=''
SQL_DB=''
SQL_USER=''
SQL_PASS=''
ANY="'%'"
SET_OK=0
EPACE=' '
echow(){
FLAG=${1}
shift
echo -e "\033[1m${EPACE}${FLAG}\033[0m${@}"
}
help_message(){
echo -e "\033[1mOPTIONS\033[0m"
echow '-D, --domain [DOMAIN_NAME]'
echo "${EPACE}${EPACE}Example: database.sh -D example.com"
echo "${EPACE}${EPACE}Will auto generate Database/username/password for the domain"
echow '-D, --domain [DOMAIN_NAME] -U, --user [xxx] -P, --password [xxx] -DB, --database [xxx]'
echo "${EPACE}${EPACE}Example: database.sh -D example.com -U USERNAME -P PASSWORD -DB DATABASENAME"
echo "${EPACE}${EPACE}Will create Database/username/password by given"
echow '-H, --help'
echo "${EPACE}${EPACE}Display help and exit."
exit 0
}
check_input(){
if [ -z "${1}" ]; then
help_message
exit 1
fi
}
specify_name(){
check_input ${SQL_USER}
check_input ${SQL_PASS}
check_input ${SQL_DB}
}
auto_name(){
SQL_DB="${TRANSNAME}"
SQL_USER="${TRANSNAME}"
SQL_PASS="'${RANDOM_PASS}'"
}
gen_pass(){
RANDOM_PASS="$(openssl rand -base64 12)"
}
trans_name(){
TRANSNAME=$(echo ${1} | tr -d '.&&-')
}
display_credential(){
if [ ${SET_OK} = 0 ]; then
echo "Database: ${SQL_DB}"
echo "Username: ${SQL_USER}"
echo "Password: $(echo ${SQL_PASS} | tr -d "'")"
fi
}
store_credential(){
if [ -d "./sites/${1}" ]; then
if [ -f ./sites/${1}/.db_pass ]; then
mv ./sites/${1}/.db_pass ./sites/${1}/.db_pass.bk
fi
cat > "./sites/${1}/.db_pass" << EOT
"Database":"${SQL_DB}"
"Username":"${SQL_USER}"
"Password":"$(echo ${SQL_PASS} | tr -d "'")"
EOT
else
echo "./sites/${1} not found, abort credential store!"
fi
}
check_db_access(){
docker compose exec -T mysql su -c "mysql -uroot -p${MYSQL_ROOT_PASSWORD} -e 'status'" >/dev/null 2>&1
if [ ${?} != 0 ]; then
echo '[X] DB access failed, please check!'
exit 1
fi
}
check_db_exist(){
docker compose exec -T mysql su -c "test -e /var/lib/mysql/${1}"
if [ ${?} = 0 ]; then
echo "Database ${1} already exist, skip DB creation!"
exit 0
fi
}
db_setup(){
docker compose exec -T mysql su -c 'mysql -uroot -p${MYSQL_ROOT_PASSWORD} \
-e "CREATE DATABASE '${SQL_DB}';" \
-e "GRANT ALL PRIVILEGES ON '${SQL_DB}'.* TO '${SQL_USER}'@'${ANY}' IDENTIFIED BY '${SQL_PASS}';" \
-e "FLUSH PRIVILEGES;"'
SET_OK=${?}
}
auto_setup_main(){
check_input ${DOMAIN}
gen_pass
trans_name ${DOMAIN}
auto_name
check_db_exist ${SQL_DB}
check_db_access
db_setup
display_credential
store_credential ${DOMAIN}
}
specify_setup_main(){
specify_name
check_db_exist ${SQL_DB}
check_db_access
db_setup
display_credential
store_credential ${DOMAIN}
}
main(){
if [ "${SQL_USER}" != '' ] && [ "${SQL_PASS}" != '' ] && [ "${SQL_DB}" != '' ]; then
specify_setup_main
else
auto_setup_main
fi
}
check_input ${1}
while [ ! -z "${1}" ]; do
case ${1} in
-[hH] | -help | --help)
help_message
;;
-[dD] | -domain| --domain) shift
DOMAIN="${1}"
;;
-[uU] | -user | --user) shift
SQL_USER="${1}"
;;
-[pP] | -password| --password) shift
SQL_PASS="'${1}'"
;;
-db | -DB | -database| --database) shift
SQL_DB="${1}"
;;
*)
help_message
;;
esac
shift
done
main

View File

@ -0,0 +1,102 @@
#!/usr/bin/env bash
source .env
APP_NAME='wordpress'
CONT_NAME='litespeed'
DOC_FD=''
echow(){
FLAG=${1}
shift
echo -e "\033[1m${EPACE}${FLAG}\033[0m${@}"
}
help_message(){
case ${1} in
"1")
echow "Script will get 'DOMAIN' and 'database' info from .env file, then auto setup virtual host and the wordpress site for you."
exit 0
;;
"2")
echow 'Service finished, enjoy your accelarated LiteSpeed server!'
;;
esac
}
domain_filter(){
if [ ! -n "${DOMAIN}" ]; then
echo "Parameters not supplied, please check!"
exit 1
fi
DOMAIN="${1}"
DOMAIN="${DOMAIN#http://}"
DOMAIN="${DOMAIN#https://}"
DOMAIN="${DOMAIN#ftp://}"
DOMAIN="${DOMAIN#scp://}"
DOMAIN="${DOMAIN#scp://}"
DOMAIN="${DOMAIN#sftp://}"
DOMAIN=${DOMAIN%%/*}
}
gen_root_fd(){
DOC_FD="./sites/${1}/"
if [ -d "./sites/${1}" ]; then
echo -e "[O] The root folder \033[32m${DOC_FD}\033[0m exist."
else
echo "Creating - document root."
bash bin/domain.sh -add ${1}
echo "Finished - document root."
fi
}
create_db(){
if [ ! -n "${MYSQL_DATABASE}" ] || [ ! -n "${MYSQL_USER}" ] || [ ! -n "${MYSQL_PASSWORD}" ]; then
echo "Parameters not supplied, please check!"
exit 1
else
bash bin/database.sh -D ${1} -U ${MYSQL_USER} -P ${MYSQL_PASSWORD} -DB ${MYSQL_DATABASE}
fi
}
store_credential(){
if [ -f ${DOC_FD}/.db_pass ]; then
echo '[O] db file exist!'
else
echo 'Storing database parameter'
cat > "${DOC_FD}/.db_pass" << EOT
"Database":"${MYSQL_DATABASE}"
"Username":"${MYSQL_USER}"
"Password":"$(echo ${MYSQL_PASSWORD} | tr -d "'")"
EOT
fi
}
app_download(){
docker compose exec -T ${CONT_NAME} su -c "appinstallctl.sh --app ${1} --domain ${2}"
}
lsws_restart(){
bash bin/webadmin.sh -r
}
main(){
domain_filter ${DOMAIN}
gen_root_fd ${DOMAIN}
create_db ${DOMAIN}
store_credential
app_download ${APP_NAME} ${DOMAIN}
lsws_restart
help_message 2
}
while [ ! -z "${1}" ]; do
case ${1} in
-[hH] | -help | --help)
help_message 1
;;
*)
help_message 1
;;
esac
shift
done
main

View File

@ -0,0 +1,2 @@
#!/usr/bin/env bash
git ls-files -v|grep '^S'

View File

@ -0,0 +1,2 @@
#!/usr/bin/env bash
find conf -maxdepth 1 -type d \( ! -name . \) -exec bash -c "cd '{}' && pwd && git ls-files -z ${pwd} | xargs -0 git update-index --no-skip-worktree" \;

View File

@ -0,0 +1,3 @@
#!/usr/bin/env bash
find conf -maxdepth 1 -type d \( ! -name . \) -exec bash -c "cd '{}' && pwd && git ls-files -z ${pwd} | xargs -0 git update-index --skip-worktree" \;

View File

@ -0,0 +1,61 @@
#!/usr/bin/env bash
CONT_NAME='litespeed'
EPACE=' '
echow(){
FLAG=${1}
shift
echo -e "\033[1m${EPACE}${FLAG}\033[0m${@}"
}
help_message(){
echo -e "\033[1mOPTIONS\033[0m"
echow "-A, --add [domain_name]"
echo "${EPACE}${EPACE}Example: domain.sh -A example.com, will add the domain to Listener and auto create a new virtual host."
echow "-D, --del [domain_name]"
echo "${EPACE}${EPACE}Example: domain.sh -D example.com, will delete the domain from Listener."
echow '-H, --help'
echo "${EPACE}${EPACE}Display help and exit."
}
check_input(){
if [ -z "${1}" ]; then
help_message
exit 1
fi
}
add_domain(){
check_input ${1}
docker compose exec ${CONT_NAME} su -s /bin/bash lsadm -c "cd /usr/local/lsws/conf && domainctl.sh --add ${1}"
if [ ! -d "./sites/${1}" ]; then
mkdir -p ./sites/${1}/{html,logs,certs}
fi
bash bin/webadmin.sh -r
}
del_domain(){
check_input ${1}
docker compose exec ${CONT_NAME} su -s /bin/bash lsadm -c "cd /usr/local/lsws/conf && domainctl.sh --del ${1}"
bash bin/webadmin.sh -r
}
check_input ${1}
while [ ! -z "${1}" ]; do
case ${1} in
-[hH] | -help | --help)
help_message
;;
-[aA] | -add | --add) shift
add_domain ${1}
;;
-[dD] | -del | --del | --delete) shift
del_domain ${1}
;;
*)
help_message
;;
esac
shift
done

View File

@ -0,0 +1,98 @@
#!/usr/bin/env bash
CONT_NAME='litespeed'
EPACE=' '
echow(){
FLAG=${1}
shift
echo -e "\033[1m${EPACE}${FLAG}\033[0m${@}"
}
help_message(){
echo -e "\033[1mOPTIONS\033[0m"
echow '[Enter Your PASSWORD]'
echo "${EPACE}${EPACE}Example: webadmin.sh MY_SECURE_PASS, to update web admin password immediatly."
echow '-R, --restart'
echo "${EPACE}${EPACE}Will gracefully restart LiteSpeed Web Server."
echow '-M, --mod-secure [enable|disable]'
echo "${EPACE}${EPACE}Example: webadmin.sh -M enable, will enable and apply Mod_Secure OWASP rules on server"
echow '-U, --upgrade'
echo "${EPACE}${EPACE}Will upgrade web server to latest stable version"
echow '-S, --serial [YOUR_SERIAL|TRIAL]'
echo "${EPACE}${EPACE}Will apply your serial number to LiteSpeed Web Server."
echow '-H, --help'
echo "${EPACE}${EPACE}Display help and exit."
exit 0
}
check_input(){
if [ -z "${1}" ]; then
help_message
exit 1
fi
}
lsws_restart(){
docker compose exec -T ${CONT_NAME} su -c '/usr/local/lsws/bin/lswsctrl restart >/dev/null'
}
apply_serial(){
docker compose exec ${CONT_NAME} su -c "serialctl.sh --serial ${1}"
lsws_restart
}
mod_secure(){
if [ "${1}" = 'enable' ] || [ "${1}" = 'Enable' ]; then
docker compose exec ${CONT_NAME} su -s /bin/bash root -c "owaspctl.sh --enable"
lsws_restart
elif [ "${1}" = 'disable' ] || [ "${1}" = 'Disable' ]; then
docker compose exec ${CONT_NAME} su -s /bin/bash root -c "owaspctl.sh --disable"
lsws_restart
else
help_message
fi
}
ls_upgrade(){
echo 'Upgrade web server to latest stable version.'
docker compose exec ${CONT_NAME} su -c '/usr/local/lsws/admin/misc/lsup.sh 2>/dev/null'
}
set_web_admin(){
echo 'Update web admin password.'
local LSADPATH='/usr/local/lsws/admin'
docker compose exec ${CONT_NAME} su -s /bin/bash lsadm -c \
'if [ -e /usr/local/lsws/admin/fcgi-bin/admin_php ]; then \
echo "admin:$('${LSADPATH}'/fcgi-bin/admin_php -q '${LSADPATH}'/misc/htpasswd.php '${1}')" > '${LSADPATH}'/conf/htpasswd; \
else echo "admin:$('${LSADPATH}'/fcgi-bin/admin_php5 -q '${LSADPATH}'/misc/htpasswd.php '${1}')" > '${LSADPATH}'/conf/htpasswd; \
fi';
}
main(){
set_web_admin ${1}
}
check_input ${1}
while [ ! -z "${1}" ]; do
case ${1} in
-[hH] | -help | --help)
help_message
;;
-[rR] | -restart | --restart)
lsws_restart
;;
-M | -mode-secure | --mod-secure) shift
mod_secure ${1}
;;
-lsup | --lsup | --upgrade | -U) shift
ls_upgrade
;;
-[sS] | -serial | --serial) shift
apply_serial ${1}
;;
*)
main ${1}
;;
esac
shift
done

View File

@ -0,0 +1,2 @@
*
!.gitignore

View File

@ -0,0 +1,30 @@
version: '3'
services:
litespeed:
container_name: ${CONTAINER_NAME}
restart: always
networks:
- 1panel-network
logging:
driver: none
volumes:
- ${DATA_PATH}/lsws/conf:/usr/local/lsws/conf
- ${DATA_PATH}/lsws/admin-conf:/usr/local/lsws/admin/conf
- ${DATA_PATH}/bin/container:/usr/local/bin
- ${DATA_PATH}/sites:/var/www/vhosts/
- ${DATA_PATH}/acme:/root/.acme.sh/
- ${DATA_PATH}/logs:/usr/local/lsws/logs/
ports:
- "${PANEL_APP_PORT_HTTP}:80"
- "${PANEL_APP_PORT_HTTPS}:443"
- "${PANEL_APP_PORT_HTTPS}:443/udp"
- "${PANEL_APP_PORT_CONSOLE}:7080"
environment:
- TZ=${TIME_ZONE}
image: litespeedtech/openlitespeed:1.7.17-lsphp74
labels:
createdBy: "Apps"
networks:
1panel-network:
external: true

View File

@ -0,0 +1,6 @@
CONTAINER_NAME="openlitespeed"
DATA_PATH="./data"
PANEL_APP_PORT_CONSOLE="40113"
PANEL_APP_PORT_HTTP="80"
PANEL_APP_PORT_HTTPS="443"
TIME_ZONE="Asia/Shanghai"

View File

@ -0,0 +1,40 @@
additionalProperties:
formFields:
- default: 80
edit: true
envKey: PANEL_APP_PORT_HTTP
labelEn: HTTP Port
labelZh: HTTP端口
required: true
rule: paramPort
type: number
- default: 443
edit: true
envKey: PANEL_APP_PORT_HTTPS
labelEn: HTTPS Port
labelZh: HTTPS端口
required: true
rule: paramPort
type: number
- default: 40113
edit: true
envKey: PANEL_APP_PORT_CONSOLE
labelEn: Console Port
labelZh: 控制台端口
required: true
rule: paramPort
type: number
- default: ./data
disabled: true
envKey: DATA_PATH
labelEn: Data folder path
labelZh: 数据文件夹路径
required: true
type: text
- default: Asia/Shanghai
edit: true
envKey: TIME_ZONE
labelEn: Time zone
labelZh: 时区
required: true
type: text

View File

@ -0,0 +1,293 @@
#!/usr/bin/env bash
EMAIL=''
NO_EMAIL=''
DOMAIN=''
INSTALL=''
UNINSTALL=''
TYPE=0
CONT_NAME='litespeed'
ACME_SRC='https://raw.githubusercontent.com/Neilpang/acme.sh/master/acme.sh'
EPACE=' '
RENEW=''
RENEW_ALL=''
FORCE=''
REVOKE=''
REMOVE=''
echow(){
FLAG=${1}
shift
echo -e "\033[1m${EPACE}${FLAG}\033[0m${@}"
}
help_message(){
case ${1} in
"1")
echo 'You will need to install acme script at the first time.'
echo 'Please run acme.sh --install --email example@example.com'
;;
"2")
echo -e "\033[1mOPTIONS\033[0m"
echow '-D, --domain [DOMAIN_NAME]'
echo "${EPACE}${EPACE}Example: acme.sh --domain example.com"
echo "${EPACE}${EPACE}will auto detect and apply for both example.com and www.example.com domains."
echow '-H, --help'
echo "${EPACE}${EPACE}Display help and exit."
echo -e "\033[1m Only for the First time\033[0m"
echow '--install --email [EMAIL_ADDR]'
echo "${EPACE}${EPACE}Will install ACME with the Email provided"
echow '-r, --renew'
echo "${EPACE}${EPACE}Renew a specific domain with -D or --domain parameter if posibile. To force renew, use -f parameter."
echow '-R, --renew-all'
echo "${EPACE}${EPACE}Renew all domains if possible. To force renew, use -f parameter."
echow '-f, -F, --force'
echo "${EPACE}${EPACE}Force renew for a specific domain or all domains."
echow '-v, --revoke'
echo "${EPACE}${EPACE}Revoke a domain."
echow '-V, --remove'
echo "${EPACE}${EPACE}Remove a domain."
exit 0
;;
"3")
echo 'Please run acme.sh --domain [DOMAIN_NAME] to apply certificate'
exit 0
;;
esac
}
check_input(){
if [ -z "${1}" ]; then
help_message 2
fi
}
domain_filter(){
if [ -z "${1}" ]; then
help_message 3
fi
DOMAIN="${1}"
DOMAIN="${DOMAIN#http://}"
DOMAIN="${DOMAIN#https://}"
DOMAIN="${DOMAIN#ftp://}"
DOMAIN="${DOMAIN#scp://}"
DOMAIN="${DOMAIN#scp://}"
DOMAIN="${DOMAIN#sftp://}"
DOMAIN=${DOMAIN%%/*}
}
email_filter(){
CKREG="^[a-z0-9!#\$%&'*+/=?^_\`{|}~-]+(\.[a-z0-9!#$%&'*+/=?^_\`{|}~-]+)*@([a-z0-9]([a-z0-9-]*[a-z0-9])?\.)+[a-z0-9]([a-z0-9-]*[a-z0-9])?\$"
if [[ "${1}" =~ ${CKREG} ]] ; then
echo -e "[O] The E-mail \033[32m${1}\033[0m is valid."
else
echo -e "[X] The E-mail \e[31m${1}\e[39m is invalid"
exit 1
fi
}
cert_hook(){
echo '[Start] Adding ACME hook'
docker compose exec ${CONT_NAME} su -s /bin/bash -c "certhookctl.sh"
echo '[End] Adding ACME hook'
}
www_domain(){
CHECK_WWW=$(echo ${1} | cut -c1-4)
if [[ ${CHECK_WWW} == www. ]] ; then
DOMAIN=$(echo ${1} | cut -c 5-)
else
DOMAIN=${1}
fi
WWW_DOMAIN="www.${DOMAIN}"
}
domain_verify(){
curl -Is http://${DOMAIN}/ | grep -i LiteSpeed > /dev/null 2>&1
if [ ${?} = 0 ]; then
echo -e "[O] The domain name \033[32m${DOMAIN}\033[0m is accessible."
TYPE=1
curl -Is http://${WWW_DOMAIN}/ | grep -i LiteSpeed > /dev/null 2>&1
if [ ${?} = 0 ]; then
echo -e "[O] The domain name \033[32m${WWW_DOMAIN}\033[0m is accessible."
TYPE=2
else
echo -e "[!] The domain name ${WWW_DOMAIN} is inaccessible."
fi
else
echo -e "[X] The domain name \e[31m${DOMAIN}\e[39m is inaccessible, please verify."
exit 1
fi
}
install_acme(){
echo '[Start] Install ACME'
if [ "${1}" = 'true' ]; then
docker compose exec litespeed su -c "cd; wget ${ACME_SRC}; chmod 755 acme.sh; \
./acme.sh --install --cert-home ~/.acme.sh/certs; \
rm ~/acme.sh"
elif [ "${2}" != '' ]; then
email_filter "${2}"
docker compose exec litespeed su -c "cd; wget ${ACME_SRC}; chmod 755 acme.sh; \
./acme.sh --install --cert-home ~/.acme.sh/certs --accountemail ${2}; \
rm ~/acme.sh"
else
help_message 1
exit 1
fi
echo '[End] Install ACME'
}
uninstall_acme(){
echo '[Start] Uninstall ACME'
docker compose exec ${CONT_NAME} su -c "~/.acme.sh/acme.sh --uninstall"
echo '[End] Uninstall ACME'
exit 0
}
check_acme(){
echo '[Start] Checking ACME'
docker compose exec ${CONT_NAME} su -c "test -f /root/.acme.sh/acme.sh"
if [ ${?} != 0 ]; then
install_acme "${NO_EMAIL}" "${EMAIL}"
cert_hook
help_message 3
fi
echo '[End] Checking ACME'
}
lsws_restart(){
docker compose exec ${CONT_NAME} su -c '/usr/local/lsws/bin/lswsctrl restart >/dev/null'
}
doc_root_verify(){
if [ "${DOC_ROOT}" = '' ]; then
DOC_PATH="/var/www/vhosts/${1}/html"
else
DOC_PATH="${DOC_ROOT}"
fi
docker compose exec ${CONT_NAME} su -c "[ -e ${DOC_PATH} ]"
if [ ${?} -eq 0 ]; then
echo -e "[O] The document root folder \033[32m${DOC_PATH}\033[0m does exist."
else
echo -e "[X] The document root folder \e[31m${DOC_PATH}\e[39m does not exist!"
exit 1
fi
}
install_cert(){
echo '[Start] Apply Lets Encrypt Certificate'
if [ ${TYPE} = 1 ]; then
docker compose exec ${CONT_NAME} su -c "/root/.acme.sh/acme.sh --issue -d ${1} -w ${DOC_PATH}"
elif [ ${TYPE} = 2 ]; then
docker compose exec ${CONT_NAME} su -c "/root/.acme.sh/acme.sh --issue -d ${1} -d www.${1} -w ${DOC_PATH}"
else
echo 'unknown Type!'
exit 2
fi
echo '[End] Apply Lets Encrypt Certificate'
}
renew_acme(){
echo '[Start] Renew ACME'
if [ "${FORCE}" = 'true' ]; then
docker compose exec ${CONT_NAME} su -c "~/.acme.sh/acme.sh --renew --domain ${1} --force"
else
docker compose exec ${CONT_NAME} su -c "~/.acme.sh/acme.sh --renew --domain ${1}"
fi
echo '[End] Renew ACME'
lsws_restart
}
renew_all_acme(){
echo '[Start] Renew all ACME'
if [ "${FORCE}" = 'true' ]; then
docker compose exec ${CONT_NAME} su -c "~/.acme.sh/acme.sh --renew-all --force"
else
docker compose exec ${CONT_NAME} su -c "~/.acme.sh/acme.sh --renew-all"
fi
echo '[End] Renew all ACME'
lsws_restart
}
revoke(){
echo '[Start] Revoke a domain'
docker compose exec ${CONT_NAME} su -c "~/.acme.sh/acme.sh --revoke --domain ${1}"
echo '[End] Revoke a domain'
lsws_restart
}
remove(){
echo '[Start] Remove a domain'
docker compose exec ${CONT_NAME} su -c "~/.acme.sh/acme.sh --remove --domain ${1}"
echo '[End] Remove a domain'
lsws_restart
}
main(){
if [ "${RENEW_ALL}" = 'true' ]; then
renew_all_acme
exit 0
elif [ "${RENEW}" = 'true' ]; then
renew_acme ${DOMAIN}
exit 0
elif [ "${REVOKE}" = 'true' ]; then
revoke ${DOMAIN}
exit 0
elif [ "${REMOVE}" = 'true' ]; then
remove ${DOMAIN}
exit 0
fi
check_acme
domain_filter ${DOMAIN}
www_domain ${DOMAIN}
domain_verify
doc_root_verify ${DOMAIN}
install_cert ${DOMAIN}
lsws_restart
}
check_input ${1}
while [ ! -z "${1}" ]; do
case ${1} in
-[hH] | -help | --help)
help_message 2
;;
-[dD] | -domain | --domain) shift
check_input "${1}"
DOMAIN="${1}"
;;
-[iI] | --install )
INSTALL=true
;;
-[uU] | --uninstall )
UNINSTALL=true
uninstall_acme
;;
-[fF] | --force )
FORCE=true
;;
-[r] | --renew )
RENEW=true
;;
-[R] | --renew-all )
RENEW_ALL=true
;;
-[v] | --revoke )
REVOKE=true
;;
-[V] | --remove )
REMOVE=true
;;
-[eE] | --email ) shift
check_input "${1}"
EMAIL="${1}"
;;
*)
help_message 2
;;
esac
shift
done
main

View File

@ -0,0 +1,60 @@
#!/usr/bin/env bash
APP_NAME=''
DOMAIN=''
EPACE=' '
echow(){
FLAG=${1}
shift
echo -e "\033[1m${EPACE}${FLAG}\033[0m${@}"
}
help_message(){
echo -e "\033[1mOPTIONS\033[0m"
echow '-A, --app [app_name] -D, --domain [DOMAIN_NAME]'
echo "${EPACE}${EPACE}Example: appinstall.sh -A wordpress -D example.com"
echo "${EPACE}${EPACE}Will install WordPress CMS under the example.com domain"
echow '-H, --help'
echo "${EPACE}${EPACE}Display help and exit."
exit 0
}
check_input(){
if [ -z "${1}" ]; then
help_message
exit 1
fi
}
app_download(){
docker compose exec litespeed su -c "appinstallctl.sh --app ${1} --domain ${2}"
bash bin/webadmin.sh -r
exit 0
}
main(){
app_download ${APP_NAME} ${DOMAIN}
}
check_input ${1}
while [ ! -z "${1}" ]; do
case ${1} in
-[hH] | -help | --help)
help_message
;;
-[aA] | -app | --app) shift
check_input "${1}"
APP_NAME="${1}"
;;
-[dD] | -domain | --domain) shift
check_input "${1}"
DOMAIN="${1}"
;;
*)
help_message
;;
esac
shift
done
main

View File

@ -0,0 +1,660 @@
#!/bin/bash
DEFAULT_VH_ROOT='/var/www/vhosts'
VH_DOC_ROOT=''
VHNAME=''
APP_NAME=''
DOMAIN=''
WWW_UID=''
WWW_GID=''
WP_CONST_CONF=''
PUB_IP=$(curl -s http://checkip.amazonaws.com)
DB_HOST='mysql'
PLUGINLIST="litespeed-cache.zip"
THEME='twentytwenty'
EPACE=' '
echow(){
FLAG=${1}
shift
echo -e "\033[1m${EPACE}${FLAG}\033[0m${@}"
}
help_message(){
echo -e "\033[1mOPTIONS\033[0m"
echow '-A, -app [wordpress] -D, --domain [DOMAIN_NAME]'
echo "${EPACE}${EPACE}Example: appinstallctl.sh --app wordpress --domain example.com"
echow '-H, --help'
echo "${EPACE}${EPACE}Display help and exit."
exit 0
}
check_input(){
if [ -z "${1}" ]; then
help_message
exit 1
fi
}
linechange(){
LINENUM=$(grep -n "${1}" ${2} | cut -d: -f 1)
if [ -n "${LINENUM}" ] && [ "${LINENUM}" -eq "${LINENUM}" ] 2>/dev/null; then
sed -i "${LINENUM}d" ${2}
sed -i "${LINENUM}i${3}" ${2}
fi
}
ck_ed(){
if [ ! -f /bin/ed ]; then
echo "Install ed package.."
apt-get install ed -y > /dev/null 2>&1
fi
}
ck_unzip(){
if [ ! -f /usr/bin/unzip ]; then
echo "Install unzip package.."
apt-get install unzip -y > /dev/null 2>&1
fi
}
get_owner(){
WWW_UID=$(stat -c "%u" ${DEFAULT_VH_ROOT})
WWW_GID=$(stat -c "%g" ${DEFAULT_VH_ROOT})
if [ ${WWW_UID} -eq 0 ] || [ ${WWW_GID} -eq 0 ]; then
WWW_UID=1000
WWW_GID=1000
echo "Set owner to ${WWW_UID}"
fi
}
get_db_pass(){
if [ -f ${DEFAULT_VH_ROOT}/${1}/.db_pass ]; then
SQL_DB=$(grep -i Database ${VH_ROOT}/.db_pass | awk -F ':' '{print $2}' | tr -d '"')
SQL_USER=$(grep -i Username ${VH_ROOT}/.db_pass | awk -F ':' '{print $2}' | tr -d '"')
SQL_PASS=$(grep -i Password ${VH_ROOT}/.db_pass | awk -F ':' '{print $2}' | tr -d '"')
else
echo 'db pass file can not locate, skip wp-config pre-config.'
fi
}
set_vh_docroot(){
if [ "${VHNAME}" != '' ]; then
VH_ROOT="${DEFAULT_VH_ROOT}/${VHNAME}"
VH_DOC_ROOT="${DEFAULT_VH_ROOT}/${VHNAME}/html"
WP_CONST_CONF="${VH_DOC_ROOT}/wp-content/plugins/litespeed-cache/data/const.default.ini"
elif [ -d ${DEFAULT_VH_ROOT}/${1}/html ]; then
VH_ROOT="${DEFAULT_VH_ROOT}/${1}"
VH_DOC_ROOT="${DEFAULT_VH_ROOT}/${1}/html"
WP_CONST_CONF="${VH_DOC_ROOT}/wp-content/plugins/litespeed-cache/data/const.default.ini"
else
echo "${DEFAULT_VH_ROOT}/${1}/html does not exist, please add domain first! Abort!"
exit 1
fi
}
check_sql_native(){
local COUNTER=0
local LIMIT_NUM=100
until [ "$(curl -v mysql:3306 2>&1 | grep -i 'native\|Connected')" ]; do
echo "Counter: ${COUNTER}/${LIMIT_NUM}"
COUNTER=$((COUNTER+1))
if [ ${COUNTER} = 10 ]; then
echo '--- MySQL is starting, please wait... ---'
elif [ ${COUNTER} = ${LIMIT_NUM} ]; then
echo '--- MySQL is timeout, exit! ---'
exit 1
fi
sleep 1
done
}
install_wp_plugin(){
for PLUGIN in ${PLUGINLIST}; do
wget -q -P ${VH_DOC_ROOT}/wp-content/plugins/ https://downloads.wordpress.org/plugin/${PLUGIN}
if [ ${?} = 0 ]; then
ck_unzip
unzip -qq -o ${VH_DOC_ROOT}/wp-content/plugins/${PLUGIN} -d ${VH_DOC_ROOT}/wp-content/plugins/
else
echo "${PLUGINLIST} FAILED to download"
fi
done
rm -f ${VH_DOC_ROOT}/wp-content/plugins/*.zip
}
set_htaccess(){
if [ ! -f ${VH_DOC_ROOT}/.htaccess ]; then
touch ${VH_DOC_ROOT}/.htaccess
fi
cat << EOM > ${VH_DOC_ROOT}/.htaccess
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
EOM
}
get_theme_name(){
THEME_NAME=$(grep WP_DEFAULT_THEME ${VH_DOC_ROOT}/wp-includes/default-constants.php | grep -v '!' | awk -F "'" '{print $4}')
echo "${THEME_NAME}" | grep 'twenty' >/dev/null 2>&1
if [ ${?} = 0 ]; then
THEME="${THEME_NAME}"
fi
}
set_lscache(){
cat << EOM > "${WP_CONST_CONF}"
;
; This is the predefined default LSCWP configuration file
;
; All the keys and values please refer \`src/const.cls.php\`
;
; Comments start with \`;\`
;
;; -------------------------------------------------- ;;
;; -------------- General ----------------- ;;
;; -------------------------------------------------- ;;
; O_AUTO_UPGRADE
auto_upgrade = false
; O_API_KEY
api_key = ''
; O_SERVER_IP
server_ip = ''
; O_NEWS
news = false
;; -------------------------------------------------- ;;
;; -------------- Cache ----------------- ;;
;; -------------------------------------------------- ;;
cache-priv = true
cache-commenter = true
cache-rest = true
cache-page_login = true
cache-favicon = true
cache-resources = true
cache-browser = false
cache-mobile = false
cache-mobile_rules = 'Mobile
Android
Silk/
Kindle
BlackBerry
Opera Mini
Opera Mobi'
cache-exc_useragents = ''
cache-exc_cookies = ''
cache-exc_qs = ''
cache-exc_cat = ''
cache-exc_tag = ''
cache-force_uri = ''
cache-force_pub_uri = ''
cache-priv_uri = ''
cache-exc = ''
cache-exc_roles = ''
cache-drop_qs = 'fbclid
gclid
utm*
_ga'
cache-ttl_pub = 604800
cache-ttl_priv = 1800
cache-ttl_frontpage = 604800
cache-ttl_feed = 604800
; O_CACHE_TTL_REST
cache-ttl_rest = 604800
cache-ttl_browser = 31557600
cache-login_cookie = ''
cache-vary_group = ''
cache-ttl_status = '403 3600
404 3600
500 3600'
;; -------------------------------------------------- ;;
;; -------------- Purge ----------------- ;;
;; -------------------------------------------------- ;;
; O_PURGE_ON_UPGRADE
purge-upgrade = true
; O_PURGE_STALE
purge-stale = true
purge-post_all = false
purge-post_f = true
purge-post_h = true
purge-post_p = true
purge-post_pwrp = true
purge-post_a = true
purge-post_y = false
purge-post_m = true
purge-post_d = false
purge-post_t = true
purge-post_pt = true
purge-timed_urls = ''
purge-timed_urls_time = ''
purge-hook_all = 'switch_theme
wp_create_nav_menu
wp_update_nav_menu
wp_delete_nav_menu
create_term
edit_terms
delete_term
add_link
edit_link
delete_link'
;; -------------------------------------------------- ;;
;; -------------- ESI ----------------- ;;
;; -------------------------------------------------- ;;
; O_ESI
esi = false
; O_ESI_CACHE_ADMBAR
esi-cache_admbar = true
; O_ESI_CACHE_COMMFORM
esi-cache_commform = true
; O_ESI_NONCE
esi-nonce = 'stats_nonce
subscribe_nonce'
;; -------------------------------------------------- ;;
;; -------------- Utilities ----------------- ;;
;; -------------------------------------------------- ;;
util-heartbeat = true
util-instant_click = false
util-check_advcache = true
util-no_https_vary = false
;; -------------------------------------------------- ;;
;; -------------- Debug ----------------- ;;
;; -------------------------------------------------- ;;
; O_DEBUG_DISABLE_ALL
debug-disable_all = false
; O_DEBUG
debug = false
; O_DEBUG_IPS
debug-ips = '127.0.0.1'
; O_DEBUG_LEVEL
debug-level = false
; O_DEBUG_FILESIZE
debug-filesize = 3
; O_DEBUG_COOKIE
debug-cookie = false
; O_DEBUG_COLLAPS_QS
debug-collaps_qs = false
; O_DEBUG_INC
debug-inc = ''
; O_DEBUG_EXC
debug-exc = ''
;; -------------------------------------------------- ;;
;; -------------- DB Optm ----------------- ;;
;; -------------------------------------------------- ;;
; O_DB_OPTM_REVISIONS_MAX
db_optm-revisions_max = 0
; O_DB_OPTM_REVISIONS_AGE
db_optm-revisions_age = 0
;; -------------------------------------------------- ;;
;; -------------- HTML Optm ----------------- ;;
;; -------------------------------------------------- ;;
; O_OPTM_CSS_MIN
optm-css_min = false
optm-css_inline_min = false
; O_OPTM_CSS_COMB
optm-css_comb = false
optm-css_comb_priority = false
; O_OPTM_CSS_HTTP2
optm-css_http2 = false
optm-css_exc = ''
; O_OPTM_JS_MIN
optm-js_min = false
optm-js_inline_min = false
; O_OPTM_JS_COMB
optm-js_comb = false
optm-js_comb_priority = false
; O_OPTM_JS_HTTP2
optm-js_http2 = false
; O_OPTM_EXC_JQ
optm-js_exc = ''
optm-ttl = 604800
optm-html_min = false
optm-qs_rm = false
optm-ggfonts_rm = false
; O_OPTM_CSS_ASYNC
optm-css_async = false
; O_OPTM_CCSS_GEN
optm-ccss_gen = true
; O_OPTM_CCSS_ASYNC
optm-ccss_async = true
; O_OPTM_CSS_ASYNC_INLINE
optm-css_async_inline = true
; O_OPTM_CSS_FONT_DISPLAY
optm-css_font_display = false
; O_OPTM_JS_DEFER
optm-js_defer = false
; O_OPTM_JS_INLINE_DEFER
optm-js_inline_defer = false
optm-emoji_rm = false
optm-exc_jq = true
optm-ggfonts_async = false
optm-max_size = 2
optm-rm_comment = false
optm-exc_roles = ''
optm-ccss_con = ''
optm-js_defer_exc = ''
; O_OPTM_DNS_PREFETCH
optm-dns_prefetch = ''
; O_OPTM_DNS_PREFETCH_CTRL
optm-dns_prefetch_ctrl = false
optm-exc = ''
; O_OPTM_CCSS_SEP_POSTTYPE
optm-ccss_sep_posttype = ''
; O_OPTM_CCSS_SEP_URI
optm-ccss_sep_uri = ''
;; -------------------------------------------------- ;;
;; -------------- Object Cache ----------------- ;;
;; -------------------------------------------------- ;;
object = true
object-kind = false
;object-host = 'localhost'
object-host = '/var/www/memcached.sock'
;object-port = 11211
cache_object_port = ''
object-life = 360
object-persistent = true
object-admin = true
object-transients = true
object-db_id = 0
object-user = ''
object-pswd = ''
object-global_groups = 'users
userlogins
usermeta
user_meta
site-transient
site-options
site-lookup
blog-lookup
blog-details
rss
global-posts
blog-id-cache'
object-non_persistent_groups = 'comment
counts
plugins
wc_session_id'
;; -------------------------------------------------- ;;
;; -------------- Discussion ----------------- ;;
;; -------------------------------------------------- ;;
; O_DISCUSS_AVATAR_CACHE
discuss-avatar_cache = false
; O_DISCUSS_AVATAR_CRON
discuss-avatar_cron = false
; O_DISCUSS_AVATAR_CACHE_TTL
discuss-avatar_cache_ttl = 604800
;; -------------------------------------------------- ;;
;; -------------- Media ----------------- ;;
;; -------------------------------------------------- ;;
; O_MEDIA_LAZY
media-lazy = false
; O_MEDIA_LAZY_PLACEHOLDER
media-lazy_placeholder = ''
; O_MEDIA_PLACEHOLDER_RESP
media-placeholder_resp = false
; O_MEDIA_PLACEHOLDER_RESP_COLOR
media-placeholder_resp_color = '#cfd4db'
; O_MEDIA_PLACEHOLDER_RESP_GENERATOR
media-placeholder_resp_generator = false
; O_MEDIA_PLACEHOLDER_RESP_SVG
media-placeholder_resp_svg = '<svg xmlns="http://www.w3.org/2000/svg" width="{width}" height="{height}" viewBox="0 0 {width} {height}"><rect width="100%" height="100%" fill="{color}"/></svg>'
; O_MEDIA_PLACEHOLDER_LQIP
media-placeholder_lqip = false
; O_MEDIA_PLACEHOLDER_LQIP_QUAL
media-placeholder_lqip_qual = 4
; O_MEDIA_PLACEHOLDER_RESP_ASYNC
media-placeholder_resp_async = true
; O_MEDIA_IFRAME_LAZY
media-iframe_lazy = false
; O_MEDIA_LAZYJS_INLINE
media-lazyjs_inline = false
; O_MEDIA_LAZY_EXC
media-lazy_exc = ''
; O_MEDIA_LAZY_CLS_EXC
media-lazy_cls_exc = ''
; O_MEDIA_LAZY_PARENT_CLS_EXC
media-lazy_parent_cls_exc = ''
; O_MEDIA_IFRAME_LAZY_CLS_EXC
media-iframe_lazy_cls_exc = ''
; O_MEDIA_IFRAME_LAZY_PARENT_CLS_EXC
media-iframe_lazy_parent_cls_exc = ''
; O_MEDIA_LAZY_URI_EXC
media-lazy_uri_exc = ''
;; -------------------------------------------------- ;;
;; -------------- Image Optm ----------------- ;;
;; -------------------------------------------------- ;;
img_optm-auto = false
img_optm-cron = true
img_optm-ori = true
img_optm-rm_bkup = false
img_optm-webp = false
img_optm-lossless = false
img_optm-exif = false
img_optm-webp_replace = false
img_optm-webp_attr = 'img.src
div.data-thumb
img.data-src
div.data-large_image
img.retina_logo_url
div.data-parallax-image
video.poster'
img_optm-webp_replace_srcset = false
img_optm-jpg_quality = 82
;; -------------------------------------------------- ;;
;; -------------- Crawler ----------------- ;;
;; -------------------------------------------------- ;;
crawler = false
crawler-inc_posts = true
crawler-inc_pages = true
crawler-inc_cats = true
crawler-inc_tags = true
crawler-exc_cpt = ''
crawler-order_links = 'date_desc'
crawler-usleep = 500
crawler-run_duration = 400
crawler-run_interval = 600
crawler-crawl_interval = 302400
crawler-threads = 3
crawler-timeout = 30
crawler-load_limit = 1
; O_CRAWLER_SITEMAP
crawler-sitemap = ''
; O_CRAWLER_DROP_DOMAIN
crawler-drop_domain = true
crawler-roles = ''
crawler-cookies = ''
;; -------------------------------------------------- ;;
;; -------------- Misc ----------------- ;;
;; -------------------------------------------------- ;;
; O_MISC_HTACCESS_FRONT
misc-htaccess_front = ''
; O_MISC_HTACCESS_BACK
misc-htaccess_back = ''
; O_MISC_HEARTBEAT_FRONT
misc-heartbeat_front = false
; O_MISC_HEARTBEAT_FRONT_TTL
misc-heartbeat_front_ttl = 60
; O_MISC_HEARTBEAT_BACK
misc-heartbeat_back = false
; O_MISC_HEARTBEAT_BACK_TTL
misc-heartbeat_back_ttl = 60
; O_MISC_HEARTBEAT_EDITOR
misc-heartbeat_editor = false
; O_MISC_HEARTBEAT_EDITOR_TTL
misc-heartbeat_editor_ttl = 15
;; -------------------------------------------------- ;;
;; -------------- CDN ----------------- ;;
;; -------------------------------------------------- ;;
cdn = false
cdn-ori = ''
cdn-ori_dir = ''
cdn-exc = ''
cdn-remote_jq = false
cdn-quic = false
cdn-quic_email = ''
cdn-quic_key = ''
cdn-cloudflare = false
cdn-cloudflare_email = ''
cdn-cloudflare_key = ''
cdn-cloudflare_name = ''
cdn-cloudflare_zone = ''
; \`cdn-mapping\` needs to be put in the end with a section tag
;; -------------------------------------------------- ;;
;; -------------- CDN 2 ----------------- ;;
;; -------------------------------------------------- ;;
; <------------ CDN Mapping Example BEGIN -------------------->
; Need to keep the section tag \`[cdn-mapping]\` before list.
;
; NOTE 1) Need to set all child options to make all resources to be replaced without missing.
; NOTE 2) \`url[n]\` option must have to enable the row setting of \`n\`.
; NOTE 3) This section needs to be put in the end of this .ini file
;
; To enable the 2nd mapping record by default, please remove the \`;;\` in the related lines.
[cdn-mapping]
url[0] = ''
inc_js[0] = true
inc_css[0] = true
inc_img[0] = true
filetype[0] = '.aac
.css
.eot
.gif
.jpeg
.js
.jpg
.less
.mp3
.mp4
.ogg
.otf
.pdf
.png
.svg
.ttf
.woff'
;;url[1] = 'https://2nd_CDN_url.com/'
;;filetype[1] = '.webm'
; <------------ CDN Mapping Example END ------------------>
EOM
THEME_PATH="${VH_DOC_ROOT}/wp-content/themes/${THEME}"
if [ ! -f ${THEME_PATH}/functions.php ]; then
cat >> "${THEME_PATH}/functions.php" <<END
<?php
require_once( WP_CONTENT_DIR.'/../wp-admin/includes/plugin.php' );
\$path = 'litespeed-cache/litespeed-cache.php' ;
if (!is_plugin_active( \$path )) {
activate_plugin( \$path ) ;
rename( __FILE__ . '.bk', __FILE__ );
}
END
elif [ ! -f ${THEME_PATH}/functions.php.bk ]; then
cp ${THEME_PATH}/functions.php ${THEME_PATH}/functions.php.bk
ck_ed
ed ${THEME_PATH}/functions.php << END >>/dev/null 2>&1
2i
require_once( WP_CONTENT_DIR.'/../wp-admin/includes/plugin.php' );
\$path = 'litespeed-cache/litespeed-cache.php' ;
if (!is_plugin_active( \$path )) {
activate_plugin( \$path ) ;
rename( __FILE__ . '.bk', __FILE__ );
}
.
w
q
END
fi
}
preinstall_wordpress(){
if [ "${VHNAME}" != '' ]; then
get_db_pass ${VHNAME}
else
get_db_pass ${DOMAIN}
fi
if [ ! -f ${VH_DOC_ROOT}/wp-config.php ] && [ -f ${VH_DOC_ROOT}/wp-config-sample.php ]; then
cp ${VH_DOC_ROOT}/wp-config-sample.php ${VH_DOC_ROOT}/wp-config.php
NEWDBPWD="define('DB_PASSWORD', '${SQL_PASS}');"
linechange 'DB_PASSWORD' ${VH_DOC_ROOT}/wp-config.php "${NEWDBPWD}"
NEWDBPWD="define('DB_USER', '${SQL_USER}');"
linechange 'DB_USER' ${VH_DOC_ROOT}/wp-config.php "${NEWDBPWD}"
NEWDBPWD="define('DB_NAME', '${SQL_DB}');"
linechange 'DB_NAME' ${VH_DOC_ROOT}/wp-config.php "${NEWDBPWD}"
#NEWDBPWD="define('DB_HOST', '${PUB_IP}');"
NEWDBPWD="define('DB_HOST', '${DB_HOST}');"
linechange 'DB_HOST' ${VH_DOC_ROOT}/wp-config.php "${NEWDBPWD}"
elif [ -f ${VH_DOC_ROOT}/wp-config.php ]; then
echo "${VH_DOC_ROOT}/wp-config.php already exist, exit !"
exit 1
else
echo 'Skip!'
exit 2
fi
}
app_wordpress_dl(){
if [ ! -f "${VH_DOC_ROOT}/wp-config.php" ] && [ ! -f "${VH_DOC_ROOT}/wp-config-sample.php" ]; then
wp core download \
--allow-root \
--quiet
else
echo 'wordpress already exist, abort!'
exit 1
fi
}
change_owner(){
if [ "${VHNAME}" != '' ]; then
chown -R ${WWW_UID}:${WWW_GID} ${DEFAULT_VH_ROOT}/${VHNAME}
else
chown -R ${WWW_UID}:${WWW_GID} ${DEFAULT_VH_ROOT}/${DOMAIN}
fi
}
main(){
set_vh_docroot ${DOMAIN}
get_owner
cd ${VH_DOC_ROOT}
if [ "${APP_NAME}" = 'wordpress' ] || [ "${APP_NAME}" = 'wp' ]; then
check_sql_native
app_wordpress_dl
preinstall_wordpress
install_wp_plugin
set_htaccess
get_theme_name
set_lscache
change_owner
exit 0
else
echo "APP: ${APP_NAME} not support, exit!"
exit 1
fi
}
check_input ${1}
while [ ! -z "${1}" ]; do
case ${1} in
-[hH] | -help | --help)
help_message
;;
-[aA] | -app | --app) shift
check_input "${1}"
APP_NAME="${1}"
;;
-[dD] | -domain | --domain) shift
check_input "${1}"
DOMAIN="${1}"
;;
-vhname | --vhname) shift
VHNAME="${1}"
;;
*)
help_message
;;
esac
shift
done
main

View File

@ -0,0 +1,18 @@
#!/bin/bash
BOTCRON='/var/spool/cron/crontabs/root'
cert_hook(){
grep 'acme' ${BOTCRON} >/dev/null
if [ ${?} = 0 ]; then
grep 'lswsctrl' ${BOTCRON} >/dev/null
if [ ${?} = 0 ]; then
echo 'Hook already exist, skip!'
else
sed -i 's/--cron/--cron --renew-hook "\/usr\/local\/lsws\/bin\/lswsctrl restart"/g' ${BOTCRON}
fi
else
echo "[X] ${BOTCRON} does not exist, please check it later!"
fi
}
cert_hook

View File

@ -0,0 +1,160 @@
#!/usr/bin/env bash
CK_RESULT=''
LSDIR='/usr/local/lsws'
LS_HTTPD_CONF="${LSDIR}/conf/httpd_config.xml"
OLS_HTTPD_CONF="${LSDIR}/conf/httpd_config.conf"
EPACE=' '
echow(){
FLAG=${1}
shift
echo -e "\033[1m${EPACE}${FLAG}\033[0m${@}"
}
help_message(){
echo -e "\033[1mOPTIONS\033[0m"
echow '-A, --add [DOMAIN_NAME]'
echo "${EPACE}${EPACE}Will add domain to listener and creat a virtual host from template"
echow '-D, --del [DOMAIN_NAME]'
echo "${EPACE}${EPACE}Will delete domain from listener"
echow '-H, --help'
echo "${EPACE}${EPACE}Display help."
}
check_lsv(){
if [ -f ${LSDIR}/bin/openlitespeed ]; then
LSV='openlitespeed'
elif [ -f ${LSDIR}/bin/litespeed ]; then
LSV='lsws'
else
echo 'Version not exist, abort!'
exit 1
fi
}
dot_escape(){
ESCAPE=$(echo ${1} | sed 's/\./\\./g')
}
check_duplicate(){
CK_RESULT=$(grep -E "${1}" ${2})
}
fst_match_line(){
FIRST_LINE_NUM=$(grep -n -m 1 ${1} ${2} | awk -F ':' '{print $1}')
}
fst_match_after(){
FIRST_NUM_AFTER=$(tail -n +${1} ${2} | grep -n -m 1 ${3} | awk -F ':' '{print $1}')
}
lst_match_line(){
fst_match_after ${1} ${2} ${3}
LAST_LINE_NUM=$((${FIRST_LINE_NUM}+${FIRST_NUM_AFTER}-1))
}
check_input(){
if [ -z "${1}" ]; then
help_message
exit 1
fi
}
check_www(){
CHECK_WWW=$(echo ${1} | cut -c1-4)
if [[ ${CHECK_WWW} == www. ]] ; then
echo 'www domain shoudnt be passed!'
exit 1
fi
}
www_domain(){
check_www ${1}
WWW_DOMAIN=$(echo www.${1})
}
add_ls_domain(){
fst_match_line 'docker.xml</templateFile>' ${LS_HTTPD_CONF}
NEWNUM=$((FIRST_LINE_NUM+2))
sed -i "${NEWNUM}i \ \ \ \ \ \ <member>\n \ \ \ \ \ \ \ <vhName>${DOMAIN}</vhName>\n \ \ \ \ \ \ \ <vhDomain>${DOMAIN},${WWW_DOMAIN}</vhDomain>\n \ \ \ \ \ \ </member>" ${LS_HTTPD_CONF}
}
add_ols_domain(){
perl -0777 -p -i -e 's/(vhTemplate docker \{[^}]+)\}*(^.*listeners.*$)/\1$2
member '${DOMAIN}' {
vhDomain '${DOMAIN},${WWW_DOMAIN}'
}/gmi' ${OLS_HTTPD_CONF}
}
add_domain(){
check_lsv
dot_escape ${1}
DOMAIN=${ESCAPE}
www_domain ${1}
if [ "${LSV}" = 'lsws' ]; then
check_duplicate "vhDomain.*${DOMAIN}" ${LS_HTTPD_CONF}
if [ "${CK_RESULT}" != '' ]; then
echo "# It appears the domain already exist! Check the ${LS_HTTPD_CONF} if you believe this is a mistake!"
exit 1
fi
elif [ "${LSV}" = 'openlitespeed' ]; then
check_duplicate "member.*${DOMAIN}" ${OLS_HTTPD_CONF}
if [ "${CK_RESULT}" != '' ]; then
echo "# It appears the domain already exist! Check the ${OLS_HTTPD_CONF} if you believe this is a mistake!"
exit 1
fi
fi
add_ls_domain
add_ols_domain
}
del_ls_domain(){
fst_match_line "<vhName>*${1}" ${LS_HTTPD_CONF}
FIRST_LINE_NUM=$((FIRST_LINE_NUM-1))
lst_match_line ${FIRST_LINE_NUM} ${LS_HTTPD_CONF} '</member>'
sed -i "${FIRST_LINE_NUM},${LAST_LINE_NUM}d" ${LS_HTTPD_CONF}
}
del_ols_domain(){
fst_match_line ${1} ${OLS_HTTPD_CONF}
lst_match_line ${FIRST_LINE_NUM} ${OLS_HTTPD_CONF} '}'
sed -i "${FIRST_LINE_NUM},${LAST_LINE_NUM}d" ${OLS_HTTPD_CONF}
}
del_domain(){
check_lsv
dot_escape ${1}
DOMAIN=${ESCAPE}
if [ "${LSV}" = 'lsws' ]; then
check_duplicate "vhDomain.*${DOMAIN}" ${LS_HTTPD_CONF}
if [ "${CK_RESULT}" = '' ]; then
echo "# Domain non-exist! Check the ${LS_HTTPD_CONF} if you believe this is a mistake!"
exit 1
fi
elif [ "${LSV}" = 'openlitespeed' ]; then
check_duplicate "member.*${DOMAIN}" ${OLS_HTTPD_CONF}
if [ "${CK_RESULT}" = '' ]; then
echo "# Domain non-exist! Check the ${OLS_HTTPD_CONF} if you believe this is a mistake!"
exit 1
fi
fi
del_ls_domain ${1}
del_ols_domain ${1}
}
check_input ${1}
while [ ! -z "${1}" ]; do
case ${1} in
-[hH] | -help | --help)
help_message
;;
-[aA] | -add | --add) shift
add_domain ${1}
;;
-[dD] | -del | --del | --delete) shift
del_domain ${1}
;;
*)
help_message
;;
esac
shift
done

View File

@ -0,0 +1,236 @@
#!/bin/bash
LSDIR='/usr/local/lsws'
OWASP_DIR="${LSDIR}/conf/owasp"
RULE_FILE='modsec_includes.conf'
LS_HTTPD_CONF="${LSDIR}/conf/httpd_config.xml"
OLS_HTTPD_CONF="${LSDIR}/conf/httpd_config.conf"
EPACE=' '
OWASP_V='3.3.4'
echow(){
FLAG=${1}
shift
echo -e "\033[1m${EPACE}${FLAG}\033[0m${@}"
}
help_message(){
echo -e "\033[1mOPTIONS\033[0m"
echow '-E, --enable'
echo "${EPACE}${EPACE}Will Enable mod_secure module with latest OWASP version of rules"
echow '-D, --disable'
echo "${EPACE}${EPACE}Will Disable mod_secure module with latest OWASP version of rules"
echow '-H, --help'
echo "${EPACE}${EPACE}Display help and exit."
exit 0
}
check_lsv(){
if [ -f ${LSDIR}/bin/openlitespeed ]; then
LSV='openlitespeed'
elif [ -f ${LSDIR}/bin/litespeed ]; then
LSV='lsws'
else
echo 'Version not exist, abort!'
exit 1
fi
}
check_input(){
if [ -z "${1}" ]; then
help_message
exit 1
fi
}
mk_owasp_dir(){
if [ -d ${OWASP_DIR} ] ; then
rm -rf ${OWASP_DIR}
fi
mkdir -p ${OWASP_DIR}
if [ ${?} -ne 0 ] ; then
echo "Unable to create directory: ${OWASP_DIR}, exit!"
exit 1
fi
}
fst_match_line(){
FIRST_LINE_NUM=$(grep -n -m 1 "${1}" ${2} | awk -F ':' '{print $1}')
}
fst_match_after(){
FIRST_NUM_AFTER=$(tail -n +${1} ${2} | grep -n -m 1 ${3} | awk -F ':' '{print $1}')
}
lst_match_line(){
fst_match_after ${1} ${2} ${3}
LAST_LINE_NUM=$((${FIRST_LINE_NUM}+${FIRST_NUM_AFTER}-1))
}
enable_ols_modsec(){
grep 'module mod_security {' ${OLS_HTTPD_CONF} >/dev/null 2>&1
if [ ${?} -eq 0 ] ; then
echo "Already configured for modsecurity."
else
echo 'Enable modsecurity'
sed -i "s=module cache=module mod_security {\nmodsecurity on\
\nmodsecurity_rules \`\nSecRuleEngine On\n\`\nmodsecurity_rules_file \
${OWASP_DIR}/${RULE_FILE}\n ls_enabled 1\n}\
\n\nmodule cache=" ${OLS_HTTPD_CONF}
fi
}
enable_ls_modsec(){
grep '<enableCensorship>1</enableCensorship>' ${LS_HTTPD_CONF} >/dev/null 2>&1
if [ ${?} -eq 0 ] ; then
echo "LSWS already configured for modsecurity"
else
echo 'Enable modsecurity'
sed -i \
"s=<enableCensorship>0</enableCensorship>=<enableCensorship>1</enableCensorship>=" ${LS_HTTPD_CONF}
sed -i \
"s=</censorshipControl>=</censorshipControl>\n\
<censorshipRuleSet>\n\
<name>ModSec</name>\n\
<enabled>1</enabled>\n\
<ruleSet>include ${OWASP_DIR}/modsec_includes.conf</ruleSet>\n\
</censorshipRuleSet>=" ${LS_HTTPD_CONF}
fi
}
enable_modsec(){
if [ "${LSV}" = 'lsws' ]; then
enable_ls_modsec
elif [ "${LSV}" = 'openlitespeed' ]; then
enable_ols_modsec
fi
}
disable_ols_modesec(){
grep 'module mod_security {' ${OLS_HTTPD_CONF} >/dev/null 2>&1
if [ ${?} -eq 0 ] ; then
echo 'Disable modsecurity'
fst_match_line 'module mod_security' ${OLS_HTTPD_CONF}
lst_match_line ${FIRST_LINE_NUM} ${OLS_HTTPD_CONF} '}'
sed -i "${FIRST_LINE_NUM},${LAST_LINE_NUM}d" ${OLS_HTTPD_CONF}
else
echo 'Already disabled for modsecurity'
fi
}
disable_ls_modesec(){
grep '<enableCensorship>0</enableCensorship>' ${LS_HTTPD_CONF}
if [ ${?} -eq 0 ] ; then
echo 'Already disabled for modsecurity'
else
echo 'Disable modsecurity'
sed -i \
"s=<enableCensorship>1</enableCensorship>=<enableCensorship>0</enableCensorship>=" ${LS_HTTPD_CONF}
fst_match_line 'censorshipRuleSet' ${LS_HTTPD_CONF}
lst_match_line ${FIRST_LINE_NUM} ${LS_HTTPD_CONF} '/censorshipRuleSet'
sed -i "${FIRST_LINE_NUM},${LAST_LINE_NUM}d" ${LS_HTTPD_CONF}
fi
}
disable_modsec(){
check_lsv
if [ "${LSV}" = 'lsws' ]; then
disable_ls_modesec
elif [ "${LSV}" = 'openlitespeed' ]; then
disable_ols_modesec
fi
}
install_unzip(){
if [ ! -f /usr/bin/unzip ]; then
echo 'Install Unzip'
apt update >/dev/null 2>&1
apt-get install unzip -y >/dev/null 2>&1
fi
}
install_owasp(){
cd ${OWASP_DIR}
echo 'Download OWASP rules'
wget -q https://github.com/coreruleset/coreruleset/archive/refs/tags/v${OWASP_V}.zip
unzip -qq v${OWASP_V}.zip
rm -f v${OWASP_V}.zip
mv coreruleset-* owasp-modsecurity-crs
}
configure_owasp(){
echo 'Config OWASP rules.'
cd ${OWASP_DIR}
echo "include modsecurity.conf
include owasp-modsecurity-crs/crs-setup.conf
include owasp-modsecurity-crs/rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf
include owasp-modsecurity-crs/rules/REQUEST-901-INITIALIZATION.conf
include owasp-modsecurity-crs/rules/REQUEST-903.9001-DRUPAL-EXCLUSION-RULES.conf
include owasp-modsecurity-crs/rules/REQUEST-903.9002-WORDPRESS-EXCLUSION-RULES.conf
include owasp-modsecurity-crs/rules/REQUEST-903.9003-NEXTCLOUD-EXCLUSION-RULES.conf
include owasp-modsecurity-crs/rules/REQUEST-903.9004-DOKUWIKI-EXCLUSION-RULES.conf
include owasp-modsecurity-crs/rules/REQUEST-903.9005-CPANEL-EXCLUSION-RULES.conf
include owasp-modsecurity-crs/rules/REQUEST-903.9006-XENFORO-EXCLUSION-RULES.conf
include owasp-modsecurity-crs/rules/REQUEST-905-COMMON-EXCEPTIONS.conf
include owasp-modsecurity-crs/rules/REQUEST-910-IP-REPUTATION.conf
include owasp-modsecurity-crs/rules/REQUEST-911-METHOD-ENFORCEMENT.conf
include owasp-modsecurity-crs/rules/REQUEST-912-DOS-PROTECTION.conf
include owasp-modsecurity-crs/rules/REQUEST-913-SCANNER-DETECTION.conf
include owasp-modsecurity-crs/rules/REQUEST-920-PROTOCOL-ENFORCEMENT.conf
include owasp-modsecurity-crs/rules/REQUEST-921-PROTOCOL-ATTACK.conf
include owasp-modsecurity-crs/rules/REQUEST-930-APPLICATION-ATTACK-LFI.conf
include owasp-modsecurity-crs/rules/REQUEST-931-APPLICATION-ATTACK-RFI.conf
include owasp-modsecurity-crs/rules/REQUEST-932-APPLICATION-ATTACK-RCE.conf
include owasp-modsecurity-crs/rules/REQUEST-933-APPLICATION-ATTACK-PHP.conf
include owasp-modsecurity-crs/rules/REQUEST-934-APPLICATION-ATTACK-NODEJS.conf
include owasp-modsecurity-crs/rules/REQUEST-941-APPLICATION-ATTACK-XSS.conf
include owasp-modsecurity-crs/rules/REQUEST-942-APPLICATION-ATTACK-SQLI.conf
include owasp-modsecurity-crs/rules/REQUEST-943-APPLICATION-ATTACK-SESSION-FIXATION.conf
include owasp-modsecurity-crs/rules/REQUEST-944-APPLICATION-ATTACK-JAVA.conf
include owasp-modsecurity-crs/rules/REQUEST-949-BLOCKING-EVALUATION.conf
include owasp-modsecurity-crs/rules/RESPONSE-950-DATA-LEAKAGES.conf
include owasp-modsecurity-crs/rules/RESPONSE-951-DATA-LEAKAGES-SQL.conf
include owasp-modsecurity-crs/rules/RESPONSE-952-DATA-LEAKAGES-JAVA.conf
include owasp-modsecurity-crs/rules/RESPONSE-953-DATA-LEAKAGES-PHP.conf
include owasp-modsecurity-crs/rules/RESPONSE-954-DATA-LEAKAGES-IIS.conf
include owasp-modsecurity-crs/rules/RESPONSE-959-BLOCKING-EVALUATION.conf
include owasp-modsecurity-crs/rules/RESPONSE-980-CORRELATION.conf
include owasp-modsecurity-crs/rules/RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf">modsec_includes.conf
echo "SecRuleEngine On">modsecurity.conf
cd ${OWASP_DIR}/owasp-modsecurity-crs
if [ -f crs-setup.conf.example ]; then
mv crs-setup.conf.example crs-setup.conf
fi
cd ${OWASP_DIR}/owasp-modsecurity-crs/rules
if [ -f REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf.example ]; then
mv REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf.example REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf
fi
if [ -f RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf.example ]; then
mv RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf.example RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf
fi
}
main_owasp(){
mk_owasp_dir
install_unzip
install_owasp
configure_owasp
check_lsv
enable_modsec
}
check_input ${1}
while [ ! -z "${1}" ]; do
case ${1} in
-[hH] | -help | --help)
help_message
;;
-[eE] | -enable | --enable)
main_owasp
;;
-[dD] | -disable | --disable)
disable_modsec
;;
*)
help_message
;;
esac
shift
done

View File

@ -0,0 +1,84 @@
#!/bin/bash
LSDIR='/usr/local/lsws'
EPACE=' '
echow(){
FLAG=${1}
shift
echo -e "\033[1m${EPACE}${FLAG}\033[0m${@}"
}
help_message(){
echo -e "\033[1mOPTIONS\033[0m"
echow '-S, --serial [YOUR_SERIAL|TRIAL]'
echo "${EPACE}${EPACE}Will apply and register the serial to LSWS."
echow '-H, --help'
echo "${EPACE}${EPACE}Display help and exit."
exit 0
}
check_input(){
if [ -z "${1}" ]; then
help_message
exit 1
fi
}
backup_old(){
if [ -f ${1} ] && [ ! -f ${1}_old ]; then
mv ${1} ${1}_old
fi
}
detect_ols(){
if [ -e ${LSDIR}/bin/openlitespeed ]; then
echo '[X] Detect OpenLiteSpeed, abort!'
exit 1
fi
}
apply_serial(){
detect_ols
check_input ${1}
echo ${1} | grep -i 'trial' >/dev/null
if [ ${?} = 0 ]; then
echo 'Apply Trial License'
if [ ! -e ${LSDIR}/conf/serial.no ] && [ ! -e ${LSDIR}/conf/license.key ]; then
rm -f ${LSDIR}/conf/trial.key*
wget -P ${LSDIR}/conf -q http://license.litespeedtech.com/reseller/trial.key
echo 'Apply trial finished'
else
echo "Please backup and remove your existing license, apply abort!"
exit 1
fi
else
echo "Apply Serial number: ${1}"
backup_old ${LSDIR}/conf/serial.no
backup_old ${LSDIR}/conf/license.key
backup_old ${LSDIR}/conf/trial.key
echo "${1}" > ${LSDIR}/conf/serial.no
${LSDIR}/bin/lshttpd -r
if [ -f ${LSDIR}/conf/license.key ]; then
echo '[O] Apply success'
else
echo '[X] Apply failed, please check!'
exit 1
fi
fi
}
check_input ${1}
while [ ! -z "${1}" ]; do
case ${1} in
-[hH] | -help | --help)
help_message
;;
-[sS] | -serial | --serial) shift
apply_serial "${1}"
;;
*)
help_message
;;
esac
shift
done

View File

@ -0,0 +1,158 @@
#!/usr/bin/env bash
source .env
DOMAIN=''
SQL_DB=''
SQL_USER=''
SQL_PASS=''
ANY="'%'"
SET_OK=0
EPACE=' '
echow(){
FLAG=${1}
shift
echo -e "\033[1m${EPACE}${FLAG}\033[0m${@}"
}
help_message(){
echo -e "\033[1mOPTIONS\033[0m"
echow '-D, --domain [DOMAIN_NAME]'
echo "${EPACE}${EPACE}Example: database.sh -D example.com"
echo "${EPACE}${EPACE}Will auto generate Database/username/password for the domain"
echow '-D, --domain [DOMAIN_NAME] -U, --user [xxx] -P, --password [xxx] -DB, --database [xxx]'
echo "${EPACE}${EPACE}Example: database.sh -D example.com -U USERNAME -P PASSWORD -DB DATABASENAME"
echo "${EPACE}${EPACE}Will create Database/username/password by given"
echow '-H, --help'
echo "${EPACE}${EPACE}Display help and exit."
exit 0
}
check_input(){
if [ -z "${1}" ]; then
help_message
exit 1
fi
}
specify_name(){
check_input ${SQL_USER}
check_input ${SQL_PASS}
check_input ${SQL_DB}
}
auto_name(){
SQL_DB="${TRANSNAME}"
SQL_USER="${TRANSNAME}"
SQL_PASS="'${RANDOM_PASS}'"
}
gen_pass(){
RANDOM_PASS="$(openssl rand -base64 12)"
}
trans_name(){
TRANSNAME=$(echo ${1} | tr -d '.&&-')
}
display_credential(){
if [ ${SET_OK} = 0 ]; then
echo "Database: ${SQL_DB}"
echo "Username: ${SQL_USER}"
echo "Password: $(echo ${SQL_PASS} | tr -d "'")"
fi
}
store_credential(){
if [ -d "./sites/${1}" ]; then
if [ -f ./sites/${1}/.db_pass ]; then
mv ./sites/${1}/.db_pass ./sites/${1}/.db_pass.bk
fi
cat > "./sites/${1}/.db_pass" << EOT
"Database":"${SQL_DB}"
"Username":"${SQL_USER}"
"Password":"$(echo ${SQL_PASS} | tr -d "'")"
EOT
else
echo "./sites/${1} not found, abort credential store!"
fi
}
check_db_access(){
docker compose exec -T mysql su -c "mysql -uroot -p${MYSQL_ROOT_PASSWORD} -e 'status'" >/dev/null 2>&1
if [ ${?} != 0 ]; then
echo '[X] DB access failed, please check!'
exit 1
fi
}
check_db_exist(){
docker compose exec -T mysql su -c "test -e /var/lib/mysql/${1}"
if [ ${?} = 0 ]; then
echo "Database ${1} already exist, skip DB creation!"
exit 0
fi
}
db_setup(){
docker compose exec -T mysql su -c 'mysql -uroot -p${MYSQL_ROOT_PASSWORD} \
-e "CREATE DATABASE '${SQL_DB}';" \
-e "GRANT ALL PRIVILEGES ON '${SQL_DB}'.* TO '${SQL_USER}'@'${ANY}' IDENTIFIED BY '${SQL_PASS}';" \
-e "FLUSH PRIVILEGES;"'
SET_OK=${?}
}
auto_setup_main(){
check_input ${DOMAIN}
gen_pass
trans_name ${DOMAIN}
auto_name
check_db_exist ${SQL_DB}
check_db_access
db_setup
display_credential
store_credential ${DOMAIN}
}
specify_setup_main(){
specify_name
check_db_exist ${SQL_DB}
check_db_access
db_setup
display_credential
store_credential ${DOMAIN}
}
main(){
if [ "${SQL_USER}" != '' ] && [ "${SQL_PASS}" != '' ] && [ "${SQL_DB}" != '' ]; then
specify_setup_main
else
auto_setup_main
fi
}
check_input ${1}
while [ ! -z "${1}" ]; do
case ${1} in
-[hH] | -help | --help)
help_message
;;
-[dD] | -domain| --domain) shift
DOMAIN="${1}"
;;
-[uU] | -user | --user) shift
SQL_USER="${1}"
;;
-[pP] | -password| --password) shift
SQL_PASS="'${1}'"
;;
-db | -DB | -database| --database) shift
SQL_DB="${1}"
;;
*)
help_message
;;
esac
shift
done
main

View File

@ -0,0 +1,102 @@
#!/usr/bin/env bash
source .env
APP_NAME='wordpress'
CONT_NAME='litespeed'
DOC_FD=''
echow(){
FLAG=${1}
shift
echo -e "\033[1m${EPACE}${FLAG}\033[0m${@}"
}
help_message(){
case ${1} in
"1")
echow "Script will get 'DOMAIN' and 'database' info from .env file, then auto setup virtual host and the wordpress site for you."
exit 0
;;
"2")
echow 'Service finished, enjoy your accelarated LiteSpeed server!'
;;
esac
}
domain_filter(){
if [ ! -n "${DOMAIN}" ]; then
echo "Parameters not supplied, please check!"
exit 1
fi
DOMAIN="${1}"
DOMAIN="${DOMAIN#http://}"
DOMAIN="${DOMAIN#https://}"
DOMAIN="${DOMAIN#ftp://}"
DOMAIN="${DOMAIN#scp://}"
DOMAIN="${DOMAIN#scp://}"
DOMAIN="${DOMAIN#sftp://}"
DOMAIN=${DOMAIN%%/*}
}
gen_root_fd(){
DOC_FD="./sites/${1}/"
if [ -d "./sites/${1}" ]; then
echo -e "[O] The root folder \033[32m${DOC_FD}\033[0m exist."
else
echo "Creating - document root."
bash bin/domain.sh -add ${1}
echo "Finished - document root."
fi
}
create_db(){
if [ ! -n "${MYSQL_DATABASE}" ] || [ ! -n "${MYSQL_USER}" ] || [ ! -n "${MYSQL_PASSWORD}" ]; then
echo "Parameters not supplied, please check!"
exit 1
else
bash bin/database.sh -D ${1} -U ${MYSQL_USER} -P ${MYSQL_PASSWORD} -DB ${MYSQL_DATABASE}
fi
}
store_credential(){
if [ -f ${DOC_FD}/.db_pass ]; then
echo '[O] db file exist!'
else
echo 'Storing database parameter'
cat > "${DOC_FD}/.db_pass" << EOT
"Database":"${MYSQL_DATABASE}"
"Username":"${MYSQL_USER}"
"Password":"$(echo ${MYSQL_PASSWORD} | tr -d "'")"
EOT
fi
}
app_download(){
docker compose exec -T ${CONT_NAME} su -c "appinstallctl.sh --app ${1} --domain ${2}"
}
lsws_restart(){
bash bin/webadmin.sh -r
}
main(){
domain_filter ${DOMAIN}
gen_root_fd ${DOMAIN}
create_db ${DOMAIN}
store_credential
app_download ${APP_NAME} ${DOMAIN}
lsws_restart
help_message 2
}
while [ ! -z "${1}" ]; do
case ${1} in
-[hH] | -help | --help)
help_message 1
;;
*)
help_message 1
;;
esac
shift
done
main

View File

@ -0,0 +1,2 @@
#!/usr/bin/env bash
git ls-files -v|grep '^S'

View File

@ -0,0 +1,2 @@
#!/usr/bin/env bash
find conf -maxdepth 1 -type d \( ! -name . \) -exec bash -c "cd '{}' && pwd && git ls-files -z ${pwd} | xargs -0 git update-index --no-skip-worktree" \;

View File

@ -0,0 +1,3 @@
#!/usr/bin/env bash
find conf -maxdepth 1 -type d \( ! -name . \) -exec bash -c "cd '{}' && pwd && git ls-files -z ${pwd} | xargs -0 git update-index --skip-worktree" \;

View File

@ -0,0 +1,61 @@
#!/usr/bin/env bash
CONT_NAME='litespeed'
EPACE=' '
echow(){
FLAG=${1}
shift
echo -e "\033[1m${EPACE}${FLAG}\033[0m${@}"
}
help_message(){
echo -e "\033[1mOPTIONS\033[0m"
echow "-A, --add [domain_name]"
echo "${EPACE}${EPACE}Example: domain.sh -A example.com, will add the domain to Listener and auto create a new virtual host."
echow "-D, --del [domain_name]"
echo "${EPACE}${EPACE}Example: domain.sh -D example.com, will delete the domain from Listener."
echow '-H, --help'
echo "${EPACE}${EPACE}Display help and exit."
}
check_input(){
if [ -z "${1}" ]; then
help_message
exit 1
fi
}
add_domain(){
check_input ${1}
docker compose exec ${CONT_NAME} su -s /bin/bash lsadm -c "cd /usr/local/lsws/conf && domainctl.sh --add ${1}"
if [ ! -d "./sites/${1}" ]; then
mkdir -p ./sites/${1}/{html,logs,certs}
fi
bash bin/webadmin.sh -r
}
del_domain(){
check_input ${1}
docker compose exec ${CONT_NAME} su -s /bin/bash lsadm -c "cd /usr/local/lsws/conf && domainctl.sh --del ${1}"
bash bin/webadmin.sh -r
}
check_input ${1}
while [ ! -z "${1}" ]; do
case ${1} in
-[hH] | -help | --help)
help_message
;;
-[aA] | -add | --add) shift
add_domain ${1}
;;
-[dD] | -del | --del | --delete) shift
del_domain ${1}
;;
*)
help_message
;;
esac
shift
done

View File

@ -0,0 +1,98 @@
#!/usr/bin/env bash
CONT_NAME='litespeed'
EPACE=' '
echow(){
FLAG=${1}
shift
echo -e "\033[1m${EPACE}${FLAG}\033[0m${@}"
}
help_message(){
echo -e "\033[1mOPTIONS\033[0m"
echow '[Enter Your PASSWORD]'
echo "${EPACE}${EPACE}Example: webadmin.sh MY_SECURE_PASS, to update web admin password immediatly."
echow '-R, --restart'
echo "${EPACE}${EPACE}Will gracefully restart LiteSpeed Web Server."
echow '-M, --mod-secure [enable|disable]'
echo "${EPACE}${EPACE}Example: webadmin.sh -M enable, will enable and apply Mod_Secure OWASP rules on server"
echow '-U, --upgrade'
echo "${EPACE}${EPACE}Will upgrade web server to latest stable version"
echow '-S, --serial [YOUR_SERIAL|TRIAL]'
echo "${EPACE}${EPACE}Will apply your serial number to LiteSpeed Web Server."
echow '-H, --help'
echo "${EPACE}${EPACE}Display help and exit."
exit 0
}
check_input(){
if [ -z "${1}" ]; then
help_message
exit 1
fi
}
lsws_restart(){
docker compose exec -T ${CONT_NAME} su -c '/usr/local/lsws/bin/lswsctrl restart >/dev/null'
}
apply_serial(){
docker compose exec ${CONT_NAME} su -c "serialctl.sh --serial ${1}"
lsws_restart
}
mod_secure(){
if [ "${1}" = 'enable' ] || [ "${1}" = 'Enable' ]; then
docker compose exec ${CONT_NAME} su -s /bin/bash root -c "owaspctl.sh --enable"
lsws_restart
elif [ "${1}" = 'disable' ] || [ "${1}" = 'Disable' ]; then
docker compose exec ${CONT_NAME} su -s /bin/bash root -c "owaspctl.sh --disable"
lsws_restart
else
help_message
fi
}
ls_upgrade(){
echo 'Upgrade web server to latest stable version.'
docker compose exec ${CONT_NAME} su -c '/usr/local/lsws/admin/misc/lsup.sh 2>/dev/null'
}
set_web_admin(){
echo 'Update web admin password.'
local LSADPATH='/usr/local/lsws/admin'
docker compose exec ${CONT_NAME} su -s /bin/bash lsadm -c \
'if [ -e /usr/local/lsws/admin/fcgi-bin/admin_php ]; then \
echo "admin:$('${LSADPATH}'/fcgi-bin/admin_php -q '${LSADPATH}'/misc/htpasswd.php '${1}')" > '${LSADPATH}'/conf/htpasswd; \
else echo "admin:$('${LSADPATH}'/fcgi-bin/admin_php5 -q '${LSADPATH}'/misc/htpasswd.php '${1}')" > '${LSADPATH}'/conf/htpasswd; \
fi';
}
main(){
set_web_admin ${1}
}
check_input ${1}
while [ ! -z "${1}" ]; do
case ${1} in
-[hH] | -help | --help)
help_message
;;
-[rR] | -restart | --restart)
lsws_restart
;;
-M | -mode-secure | --mod-secure) shift
mod_secure ${1}
;;
-lsup | --lsup | --upgrade | -U) shift
ls_upgrade
;;
-[sS] | -serial | --serial) shift
apply_serial ${1}
;;
*)
main ${1}
;;
esac
shift
done

View File

@ -0,0 +1,2 @@
*
!.gitignore

View File

@ -0,0 +1,30 @@
version: '3'
services:
litespeed:
container_name: ${CONTAINER_NAME}
restart: always
networks:
- 1panel-network
logging:
driver: none
volumes:
- ${DATA_PATH}/lsws/conf:/usr/local/lsws/conf
- ${DATA_PATH}/lsws/admin-conf:/usr/local/lsws/admin/conf
- ${DATA_PATH}/bin/container:/usr/local/bin
- ${DATA_PATH}/sites:/var/www/vhosts/
- ${DATA_PATH}/acme:/root/.acme.sh/
- ${DATA_PATH}/logs:/usr/local/lsws/logs/
ports:
- "${PANEL_APP_PORT_HTTP}:80"
- "${PANEL_APP_PORT_HTTPS}:443"
- "${PANEL_APP_PORT_HTTPS}:443/udp"
- "${PANEL_APP_PORT_CONSOLE}:7080"
environment:
- TZ=${TIME_ZONE}
image: litespeedtech/openlitespeed:1.7.17-lsphp81
labels:
createdBy: "Apps"
networks:
1panel-network:
external: true

View File

@ -0,0 +1,43 @@
# 使用说明
安装完成后,在容器功能界面,连接容器终端,执行以下命令创建管理员账户密码
```
/usr/local/lsws/admin/misc/admpass.sh
```
# 原始相关
OpenLiteSpeed Web Server
========
Description
--------
OpenLiteSpeed is a high-performance, lightweight, open source HTTP server developed and copyrighted by
LiteSpeed Technologies. Users are free to download, use, distribute, and modify OpenLiteSpeed and its
source code in accordance with the precepts of the GPLv3 license.
This is the official repository for OpenLiteSpeed's source code. It is maintained by LiteSpeed
Technologies.
Documentation
--------
Users can find all OpenLiteSpeed documentation on the [OpenLiteSpeed site](https://openlitespeed.org),
but here are some quick links to important parts of the site:
[Installation](https://openlitespeed.org/kb/category/installation/)
[Configuration](https://openlitespeed.org/kb/category/configuration/)
[Road map](https://openlitespeed.org/mediawiki/index.php/Road_Map)
[Release log](https://openlitespeed.org/release-log/)
Get in Touch
--------
OpenLiteSpeed has a [Google Group](https://groups.google.com/forum/#!forum/openlitespeed-development). If
you find a bug, want to request new features, or just want to talk about OpenLiteSpeed, this is the place
to do it.

View File

@ -0,0 +1,20 @@
name: OpenLiteSpeed
tags:
- Web 服务器
title: 一个高性能、轻量级、开源 的HTTP 服务器
type: Web 服务器
description: 一个高性能、轻量级、开源 的HTTP 服务器
additionalProperties:
key: openlitespeed
name: OpenLiteSpeed
tags:
- Server
shortDescZh: 一个高性能、轻量级、开源 的HTTP 服务器
shortDescEn: A high-performance, lightweight, open source HTTP server
type: runtime
crossVersionUpdate: true
limit: 1
recommend: 3
website: https://openlitespeed.org
github: https://github.com/litespeedtech/openlitespeed
document: https://openlitespeed.org/#install

View File

@ -0,0 +1,6 @@
CONTAINER_NAME="openlitespeed"
DATA_PATH="./data"
PANEL_APP_PORT_CONSOLE="40113"
PANEL_APP_PORT_HTTP="80"
PANEL_APP_PORT_HTTPS="443"
TIME_ZONE="Asia/Shanghai"

View File

@ -0,0 +1,40 @@
additionalProperties:
formFields:
- default: 80
edit: true
envKey: PANEL_APP_PORT_HTTP
labelEn: HTTP Port
labelZh: HTTP端口
required: true
rule: paramPort
type: number
- default: 443
edit: true
envKey: PANEL_APP_PORT_HTTPS
labelEn: HTTPS Port
labelZh: HTTPS端口
required: true
rule: paramPort
type: number
- default: 40113
edit: true
envKey: PANEL_APP_PORT_CONSOLE
labelEn: Console Port
labelZh: 控制台端口
required: true
rule: paramPort
type: number
- default: ./data
disabled: true
envKey: DATA_PATH
labelEn: Data folder path
labelZh: 数据文件夹路径
required: true
type: text
- default: Asia/Shanghai
edit: true
envKey: TIME_ZONE
labelEn: Time zone
labelZh: 时区
required: true
type: text

View File

@ -0,0 +1,293 @@
#!/usr/bin/env bash
EMAIL=''
NO_EMAIL=''
DOMAIN=''
INSTALL=''
UNINSTALL=''
TYPE=0
CONT_NAME='litespeed'
ACME_SRC='https://raw.githubusercontent.com/Neilpang/acme.sh/master/acme.sh'
EPACE=' '
RENEW=''
RENEW_ALL=''
FORCE=''
REVOKE=''
REMOVE=''
echow(){
FLAG=${1}
shift
echo -e "\033[1m${EPACE}${FLAG}\033[0m${@}"
}
help_message(){
case ${1} in
"1")
echo 'You will need to install acme script at the first time.'
echo 'Please run acme.sh --install --email example@example.com'
;;
"2")
echo -e "\033[1mOPTIONS\033[0m"
echow '-D, --domain [DOMAIN_NAME]'
echo "${EPACE}${EPACE}Example: acme.sh --domain example.com"
echo "${EPACE}${EPACE}will auto detect and apply for both example.com and www.example.com domains."
echow '-H, --help'
echo "${EPACE}${EPACE}Display help and exit."
echo -e "\033[1m Only for the First time\033[0m"
echow '--install --email [EMAIL_ADDR]'
echo "${EPACE}${EPACE}Will install ACME with the Email provided"
echow '-r, --renew'
echo "${EPACE}${EPACE}Renew a specific domain with -D or --domain parameter if posibile. To force renew, use -f parameter."
echow '-R, --renew-all'
echo "${EPACE}${EPACE}Renew all domains if possible. To force renew, use -f parameter."
echow '-f, -F, --force'
echo "${EPACE}${EPACE}Force renew for a specific domain or all domains."
echow '-v, --revoke'
echo "${EPACE}${EPACE}Revoke a domain."
echow '-V, --remove'
echo "${EPACE}${EPACE}Remove a domain."
exit 0
;;
"3")
echo 'Please run acme.sh --domain [DOMAIN_NAME] to apply certificate'
exit 0
;;
esac
}
check_input(){
if [ -z "${1}" ]; then
help_message 2
fi
}
domain_filter(){
if [ -z "${1}" ]; then
help_message 3
fi
DOMAIN="${1}"
DOMAIN="${DOMAIN#http://}"
DOMAIN="${DOMAIN#https://}"
DOMAIN="${DOMAIN#ftp://}"
DOMAIN="${DOMAIN#scp://}"
DOMAIN="${DOMAIN#scp://}"
DOMAIN="${DOMAIN#sftp://}"
DOMAIN=${DOMAIN%%/*}
}
email_filter(){
CKREG="^[a-z0-9!#\$%&'*+/=?^_\`{|}~-]+(\.[a-z0-9!#$%&'*+/=?^_\`{|}~-]+)*@([a-z0-9]([a-z0-9-]*[a-z0-9])?\.)+[a-z0-9]([a-z0-9-]*[a-z0-9])?\$"
if [[ "${1}" =~ ${CKREG} ]] ; then
echo -e "[O] The E-mail \033[32m${1}\033[0m is valid."
else
echo -e "[X] The E-mail \e[31m${1}\e[39m is invalid"
exit 1
fi
}
cert_hook(){
echo '[Start] Adding ACME hook'
docker compose exec ${CONT_NAME} su -s /bin/bash -c "certhookctl.sh"
echo '[End] Adding ACME hook'
}
www_domain(){
CHECK_WWW=$(echo ${1} | cut -c1-4)
if [[ ${CHECK_WWW} == www. ]] ; then
DOMAIN=$(echo ${1} | cut -c 5-)
else
DOMAIN=${1}
fi
WWW_DOMAIN="www.${DOMAIN}"
}
domain_verify(){
curl -Is http://${DOMAIN}/ | grep -i LiteSpeed > /dev/null 2>&1
if [ ${?} = 0 ]; then
echo -e "[O] The domain name \033[32m${DOMAIN}\033[0m is accessible."
TYPE=1
curl -Is http://${WWW_DOMAIN}/ | grep -i LiteSpeed > /dev/null 2>&1
if [ ${?} = 0 ]; then
echo -e "[O] The domain name \033[32m${WWW_DOMAIN}\033[0m is accessible."
TYPE=2
else
echo -e "[!] The domain name ${WWW_DOMAIN} is inaccessible."
fi
else
echo -e "[X] The domain name \e[31m${DOMAIN}\e[39m is inaccessible, please verify."
exit 1
fi
}
install_acme(){
echo '[Start] Install ACME'
if [ "${1}" = 'true' ]; then
docker compose exec litespeed su -c "cd; wget ${ACME_SRC}; chmod 755 acme.sh; \
./acme.sh --install --cert-home ~/.acme.sh/certs; \
rm ~/acme.sh"
elif [ "${2}" != '' ]; then
email_filter "${2}"
docker compose exec litespeed su -c "cd; wget ${ACME_SRC}; chmod 755 acme.sh; \
./acme.sh --install --cert-home ~/.acme.sh/certs --accountemail ${2}; \
rm ~/acme.sh"
else
help_message 1
exit 1
fi
echo '[End] Install ACME'
}
uninstall_acme(){
echo '[Start] Uninstall ACME'
docker compose exec ${CONT_NAME} su -c "~/.acme.sh/acme.sh --uninstall"
echo '[End] Uninstall ACME'
exit 0
}
check_acme(){
echo '[Start] Checking ACME'
docker compose exec ${CONT_NAME} su -c "test -f /root/.acme.sh/acme.sh"
if [ ${?} != 0 ]; then
install_acme "${NO_EMAIL}" "${EMAIL}"
cert_hook
help_message 3
fi
echo '[End] Checking ACME'
}
lsws_restart(){
docker compose exec ${CONT_NAME} su -c '/usr/local/lsws/bin/lswsctrl restart >/dev/null'
}
doc_root_verify(){
if [ "${DOC_ROOT}" = '' ]; then
DOC_PATH="/var/www/vhosts/${1}/html"
else
DOC_PATH="${DOC_ROOT}"
fi
docker compose exec ${CONT_NAME} su -c "[ -e ${DOC_PATH} ]"
if [ ${?} -eq 0 ]; then
echo -e "[O] The document root folder \033[32m${DOC_PATH}\033[0m does exist."
else
echo -e "[X] The document root folder \e[31m${DOC_PATH}\e[39m does not exist!"
exit 1
fi
}
install_cert(){
echo '[Start] Apply Lets Encrypt Certificate'
if [ ${TYPE} = 1 ]; then
docker compose exec ${CONT_NAME} su -c "/root/.acme.sh/acme.sh --issue -d ${1} -w ${DOC_PATH}"
elif [ ${TYPE} = 2 ]; then
docker compose exec ${CONT_NAME} su -c "/root/.acme.sh/acme.sh --issue -d ${1} -d www.${1} -w ${DOC_PATH}"
else
echo 'unknown Type!'
exit 2
fi
echo '[End] Apply Lets Encrypt Certificate'
}
renew_acme(){
echo '[Start] Renew ACME'
if [ "${FORCE}" = 'true' ]; then
docker compose exec ${CONT_NAME} su -c "~/.acme.sh/acme.sh --renew --domain ${1} --force"
else
docker compose exec ${CONT_NAME} su -c "~/.acme.sh/acme.sh --renew --domain ${1}"
fi
echo '[End] Renew ACME'
lsws_restart
}
renew_all_acme(){
echo '[Start] Renew all ACME'
if [ "${FORCE}" = 'true' ]; then
docker compose exec ${CONT_NAME} su -c "~/.acme.sh/acme.sh --renew-all --force"
else
docker compose exec ${CONT_NAME} su -c "~/.acme.sh/acme.sh --renew-all"
fi
echo '[End] Renew all ACME'
lsws_restart
}
revoke(){
echo '[Start] Revoke a domain'
docker compose exec ${CONT_NAME} su -c "~/.acme.sh/acme.sh --revoke --domain ${1}"
echo '[End] Revoke a domain'
lsws_restart
}
remove(){
echo '[Start] Remove a domain'
docker compose exec ${CONT_NAME} su -c "~/.acme.sh/acme.sh --remove --domain ${1}"
echo '[End] Remove a domain'
lsws_restart
}
main(){
if [ "${RENEW_ALL}" = 'true' ]; then
renew_all_acme
exit 0
elif [ "${RENEW}" = 'true' ]; then
renew_acme ${DOMAIN}
exit 0
elif [ "${REVOKE}" = 'true' ]; then
revoke ${DOMAIN}
exit 0
elif [ "${REMOVE}" = 'true' ]; then
remove ${DOMAIN}
exit 0
fi
check_acme
domain_filter ${DOMAIN}
www_domain ${DOMAIN}
domain_verify
doc_root_verify ${DOMAIN}
install_cert ${DOMAIN}
lsws_restart
}
check_input ${1}
while [ ! -z "${1}" ]; do
case ${1} in
-[hH] | -help | --help)
help_message 2
;;
-[dD] | -domain | --domain) shift
check_input "${1}"
DOMAIN="${1}"
;;
-[iI] | --install )
INSTALL=true
;;
-[uU] | --uninstall )
UNINSTALL=true
uninstall_acme
;;
-[fF] | --force )
FORCE=true
;;
-[r] | --renew )
RENEW=true
;;
-[R] | --renew-all )
RENEW_ALL=true
;;
-[v] | --revoke )
REVOKE=true
;;
-[V] | --remove )
REMOVE=true
;;
-[eE] | --email ) shift
check_input "${1}"
EMAIL="${1}"
;;
*)
help_message 2
;;
esac
shift
done
main

View File

@ -0,0 +1,60 @@
#!/usr/bin/env bash
APP_NAME=''
DOMAIN=''
EPACE=' '
echow(){
FLAG=${1}
shift
echo -e "\033[1m${EPACE}${FLAG}\033[0m${@}"
}
help_message(){
echo -e "\033[1mOPTIONS\033[0m"
echow '-A, --app [app_name] -D, --domain [DOMAIN_NAME]'
echo "${EPACE}${EPACE}Example: appinstall.sh -A wordpress -D example.com"
echo "${EPACE}${EPACE}Will install WordPress CMS under the example.com domain"
echow '-H, --help'
echo "${EPACE}${EPACE}Display help and exit."
exit 0
}
check_input(){
if [ -z "${1}" ]; then
help_message
exit 1
fi
}
app_download(){
docker compose exec litespeed su -c "appinstallctl.sh --app ${1} --domain ${2}"
bash bin/webadmin.sh -r
exit 0
}
main(){
app_download ${APP_NAME} ${DOMAIN}
}
check_input ${1}
while [ ! -z "${1}" ]; do
case ${1} in
-[hH] | -help | --help)
help_message
;;
-[aA] | -app | --app) shift
check_input "${1}"
APP_NAME="${1}"
;;
-[dD] | -domain | --domain) shift
check_input "${1}"
DOMAIN="${1}"
;;
*)
help_message
;;
esac
shift
done
main

View File

@ -0,0 +1,660 @@
#!/bin/bash
DEFAULT_VH_ROOT='/var/www/vhosts'
VH_DOC_ROOT=''
VHNAME=''
APP_NAME=''
DOMAIN=''
WWW_UID=''
WWW_GID=''
WP_CONST_CONF=''
PUB_IP=$(curl -s http://checkip.amazonaws.com)
DB_HOST='mysql'
PLUGINLIST="litespeed-cache.zip"
THEME='twentytwenty'
EPACE=' '
echow(){
FLAG=${1}
shift
echo -e "\033[1m${EPACE}${FLAG}\033[0m${@}"
}
help_message(){
echo -e "\033[1mOPTIONS\033[0m"
echow '-A, -app [wordpress] -D, --domain [DOMAIN_NAME]'
echo "${EPACE}${EPACE}Example: appinstallctl.sh --app wordpress --domain example.com"
echow '-H, --help'
echo "${EPACE}${EPACE}Display help and exit."
exit 0
}
check_input(){
if [ -z "${1}" ]; then
help_message
exit 1
fi
}
linechange(){
LINENUM=$(grep -n "${1}" ${2} | cut -d: -f 1)
if [ -n "${LINENUM}" ] && [ "${LINENUM}" -eq "${LINENUM}" ] 2>/dev/null; then
sed -i "${LINENUM}d" ${2}
sed -i "${LINENUM}i${3}" ${2}
fi
}
ck_ed(){
if [ ! -f /bin/ed ]; then
echo "Install ed package.."
apt-get install ed -y > /dev/null 2>&1
fi
}
ck_unzip(){
if [ ! -f /usr/bin/unzip ]; then
echo "Install unzip package.."
apt-get install unzip -y > /dev/null 2>&1
fi
}
get_owner(){
WWW_UID=$(stat -c "%u" ${DEFAULT_VH_ROOT})
WWW_GID=$(stat -c "%g" ${DEFAULT_VH_ROOT})
if [ ${WWW_UID} -eq 0 ] || [ ${WWW_GID} -eq 0 ]; then
WWW_UID=1000
WWW_GID=1000
echo "Set owner to ${WWW_UID}"
fi
}
get_db_pass(){
if [ -f ${DEFAULT_VH_ROOT}/${1}/.db_pass ]; then
SQL_DB=$(grep -i Database ${VH_ROOT}/.db_pass | awk -F ':' '{print $2}' | tr -d '"')
SQL_USER=$(grep -i Username ${VH_ROOT}/.db_pass | awk -F ':' '{print $2}' | tr -d '"')
SQL_PASS=$(grep -i Password ${VH_ROOT}/.db_pass | awk -F ':' '{print $2}' | tr -d '"')
else
echo 'db pass file can not locate, skip wp-config pre-config.'
fi
}
set_vh_docroot(){
if [ "${VHNAME}" != '' ]; then
VH_ROOT="${DEFAULT_VH_ROOT}/${VHNAME}"
VH_DOC_ROOT="${DEFAULT_VH_ROOT}/${VHNAME}/html"
WP_CONST_CONF="${VH_DOC_ROOT}/wp-content/plugins/litespeed-cache/data/const.default.ini"
elif [ -d ${DEFAULT_VH_ROOT}/${1}/html ]; then
VH_ROOT="${DEFAULT_VH_ROOT}/${1}"
VH_DOC_ROOT="${DEFAULT_VH_ROOT}/${1}/html"
WP_CONST_CONF="${VH_DOC_ROOT}/wp-content/plugins/litespeed-cache/data/const.default.ini"
else
echo "${DEFAULT_VH_ROOT}/${1}/html does not exist, please add domain first! Abort!"
exit 1
fi
}
check_sql_native(){
local COUNTER=0
local LIMIT_NUM=100
until [ "$(curl -v mysql:3306 2>&1 | grep -i 'native\|Connected')" ]; do
echo "Counter: ${COUNTER}/${LIMIT_NUM}"
COUNTER=$((COUNTER+1))
if [ ${COUNTER} = 10 ]; then
echo '--- MySQL is starting, please wait... ---'
elif [ ${COUNTER} = ${LIMIT_NUM} ]; then
echo '--- MySQL is timeout, exit! ---'
exit 1
fi
sleep 1
done
}
install_wp_plugin(){
for PLUGIN in ${PLUGINLIST}; do
wget -q -P ${VH_DOC_ROOT}/wp-content/plugins/ https://downloads.wordpress.org/plugin/${PLUGIN}
if [ ${?} = 0 ]; then
ck_unzip
unzip -qq -o ${VH_DOC_ROOT}/wp-content/plugins/${PLUGIN} -d ${VH_DOC_ROOT}/wp-content/plugins/
else
echo "${PLUGINLIST} FAILED to download"
fi
done
rm -f ${VH_DOC_ROOT}/wp-content/plugins/*.zip
}
set_htaccess(){
if [ ! -f ${VH_DOC_ROOT}/.htaccess ]; then
touch ${VH_DOC_ROOT}/.htaccess
fi
cat << EOM > ${VH_DOC_ROOT}/.htaccess
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
EOM
}
get_theme_name(){
THEME_NAME=$(grep WP_DEFAULT_THEME ${VH_DOC_ROOT}/wp-includes/default-constants.php | grep -v '!' | awk -F "'" '{print $4}')
echo "${THEME_NAME}" | grep 'twenty' >/dev/null 2>&1
if [ ${?} = 0 ]; then
THEME="${THEME_NAME}"
fi
}
set_lscache(){
cat << EOM > "${WP_CONST_CONF}"
;
; This is the predefined default LSCWP configuration file
;
; All the keys and values please refer \`src/const.cls.php\`
;
; Comments start with \`;\`
;
;; -------------------------------------------------- ;;
;; -------------- General ----------------- ;;
;; -------------------------------------------------- ;;
; O_AUTO_UPGRADE
auto_upgrade = false
; O_API_KEY
api_key = ''
; O_SERVER_IP
server_ip = ''
; O_NEWS
news = false
;; -------------------------------------------------- ;;
;; -------------- Cache ----------------- ;;
;; -------------------------------------------------- ;;
cache-priv = true
cache-commenter = true
cache-rest = true
cache-page_login = true
cache-favicon = true
cache-resources = true
cache-browser = false
cache-mobile = false
cache-mobile_rules = 'Mobile
Android
Silk/
Kindle
BlackBerry
Opera Mini
Opera Mobi'
cache-exc_useragents = ''
cache-exc_cookies = ''
cache-exc_qs = ''
cache-exc_cat = ''
cache-exc_tag = ''
cache-force_uri = ''
cache-force_pub_uri = ''
cache-priv_uri = ''
cache-exc = ''
cache-exc_roles = ''
cache-drop_qs = 'fbclid
gclid
utm*
_ga'
cache-ttl_pub = 604800
cache-ttl_priv = 1800
cache-ttl_frontpage = 604800
cache-ttl_feed = 604800
; O_CACHE_TTL_REST
cache-ttl_rest = 604800
cache-ttl_browser = 31557600
cache-login_cookie = ''
cache-vary_group = ''
cache-ttl_status = '403 3600
404 3600
500 3600'
;; -------------------------------------------------- ;;
;; -------------- Purge ----------------- ;;
;; -------------------------------------------------- ;;
; O_PURGE_ON_UPGRADE
purge-upgrade = true
; O_PURGE_STALE
purge-stale = true
purge-post_all = false
purge-post_f = true
purge-post_h = true
purge-post_p = true
purge-post_pwrp = true
purge-post_a = true
purge-post_y = false
purge-post_m = true
purge-post_d = false
purge-post_t = true
purge-post_pt = true
purge-timed_urls = ''
purge-timed_urls_time = ''
purge-hook_all = 'switch_theme
wp_create_nav_menu
wp_update_nav_menu
wp_delete_nav_menu
create_term
edit_terms
delete_term
add_link
edit_link
delete_link'
;; -------------------------------------------------- ;;
;; -------------- ESI ----------------- ;;
;; -------------------------------------------------- ;;
; O_ESI
esi = false
; O_ESI_CACHE_ADMBAR
esi-cache_admbar = true
; O_ESI_CACHE_COMMFORM
esi-cache_commform = true
; O_ESI_NONCE
esi-nonce = 'stats_nonce
subscribe_nonce'
;; -------------------------------------------------- ;;
;; -------------- Utilities ----------------- ;;
;; -------------------------------------------------- ;;
util-heartbeat = true
util-instant_click = false
util-check_advcache = true
util-no_https_vary = false
;; -------------------------------------------------- ;;
;; -------------- Debug ----------------- ;;
;; -------------------------------------------------- ;;
; O_DEBUG_DISABLE_ALL
debug-disable_all = false
; O_DEBUG
debug = false
; O_DEBUG_IPS
debug-ips = '127.0.0.1'
; O_DEBUG_LEVEL
debug-level = false
; O_DEBUG_FILESIZE
debug-filesize = 3
; O_DEBUG_COOKIE
debug-cookie = false
; O_DEBUG_COLLAPS_QS
debug-collaps_qs = false
; O_DEBUG_INC
debug-inc = ''
; O_DEBUG_EXC
debug-exc = ''
;; -------------------------------------------------- ;;
;; -------------- DB Optm ----------------- ;;
;; -------------------------------------------------- ;;
; O_DB_OPTM_REVISIONS_MAX
db_optm-revisions_max = 0
; O_DB_OPTM_REVISIONS_AGE
db_optm-revisions_age = 0
;; -------------------------------------------------- ;;
;; -------------- HTML Optm ----------------- ;;
;; -------------------------------------------------- ;;
; O_OPTM_CSS_MIN
optm-css_min = false
optm-css_inline_min = false
; O_OPTM_CSS_COMB
optm-css_comb = false
optm-css_comb_priority = false
; O_OPTM_CSS_HTTP2
optm-css_http2 = false
optm-css_exc = ''
; O_OPTM_JS_MIN
optm-js_min = false
optm-js_inline_min = false
; O_OPTM_JS_COMB
optm-js_comb = false
optm-js_comb_priority = false
; O_OPTM_JS_HTTP2
optm-js_http2 = false
; O_OPTM_EXC_JQ
optm-js_exc = ''
optm-ttl = 604800
optm-html_min = false
optm-qs_rm = false
optm-ggfonts_rm = false
; O_OPTM_CSS_ASYNC
optm-css_async = false
; O_OPTM_CCSS_GEN
optm-ccss_gen = true
; O_OPTM_CCSS_ASYNC
optm-ccss_async = true
; O_OPTM_CSS_ASYNC_INLINE
optm-css_async_inline = true
; O_OPTM_CSS_FONT_DISPLAY
optm-css_font_display = false
; O_OPTM_JS_DEFER
optm-js_defer = false
; O_OPTM_JS_INLINE_DEFER
optm-js_inline_defer = false
optm-emoji_rm = false
optm-exc_jq = true
optm-ggfonts_async = false
optm-max_size = 2
optm-rm_comment = false
optm-exc_roles = ''
optm-ccss_con = ''
optm-js_defer_exc = ''
; O_OPTM_DNS_PREFETCH
optm-dns_prefetch = ''
; O_OPTM_DNS_PREFETCH_CTRL
optm-dns_prefetch_ctrl = false
optm-exc = ''
; O_OPTM_CCSS_SEP_POSTTYPE
optm-ccss_sep_posttype = ''
; O_OPTM_CCSS_SEP_URI
optm-ccss_sep_uri = ''
;; -------------------------------------------------- ;;
;; -------------- Object Cache ----------------- ;;
;; -------------------------------------------------- ;;
object = true
object-kind = false
;object-host = 'localhost'
object-host = '/var/www/memcached.sock'
;object-port = 11211
cache_object_port = ''
object-life = 360
object-persistent = true
object-admin = true
object-transients = true
object-db_id = 0
object-user = ''
object-pswd = ''
object-global_groups = 'users
userlogins
usermeta
user_meta
site-transient
site-options
site-lookup
blog-lookup
blog-details
rss
global-posts
blog-id-cache'
object-non_persistent_groups = 'comment
counts
plugins
wc_session_id'
;; -------------------------------------------------- ;;
;; -------------- Discussion ----------------- ;;
;; -------------------------------------------------- ;;
; O_DISCUSS_AVATAR_CACHE
discuss-avatar_cache = false
; O_DISCUSS_AVATAR_CRON
discuss-avatar_cron = false
; O_DISCUSS_AVATAR_CACHE_TTL
discuss-avatar_cache_ttl = 604800
;; -------------------------------------------------- ;;
;; -------------- Media ----------------- ;;
;; -------------------------------------------------- ;;
; O_MEDIA_LAZY
media-lazy = false
; O_MEDIA_LAZY_PLACEHOLDER
media-lazy_placeholder = ''
; O_MEDIA_PLACEHOLDER_RESP
media-placeholder_resp = false
; O_MEDIA_PLACEHOLDER_RESP_COLOR
media-placeholder_resp_color = '#cfd4db'
; O_MEDIA_PLACEHOLDER_RESP_GENERATOR
media-placeholder_resp_generator = false
; O_MEDIA_PLACEHOLDER_RESP_SVG
media-placeholder_resp_svg = '<svg xmlns="http://www.w3.org/2000/svg" width="{width}" height="{height}" viewBox="0 0 {width} {height}"><rect width="100%" height="100%" fill="{color}"/></svg>'
; O_MEDIA_PLACEHOLDER_LQIP
media-placeholder_lqip = false
; O_MEDIA_PLACEHOLDER_LQIP_QUAL
media-placeholder_lqip_qual = 4
; O_MEDIA_PLACEHOLDER_RESP_ASYNC
media-placeholder_resp_async = true
; O_MEDIA_IFRAME_LAZY
media-iframe_lazy = false
; O_MEDIA_LAZYJS_INLINE
media-lazyjs_inline = false
; O_MEDIA_LAZY_EXC
media-lazy_exc = ''
; O_MEDIA_LAZY_CLS_EXC
media-lazy_cls_exc = ''
; O_MEDIA_LAZY_PARENT_CLS_EXC
media-lazy_parent_cls_exc = ''
; O_MEDIA_IFRAME_LAZY_CLS_EXC
media-iframe_lazy_cls_exc = ''
; O_MEDIA_IFRAME_LAZY_PARENT_CLS_EXC
media-iframe_lazy_parent_cls_exc = ''
; O_MEDIA_LAZY_URI_EXC
media-lazy_uri_exc = ''
;; -------------------------------------------------- ;;
;; -------------- Image Optm ----------------- ;;
;; -------------------------------------------------- ;;
img_optm-auto = false
img_optm-cron = true
img_optm-ori = true
img_optm-rm_bkup = false
img_optm-webp = false
img_optm-lossless = false
img_optm-exif = false
img_optm-webp_replace = false
img_optm-webp_attr = 'img.src
div.data-thumb
img.data-src
div.data-large_image
img.retina_logo_url
div.data-parallax-image
video.poster'
img_optm-webp_replace_srcset = false
img_optm-jpg_quality = 82
;; -------------------------------------------------- ;;
;; -------------- Crawler ----------------- ;;
;; -------------------------------------------------- ;;
crawler = false
crawler-inc_posts = true
crawler-inc_pages = true
crawler-inc_cats = true
crawler-inc_tags = true
crawler-exc_cpt = ''
crawler-order_links = 'date_desc'
crawler-usleep = 500
crawler-run_duration = 400
crawler-run_interval = 600
crawler-crawl_interval = 302400
crawler-threads = 3
crawler-timeout = 30
crawler-load_limit = 1
; O_CRAWLER_SITEMAP
crawler-sitemap = ''
; O_CRAWLER_DROP_DOMAIN
crawler-drop_domain = true
crawler-roles = ''
crawler-cookies = ''
;; -------------------------------------------------- ;;
;; -------------- Misc ----------------- ;;
;; -------------------------------------------------- ;;
; O_MISC_HTACCESS_FRONT
misc-htaccess_front = ''
; O_MISC_HTACCESS_BACK
misc-htaccess_back = ''
; O_MISC_HEARTBEAT_FRONT
misc-heartbeat_front = false
; O_MISC_HEARTBEAT_FRONT_TTL
misc-heartbeat_front_ttl = 60
; O_MISC_HEARTBEAT_BACK
misc-heartbeat_back = false
; O_MISC_HEARTBEAT_BACK_TTL
misc-heartbeat_back_ttl = 60
; O_MISC_HEARTBEAT_EDITOR
misc-heartbeat_editor = false
; O_MISC_HEARTBEAT_EDITOR_TTL
misc-heartbeat_editor_ttl = 15
;; -------------------------------------------------- ;;
;; -------------- CDN ----------------- ;;
;; -------------------------------------------------- ;;
cdn = false
cdn-ori = ''
cdn-ori_dir = ''
cdn-exc = ''
cdn-remote_jq = false
cdn-quic = false
cdn-quic_email = ''
cdn-quic_key = ''
cdn-cloudflare = false
cdn-cloudflare_email = ''
cdn-cloudflare_key = ''
cdn-cloudflare_name = ''
cdn-cloudflare_zone = ''
; \`cdn-mapping\` needs to be put in the end with a section tag
;; -------------------------------------------------- ;;
;; -------------- CDN 2 ----------------- ;;
;; -------------------------------------------------- ;;
; <------------ CDN Mapping Example BEGIN -------------------->
; Need to keep the section tag \`[cdn-mapping]\` before list.
;
; NOTE 1) Need to set all child options to make all resources to be replaced without missing.
; NOTE 2) \`url[n]\` option must have to enable the row setting of \`n\`.
; NOTE 3) This section needs to be put in the end of this .ini file
;
; To enable the 2nd mapping record by default, please remove the \`;;\` in the related lines.
[cdn-mapping]
url[0] = ''
inc_js[0] = true
inc_css[0] = true
inc_img[0] = true
filetype[0] = '.aac
.css
.eot
.gif
.jpeg
.js
.jpg
.less
.mp3
.mp4
.ogg
.otf
.pdf
.png
.svg
.ttf
.woff'
;;url[1] = 'https://2nd_CDN_url.com/'
;;filetype[1] = '.webm'
; <------------ CDN Mapping Example END ------------------>
EOM
THEME_PATH="${VH_DOC_ROOT}/wp-content/themes/${THEME}"
if [ ! -f ${THEME_PATH}/functions.php ]; then
cat >> "${THEME_PATH}/functions.php" <<END
<?php
require_once( WP_CONTENT_DIR.'/../wp-admin/includes/plugin.php' );
\$path = 'litespeed-cache/litespeed-cache.php' ;
if (!is_plugin_active( \$path )) {
activate_plugin( \$path ) ;
rename( __FILE__ . '.bk', __FILE__ );
}
END
elif [ ! -f ${THEME_PATH}/functions.php.bk ]; then
cp ${THEME_PATH}/functions.php ${THEME_PATH}/functions.php.bk
ck_ed
ed ${THEME_PATH}/functions.php << END >>/dev/null 2>&1
2i
require_once( WP_CONTENT_DIR.'/../wp-admin/includes/plugin.php' );
\$path = 'litespeed-cache/litespeed-cache.php' ;
if (!is_plugin_active( \$path )) {
activate_plugin( \$path ) ;
rename( __FILE__ . '.bk', __FILE__ );
}
.
w
q
END
fi
}
preinstall_wordpress(){
if [ "${VHNAME}" != '' ]; then
get_db_pass ${VHNAME}
else
get_db_pass ${DOMAIN}
fi
if [ ! -f ${VH_DOC_ROOT}/wp-config.php ] && [ -f ${VH_DOC_ROOT}/wp-config-sample.php ]; then
cp ${VH_DOC_ROOT}/wp-config-sample.php ${VH_DOC_ROOT}/wp-config.php
NEWDBPWD="define('DB_PASSWORD', '${SQL_PASS}');"
linechange 'DB_PASSWORD' ${VH_DOC_ROOT}/wp-config.php "${NEWDBPWD}"
NEWDBPWD="define('DB_USER', '${SQL_USER}');"
linechange 'DB_USER' ${VH_DOC_ROOT}/wp-config.php "${NEWDBPWD}"
NEWDBPWD="define('DB_NAME', '${SQL_DB}');"
linechange 'DB_NAME' ${VH_DOC_ROOT}/wp-config.php "${NEWDBPWD}"
#NEWDBPWD="define('DB_HOST', '${PUB_IP}');"
NEWDBPWD="define('DB_HOST', '${DB_HOST}');"
linechange 'DB_HOST' ${VH_DOC_ROOT}/wp-config.php "${NEWDBPWD}"
elif [ -f ${VH_DOC_ROOT}/wp-config.php ]; then
echo "${VH_DOC_ROOT}/wp-config.php already exist, exit !"
exit 1
else
echo 'Skip!'
exit 2
fi
}
app_wordpress_dl(){
if [ ! -f "${VH_DOC_ROOT}/wp-config.php" ] && [ ! -f "${VH_DOC_ROOT}/wp-config-sample.php" ]; then
wp core download \
--allow-root \
--quiet
else
echo 'wordpress already exist, abort!'
exit 1
fi
}
change_owner(){
if [ "${VHNAME}" != '' ]; then
chown -R ${WWW_UID}:${WWW_GID} ${DEFAULT_VH_ROOT}/${VHNAME}
else
chown -R ${WWW_UID}:${WWW_GID} ${DEFAULT_VH_ROOT}/${DOMAIN}
fi
}
main(){
set_vh_docroot ${DOMAIN}
get_owner
cd ${VH_DOC_ROOT}
if [ "${APP_NAME}" = 'wordpress' ] || [ "${APP_NAME}" = 'wp' ]; then
check_sql_native
app_wordpress_dl
preinstall_wordpress
install_wp_plugin
set_htaccess
get_theme_name
set_lscache
change_owner
exit 0
else
echo "APP: ${APP_NAME} not support, exit!"
exit 1
fi
}
check_input ${1}
while [ ! -z "${1}" ]; do
case ${1} in
-[hH] | -help | --help)
help_message
;;
-[aA] | -app | --app) shift
check_input "${1}"
APP_NAME="${1}"
;;
-[dD] | -domain | --domain) shift
check_input "${1}"
DOMAIN="${1}"
;;
-vhname | --vhname) shift
VHNAME="${1}"
;;
*)
help_message
;;
esac
shift
done
main

View File

@ -0,0 +1,18 @@
#!/bin/bash
BOTCRON='/var/spool/cron/crontabs/root'
cert_hook(){
grep 'acme' ${BOTCRON} >/dev/null
if [ ${?} = 0 ]; then
grep 'lswsctrl' ${BOTCRON} >/dev/null
if [ ${?} = 0 ]; then
echo 'Hook already exist, skip!'
else
sed -i 's/--cron/--cron --renew-hook "\/usr\/local\/lsws\/bin\/lswsctrl restart"/g' ${BOTCRON}
fi
else
echo "[X] ${BOTCRON} does not exist, please check it later!"
fi
}
cert_hook

View File

@ -0,0 +1,160 @@
#!/usr/bin/env bash
CK_RESULT=''
LSDIR='/usr/local/lsws'
LS_HTTPD_CONF="${LSDIR}/conf/httpd_config.xml"
OLS_HTTPD_CONF="${LSDIR}/conf/httpd_config.conf"
EPACE=' '
echow(){
FLAG=${1}
shift
echo -e "\033[1m${EPACE}${FLAG}\033[0m${@}"
}
help_message(){
echo -e "\033[1mOPTIONS\033[0m"
echow '-A, --add [DOMAIN_NAME]'
echo "${EPACE}${EPACE}Will add domain to listener and creat a virtual host from template"
echow '-D, --del [DOMAIN_NAME]'
echo "${EPACE}${EPACE}Will delete domain from listener"
echow '-H, --help'
echo "${EPACE}${EPACE}Display help."
}
check_lsv(){
if [ -f ${LSDIR}/bin/openlitespeed ]; then
LSV='openlitespeed'
elif [ -f ${LSDIR}/bin/litespeed ]; then
LSV='lsws'
else
echo 'Version not exist, abort!'
exit 1
fi
}
dot_escape(){
ESCAPE=$(echo ${1} | sed 's/\./\\./g')
}
check_duplicate(){
CK_RESULT=$(grep -E "${1}" ${2})
}
fst_match_line(){
FIRST_LINE_NUM=$(grep -n -m 1 ${1} ${2} | awk -F ':' '{print $1}')
}
fst_match_after(){
FIRST_NUM_AFTER=$(tail -n +${1} ${2} | grep -n -m 1 ${3} | awk -F ':' '{print $1}')
}
lst_match_line(){
fst_match_after ${1} ${2} ${3}
LAST_LINE_NUM=$((${FIRST_LINE_NUM}+${FIRST_NUM_AFTER}-1))
}
check_input(){
if [ -z "${1}" ]; then
help_message
exit 1
fi
}
check_www(){
CHECK_WWW=$(echo ${1} | cut -c1-4)
if [[ ${CHECK_WWW} == www. ]] ; then
echo 'www domain shoudnt be passed!'
exit 1
fi
}
www_domain(){
check_www ${1}
WWW_DOMAIN=$(echo www.${1})
}
add_ls_domain(){
fst_match_line 'docker.xml</templateFile>' ${LS_HTTPD_CONF}
NEWNUM=$((FIRST_LINE_NUM+2))
sed -i "${NEWNUM}i \ \ \ \ \ \ <member>\n \ \ \ \ \ \ \ <vhName>${DOMAIN}</vhName>\n \ \ \ \ \ \ \ <vhDomain>${DOMAIN},${WWW_DOMAIN}</vhDomain>\n \ \ \ \ \ \ </member>" ${LS_HTTPD_CONF}
}
add_ols_domain(){
perl -0777 -p -i -e 's/(vhTemplate docker \{[^}]+)\}*(^.*listeners.*$)/\1$2
member '${DOMAIN}' {
vhDomain '${DOMAIN},${WWW_DOMAIN}'
}/gmi' ${OLS_HTTPD_CONF}
}
add_domain(){
check_lsv
dot_escape ${1}
DOMAIN=${ESCAPE}
www_domain ${1}
if [ "${LSV}" = 'lsws' ]; then
check_duplicate "vhDomain.*${DOMAIN}" ${LS_HTTPD_CONF}
if [ "${CK_RESULT}" != '' ]; then
echo "# It appears the domain already exist! Check the ${LS_HTTPD_CONF} if you believe this is a mistake!"
exit 1
fi
elif [ "${LSV}" = 'openlitespeed' ]; then
check_duplicate "member.*${DOMAIN}" ${OLS_HTTPD_CONF}
if [ "${CK_RESULT}" != '' ]; then
echo "# It appears the domain already exist! Check the ${OLS_HTTPD_CONF} if you believe this is a mistake!"
exit 1
fi
fi
add_ls_domain
add_ols_domain
}
del_ls_domain(){
fst_match_line "<vhName>*${1}" ${LS_HTTPD_CONF}
FIRST_LINE_NUM=$((FIRST_LINE_NUM-1))
lst_match_line ${FIRST_LINE_NUM} ${LS_HTTPD_CONF} '</member>'
sed -i "${FIRST_LINE_NUM},${LAST_LINE_NUM}d" ${LS_HTTPD_CONF}
}
del_ols_domain(){
fst_match_line ${1} ${OLS_HTTPD_CONF}
lst_match_line ${FIRST_LINE_NUM} ${OLS_HTTPD_CONF} '}'
sed -i "${FIRST_LINE_NUM},${LAST_LINE_NUM}d" ${OLS_HTTPD_CONF}
}
del_domain(){
check_lsv
dot_escape ${1}
DOMAIN=${ESCAPE}
if [ "${LSV}" = 'lsws' ]; then
check_duplicate "vhDomain.*${DOMAIN}" ${LS_HTTPD_CONF}
if [ "${CK_RESULT}" = '' ]; then
echo "# Domain non-exist! Check the ${LS_HTTPD_CONF} if you believe this is a mistake!"
exit 1
fi
elif [ "${LSV}" = 'openlitespeed' ]; then
check_duplicate "member.*${DOMAIN}" ${OLS_HTTPD_CONF}
if [ "${CK_RESULT}" = '' ]; then
echo "# Domain non-exist! Check the ${OLS_HTTPD_CONF} if you believe this is a mistake!"
exit 1
fi
fi
del_ls_domain ${1}
del_ols_domain ${1}
}
check_input ${1}
while [ ! -z "${1}" ]; do
case ${1} in
-[hH] | -help | --help)
help_message
;;
-[aA] | -add | --add) shift
add_domain ${1}
;;
-[dD] | -del | --del | --delete) shift
del_domain ${1}
;;
*)
help_message
;;
esac
shift
done

View File

@ -0,0 +1,236 @@
#!/bin/bash
LSDIR='/usr/local/lsws'
OWASP_DIR="${LSDIR}/conf/owasp"
RULE_FILE='modsec_includes.conf'
LS_HTTPD_CONF="${LSDIR}/conf/httpd_config.xml"
OLS_HTTPD_CONF="${LSDIR}/conf/httpd_config.conf"
EPACE=' '
OWASP_V='3.3.4'
echow(){
FLAG=${1}
shift
echo -e "\033[1m${EPACE}${FLAG}\033[0m${@}"
}
help_message(){
echo -e "\033[1mOPTIONS\033[0m"
echow '-E, --enable'
echo "${EPACE}${EPACE}Will Enable mod_secure module with latest OWASP version of rules"
echow '-D, --disable'
echo "${EPACE}${EPACE}Will Disable mod_secure module with latest OWASP version of rules"
echow '-H, --help'
echo "${EPACE}${EPACE}Display help and exit."
exit 0
}
check_lsv(){
if [ -f ${LSDIR}/bin/openlitespeed ]; then
LSV='openlitespeed'
elif [ -f ${LSDIR}/bin/litespeed ]; then
LSV='lsws'
else
echo 'Version not exist, abort!'
exit 1
fi
}
check_input(){
if [ -z "${1}" ]; then
help_message
exit 1
fi
}
mk_owasp_dir(){
if [ -d ${OWASP_DIR} ] ; then
rm -rf ${OWASP_DIR}
fi
mkdir -p ${OWASP_DIR}
if [ ${?} -ne 0 ] ; then
echo "Unable to create directory: ${OWASP_DIR}, exit!"
exit 1
fi
}
fst_match_line(){
FIRST_LINE_NUM=$(grep -n -m 1 "${1}" ${2} | awk -F ':' '{print $1}')
}
fst_match_after(){
FIRST_NUM_AFTER=$(tail -n +${1} ${2} | grep -n -m 1 ${3} | awk -F ':' '{print $1}')
}
lst_match_line(){
fst_match_after ${1} ${2} ${3}
LAST_LINE_NUM=$((${FIRST_LINE_NUM}+${FIRST_NUM_AFTER}-1))
}
enable_ols_modsec(){
grep 'module mod_security {' ${OLS_HTTPD_CONF} >/dev/null 2>&1
if [ ${?} -eq 0 ] ; then
echo "Already configured for modsecurity."
else
echo 'Enable modsecurity'
sed -i "s=module cache=module mod_security {\nmodsecurity on\
\nmodsecurity_rules \`\nSecRuleEngine On\n\`\nmodsecurity_rules_file \
${OWASP_DIR}/${RULE_FILE}\n ls_enabled 1\n}\
\n\nmodule cache=" ${OLS_HTTPD_CONF}
fi
}
enable_ls_modsec(){
grep '<enableCensorship>1</enableCensorship>' ${LS_HTTPD_CONF} >/dev/null 2>&1
if [ ${?} -eq 0 ] ; then
echo "LSWS already configured for modsecurity"
else
echo 'Enable modsecurity'
sed -i \
"s=<enableCensorship>0</enableCensorship>=<enableCensorship>1</enableCensorship>=" ${LS_HTTPD_CONF}
sed -i \
"s=</censorshipControl>=</censorshipControl>\n\
<censorshipRuleSet>\n\
<name>ModSec</name>\n\
<enabled>1</enabled>\n\
<ruleSet>include ${OWASP_DIR}/modsec_includes.conf</ruleSet>\n\
</censorshipRuleSet>=" ${LS_HTTPD_CONF}
fi
}
enable_modsec(){
if [ "${LSV}" = 'lsws' ]; then
enable_ls_modsec
elif [ "${LSV}" = 'openlitespeed' ]; then
enable_ols_modsec
fi
}
disable_ols_modesec(){
grep 'module mod_security {' ${OLS_HTTPD_CONF} >/dev/null 2>&1
if [ ${?} -eq 0 ] ; then
echo 'Disable modsecurity'
fst_match_line 'module mod_security' ${OLS_HTTPD_CONF}
lst_match_line ${FIRST_LINE_NUM} ${OLS_HTTPD_CONF} '}'
sed -i "${FIRST_LINE_NUM},${LAST_LINE_NUM}d" ${OLS_HTTPD_CONF}
else
echo 'Already disabled for modsecurity'
fi
}
disable_ls_modesec(){
grep '<enableCensorship>0</enableCensorship>' ${LS_HTTPD_CONF}
if [ ${?} -eq 0 ] ; then
echo 'Already disabled for modsecurity'
else
echo 'Disable modsecurity'
sed -i \
"s=<enableCensorship>1</enableCensorship>=<enableCensorship>0</enableCensorship>=" ${LS_HTTPD_CONF}
fst_match_line 'censorshipRuleSet' ${LS_HTTPD_CONF}
lst_match_line ${FIRST_LINE_NUM} ${LS_HTTPD_CONF} '/censorshipRuleSet'
sed -i "${FIRST_LINE_NUM},${LAST_LINE_NUM}d" ${LS_HTTPD_CONF}
fi
}
disable_modsec(){
check_lsv
if [ "${LSV}" = 'lsws' ]; then
disable_ls_modesec
elif [ "${LSV}" = 'openlitespeed' ]; then
disable_ols_modesec
fi
}
install_unzip(){
if [ ! -f /usr/bin/unzip ]; then
echo 'Install Unzip'
apt update >/dev/null 2>&1
apt-get install unzip -y >/dev/null 2>&1
fi
}
install_owasp(){
cd ${OWASP_DIR}
echo 'Download OWASP rules'
wget -q https://github.com/coreruleset/coreruleset/archive/refs/tags/v${OWASP_V}.zip
unzip -qq v${OWASP_V}.zip
rm -f v${OWASP_V}.zip
mv coreruleset-* owasp-modsecurity-crs
}
configure_owasp(){
echo 'Config OWASP rules.'
cd ${OWASP_DIR}
echo "include modsecurity.conf
include owasp-modsecurity-crs/crs-setup.conf
include owasp-modsecurity-crs/rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf
include owasp-modsecurity-crs/rules/REQUEST-901-INITIALIZATION.conf
include owasp-modsecurity-crs/rules/REQUEST-903.9001-DRUPAL-EXCLUSION-RULES.conf
include owasp-modsecurity-crs/rules/REQUEST-903.9002-WORDPRESS-EXCLUSION-RULES.conf
include owasp-modsecurity-crs/rules/REQUEST-903.9003-NEXTCLOUD-EXCLUSION-RULES.conf
include owasp-modsecurity-crs/rules/REQUEST-903.9004-DOKUWIKI-EXCLUSION-RULES.conf
include owasp-modsecurity-crs/rules/REQUEST-903.9005-CPANEL-EXCLUSION-RULES.conf
include owasp-modsecurity-crs/rules/REQUEST-903.9006-XENFORO-EXCLUSION-RULES.conf
include owasp-modsecurity-crs/rules/REQUEST-905-COMMON-EXCEPTIONS.conf
include owasp-modsecurity-crs/rules/REQUEST-910-IP-REPUTATION.conf
include owasp-modsecurity-crs/rules/REQUEST-911-METHOD-ENFORCEMENT.conf
include owasp-modsecurity-crs/rules/REQUEST-912-DOS-PROTECTION.conf
include owasp-modsecurity-crs/rules/REQUEST-913-SCANNER-DETECTION.conf
include owasp-modsecurity-crs/rules/REQUEST-920-PROTOCOL-ENFORCEMENT.conf
include owasp-modsecurity-crs/rules/REQUEST-921-PROTOCOL-ATTACK.conf
include owasp-modsecurity-crs/rules/REQUEST-930-APPLICATION-ATTACK-LFI.conf
include owasp-modsecurity-crs/rules/REQUEST-931-APPLICATION-ATTACK-RFI.conf
include owasp-modsecurity-crs/rules/REQUEST-932-APPLICATION-ATTACK-RCE.conf
include owasp-modsecurity-crs/rules/REQUEST-933-APPLICATION-ATTACK-PHP.conf
include owasp-modsecurity-crs/rules/REQUEST-934-APPLICATION-ATTACK-NODEJS.conf
include owasp-modsecurity-crs/rules/REQUEST-941-APPLICATION-ATTACK-XSS.conf
include owasp-modsecurity-crs/rules/REQUEST-942-APPLICATION-ATTACK-SQLI.conf
include owasp-modsecurity-crs/rules/REQUEST-943-APPLICATION-ATTACK-SESSION-FIXATION.conf
include owasp-modsecurity-crs/rules/REQUEST-944-APPLICATION-ATTACK-JAVA.conf
include owasp-modsecurity-crs/rules/REQUEST-949-BLOCKING-EVALUATION.conf
include owasp-modsecurity-crs/rules/RESPONSE-950-DATA-LEAKAGES.conf
include owasp-modsecurity-crs/rules/RESPONSE-951-DATA-LEAKAGES-SQL.conf
include owasp-modsecurity-crs/rules/RESPONSE-952-DATA-LEAKAGES-JAVA.conf
include owasp-modsecurity-crs/rules/RESPONSE-953-DATA-LEAKAGES-PHP.conf
include owasp-modsecurity-crs/rules/RESPONSE-954-DATA-LEAKAGES-IIS.conf
include owasp-modsecurity-crs/rules/RESPONSE-959-BLOCKING-EVALUATION.conf
include owasp-modsecurity-crs/rules/RESPONSE-980-CORRELATION.conf
include owasp-modsecurity-crs/rules/RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf">modsec_includes.conf
echo "SecRuleEngine On">modsecurity.conf
cd ${OWASP_DIR}/owasp-modsecurity-crs
if [ -f crs-setup.conf.example ]; then
mv crs-setup.conf.example crs-setup.conf
fi
cd ${OWASP_DIR}/owasp-modsecurity-crs/rules
if [ -f REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf.example ]; then
mv REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf.example REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf
fi
if [ -f RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf.example ]; then
mv RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf.example RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf
fi
}
main_owasp(){
mk_owasp_dir
install_unzip
install_owasp
configure_owasp
check_lsv
enable_modsec
}
check_input ${1}
while [ ! -z "${1}" ]; do
case ${1} in
-[hH] | -help | --help)
help_message
;;
-[eE] | -enable | --enable)
main_owasp
;;
-[dD] | -disable | --disable)
disable_modsec
;;
*)
help_message
;;
esac
shift
done

View File

@ -0,0 +1,84 @@
#!/bin/bash
LSDIR='/usr/local/lsws'
EPACE=' '
echow(){
FLAG=${1}
shift
echo -e "\033[1m${EPACE}${FLAG}\033[0m${@}"
}
help_message(){
echo -e "\033[1mOPTIONS\033[0m"
echow '-S, --serial [YOUR_SERIAL|TRIAL]'
echo "${EPACE}${EPACE}Will apply and register the serial to LSWS."
echow '-H, --help'
echo "${EPACE}${EPACE}Display help and exit."
exit 0
}
check_input(){
if [ -z "${1}" ]; then
help_message
exit 1
fi
}
backup_old(){
if [ -f ${1} ] && [ ! -f ${1}_old ]; then
mv ${1} ${1}_old
fi
}
detect_ols(){
if [ -e ${LSDIR}/bin/openlitespeed ]; then
echo '[X] Detect OpenLiteSpeed, abort!'
exit 1
fi
}
apply_serial(){
detect_ols
check_input ${1}
echo ${1} | grep -i 'trial' >/dev/null
if [ ${?} = 0 ]; then
echo 'Apply Trial License'
if [ ! -e ${LSDIR}/conf/serial.no ] && [ ! -e ${LSDIR}/conf/license.key ]; then
rm -f ${LSDIR}/conf/trial.key*
wget -P ${LSDIR}/conf -q http://license.litespeedtech.com/reseller/trial.key
echo 'Apply trial finished'
else
echo "Please backup and remove your existing license, apply abort!"
exit 1
fi
else
echo "Apply Serial number: ${1}"
backup_old ${LSDIR}/conf/serial.no
backup_old ${LSDIR}/conf/license.key
backup_old ${LSDIR}/conf/trial.key
echo "${1}" > ${LSDIR}/conf/serial.no
${LSDIR}/bin/lshttpd -r
if [ -f ${LSDIR}/conf/license.key ]; then
echo '[O] Apply success'
else
echo '[X] Apply failed, please check!'
exit 1
fi
fi
}
check_input ${1}
while [ ! -z "${1}" ]; do
case ${1} in
-[hH] | -help | --help)
help_message
;;
-[sS] | -serial | --serial) shift
apply_serial "${1}"
;;
*)
help_message
;;
esac
shift
done

View File

@ -0,0 +1,158 @@
#!/usr/bin/env bash
source .env
DOMAIN=''
SQL_DB=''
SQL_USER=''
SQL_PASS=''
ANY="'%'"
SET_OK=0
EPACE=' '
echow(){
FLAG=${1}
shift
echo -e "\033[1m${EPACE}${FLAG}\033[0m${@}"
}
help_message(){
echo -e "\033[1mOPTIONS\033[0m"
echow '-D, --domain [DOMAIN_NAME]'
echo "${EPACE}${EPACE}Example: database.sh -D example.com"
echo "${EPACE}${EPACE}Will auto generate Database/username/password for the domain"
echow '-D, --domain [DOMAIN_NAME] -U, --user [xxx] -P, --password [xxx] -DB, --database [xxx]'
echo "${EPACE}${EPACE}Example: database.sh -D example.com -U USERNAME -P PASSWORD -DB DATABASENAME"
echo "${EPACE}${EPACE}Will create Database/username/password by given"
echow '-H, --help'
echo "${EPACE}${EPACE}Display help and exit."
exit 0
}
check_input(){
if [ -z "${1}" ]; then
help_message
exit 1
fi
}
specify_name(){
check_input ${SQL_USER}
check_input ${SQL_PASS}
check_input ${SQL_DB}
}
auto_name(){
SQL_DB="${TRANSNAME}"
SQL_USER="${TRANSNAME}"
SQL_PASS="'${RANDOM_PASS}'"
}
gen_pass(){
RANDOM_PASS="$(openssl rand -base64 12)"
}
trans_name(){
TRANSNAME=$(echo ${1} | tr -d '.&&-')
}
display_credential(){
if [ ${SET_OK} = 0 ]; then
echo "Database: ${SQL_DB}"
echo "Username: ${SQL_USER}"
echo "Password: $(echo ${SQL_PASS} | tr -d "'")"
fi
}
store_credential(){
if [ -d "./sites/${1}" ]; then
if [ -f ./sites/${1}/.db_pass ]; then
mv ./sites/${1}/.db_pass ./sites/${1}/.db_pass.bk
fi
cat > "./sites/${1}/.db_pass" << EOT
"Database":"${SQL_DB}"
"Username":"${SQL_USER}"
"Password":"$(echo ${SQL_PASS} | tr -d "'")"
EOT
else
echo "./sites/${1} not found, abort credential store!"
fi
}
check_db_access(){
docker compose exec -T mysql su -c "mysql -uroot -p${MYSQL_ROOT_PASSWORD} -e 'status'" >/dev/null 2>&1
if [ ${?} != 0 ]; then
echo '[X] DB access failed, please check!'
exit 1
fi
}
check_db_exist(){
docker compose exec -T mysql su -c "test -e /var/lib/mysql/${1}"
if [ ${?} = 0 ]; then
echo "Database ${1} already exist, skip DB creation!"
exit 0
fi
}
db_setup(){
docker compose exec -T mysql su -c 'mysql -uroot -p${MYSQL_ROOT_PASSWORD} \
-e "CREATE DATABASE '${SQL_DB}';" \
-e "GRANT ALL PRIVILEGES ON '${SQL_DB}'.* TO '${SQL_USER}'@'${ANY}' IDENTIFIED BY '${SQL_PASS}';" \
-e "FLUSH PRIVILEGES;"'
SET_OK=${?}
}
auto_setup_main(){
check_input ${DOMAIN}
gen_pass
trans_name ${DOMAIN}
auto_name
check_db_exist ${SQL_DB}
check_db_access
db_setup
display_credential
store_credential ${DOMAIN}
}
specify_setup_main(){
specify_name
check_db_exist ${SQL_DB}
check_db_access
db_setup
display_credential
store_credential ${DOMAIN}
}
main(){
if [ "${SQL_USER}" != '' ] && [ "${SQL_PASS}" != '' ] && [ "${SQL_DB}" != '' ]; then
specify_setup_main
else
auto_setup_main
fi
}
check_input ${1}
while [ ! -z "${1}" ]; do
case ${1} in
-[hH] | -help | --help)
help_message
;;
-[dD] | -domain| --domain) shift
DOMAIN="${1}"
;;
-[uU] | -user | --user) shift
SQL_USER="${1}"
;;
-[pP] | -password| --password) shift
SQL_PASS="'${1}'"
;;
-db | -DB | -database| --database) shift
SQL_DB="${1}"
;;
*)
help_message
;;
esac
shift
done
main

View File

@ -0,0 +1,102 @@
#!/usr/bin/env bash
source .env
APP_NAME='wordpress'
CONT_NAME='litespeed'
DOC_FD=''
echow(){
FLAG=${1}
shift
echo -e "\033[1m${EPACE}${FLAG}\033[0m${@}"
}
help_message(){
case ${1} in
"1")
echow "Script will get 'DOMAIN' and 'database' info from .env file, then auto setup virtual host and the wordpress site for you."
exit 0
;;
"2")
echow 'Service finished, enjoy your accelarated LiteSpeed server!'
;;
esac
}
domain_filter(){
if [ ! -n "${DOMAIN}" ]; then
echo "Parameters not supplied, please check!"
exit 1
fi
DOMAIN="${1}"
DOMAIN="${DOMAIN#http://}"
DOMAIN="${DOMAIN#https://}"
DOMAIN="${DOMAIN#ftp://}"
DOMAIN="${DOMAIN#scp://}"
DOMAIN="${DOMAIN#scp://}"
DOMAIN="${DOMAIN#sftp://}"
DOMAIN=${DOMAIN%%/*}
}
gen_root_fd(){
DOC_FD="./sites/${1}/"
if [ -d "./sites/${1}" ]; then
echo -e "[O] The root folder \033[32m${DOC_FD}\033[0m exist."
else
echo "Creating - document root."
bash bin/domain.sh -add ${1}
echo "Finished - document root."
fi
}
create_db(){
if [ ! -n "${MYSQL_DATABASE}" ] || [ ! -n "${MYSQL_USER}" ] || [ ! -n "${MYSQL_PASSWORD}" ]; then
echo "Parameters not supplied, please check!"
exit 1
else
bash bin/database.sh -D ${1} -U ${MYSQL_USER} -P ${MYSQL_PASSWORD} -DB ${MYSQL_DATABASE}
fi
}
store_credential(){
if [ -f ${DOC_FD}/.db_pass ]; then
echo '[O] db file exist!'
else
echo 'Storing database parameter'
cat > "${DOC_FD}/.db_pass" << EOT
"Database":"${MYSQL_DATABASE}"
"Username":"${MYSQL_USER}"
"Password":"$(echo ${MYSQL_PASSWORD} | tr -d "'")"
EOT
fi
}
app_download(){
docker compose exec -T ${CONT_NAME} su -c "appinstallctl.sh --app ${1} --domain ${2}"
}
lsws_restart(){
bash bin/webadmin.sh -r
}
main(){
domain_filter ${DOMAIN}
gen_root_fd ${DOMAIN}
create_db ${DOMAIN}
store_credential
app_download ${APP_NAME} ${DOMAIN}
lsws_restart
help_message 2
}
while [ ! -z "${1}" ]; do
case ${1} in
-[hH] | -help | --help)
help_message 1
;;
*)
help_message 1
;;
esac
shift
done
main

View File

@ -0,0 +1,2 @@
#!/usr/bin/env bash
git ls-files -v|grep '^S'

View File

@ -0,0 +1,2 @@
#!/usr/bin/env bash
find conf -maxdepth 1 -type d \( ! -name . \) -exec bash -c "cd '{}' && pwd && git ls-files -z ${pwd} | xargs -0 git update-index --no-skip-worktree" \;

View File

@ -0,0 +1,3 @@
#!/usr/bin/env bash
find conf -maxdepth 1 -type d \( ! -name . \) -exec bash -c "cd '{}' && pwd && git ls-files -z ${pwd} | xargs -0 git update-index --skip-worktree" \;

View File

@ -0,0 +1,61 @@
#!/usr/bin/env bash
CONT_NAME='litespeed'
EPACE=' '
echow(){
FLAG=${1}
shift
echo -e "\033[1m${EPACE}${FLAG}\033[0m${@}"
}
help_message(){
echo -e "\033[1mOPTIONS\033[0m"
echow "-A, --add [domain_name]"
echo "${EPACE}${EPACE}Example: domain.sh -A example.com, will add the domain to Listener and auto create a new virtual host."
echow "-D, --del [domain_name]"
echo "${EPACE}${EPACE}Example: domain.sh -D example.com, will delete the domain from Listener."
echow '-H, --help'
echo "${EPACE}${EPACE}Display help and exit."
}
check_input(){
if [ -z "${1}" ]; then
help_message
exit 1
fi
}
add_domain(){
check_input ${1}
docker compose exec ${CONT_NAME} su -s /bin/bash lsadm -c "cd /usr/local/lsws/conf && domainctl.sh --add ${1}"
if [ ! -d "./sites/${1}" ]; then
mkdir -p ./sites/${1}/{html,logs,certs}
fi
bash bin/webadmin.sh -r
}
del_domain(){
check_input ${1}
docker compose exec ${CONT_NAME} su -s /bin/bash lsadm -c "cd /usr/local/lsws/conf && domainctl.sh --del ${1}"
bash bin/webadmin.sh -r
}
check_input ${1}
while [ ! -z "${1}" ]; do
case ${1} in
-[hH] | -help | --help)
help_message
;;
-[aA] | -add | --add) shift
add_domain ${1}
;;
-[dD] | -del | --del | --delete) shift
del_domain ${1}
;;
*)
help_message
;;
esac
shift
done

View File

@ -0,0 +1,98 @@
#!/usr/bin/env bash
CONT_NAME='litespeed'
EPACE=' '
echow(){
FLAG=${1}
shift
echo -e "\033[1m${EPACE}${FLAG}\033[0m${@}"
}
help_message(){
echo -e "\033[1mOPTIONS\033[0m"
echow '[Enter Your PASSWORD]'
echo "${EPACE}${EPACE}Example: webadmin.sh MY_SECURE_PASS, to update web admin password immediatly."
echow '-R, --restart'
echo "${EPACE}${EPACE}Will gracefully restart LiteSpeed Web Server."
echow '-M, --mod-secure [enable|disable]'
echo "${EPACE}${EPACE}Example: webadmin.sh -M enable, will enable and apply Mod_Secure OWASP rules on server"
echow '-U, --upgrade'
echo "${EPACE}${EPACE}Will upgrade web server to latest stable version"
echow '-S, --serial [YOUR_SERIAL|TRIAL]'
echo "${EPACE}${EPACE}Will apply your serial number to LiteSpeed Web Server."
echow '-H, --help'
echo "${EPACE}${EPACE}Display help and exit."
exit 0
}
check_input(){
if [ -z "${1}" ]; then
help_message
exit 1
fi
}
lsws_restart(){
docker compose exec -T ${CONT_NAME} su -c '/usr/local/lsws/bin/lswsctrl restart >/dev/null'
}
apply_serial(){
docker compose exec ${CONT_NAME} su -c "serialctl.sh --serial ${1}"
lsws_restart
}
mod_secure(){
if [ "${1}" = 'enable' ] || [ "${1}" = 'Enable' ]; then
docker compose exec ${CONT_NAME} su -s /bin/bash root -c "owaspctl.sh --enable"
lsws_restart
elif [ "${1}" = 'disable' ] || [ "${1}" = 'Disable' ]; then
docker compose exec ${CONT_NAME} su -s /bin/bash root -c "owaspctl.sh --disable"
lsws_restart
else
help_message
fi
}
ls_upgrade(){
echo 'Upgrade web server to latest stable version.'
docker compose exec ${CONT_NAME} su -c '/usr/local/lsws/admin/misc/lsup.sh 2>/dev/null'
}
set_web_admin(){
echo 'Update web admin password.'
local LSADPATH='/usr/local/lsws/admin'
docker compose exec ${CONT_NAME} su -s /bin/bash lsadm -c \
'if [ -e /usr/local/lsws/admin/fcgi-bin/admin_php ]; then \
echo "admin:$('${LSADPATH}'/fcgi-bin/admin_php -q '${LSADPATH}'/misc/htpasswd.php '${1}')" > '${LSADPATH}'/conf/htpasswd; \
else echo "admin:$('${LSADPATH}'/fcgi-bin/admin_php5 -q '${LSADPATH}'/misc/htpasswd.php '${1}')" > '${LSADPATH}'/conf/htpasswd; \
fi';
}
main(){
set_web_admin ${1}
}
check_input ${1}
while [ ! -z "${1}" ]; do
case ${1} in
-[hH] | -help | --help)
help_message
;;
-[rR] | -restart | --restart)
lsws_restart
;;
-M | -mode-secure | --mod-secure) shift
mod_secure ${1}
;;
-lsup | --lsup | --upgrade | -U) shift
ls_upgrade
;;
-[sS] | -serial | --serial) shift
apply_serial ${1}
;;
*)
main ${1}
;;
esac
shift
done

View File

@ -0,0 +1,2 @@
*
!.gitignore

View File

@ -0,0 +1,30 @@
version: '3'
services:
litespeed:
container_name: ${CONTAINER_NAME}
restart: always
networks:
- 1panel-network
logging:
driver: none
volumes:
- ${DATA_PATH}/lsws/conf:/usr/local/lsws/conf
- ${DATA_PATH}/lsws/admin-conf:/usr/local/lsws/admin/conf
- ${DATA_PATH}/bin/container:/usr/local/bin
- ${DATA_PATH}/sites:/var/www/vhosts/
- ${DATA_PATH}/acme:/root/.acme.sh/
- ${DATA_PATH}/logs:/usr/local/lsws/logs/
ports:
- "${PANEL_APP_PORT_HTTP}:80"
- "${PANEL_APP_PORT_HTTPS}:443"
- "${PANEL_APP_PORT_HTTPS}:443/udp"
- "${PANEL_APP_PORT_CONSOLE}:7080"
environment:
- TZ=${TIME_ZONE}
image: litespeedtech/openlitespeed:latest
labels:
createdBy: "Apps"
networks:
1panel-network:
external: true

BIN
apps/openlitespeed/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 MiB

After

Width:  |  Height:  |  Size: 1.8 MiB

View File

@ -1,2 +0,0 @@
[ZoneTransfer]
ZoneId=3