IcddlZddlZddlZddlmZddlmZddlmZddl m Z m Z ddl m Z ddlmZmZddlmZdd lmZmZmZmZdd lmZmZmZmZmZmZdd lm Z d Z!d Z"edZ#dZ$dZ%ej&e'Z(Gddej)Z*dZ+dZ,GddeZ-GddeZ.GddeZ/GddeZ0dS)N)suppress)Version)Path)DictOptional)urlparse) ConfigFileCore)base) OsReleaseInfoasync_lru_cacheatomic_rewrite check_run)MODSEC_NAME_TEMPLATE FilesVendorFilesVendorListModSecSettingInterfaceModSecurityInterfaceskip_if_not_installed_modsec)graceful_restartz*/usr/local/psa/admin/sbin/modsecurity_ctl z/usr/local/psa/bin/server_pref z/usr/local/psa/bin/server_prefz"/usr/local/psa/admin/bin/httpdmng customceZdZdS)PleskModSecExceptionN)__name__ __module__ __qualname__[/opt/imunify360/venv/lib/python3.11/site-packages/im360/subsys/panels/plesk/mod_security.pyrr'sDrrcKtd|t|td{V}|S)NzRunning CMD: %s raise_exc)loggerdebugrsplitrdecodestrip)cmddatas rrun_cmdr*+sb LL"C(((399;;2FGGG G G G G G GD ;;==    rcKddlm}t|d{VtdkS)NrPleskz17.5)#defence360agent.subsys.panels.pleskr-rversionr,s rplesk_supports_custom_vendorsr01sK999999 (((((( ) )WV__ <z6ModSecSettings.waf_rule_engine_mode..Ls.HHDD4G,G,G4,G,G,G,GHHr)r* SERV_PERFiter splitlinesnext)clsrvstatusr)s @rwaf_rule_engine_modez#ModSecSettings.waf_rule_engine_modeGs~Y)BBCCCCCCCCDOO%%&& HHHHDHHH$ O O&R rcd} t|j5}|}dddn #1swxYwYn#t$rYnwxYw|S)N)openUSER_MODSEC_CONF_REDHATreadOSError)r>contentfs r_read_custom_confz ModSecSettings._read_custom_confPs c122 #a&&(( # # # # # # # # # # # # # # #    D s.A9 A=A=A AAc|}|j|vr)|d|jzdzz }t|j|ddSdS)N Fbackup)rJI360_INCLUDE_REDHATrrEr>rHs r_include_modsec_conf_redhatz*ModSecSettings._include_modsec_conf_redhatZs^''))  "' 1 1 tc55< s r_include_modsec_conf_debianz*ModSecSettings._include_modsec_conf_debianasU  J+3         DD s # 11ctjtjzr|dS|dSrS)r id_likeDEBIANrZrQrYs rinclude_modsec_confz"ModSecSettings.include_modsec_confkK  " "]%9 9 .  + + - - - - -  + + - - - - -rc|}|j|vr4||jd}t|j|ddSdS)NrCFrM)rJrOreplacerrErPs r_revert_conf_include_redhatz*ModSecSettings._revert_conf_include_redhatrs]''))  "g - -ooc&=rBBG 36 N N N N N N . -rc|jtfD]B}tt5t j|dddn #1swxYwYCdSrS)rWPleskModSecurityconf_disable_global_symlinkrFileNotFoundErrorrTunlink)r>confs r_revert_conf_include_debianz*ModSecSettings._revert_conf_include_debianys  /  8 8 : :   D+,,   $                 sAA A ctjtjzr|dS|dSrS)r r\r]rirbrYs rrevert_conf_includez"ModSecSettings.revert_conf_includer_rcK||d{Vx}}|dkr|Sd}td{Vrtt|zd{V|S|dz }tt|zd{Vtt dzd{Vtt dzd{V|S)Noffz. --update-web-app-firewall -waf-rule-engine onz -waf-rule-set crsz!--disable-all-rules --ruleset crsz--uninstall --ruleset crs)r^rAr0r*r: MODSEC_API)r> prev_valuer@ waf_options rapplyzModSecSettings.applys$ !!!$'$<$<$>$>>>>>>>> V U??ME .00 0 0 0 0 0 0 )j011 1 1 1 1 1 1 1  ** i*,---------j#FFGGGGGGGGGj#>>?????????rrocK||r2ttd|zd{VdSdS)Nz---update-web-app-firewall -waf-rule-engine {})rkr*r:format)r>ros rrevertzModSecSettings.reverts !!!  AHH           rcdS)NTrrYs r is_enabledzModSecSettings.is_enabledstrN)rrrrErOrVrW config_key classmethodrArJrQrZr^rbrirkrqstrrtrvrrrr2r28srML: ?$!J[[OO[O [..[. OO[O   [ ..[. [0c[[rr2ceZdZdZdZdZdZedefdZ edZ edZ ed e ee ffd Zedefd Zedefd Zed ZedZedZejd$dZd%dZdZdZejd$dZedZeeddZedZeedde e!fdZ"edeffd Z#eeddZ$ede ed ede%fd!Z&ed"Z'ee(d#Z)xZ*S)&rdz/var/log/modsec_audit.logz/usr/local/cwafz//var/www/vhosts/system/{domain}/conf/siteapp.d/z"zz999-i360-app-based-excludes.confreturncJtjtjzrdSdS)Nz/etc/apache2/conf-enabledz/etc/httpd/conf.d/r r\r]rYs r _get_conf_dirzPleskModSecurity._get_conf_dirs'  " "]%9 9 /..##rcJtjtjzrdSdS)Nz/etc/apache2/plesk.conf.dz/etc/httpd/conf/plesk.conf.dr}rYs r_get_global_include_dirz(PleskModSecurity._get_global_include_dirs'  " "]%9 9 2..11rcftj|dS)Nz"zz999_modsec2.imunify_disable.conf)rTpathjoinr~rYs rrez,PleskModSecurity.conf_disable_global_symlinks,w||     !E   rdomain_rules_mapcK|D]\}}|j|}tj|dt tj|d||dttd|zd{VdS)N)domainTexist_oki360_modsec_disable.confFrMz0--reconfigure-domain {} -skip-broken -no-restart) itemsDOMAIN_INCLUDE_DIR_TMLrsrTmakedirsrrrgenerate_disabled_rules_configr*HTTPDMNG)r>rr rule_listconf_dirs rsync_disabled_rules_for_domainsz0PleskModSecurity.sync_disabled_rules_for_domainss"2!7!7!9!9   FI1888GGH K4 0 0 0 0  X'ABB229==     DKK          rctj|dttj|d||d} tjtj|d|n#t$rYnwxYw|S)z :param list rule_list: rule ids to sync :raise OSError: if httpd reconfigure returned not zero exit code :return: True if config was changed, False otherwise TrrFrM) rTrrrrrrrUrerX)r>rchangeds rwrite_global_disabled_rulesz,PleskModSecurity.write_global_disabled_ruless C//11DAAAA GLL++--/I    . .y 9 9      J //113M//11          D s?AC C$#C$c0K||S)z= just alias to write_global_disabled_rules() )r)r>rs rsync_global_disabled_rulesz+PleskModSecurity.sync_global_disabled_ruless ..y999rc|jSrS)AUDIT_LOG_FILErYs rget_audit_log_pathz#PleskModSecurity.get_audit_log_paths !!rcdS)Nz/var/log/apache2/modsec_auditrrYs rget_audit_logdir_pathz&PleskModSecurity.get_audit_logdir_paths..rcKtjtsdS t t dzd{VdS#t$rYdSwxYw)z6Check if all the panel utilities we use are available.Fr5NT)rTrisfilernrstripr*r:rrYs rinstalled_modsecz!PleskModSecurity.installed_modsecsw~~j//1122 5 )&??@@ @ @ @ @ @ @ @4$   55 sA A)(A)TcKt}|D]6}|d|j|d{V7t d{VdS)NMOD_SEC)r _get_avalible_settingssetrwrqrself reload_wafdconfigsettings r_install_settingsz"PleskModSecurity._install_settingss2244 M MG JJy'"4GMMOO6K6K6K6K6K6K L L L L           rNcKtrSNotImplementedError)rdirective_namedefaults rmodsec_get_directivez%PleskModSecurity.modsec_get_directive !!rcKtrSrrs rreset_modsec_directivesz(PleskModSecurity.reset_modsec_directivesrrcKtrSrrs rreset_modsec_rulesetsz&PleskModSecurity.reset_modsec_rulesets!rrcK|d{VstddSt}|D]R}||d|jd{V|d|jdStd{VdS)Nzr)s rmodsec_vendor_listz#PleskModSecurity.modsec_vendor_list;s~))++++++++ IZ*;;<<<<<<<<@@FFFFFFFFFrc,Kd|D}td{Vs|S|d{V}|rA |tn#t $rYnwxYw|||S)a On new plesk panels we have convert all 'custom' vendors from plesk api calls to real imunify-vendor names(ex. imunify360-full-apache) as on this panel 'custom' - is a fixed vendor name for 3rd party installed vendor. If we will find RELEASE file with real vendor name in vendor directory, it means it is imunify vendor, we will return this real name :param data: :return: vendor list, example: ['imunify360-full-apache', 'other-vendor'] cg|]}||Srr)r7vendors r zLPleskModSecurity._vendor_list_with_custom_vendor_removed..QsHHH&HvHHHrN)r<r0#get_modsec_vendor_from_release_fileremoveCUSTOM_VENDOR_NAME ValueErrorappend)r>r) vendor_listrs rrz8PleskModSecurity._vendor_list_with_custom_vendor_removedDsIHDOO,=,=HHH 244444444  >>@@@@@@@@  ' ""#56666       v & & &sA// A<;A<cKtd{Vr|ddd{V}n4||d{Vdd{V} |5}t j|}dddn #1swxYwY|S#t ttjf$rYdSwxYw)NRELEASE) r0build_vendor_file_pathget_i360_vendor_namerDjsonloadrGIOErrorJSONDecodeError)r>modsec_release_file release_f json_datas r_get_release_info_from_filez,PleskModSecurity._get_release_info_from_file_si/00 0 0 0 0 0 0 ),(B(Bi))######  ),(B(B..00000000)))######  $))++ 1y Ii00  1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 $"67   44 s6)B+=B B+B""B+%B"&B++C  C cK|d{V}|r|dr|dStd{VS)Nr/)rrsuperget_i360_vendor_version)r> release_dict __class__s rrz(PleskModSecurity.get_i360_vendor_versiontsz <<>>>>>>>>  +L,,Y77 + * *WW44666666666rcK|d{VsgSttdzd{V}||d{VS)z-Return a list of enabled ModSecurity vendors.Nz--list-rulesets --enabledrrs renabled_modsec_vendor_listz+PleskModSecurity.enabled_modsec_vendor_list{s~))++++++++ IZ*EEFFFFFFFF@@FFFFFFFFFrrfilenamecdKttdzd{V}td{Vs|std|}nU|rL|t js-td|t jt}t||z |z S)z :param vendor: vendor directory: old plesk panels - imunify360-*; new plesk panels - imunify360-* or None - we will look into custom directory anyway :param filename: :return: z--rules-base-dirNz2Vendor directory can't be None on old plesk panelszHVendor directory {} should be None or starts with {} on new plesk panels) r*rnr0r startswithr PRODUCTrsrr)r>rr rule_base_dir vendor_dirs rrz'PleskModSecurity.build_vendor_file_paths&j3E&EFFFFFFFF 244444444 ,  H JJ f// ==  #VFDL99 ,JM""Z/(::rcttgSrS)r2PleskFilesVendorListrYs rrz'PleskModSecurity._get_avalible_settingss 455rc|K|d{Vtd{VdSrS)"invalidate_installed_vendors_cacherinstall_or_updaterYs r_apply_modsec_files_updatez+PleskModSecurity._apply_modsec_files_updatesV44666666666"4466666666666r)TrS)+rrrrrrAPP_BASED_EXCLUDE_CONF_NAMErxryr~rrerlistrboolrrrrrr ensure_valid_panelrrrrrrr rrrdictrrrrrrrr __classcell__)rs@rrdrds}0N-N"F$c$$$[$ 22[2   [ #CI[$t[4:D:::[: ""["//[/  [ T!!!! """"""""""T ! ! ! !99[9_QGG [G[4_Q(4. [&7c77777[7 _QGG [G;c];.1; ;;;[;:66[6!77"![77777rrdceZdZeZejej dZ dZ dZ dZ dZdefdZdZd Zd Zd Zd S) PleskFilesVendorzi360_modsec_vendor.zipcrK|d{V|d{VdSrS)_remove_obsoleted_add_or_update_vendorrs rrqzPleskFilesVendor.applysT$$&&&&&&&&&((***********rcK|d{Vr<|d{Vtd|jdSdS)z Removes and disables ModSecurity vendor + on new plesk also we will always delete "custom" ruleset in all cases NzSuccessfully removed vendor %r.) _is_installed_remove_vendorr#info vendor_idrs rrtzPleskFilesVendor.reverts| ##%% % % % % % % K%%'' ' ' ' ' ' ' ' KK94> J J J J J K Krc.Kt|jd{V}t|jdg}||zD]8}t d|||d{V9dS)N obsoleteszRemoving obsoleted vendor %r)rmodsec_interfacer_itemrr#r_remove_vendor_by_id)renabled_vendors obsoletedrs rrz"PleskFilesVendor._remove_obsoleteds'BBDD D D D D D D   {B7788 % 1 4 4F KK6 ? ? ?++F33 3 3 3 3 3 3 3 3 4 4rcK|jd{V}|d{V|j|vr"td|jdStd|jdS)NzSuccessfully updated vendor %r.z!Successfully installed vendor %r.)rr _add_vendorrr#r)rinstalled_vendorss rrz&PleskFilesVendor._add_or_update_vendors'BBDD D D D D D D          >. . . KK94> J J J J J KK;T^ L L L L LrrcKtd{Vrmtd ttdzd{Vn2#t $r%}td|Yd}~nd}~wwxYwdSttd|zzd{Vttd|zzd{VdS)Nz,Plesk doesn't support uninstalling rulesets.z.--update-web-app-firewall -waf-rule-engine offz&Couldn't turn WAF rule engine off: %s z --disable-all-rules --ruleset %sz--uninstall --ruleset %s)r0r#rr*r: Exceptionerrorrn)rres rrz%PleskFilesVendor._remove_vendor_by_ids?.00 0 0 0 0 0 0  NNI J J J JFG J J J EqIIIIIIII J F ;iG G         j#= #IIJJJJJJJJJJJsA A?A::A?cJK||jd{VdSrS)rrrs rrzPleskFilesVendor._remove_vendors4''77777777777rctjt|jdj}tj|\}}|S)Nurl)rTrbasenamerrsplitext)rrbasename_no_zip_s r _vendor_idzPleskFilesVendor._vendor_idsI7##HTZ->$?$?$DEEW--h77rcKtd{Vr|d{VdSttd|jd|jdzd{VdS)Nz3--install --with-backup --enable-ruleset --ruleset z --archive-path local_path)r0!_install_or_update_custom_rulesetr*rnrrrs rrzPleskFilesVendor._add_vendors.00 0 0 0 0 0 0 88:: : : : : : : : : :J~~~tz,'?'?AA         rc Ktd{Vpd}|jj}|dks|r|rdn|}t d|rdndt||krd|d|nt|ttd gd |gzd td |j d gztd{VdSt ddS)a Install or update custom ruleset from *TMP_VENDOR_PATH*. Installation happens iff the "installing_settings" var is true. Installation turns on the waf rule engine. The update command preserves waf rule engine mode. If the war rule engine is off, then the update command is skipped. Unknown (None/empty) mode is considered to be "off." Nrmonz'%s %s ruleset, waf-rule-engine mode: %s InstallingUpdatingz old_mode=z new_mode=z--update-web-app-firewallz-waf-rule-enginez -waf-rule-setz-waf-archive-pathrr!zSwaf rule engine remains off. Skip the update command as a workaround for DEF-15857.) r2rArinstalling_settings_varrr#rrreprrSERVER_PREF_BINrr)rold_mode installingnew_modes rrz2PleskFilesVendor._install_or_update_custom_rulesets^(<<>>>>>>>>G%*BFFHH u   )7ttxH KK9 *: " 8++3x22X222h    "=>%x01$&'J|, /             KKJ     rN)rrrrdrrTrrr TMPDIRTMP_VENDOR_PATHrqrtrrryrrrrrrrrrrs'gll4;0HIIO+++KKK444 M M MKCKKKK"888   )))))rrcBeZdZeZeZedZedZ dS)rc8|ddS)Nnameplesk)endswith)r>items rvendor_fit_panelz%PleskFilesVendorList.vendor_fit_panel,sF|$$W---rcK|d{V}|s|d|tj||dS)NzBWeb-server is not running, skipping imunify360 vendor installationr&)ruleset_suffix webserverpanel)_get_web_serverCompatiblityCheckFailedrrsget_ruleset_suffix)r>r web_servers r_get_compatible_namez)PleskFilesVendorList._get_compatible_name0s..00000000  --1!  $*1133     rN) rrrr files_vendorrdrrxr)r2rrrrr(sS#L'..[.   [    rr)1rloggingrT contextlibrpackaging.versionrpathlibrtypingrr urllib.parser defence360agent.contracts.configr r defence360agent.subsys.panelsr defence360agent.utilsr r rrim360.subsys.panels.baserrrrrr!defence360agent.subsys.web_serverrrnr:rrr getLoggerrr#PanelExceptionrr*r0r2rdrrrrrrAs  %%%%%%!!!!!!!!!!!!!!========...... ?>>>>> 9 - $788 /  8 $ $     4.   !!! ===wwwww+wwwtx7x7x7x7x7+x7x7x7vxxxxx{xxxv     ?     r