PNG  IHDRX cHRMz&u0`:pQ<bKGD pHYsodtIME MeqIDATxw]Wug^Qd˶ 6`!N:!@xI~)%7%@Bh&`lnjVF29gΨ4E$|>cɚ{gk= %,a KX%,a KX%,a KX%,a KX%,a KX%,a KX%, b` ǟzeאfp]<!SJmɤY޲ڿ,%c ~ع9VH.!Ͳz&QynֺTkRR.BLHi٪:l;@(!MԴ=žI,:o&N'Kù\vRmJ雵֫AWic H@" !: Cé||]k-Ha oݜ:y F())u]aG7*JV@J415p=sZH!=!DRʯvɱh~V\}v/GKY$n]"X"}t@ xS76^[bw4dsce)2dU0 CkMa-U5tvLƀ~mlMwfGE/-]7XAƟ`׮g ewxwC4\[~7@O-Q( a*XGƒ{ ՟}$_y3tĐƤatgvێi|K=uVyrŲlLӪuܿzwk$m87k( `múcE)"@rK( z4$D; 2kW=Xb$V[Ru819קR~qloѱDyįݎ*mxw]y5e4K@ЃI0A D@"BDk_)N\8͜9dz"fK0zɿvM /.:2O{ Nb=M=7>??Zuo32 DLD@D| &+֎C #B8ַ`bOb $D#ͮҪtx]%`ES`Ru[=¾!@Od37LJ0!OIR4m]GZRJu$‡c=%~s@6SKy?CeIh:[vR@Lh | (BhAMy=݃  G"'wzn޺~8ԽSh ~T*A:xR[ܹ?X[uKL_=fDȊ؂p0}7=D$Ekq!/t.*2ʼnDbŞ}DijYaȲ(""6HA;:LzxQ‘(SQQ}*PL*fc\s `/d'QXW, e`#kPGZuŞuO{{wm[&NBTiiI0bukcA9<4@SӊH*؎4U/'2U5.(9JuDfrޱtycU%j(:RUbArLֺN)udA':uGQN"-"Is.*+k@ `Ojs@yU/ H:l;@yyTn}_yw!VkRJ4P)~y#)r,D =ě"Q]ci'%HI4ZL0"MJy 8A{ aN<8D"1#IJi >XjX֔#@>-{vN!8tRݻ^)N_╗FJEk]CT՟ YP:_|H1@ CBk]yKYp|og?*dGvzنzӴzjֺNkC~AbZƷ`.H)=!QͷVTT(| u78y֮}|[8-Vjp%2JPk[}ԉaH8Wpqhwr:vWª<}l77_~{s۴V+RCģ%WRZ\AqHifɤL36: #F:p]Bq/z{0CU6ݳEv_^k7'>sq*+kH%a`0ԣisqにtү04gVgW΂iJiS'3w.w}l6MC2uԯ|>JF5`fV5m`Y**Db1FKNttu]4ccsQNnex/87+}xaUW9y>ͯ骵G{䩓Գ3+vU}~jJ.NFRD7<aJDB1#ҳgSb,+CS?/ VG J?|?,2#M9}B)MiE+G`-wo߫V`fio(}S^4e~V4bHOYb"b#E)dda:'?}׮4繏`{7Z"uny-?ǹ;0MKx{:_pÚmFמ:F " .LFQLG)Q8qN q¯¯3wOvxDb\. BKD9_NN &L:4D{mm o^tֽ:q!ƥ}K+<"m78N< ywsard5+вz~mnG)=}lYݧNj'QJS{S :UYS-952?&O-:W}(!6Mk4+>A>j+i|<<|;ر^߉=HE|V#F)Emm#}/"y GII웻Jі94+v뾧xu~5C95~ūH>c@덉pʃ1/4-A2G%7>m;–Y,cyyaln" ?ƻ!ʪ<{~h~i y.zZB̃/,雋SiC/JFMmBH&&FAbϓO^tubbb_hZ{_QZ-sύodFgO(6]TJA˯#`۶ɟ( %$&+V'~hiYy>922 Wp74Zkq+Ovn錄c>8~GqܲcWꂎz@"1A.}T)uiW4="jJ2W7mU/N0gcqܗOO}?9/wìXžΏ0 >֩(V^Rh32!Hj5`;O28؇2#ݕf3 ?sJd8NJ@7O0 b־?lldщ̡&|9C.8RTWwxWy46ah嘦mh٤&l zCy!PY?: CJyв]dm4ǜҐR޻RլhX{FƯanшQI@x' ao(kUUuxW_Ñ줮[w8 FRJ(8˼)_mQ _!RJhm=!cVmm ?sFOnll6Qk}alY}; "baӌ~M0w,Ggw2W:G/k2%R,_=u`WU R.9T"v,<\Ik޽/2110Ӿxc0gyC&Ny޽JҢrV6N ``یeA16"J³+Rj*;BϜkZPJaÍ<Jyw:NP8/D$ 011z֊Ⱳ3ι֘k1V_"h!JPIΣ'ɜ* aEAd:ݺ>y<}Lp&PlRfTb1]o .2EW\ͮ]38؋rTJsǏP@芎sF\> P^+dYJLbJ C-xϐn> ι$nj,;Ǖa FU *择|h ~izť3ᤓ`K'-f tL7JK+vf2)V'-sFuB4i+m+@My=O҈0"|Yxoj,3]:cо3 $#uŘ%Y"y죯LebqtҢVzq¼X)~>4L׶m~[1_k?kxֺQ`\ |ٛY4Ѯr!)N9{56(iNq}O()Em]=F&u?$HypWUeB\k]JɩSع9 Zqg4ZĊo oMcjZBU]B\TUd34ݝ~:7ڶSUsB0Z3srx 7`:5xcx !qZA!;%͚7&P H<WL!džOb5kF)xor^aujƍ7 Ǡ8/p^(L>ὴ-B,{ۇWzֺ^k]3\EE@7>lYBȝR.oHnXO/}sB|.i@ɥDB4tcm,@ӣgdtJ!lH$_vN166L__'Z)y&kH;:,Y7=J 9cG) V\hjiE;gya~%ks_nC~Er er)muuMg2;֫R)Md) ,¶ 2-wr#F7<-BBn~_(o=KO㭇[Xv eN_SMgSҐ BS헃D%g_N:/pe -wkG*9yYSZS.9cREL !k}<4_Xs#FmҶ:7R$i,fi!~' # !6/S6y@kZkZcX)%5V4P]VGYq%H1!;e1MV<!ϐHO021Dp= HMs~~a)ަu7G^];git!Frl]H/L$=AeUvZE4P\.,xi {-~p?2b#amXAHq)MWǾI_r`S Hz&|{ +ʖ_= (YS(_g0a03M`I&'9vl?MM+m~}*xT۲(fY*V4x@29s{DaY"toGNTO+xCAO~4Ϳ;p`Ѫ:>Ҵ7K 3}+0 387x\)a"/E>qpWB=1 ¨"MP(\xp߫́A3+J] n[ʼnӼaTbZUWb={~2ooKױӰp(CS\S筐R*JغV&&"FA}J>G֐p1ٸbk7 ŘH$JoN <8s^yk_[;gy-;߉DV{c B yce% aJhDȶ 2IdйIB/^n0tNtџdcKj4϶v~- CBcgqx9= PJ) dMsjpYB] GD4RDWX +h{y`,3ꊕ$`zj*N^TP4L:Iz9~6s) Ga:?y*J~?OrMwP\](21sZUD ?ܟQ5Q%ggW6QdO+\@ ̪X'GxN @'4=ˋ+*VwN ne_|(/BDfj5(Dq<*tNt1х!MV.C0 32b#?n0pzj#!38}޴o1KovCJ`8ŗ_"]] rDUy޲@ Ȗ-;xџ'^Y`zEd?0„ DAL18IS]VGq\4o !swV7ˣι%4FѮ~}6)OgS[~Q vcYbL!wG3 7띸*E Pql8=jT\꘿I(z<[6OrR8ºC~ډ]=rNl[g|v TMTղb-o}OrP^Q]<98S¤!k)G(Vkwyqyr޽Nv`N/e p/~NAOk \I:G6]4+K;j$R:Mi #*[AȚT,ʰ,;N{HZTGMoּy) ]%dHء9Պ䠬|<45,\=[bƟ8QXeB3- &dҩ^{>/86bXmZ]]yޚN[(WAHL$YAgDKp=5GHjU&99v簪C0vygln*P)9^͞}lMuiH!̍#DoRBn9l@ xA/_v=ȺT{7Yt2N"4!YN`ae >Q<XMydEB`VU}u]嫇.%e^ánE87Mu\t`cP=AD/G)sI"@MP;)]%fH9'FNsj1pVhY&9=0pfuJ&gޤx+k:!r˭wkl03׼Ku C &ѓYt{.O.zҏ z}/tf_wEp2gvX)GN#I ݭ߽v/ .& и(ZF{e"=V!{zW`, ]+LGz"(UJp|j( #V4, 8B 0 9OkRrlɱl94)'VH9=9W|>PS['G(*I1==C<5"Pg+x'K5EMd؞Af8lG ?D FtoB[je?{k3zQ vZ;%Ɠ,]E>KZ+T/ EJxOZ1i #T<@ I}q9/t'zi(EMqw`mYkU6;[t4DPeckeM;H}_g pMww}k6#H㶏+b8雡Sxp)&C $@'b,fPߑt$RbJ'vznuS ~8='72_`{q纶|Q)Xk}cPz9p7O:'|G~8wx(a 0QCko|0ASD>Ip=4Q, d|F8RcU"/KM opKle M3#i0c%<7׿p&pZq[TR"BpqauIp$ 8~Ĩ!8Սx\ւdT>>Z40ks7 z2IQ}ItԀ<-%S⍤};zIb$I 5K}Q͙D8UguWE$Jh )cu4N tZl+[]M4k8֦Zeq֮M7uIqG 1==tLtR,ƜSrHYt&QP윯Lg' I,3@P'}'R˪e/%-Auv·ñ\> vDJzlӾNv5:|K/Jb6KI9)Zh*ZAi`?S {aiVDԲuy5W7pWeQJk֤#5&V<̺@/GH?^τZL|IJNvI:'P=Ϛt"¨=cud S Q.Ki0 !cJy;LJR;G{BJy޺[^8fK6)=yʊ+(k|&xQ2`L?Ȓ2@Mf 0C`6-%pKpm')c$׻K5[J*U[/#hH!6acB JA _|uMvDyk y)6OPYjœ50VT K}cǻP[ $:]4MEA.y)|B)cf-A?(e|lɉ#P9V)[9t.EiQPDѠ3ϴ;E:+Օ t ȥ~|_N2,ZJLt4! %ա]u {+=p.GhNcŞQI?Nd'yeh n7zi1DB)1S | S#ًZs2|Ɛy$F SxeX{7Vl.Src3E℃Q>b6G ўYCmtկ~=K0f(=LrAS GN'ɹ9<\!a`)֕y[uՍ[09` 9 +57ts6}b4{oqd+J5fa/,97J#6yν99mRWxJyѡyu_TJc`~W>l^q#Ts#2"nD1%fS)FU w{ܯ R{ ˎ󅃏џDsZSQS;LV;7 Od1&1n$ N /.q3~eNɪ]E#oM~}v֯FڦwyZ=<<>Xo稯lfMFV6p02|*=tV!c~]fa5Y^Q_WN|Vs 0ҘދU97OI'N2'8N֭fgg-}V%y]U4 峧p*91#9U kCac_AFңĪy뚇Y_AiuYyTTYЗ-(!JFLt›17uTozc. S;7A&&<ԋ5y;Ro+:' *eYJkWR[@F %SHWP 72k4 qLd'J "zB6{AC0ƁA6U.'F3:Ȅ(9ΜL;D]m8ڥ9}dU "v!;*13Rg^fJyShyy5auA?ɩGHRjo^]׽S)Fm\toy 4WQS@mE#%5ʈfFYDX ~D5Ϡ9tE9So_aU4?Ѽm%&c{n>.KW1Tlb}:j uGi(JgcYj0qn+>) %\!4{LaJso d||u//P_y7iRJ߬nHOy) l+@$($VFIQ9%EeKʈU. ia&FY̒mZ=)+qqoQn >L!qCiDB;Y<%} OgBxB!ØuG)WG9y(Ą{_yesuZmZZey'Wg#C~1Cev@0D $a@˲(.._GimA:uyw֬%;@!JkQVM_Ow:P.s\)ot- ˹"`B,e CRtaEUP<0'}r3[>?G8xU~Nqu;Wm8\RIkբ^5@k+5(By'L&'gBJ3ݶ!/㮻w҅ yqPWUg<e"Qy*167΃sJ\oz]T*UQ<\FԎ`HaNmڜ6DysCask8wP8y9``GJ9lF\G g's Nn͵MLN֪u$| /|7=]O)6s !ĴAKh]q_ap $HH'\1jB^s\|- W1:=6lJBqjY^LsPk""`]w)󭃈,(HC ?䔨Y$Sʣ{4Z+0NvQkhol6C.婧/u]FwiVjZka&%6\F*Ny#8O,22+|Db~d ~Çwc N:FuuCe&oZ(l;@ee-+Wn`44AMK➝2BRՈt7g*1gph9N) *"TF*R(#'88pm=}X]u[i7bEc|\~EMn}P瘊J)K.0i1M6=7'_\kaZ(Th{K*GJyytw"IO-PWJk)..axӝ47"89Cc7ĐBiZx 7m!fy|ϿF9CbȩV 9V-՛^pV̌ɄS#Bv4-@]Vxt-Z, &ֺ*diؠ2^VXbs֔Ìl.jQ]Y[47gj=幽ex)A0ip׳ W2[ᎇhuE^~q흙L} #-b۸oFJ_QP3r6jr+"nfzRJTUqoaۍ /$d8Mx'ݓ= OՃ| )$2mcM*cЙj}f };n YG w0Ia!1Q.oYfr]DyISaP}"dIӗթO67jqR ҊƐƈaɤGG|h;t]䗖oSv|iZqX)oalv;۩meEJ\!8=$4QU4Xo&VEĊ YS^E#d,yX_> ۘ-e\ "Wa6uLĜZi`aD9.% w~mB(02G[6y.773a7 /=o7D)$Z 66 $bY^\CuP. (x'"J60׿Y:Oi;F{w佩b+\Yi`TDWa~|VH)8q/=9!g߆2Y)?ND)%?Ǐ`k/sn:;O299yB=a[Ng 3˲N}vLNy;*?x?~L&=xyӴ~}q{qE*IQ^^ͧvü{Huu=R|>JyUlZV, B~/YF!Y\u_ݼF{_C)LD]m {H 0ihhadd nUkf3oٺCvE\)QJi+֥@tDJkB$1!Đr0XQ|q?d2) Ӣ_}qv-< FŊ߫%roppVBwü~JidY4:}L6M7f٬F "?71<2#?Jyy4뷢<_a7_=Q E=S1И/9{+93֮E{ǂw{))?maÆm(uLE#lïZ  ~d];+]h j?!|$F}*"4(v'8s<ŏUkm7^7no1w2ؗ}TrͿEk>p'8OB7d7R(A 9.*Mi^ͳ; eeUwS+C)uO@ =Sy]` }l8^ZzRXj[^iUɺ$tj))<sbDJfg=Pk_{xaKo1:-uyG0M ԃ\0Lvuy'ȱc2Ji AdyVgVh!{]/&}}ċJ#%d !+87<;qN޼Nفl|1N:8ya  8}k¾+-$4FiZYÔXk*I&'@iI99)HSh4+2G:tGhS^繿 Kتm0 вDk}֚+QT4;sC}rՅE,8CX-e~>G&'9xpW,%Fh,Ry56Y–hW-(v_,? ; qrBk4-V7HQ;ˇ^Gv1JVV%,ik;D_W!))+BoS4QsTM;gt+ndS-~:11Sgv!0qRVh!"Ȋ(̦Yl.]PQWgٳE'`%W1{ndΗBk|Ž7ʒR~,lnoa&:ü$ 3<a[CBݮwt"o\ePJ=Hz"_c^Z.#ˆ*x z̝grY]tdkP*:97YľXyBkD4N.C_[;F9`8& !AMO c `@BA& Ost\-\NX+Xp < !bj3C&QL+*&kAQ=04}cC!9~820G'PC9xa!w&bo_1 Sw"ܱ V )Yl3+ס2KoXOx]"`^WOy :3GO0g;%Yv㐫(R/r (s } u B &FeYZh0y> =2<Ϟc/ -u= c&׭,.0"g"7 6T!vl#sc>{u/Oh Bᾈ)۴74]x7 gMӒ"d]U)}" v4co[ ɡs 5Gg=XR14?5A}D "b{0$L .\4y{_fe:kVS\\O]c^W52LSBDM! C3Dhr̦RtArx4&agaN3Cf<Ԉp4~ B'"1@.b_/xQ} _߃҉/gٓ2Qkqp0շpZ2fԫYz< 4L.Cyυι1t@鎫Fe sYfsF}^ V}N<_`p)alٶ "(XEAVZ<)2},:Ir*#m_YӼ R%a||EƼIJ,,+f"96r/}0jE/)s)cjW#w'Sʯ5<66lj$a~3Kʛy 2:cZ:Yh))+a߭K::N,Q F'qB]={.]h85C9cr=}*rk?vwV렵ٸW Rs%}rNAkDv|uFLBkWY YkX מ|)1!$#3%y?pF<@<Rr0}: }\J [5FRxY<9"SQdE(Q*Qʻ)q1E0B_O24[U'],lOb ]~WjHޏTQ5Syu wq)xnw8~)c 쫬gٲߠ H% k5dƝk> kEj,0% b"vi2Wس_CuK)K{n|>t{P1򨾜j>'kEkƗBg*H%'_aY6Bn!TL&ɌOb{c`'d^{t\i^[uɐ[}q0lM˕G:‚4kb祔c^:?bpg… +37stH:0}en6x˟%/<]BL&* 5&fK9Mq)/iyqtA%kUe[ڛKN]Ě^,"`/ s[EQQm?|XJ߅92m]G.E΃ח U*Cn.j_)Tѧj̿30ڇ!A0=͜ar I3$C^-9#|pk!)?7.x9 @OO;WƝZBFU keZ75F6Tc6"ZȚs2y/1 ʵ:u4xa`C>6Rb/Yм)^=+~uRd`/|_8xbB0?Ft||Z\##|K 0>>zxv8۴吅q 8ĥ)"6>~\8:qM}#͚'ĉ#p\׶ l#bA?)|g g9|8jP(cr,BwV (WliVxxᡁ@0Okn;ɥh$_ckCgriv}>=wGzβ KkBɛ[˪ !J)h&k2%07δt}!d<9;I&0wV/ v 0<H}L&8ob%Hi|޶o&h1L|u֦y~󛱢8fٲUsւ)0oiFx2}X[zVYr_;N(w]_4B@OanC?gĦx>мgx>ΛToZoOMp>40>V Oy V9iq!4 LN,ˢu{jsz]|"R޻&'ƚ{53ўFu(<٪9:΋]B;)B>1::8;~)Yt|0(pw2N%&X,URBK)3\zz&}ax4;ǟ(tLNg{N|Ǽ\G#C9g$^\}p?556]/RP.90 k,U8/u776s ʪ_01چ|\N 0VV*3H鴃J7iI!wG_^ypl}r*jɤSR 5QN@ iZ#1ٰy;_\3\BQQ x:WJv츟ٯ$"@6 S#qe딇(/P( Dy~TOϻ<4:-+F`0||;Xl-"uw$Цi󼕝mKʩorz"mϺ$F:~E'ҐvD\y?Rr8_He@ e~O,T.(ފR*cY^m|cVR[8 JҡSm!ΆԨb)RHG{?MpqrmN>߶Y)\p,d#xۆWY*,l6]v0h15M˙MS8+EdI='LBJIH7_9{Caз*Lq,dt >+~ّeʏ?xԕ4bBAŚjﵫ!'\Ը$WNvKO}ӽmSşذqsOy?\[,d@'73'j%kOe`1.g2"e =YIzS2|zŐƄa\U,dP;jhhhaxǶ?КZ՚.q SE+XrbOu%\GتX(H,N^~]JyEZQKceTQ]VGYqnah;y$cQahT&QPZ*iZ8UQQM.qo/T\7X"u?Mttl2Xq(IoW{R^ ux*SYJ! 4S.Jy~ BROS[V|žKNɛP(L6V^|cR7i7nZW1Fd@ Ara{詑|(T*dN]Ko?s=@ |_EvF]׍kR)eBJc" MUUbY6`~V޴dJKß&~'d3i WWWWWW
Current Directory: /opt/saltstack/salt/lib/python3.10/site-packages/salt/states
Viewing File: /opt/saltstack/salt/lib/python3.10/site-packages/salt/states/iptables.py
""" Management of iptables ====================== This is an iptables-specific module designed to manage Linux firewalls. It is expected that this state module, and other system-specific firewall states, may at some point be deprecated in favor of a more generic ``firewall`` state. .. code-block:: yaml httpd: iptables.append: - table: filter - chain: INPUT - jump: ACCEPT - match: state - connstate: NEW - dport: 80 - protocol: tcp - sport: 1025:65535 - save: True httpd: iptables.append: - table: filter - chain: INPUT - jump: ACCEPT - match: - state - comment - comment: "Allow HTTP" - connstate: NEW - dport: 80 - protocol: tcp - sport: 1025:65535 - save: True httpd: iptables.append: - table: filter - chain: INPUT - jump: ACCEPT - match: - state - comment - comment: "Allow HTTP" - connstate: NEW - source: '127.0.0.1' - dport: 80 - protocol: tcp - sport: 1025:65535 - save: True .. Invert Rule httpd: iptables.append: - table: filter - chain: INPUT - jump: ACCEPT - match: - state - comment - comment: "Allow HTTP" - connstate: NEW - source: '! 127.0.0.1' - dport: 80 - protocol: tcp - sport: 1025:65535 - save: True httpd: iptables.append: - table: filter - chain: INPUT - jump: ACCEPT - match: - state - comment - comment: "Allow HTTP" - connstate: NEW - source: 'not 127.0.0.1' - dport: 80 - protocol: tcp - sport: 1025:65535 - save: True httpd: iptables.append: - table: filter - family: ipv6 - chain: INPUT - jump: ACCEPT - match: state - connstate: NEW - dport: 80 - protocol: tcp - sport: 1025:65535 - save: True httpd: iptables.append: - table: filter - family: ipv4 - chain: INPUT - jump: ACCEPT - match: state - connstate: NEW - dports: - 80 - 443 - protocol: tcp - sport: 1025:65535 - save: True httpd: iptables.insert: - position: 1 - table: filter - chain: INPUT - jump: ACCEPT - match: state - connstate: NEW - dport: 80 - protocol: tcp - sport: 1025:65535 - save: True httpd: iptables.insert: - position: 1 - table: filter - family: ipv6 - chain: INPUT - jump: ACCEPT - match: state - connstate: NEW - dport: 80 - protocol: tcp - sport: 1025:65535 - save: True httpd: iptables.delete: - table: filter - chain: INPUT - jump: ACCEPT - match: state - connstate: NEW - dport: 80 - protocol: tcp - sport: 1025:65535 - save: True httpd: iptables.delete: - position: 1 - table: filter - chain: INPUT - jump: ACCEPT - match: state - connstate: NEW - dport: 80 - protocol: tcp - sport: 1025:65535 - save: True httpd: iptables.delete: - table: filter - family: ipv6 - chain: INPUT - jump: ACCEPT - match: state - connstate: NEW - dport: 80 - protocol: tcp - sport: 1025:65535 - save: True default to accept: iptables.set_policy: - chain: INPUT - policy: ACCEPT .. note:: Whereas iptables will accept ``-p``, ``--proto[c[o[l]]]`` as synonyms of ``--protocol``, if ``--proto`` appears in an iptables command after the appearance of ``-m policy``, it is interpreted as the ``--proto`` option of the policy extension (see the iptables-extensions(8) man page). Example rules for IPSec policy: .. code-block:: yaml accept_esp_in: iptables.append: - table: filter - chain: INPUT - jump: ACCEPT - source: 10.20.0.0/24 - destination: 10.10.0.0/24 - in-interface: eth0 - match: policy - dir: in - pol: ipsec - reqid: 1 - proto: esp accept_esp_forward_in: iptables.append: - use: - iptables: accept_esp_in - chain: FORWARD accept_esp_out: iptables.append: - table: filter - chain: OUTPUT - jump: ACCEPT - source: 10.10.0.0/24 - destination: 10.20.0.0/24 - out-interface: eth0 - match: policy - dir: out - pol: ipsec - reqid: 1 - proto: esp accept_esp_forward_out: iptables.append: - use: - iptables: accept_esp_out - chain: FORWARD .. note:: ``name`` is reserved for the Salt state name. To pass ``--name EXAMPLE`` to iptables, provide it with ``- name_: EXAMPLE``. .. note:: Various functions of the ``iptables`` module use the ``--check`` option. If the version of ``iptables`` on the target system does not include this option, an alternate version of this check will be performed using the output of iptables-save. This may have unintended consequences on legacy releases of ``iptables``. """ import copy from salt.state import STATE_INTERNAL_KEYWORDS as _STATE_INTERNAL_KEYWORDS def __virtual__(): """ Only load if the locale module is available in __salt__ """ if "iptables.version" in __salt__: return True return (False, "iptables module could not be loaded") def chain_present(name, table="filter", family="ipv4"): """ .. versionadded:: 2014.1.0 Verify the chain is exist. name A user-defined chain name. table The table to own the chain. family Networking family, either ipv4 or ipv6 """ ret = {"name": name, "changes": {}, "result": None, "comment": ""} chain_check = __salt__["iptables.check_chain"](table, name, family) if chain_check is True: ret["result"] = True ret["comment"] = "iptables {} chain is already exist in {} table for {}".format( name, table, family ) return ret if __opts__["test"]: ret["comment"] = "iptables {} chain in {} table needs to be set for {}".format( name, table, family ) return ret command = __salt__["iptables.new_chain"](table, name, family) if command is True: ret["changes"] = {"locale": name} ret["result"] = True ret["comment"] = "iptables {} chain in {} table create success for {}".format( name, table, family ) return ret else: ret["result"] = False ret["comment"] = "Failed to create {} chain in {} table: {} for {}".format( name, table, command.strip(), family ) return ret def chain_absent(name, table="filter", family="ipv4"): """ .. versionadded:: 2014.1.0 Verify the chain is absent. table The table to remove the chain from family Networking family, either ipv4 or ipv6 """ ret = {"name": name, "changes": {}, "result": None, "comment": ""} chain_check = __salt__["iptables.check_chain"](table, name, family) if not chain_check: ret["result"] = True ret["comment"] = ( "iptables {} chain is already absent in {} table for {}".format( name, table, family ) ) return ret if __opts__["test"]: ret["comment"] = "iptables {} chain in {} table needs to be removed {}".format( name, table, family ) return ret flush_chain = __salt__["iptables.flush"](table, name, family) if not flush_chain: command = __salt__["iptables.delete_chain"](table, name, family) if command is True: ret["changes"] = {"locale": name} ret["result"] = True ret["comment"] = ( "iptables {} chain in {} table delete success for {}".format( name, table, family ) ) else: ret["result"] = False ret["comment"] = "Failed to delete {} chain in {} table: {} for {}".format( name, table, command.strip(), family ) else: ret["result"] = False ret["comment"] = "Failed to flush {} chain in {} table: {} for {}".format( name, table, flush_chain.strip(), family ) return ret def append(name, table="filter", family="ipv4", **kwargs): """ .. versionadded:: 0.17.0 Add a rule to the end of the specified chain. If the rule is already present anywhere in the chain, its position is not changed. name A user-defined name to call this rule by in another part of a state or formula. This should not be an actual rule. table The table that owns the chain which should be modified family Network family, ipv4 or ipv6. save If set to a true value, the new iptables rules for the given family will be saved to a file. If the value is True, rules are saved to an OS-dependent file that will be loaded during system startup, resulting in the firewall rule remaining active across reboots if possible. Note that loading the iptables rules during system startup may require non-default packages to be installed. On Debian-derived systems, the iptables-persistent package is required. If the value is a string, it is taken to be a filename to which the rules will be saved. Arranging for the rules to be loaded during system startup must be done separately. All other arguments are passed in with the same name as the long option that would normally be used for iptables, with one exception: ``--state`` is specified as `connstate` instead of `state` (not to be confused with `ctstate`). Jump options that doesn't take arguments should be passed in with an empty string. """ ret = {"name": name, "changes": {}, "result": None, "comment": ""} if "rules" in kwargs: ret["changes"]["locale"] = [] comments = [] save = False for rule in kwargs["rules"]: if "rules" in rule: del rule["rules"] if "__agg__" in rule: del rule["__agg__"] if "save" in rule and rule["save"]: save = True if rule["save"] is not True: save_file = rule["save"] else: save_file = True rule["save"] = False _ret = append(**rule) if "locale" in _ret["changes"]: ret["changes"]["locale"].append(_ret["changes"]["locale"]) comments.append(_ret["comment"]) ret["result"] = _ret["result"] if save: if save_file is True: save_file = None __salt__["iptables.save"](filename=save_file, family=family) if not ret["changes"]["locale"]: del ret["changes"]["locale"] ret["comment"] = "\n".join(comments) return ret if "__agg__" in kwargs: del kwargs["__agg__"] for ignore in _STATE_INTERNAL_KEYWORDS: if ignore in kwargs: del kwargs[ignore] kwargs["name"] = name kwargs["table"] = table rule = __salt__["iptables.build_rule"](family=family, **kwargs) command = __salt__["iptables.build_rule"]( full="True", family=family, command="A", **kwargs ) if __salt__["iptables.check"](table, kwargs["chain"], rule, family) is True: ret["result"] = True ret["comment"] = "iptables rule for {} already set ({}) for {}".format( name, command.strip(), family ) if "save" in kwargs and kwargs["save"]: if kwargs["save"] is not True: filename = kwargs["save"] else: filename = None saved_rules = __salt__["iptables.get_saved_rules"]( conf_file=filename, family=family ) _rules = __salt__["iptables.get_rules"](family=family) __rules = [] for table in _rules: for chain in _rules[table]: __rules.append(_rules[table][chain].get("rules")) __saved_rules = [] for table in saved_rules: for chain in saved_rules[table]: __saved_rules.append(saved_rules[table][chain].get("rules")) # Only save if rules in memory are different than saved rules if __rules != __saved_rules: out = __salt__["iptables.save"](filename=filename, family=family) ret["comment"] += "\nSaved iptables rule {} for {}\n{}\n{}".format( name, family, command.strip(), out ) return ret if __opts__["test"]: ret["comment"] = "iptables rule for {} needs to be set ({}) for {}".format( name, command.strip(), family ) return ret if __salt__["iptables.append"](table, kwargs["chain"], rule, family): ret["changes"] = {"locale": name} ret["result"] = True ret["comment"] = "Set iptables rule for {} to: {} for {}".format( name, command.strip(), family ) if "save" in kwargs and kwargs["save"]: if kwargs["save"] is not True: filename = kwargs["save"] else: filename = None out = __salt__["iptables.save"](filename=filename, family=family) ret["comment"] = "Set and saved iptables rule {} for {}\n{}\n{}".format( name, family, command.strip(), out ) return ret else: ret["result"] = False ret["comment"] = ( "Failed to set iptables rule for {}.\nAttempted rule was {} for {}".format( name, command.strip(), family ) ) return ret def insert(name, table="filter", family="ipv4", **kwargs): """ .. versionadded:: 2014.1.0 Insert a rule into a chain. If the rule is already present anywhere in the chain, its position is not changed. name A user-defined name to call this rule by in another part of a state or formula. This should not be an actual rule. table The table that owns the chain that should be modified family Networking family, either ipv4 or ipv6 position The numerical representation of where the rule should be inserted into the chain. Note that ``-1`` is not a supported position value. save If set to a true value, the new iptables rules for the given family will be saved to a file. See the ``append`` state for more details. All other arguments are passed in with the same name as the long option that would normally be used for iptables, with one exception: ``--state`` is specified as `connstate` instead of `state` (not to be confused with `ctstate`). Jump options that doesn't take arguments should be passed in with an empty string. """ ret = {"name": name, "changes": {}, "result": None, "comment": ""} if "rules" in kwargs: ret["changes"]["locale"] = [] comments = [] save = False for rule in kwargs["rules"]: if "rules" in rule: del rule["rules"] if "__agg__" in rule: del rule["__agg__"] if "save" in rule and rule["save"]: save = True if rule["save"] is not True: save_file = rule["save"] else: save_file = True rule["save"] = False _ret = insert(**rule) if "locale" in _ret["changes"]: ret["changes"]["locale"].append(_ret["changes"]["locale"]) comments.append(_ret["comment"]) ret["result"] = _ret["result"] if save: if save_file is True: save_file = None __salt__["iptables.save"](filename=save_file, family=family) if not ret["changes"]["locale"]: del ret["changes"]["locale"] ret["comment"] = "\n".join(comments) return ret for ignore in _STATE_INTERNAL_KEYWORDS: if ignore in kwargs: del kwargs[ignore] kwargs["name"] = name kwargs["table"] = table rule = __salt__["iptables.build_rule"](family=family, **kwargs) command = __salt__["iptables.build_rule"]( full=True, family=family, command="I", **kwargs ) if __salt__["iptables.check"](table, kwargs["chain"], rule, family) is True: ret["result"] = True ret["comment"] = "iptables rule for {} already set for {} ({})".format( name, family, command.strip() ) if "save" in kwargs and kwargs["save"]: if kwargs["save"] is not True: filename = kwargs["save"] else: filename = None saved_rules = __salt__["iptables.get_saved_rules"]( conf_file=filename, family=family ) _rules = __salt__["iptables.get_rules"](family=family) __rules = [] for table in _rules: for chain in _rules[table]: __rules.append(_rules[table][chain].get("rules")) __saved_rules = [] for table in saved_rules: for chain in saved_rules[table]: __saved_rules.append(saved_rules[table][chain].get("rules")) # Only save if rules in memory are different than saved rules if __rules != __saved_rules: out = __salt__["iptables.save"](filename=filename, family=family) ret["comment"] += "\nSaved iptables rule {} for {}\n{}\n{}".format( name, family, command.strip(), out ) return ret if __opts__["test"]: ret["comment"] = "iptables rule for {} needs to be set for {} ({})".format( name, family, command.strip() ) return ret if not __salt__["iptables.insert"]( table, kwargs["chain"], kwargs["position"], rule, family ): ret["changes"] = {"locale": name} ret["result"] = True ret["comment"] = "Set iptables rule for {} to: {} for {}".format( name, command.strip(), family ) if "save" in kwargs and kwargs["save"]: if kwargs["save"] is not True: filename = kwargs["save"] else: filename = None out = __salt__["iptables.save"](filename=filename, family=family) ret["comment"] = "Set and saved iptables rule {} for {}\n{}\n{}".format( name, family, command.strip(), out ) return ret else: ret["result"] = False ret["comment"] = ( "Failed to set iptables rule for {}.\nAttempted rule was {}".format( name, command.strip() ) ) return ret def delete(name, table="filter", family="ipv4", **kwargs): """ .. versionadded:: 2014.1.0 Delete a rule from a chain if present. If the rule is already absent, this is not an error and nothing is changed. name A user-defined name to call this rule by in another part of a state or formula. This should not be an actual rule. table The table that owns the chain that should be modified family Networking family, either ipv4 or ipv6 save If set to a true value, the new iptables rules for the given family will be saved to a file. See the ``append`` state for more details. All other arguments are passed in with the same name as the long option that would normally be used for iptables, with one exception: ``--state`` is specified as `connstate` instead of `state` (not to be confused with `ctstate`). Jump options that doesn't take arguments should be passed in with an empty string. """ ret = {"name": name, "changes": {}, "result": None, "comment": ""} if "rules" in kwargs: ret["changes"]["locale"] = [] comments = [] save = False for rule in kwargs["rules"]: if "rules" in rule: del rule["rules"] if "__agg__" in rule: del rule["__agg__"] if "save" in rule and rule["save"]: if rule["save"] is not True: save_file = rule["save"] else: save_file = True rule["save"] = False _ret = delete(**rule) if "locale" in _ret["changes"]: ret["changes"]["locale"].append(_ret["changes"]["locale"]) comments.append(_ret["comment"]) ret["result"] = _ret["result"] if save: if save_file is True: save_file = None __salt__["iptables.save"](filename=save_file, family=family) if not ret["changes"]["locale"]: del ret["changes"]["locale"] ret["comment"] = "\n".join(comments) return ret for ignore in _STATE_INTERNAL_KEYWORDS: if ignore in kwargs: del kwargs[ignore] kwargs["name"] = name kwargs["table"] = table rule = __salt__["iptables.build_rule"](family=family, **kwargs) command = __salt__["iptables.build_rule"]( full=True, family=family, command="D", **kwargs ) if not __salt__["iptables.check"](table, kwargs["chain"], rule, family) is True: if "position" not in kwargs: ret["result"] = True ret["comment"] = "iptables rule for {} already absent for {} ({})".format( name, family, command.strip() ) return ret if __opts__["test"]: ret["comment"] = "iptables rule for {} needs to be deleted for {} ({})".format( name, family, command.strip() ) return ret if "position" in kwargs: result = __salt__["iptables.delete"]( table, kwargs["chain"], family=family, position=kwargs["position"] ) else: result = __salt__["iptables.delete"]( table, kwargs["chain"], family=family, rule=rule ) if not result: ret["changes"] = {"locale": name} ret["result"] = True ret["comment"] = f"Delete iptables rule for {name} {command.strip()}" if "save" in kwargs and kwargs["save"]: if kwargs["save"] is not True: filename = kwargs["save"] else: filename = None out = __salt__["iptables.save"](filename=filename, family=family) ret["comment"] = "Deleted and saved iptables rule {} for {}\n{}\n{}".format( name, family, command.strip(), out ) return ret else: ret["result"] = False ret["comment"] = ( "Failed to delete iptables rule for {}.\nAttempted rule was {}".format( name, command.strip() ) ) return ret def set_policy(name, table="filter", family="ipv4", **kwargs): """ .. versionadded:: 2014.1.0 Sets the default policy for iptables firewall tables table The table that owns the chain that should be modified family Networking family, either ipv4 or ipv6 policy The requested table policy save If set to a true value, the new iptables rules for the given family will be saved to a file. See the ``append`` state for more details. """ ret = {"name": name, "changes": {}, "result": None, "comment": ""} for ignore in _STATE_INTERNAL_KEYWORDS: if ignore in kwargs: del kwargs[ignore] if ( __salt__["iptables.get_policy"](table, kwargs["chain"], family) == kwargs["policy"] ): ret["result"] = True ret["comment"] = ( "iptables default policy for chain {} on table {} for {} already set to {}".format( kwargs["chain"], table, family, kwargs["policy"] ) ) return ret if __opts__["test"]: ret["comment"] = ( "iptables default policy for chain {} on table {} for {} needs to be set" " to {}".format(kwargs["chain"], table, family, kwargs["policy"]) ) return ret if not __salt__["iptables.set_policy"]( table, kwargs["chain"], kwargs["policy"], family ): ret["changes"] = {"locale": name} ret["result"] = True ret["comment"] = "Set default policy for {} to {} family {}".format( kwargs["chain"], kwargs["policy"], family ) if "save" in kwargs and kwargs["save"]: if kwargs["save"] is not True: filename = kwargs["save"] else: filename = None __salt__["iptables.save"](filename=filename, family=family) ret["comment"] = ( "Set and saved default policy for {} to {} family {}".format( kwargs["chain"], kwargs["policy"], family ) ) return ret else: ret["result"] = False ret["comment"] = "Failed to set iptables default policy" return ret def flush(name, table="filter", family="ipv4", **kwargs): """ .. versionadded:: 2014.1.0 Flush current iptables state table The table that owns the chain that should be modified family Networking family, either ipv4 or ipv6 chain The chain to be flushed. All the chains in the table if none is given. """ ret = {"name": name, "changes": {}, "result": None, "comment": ""} for ignore in _STATE_INTERNAL_KEYWORDS: if ignore in kwargs: del kwargs[ignore] if "chain" not in kwargs: kwargs["chain"] = "" if __opts__["test"]: ret["comment"] = ( "iptables rules in {} table {} chain {} family needs to be flushed".format( name, table, family ) ) return ret if not __salt__["iptables.flush"](table, kwargs["chain"], family): ret["changes"] = {"locale": name} ret["result"] = True ret["comment"] = "Flush iptables rules in {} table {} chain {} family".format( table, kwargs["chain"], family ) return ret else: ret["result"] = False ret["comment"] = "Failed to flush iptables rules" return ret def mod_aggregate(low, chunks, running): """ The mod_aggregate function which looks up all rules in the available low chunks and merges them into a single rules ref in the present low data """ rules = [] agg_enabled = [ "append", "insert", ] if low.get("fun") not in agg_enabled: return low for chunk in chunks: tag = __utils__["state.gen_tag"](chunk) if tag in running: # Already ran the iptables state, skip aggregation continue if chunk.get("state") == "iptables": if "__agg__" in chunk: continue # Check for the same function if chunk.get("fun") != low.get("fun"): continue if chunk not in rules: rules.append(copy.deepcopy(chunk)) chunk["__agg__"] = True if rules: if "rules" in low: low["rules"].extend(rules) else: low["rules"] = rules return low