o ;s*b@sdZdZdZddlZddlZddlZddlZddlZddlZddl Z ddl m Z m Z mZmZmZddlmZddlmZdd lmZmZmZdd lmZdd lmZmZmZdd l m!Z!mZ"dd l#m$Z$ddl%m%Z%ddl&m'Z'ddl(m)Z)ddl*m+Z+m,Z-m.Z.m/Z/m0Z0m1Z1m2Z3m4Z4m5Z5ddl6m7Z7e7e8Z,dZ9dZ:ee!;Ze j=j?Z?e j=>e j=j@Z@e?de_?e,e_,e_,e_,e%jAZBe%jCZDddZEeEe_Fe_Fe_Fe$_FddZGe%jHZHddZIe@fddZJGdddejKZKGd d!d!ejKZLeKZMeLZNgaOd"d#ZPePe_Qd$e_Re_Re+jSZTd%d&ZUd'd(ZV  , d?d-d.ZWd/d0ZXd1d2ZYd3d4ZZd5d6Z[ifd7d8Z\Gd9d:d:e+Z]Gd;d<dd>e]Z_dS)@z Serg BresterzICopyright (c) 2014- Serg G. Brester (sebres), 2008- Fail2Ban ContributorsGPLN)joinisdirisfileexistsdirnamewraps)Thread)fail2banclientfail2banserverfail2bancmdline)Fail2banCmdLine)exec_command_lineCSocket VisualWait)Fail2banServerr)protocol)server)MyTime)Utils) LogCaptureTestCaselogSys with_tmpdirshutilloggingSTOCK CONFIG_DIRTEST_NOWtearDownMyTime) getLoggerzfail2ban-clientzfail2ban-servercGst|ddSNr)rinfoargsr'G/usr/lib/python3/dist-packages/fail2ban/tests/fail2banclienttestcase.py _test_outputJsr)cCs&td|tt|ddS)Nz===>>> time shift + %s min<)rdebugrsetTimetime)shiftr'r'r( _time_shiftQs r/cCs.tjdurtjttjtddSdS)z$Helper to wait observer becomes idleN) ObserversMain wait_empty MID_WAITTIME wait_idler'r'r'r(_observer_wait_idleYs  r6cs2tjdurtjjfdd}|tj_dSdS)zOHelper to block observer before increase bantime until some condition gets trueNcs:tj_tdttd|i|dS)Nz4 [Observer::banFound] *** observer blocked for testz. [Observer::banFound] +++ observer runs again)r1r2banFoundrr+rwait_forr&kwargs _obs_banFoundcondtimeoutr'r( _banFoundds    z0_observer_wait_before_incrban.._banFound)r1r2r7)r=r>r?r'r;r(_observer_wait_before_incrban_s  r@c@eZdZdZdS) ExitExceptionzException upon a normal exitN__name__ __module__ __qualname____doc__r'r'r'r(rBtrBc@rA)FailExitExceptionzException upon abnormal exitNrCr'r'r'r(rIyrHrIcGsttr tdSdS)Nrexit)lenINTERACTpopr%r'r'r(_test_input_commands rNFcGs2t||}|d||rdnd|dS)N )openwriterclose)fnmodelinesfr'r'r( _write_files  rXcCs>d}zt|}|W|dur|SS|dur|wwN)rQreadrS)rTrWr'r'r( _read_files  r[ /dev/null:memory:r'rPcCst|d}|dkrt|d}d} |r}tr}dd} tjt|| d|dus,Jdt||dur2d }td } tj t|d d d D]} | d} | | rOd} t | qAtd} tj t|dd d D]} | d} | | rqd} t | qc|rzdnd} n*t |tt|d dddd|ddddt|ddt|ddd|d d!d | rtt|| dgd"dd#d$|df|R|rtt|d%dg|Rtjjtjkrtt|d tt|d|rtt|d%| r| dkrtt|| |rtr|D]} t t jtt| t|| q|r%|D] } t| d&|iddqd'\}}tjjtjkrGttjj}tjjd(krGd)d*tjjf}|d+|f}d,|d-t|dd.t|dd/|f|d0dd1ttjfS)2Nconfigautozf2b-db.sqlite3 jail.confcsfdd|DS)z?Filters list of 'files' to contain only directories (under dir)csg|] }tt|r|qSr')rpjoin).0rWdirr'r( sz2_start_params..ig_dirs..r')refilesr'rdr(ig_dirssz_start_params..ig_dirs)ignorez?We are about to overload use_stock_cfg from the one provided %s)action.dzfilter.dz ^dbfile\s*=z fail2ban.confT)inplacerOzdbfile = :memory:z ^backend\s*=backend = pollingz jail.localrPw [Definition]zloglevel = INFOz logtarget = %z%%zsyslogsocket = autoz socket = f2b.sockz pidfile = f2b.pidz dbfile = zdbmaxmatches = 100zdbpurgeage = 1d [INCLUDES] [DEFAULT]ztmp = zfail2ban.localtmp)r'INFOr-vz --loglevel-c-sz-p --logtargetz--syslogsocketz --timeout)rbrrcopytreeSTOCK_CONF_DIRreprrecompile fileinputinputrstripmatchprintosmkdirrXreplaceunittestF2B log_levelrDEBUG _out_filesymlinkpathabspathrustr verbosityr MAX_WAITTIME)rt use_stock use_stock_cfg logtargetdb f2b_localjailscreate_before_startcfgj_confrhrlinenvvvllevr'r'r( _start_paramss                    "   rcCs.z ||dddkWStyYdSw)Nrzr INHERITEDF)index ValueError startparamsr'r'r(_inherited_logs  rc CsXd}zt|}td|}t|WSty+}z t|WYd}~|Sd}~ww)Nz\S+)r[r~rgroupint Exceptionrr+)pidfilepider'r'r(_get_pid_from_files rc sftd|t|ft|r|}t|d}t|st|d}tjjtj kr:t|d}t|r3t |nt dd|t|sFtd|dStd |t |durVd SzDtd d ksgt krotd |ftswWdSt tjtfdddst tjtdt WSty}z t|WYd}~dSd}~ww)Nz cleanup: %rrqz fail2ban.pidf2b.logr0z no logfile %rzcleanup: no pidfile for %rTzcleanup pidfile: %rFzcleanup pid: %rrzpid %s of %s is invalidcs t SrY)r pid_existsr'rr'r(+ z_kill_srv..rcleanup: kill ready)rr+rrbrrrrrrrlogrrgetpidrrrkillsignalSIGTERMr8SIGKILLr exception)rpiddirlogfilerr'rr( _kill_srv sD         rcstfdd}|S)zHelper to decorate tests which receive in the last argument tmpdir to pass to kill_srv To be used in tandem with @with_tmpdir cs.|d}z |g|RWt|St|w)N)r)selfr&rrWr'r(wrapper:szwith_kill_srv..wrapperrrWrr'rr( with_kill_srv5srcsfdd}|S)z}Helper to decorate tests uses foreground server (as thread), started directly in test-cases To be used only in subclasses csttfdd}|S)Nc sd}tzz|tfdditdjfd}d|_|ttfffdd }|_t fdd t  d djdd td g|Ri|WW|rtd  ddr|tSty}ztd|}|rtd|d}~ww|rtd  ddr|tw)Nrr_TestCaseWorker)nametargetr&TcstddstjtdstfddtddsE |dtfddt  ddj ddd t d d d_ dS) NendrqcddduSNrgetr'phaser'r(r_zywith_foreground_server_thread.._deco_wrapper..wrapper.._stopAndWaitForServerEnd..stopcrrrr'rr'r(rdrShutdown successfulzExiting Fail2banTallwaitc_dSrYr'r9r'r'r(rh)r!rrrrrbrr8r4execCmdr assertTrue assertLoggedstopAndWaitForServerEndcoderrrrtr'r(_stopAndWaitForServerEnd[s zgwith_foreground_server_thread.._deco_wrapper..wrapper.._stopAndWaitForServerEndcr)Nstartrr'rr'r(rkrzWwith_foreground_server_thread.._deco_wrapper..wrapper..r)rrz=== within server: begin ===z=== within server: end. ===rz=== Catch an exception: %sz#=== Error of server, log: === %s===)dictrr _testStartForegrounddaemonrSUCCESSFAILEDrrr8rrr _wait_for_srv DefLogSysr$pruneLogrr!rrgetLog)rrtr&r:thrrr)rW startextrarr(rIsT       zEwith_foreground_server_thread.._deco_wrapper..wrapper)rr rrrr( _deco_wrapperHs:z4with_foreground_server_thread.._deco_wrapperr')rrr'rr(with_foreground_server_threadCs >rc@speZdZejZddZddZddZe ddd Z dd d Z ddZ ddZ ddZeddidddZd S)Fail2banClientServerBasecOrrYr')rr&r:r'r'r( _setLogLevelsz%Fail2banClientServerBase._setLogLevelcCs(t|dt_tjt_t|jt _ dS)zCall before every test case.rN) rsetUpr DEF_LOGTARGETrlevel DEF_LOGLEVEL staticmethod _test_exitr_exitrr'r'r(rs zFail2banClientServerBase.setUpcCs(|jt_tt_tt_t |t dS)zCall after every test case.N) _orig_exitrrSRV_DEF_LOGTARGETrrSRV_DEF_LOGLEVELrrtearDownr!rr'r'r(rs   z!Fail2banClientServerBase.tearDownrcCs|dkrttr#)rBrIrr'r'r(rsz#Fail2banClientServerBase._test_exitTNcssiz:t|dtfddt}|rdr#td|f|r9tfddt}|s.rz9Unexpected: Socket file does not exists. Start failed: %rcs dvS)N Server ready)rr'rr'r(rrzBUnexpected: Server ready was not found, phase %r. Start failed: %rz,=== Error by wait fot server, log: === %s===rz*No log file %s to examine details of error)rbrr8rrrrrrrrrrr+)rrtreadyrrretrr')rrrr(rs>   z&Fail2banClientServerBase._wait_for_srvcGs*|||jd|jdd||dS)Nrr) assertRaisesr)rexitTyperr&r'r'r(rsz Fail2banClientServerBase.execCmdcGs:||dd}t|}z ||W|S|w)Nryr)rrsendrS)rrr&rsr'r'r( execCmdDirects  z&Fail2banClientServerBase.execCmdDirectc Csbtdd|d<z|td|dWd|d<d|d<tddSd|d<d|d<tdw)Nzstart of test workerTr)z-fFrzend of test worker)rr+rr)rrtrrr'r'r(rs  z-Fail2banClientServerBase._testStartForegroundr)z[Thread]zstacksize = 128rcCsR||t|dd|d|t|d|t|d|t|dddS)Nrthreadz{'stacksize': 128}ping~~unknown~cmd~failed~~echo TEST-ECHO)rrrrrrrtrr'r'r(testStartForegrounds  z,Fail2banClientServerBase.testStartForeground)r)TNN)rDrErFrrrrrrrrrrrrrr r'r'r'r(rs   rc@steZdZeefZddZddZeddZ ee ddZ ee d d Z ee d d Z ed dZddZdS)Fail2banClientTestcCs,|tttt|ttttdSrY)rrrbBINCLIENTSERVERrr'r'r(testConsistencysz"Fail2banClientTest.testConsistencycCs|tdd|dt|d||tdd|t||tddd|dtj||tdd d |d dS) Nr'-hUsage: Report bugs to z-Vz-vqz --versionz Fail2Ban vz --str2sec1d12h30m131400)rrrrrr normVersionversionrr'r'r(testClientUsages z"Fail2banClientTest.testClientUsagecCsPt|d}|t|d|d|d||t|d|ddS)NTz-vvdz Loading filesz['set', 'logtarget',z--dp)rrrrrr r'r'r(testClientDumps   z!Fail2banClientTest.testClientDumpc Cs t|d}|td|d|j|d|d|d|dz8|t|dd|t|d ||td|d|d W||t|d |d |dn||t|d |d |dw||t|d |d |ddS)NTz-brrrExit with code 0rr rzServer already runningrrzFailed to access socket pathzIs fail2ban running?)rrrrrrrr r'r'r(testClientStartBackgroundInsides.         z2Fail2banClientTest.testClientStartBackgroundInsidec Cst|t|dd}tjjr|t|dn0tjtt t f}t d|||d}t j|tddd}|t|o<|d |j|d|d |d |z|t|d d |d |d||t|dd|d|tt|d}zt|tjtt j|t|ddWt|tjnt|tjw|d|tgd7a|t|d|d|dd|d|tgd7a|t|d|d|d|d |d|tddg7a|t|d|d||t|d d!|d|d"|W||t|d#|d|ddS||t|d#|d|dw)$Nrr)r Start %s ...)--asyncrFTr>shelloutputrrrrr rrz0.1zServer replied: pongrqz1e-10z timed out)zecho INTERACT-ECHOstatusrJz-iz INTERACT-ECHOStatuszNumber of jail:)reloadrestartrJzReading config files:rzreload ~~unknown~jail~fail~~rJz@Failed during configuration: No section: '~~unknown~jail~fail~~'r%z~~unknown~jail~fail~~zExit with code 255r) rrbrrfastrrsys executabler rrr+r executeCmdrrrKrrrrrrrSIGSTOPr-sleepDEFAULT_SHORT_INTERVALrSIGCONTrL)rrtrcmdrrr'r'r(testClientStartBackgroundCall2sv                         z0Fail2banClientTest.testClientStartBackgroundCallc Cst|dd}|tdddt|dd|dt|dd ||tddt|d d t|d d |d|tt|d d|tdddt|d d t|d d|d|t t|d |tdd |d|dS)Nrrr'rrxmissrBase configuration directory  does not existr_ryrpr%Could not find serveraLFail2ban seems to be in unexpected state (not running but the socket exists)r rrrrbrrrQrSrremover r'r'r(testClientFailStarts*     z&Fail2banClientTest.testClientFailStartcCsXt|dd}|t|dd|d||t|dddd|d|dS) Nrrr%jailr4rz--xxxz"Unexpected argument(s) for reload:)rrrrrr r'r'r(testClientFailCommandss    z)Fail2banClientTest.testClientFailCommandsc Csnd}dD]0}d}t|d}|r%||rtjjst||d8}|sWdn1s/wYqdS)NgQ?)r rr0r)r heartbeatrrr'r-r,)r sleeptimeverbosecntrvisr'r'r(testVisualWaits   z!Fail2banClientTest.testVisualWaitN)rDrErF _exec_clientrrrrrrrrr0r9r;rBr'r'r'r(r s$    T   r c@seZdZeefZddZeeddZ eeddZ eeddZ ed d Z e d d id ddZejjdde ddddd ddZejjdde dddddd dd Ze d!d"Zd(S))Fail2banServerTestcCs*|tdd|dt|ddS)Nr'rrr)rrrrrr'r'r(testServerUsagesz"Fail2banServerTest.testServerUsagec Cst|t|dd}tjtttf}td|||d}tj |t ddd}| t |o/|d|j |d|d |d |z'|t|d d |t|d W||t|d|d|ddS||t|d|d|dw)NrrrrFTr rrrrr rrrr)rrbr(r)r rrr+rr*rrrKrrrrrrrrtrr/rr'r'r(testServerStartBackgrounds(      z,Fail2banServerTest.testServerStartBackgroundc Cst|dd}|tddt|d|dt|dd|tt|dd |tddt|d d t|d|d |t t|ddS) Nrrr'rxr1r2r3rpr5r_ryr6r7r r'r'r(testServerFailStarts   z&Fail2banServerTest.testServerFailStartcCst|dd}t|d}|d|t|d|dtt|ddd d d d d |d |t|d|jddddd|d|t|dd|jddddddS)Nrrr_z[test-phase 0]z--testz$OK: configuration test is successfulrar5rP [broken-jail]filter = broken-jail-filterenabled = truez[test-phase 0a].Unable to read the filter 'broken-jail-filter'zErrors in jail 'broken-jail'.z ERROR: test configuration failedTrz[test-phase 0b]z-tr)rrbrrrrrXr)rrtrrr'r'r(testServerTestFailStarts(       z*Fail2banServerTest.testServerTestFailStartc s zQttdd}tjtttf}td|||d}tj |t ddd}| t |o0|d|j d|d |d |td W| tn| twtfd d t |ttd|d|| t|ddS)NzGf2b.log[format="SRV: %(relativeCreated)3d | %(message)s", datetime=off]rrrFTr rrrzKill server ... %scsttd S)Nrq)rrbr'rtr'r(r-rz7Fail2banServerTest.testKillAfterStart..rqrzcleanup: no pidfile for)rrbr(r)r rrr+rr*rrrKrrrrr8 assertFalserrFr'rOr(testKillAfterStarts(     z%Fail2banServerTest.testKillAfterStartrr`rc s t|dt|dt|dt|dttd  dȇfd d }dɇfdd }|dd|dd|dggddttdddddddtdgtttdfdRtdtd|dt j j t j kr}t|t|d|jdd dtd!|d"|d#|jd$d%dd&|jd'd(dtd!|jd)d*d+dd&|d,|dd-gd.td/t j j t j krt|t|d|jdtd0|jd1d#dd&|jd"d"dd&|jd2d3dd&|jd4d5dd&|jd6d7dd&|d8|d9|dgd.|dd:dd;dd|jd2d?dd&|d@|dA|dB|ddCdD|d-dgd.|dEtd/gtttdFfdtttdGfdtttdHfdtttdIfdRt j j t j krt|jdJdKdtd!|t|dLdMdNdO|jdPtd0|jdQdRdSdTdUdVdWdd&|jdXdYdZd[dd&t|||d\d]d^gd_idMgd`igf|||d\dadbdcd]d^gd^dMgggf|||ddd^d\dgd_|||dddMd\dgd`|||ddd^d\dedd|||ddd^d\dOdd]|||ddd^d\dedOddd]gtd/td/|df|t|dgdM|jddhdPdtd!|jdidjdkdld5dmdndodd& |jdpdqdtd!|jdrdsdd&|dt|t|dLdMdNdu|t|dLdMdNdv|jdwdxdtd!t|dy|t|dddMdNdz|jdbd{dudvdtd!|d||t|ddd^dN|jdad}dedbd{dtd!|d~|t|dgddM|jdd5dtd!|jdld5didjdkdd&|jdddd&|d|jdddd&|jdUdVdd&|ddCdD|gd.|d|t|dd^|jdtd0|jdddd&|jddddd&|d|dgd|t|d|jdtd0|d|jddldd&|jdddd&|dtd/gtttdfdtttdfdtttdfdRt j j t j krt|jdddtd!|jdddddd&|d|d|t|dddd|jdddtd!|d|t|ddd|jdddtd!|t|dddd|jdddtd!|d|t|ddLd^dNdd|jdddtd!|t|ddLd^dd|jdddtd!|d|t|dd|jdtd0|jdd1ddd&|jddd#dSdd&|d|t|ddd|jdddd&|d|dgdd|t|d|jdtd0|jdddd&|d|dgd|t|d|jdtd0|d|t|dddM|jdtd0|d||t|ddddM|jdtd0|jd4d5dd&|d|t|dddd|jdtd0|jdddtd!|dá|t|ddLd^dddơ|t|dddd^dǡ|jdddd&dS)Nr_ test1.logz test2.logz test3.logrj test-action1TrPcsntdd|}|st|dSt|ddddddd d d d |d |d|d|d|tjjtjkr5t |dSdS)Nrj%s.confrmrsz_exec_once = 0rPrnznorestored = %(_exec_once)sz restore = zinfo = z<_use_flush_ = echo '[%(name)s] %(actname)s: -- flushing IPs'z6actionstart = echo '[%(name)s] %(actname)s: ** start'z7actionreload = echo '[%(name)s] %(actname)s: .. reload'zMactionban = echo '[%(name)s] %(actname)s: ++ ban %(restore)s%(info)s'z;actionunban = echo '[%(name)s] %(actname)s: -- unban 'z5actionstop = echo '[%(name)s] %(actname)s: __ stop') rbrr8rXrrrrrr)actnameallowrr%banunbanrrTrr'r(_write_action_cfgEs,  zBFail2banServerTest.testServerReloadTest.._write_action_cfgrr r'pollingcsPtgtdddddddddd d d dd d |ddd|vr/dndd|vr7dndd|vr?dnddd|vrMdndd|vrWdndd d|vradndd|vridndddd |ddd|vr}dndd|vrdnddd|vrdndRtjjtjkrttddSdS)NrarmrrrPrs usedns = no maxretry = 3zfindtime = 10mzBfailregex = ^\s*failure 401|403 from datepattern = {^LN-BEG}EPOCHzignoreip = 127.0.0.1/8 ::1 [test-jail1] backend = filter =z action = rz* test-action1[name='%(__name__)s']r zj test-action2[name='%(__name__)s', restore='restored: ', info=', err-code: ']z test-action2[name='%(__name__)s', actname=test-action3, _exec_once=1, restore='restored: ', actionflush=<_use_flush_>] logpath = z z@ ^\s*error 401|403 from rKz [test-jail2]rXrbrrrrrr)enabledactionsbackendrtest1logtest2logtest3logr'r(_write_jail_cfg]s      !"#%z@Fail2banServerTest.testServerReloadTest.._write_jail_cfg)rU test-action2r)rr rc)rfrgrar5rIrJrKrmz# failure 401 from 192.0.2.1: test 1rcz[test-phase 1a]r%Reload finished.z1 ticket(s) in 'test-jail1rzAdded logfile: %rz[test-jail1] Ban 192.0.2.1z-stdout: '[test-jail1] test-action1: ** start'z-stdout: '[test-jail1] test-action2: ** start'rMzPstdout: '[test-jail1] test-action2: ++ ban 192.0.2.1 restored: 0, err-code: 401'zAstdout: '[test-jail1] test-action3: ++ ban 192.0.2.1 restored: 0'rLz)Errors in jail 'broken-jail'. Skipping...z:Jail 'broken-jail' skipped, because of wrong configurationz[test-phase 1b]r )rgw+rz[test-jail1] Unban 192.0.2.1z.stdout: '[test-jail1] test-action1: .. reload'z.stdout: '[test-jail1] test-action2: .. reload'zCreating new jail 'test-jail2'zJail 'test-jail2' startedz4stdout: '[test-jail1] test-action3: -- flushing IPs'z,stdout: '[test-jail1] test-action3: __ stop'z7stdout: '[test-jail1] test-action3: -- unban 192.0.2.1'z[test-phase 2a]z+ echo '[] %s: started.'z, echo '[] %s: reloaded.'z+ echo '[] %s: stopped.')rUrr%rzAdded logfile:z.stdout: '[test-jail1] test-action1: reloaded.'z7stdout: '[test-jail1] test-action2: -- unban 192.0.2.1'z,stdout: '[test-jail1] test-action2: __ stop'z7stdout: '[test-jail1] test-action1: -- unban 192.0.2.1'F)rUrVz[test-phase 2b]z# error 403 from 192.0.2.2: test 2z# error 403 from 192.0.2.3: test 2z# failure 401 from 192.0.2.4: test 2z# failure 401 from 192.0.2.8: test 2z2 ticket(s) in 'test-jail2z5 ticket(s) in 'test-jail1setz test-jail2banip 192.0.2.9z3 ticket(s) in 'test-jail2z[test-jail1] Ban 192.0.2.2z[test-jail1] Ban 192.0.2.3z[test-jail1] Ban 192.0.2.4z[test-jail1] Ban 192.0.2.8z[test-jail2] Ban 192.0.2.4z[test-jail2] Ban 192.0.2.8z[test-jail2] Ban 192.0.2.9z[test-jail2] Found 192.0.2.2z[test-jail2] Ban 192.0.2.2z[test-jail2] Found 192.0.2.3z[test-jail2] Ban 192.0.2.3bannedr test-jail1) 192.0.2.4 192.0.2.1 192.0.2.8 192.0.2.3 192.0.2.2)rwrtryrxrwz 192.0.2.222rrzz[test-phase 2c]r&z Restore Banz[test-jail2] Unban 192.0.2.4z[test-jail2] Unban 192.0.2.8z[test-jail2] Unban 192.0.2.9zJail 'test-jail2' stoppedz"[test-jail2] Restore Ban 192.0.2.4z"[test-jail2] Restore Ban 192.0.2.8z"[test-jail2] Restore Ban 192.0.2.9zPstdout: '[test-jail2] test-action2: ++ ban 192.0.2.4 restored: 1, err-code: 401'zPstdout: '[test-jail2] test-action2: ++ ban 192.0.2.8 restored: 1, err-code: 401'zAstdout: '[test-jail2] test-action3: ++ ban 192.0.2.4 restored: 1'zAstdout: '[test-jail2] test-action3: ++ ban 192.0.2.8 restored: 1'z[test-phase 2d]z 192.0.2.21z 192.0.2.22z5stdout: '[test-jail2] test-action3: ++ ban 192.0.2.22z6stdout: '[test-jail2] test-action3: ++ ban 192.0.2.22 z[test-phase 2d.1]rOryz[test-phase 2d.2]r{z[test-phase 2e]z--unbanz7stdout: '[test-jail2] test-action2: -- unban 192.0.2.21z8stdout: '[test-jail2] test-action2: -- unban 192.0.2.22'z4stdout: '[test-jail2] test-action3: -- flushing IPs'z8stdout: '[test-jail2] test-action3: -- unban 192.0.2.21'z8stdout: '[test-jail2] test-action3: -- unban 192.0.2.22'z[test-phase 3]zReload jail 'test-jail1'zJail 'test-jail1' reloadedzReload jail 'test-jail2'zJail 'test-jail2' reloadedzJail 'test-jail1' startedz[test-phase 4])rfzStopping jail 'test-jail2'zRemoved logfile: %rz[test-phase 5]z# failure 401 from 192.0.2.1: test 5z# error 403 from 192.0.2.5: test 5z# failure 401 from 192.0.2.6: test 5z6 ticket(s) in 'test-jail1z%[test-jail1] 192.0.2.1 already bannedz[test-jail1] Found 192.0.2.1z[test-jail1] Found 192.0.2.6z[test-jail1] Ban 192.0.2.6z[test-jail1] Found 192.0.2.5z[test-phase 6a]rrXz 192.0.2.5z 192.0.2.6z192.0.2.5 is not bannedz[test-jail1] Unban 192.0.2.6z[test-phase 6b]z 192.0.2.2/31z[test-jail1] Unban 192.0.2.2z[test-jail1] Unban 192.0.2.3z 192.0.2.8/31z192.0.2.100/31z[test-jail1] Unban 192.0.2.8z192.0.2.100/31 is not bannedz[test-phase 6c]z 192.0.2.96/28z192.0.2.112/28z[test-jail1] Ban 192.0.2.96/28z[test-jail1] Ban 192.0.2.112/28unbanipz 192.0.2.64/26z [test-jail1] Unban 192.0.2.96/28z![test-jail1] Unban 192.0.2.112/28z[test-phase 7]z[test-jail1] Unban 192.0.2.4zJail 'test-jail1' stoppedz[test-phase 7b]--allzFlush ban listz'Unbanned 0, 0 ticket(s) in 'test-jail1'z[test-phase 8a]zxxx-unknown-backend-zzz)rfrhz0Restart jail 'test-jail1' (reason: 'polling' != zUnknown backend z[test-phase 8b]z[test-phase end-1]z$the jail 'test-jail2' does not existz --if-existsz[test-phase end-2] --restartz[test-phase end-3] addignoreipz 192.0.2.1/32z2001:DB8::1/96ignoreip)rSTrPrPrPrPrP)r[r'r\)rbrrrXrrrr-rrrrrrrrrrr4assertNotLoggedr6assertSortedEqualr assertEqualr)rrtrrZrmr'rir(testServerReloadTest5sZ    * (                                                      z'Fail2banServerTest.testServerReloadTestznginx-block-map)action)%(tmp)s/blck-failures.log)rj) z[nginx-blck-lst]rlr]z#logpath = %(tmp)s/blck-failures.logzRaction = nginx-block-map[blck_lst_reload="", blck_lst_file="%(tmp)s/blck-lst.map"]z blocklist_de[actionban='curl() { echo "*** curl" "$*";}; ', email="Fail2Ban ", apikey="TEST-API-KEY", agent="fail2ban-test-agent", service=]rbdatepattern = ^Epochz3failregex = ^ failure "[^"]+" - z maxretry = 1rK)rrrc Cst|d}dd|i}dd|i}t|dtttdtttdtttdtttd tttd |jd d d ddddtdt|t |}| d|| d|| d|| d|| d||jdddtd| t |ddddt|t |}| d|| d|| d|| d|| d||t |dt|t |}||ddS) Nr_rrtz%(tmp)s/blck-lst.maprpz" failure "125-000-001" - 192.0.2.1z" failure "125-000-002" - 192.0.2.1u1 failure "125-000-003" - 192.0.2.1 (òðåòèé)u1 failure "125-000-004" - 192.0.2.1 (òðåòèé)z" failure "125-000-005" - 192.0.2.1z [nginx-blck-lst] Ban 125-000-001z [nginx-blck-lst] Ban 125-000-002z [nginx-blck-lst] Ban 125-000-003z [nginx-blck-lst] Ban 125-000-004z [nginx-blck-lst] Ban 125-000-005z 5 ticket(s)Trz\125-000-001 1; z\125-000-002 1; z\125-000-003 1; z\125-000-004 1; z\125-000-005 1; zstdout: '*** curl --fail --data-urlencode server=Fail2Ban --data apikey=TEST-API-KEY --data service=nginx-blck-lst z=stdout: ' --data format=text --user-agent fail2ban-test-agentrXz 125-000-001z 125-000-002z 125-000-005z5[nginx-blck-lst] Flush ticket(s) with nginx-block-maprP)rbrXrrrr-rr4rr[assertInrr assertNotInrr)rrtrrlgfnmpfnmpr'r'r(testServerActions_NginxBlockMap'sX                z2Fail2banServerTest.testServerActions_NginxBlockMapz sendmail-auth)filter)%(tmp)s/test.logT)rszdbmaxmatches = 1)ztest_action = dummy[actionstart_on_demand=1, init="start: %(__name__)s", target="%(tmp)s/test.txt", actionban='; echo ""; printf "=====\n%%b\n=====\n\n" "" >> ']z[sendmail-auth]rlr]logpath = %(tmp)s/test.logaction = %(test_action)sz%filter = sendmail-auth[logtype=short]rr^zmaxmatches = 2rKz[sendmail-reject]rlr]rrz'filter = sendmail-reject[logtype=short]rr^rK)rrrrc Cs`t|d}dd|i}dd|i}tttdtttdtttdf}tttdtttd tttd f}|d t|d g|R|jd ddtdt |t |}|d} | | ||ddD]} | | |qz|dt|d g|R|jdddtdt |t |}|D]} | | |q|d| t|ddd|jddddtdt |}|d} || | | ||ddD] } || | | |q|jdddtdt |}|d} || | | ||ddD]} || | | |q|d|t|t|dS)Nr_rrtz%(tmp)s/test.txtz] smtp1 sm-mta[5133]: s1000000000001: [192.0.2.1]: possible SMTP attack: command=AUTH, count=1z] smtp1 sm-mta[5133]: s1000000000002: [192.0.2.1]: possible SMTP attack: command=AUTH, count=2z] smtp1 sm-mta[5133]: s1000000000003: [192.0.2.1]: possible SMTP attack: command=AUTH, count=3z smtp1 sm-mta[21134]: s2000000000001: ruleset=check_rcpt, arg1=<123@example.com>, relay=xxx.dynamic.example.com [192.0.2.2], reject=550 5.7.1 <123@example.com>... Relaying denied. Proper authentication required.z smtp1 sm-mta[21134]: s2000000000002: ruleset=check_rcpt, arg1=<345@example.com>, relay=xxx.dynamic.example.com [192.0.2.2], reject=550 5.7.1 <345@example.com>... Relaying denied. Proper authentication required.z smtp1 sm-mta[21134]: s3000000000003: ruleset=check_rcpt, arg1=<567@example.com>, relay=xxx.dynamic.example.com [192.0.2.2], reject=550 5.7.1 <567@example.com>... Relaying denied. Proper authentication required.z[test-phase sendmail-auth]rpz[sendmail-auth] Ban 192.0.2.1z1 ticket(s) in 'sendmail-auth'Trrrz[test-phase sendmail-reject]z[sendmail-reject] Ban 192.0.2.2z 1 ticket(s) in 'sendmail-reject'z[test-phase restart sendmail-*]r%r~r}roz%[sendmail-auth] Restore Ban 192.0.2.1rz'[sendmail-reject] Restore Ban 192.0.2.2z[test-phase stop server])rbrrrr-rrXrr4rr[rrrrrrrPr) rrtrrrtofn smaut_msg smrej_msgtdmr'r'r(testServerJails_Sendmailwsv (              z+Fail2banServerTest.testServerJails_Sendmailcst|dt|dttdd=fdd }d>fd d }|dd d |d dd |td|d|t|dtdgttt dfdRt |j dddt dt |dtdt |j ddddt dt |dd tfddtdgttt dfd R|j d!d"dt d|d#|t|d$d%d&d'|j d(d)dt ddt |d*td+t |j d,dt dt |d-|t|d$d%d&d'|j d(d.dt d|d/td0d1itjfd2d3}d4|d4d5dtfd6dtjtjjr-d7nd8dffd9d: }|_|t|d;|j|j dd d0<|j d;dd<!dS)?Nr_rRrjrSTc sLtdd|}t|ddddd|rdndd tjjtjkr$t|dSdS) NrjrTrmrsrPrnzeactionban = printf %%s "[%(name)s] %(actname)s: ++ ban -c -t : "ziactionprolong = printf %%s "[%(name)s] %(actname)s: ++ prolong -c -t : "zBactionunban = printf %%b '[%(name)s] %(actname)s: -- unban ')rbrXrrrrrr)rUprolongrTrYr'r(rZs z@Fail2banServerTest.testServerObserver.._write_action_cfgr\csdttdddddddddd d d dd d |dddddddtjjtjkr0ttddSdS)NrarmrrrPrsr]r^z findtime = 1mz bantime = 5mzbantime.increment = truer_r`rarbz*action = test-action1[name='%(__name__)s']z* test-action2[name='%(__name__)s']rdzXfailregex = ^\s*failure 401|403 from :\s*.*$rKre)rh)rrjr'r(rms*  z>Fail2banServerTest.testServerObserver.._write_jail_cfgF)rUrrnrmz[test-phase 0) time-0]r%rpz> failure 401 from 192.0.2.11: I'm bad "hacker" `` $(echo test)rczDstdout: '[test-jail1] test-action1: ++ ban 192.0.2.11 -c 1 -t 300 : zDstdout: '[test-jail1] test-action2: ++ ban 192.0.2.11 -c 1 -t 300 : rz[test-phase 1) time+10m] z7stdout: '[test-jail1] test-action1: -- unban 192.0.2.11z7stdout: '[test-jail1] test-action2: -- unban 192.0.2.11z0 ticket(s) in 'test-jail1'z[test-phase 2) time+10m]csSrYr'r')wakeObsr'r(r9rz7Fail2banServerTest.testServerObserver..zC failure 401 from 192.0.2.11: I'm very bad "hacker" `` $(echo test)r zDstdout: '[test-jail1] test-action1: ++ ban 192.0.2.11 -c 2 -t 300 : zDstdout: '[test-jail1] test-action2: ++ ban 192.0.2.11 -c 2 -t 300 : z"[test-phase 2) time+10m - get-ips]rrvrsz --with-timez 192.0.2.11z+ 300 =z[test-phase 2) time+11m]rzHstdout: '[test-jail1] test-action2: ++ prolong 192.0.2.11 -c 2 -t 600 : z"[test-phase 2) time+11m - get-ips]z+ 600 =z'[test-phase end) stop on busy observer]statercs<tddd<tfddttddS)Nz!++ observer enters busy state ...rrc ddkS)Nrr r'r'r5r'r(rerzMFail2banServerTest.testServerObserver.._long_action..z-- observer leaves busy state.)rr$rr8rdb_purger')r5obsMainr'r( _long_actionbs z;Fail2banServerTest.testServerObserver.._long_actioncallcSrrYr'r'r'r'r(rircr)Nrrr'r'rr'r(rkrg{Gz?g?cs ||SrYr')wtime forceQuit) obsMain_stopr'r(_stopns z4Fail2banServerTest.testServerObserver.._stopzobserver leaves busy staterq)rST)r\)"rbrrrXrrrrrrr-r6rr4r/r@r!r1r2addrr8rrrrr'rrrPidler_ObserverThread__dbr)rrtrrZrmrrr')r5rrrrjrr(testServerObservers                  z%Fail2banServerTest.testServerObserverFcCs|tdSrY)rrr r'r'r(_testServerStartStop~sz'Fail2banServerTest._testServerStartStopcCstdD]}|qdS)Ni)ranger)rir'r'r(testServerStartStops  z&Fail2banServerTest.testServerStartStopN)rDrErF _exec_serverrrrErrrGrHrNrQrrrrskip_if_cfg_missingrrrrrr'r'r'r(rDsL       t  : &L rD)FNr\r]r'r^N)` __author__ __copyright__ __license__rrr~r(r-rros.pathrrbrrrr functoolsr threadingr clientr r rclient.fail2bancmdlinerclient.fail2banclientrrCrrclient.fail2banserverrrrPrr server.mytimer server.utilsrutilsrrrrrrrrr|r r!helpersr"rDrr getServerPathr r maxWaitTimerr4rrrrr)r"r/r1r6r@rBrIrrrLrN input_command PRODUCTIONdumpFilerrXr[rrrrrrrr rDr'r'r'r(s       ,      W , FhU