&VddZddlZddlZddlZddlZddlZddlZddlmZddl m Z ddl m Z m Z mZddlmZddlmZmZmZmZddlmZmZmZdd lmZdd lmZdd lmZdd l m!Z!dd l"m#Z#m$Z$ej%e&Z'dZ(dZ)GddeZ*GddeZ+GddeZ,ddZ-dS)z+CoraZa ModSecurity interface for Imunify360N)chain)Path)DictListOptional)urlparse)atomic_rewriteasync_lru_cache check_run CheckRunError) FilesVendorFilesVendorListModSecurityInterface)forbid_dns_only)catch_exception)is_force_use_coraza)$get_shared_disabled_modsec_rules_ids)is_apache2nginx_enableduse_coraza4cpanelz/var/imunify360/modsec/corazacKtdrddg}ngd} t|d{VdS#t$rtdYdSwxYw)Nz/usr/bin/imunify360-wsctlzimunify360-wsctlreload) systemctlrzimunify360-wafdz"Failed to reload 'imunify360-wafd')ris_filer r loggerwarning)argss [/opt/imunify360/venv/lib/python3.11/site-packages/im360/subsys/panels/coraza_modsecurity.py reload_wafdr&s '((0022:"H-999=oo ===;<<<<<<=sA$A-,A-cXeZdZdZdZdZdZdZdZdZ e dZ e d e fd Z e d Ze d Ze d e fd Zeed$dZe dZd$dZe d eefdZe edd eefdZe d eefdZdZe dZe d%dZ dZ!dZ"e d$dZ#e dZ$e deded e%fd Z&e d!Z'e d"e(ee)ffd#Z*dS)&CorazaModSecurityz+Coraza ModSecurity interface for Imunify360z../app-specific-rules.jsonzcoraza.i360_disabled_rules.confz"/etc/imunify360-wafd/modsecurity.dz,/etc/imunify360-wafd/disabled-ids-rules.jsonz /var/log/imunify360/modsec_auditz$/var/log/imunify360/modsec_audit.logc|jSN)WAFD_CORAZA_AUDIT_LOG_FILEclss rget_audit_log_pathz$CorazaModSecurity.get_audit_log_path=s --returnclK||}|r|d{V|S)s :param list rule_list: rules to sync :return: True if config was changed, False otherwise N)write_global_disabled_rules reload_modsec)r% rule_listchangeds rsync_global_disabled_rulesz,CorazaModSecurity.sync_global_disabled_rulesAsL 11)<<  &##%% % % % % % % %r'c|jSr")WAFD_CORAZA_AUDIT_DIRr$s rget_audit_logdir_pathz'CorazaModSecurity.get_audit_logdir_pathLs ((r'cd}d}dt|tD}|r6|dt |}|S)NzSecRuleRemoveById {rules_list}c,h|]}t|S)str).0id_s r zCCorazaModSecurity.generate_disabled_rules_config..Ts.    HH   r' ) rules_list)rrformatjoinsorted)r%r-tplcontent rules_idss rgenerate_disabled_rules_configz0CorazaModSecurity.generate_disabled_rules_configPsw2  466     IjjCHHVI5F5F,G,GjHHGr'ctj|jdttj|j|j||dS)r*T)exist_okFbackup)osmakedirsDISABLED_RULES_CONFIG_DIRr pathr>%GLOBAL_DISABLED_RULES_CONFIG_FILENAMErC)r%r-s rr+z-CorazaModSecurity.write_global_disabled_rules_sh C1DAAAA GLL-9    . .y 9 9     r'TcKtd{V||d{VdSN) should_reload)CorazaFilesVendorListapplyr,selfrs r_install_settingsz#CorazaModSecurity._install_settingsos[$))+++++++++  { ;;;;;;;;;;;r'cZKtptp tSr")rrrr$s rinstalled_modsecz"CorazaModSecurity.installed_modsecus2 ! ! #&(( # "" r'cKtd{V||d{VdSrN)rPrevertr,rRs rrevert_settingsz!CorazaModSecurity.revert_settingss[$**,,,,,,,,,  { ;;;;;;;;;;;r'cpKg}|d{V}|r|||S)z/Return a list of installed ModSecurity vendors.N)#get_modsec_vendor_from_release_fileappend)r% vendor_listvendors rmodsec_vendor_listz$CorazaModSecurity.modsec_vendor_listsR >>@@@@@@@@  '   v & & &r')maxsizecK|ddd{V} |5}tj|}dddn #1swxYwY|S#ttjf$rYdSwxYw)NzNot usedRELEASE)r^filename)build_vendor_file_pathopenjsonloadOSErrorJSONDecodeError)r%modsec_release_file release_f json_datas r_get_release_info_from_filez-CorazaModSecurity._get_release_info_from_files%($>$> %?% %        $))++ 1y Ii00  1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 -.   44 s4A#A A#AA#AA##A=<A=c:K|d{VS)zj Return a list of enabled modsec vendors Checked by existence of CORAZA_RULES_DIR N)r_r$s renabled_modsec_vendor_listz,CorazaModSecurity.enabled_modsec_vendor_lists, ++---------r'Nc|jSr")rJr$s r _get_conf_dirzCorazaModSecurity._get_conf_dirs ,,r'cKt)z N/A for Coraza NotImplementedError)r%directive_namedefaults rmodsec_get_directivez&CorazaModSecurity.modsec_get_directives "!r'cKt)z Used for `imunify360-agent fix modsec directives` to reset ModSecurity settings to values chosen by Imunify360 N/A for Coraza rtrSs rreset_modsec_directivesz)CorazaModSecurity.reset_modsec_directivess"!r'cKtr"rtrzs rreset_modsec_rulesetsz'CorazaModSecurity.reset_modsec_rulesetss !!r'cnK|stddStd{VdS)z.Reload the wafd service to apply updated ruleszSkipping reload wafd.N)rinfor)r%rOs rr,zCorazaModSecurity.reload_modsecsJ  KK/ 0 0 0 Fmmr'cdS)NFr6r$s r detect_cwafzCorazaModSecurity.detect_cwafs ur'r^rdc4Ktt|z Sr")rCORAZA_RULES_DIR)r%r^rds rrez(CorazaModSecurity.build_vendor_file_paths$%%00r'cKtd{Vr|d{VdSdSr")rPinstall_or_updater,r$s r_apply_modsec_files_updatez,CorazaModSecurity._apply_modsec_files_updates`&88:: : : : : : : &##%% % % % % % % % % % & &r'domain_rules_mapcKtdd|i} t|jd5}t j|}d|D}dddn #1swxYwYn6#t jtf$rt dYnwxYw| |d| D}t|jt j |dr"td |jdStd |jdS) NzSync disabled rules for [%s],rc,i|]}|d|dSdomain disabled_idsr6)r8items r zECorazaModSecurity.sync_disabled_rules_for_domains..s3ND$8r'zHCould not load or parse existing config file. A new one will be created.c6g|]\}}||d|DdS)c,g|]}t|Sr6)int)r8_ids r zPCorazaModSecurity.sync_disabled_rules_for_domains...s/H/H/HSC/H/H/Hr'rr6)r8ridss rrzECorazaModSecurity.sync_disabled_rules_for_domains..sI    /H/HC/H/H/H I I   r'FrFz@Disabled rules for domains were successfully updated on path %s.z7Failed to update disabled rules for domains on path %s.)rrr>rf)PER_DOMAIN_DISABLED_RULES_CONFIG_FILENAMErgrhrjFileNotFoundErrorrupdateitemsr dumpserror)r%r config_mapfold_config_list final_configs rsync_disabled_rules_for_domainsz1CorazaModSecurity.sync_disabled_rules_for_domainss  2CHH=M4N4NOOO  cCSII Q"&)A,, /                 $&78    NN       *+++  )//11     9 J| $ $     KK=      LLI=     s5B !A6* B6A::B=A:>B0B54B5)Tr")+__name__ __module__ __qualname____doc__APP_BASED_EXCLUDE_CONF_NAMErLrJrr1r# classmethodr&boolr/r2rCr+rrrTrVrYrr7r_r rdictrnrpREBUILD_HTTPDCONF_CMDrrrxr{r}r,rrrerrlistrr6r'rr r 1s55">,M) D6.?!G..[.D[))[)  [   t    [  <<<__<  [ <<<< c[_Q (4.    [ .c...[.!--[-"""[" """"""[[1#11111[1&&[&)#CI)))[)))r'r c$eZdZeZdZdZdZdS)CorazaFilesVendorc&KtdS)z# Clear vendor data N)atomically_swap_foldersrzs r_remove_vendorz CorazaFilesVendor._remove_vendors !!!!!r'cKt|jdddlm}t |j}dt |dD}|D]m}t d| | |id{V;#t$r&}t d||Yd}~fd}~wwxYwdS) zw Atomically swap vendor folders. We can swap them atomically only by swapping symlinks to them local_pathr) cPanelApachePackageApplyStrategycDg|]}||jSr6)is_dirname)r8dps rrz+CorazaFilesVendor.apply..s7    G   r'z imunify360-*z*Removing vendor '%s' left by cPanel setup.NzFailed to remove vendor %s: %s) r_item'im360.subsys.panels.cpanel.mod_securityrrAPACHE_MODSEC_VENDOR_CONF_DIRrglobrr remove_vendor Exceptionr)rSrrKvendorsrrs rrQzCorazaFilesVendor.apply s2  < 8999       , J    "499^#<#<==    L LD KKDd K K K L6DDT2NNNNNNNNNN L L L =tUKKKKKKKK L  L LsB  C*C  Cctjt|jdj}tj|\}}|S)Nurl)rHrKbasenamerrsplitext)rSrbasename_no_zip_s r _vendor_idzCorazaFilesVendor._vendor_id#sI7##HTZ->$?$?$DEEW--h77r'N)rrrr modsec_interfacerrQrr6r'rrrsJ(""" LLL4r'rcXeZdZeZeZedZedZ edZ dS)rPc6Kd|dS)Nz imunify360--coraza)get_ruleset_suffix)r%installed_vendorss r_get_compatible_namez*CorazaFilesVendorList._get_compatible_name-s#>S3355>>>>r'c8|ddS)Nrr)endswith)r%rs rvendor_fit_panelz&CorazaFilesVendorList.vendor_fit_panel1sF|$$Y///r'cKtjtrtjt}tjtjt|}tj|dtj tdStjtddS)NT ignore_errors) rHrKislinkrreadlinkr>dirnameshutilrmtreeremove)r%rdst_namedsts rrXzCorazaFilesVendorList.revert5s 7>>* + + @{#344H',,rw/?@@(KKC M#T 2 2 2 2 I& ' ' ' ' ' M*$ ? ? ? ? ? ?r'N) rrrr files_vendorr rrrrrXr6r'rrPrP)ss$L(??[?00[0@@[@@@r'rPc tjddtj}td|}td|d}t j|d|rt j|5}|D]}tj |}|s$tj ||}| |5}t|d5} tj|| dddn #1swxYwYdddn #1swxYwY dddn #1swxYwYt jtj ||tj trt jt} tj tj t| } t j|ttj| d dStjtd t j|tdS) a$ Tries to swap folders atomically. The idea is to atomically swap symlynks to the folders while folders themselves can be removed afterwards. If path to zip file is passed, current folder is replaced with contents of the archive. Otherwise it's replaced with empty folder z%Y-%m-%dT%H%M%S.r_symi)modewbNTr)timestrftime monotonic_nsrrHrIzipfileZipFilenamelistrKrr>rfr copyfileobjsymlinkrrrrenamer) zip_path curr_time dest_dirpath dest_symlinkzfmemberrdtargetsrcrrs rrr@s=!233KKd6G6I6IKKI&4444L&88888LK 5))))1 _X & & 1"++-- 1 17++F33lH==WWV__1T&$-?-?13&sC000111111111111111111111111111111  1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1Jrw --|<<< w~~&''2;/00gll27??+;<rsJ11  ''''''''''!!!!!!  ?>>>>>DDDDDD777777CBBBBBBB  8 $ $2===LLLLL,LLL^&&&&& &&&R@@@@@O@@@.!2!2!2!2!2!2r'