From 4aa0865d9fa00ddb5dc12dddf7208bf53f14075a Mon Sep 17 00:00:00 2001 From: rebortg Date: Thu, 23 Nov 2023 21:09:57 +0100 Subject: [PATCH] backport Firewall docs from master --- .../images/firewall-bridge-packet-flow.png | Bin 0 -> 22625 bytes .../images/firewall-flowtable-packet-flow.png | Bin 0 -> 47883 bytes .../images/firewall-fwd-packet-flow.png | Bin 0 -> 39628 bytes .../images/firewall-gral-packet-flow.png | Bin 0 -> 40500 bytes .../images/firewall-input-packet-flow.png | Bin 0 -> 56752 bytes docs/_static/images/firewall-traditional.png | Bin 0 -> 53437 bytes docs/_static/images/firewall-zonebased.png | Bin 0 -> 55621 bytes docs/configexamples/zone-policy.rst | 2 +- docs/configuration/firewall/bridge.rst | 42 + docs/configuration/firewall/flowtables.rst | 52 + .../configuration/firewall/general-legacy.rst | 19 +- docs/configuration/firewall/general.rst | 1506 ----------------- .../configuration/firewall/global-options.rst | 117 ++ docs/configuration/firewall/groups.rst | 210 +++ docs/configuration/firewall/index.rst | 199 ++- docs/configuration/firewall/ipv4.rst | 1145 +++++++++++++ docs/configuration/firewall/ipv6.rst | 1167 +++++++++++++ docs/configuration/firewall/zone.rst | 39 +- 18 files changed, 2966 insertions(+), 1532 deletions(-) create mode 100644 docs/_static/images/firewall-bridge-packet-flow.png create mode 100644 docs/_static/images/firewall-flowtable-packet-flow.png create mode 100644 docs/_static/images/firewall-fwd-packet-flow.png create mode 100644 docs/_static/images/firewall-gral-packet-flow.png create mode 100644 docs/_static/images/firewall-input-packet-flow.png create mode 100644 docs/_static/images/firewall-traditional.png create mode 100644 docs/_static/images/firewall-zonebased.png create mode 100644 docs/configuration/firewall/bridge.rst create mode 100644 docs/configuration/firewall/flowtables.rst delete mode 100644 docs/configuration/firewall/general.rst create mode 100644 docs/configuration/firewall/global-options.rst create mode 100644 docs/configuration/firewall/groups.rst create mode 100644 docs/configuration/firewall/ipv4.rst create mode 100644 docs/configuration/firewall/ipv6.rst diff --git a/docs/_static/images/firewall-bridge-packet-flow.png b/docs/_static/images/firewall-bridge-packet-flow.png new file mode 100644 index 0000000000000000000000000000000000000000..9e32315eca7deffb53c007bf2e320e9c0bea3a0b GIT binary patch literal 22625 zcmdRWg*a4 z!(Ugeg`Uf!!^;I-&maCxWFx9<^V;0N#$MY>A7N-_ZmQ2{t!t&PZ)R;|ZnKG6!v}Ao zMZQVcN?+T?*xZa#-q=(hVQRcg`GkYg%-oKWaqLg%V*OL3dC_ssMxL8@P zv$G(bKsZUbVIFe+Lr$RzKl?G|3CSz9HFHD8QPax4l93u29!%rVdT(t184?XK3dM<;{EgLzS=nR z|GqZB>ur^Pbmzs37fG^oT|GT0A!4bcw7BS$1VPi&(;l_80uuM|X-Ypa_`FCLdi4tL zTXuG`V)kjAwVj>ahZeo9!^1^R@xL>?hdAB*+L99_+|bZaZnsYS<;xdYWo7?ZcJrBz zcy6P2??em@ABa%nk&=;3FD&?e|Ni9a)vL7=6Xezl?H>90`312u2AMfIH&s+rjLgi$ zEG?OLc6KaI4@_B~JxfkaMO9Q(w6L&v|KkU@kdP2ADd|mTXXo}W&oHlCxzcFH_jhdJ zuZ&JN|NQwwM@Of1IsQ9Z-%=u7Zu-Y&wXmrv$b(y)j4Rb9K1$r&`iqy}UMy&I`e!V{Fc4}I)7$-|7qNGGfOibJbuf@0@Ftkq2 zzjOUXcF3I_$3Tg+wX?ISKU>Lip`ECC-U=}uZ{>RD&Yk4UOms{FhT8MfLp*ZwP@<;> z!3x$bD02%7)DIq@Eq27$AMY++30{i}3JGaIzKMt^04`DRb|b0Od@{7JPyXlGPTNq4 z2_YgWDG8CSl;3FXeyWm)0s8!sa|m7 zG)zo56%`eYd?GB&@ON`t8%cz9-uLgg$H&KFoR29eDA2E>oGr_^uh^fC|FAExUVJGc zF0OlVc6@Z)=^onH*l1~X|L+3E&>u|x2~!CsmCKSZciMl1P0r&FKYpb^N-;1rv?f{OGe4HqDhKzC|l5s}FH;JhY2rbzW%N`uf-G?GG*a7jtrRw|`+WP360v)5AJh=^NmNA(ml zUCF|9OiY8k8tUp;h^?)yF5U$=TBW6ItgNiT&i@Y01%_5F<@P3qZFua1aQF3(2?^K% zBA&3PnBAFJ)HyjhC1hm$B<>OK9&%YP+*DIjo7&vuU)bFLPN?aEm*{r#@M0&bW{JF) zz{hN|I@dX;vXZ#8wA8}NiujQ2@0h}m;kdcP*dULaV6I{+oMIFYt@g=$_~LB|@uSay z)`Sl-18h118gzc{w9-3Vo*&wVIXXM*!VWq*SYg+H-JN3&tC)YNhg9hEdRLVJ4T zQsb<*x3`bxB4jKUJIKa$Z``;sROQU>cD|~q+mrU(;b7QsyEpN|W^7dKZ@gR3C2fU!iu;=`%+%G@wjno2b8~YM zN!$<7MmMKNXJ&Nd6%};`a#Ut5{q=Ob93{1FE7-T)KolD z(qKXjhbz+3(q0?+Rg8>`K0?X0Yr{oNXGeS&N3$A-rtjWaz zhSmIFN4u(zH+6+MX!nTEv6yvj6 zX&D(I?#+-v>vDbh>GNkQMnjFocYYlmo$KS1_4TNhmX=!w2jpQ3e-8uExW&ol z$jk>nKeU65am+0Fz}D6mE;}s`V0u_iH^sDi8mJImMy$92B9)gexqh1_i5cV9lLniU zlMeV}g2eOZMBh2m&WQ@O>QESzzia*cV!~WJS+lJ? z?uneuMqj>j%5{o&gb&w=*x#u(gw6j>VM z!A)Du>_y#^4Rd|{oqZN!UD%%WT$5wtzc$@3Pqo+0Gp%1fj-q+| z7~86X6vGEawag6Sqo<&TbBeWv1wgW^h$WUkh^Z$23ueg4Tgw@VGmHF}oWJVpE$3VB zq@|@%($S%t4CHk4mO<+4roPE*UkmHC=z6H)F9j#LS>sP5RWJz1A0t#A3D) zt395ZP*6~?xwCVSck_3^E#(?FUW1OffTbm)Gl*Xz*49OWp@(P3yF-Qgm-*@pMJ|trZL0XEbTco%@Rzvf>E-41ct}Z-JNO;tc?fBb zy*nBjT7uTCA%R6T8Qx9`O-;?Ui7JxEj~~NsY`i!>?H(THTx$07>*N=XvxXp4iEEry z#;?cc)-1*E0~rue3)xJ3|Kygswe{1&qM|EFgPBw$BqWI1>3TodB*9ZtTI0IBkeO!0 z`A_g566vuJEp)^OLAu)`LQ$2I^JJfJK!x2M&8&O<=g*&8vlN$iLqb9j@1IA|URiof zS#@!;8qI2qpWwW~`6)7T=JI0m(&BJKeQmVNT)yc`Y-~`JrW+A_05T@Ndh;d_pvrAR z!r55!YC$6-ItV%+;^RYfn?k44qcl(uE~o2di1(b<3$?wyuk+bfPS0tOajEyvLi6o+ zx5Hf3vLyLOwhiP-r(qvp7e#Z~zRiyg^Dts1KA6Np27jG`yZ8ZD0oPUehV94IXZBBS z75d%k*dNxU4hI0~mV*-_^{J|g_a6R@zPJ1D7o!f&ENyN3@A&eaEYZaAxf0hNX3t@j z)ErccPcVUmmDvQ;>nr z&dxMwf)G=Xpu_<@qM)K8Pp7hq$}}K2l8agXi`2p0i=!rf6olQ{kjJ2gGo)|GJTve~ z0H1`Fm52Pps>;jnhVdTU{q^hDcikrJ;?hzb2=9>6eut2-2Mu=W}~h$OOoU1vhT7I*?11xVpR?&=5q3ih%Qd1rf$~LI(#z_SGwoBE!y={R9Br z(QKw8%_PzWrX$71z#zL;S2yx+~u4dBULJJph7 zAqWYf9rz6DMK@T?-Nz52Md>MbZ~RV9bA^cIq4wAiJ3L`zbkuTvq(mcZcxWgoB?X1u ze4@`s!G!Tmu~FAA-%@1&qSx8k*%9Nr+2?0xHoYZIe4E|k6#aKzD&}j9XLIz8jRnI} zp)B#)17W#>K!ypJEz9X&KCkZhB{;1-5269^6jG|${z#sr6%0PQl%%uNa;fQ#Y7!NEB?IXMU$)@k55mFF3l)u)k${_51Zf)(8ykVy&utHirjNdXdk8MTz4Sx`*^Ty<3p=}w{qmq7$(qj9<8qOn(@O>JhMP<7l}SR$cZ(T? zUp@NlfSj4_8BqY1dm~@Z=|hwm8Y5)*0#MPgry$r`*xHK1Mvr7vy)G^;uFfnm$%eiE z?>T3WyEvV1i`w?%Kf7Wwm?x^Ickhj=D)Phb-M^n)TB?{ohyWsWFXA!w^LzL(>^guG zFVd~L?ynUV7H)Y_oN3jrkMw6;SH+NlIq2xflQ9gY4NX{#gS*>vaa@eIzdk-;?KCV< z#uD>xXmPCmSZH-tlW6bwB~GCD@o-E#6)}~PlF}KRx5jGMQ&}Y?zqPe@3~J@FWv-e1 zCB;6!PfkuW!Up^L_A2vvah&*MRG;*$sC;sQ_>Oz`?vTl;k@(cv+yj0=MMVMvCXK(# z4clX=+LarilM}D`?!q4qiz&p*c&_wQlRuTVt73g(c`uPTQSZXH*PRgkDu??8&ttXn zCn;{XPd9xHcM_WoAq8b-W@2;XMrpY#@@N=Zq1;(YL~ zYLtM2BA@=IDAOA*J#C4$78Or8HMmtq4*}ER-?~)*(~9TnPWx?d&t|;Fk2{}}k`jUV z5EYdX`^EPB#8zHje(&^WaWSj9@;)R9XI^mz0-AgGt_s*Mbbq`r`5kC4Ff;(hheYwL zq{Ja&?C~$Tanu+HRxyOh$jB-eVI-9BexT+Yz!1Jl#iY{bsN@%uI^~iJzyhRup8FlHSii(LLp>e%a6{LNg)=v-1?KjDhhb=n#ZXCBgHaR(Y zW?tTa^q|v1jN#VtVqz*VP7-!AZ}~^-x6H5*`BewR6ArUjE=SXT01Ctb=K`=nZckEf zyLZh8@5UNR#$^kQmD^>jf%k%hmvx7Lb{@)r^iI%D~N!=Pp}X}#m2WL z92d#Pe%RyipH1U9|G}a#{bvr4>=7sy%mIVO&%0DqRB#^F6&U;6LXbH}P*xU~fboqU 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

wjLZgLJUJXc5>(~A9M78?aDp8#mR92G_`Ph? zckS&Cu+=+p0ktqt`ZgS~*{$q=!PS%D4fDwp^9uIS*gFzPiw_DbsYCU{Wl$nI5b}IS zPD6dGbmEdcE^U>#Fe;;{&7ON9(9N<@dU(VdK!Z;E!tQ0wanhReB3EZv`0)e}r;=B% zkd{sl&+E#mXTx?YDb&Ew8&b9&JuI{@8gVRs(Yl-2u49i2;(YtdMI*Z+KD(z5-!4Uw zU01}tANy^i^L*cy*pPJ}6D|szO}HYX9c(>@OsxvIj1`~y`{&EFtM+c9)S zC%J3wfcdMARsPCR`-Q=Re1ndmAI<%}{OSGuRN?BI>@;$xtgN)0-1`AN+YODMuW6?N zl~}}H%H}(Clci14(#*38j|1K?u}h5Po^!fc=|e(@4Ch#%%U9ogF~VP8(9*+C79@`* zvaT*pm~`&hlTDi4wqs_OeQ;$p$P#l_B+F4$mW_XKRSWtG?b!WTE4rTcvHbiTdhJOv z6n8vc56+yBvr99fH28bj=D)itGvVS|XJtBb+wFAp;+gnm+j^_`KFPO}RK^QIedR=b zI4Z{LS0mHz`wC9>mA)L#zpGKp$&ub9+vpcJ(yO|56+sXW44Vn1Wl3LN4O^UhayqhY z(qZNX(b;pwYce~f*rkqZ zY-x#i0+$J6R$*^;Pe?9U@8*9gmaU7Nzx*te#mZq?&8`N9MB@h0O%3X4)`;CcGJ)5 z=XEy(4*eO3Y5$OSkn6TzYp6s=;VW$f7ucilrlDl4JkoorsHiB7 z3`}eYQ6iu|Q_H;oO6PH>n%9z7$ONkToNIG0Y$s&o=9U9llq1-nyBZl88G-97^RZBu zuYci>*+XXb<#+Srz$=ZD9=X zeA6Bf{72-KlxUNEg~1ROg34o=Yt(TC z#sq_(UrL~!DmXgUe4~BaFUD{TycY+>nqtc0mmg87C(`s|7XF0U zLwa3BBj@lFS8c(ixwpIPzK(^Xqaz<;Vbji`{9bV7OgeAxHY=N(i-5E{ex%9aPjYfV z>9C_hr{yqgiEHAHjE;&S(~2U={L(?PFEYco211x8v5jO1)}k|^?lFMfn~(b5k8QIn zLk4uWD=Kn<1}(MY+`{VpuvbA<7;SAk5DzSiQ%jrJtjF_^ESNUnk9pIjhP23vWQx=GAFgSw)aU=+}uN57-UR*_dq>HbLW$V-`QJUh;H%c3KN)K~gmWKeeSiFiUJg z!yu#YE4yGWUA(=^fTyQNFSuQRmqA*1_hHLIoOM|WDNTRy0E2tjf_R^Db|!aq+2Bsy zqXyW%y^KqB{9R1drIT)~!sjo#kUHB%#mffOFT$$11OB-#5FO+ZzQMvSZC`=q&HiOE z?8h1f6|kL2Q7PEKmbIyg!Qu6s*vP%^+*BUw3CUkX|DHp%i+$wog z@nPBn&Wj-<%k+F(fEgei=FK3a|4{DsGVz~YUD#)&`%(>=R`PkD6kgN%>(ta#lp+dO zp65?~RUU$bUAvIHvwuL(?kDm#0>B4V@mo?g&infpljnjN#$0_cm}05}-L>IPSOcDn zPB55;kIemKApbm!Vm2%0Vt_DApy&T9C+9XoW(InDTTWM8X0ZtiB!r%4vw6 zQJr80fg%32RVXKF`9HMRf*0rtV^qf@VI3-UHQ{)lDBtjGDOe8Gu{R3KH$Q=PBG%ZT z-jHfaDNp`)EZq801=V*5UZdCa_>v4DJz9jPnzJmf8b))7v&f?OK+i2}sNFq!({tD& zlHC%PEBV*WE0Q@NUEb@m88wXd(4NA@N>oWy@B9IrQ9Qg-X`& z^26W#tZYPaJEs)>Z$Zo=;Q^#PDD>|KzP<(oA|Dm-gBHh|;nt(R^5_k@wZp1=_^4(1 zhJcRA3cWP;uP&vuj6lYuo?$A1ZIknxNOvOY=-VaS&B)kW%%B0XR0f;RoN|h&j2JW5 zRu>0XLSFj-d?j2Or<@hNzl5qD+RA9Hg<74c7h)E?;&4)W literal 0 HcmV?d00001 diff --git a/docs/_static/images/firewall-flowtable-packet-flow.png b/docs/_static/images/firewall-flowtable-packet-flow.png new file mode 100644 index 0000000000000000000000000000000000000000..fca7e13abb2df65a75a7627cea7cea14e3f50eb3 GIT binary patch literal 47883 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 Wp2OESUSyy?5_>8kl=(#S&Hn+E1UO~@ literal 0 HcmV?d00001 diff --git a/docs/_static/images/firewall-gral-packet-flow.png b/docs/_static/images/firewall-gral-packet-flow.png new file mode 100644 index 0000000000000000000000000000000000000000..ee4e7b708b0ec11c386dd3360f8c0d5119ebd3ac GIT binary patch literal 40500 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 Yl6G<=$8Vu{ke^83mY2x7_3*|20nZ`XUH||9 literal 0 HcmV?d00001 diff --git a/docs/_static/images/firewall-traditional.png b/docs/_static/images/firewall-traditional.png new file mode 100644 index 0000000000000000000000000000000000000000..7eb2b49dcead6984c7d4ae17c7248400a8ca7f2d GIT binary patch literal 53437 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

QGc*H+=zn2kRR2WV6*O>YwZ!F0n^)g44BS zR*z(E-!025dQ2_aK4Yxh{E{_yl^Kl#Rhv?%nv1Js6J<>c$hj>8x zYe$ya_l0O#18b}MT<>qLQnn?o_PM~DaN^fFt!p}cl-tAVweo0ox~oXC!yXNQER!u~ zhR|-;xciqxgl;HjTAivtL{m7Zy7noDbE1=3=CLu=jn)Fofrya{lj;d8HIBZc^@+D^+ro45rL-)l%zgr6GOd^CsxpJ#1_=c#`7j_eSO= zq5fXdxeGBBS2U}QTeXUP2CjX(y3?Zd*nBA^$=q#T4R^ASGKzEBcf{qzbS46#eCt1< zVVFLr^}wjPBZ8il+tf^-cSF7KTpUTV@Kj^L)$9#dZn}+?YLjC{EXvs2Fvle1&YP8v zT?35h=QF0)y>FpuYVtmb`3lD$#JOl#nP1M6ek(oqR_wlv&eo#EMg3~1>Ge|SauGfIB)h26#&mWy$Hzxr+%4L}e?X7#IO=TbWWbKLPNgR}T`gT@< z)|v@pEbXcmlb-*2Kka$&1s3i?|Kx|ZV;42gA8MbawT`2Cp*Zv4{7GRKvpavaEK1sv zXfZTu9g*?2|I6w1hlcv7`Wv$M}v*y|1Lo84x3CuGG5AL~=2y(&s1i^s233Y#sT zzlMAK)my3IkvTi!&#-FR1^{%6P1*6xNZ##NUqNansqi+3%ZWX z_HVwfE91Cjj@IOd%PD3<6dAjAd8)r!SUmHh`Au&1Ue*9N*W>1$Lk1?6S9s=c^jCaz zr|@m+C<*=8Hx7Z(+7I@cJ+F=%l82L2l{#StMrH^tce0G~jj|g5okk09+jnI?*_y6+ zb|AN?{-o6W#xm_?7A&1M1)bH4J;`qto8-Dca@heD(Pk4gE~RLes{@jY8D;;_)?UV6 zWo}I#v-0iwF>^ML-9F=wV}r))h1MHPOga3QMd<|njhf{;pz;JQgAk^qOoLpCtmYmw z)~MosdcQ~|n8|~|-7%PAUhiC!)A&|m*e~`wvwu%88wT!poDpzYRSLMm%l+Wa^n4y} z;CscRfmi(e!VSOr0S|eC*(#uBJ~$B8tHQ9wqKf4|zv2(>u@x;xi&D3HkGQfjaOk?f ze(mcX82`uP=aN9rn`k@xMr?bM`5dL(DNc49FXt|c{>{YPu%AWs(H$#7)umQ7>J+6z zGRKwz0`$@fYDi^Gcn6`V}WNEHKo>Gxp`kI;mVok-46~Tbj@($G0E0tVr*w=Rs zH>P=F(R|5ceW#7h+RaRzy|S}aiRZQO60Jf-eO$;A6PL@EobWY|Ou-9p9&)GNq+aEW zUcEJsb!Bi-^h)inODc<$Dh3$eZcH*S3E0%zRGN7=a{R*#(-}=Vx>WVNIUQ#8<9Npt z9ybpr*Zi5WY;LaKv=Zid*DH2=0*}V@8b44v;}#$>?(}(89bUB!3n96FLt1E6OLpfS zwVT=Nt`1|{Mx|?48-`mcR98OAPpRs~3RnNLA-&>gw1#rigQd^$2Sk@`&OvN=v0|Uj9aQ2AU!-HFSqGXT6)(C z6D3O3X)S~Gd)Ih6_bR;CHL;>tm7A7wS8=3lO>u@U<^EBVVb8gH(w}bh9RCZXVBgqL z=RGQ+tL$jouTPWATQ#$_AE)q^tW>(VX8Hp)v-?^)HGLjEyemEJ1hFo5p98Of^EfT5 zd1he#>ZdO{Z>P)cn_JWCjaFc)wo&L{N}XY-*&6~)HFZ+q+u6`2{a-F7)5f zIpU$_`rOC1X$wL^q<+FSKzBD}O>vuoP#`~?{8I6zU7?T@DL7i~I{irz}6 X?q^M1yhnG61o*MDnrxY4;k)2}L%0;E literal 0 HcmV?d00001 diff --git a/docs/_static/images/firewall-zonebased.png b/docs/_static/images/firewall-zonebased.png new file mode 100644 index 0000000000000000000000000000000000000000..46b2f6236ebb42fe6246579524e3f21d554f1501 GIT binary patch literal 55621 zcmeHQ2_RJ4|3^YKS+X>w#gXP^=ewTo2{zQ%oI6`+HWL%mTx~5i zBPJ&10N`^72OID^9o@4W_`~dMq^ZJ`UM~ECiRsD^MSU~H(cPNhfM=3Gs*Zn>K)`H? z&J+oxngjxYC6Q!s1gs4i>*y@wgr@*azAeGTD z;1>)fBa4yUGJZYQ2Jb|>p&rqb;NXCjKxm+4V8E@G>0zx1P86cEtprj9IM#Ne;2nU! zKr`^$z!>^1iD*L-waQ|+Kj)|dJj!~5^AT; zdbGU`*-g(L2ZLLVzl|%N>`Wj!(Ow=dgONdxpP+b<@Z+tPWTKlho;==60$$&Fyd6nx zL8?o@l!3me{~=XrqYE53VS#5H8+Cm=1(*{G^#(9k0^V)>J_Oo$Yq+~iEz)9>1M6(Si1Q zv}>rNHsK0tgRvFXfw6TH0Y?GIhf1#~_}CC5VAQL%@B|xMTF(f1+I=0d;I*_Dakj0=J`^KKj$(MUL*Ocn2y8gTqMc2cWe7|93wP2Kf^Q{hix6 znPN1|C_7{~5p3~9Lnk{;k{Mi@)`u(B!G$)q<5S{H@c;)K?}SsP&KWRDPDCf*DivFb zqXTdR2R@RCE>5^HFaYRT1&4LE9Xp_&q8=DxDF7u?*#+nb29PPh=2QYAVL!hU?Gf;} z33LASk^Vg1ns|V_DP#}erf#1}0f3>ger)Ne0Bj@U9k3LF>qJt*(kRmA)9t3>DaI-P z{2+!z0Lp-;0J#iB0|t=CP?+&Y0(){Mx{$5#v~N+zm1E&*($ z-WlwYf+gGFDgQ&4NB~$h05|~$=j)S0yLyZhzI7!7!>H_V(X-cARk0#?NUP|WZd9{2 zF_MPMjlam($kf>$PqCsR0hJJmE))lX6JGTb{!kmOiB1$%q63i(TqJ=&0{=9C$3vE{6f1-S9M}Ux^5CF8&#aiMW z42jMJ%DBj|BvL3uN4g7?9SAm5=AaNsKr5DZWCc760RI#CjQZ>}9EMZbXzZBAqtq_3 z&ZKdmwI;YzIZ%Z}B}Y72-4(bQmA0uI383AWkaBbfUYTSogLQL8$ym8K0}q8K@36sA z@NQUucD~G`)EC3k2z-ofzdpU6nd1}XeBuwdER7#PVujI;>9`m}n|69G2HQZIrf1mi z;h}$kIBBx;YsC34Vdyx6kC8XxtBmxEfh`(9IV#YBwDiwoEdU-9x&&0wUj%CrG$rb5 zfxk+_uu*4de01t7^6HHAswYAt7lx1xSwBDeyuYbl3DQH_c(gVHZX z%U=XW5b=Jz;((z|ImkXB6oWlZTfG56)4}LyS=~g7rX|s-xPVXtbbESgok)jMXauw- z2AK`Yeo(YK5^y-GCavOTOQ7J5NmwhY;^_v+U!ZNG_B;+CQ>ey2QtVEIEjS2cbW#^J zh3<@`wSg4z-%DKtO}CvmwKQAex13s}?BuznjmGqwTSj$XTYsE8e#@CffJ!e7pfQZ9 zGRUCxsxsL26EQ8Ls%)^)=-}AYW6XnV1lZ!BH}tpU zUN~mr9K+>kS_vI4gPxn8e3BVuE(7m=!!)pTAX?c^RJA55L6ZyvJRFC{V}LJARLB6s zKwcJu#LAAH!ICMUhZ4L$V2x-1{u@BmqS_A5fCfvUJN}}k^^4gOlNEauZ301w@Z(Jh z2I~cdmchW}KmX7~JNN|C*0ew}>L|Jfs>(nRit32?ErCvck{JnSR8yu0&Vd#XoiO{| z=N2LR%S{6 z{dnF$g0k=P6O5A#*yZ$PhQA-zp!s~imlpubMGl9W%65@MSR!Sqw#yV|%4ADseE6sE z3jboZ3IpZIO^T@fcw%Q@x5-^jUt*^@js6Dm{~>mO^Juyv2!8ZokMBu+7>D~QfS$oj z27N+cPd}d6C;I{>_c(oNoiWJwTSp7vFq#Gpig3{Art>#~p@E;<-w0|$bSURK+Y zXk&z-@wkfgIfdGUn$Snhxx+e`(lV&&Z~GaQ|KvxHB~JgzkEW)N+YxqpZ1zN18%rCg zI;q>Kqt&eKzb8NXPvYrVhW~U;Je6nkQiI`kdg%zZfeISEDo6#CZ|C=qrBMHGNzqf1 z=HFNG|M)Tgjvtd6=%L1XKs5{fFW9S-))Y+caysbnQ_?b{3O_!!baAvF?vwux_ssZ1 z{QABZ29G!xx&zVf$D5*JGEfF0XhNnTf6q@}IbaLnjR{@$;Az}$!UYGn~9UhMx2eYs?nzJiDc0&;r~|l&!>7Pe=7YEcGb~l~IFWa60`VRQg2XDL+qnR4hR+{5P{yB+-t`6W-rO2rBJ7xL`{L}hUu)H5y zo+jV_RQLNraz0Y^3yDkgtVJF1pSQXn#@)rz!^3T-vMxn$(+*R4J1tGT^mjn%7wUwK zS4E_*o&6-~sRwka?_XY!`=uqk4wK5EeX4T?)=c@k_0p!S`Ub|0!J=obcs$lo27#ki zG<74A?RQvV$<%^rOi5adCd2RUPoF%u zv@j%{oj;X79Zqv!gSz6s>Q8qt++ZN5C2wZ81&Nck#=zb6@UVa1P{6wrD4VG(^=0IN zRn@?v7~t4!>==!pE}x+ut5K^CQW0qEfXYAMfgzqu04jh|3nq@WeUXpHwQ%4n;EJ!2 z^tj^umFsAz`irf<0n4L;*aR+;1PSxU8!=!?-RB;sqYX194>1Z}K%JvX8z5hdTIHH- zO|1h))h=YQjwFDr$A1Hd4%9+qmgEUF1Y~!*P-_p575$WU9;?PotsxDEkpQj$1Q&Q7 z_+&%9PK^wdx24{Kt}Eb)e!i*%^i@r%{QO1U{edzV4U?H=F!@f?ZAr7tq&8gf580K-C1tu^RD=g^%e>lrh_8tgts)MFOn`01QL9MtTII)>Wq6 zR*m3j1LSKv5G;Y;SWg!+9++AUU?&4S84Hwm*U)w%xlnc(xKMyUGS05RwgLYNcEK48 z2pW;mDVcy%2Mjq)fG(P;0n)~QuV+q`^E)p7NT49ocCsPkot^2$;<$v9K&u!7yERZn zD4aU8G`R`P%%|@%P|VMf076f2|CY#uV-PYh8tj5tF@?|r9oh6`gZTN(6B@~X4IFHM znqmMUP~rG{40;5NwowJv65RA)tP{pXWAy%@@y}y^IIu4Mr|RZN#H2NtQ`A`n(VKp_ z!M2}=OBwU#7#QoD?wbiKr0DQ@lA}l&jt2IQ0icw@wPZc^1DpZ70;}tOp>Y00;8y`A zQx!(FEmUD+V4(`Y2TTS|tqu&dkN=@NL2H%8j>9zAXU1Q#=EB zG3`!NBpZLYv4*kl&^;KnyUA_fTYSF5n4tTDTW>=7e=CBs6>*0%)*3HkMRX)l_bI?@ z1DpViv!%`W2Q|=ZMt3c+^9!(RfsCaC*2#Vc4)02!Ry0-taQZvH0_=@L`wk@%R9?|U)^7HW@V|F70|Iu+2$RA(yq%tT#V@_EWtd%_#Go5hYwiZBv z#cwd(IFoLo?YTnLofy~_29twnj4?F0%?|Zoffx=B6OCqvc*!3+5dn@ zsJgVV<2 z0PIjXMzLR;=zmKTf<*UCSx7U$elbyqkOLCdCP_n-Ea-Fp=j0(0F83Y%PG6x&!(=)N zH=@g}D-`MVwG@}5Cp5)m9 zJw0@Q2=328Zy12}!a>shSN*TDD1BvPUA(g$%FIC9&`k%0QP=sNIR6C4&6L?SRCgww z&G=_e#s6|oMKtIsp$Thn8$3GFMA86a0%_9Pejd`K8PRko#-Nb>|Kv1PdK%NV%OsL1 zwnQ6haWM7Ity8!eXaN)YxaX8cEe#Lo1^JZxMw52Gm>@?^HZUi<(0;s4iv&ZfG%^Q+ zVj%tg&(a(8=mRBqfqhUv@0&|=Cj+|U_e2EfV+2!VVIxr!)gD=zQVPVb{vWp=OH>|z z&hL39umB$zsQCJKXjlJlwW_{G`(I<|-_pYRv}HMn*ofzZ zA(;m8zZfJVW|Gd z!Df;NoP|ibEj}jFCn&$^)YK_0sQ)swG9}E=UV~1mO_>S^fzophA3nXpPhYnEFSnFZT zj~UMj{JMZZ{}B-M0s<{JkszjE`RO4MXoO5B5g4HT|L3?E|N0b3Z1ir4DTNblM8By6 z(?IGM(}B_8@)epw3R>C!oC+*EX)9mZNnW*Ss{w;f#jg?dZz;ymFvjpG=nbROWv7h+ zKSidH29fMWT^`F2GNQ9~H2zpS6nbHXl9Q96vvuUb)%P?c`n0JK9f?d2;WkCa&EJ%6 zRH5@gE1zi z{_Q#rm_N)<&-|Fl3a2d1xk5(~(}eGTrl8n&XNLWvVKFpKqo>IeYSjP$X<(qf_TyDV zSum;q_V}Zmg8y}57**|~4&B#0XJ4qo@cR{4wRRwow18Fh)N1kL!!|`o`$yDwpqcA( zUWGAgQ1oI2PKL2O0?0+sk zX_^=vs{JXEiX{Q^ajXsx9wR9nPmF>L`XV@&0pA&0>o`HmSn3(#Niz# zEE*g;iz8rd$XG|(3ECHcT6;j5HtPNtLC@p-nV6O^X{#xlxSRK!V83dv9&>jO#%P8w zceuu&fJR#=`?wV|Ka4uDpHInR6Gr(u0DHRz_DuFC9(@ zir%+q3rm7uqxT04@?~RGpO=mP`|{T(+)hdwMDBX7`}Y3o!MNFy^H!tC+aZmxCWH2fBxvupWTMqBDfT zR?X04db+JzfTh}J@wJbAEXTPD@AhKyx95}d&(6ykmS}xr?NYx5X~EIRrOU2Aqn-Ia z)7BilgE=Fft*#dM))&lOqxqD(K?!E6Z|7PpzqqP@mr`s2U#o7bVe9pLr~GT%gC2L~ zZ>~#2`i%Nqxc1Rr)b7+41Z#?lQXvUNN)ZdF^*!xlwax$7jBG);$;>_S&xGL7epZ5K z&aUK><)+R`@bq9D8tx>zsc*(P(3C&#$fxW7AIvTB9%DXCI}ln)<# zgzxGw$FUwfbZz$48uaT6he}vs={oIrlci%M%~>eTZIp z;e=sVn^pLo_{7k%+r2FU=?xY!z~jT@VsTcIx^mv3(%G@e+DRq@YP>wcFN$tucW=<- zs}k}u+IQC@KdF~}Ks!jhJlN&#sYt|uzIgm_(rN9*&2cZg(suaYu$EwZwywnAY5^Rz zx%B{)h5c-`c&ZQ7%RbT7zVe8N)^qO2s#qUg!`U;0IlDvf_RK8JHPVBg0x(sDRwOf6rR}H=ol#ouMtZ$)q%1g zTx8a|b_bIYyNu8Bs6t&2+oJ$(n>CLIQG5XEpn#s~do@b_-1a0m3SSu8#3>fQ`IJ`y zI29}1=t$Te`7zb_V<@yil>hb!p^&>^Rf#y#a@kU^S1vnQ)893oH3)p1%cro=C^iUN z{_IHEgM`xXcaG(kOX`s}*;hVlKq4ag+Ht)}vGy5e>owyOd7r%Czp_L#`5cn-_TJHU z@@w_^GPcZW{yA6s9|zveHZu=}9)I&DDnVQSx{8tY;v?S8r)z_(;VxN1$t)*`*NfAJ z3oW9~=XV$P6CO!!VN1@jF0<=gncAFnsM^)T5efINx+jTpl zKEBoxzn2-K8XBziazKHQ_g*mX!>QF_D>v>};(d0dVNsY&?xDgZ9EtD)Ct#0#%3SLm zPw8cKs;3{})nkRB)(j}+8bw1?Rx9pux2-J8sPsV#;<g3KLE z=jM$@1?O;xUXY^PYP?pIo;iVe=R0;Uv}fM z#@mHig7Ct4Gp{TW7)#>46QmvMP3DGjF4$FxOHt|q^(dqMGU?5lceT!~X-_}j?}GG?y`NZ2$D9hco zgp7K%Ijk_vELNkUG>NNCH}sWPVHMZgnJbg~CDS$i^B$;iM%~pvN*WQ`>V$@SHs5MP z2QJC#=M@Wp_%%zh6fWJu#)QP_iTba($-2XFZ&Ez$K|1@BkZ{#V!Z}W|VUq$RdqAN} z|5cJSqDTzy&BFT%(ybdK_GX5;d!J-dP*>Wh#u-y!HE7YR zmyiP^e`vghZ15zl;Bs|*cPA(zKY6s+^i^;(i(cobfx$y(ce#e(Q;Dr5A<{$p3pAsG zlv^acjal3D8!E7u1MFe~oB8Ypw%}MFy>ygjkuNd~5w2PH$d`Zdvo|uiD~*C8W^7oe zjGH7b#3Z*k%&l(D(L(o0=ygK+m~yQoEBMdKyH#uA0@M0>N9)j3p!)oX4-B##h*`GO|ijTuw8!4Fx^KTx45l z_;E@3jGG+C>k~TpeHSy2YV3C7A~BKtM`Ji1bF_9{S~EIhPskyUD6z0QmQ^_|j;xI{ z9XJ}d?s=_Q_fW^EBU5gE=$d;WHtbPG#+htU)#v@>l>jp7T&$~iwZJFtZpwqr+c;Np z39~jr&O^Ke<%Hc=kfaaX*#3@S5hAu9?IX6(!=XD9!vCI4sW3j1o#b=?s>UsP;$)IL zpV4+6g`3s6HBg~+^wHz5DAq$+WU+vemjq?#?>7?(-3(+WW^ZwiLB6OA-Fko1r+%R&uey4(3-g6ge7M9G;XaYu6Sx4#kVj zd%Gx6T5Ht3;m|5$qm(=0r-{r>A2kn~+t1Mxp~71^u_jI41$y;nM76GpO^hF)<8kag z=e$(5LwM_1#exN((@FPHpaWvtIqC!@$$J2{uM`~_{5Z!O3- zGYb~c{J59fac@?IxMhcrCjKTHVQ=TI5ZR+@kkF{=`rUi9&$NE@uo{C?muSWc}2DNN|?xOU0uHvaTV=E z*qSw7+WFQ?gP}r_XLnjA+aZk)cfVGZ*MJCWYV+E^z#mcA`M#{~MCJ=w-fM#a^3iIL zK2n2{SLG4pmen6l`#klTnSU-nAtGs1OKk1Zp+ux0fo0c@+XDHonFvB5UbAH-f}vjP zKDrjWxWtwVvu|{F8s2#OR3_&I*FmVOTSFi* z;O1id$tsm6!M9#-Y%`?%g}!~DM%>t_*0FN)!MKZ6HD%e4+~4tXt>UOJ)e;y{(SKUl zihuPWwfDGlUk}$ilwS;{zz+7%j0&Z7eOXy8E(?)f~qxlfJ89rMy@Ph0ex_@o65$YVuRWUiE-cjRR z^`hha@WFd6zznhV+-YBzLwdDavwOG2gY~hN8g|Rz2N06{B4t9Mt=Pia0Aq`hKH`Oc=3t+W~a^0!{In7g)v!KLIBV=XtA+;CL zSGdoX87%hae_|+Or@tPtD=P--)pFseOVi$&28!O1Zx`n1oaa$x_sZ$XIsiS)y0XM+ zWyw>F%QnO&b~rAVOKOhB%gTOhgFb@})cZ&0pLyzKclUQ?hAQX1Zw?ZXwIp0m%L%%* zSf%rfQtrLfsM8y?368VsL;XkQM>g9YRLqEaa5B8*^KxbGjb7P*9ffB$(y(u z-iG!ID5{QcgIfk2z!f>A^1_SC&0V*6)b3QcP%)S|!%Go`NrV$NEDtmDAO@3Y`vv2J=!LFR-!Ze?) zVljLtl2ctN?8gj3WUF)Sa)OL)5)W%>7aD5L;6HX@bPu1^9@+jbAs>VDqLl2~64_Te zO-)O;3BhZ$XS>W(6(AR>K+MqF3?L1qD=#-zVP0)XGWUG^OdFpq;#s~dvAf=8$Hryv z6cP{SulXRV*JQ$NkTdFleqDgcLF$fdeI6A}84h()2kbbL)~5%de8pEW{X7qn z@FD>z3*HE{3c2~TFK-R>`D@W0ehv#leMWEA`c(J)Ih}289T!)}!5!Nxo|Le6E%na{ z7Ks*CxpLGATSItq<|RQTByi8`6upL0RDNG;T@y;@U}j)fqkPm|Ve2YrRS?!uiQU@8 zJcS!>QmeEuYvj5WVz_Iyk1J=DiJgvz>((o1C#B^fBMWn+-Df4jEcai4h7_w7h!M9P z5Z`{E*<_wjR~KnGbQ^B|Ik%T*JVXk^1vIw9t!J3ssH2qRypmwoIte|+<#O(5pcSG% z6nb;cntA6&xA%^`PnIIsyPe(Q6q=C2)`>>cU)A5aFnq2quTfZeO=L)SmK~v$Y2y<& zt3l!k#ELAARpyYVn@C)SuT`&S$O&gJfbR>~5NK-mRzs}9D$h@nt;v;JZ_6tDyn%BI z;M-pGt{?Pp32RsZU#yC?OiuAtaJpchxaY-|ykonNOY~Hw)DODt8I3;e=KZL-+HG}m zXPK>3SP0Uh3D!b?Q|KjNE)GxSBiEq_b^5{IZRPlCyOm zsb_!bi7L@y$q&TZQ*jjbB$~g7fLFE0n)rotWMsW3Vnnn&H!Y=%3 zr&n*>@H8@LAStl?LKOW+=qothqolI8FfXmH18W4*ndGdWlkyi4b*z| zu|0<>Uj21<$vojhr^I9SMZKHNi`n58S!{Rc2~!n`nAe_eemwkDVZ7~W_o~}R?_Xcs z-V{EHm}3vwi0((`W0-S!mk@Jw*AKwm<5aJREtYCZeXhazOhxAG;Nbn6Fv*dt2C>Gq zry>PHm9y&_2aaEna>KD-M-gAG^t|GwADy$1w_=Nz^L)$Al8=Q|QQK-UIwEPFq7T=- zzOLpxc-(5)Xcm=BH<-2(1Xyhg8{=! zbBmWCJ09*VIdQXG!(PAiiCe|ywVo|cLk+d#JT0-Zhfo$u84lJa+lm(MV6Npf5dbWn zf|%QV7KIms_*4u+t*^<~IBiN%-4d74e1^ zuF-&O*FYEcRk&If1_L`#mdmcbf_U*d}rAcH{0u_)|Djoot0cKqIgtiuP0o; zl%=0><9gbfq+{Vn?yKy}H9onfN6KhZgAT>R{OVxOEVN(NM(efuFJYZGp2`=sP;DKj z?552NB+Zi7iOgy+T&J2}!B=i13Ezj3EqvLScAOh&y8!>d>Veb&1>ClV!*_#3NQF_Z zR*uJT`0lKX*eI63Wt*~+cvQ7&Otm!ckF;MqYp~h-Oz~ESyyAI0u8vV=j}HlGEZj>t zHUI^5j~@LEOB`cy_@1oTOep5O^yyO(D(~ksz2lsncW}pO)zX;Z#Q5tuo)lZ@g4xx_ zsb&EH&-YJxY_T*(;}1srJOBJgOUS z9=Y0*AYEt}P=9%6R7Mh;Ae@h>AxgD=zqRkuLnG(^ihblIzr+_?xp%W^jpk z6g>?ajK(SyD;(Do3COu(y$dT-%mIg$P_y(F<_g{4-9bA`Xhvv{X7P?logc1I~F7GHDuQ@hk53p2&V{57;r zp;f5u!s4Q^r`d}a2b;&-yc=dOf1~cP^0At1jtofLins#nxjh|uI${C(Ex2=+jhoFQ zEGk_ez3x%Y4@%f`XJmI;Wj-N)O{<`VPV3A%|GF93Zo67n+iy~bsKUIV)-_t33VW`| z@#n58njbx+WQegW8b~%=mbFkzS*`ZMAPEw$Ga~NC6Ha1KtZ#Hf)LORc1l&z=H zz@_k_0*Q}wAl1&fH7g?+yZ=h|u@6PYuVvf^>NO2g{Df03=DO`#iVB8iDBcxBG@j5( zklC?bYZTE|ne!6g%3*PQ)JX(3_f5p;N16P$3(wEXWA0@+TwPzhPa%(0I4)uB{>u;2 zp0yLK)_GYKR&brpOb*>?`9_)qy9g&?3+85*y{P_0fDXTRil=Z+^vAC_r8nIb%=gZ(Yy24J zDzvj*=9NlGS!0pn8(=uO*ox6`eMlVBD`rzB*9)=G8n%dn9XqPkh4qMI@QLU%NfPJ z%-gp6hl#9*uspfs&qbp<(vnN8vA}&IoEi&g5^_5z#KZ2qDcOt?F-92)gz9Rnn-;iNS0S%==8cvlRaQ z4np#668_@S%156`Ulw>V`+}NcQkU-upE*`>1it}C3$s=|{mbEtAHUVQxu5C1eENE0 zqYIghBR)Qhc%qk22~#^X7)))34QwI6d^l zqi}Juk)O7NgDTPLx`+p^4!k9_+7-<_;(-PKkwWjsL9S5?>NO;+u_xPMIuK& zir$(Zd0o$6;>-w38)iet&?oP>%ZF&4?Ytj4McWl;-)Iv(%;%BGLozr~*xHq%QNM(zk!R#}NTn}sBD=E&3D3rgn`|zSeHGI<926vo;t+OJbUgw?j zIJcbWY4+;r>5wgc;&|;%){YtvXm5u&xxeS0>OAc?Y~j9&3vntzs$w4x3wXx_QaDAV z(q9Q7yPp^4`Iuh;a7OJ*#^{(QxAWbt=KiJ!!@zj_XN<46ro7jU(GQ-cxJc&`LUh6C^w3l%0vDgEgH0H+q+%iI8#nyN1Ij_u9x(K_2 z_U4C$`_`dmALbwOIDCR+=zEyJ#{!VCUSLa5!V9sQ=RHw5yWi)|zi;;D$=-YSSBoq2 ziv-_jC=9xGt|++cQ~}^n;=47}w=3aUQg#YP{s7d|Z&#Py``Rm#b>zE70v2M5Gl`yC zyvj5VbDUY}(q3j?7(V}+L(8yHN!f!cJLd&(ll{alojneZ{Tj(1pIuR3K6iPm24pzY zfj6^p#PiX$rD6f*VfjpTtBkI8AKXz(K5L{6TmFtbLka$NkoR5g~x_4g~(q_cTzlV$)$jjf9qRyvlovPu!;jMS_GgB5_do)`ve%q{5GfZs{AMI!B&Kz&xoP47$2VW;y}WY&236NBsf23wj^T@QeA1W+Oe3Ry zy$=l5Ef25)#r2euPD?knc;*;oKfJe3oHy#;hg}QzM&MU=+TM?^ ztyGoHjxZF0qsW_ME0Zg3Cu3JjOE-kg2xQtZQ<3QgPk$drNAselI^_NL+ven@OCKp- zb`rOKWaW~N{#EAXTq4d@a;^HU1?4p+FXHQqpOf52bxY>^#CcYoMv5MM z+3P#9$)_&AXyJOv9NA#^m1rhk?wH{+hoHlcm}(9??B!7v3p^tjy8ak0M|=3%5rJ~~ zcixf&OmlSR-mUo`o21{&mLA6JxpyHkD+D?;yB?mu`nZ{v!ReC=UhF$wi9jxVHlSS~ z2YKTm9+o-teM|cWRgHCe*51ekNzY_ibN8SMSaWu&Rvl-P(92+xi>X#pDDaP6-mt85 zZqHvlJ}Nst-X<&}E0jd6W$xd-Khw3o zZ-vH^eNZ8QG!CqP^&}LUVf7$(m4aS|;)Xmow%vX2Acz&}QRe)+mbV*MAfu_iqvBQb!~YTw~h7Cc~kKx()%hd--2q}*3&vHdl9&#g_88jxD- zqt_CelJ!j8nK(A1#K=sRn9#O$7f}`*LzfOeN{#?x+chLqDm)gK8n)GDWW|M>YdDUy z=H5E7u>gzYh9i}C%ee{;yx8^bO~)${i?zKNRyN&| z9*NZD=a`sS2C2CKg6}jSYyED%<+qOv1)QG&#|>;1Egt-JQVeFX#p!-O%CbXn$n+8r znvV|kAzXX5#IDeg^PuVaKJE%B+zE|?N&Y_OR-<0xjVSv$E>Fzr@bCT-t~E>O+P=G* zTym>9C_z{_ExK8xHCWk(lVYf+9eAG-;&Jf0GTNYvLegV@^niKMJ!2nlD~_QRKrr&X z0{MYcn2#je38M#&=M=r?R-hYmm<&7)k^(D-)*s_cd66!jd&f2Sy0F3iyhYuWJ?E}7 ze`N2Fwrz?}$=G;DyVnMDEnA2(KPvs9q1mSEbB4Q{#iPn@Y64nLU*N^zh5d!FnOAF? zwhno=@@ewLxw0m>38`^r%UJ?Sh$Pb-pSevh@Y|!$O0GR4;qXk~pl|N+zD0u@%yXY4 zxd{)2hw1Bf#m*%x&mj!EZz6WF-)8C{0($Ytu6O5$_qz`4TmUqjwosZOM1(wK!gC9E%BK5?#3VrIh7E)~h9Kh1^h9;4W-fzDG@g z$ziwbAzkuO;kp`eEGOAsv0KY0XFkoV*nVcA1lz}oFjT-Ycn6zl%;6{6_?FJ*qvq$D z3M_ILi&JkvKs~BIBEGmFyD{x-&Rdh+`!4$~mJ7;^?|b27%nyIlbaPLsq&}qieB%Bg zzL$xKkIY=oMwXgBXV!r9MCbW-U*RcG;a&)vmutn@`wycOssBT=qwfb7J({l!K0#(3duF`(7#lr3RV#A>-$ZO}dIbu;!TpMbymm|bpeC(sx z2zkBr)UvYhp)~+B)^+npw zhE-jpavHM2WAN^+;BxvkeX&<$iyrbz|vZOb}XR;BFgfS%dBDco!tjw R1(|>!ZFPOMbQO!e{|8rXn?V2o literal 0 HcmV?d00001 diff --git a/docs/configexamples/zone-policy.rst b/docs/configexamples/zone-policy.rst index 08db13b9..6f3d75ec 100644 --- a/docs/configexamples/zone-policy.rst +++ b/docs/configexamples/zone-policy.rst @@ -11,7 +11,7 @@ Zone-Policy example found in the `firewall `_ chapter. The legacy firewall is still available for versions before - 1.4-rolling-202308040557 and can be found in the :ref:`firewall-legacy` + 1.4-rolling-202308040557 and can be found in the :ref:`legacy-firewall` chapter. The examples in this section use the legacy firewall configuration commands, since this feature has been removed in earlier releases. diff --git a/docs/configuration/firewall/bridge.rst b/docs/configuration/firewall/bridge.rst new file mode 100644 index 00000000..4a0dc3bb --- /dev/null +++ b/docs/configuration/firewall/bridge.rst @@ -0,0 +1,42 @@ +:lastproofread: 2023-11-08 + +.. _firewall-configuration: + +############################# +Bridge Firewall Configuration +############################# + +.. note:: **Documentation under development** + +******** +Overview +******** + +In this section there's useful information of all firewall configuration that +can be done regarding bridge, and appropiate op-mode commands. +Configuration commands covered in this section: + +.. cfgcmd:: set firewall bridge ... + +From main structure defined in :doc:`Firewall Overview` +in this section you can find detailed information only for the next part +of the general structure: + +.. code-block:: none + + - set firewall + * bridge + - forward + + filter + - name + + custom_name + +Traffic which is received by the router on an interface which is member of a +bridge is processed on the **Bridge Layer**. A simplified packet flow diagram +for this layer is shown next: + +.. figure:: /_static/images/firewall-bridge-packet-flow.png + +For traffic that needs to be forwared internally by the bridge, base chain is +is **forward**, and it's base command for filtering is ``set firewall bridge +forward filter ...`` diff --git a/docs/configuration/firewall/flowtables.rst b/docs/configuration/firewall/flowtables.rst new file mode 100644 index 00000000..8b44a9b9 --- /dev/null +++ b/docs/configuration/firewall/flowtables.rst @@ -0,0 +1,52 @@ +:lastproofread: 2023-11-08 + +.. _firewall-flowtables-configuration: + +################################# +Flowtables Firewall Configuration +################################# + +.. note:: **Documentation under development** + +******** +Overview +******** + +In this section there's useful information of all firewall configuration that +can be done regarding flowtables + +.. cfgcmd:: set firewall flowtables ... + +From main structure defined in :doc:`Firewall Overview` +in this section you can find detailed information only for the next part +of the general structure: + +.. code-block:: none + + - set firewall + * flowtable + - custom_flow_table + + ... + + +Flowtables allows you to define a fastpath through the flowtable datapath. +The flowtable supports for the layer 3 IPv4 and IPv6 and the layer 4 TCP +and UDP protocols. + +.. figure:: /_static/images/firewall-flowtable-packet-flow.png + +Once the first packet of the flow successfully goes through the IP forwarding +path (black circles path), from the second packet on, you might decide to +offload the flow to the flowtable through your ruleset. The flowtable +infrastructure provides a rule action that allows you to specify when to add +a flow to the flowtable (On forward filtering, red circle number 6) + +A packet that finds a matching entry in the flowtable (flowtable hit) is +transmitted to the output netdevice, hence, packets bypass the classic IP +forwarding path and uses the **Fast Path** (orange circles path). The visible +effect is that you do not see these packets from any of the Netfilter +hooks coming after ingress. In case that there is no matching entry in the +flowtable (flowtable miss), the packet follows the classic IP forwarding path. + +.. note:: **Flowtable Reference:** + https://docs.kernel.org/networking/nf_flowtable.html diff --git a/docs/configuration/firewall/general-legacy.rst b/docs/configuration/firewall/general-legacy.rst index 2e6b0061..5d235eb8 100644 --- a/docs/configuration/firewall/general-legacy.rst +++ b/docs/configuration/firewall/general-legacy.rst @@ -1,10 +1,10 @@ :lastproofread: 2021-06-29 -.. _firewall-legacy: +.. _legacy-firewall: -############### -Firewall-Legacy -############### +################################### +Firewall Configuration (Deprecated) +################################### .. note:: **Important note:** This documentation is valid only for VyOS Sagitta prior to @@ -424,11 +424,13 @@ There are a lot of matching criteria against which the package can be tested. An arbitrary netmask can be applied to mask addresses to only match against a specific portion. This is particularly useful with IPv6 and a zone-based firewall as rules will remain valid if the IPv6 prefix changes and the host - portion of systems IPv6 address is static (for example, with SLAAC or `tokenised IPv6 addresses - `_) - + portion of systems IPv6 address is static (for example, with SLAAC or + `tokenised IPv6 addresses + `_). + This functions for both individual addresses and address groups. + .. stop_vyoslinter .. code-block:: none # Match any IPv6 address with the suffix ::0000:0000:0000:beef @@ -442,6 +444,7 @@ There are a lot of matching criteria against which the package can be tested. set firewall group ipv6-address-group WEBSERVERS address ::2000 set firewall name WAN-LAN-v6 rule 200 source group address-group WEBSERVERS set firewall name WAN-LAN-v6 rule 200 source address-mask ::ffff:ffff:ffff:ffff + .. start_vyoslinter .. cfgcmd:: set firewall name rule <1-999999> source fqdn .. cfgcmd:: set firewall name rule <1-999999> destination fqdn @@ -1048,4 +1051,4 @@ Update geoip database .. opcmd:: update geoip - Command used to update GeoIP database and firewall sets. \ No newline at end of file + Command used to update GeoIP database and firewall sets. diff --git a/docs/configuration/firewall/general.rst b/docs/configuration/firewall/general.rst deleted file mode 100644 index 0e172a24..00000000 --- a/docs/configuration/firewall/general.rst +++ /dev/null @@ -1,1506 +0,0 @@ -:lastproofread: 2021-06-29 - -.. _firewall: - -######## -Firewall -######## - -******** -Overview -******** - -VyOS makes use of Linux `netfilter `_ for packet -filtering. - -The firewall supports the creation of groups for addresses, domains, -interfaces, mac-addresses, networks and port groups. This groups can be used -later in firewall ruleset as desired. - -.. note:: **Important note on usage of terms:** - The firewall makes use of the terms `forward`, `input`, and `output` - for firewall policy. More information of Netfilter hooks and Linux - networking packet flows can be found in `Netfilter-Hooks - `_ - - -Main structure is shown next: - -.. code-block:: none - - - set firewall - * global-options - + all-ping - + broadcast-ping - + ... - * group - - address-group - - ipv6-address-group - - network-group - - ipv6-network-group - - interface-group - - mac-group - - port-group - - domain-group - * ipv4 - - forward - + filter - - input - + filter - - output - + filter - - name - + custom_name - * ipv6 - - forward - + filter - - input - + filter - - output - + filter - - ipv6-name - + custom_name - -Where, main key words and configuration paths that needs to be understood: - - * For firewall filtering, configuration should be done in ``set firewall - [ipv4 | ipv6] ...`` - - * For transit traffic, which is received by the router and forwarded, - base chain is **forward filter**: ``set firewall [ipv4 | ipv6] - forward filter ...`` - - * For traffic originated by the router, base chain is **output filter**: - ``set firewall [ipv4 | ipv6] output filter ...`` - - * For traffic towards the router itself, base chain is **input filter**: - ``set firewall [ipv4 | ipv6] input filter ...`` - -.. note:: **Important note about default-actions:** - If default action for any chain is not defined, then the default - action is set to **accept** for that chain. Only for custom chains, - the default action is set to **drop**. - -Custom firewall chains can be created, with commands -``set firewall [ipv4 | ipv6] [name | ipv6-name] ...``. In order to use -such custom chain, a rule with **action jump**, and the appropiate **target** -should be defined in a base chain. - -************** -Global Options -************** - -Some firewall settings are global and have an affect on the whole system. - -.. cfgcmd:: set firewall global-options all-ping [enable | disable] - - By default, when VyOS receives an ICMP echo request packet destined for - itself, it will answer with an ICMP echo reply, unless you avoid it - through its firewall. - - With the firewall you can set rules to accept, drop or reject ICMP in, - out or local traffic. You can also use the general **firewall all-ping** - command. This command affects only to LOCAL (packets destined for your - VyOS system), not to IN or OUT traffic. - - .. note:: **firewall global-options all-ping** affects only to LOCAL - and it always behaves in the most restrictive way - - .. code-block:: none - - set firewall global-options all-ping enable - - When the command above is set, VyOS will answer every ICMP echo request - addressed to itself, but that will only happen if no other rule is - applied dropping or rejecting local echo requests. In case of conflict, - VyOS will not answer ICMP echo requests. - - .. code-block:: none - - set firewall global-options all-ping disable - - When the command above is set, VyOS will answer no ICMP echo request - addressed to itself at all, no matter where it comes from or whether - more specific rules are being applied to accept them. - -.. cfgcmd:: set firewall global-options broadcast-ping [enable | disable] - - This setting enable or disable the response of icmp broadcast - messages. The following system parameter will be altered: - - * ``net.ipv4.icmp_echo_ignore_broadcasts`` - -.. cfgcmd:: set firewall global-options ip-src-route [enable | disable] -.. cfgcmd:: set firewall global-options ipv6-src-route [enable | disable] - - This setting handle if VyOS accept packets with a source route - option. The following system parameter will be altered: - - * ``net.ipv4.conf.all.accept_source_route`` - * ``net.ipv6.conf.all.accept_source_route`` - -.. cfgcmd:: set firewall global-options receive-redirects [enable | disable] -.. cfgcmd:: set firewall global-options ipv6-receive-redirects - [enable | disable] - - enable or disable of ICMPv4 or ICMPv6 redirect messages accepted - by VyOS. The following system parameter will be altered: - - * ``net.ipv4.conf.all.accept_redirects`` - * ``net.ipv6.conf.all.accept_redirects`` - -.. cfgcmd:: set firewall global-options send-redirects [enable | disable] - - enable or disable ICMPv4 redirect messages send by VyOS - The following system parameter will be altered: - - * ``net.ipv4.conf.all.send_redirects`` - -.. cfgcmd:: set firewall global-options log-martians [enable | disable] - - enable or disable the logging of martian IPv4 packets. - The following system parameter will be altered: - - * ``net.ipv4.conf.all.log_martians`` - -.. cfgcmd:: set firewall global-options source-validation - [strict | loose | disable] - - Set the IPv4 source validation mode. - The following system parameter will be altered: - - * ``net.ipv4.conf.all.rp_filter`` - -.. cfgcmd:: set firewall global-options syn-cookies [enable | disable] - - Enable or Disable if VyOS use IPv4 TCP SYN Cookies. - The following system parameter will be altered: - - * ``net.ipv4.tcp_syncookies`` - -.. cfgcmd:: set firewall global-options twa-hazards-protection - [enable | disable] - - Enable or Disable VyOS to be :rfc:`1337` conform. - The following system parameter will be altered: - - * ``net.ipv4.tcp_rfc1337`` - -****** -Groups -****** - -Firewall groups represent collections of IP addresses, networks, ports, -mac addresses, domains or interfaces. Once created, a group can be referenced -by firewall, nat and policy route rules as either a source or destination -matcher, and as inbpund/outbound in the case of interface group. - -Address Groups -============== - -In an **address group** a single IP address or IP address ranges are -defined. - -.. cfgcmd:: set firewall group address-group address [address | - address range] -.. cfgcmd:: set firewall group ipv6-address-group address

- - Define a IPv4 or a IPv6 address group - - .. code-block:: none - - set firewall group address-group ADR-INSIDE-v4 address 192.168.0.1 - set firewall group address-group ADR-INSIDE-v4 address 10.0.0.1-10.0.0.8 - set firewall group ipv6-address-group ADR-INSIDE-v6 address 2001:db8::1 - -.. cfgcmd:: set firewall group address-group description -.. cfgcmd:: set firewall group ipv6-address-group description - - Provide a IPv4 or IPv6 address group description - -Network Groups -============== - -While **network groups** accept IP networks in CIDR notation, specific -IP addresses can be added as a 32-bit prefix. If you foresee the need -to add a mix of addresses and networks, the network group is -recommended. - -.. cfgcmd:: set firewall group network-group network -.. cfgcmd:: set firewall group ipv6-network-group network - - Define a IPv4 or IPv6 Network group. - - .. code-block:: none - - set firewall group network-group NET-INSIDE-v4 network 192.168.0.0/24 - set firewall group network-group NET-INSIDE-v4 network 192.168.1.0/24 - set firewall group ipv6-network-group NET-INSIDE-v6 network 2001:db8::/64 - -.. cfgcmd:: set firewall group network-group description -.. cfgcmd:: set firewall group ipv6-network-group description - - Provide an IPv4 or IPv6 network group description. - -Interface Groups -================ - -An **interface group** represents a collection of interfaces. - -.. cfgcmd:: set firewall group interface-group interface - - Define an interface group. Wildcard are accepted too. - -.. code-block:: none - - set firewall group interface-group LAN interface bond1001 - set firewall group interface-group LAN interface eth3* - -.. cfgcmd:: set firewall group interface-group description - - Provide an interface group description - -Port Groups -=========== - -A **port group** represents only port numbers, not the protocol. Port -groups can be referenced for either TCP or UDP. It is recommended that -TCP and UDP groups are created separately to avoid accidentally -filtering unnecessary ports. Ranges of ports can be specified by using -`-`. - -.. cfgcmd:: set firewall group port-group port - [portname | portnumber | startport-endport] - - Define a port group. A port name can be any name defined in - /etc/services. e.g.: http - - .. code-block:: none - - set firewall group port-group PORT-TCP-SERVER1 port http - set firewall group port-group PORT-TCP-SERVER1 port 443 - set firewall group port-group PORT-TCP-SERVER1 port 5000-5010 - -.. cfgcmd:: set firewall group port-group description - - Provide a port group description. - -MAC Groups -========== - -A **mac group** represents a collection of mac addresses. - -.. cfgcmd:: set firewall group mac-group mac-address - - Define a mac group. - -.. code-block:: none - - set firewall group mac-group MAC-G01 mac-address 88:a4:c2:15:b6:4f - set firewall group mac-group MAC-G01 mac-address 4c:d5:77:c0:19:81 - -.. cfgcmd:: set firewall group mac-group description - - Provide a mac group description. - -Domain Groups -============= - -A **domain group** represents a collection of domains. - -.. cfgcmd:: set firewall group domain-group address - - Define a domain group. - -.. code-block:: none - - set firewall group domain-group DOM address example.com - -.. cfgcmd:: set firewall group domain-group description - - Provide a domain group description. - -************** -Firewall Rules -************** - -For firewall filtering, firewall rules needs to be created. Each rule is -numbered, has an action to apply if the rule is matched, and the ability -to specify multiple criteria matchers. Data packets go through the rules -from 1 - 999999, so order is crucial. At the first match the action of the -rule will be executed. - -Actions -======= - -If a rule is defined, then an action must be defined for it. This tells the -firewall what to do if all criteria matchers defined for such rule do match. - -The action can be : - - * ``accept``: accept the packet. - - * ``drop``: drop the packet. - - * ``reject``: reject the packet. - - * ``jump``: jump to another custom chain. - - * ``return``: Return from the current chain and continue at the next rule - of the last chain. - - * ``queue``: Enqueue packet to userspace. - -.. cfgcmd:: set firewall [ipv4 | ipv6] forward filter rule <1-999999> action - [accept | drop | jump | queue | reject | return] -.. cfgcmd:: set firewall [ipv4 | ipv6] input filter rule <1-999999> action - [accept | drop | jump | queue | reject | return] -.. cfgcmd:: set firewall [ipv4 | ipv6] output filter rule <1-999999> action - [accept | drop | jump | queue | reject | return] -.. cfgcmd:: set firewall ipv4 name rule <1-999999> action - [accept | drop | jump | queue | reject | return] -.. cfgcmd:: set firewall ipv6 ipv6-name rule <1-999999> action - [accept | drop | jump | queue | reject | return] - - This required setting defines the action of the current rule. If action is - set to jump, then jump-target is also needed. - -.. cfgcmd:: set firewall [ipv4 | ipv6] forward filter rule <1-999999> - jump-target -.. cfgcmd:: set firewall [ipv4 | ipv6] input filter rule <1-999999> - jump-target -.. cfgcmd:: set firewall [ipv4 | ipv6] output filter rule <1-999999> - jump-target -.. cfgcmd:: set firewall ipv4 name rule <1-999999> - jump-target -.. cfgcmd:: set firewall ipv6 ipv6-name rule <1-999999> - jump-target - - To be used only when action is set to jump. Use this command to specify - jump target. - -Also, **default-action** is an action that takes place whenever a packet does -not match any rule in it's chain. For base chains, possible options for -**default-action** are **accept** or **drop**. - -.. cfgcmd:: set firewall [ipv4 | ipv6] forward filter default-action - [accept | drop] -.. cfgcmd:: set firewall [ipv4 | ipv6] input filter default-action - [accept | drop] -.. cfgcmd:: set firewall [ipv4 | ipv6] output filter default-action - [accept | drop] -.. cfgcmd:: set firewall ipv4 name default-action - [accept | drop | jump | queue | reject | return] -.. cfgcmd:: set firewall ipv6 ipv6-name default-action - [accept | drop | jump | queue | reject | return] - - This set the default action of the rule-set if no rule matched a packet - criteria. If defacult-action is set to ``jump``, then - ``default-jump-target`` is also needed. Note that for base chains, default - action can only be set to ``accept`` or ``drop``, while on custom chain, - more actions are available. - -.. cfgcmd:: set firewall name default-jump-target -.. cfgcmd:: set firewall ipv6-name default-jump-target - - To be used only when ``defult-action`` is set to ``jump``. Use this - command to specify jump target for default rule. - -.. note:: **Important note about default-actions:** - If default action for any chain is not defined, then the default - action is set to **drop** for that chain. - - -Firewall Logs -============= - -Logging can be enable for every single firewall rule. If enabled, other -log options can be defined. - -.. cfgcmd:: set firewall [ipv4 | ipv6] forward filter rule <1-999999> log - [disable | enable] -.. cfgcmd:: set firewall [ipv4 | ipv6] input filter rule <1-999999> log - [disable | enable] -.. cfgcmd:: set firewall [ipv4 | ipv6] output filter rule <1-999999> log - [disable | enable] -.. cfgcmd:: set firewall ipv4 name rule <1-999999> log - [disable | enable] -.. cfgcmd:: set firewall ipv6 ipv6-name rule <1-999999> log - [disable | enable] - - Enable or disable logging for the matched packet. - -.. cfgcmd:: set firewall ipv4 name enable-default-log -.. cfgcmd:: set firewall ipv6 ipv6-name enable-default-log - - Use this command to enable the logging of the default action on - custom chains. - -.. cfgcmd:: set firewall [ipv4 | ipv6] forward filter rule <1-999999> - log-options level [emerg | alert | crit | err | warn | notice - | info | debug] -.. cfgcmd:: set firewall [ipv4 | ipv6] input filter rule <1-999999> - log-options level [emerg | alert | crit | err | warn | notice - | info | debug] -.. cfgcmd:: set firewall [ipv4 | ipv6] output filter rule <1-999999> - log-options level [emerg | alert | crit | err | warn | notice - | info | debug] -.. cfgcmd:: set firewall ipv4 name rule <1-999999> - log-options level [emerg | alert | crit | err | warn | notice - | info | debug] -.. cfgcmd:: set firewall ipv6 ipv6-name rule <1-999999> - log-options level [emerg | alert | crit | err | warn | notice - | info | debug] - - Define log-level. Only applicable if rule log is enable. - -.. cfgcmd:: set firewall [ipv4 | ipv6] forward filter rule <1-999999> - log-options group <0-65535> -.. cfgcmd:: set firewall [ipv4 | ipv6] input filter rule <1-999999> - log-options group <0-65535> -.. cfgcmd:: set firewall [ipv4 | ipv6] output filter rule <1-999999> - log-options group <0-65535> -.. cfgcmd:: set firewall ipv4 name rule <1-999999> - log-options group <0-65535> -.. cfgcmd:: set firewall ipv6 ipv6-name rule <1-999999> - log-options group <0-65535> - - Define log group to send message to. Only applicable if rule log is enable. - -.. cfgcmd:: set firewall [ipv4 | ipv6] forward filter rule <1-999999> - log-options snapshot-length <0-9000> -.. cfgcmd:: set firewall [ipv4 | ipv6] input filter rule <1-999999> - log-options snapshot-length <0-9000> -.. cfgcmd:: set firewall [ipv4 | ipv6] output filter rule <1-999999> - log-options snapshot-length <0-9000> -.. cfgcmd:: set firewall ipv4 name rule <1-999999> - log-options snapshot-length <0-9000> -.. cfgcmd:: set firewall ipv6 ipv6-name rule <1-999999> - log-options snapshot-length <0-9000> - - Define length of packet payload to include in netlink message. Only - applicable if rule log is enable and log group is defined. - -.. cfgcmd:: set firewall [ipv4 | ipv6] forward filter rule <1-999999> - log-options queue-threshold <0-65535> -.. cfgcmd:: set firewall [ipv4 | ipv6] input filter rule <1-999999> - log-options queue-threshold <0-65535> -.. cfgcmd:: set firewall [ipv4 | ipv6] output filter rule <1-999999> - log-options queue-threshold <0-65535> -.. cfgcmd:: set firewall ipv4 name rule <1-999999> - log-options queue-threshold <0-65535> -.. cfgcmd:: set firewall ipv6 ipv6-name rule <1-999999> - log-options queue-threshold <0-65535> - - Define number of packets to queue inside the kernel before sending them to - userspace. Only applicable if rule log is enable and log group is defined. - - -Firewall Description -==================== - -For reference, a description can be defined for every single rule, and for -every defined custom chain. - -.. cfgcmd:: set firewall ipv4 name description -.. cfgcmd:: set firewall ipv6 ipv6-name description - - Provide a rule-set description to a custom firewall chain. - -.. cfgcmd:: set firewall [ipv4 | ipv6] forward filter rule <1-999999> - description -.. cfgcmd:: set firewall [ipv4 | ipv6] input filter rule <1-999999> - description -.. cfgcmd:: set firewall [ipv4 | ipv6] output filter rule <1-999999> - description - -.. cfgcmd:: set firewall ipv4 name rule <1-999999> description -.. cfgcmd:: set firewall ipv6 ipv6-name rule <1-999999> description - - Provide a description for each rule. - - -Rule Status -=========== - -When defining a rule, it is enable by default. In some cases, it is useful to -just disable the rule, rather than removing it. - -.. cfgcmd:: set firewall [ipv4 | ipv6] forward filter rule <1-999999> disable -.. cfgcmd:: set firewall [ipv4 | ipv6] input filter rule <1-999999> disable -.. cfgcmd:: set firewall [ipv4 | ipv6] output filter rule <1-999999> disable -.. cfgcmd:: set firewall ipv4 name rule <1-999999> disable -.. cfgcmd:: set firewall ipv6 ipv6-name rule <1-999999> disable - - Command for disabling a rule but keep it in the configuration. - - -Matching criteria -================= - -There are a lot of matching criteria against which the package can be tested. - -.. cfgcmd:: set firewall [ipv4 | ipv6] forward filter rule <1-999999> - connection-status nat [destination | source] -.. cfgcmd:: set firewall [ipv4 | ipv6] input filter rule <1-999999> - connection-status nat [destination | source] -.. cfgcmd:: set firewall [ipv4 | ipv6] output filter rule <1-999999> - connection-status nat [destination | source] -.. cfgcmd:: set firewall ipv4 name rule <1-999999> - connection-status nat [destination | source] -.. cfgcmd:: set firewall ipv6 ipv6-name rule <1-999999> - connection-status nat [destination | source] - - Match criteria based on nat connection status. - -.. cfgcmd:: set firewall [ipv4 | ipv6] forward filter rule <1-999999> - connection-mark <1-2147483647> -.. cfgcmd:: set firewall [ipv4 | ipv6] input filter rule <1-999999> - connection-mark <1-2147483647> -.. cfgcmd:: set firewall [ipv4 | ipv6] output filter rule <1-999999> - connection-mark <1-2147483647> -.. cfgcmd:: set firewall ipv4 name rule <1-999999> - connection-mark <1-2147483647> -.. cfgcmd:: set firewall ipv6 ipv6-name rule <1-999999> - connection-mark <1-2147483647> - - Match criteria based on connection mark. - -.. cfgcmd:: set firewall [ipv4 | ipv6] forward filter rule <1-999999> - source address [address | addressrange | CIDR] -.. cfgcmd:: set firewall [ipv4 | ipv6] input filter rule <1-999999> - source address [address | addressrange | CIDR] -.. cfgcmd:: set firewall [ipv4 | ipv6] output filter rule <1-999999> - source address [address | addressrange | CIDR] -.. cfgcmd:: set firewall ipv4 name rule <1-999999> - source address [address | addressrange | CIDR] -.. cfgcmd:: set firewall ipv6 ipv6-name rule <1-999999> - source address [address | addressrange | CIDR] - -.. cfgcmd:: set firewall [ipv4 | ipv6] forward filter rule <1-999999> - destination address [address | addressrange | CIDR] -.. cfgcmd:: set firewall [ipv4 | ipv6] input filter rule <1-999999> - destination address [address | addressrange | CIDR] -.. cfgcmd:: set firewall [ipv4 | ipv6] output filter rule <1-999999> - destination address [address | addressrange | CIDR] -.. cfgcmd:: set firewall ipv4 name rule <1-999999> - destination address [address | addressrange | CIDR] -.. cfgcmd:: set firewall ipv6 ipv6-name rule <1-999999> - destination address [address | addressrange | CIDR] - - Match criteria based on source and/or destination address. This is similar - to the network groups part, but here you are able to negate the matching - addresses. - - .. code-block:: none - - set firewall ipv4 name FOO rule 50 source address 192.0.2.10-192.0.2.11 - # with a '!' the rule match everything except the specified subnet - set firewall ipv4 input filter FOO rule 51 source address !203.0.113.0/24 - set firewall ipv6 ipv6-name FOO rule 100 source address 2001:db8::202 - -.. cfgcmd:: set firewall [ipv4 | ipv6] forward filter rule <1-999999> - source address-mask [address] -.. cfgcmd:: set firewall [ipv4 | ipv6] input filter rule <1-999999> - source address-mask [address] -.. cfgcmd:: set firewall [ipv4 | ipv6] output filter rule <1-999999> - source address-mask [address] -.. cfgcmd:: set firewall ipv4 name rule <1-999999> - source address-mask [address] -.. cfgcmd:: set firewall ipv6 ipv6-name rule <1-999999> - source address-mask [address] - -.. cfgcmd:: set firewall [ipv4 | ipv6] forward filter rule <1-999999> - destination address-mask [address] -.. cfgcmd:: set firewall [ipv4 | ipv6] input filter rule <1-999999> - destination address-mask [address] -.. cfgcmd:: set firewall [ipv4 | ipv6] output filter rule <1-999999> - destination address-mask [address] -.. cfgcmd:: set firewall ipv4 name rule <1-999999> - destination address-mask [address] -.. cfgcmd:: set firewall ipv6 ipv6-name rule <1-999999> - destination address-mask [address] - - An arbitrary netmask can be applied to mask addresses to only match against - a specific portion. This is particularly useful with IPv6 as rules will - remain valid if the IPv6 prefix changes and the host - portion of systems IPv6 address is static (for example, with SLAAC or - `tokenised IPv6 addresses - `_) - - This functions for both individual addresses and address groups. - - .. code-block:: none - - # Match any IPv6 address with the suffix ::0000:0000:0000:beef - set firewall ipv6 forward filter rule 100 destination address ::beef - set firewall ipv6 forward filter rule 100 destination address-mask ::ffff:ffff:ffff:ffff - # Match any IPv4 address with `11` as the 2nd octet and `13` as the forth octet - set firewall ipv4 name FOO rule 100 destination address 0.11.0.13 - set firewall ipv4 name FOO rule 100 destination address-mask 0.255.0.255 - # Address groups - set firewall group ipv6-address-group WEBSERVERS address ::1000 - set firewall group ipv6-address-group WEBSERVERS address ::2000 - set firewall ipv6 forward filter rule 200 source group address-group WEBSERVERS - set firewall ipv6 forward filter rule 200 source address-mask ::ffff:ffff:ffff:ffff - -.. cfgcmd:: set firewall [ipv4 | ipv6] forward filter rule <1-999999> - source fqdn -.. cfgcmd:: set firewall [ipv4 | ipv6] input filter rule <1-999999> - source fqdn -.. cfgcmd:: set firewall [ipv4 | ipv6] output filter rule <1-999999> - source fqdn -.. cfgcmd:: set firewall ipv4 name rule <1-999999> - source fqdn -.. cfgcmd:: set firewall ipv6 ipv6-name rule <1-999999> - source fqdn -.. cfgcmd:: set firewall [ipv4 | ipv6] forward filter rule <1-999999> - destination fqdn -.. cfgcmd:: set firewall [ipv4 | ipv6] input filter rule <1-999999> - destination fqdn -.. cfgcmd:: set firewall [ipv4 | ipv6] output filter rule <1-999999> - destination fqdn -.. cfgcmd:: set firewall ipv4 name rule <1-999999> - destination fqdn -.. cfgcmd:: set firewall ipv6 ipv6-name rule <1-999999> - destination fqdn - - Specify a Fully Qualified Domain Name as source/destination matcher. Ensure - router is able to resolve such dns query. - -.. cfgcmd:: set firewall [ipv4 | ipv6] forward filter rule <1-999999> - source geoip country-code -.. cfgcmd:: set firewall [ipv4 | ipv6] input filter rule <1-999999> - source geoip country-code -.. cfgcmd:: set firewall [ipv4 | ipv6] output filter rule <1-999999> - source geoip country-code -.. cfgcmd:: set firewall ipv4 name rule <1-999999> - source geoip country-code -.. cfgcmd:: set firewall ipv6 ipv6-name rule <1-999999> - source geoip country-code - -.. cfgcmd:: set firewall [ipv4 | ipv6] forward filter rule <1-999999> - destination geoip country-code -.. cfgcmd:: set firewall [ipv4 | ipv6] input filter rule <1-999999> - destination geoip country-code -.. cfgcmd:: set firewall [ipv4 | ipv6] output filter rule <1-999999> - destination geoip country-code -.. cfgcmd:: set firewall ipv4 name rule <1-999999> - destination geoip country-code -.. cfgcmd:: set firewall ipv6 ipv6-name rule <1-999999> - destination geoip country-code - -.. cfgcmd:: set firewall [ipv4 | ipv6] forward filter rule <1-999999> - source geoip inverse-match -.. cfgcmd:: set firewall [ipv4 | ipv6] input filter rule <1-999999> - source geoip inverse-match -.. cfgcmd:: set firewall [ipv4 | ipv6] output filter rule <1-999999> - source geoip inverse-match -.. cfgcmd:: set firewall ipv4 name rule <1-999999> - source geoip inverse-match -.. cfgcmd:: set firewall ipv6 ipv6-name rule <1-999999> - source geoip inverse-match - -.. cfgcmd:: set firewall [ipv4 | ipv6] forward filter rule <1-999999> - destination geoip inverse-match -.. cfgcmd:: set firewall [ipv4 | ipv6] input filter rule <1-999999> - destination geoip inverse-match -.. cfgcmd:: set firewall [ipv4 | ipv6] output filter rule <1-999999> - destination geoip inverse-match -.. cfgcmd:: set firewall ipv4 name rule <1-999999> - destination geoip inverse-match -.. cfgcmd:: set firewall ipv6 ipv6-name rule <1-999999> - destination geoip inverse-match - - Match IP addresses based on its geolocation. More info: `geoip matching - `_. - Use inverse-match to match anything except the given country-codes. - -Data is provided by DB-IP.com under CC-BY-4.0 license. Attribution required, -permits redistribution so we can include a database in images(~3MB -compressed). Includes cron script (manually callable by op-mode update -geoip) to keep database and rules updated. - - -.. cfgcmd:: set firewall [ipv4 | ipv6] forward filter rule <1-999999> - source mac-address -.. cfgcmd:: set firewall [ipv4 | ipv6] input filter rule <1-999999> - source mac-address -.. cfgcmd:: set firewall [ipv4 | ipv6] output filter rule <1-999999> - source mac-address -.. cfgcmd:: set firewall ipv4 name rule <1-999999> - source mac-address -.. cfgcmd:: set firewall ipv6 ipv6-name rule <1-999999> - source mac-address - - Only in the source criteria, you can specify a mac-address. - - .. code-block:: none - - set firewall ipv4 input filter rule 100 source mac-address 00:53:00:11:22:33 - set firewall ipv4 input filter rule 101 source mac-address !00:53:00:aa:12:34 - - -.. cfgcmd:: set firewall [ipv4 | ipv6] forward filter rule <1-999999> - source port [1-65535 | portname | start-end] -.. cfgcmd:: set firewall [ipv4 | ipv6] input filter rule <1-999999> - source port [1-65535 | portname | start-end] -.. cfgcmd:: set firewall [ipv4 | ipv6] output filter rule <1-999999> - source port [1-65535 | portname | start-end] -.. cfgcmd:: set firewall ipv4 name rule <1-999999> - source port [1-65535 | portname | start-end] -.. cfgcmd:: set firewall ipv6 ipv6-name rule <1-999999> - source port [1-65535 | portname | start-end] - -.. cfgcmd:: set firewall [ipv4 | ipv6] forward filter rule <1-999999> - destination port [1-65535 | portname | start-end] -.. cfgcmd:: set firewall [ipv4 | ipv6] input filter rule <1-999999> - destination port [1-65535 | portname | start-end] -.. cfgcmd:: set firewall [ipv4 | ipv6] output filter rule <1-999999> - destination port [1-65535 | portname | start-end] -.. cfgcmd:: set firewall ipv4 name rule <1-999999> - destination port [1-65535 | portname | start-end] -.. cfgcmd:: set firewall ipv6 ipv6-name rule <1-999999> - destination port [1-65535 | portname | start-end] - - A port can be set with a port number or a name which is here - defined: ``/etc/services``. - - .. code-block:: none - - set firewall ipv4 forward filter rule 10 source port '22' - set firewall ipv4 forward filter rule 11 source port '!http' - set firewall ipv4 forward filter rule 12 source port 'https' - - Multiple source ports can be specified as a comma-separated list. - The whole list can also be "negated" using ``!``. For example: - - .. code-block:: none - - set firewall ipv6 forward filter rule 10 source port '!22,https,3333-3338' - -.. cfgcmd:: set firewall [ipv4 | ipv6] forward filter rule <1-999999> - source group address-group -.. cfgcmd:: set firewall [ipv4 | ipv6] input filter rule <1-999999> - source group address-group -.. cfgcmd:: set firewall [ipv4 | ipv6] output filter rule <1-999999> - source group address-group -.. cfgcmd:: set firewall ipv4 name rule <1-999999> - source group address-group -.. cfgcmd:: set firewall ipv6 ipv6-name rule <1-999999> - source group address-group - -.. cfgcmd:: set firewall [ipv4 | ipv6] forward filter rule <1-999999> - destination group address-group -.. cfgcmd:: set firewall [ipv4 | ipv6] input filter rule <1-999999> - destination group address-group -.. cfgcmd:: set firewall [ipv4 | ipv6] output filter rule <1-999999> - destination group address-group -.. cfgcmd:: set firewall ipv4 name rule <1-999999> - destination group address-group -.. cfgcmd:: set firewall ipv6 ipv6-name rule <1-999999> - destination group address-group - - Use a specific address-group. Prepend character ``!`` for inverted matching - criteria. - -.. cfgcmd:: set firewall [ipv4 | ipv6] forward filter rule <1-999999> - source group network-group -.. cfgcmd:: set firewall [ipv4 | ipv6] input filter rule <1-999999> - source group network-group -.. cfgcmd:: set firewall [ipv4 | ipv6] output filter rule <1-999999> - source group network-group -.. cfgcmd:: set firewall ipv4 name rule <1-999999> - source group network-group -.. cfgcmd:: set firewall ipv6 ipv6-name rule <1-999999> - source group network-group - -.. cfgcmd:: set firewall [ipv4 | ipv6] forward filter rule <1-999999> - destination group network-group -.. cfgcmd:: set firewall [ipv4 | ipv6] input filter rule <1-999999> - destination group network-group -.. cfgcmd:: set firewall [ipv4 | ipv6] output filter rule <1-999999> - destination group network-group -.. cfgcmd:: set firewall ipv4 name rule <1-999999> - destination group network-group -.. cfgcmd:: set firewall ipv6 ipv6-name rule <1-999999> - destination group network-group - - Use a specific network-group. Prepend character ``!`` for inverted matching - criteria. - -.. cfgcmd:: set firewall [ipv4 | ipv6] forward filter rule <1-999999> - source group port-group -.. cfgcmd:: set firewall [ipv4 | ipv6] input filter rule <1-999999> - source group port-group -.. cfgcmd:: set firewall [ipv4 | ipv6] output filter rule <1-999999> - source group port-group -.. cfgcmd:: set firewall ipv4 name rule <1-999999> - source group port-group -.. cfgcmd:: set firewall ipv6 ipv6-name rule <1-999999> - source group port-group - -.. cfgcmd:: set firewall [ipv4 | ipv6] forward filter rule <1-999999> - destination group port-group -.. cfgcmd:: set firewall [ipv4 | ipv6] input filter rule <1-999999> - destination group port-group -.. cfgcmd:: set firewall [ipv4 | ipv6] output filter rule <1-999999> - destination group port-group -.. cfgcmd:: set firewall ipv4 name rule <1-999999> - destination group port-group -.. cfgcmd:: set firewall ipv6 ipv6-name rule <1-999999> - destination group port-group - - Use a specific port-group. Prepend character ``!`` for inverted matching - criteria. - -.. cfgcmd:: set firewall [ipv4 | ipv6] forward filter rule <1-999999> - source group domain-group -.. cfgcmd:: set firewall [ipv4 | ipv6] input filter rule <1-999999> - source group domain-group -.. cfgcmd:: set firewall [ipv4 | ipv6] output filter rule <1-999999> - source group domain-group -.. cfgcmd:: set firewall ipv4 name rule <1-999999> - source group domain-group -.. cfgcmd:: set firewall ipv6 ipv6-name rule <1-999999> - source group domain-group - -.. cfgcmd:: set firewall [ipv4 | ipv6] forward filter rule <1-999999> - destination group domain-group -.. cfgcmd:: set firewall [ipv4 | ipv6] input filter rule <1-999999> - destination group domain-group -.. cfgcmd:: set firewall [ipv4 | ipv6] output filter rule <1-999999> - destination group domain-group -.. cfgcmd:: set firewall ipv4 name rule <1-999999> - destination group domain-group -.. cfgcmd:: set firewall ipv6 ipv6-name rule <1-999999> - destination group domain-group - - Use a specific domain-group. Prepend character ``!`` for inverted matching - criteria. - -.. cfgcmd:: set firewall [ipv4 | ipv6] forward filter rule <1-999999> - source group mac-group -.. cfgcmd:: set firewall [ipv4 | ipv6] input filter rule <1-999999> - source group mac-group -.. cfgcmd:: set firewall [ipv4 | ipv6] output filter rule <1-999999> - source group mac-group -.. cfgcmd:: set firewall ipv4 name rule <1-999999> - source group mac-group -.. cfgcmd:: set firewall ipv6 ipv6-name rule <1-999999> - source group mac-group - -.. cfgcmd:: set firewall [ipv4 | ipv6] forward filter rule <1-999999> - destination group mac-group -.. cfgcmd:: set firewall [ipv4 | ipv6] input filter rule <1-999999> - destination group mac-group -.. cfgcmd:: set firewall [ipv4 | ipv6] output filter rule <1-999999> - destination group mac-group -.. cfgcmd:: set firewall ipv4 name rule <1-999999> - destination group mac-group -.. cfgcmd:: set firewall ipv6 ipv6-name rule <1-999999> - destination group mac-group - - Use a specific mac-group. Prepend character ``!`` for inverted matching - criteria. - -.. cfgcmd:: set firewall [ipv4 | ipv6] forward filter rule <1-999999> - dscp [0-63 | start-end] -.. cfgcmd:: set firewall [ipv4 | ipv6] input filter rule <1-999999> - dscp [0-63 | start-end] -.. cfgcmd:: set firewall [ipv4 | ipv6] output filter rule <1-999999> - dscp [0-63 | start-end] -.. cfgcmd:: set firewall ipv4 name rule <1-999999> - dscp [0-63 | start-end] -.. cfgcmd:: set firewall ipv6 ipv6-name rule <1-999999> - dscp [0-63 | start-end] - -.. cfgcmd:: set firewall [ipv4 | ipv6] forward filter rule <1-999999> - dscp-exclude [0-63 | start-end] -.. cfgcmd:: set firewall [ipv4 | ipv6] input filter rule <1-999999> - dscp-exclude [0-63 | start-end] -.. cfgcmd:: set firewall [ipv4 | ipv6] output filter rule <1-999999> - dscp-exclude [0-63 | start-end] -.. cfgcmd:: set firewall ipv4 name rule <1-999999> - dscp-exclude [0-63 | start-end] -.. cfgcmd:: set firewall ipv6 ipv6-name rule <1-999999> - dscp-exclude [0-63 | start-end] - - Match based on dscp value. - -.. cfgcmd:: set firewall [ipv4 | ipv6] forward filter rule <1-999999> - fragment [match-frag | match-non-frag] -.. cfgcmd:: set firewall [ipv4 | ipv6] input filter rule <1-999999> - fragment [match-frag | match-non-frag] -.. cfgcmd:: set firewall [ipv4 | ipv6] output filter rule <1-999999> - fragment [match-frag | match-non-frag] -.. cfgcmd:: set firewall ipv4 name rule <1-999999> - fragment [match-frag | match-non-frag] -.. cfgcmd:: set firewall ipv6 ipv6-name rule <1-999999> - fragment [match-frag | match-non-frag] - - Match based on fragment criteria. - -.. cfgcmd:: set firewall ipv4 forward filter rule <1-999999> - icmp [code | type] <0-255> -.. cfgcmd:: set firewall ipv4 input filter rule <1-999999> - icmp [code | type] <0-255> -.. cfgcmd:: set firewall ipv4 output filter rule <1-999999> - icmp [code | type] <0-255> -.. cfgcmd:: set firewall ipv4 name rule <1-999999> - icmp [code | type] <0-255> -.. cfgcmd:: set firewall ipv6 forward filter rule <1-999999> - icmpv6 [code | type] <0-255> -.. cfgcmd:: set firewall ipv6 input filter rule <1-999999> - icmpv6 [code | type] <0-255> -.. cfgcmd:: set firewall ipv6 output filter rule <1-999999> - icmpv6 [code | type] <0-255> -.. cfgcmd:: set firewall ipv6 ipv6-name rule <1-999999> - icmpv6 [code | type] <0-255> - - Match based on icmp|icmpv6 code and type. - -.. cfgcmd:: set firewall ipv4 forward filter rule <1-999999> - icmp type-name -.. cfgcmd:: set firewall ipv4 input filter rule <1-999999> - icmp type-name -.. cfgcmd:: set firewall ipv4 output filter rule <1-999999> - icmp type-name -.. cfgcmd:: set firewall ipv4 name rule <1-999999> - icmp type-name -.. cfgcmd:: set firewall ipv6 forward filter rule <1-999999> - icmpv6 type-name -.. cfgcmd:: set firewall ipv6 input filter rule <1-999999> - icmpv6 type-name -.. cfgcmd:: set firewall ipv6 output filter rule <1-999999> - icmpv6 type-name -.. cfgcmd:: set firewall ipv6 ipv6-name rule <1-999999> - icmpv6 type-name - - Match based on icmp|icmpv6 type-name criteria. Use tab for information - about what **type-name** criteria are supported. - -.. cfgcmd:: set firewall [ipv4 | ipv6] forward filter rule <1-999999> - inbound-interface -.. cfgcmd:: set firewall [ipv4 | ipv6] input filter rule <1-999999> - inbound-interface -.. cfgcmd:: set firewall ipv4 name rule <1-999999> - inbound-interface -.. cfgcmd:: set firewall ipv6 ipv6-name rule <1-999999> - inbound-interface - - Match based on inbound interface. Wilcard ``*`` can be used. - For example: ``eth2*`` - -.. cfgcmd:: set firewall [ipv4 | ipv6] forward filter rule <1-999999> - outbound-interface -.. cfgcmd:: set firewall [ipv4 | ipv6] output filter rule <1-999999> - outbound-interface -.. cfgcmd:: set firewall ipv4 name rule <1-999999> - outbound-interface -.. cfgcmd:: set firewall ipv6 ipv6-name rule <1-999999> - outbound-interface - - Match based on outbound interface. Wilcard ``*`` can be used. - For example: ``eth2*`` - -.. cfgcmd:: set firewall [ipv4 | ipv6] forward filter rule <1-999999> - ipsec [match-ipsec | match-none] -.. cfgcmd:: set firewall [ipv4 | ipv6] input filter rule <1-999999> - ipsec [match-ipsec | match-none] -.. cfgcmd:: set firewall [ipv4 | ipv6] output filter rule <1-999999> - ipsec [match-ipsec | match-none] -.. cfgcmd:: set firewall ipv4 name rule <1-999999> - ipsec [match-ipsec | match-none] -.. cfgcmd:: set firewall ipv6 ipv6-name rule <1-999999> - ipsec [match-ipsec | match-none] - - Match based on ipsec criteria. - -.. cfgcmd:: set firewall [ipv4 | ipv6] forward filter rule <1-999999> - limit burst <0-4294967295> -.. cfgcmd:: set firewall [ipv4 | ipv6] input filter rule <1-999999> - limit burst <0-4294967295> -.. cfgcmd:: set firewall [ipv4 | ipv6] output filter rule <1-999999> - limit burst <0-4294967295> -.. cfgcmd:: set firewall ipv4 name rule <1-999999> - limit burst <0-4294967295> -.. cfgcmd:: set firewall ipv6 ipv6-name rule <1-999999> - limit burst <0-4294967295> - - Match based on the maximum number of packets to allow in excess of rate. - -.. cfgcmd:: set firewall [ipv4 | ipv6] forward filter rule <1-999999> - limit rate -.. cfgcmd:: set firewall [ipv4 | ipv6] input filter rule <1-999999> - limit rate -.. cfgcmd:: set firewall [ipv4 | ipv6] output filter rule <1-999999> - limit rate -.. cfgcmd:: set firewall ipv4 name rule <1-999999> - limit rate -.. cfgcmd:: set firewall ipv6 ipv6-name rule <1-999999> - limit rate - - Match based on the maximum average rate, specified as **integer/unit**. - For example **5/minutes** - -.. cfgcmd:: set firewall [ipv4 | ipv6] forward filter rule <1-999999> - packet-length -.. cfgcmd:: set firewall [ipv4 | ipv6] input filter rule <1-999999> - packet-length -.. cfgcmd:: set firewall [ipv4 | ipv6] output filter rule <1-999999> - packet-length -.. cfgcmd:: set firewall ipv4 name rule <1-999999> - packet-length -.. cfgcmd:: set firewall ipv6 ipv6-name rule <1-999999> - packet-length - -.. cfgcmd:: set firewall [ipv4 | ipv6] forward filter rule <1-999999> - packet-length-exclude -.. cfgcmd:: set firewall [ipv4 | ipv6] input filter rule <1-999999> - packet-length-exclude -.. cfgcmd:: set firewall [ipv4 | ipv6] output filter rule <1-999999> - packet-length-exclude -.. cfgcmd:: set firewall ipv4 name rule <1-999999> - packet-length-exclude -.. cfgcmd:: set firewall ipv6 ipv6-name rule <1-999999> - packet-length-exclude - - Match based on packet length criteria. Multiple values from 1 to 65535 - and ranges are supported. - -.. cfgcmd:: set firewall [ipv4 | ipv6] forward filter rule <1-999999> - packet-type [broadcast | host | multicast | other] -.. cfgcmd:: set firewall [ipv4 | ipv6] input filter rule <1-999999> - packet-type [broadcast | host | multicast | other] -.. cfgcmd:: set firewall [ipv4 | ipv6] output filter rule <1-999999> - packet-type [broadcast | host | multicast | other] -.. cfgcmd:: set firewall ipv4 name rule <1-999999> - packet-type [broadcast | host | multicast | other] -.. cfgcmd:: set firewall ipv6 ipv6-name rule <1-999999> - packet-type [broadcast | host | multicast | other] - - Match based on packet type criteria. - -.. cfgcmd:: set firewall [ipv4 | ipv6] forward filter rule <1-999999> - protocol [ | <0-255> | all | tcp_udp] -.. cfgcmd:: set firewall [ipv4 | ipv6] input filter rule <1-999999> - protocol [ | <0-255> | all | tcp_udp] -.. cfgcmd:: set firewall [ipv4 | ipv6] output filter rule <1-999999> - protocol [ | <0-255> | all | tcp_udp] -.. cfgcmd:: set firewall ipv4 name rule <1-999999> - protocol [ | <0-255> | all | tcp_udp] -.. cfgcmd:: set firewall ipv6 ipv6-name rule <1-999999> - protocol [ | <0-255> | all | tcp_udp] - - Match a protocol criteria. A protocol number or a name which is here - defined: ``/etc/protocols``. - Special names are ``all`` for all protocols and ``tcp_udp`` for tcp and udp - based packets. The ``!`` negate the selected protocol. - - .. code-block:: none - - set firewall ipv4 forward fitler rule 10 protocol tcp_udp - set firewall ipv4 forward fitler rule 11 protocol !tcp_udp - set firewall ipv6 input filter rule 10 protocol tcp - -.. cfgcmd:: set firewall [ipv4 | ipv6] forward filter rule <1-999999> - recent count <1-255> -.. cfgcmd:: set firewall [ipv4 | ipv6] input filter rule <1-999999> - recent count <1-255> -.. cfgcmd:: set firewall [ipv4 | ipv6] output filter rule <1-999999> - recent count <1-255> -.. cfgcmd:: set firewall ipv4 name rule <1-999999> - recent count <1-255> -.. cfgcmd:: set firewall ipv6 ipv6-name rule <1-999999> - recent count <1-255> - -.. cfgcmd:: set firewall [ipv4 | ipv6] forward filter rule <1-999999> - recent time [second | minute | hour] -.. cfgcmd:: set firewall [ipv4 | ipv6] input filter rule <1-999999> - recent time [second | minute | hour] -.. cfgcmd:: set firewall [ipv4 | ipv6] output filter rule <1-999999> - recent time [second | minute | hour] -.. cfgcmd:: set firewall ipv4 name rule <1-999999> - recent time [second | minute | hour] -.. cfgcmd:: set firewall ipv6 ipv6-name rule <1-999999> - recent time [second | minute | hour] - - Match bases on recently seen sources. - -.. cfgcmd:: set firewall [ipv4 | ipv6] forward filter rule <1-999999> - tcp flags -.. cfgcmd:: set firewall [ipv4 | ipv6] input filter rule <1-999999> - tcp flags -.. cfgcmd:: set firewall [ipv4 | ipv6] output filter rule <1-999999> - tcp flags -.. cfgcmd:: set firewall ipv4 name rule <1-999999> - tcp flags -.. cfgcmd:: set firewall ipv6 ipv6-name rule <1-999999> - tcp flags - - Allowed values fpr TCP flags: ``SYN``, ``ACK``, ``FIN``, ``RST``, ``URG``, - ``PSH``, ``ALL`` When specifying more than one flag, flags should be comma - separated. The ``!`` negate the selected protocol. - - .. code-block:: none - - set firewall ipv4 input filter rule 10 tcp flags 'ACK' - set firewall ipv4 input filter rule 12 tcp flags 'SYN' - set firewall ipv4 input filter rule 13 tcp flags 'SYN,!ACK,!FIN,!RST' - -.. cfgcmd:: set firewall [ipv4 | ipv6] forward filter rule <1-999999> - state [established | invalid | new | related] [enable | disable] -.. cfgcmd:: set firewall [ipv4 | ipv6] input filter rule <1-999999> - state [established | invalid | new | related] [enable | disable] -.. cfgcmd:: set firewall [ipv4 | ipv6] output filter rule <1-999999> - state [established | invalid | new | related] [enable | disable] -.. cfgcmd:: set firewall ipv4 name rule <1-999999> - state [established | invalid | new | related] [enable | disable] -.. cfgcmd:: set firewall ipv6 ipv6-name rule <1-999999> - state [established | invalid | new | related] [enable | disable] - - Match against the state of a packet. - -.. cfgcmd:: set firewall [ipv4 | ipv6] forward filter rule <1-999999> - time startdate -.. cfgcmd:: set firewall [ipv4 | ipv6] input filter rule <1-999999> - time startdate -.. cfgcmd:: set firewall [ipv4 | ipv6] output filter rule <1-999999> - time startdate -.. cfgcmd:: set firewall ipv4 name rule <1-999999> - time startdate -.. cfgcmd:: set firewall ipv6 ipv6-name rule <1-999999> - time startdate -.. cfgcmd:: set firewall [ipv4 | ipv6] forward filter rule <1-999999> - time starttime -.. cfgcmd:: set firewall [ipv4 | ipv6] input filter rule <1-999999> - time starttime -.. cfgcmd:: set firewall [ipv4 | ipv6] output filter rule <1-999999> - time starttime -.. cfgcmd:: set firewall ipv4 name rule <1-999999> - time starttime -.. cfgcmd:: set firewall ipv6 ipv6-name rule <1-999999> - time starttime -.. cfgcmd:: set firewall [ipv4 | ipv6] forward filter rule <1-999999> - time stopdate -.. cfgcmd:: set firewall [ipv4 | ipv6] input filter rule <1-999999> - time stopdate -.. cfgcmd:: set firewall [ipv4 | ipv6] output filter rule <1-999999> - time stopdate -.. cfgcmd:: set firewall ipv4 name rule <1-999999> - time stopdate -.. cfgcmd:: set firewall ipv6 ipv6-name rule <1-999999> - time stopdate -.. cfgcmd:: set firewall [ipv4 | ipv6] forward filter rule <1-999999> - time stoptime -.. cfgcmd:: set firewall [ipv4 | ipv6] input filter rule <1-999999> - time stoptime -.. cfgcmd:: set firewall [ipv4 | ipv6] output filter rule <1-999999> - time stoptime -.. cfgcmd:: set firewall ipv4 name rule <1-999999> - time stoptime -.. cfgcmd:: set firewall ipv6 ipv6-name rule <1-999999> - time stoptime -.. cfgcmd:: set firewall [ipv4 | ipv6] forward filter rule <1-999999> - time weekdays -.. cfgcmd:: set firewall [ipv4 | ipv6] input filter rule <1-999999> - time weekdays -.. cfgcmd:: set firewall [ipv4 | ipv6] output filter rule <1-999999> - time weekdays -.. cfgcmd:: set firewall ipv4 name rule <1-999999> - time weekdays -.. cfgcmd:: set firewall ipv6 ipv6-name rule <1-999999> - time weekdays - - Time to match the defined rule. - -.. cfgcmd:: set firewall ipv4 forward filter rule <1-999999> - ttl <0-255> -.. cfgcmd:: set firewall ipv4 input filter rule <1-999999> - ttl <0-255> -.. cfgcmd:: set firewall ipv4 output filter rule <1-999999> - ttl <0-255> -.. cfgcmd:: set firewall ipv4 name rule <1-999999> - ttl <0-255> - - Match time to live parameter, where 'eq' stands for 'equal'; 'gt' stands for - 'greater than', and 'lt' stands for 'less than'. - -.. cfgcmd:: set firewall ipv6 forward filter rule <1-999999> - hop-limit <0-255> -.. cfgcmd:: set firewall ipv6 input filter rule <1-999999> - hop-limit <0-255> -.. cfgcmd:: set firewall ipv6 output filter rule <1-999999> - hop-limit <0-255> -.. cfgcmd:: set firewall ipv6 ipv6-name rule <1-999999> - hop-limit <0-255> - - Match hop-limit parameter, where 'eq' stands for 'equal'; 'gt' stands for - 'greater than', and 'lt' stands for 'less than'. - -.. cfgcmd:: set firewall [ipv4 | ipv6] forward filter rule <1-999999> - recent count <1-255> -.. cfgcmd:: set firewall [ipv4 | ipv6] input filter rule <1-999999> - recent count <1-255> -.. cfgcmd:: set firewall [ipv4 | ipv6] output filter rule <1-999999> - recent count <1-255> -.. cfgcmd:: set firewall ipv4 name rule <1-999999> - recent count <1-255> -.. cfgcmd:: set firewall ipv6 ipv6-name rule <1-999999> - recent count <1-255> - -.. cfgcmd:: set firewall [ipv4 | ipv6] forward filter rule <1-999999> - recent time -.. cfgcmd:: set firewall [ipv4 | ipv6] input filter rule <1-999999> - recent time -.. cfgcmd:: set firewall [ipv4 | ipv6] output filter rule <1-999999> - recent time -.. cfgcmd:: set firewall ipv4 name rule <1-999999> - recent time -.. cfgcmd:: set firewall ipv6 ipv6-name rule <1-999999> - recent time - - Match when 'count' amount of connections are seen within 'time'. These - matching criteria can be used to block brute-force attempts. - -*********************** -Operation-mode Firewall -*********************** - -Rule-set overview -================= - -.. opcmd:: show firewall - - This will show you a basic firewall overview - - .. code-block:: none - - vyos@vyos:~$ show firewall - Rulesets Information - - --------------------------------- - IPv4 Firewall "forward filter" - - Rule Action Protocol Packets Bytes Conditions - ------- -------- ---------- --------- ------- ----------------------------------------- - 5 jump all 0 0 iifname "eth1" jump NAME_VyOS_MANAGEMENT - 10 jump all 0 0 oifname "eth1" jump NAME_WAN_IN - 15 jump all 0 0 iifname "eth3" jump NAME_WAN_IN - default accept all - - --------------------------------- - IPv4 Firewall "name VyOS_MANAGEMENT" - - Rule Action Protocol Packets Bytes Conditions - ------- -------- ---------- --------- ------- -------------------------------- - 5 accept all 0 0 ct state established accept - 10 drop all 0 0 ct state invalid - 20 accept all 0 0 ip saddr @A_GOOD_GUYS accept - 30 accept all 0 0 ip saddr @N_ENTIRE_RANGE accept - 40 accept all 0 0 ip saddr @A_VyOS_SERVERS accept - 50 accept icmp 0 0 meta l4proto icmp accept - default drop all 0 0 - - --------------------------------- - IPv6 Firewall "forward filter" - - Rule Action Protocol - ------- -------- ---------- - 5 jump all - 10 jump all - 15 jump all - default accept all - - --------------------------------- - IPv6 Firewall "input filter" - - Rule Action Protocol - ------- -------- ---------- - 5 jump all - default accept all - - --------------------------------- - IPv6 Firewall "ipv6_name IPV6-VyOS_MANAGEMENT" - - Rule Action Protocol - ------- -------- ---------- - 5 accept all - 10 drop all - 20 accept all - 30 accept all - 40 accept all - 50 accept ipv6-icmp - default drop all - -.. opcmd:: show firewall summary - - This will show you a summary of rule-sets and groups - - .. code-block:: none - - vyos@vyos:~$ show firewall summary - Ruleset Summary - - IPv6 Ruleset: - - Ruleset Hook Ruleset Priority Description - -------------- -------------------- ------------------------- - forward filter - input filter - ipv6_name IPV6-VyOS_MANAGEMENT - ipv6_name IPV6-WAN_IN PUBLIC_INTERNET - - IPv4 Ruleset: - - Ruleset Hook Ruleset Priority Description - -------------- ------------------ ------------------------- - forward filter - input filter - name VyOS_MANAGEMENT - name WAN_IN PUBLIC_INTERNET - - Firewall Groups - - Name Type References Members - ----------------------- ------------------ ----------------------- ---------------- - PBX address_group WAN_IN-100 198.51.100.77 - SERVERS address_group WAN_IN-110 192.0.2.10 - WAN_IN-111 192.0.2.11 - WAN_IN-112 192.0.2.12 - WAN_IN-120 - WAN_IN-121 - WAN_IN-122 - SUPPORT address_group VyOS_MANAGEMENT-20 192.168.1.2 - WAN_IN-20 - PHONE_VPN_SERVERS address_group WAN_IN-160 10.6.32.2 - PINGABLE_ADRESSES address_group WAN_IN-170 192.168.5.2 - WAN_IN-171 - PBX ipv6_address_group IPV6-WAN_IN-100 2001:db8::1 - SERVERS ipv6_address_group IPV6-WAN_IN-110 2001:db8::2 - IPV6-WAN_IN-111 2001:db8::3 - IPV6-WAN_IN-112 2001:db8::4 - IPV6-WAN_IN-120 - IPV6-WAN_IN-121 - IPV6-WAN_IN-122 - SUPPORT ipv6_address_group IPV6-VyOS_MANAGEMENT-20 2001:db8::5 - IPV6-WAN_IN-20 - - -.. opcmd:: show firewall [ipv4 | ipv6] [forward | input | output] filter - -.. opcmd:: show firewall ipv4 name - -.. opcmd:: show firewall ipv6 ipv6-name - - This command will give an overview of a single rule-set. - - .. code-block:: none - - vyos@vyos:~$ show firewall ipv4 input filter - Ruleset Information - - --------------------------------- - IPv4 Firewall "input filter" - - Rule Action Protocol Packets Bytes Conditions - ------- -------- ---------- --------- ------- ----------------------------------------- - 5 jump all 0 0 iifname "eth2" jump NAME_VyOS_MANAGEMENT - default accept all - -.. opcmd:: show firewall [ipv4 | ipv6] [forward | input | output] - filter rule <1-999999> - -.. opcmd:: show firewall ipv4 name rule <1-999999> - -.. opcmd:: show firewall ipv6 ipv6-name rule <1-999999> - - This command will give an overview of a rule in a single rule-set - -.. opcmd:: show firewall group - - Overview of defined groups. You see the type, the members, and where the - group is used. - - .. code-block:: none - - vyos@vyos:~$ show firewall group LAN - Firewall Groups - - Name Type References Members - ------------ ------------------ ----------------------- ---------------- - LAN ipv6_network_group IPV6-VyOS_MANAGEMENT-30 2001:db8::0/64 - IPV6-WAN_IN-30 - LAN network_group VyOS_MANAGEMENT-30 192.168.200.0/24 - WAN_IN-30 - - -.. opcmd:: show firewall statistics - - This will show you a statistic of all rule-sets since the last boot. - -Show Firewall log -================= - -.. opcmd:: show log firewall [name | ipv6name] - - Show the logs of a specific Rule-Set. - -.. note:: - At the moment it not possible to look at the whole firewall log with VyOS - operational commands. All logs will save to ``/var/logs/messages``. - For example: ``grep '10.10.0.10' /var/log/messages`` - - -Example Partial Config -====================== - -.. code-block:: none - - firewall { - group { - network-group BAD-NETWORKS { - network 198.51.100.0/24 - network 203.0.113.0/24 - } - network-group GOOD-NETWORKS { - network 192.0.2.0/24 - } - port-group BAD-PORTS { - port 65535 - } - } - ipv4 { - forward { - filter { - default-action accept - rule 5 { - action accept - source { - group { - network-group GOOD-NETWORKS - } - } - } - rule 10 { - action drop - description "Bad Networks" - protocol all - source { - group { - network-group BAD-NETWORKS - } - } - } - } - } - } - } - -Update geoip database -===================== - -.. opcmd:: update geoip - - Command used to update GeoIP database and firewall sets. diff --git a/docs/configuration/firewall/global-options.rst b/docs/configuration/firewall/global-options.rst new file mode 100644 index 00000000..316e0802 --- /dev/null +++ b/docs/configuration/firewall/global-options.rst @@ -0,0 +1,117 @@ +:lastproofread: 2023-11-07 + +.. _firewall-global-options-configuration: + +##################################### +Global Options Firewall Configuration +##################################### + +******** +Overview +******** + +Some firewall settings are global and have an affect on the whole system. +In this section there's useful information about these global-options that can +be configured using vyos cli. + +Configuration commands covered in this section: + +.. cfgcmd:: set firewall global-options ... + +************* +Configuration +************* + +.. cfgcmd:: set firewall global-options all-ping [enable | disable] + + By default, when VyOS receives an ICMP echo request packet destined for + itself, it will answer with an ICMP echo reply, unless you avoid it + through its firewall. + + With the firewall you can set rules to accept, drop or reject ICMP in, + out or local traffic. You can also use the general **firewall all-ping** + command. This command affects only to LOCAL (packets destined for your + VyOS system), not to IN or OUT traffic. + + .. note:: **firewall global-options all-ping** affects only to LOCAL + and it always behaves in the most restrictive way + + .. code-block:: none + + set firewall global-options all-ping enable + + When the command above is set, VyOS will answer every ICMP echo request + addressed to itself, but that will only happen if no other rule is + applied dropping or rejecting local echo requests. In case of conflict, + VyOS will not answer ICMP echo requests. + + .. code-block:: none + + set firewall global-options all-ping disable + + When the command above is set, VyOS will answer no ICMP echo request + addressed to itself at all, no matter where it comes from or whether + more specific rules are being applied to accept them. + +.. cfgcmd:: set firewall global-options broadcast-ping [enable | disable] + + This setting enable or disable the response of icmp broadcast + messages. The following system parameter will be altered: + + * ``net.ipv4.icmp_echo_ignore_broadcasts`` + +.. cfgcmd:: set firewall global-options ip-src-route [enable | disable] +.. cfgcmd:: set firewall global-options ipv6-src-route [enable | disable] + + This setting handle if VyOS accept packets with a source route + option. The following system parameter will be altered: + + * ``net.ipv4.conf.all.accept_source_route`` + * ``net.ipv6.conf.all.accept_source_route`` + +.. cfgcmd:: set firewall global-options receive-redirects [enable | disable] +.. cfgcmd:: set firewall global-options ipv6-receive-redirects + [enable | disable] + + enable or disable of ICMPv4 or ICMPv6 redirect messages accepted + by VyOS. The following system parameter will be altered: + + * ``net.ipv4.conf.all.accept_redirects`` + * ``net.ipv6.conf.all.accept_redirects`` + +.. cfgcmd:: set firewall global-options send-redirects [enable | disable] + + enable or disable ICMPv4 redirect messages send by VyOS + The following system parameter will be altered: + + * ``net.ipv4.conf.all.send_redirects`` + +.. cfgcmd:: set firewall global-options log-martians [enable | disable] + + enable or disable the logging of martian IPv4 packets. + The following system parameter will be altered: + + * ``net.ipv4.conf.all.log_martians`` + +.. cfgcmd:: set firewall global-options source-validation + [strict | loose | disable] + + Set the IPv4 source validation mode. + The following system parameter will be altered: + + * ``net.ipv4.conf.all.rp_filter`` + +.. cfgcmd:: set firewall global-options syn-cookies [enable | disable] + + Enable or Disable if VyOS use IPv4 TCP SYN Cookies. + The following system parameter will be altered: + + * ``net.ipv4.tcp_syncookies`` + +.. cfgcmd:: set firewall global-options twa-hazards-protection + [enable | disable] + + Enable or Disable VyOS to be :rfc:`1337` conform. + The following system parameter will be altered: + + * ``net.ipv4.tcp_rfc1337`` \ No newline at end of file diff --git a/docs/configuration/firewall/groups.rst b/docs/configuration/firewall/groups.rst new file mode 100644 index 00000000..aee68793 --- /dev/null +++ b/docs/configuration/firewall/groups.rst @@ -0,0 +1,210 @@ +:lastproofread: 2023-11-08 + +.. _firewall-groups-configuration: + +############### +Firewall groups +############### + +************* +Configuration +************* + +Firewall groups represent collections of IP addresses, networks, ports, +mac addresses, domains or interfaces. Once created, a group can be referenced +by firewall, nat and policy route rules as either a source or destination +matcher, and/or as inbound/outbound in the case of interface group. + +Address Groups +============== + +In an **address group** a single IP address or IP address ranges are +defined. + +.. cfgcmd:: set firewall group address-group address [address | + address range] +.. cfgcmd:: set firewall group ipv6-address-group address
+ + Define a IPv4 or a IPv6 address group + + .. code-block:: none + + set firewall group address-group ADR-INSIDE-v4 address 192.168.0.1 + set firewall group address-group ADR-INSIDE-v4 address 10.0.0.1-10.0.0.8 + set firewall group ipv6-address-group ADR-INSIDE-v6 address 2001:db8::1 + +.. cfgcmd:: set firewall group address-group description +.. cfgcmd:: set firewall group ipv6-address-group description + + Provide a IPv4 or IPv6 address group description + +Network Groups +============== + +While **network groups** accept IP networks in CIDR notation, specific +IP addresses can be added as a 32-bit prefix. If you foresee the need +to add a mix of addresses and networks, the network group is +recommended. + +.. cfgcmd:: set firewall group network-group network +.. cfgcmd:: set firewall group ipv6-network-group network + + Define a IPv4 or IPv6 Network group. + + .. code-block:: none + + set firewall group network-group NET-INSIDE-v4 network 192.168.0.0/24 + set firewall group network-group NET-INSIDE-v4 network 192.168.1.0/24 + set firewall group ipv6-network-group NET-INSIDE-v6 network 2001:db8::/64 + +.. cfgcmd:: set firewall group network-group description +.. cfgcmd:: set firewall group ipv6-network-group description + + Provide an IPv4 or IPv6 network group description. + +Interface Groups +================ + +An **interface group** represents a collection of interfaces. + +.. cfgcmd:: set firewall group interface-group interface + + Define an interface group. Wildcard are accepted too. + +.. code-block:: none + + set firewall group interface-group LAN interface bond1001 + set firewall group interface-group LAN interface eth3* + +.. cfgcmd:: set firewall group interface-group description + + Provide an interface group description + +Port Groups +=========== + +A **port group** represents only port numbers, not the protocol. Port +groups can be referenced for either TCP or UDP. It is recommended that +TCP and UDP groups are created separately to avoid accidentally +filtering unnecessary ports. Ranges of ports can be specified by using +`-`. + +.. cfgcmd:: set firewall group port-group port + [portname | portnumber | startport-endport] + + Define a port group. A port name can be any name defined in + /etc/services. e.g.: http + + .. code-block:: none + + set firewall group port-group PORT-TCP-SERVER1 port http + set firewall group port-group PORT-TCP-SERVER1 port 443 + set firewall group port-group PORT-TCP-SERVER1 port 5000-5010 + +.. cfgcmd:: set firewall group port-group description + + Provide a port group description. + +MAC Groups +========== + +A **mac group** represents a collection of mac addresses. + +.. cfgcmd:: set firewall group mac-group mac-address + + Define a mac group. + +.. code-block:: none + + set firewall group mac-group MAC-G01 mac-address 88:a4:c2:15:b6:4f + set firewall group mac-group MAC-G01 mac-address 4c:d5:77:c0:19:81 + +.. cfgcmd:: set firewall group mac-group description + + Provide a mac group description. + +Domain Groups +============= + +A **domain group** represents a collection of domains. + +.. cfgcmd:: set firewall group domain-group address + + Define a domain group. + +.. code-block:: none + + set firewall group domain-group DOM address example.com + +.. cfgcmd:: set firewall group domain-group description + + Provide a domain group description. + +******** +Examples +******** + +As said before, once firewall groups are created, they can be referenced +either in firewall, nat, nat66 and/or policy-route rules. + +Here is an example were multiple groups are created: + + .. code-block:: none + + set firewall group address-group SERVERS address 198.51.100.101 + set firewall group address-group SERVERS address 198.51.100.102 + set firewall group network-group TRUSTEDv4 network 192.0.2.0/30 + set firewall group network-group TRUSTEDv4 network 203.0.113.128/25 + set firewall group ipv6-network-group TRUSTEDv6 network 2001:db8::/64 + set firewall group interface-group LAN interface eth2.2001 + set firewall group interface-group LAN interface bon0 + set firewall group port-group PORT-SERVERS port http + set firewall group port-group PORT-SERVERS port 443 + set firewall group port-group PORT-SERVERS port 5000-5010 + +And next, some configuration example where groups are used: + + .. code-block:: none + + set firewall ipv4 input filter rule 10 action accept + set firewall ipv4 input filter rule 10 inbound-interface group !LAN + set firewall ipv4 forward filter rule 20 action accept + set firewall ipv4 forward filter rule 20 source group network-group TRUSTEDv4 + set firewall ipv6 input filter rule 10 action accept + set firewall ipv6 input filter rule 10 source-group network-group TRUSTEDv6 + set nat destination rule 101 inbound-interface group LAN + set nat destination rule 101 destination group address-group SERVERS + set nat destination rule 101 protocol tcp + set nat destination rule 101 destination group port-group PORT-SERVERS + set nat destination rule 101 translation address 203.0.113.250 + set policy route PBR rule 201 destination group port-group PORT-SERVERS + set policy route PBR rule 201 protocol tcp + set policy route PBR rule 201 set table 15 + +************** +Operation-mode +************** + +.. opcmd:: show firewall group + + Overview of defined groups. You see the type, the members, and where the + group is used. + + .. code-block:: none + + vyos@ZBF-15-CLean:~$ show firewall group + Firewall Groups + + Name Type References Members + ------------ ------------------ ---------------------- ---------------- + SERVERS address_group nat-destination-101 198.51.100.101 + 198.51.100.102 + LAN interface_group ipv4-input-filter-10 bon0 + nat-destination-101 eth2.2001 + TRUSTEDv6 ipv6_network_group ipv6-input-filter-10 2001:db8::/64 + TRUSTEDv4 network_group ipv4-forward-filter-20 192.0.2.0/30 + 203.0.113.128/25 + PORT-SERVERS port_group route-PBR-201 443 + nat-destination-101 5000-5010 + http + vyos@ZBF-15-CLean:~$ diff --git a/docs/configuration/firewall/index.rst b/docs/configuration/firewall/index.rst index 567e48a0..5d094278 100644 --- a/docs/configuration/firewall/index.rst +++ b/docs/configuration/firewall/index.rst @@ -1,24 +1,209 @@ +:lastproofread: 2023-11-08 + ######## Firewall ######## -Starting from VyOS 1.4-rolling-202308040557, a new firewall structure -can be found on all vyos installations. Documentation for most new firewall -cli can be found here: +.. attention:: + Starting from VyOS 1.4-rolling-202308040557, a new firewall structure + can be found on all vyos installations. + +*************** +Netfilter based +*************** + +With VyOS being based on top of Linux and its kernel, the Netfilter project +created the iptables and now the successor nftables for the Linux kernel to +work directly on the data flows. This now extends the concept of zone-based +security to allow for manipulating the data at multiple stages once accepted +by the network interface and the driver before being handed off to the +destination (e.g. a web server OR another device). + +A simplified traffic flow, based on Netfilter packet flow, is shown next, in +order to have a full view and understanding of how packets are processed, and +what possible paths can take. + +.. figure:: /_static/images/firewall-gral-packet-flow.png + +Main notes regarding this packet flow and terminology used in VyOS firewall: + + * **Bridge Port?**: choose appropiate path based on if interface were the + packet was received is part of a bridge, or not. + +If interface were the packet was received isn't part of a bridge, then packet +is processed at the **IP Layer**: + + * **Prerouting**: several actions can be done in this stage, and currently + these actions are defined in different parts in vyos configuration. Order + is important, and all these actions are performed before any actions + define under ``firewall`` section. Relevant configuration that acts in + this stage are: + + * **Conntrack Ignore**: rules defined under ``set system conntrack ignore + [ipv4 | ipv6] ...``. + + * **Policy Route**: rules defined under ``set policy [route | route6] + ...``. + + * **Destination NAT**: rules defined under ``set [nat | nat66] + destination...``. + + * **Destination is the router?**: choose appropiate path based on + destination IP address. Transit forward continunes to **forward**, + while traffic that destination IP address is configured on the router + continues to **input**. + + * **Input**: stage where traffic destinated to the router itself can be + filtered and controlled. This is where all rules for securing the router + should take place. This includes ipv4 and ipv6 filtering rules, defined + in: + + * ``set firewall ipv4 input filter ...``. + + * ``set firewall ipv6 input filter ...``. + + * **Forward**: stage where transit traffic can be filtered and controlled. + This includes ipv4 and ipv6 filtering rules, defined in: + + * ``set firewall ipv4 forward filter ...``. + + * ``set firewall ipv6 forward filter ...``. + + * **Output**: stage where traffic that is originated by the router itself + can be filtered and controlled. Bare in mind that this traffic can be a + new connection originted by a internal process running on VyOS router, + such as NTP, or can be a response to traffic received externaly through + **inputt** (for example response to an ssh login attempt to the router). + This includes ipv4 and ipv6 filtering rules, defined in: + + * ``set firewall ipv4 input filter ...``. + + * ``set firewall ipv6 output filter ...``. + + * **Postrouting**: as in **Prerouting**, several actions defined in + different parts of VyOS configuration are performed in this + stage. This includes: + + * **Source NAT**: rules defined under ``set [nat | nat66] + destination...``. + +If interface were the packet was received is part of a bridge, then packet +is processed at the **Bridge Layer**, which contains a ver basic setup where +for bridge filtering: + + * **Forward (Bridge)**: stage where traffic that is trasspasing through the + bridge is filtered and controlled: + + * ``set firewall bridge forward filter ...``. + +Main structure VyOS firewall cli is shown next: + +.. code-block:: none + + - set firewall + * bridge + - forward + + filter + * flowtable + - custom_flow_table + + ... + * global-options + + all-ping + + broadcast-ping + + ... + * group + - address-group + - ipv6-address-group + - network-group + - ipv6-network-group + - interface-group + - mac-group + - port-group + - domain-group + * ipv4 + - forward + + filter + - input + + filter + - output + + filter + - name + + custom_name + * ipv6 + - forward + + filter + - input + + filter + - output + + filter + - ipv6-name + + custom_name + * zone + - custom_zone_name + + ... + +Please, refer to appropiate section for more information about firewall +configuration: .. toctree:: :maxdepth: 1 :includehidden: - general + global-options + groups + bridge + ipv4 + ipv6 + flowtables + zone -Also, for those who haven't updated to newer version, legacy documentation is -still present and valid for all sagitta version prior to VyOS -1.4-rolling-202308040557: +.. note:: **For more information** + of Netfilter hooks and Linux networking packet flows can be + found in `Netfilter-Hooks + `_ + +*************** +Legacy Firewall +*************** .. toctree:: :maxdepth: 1 :includehidden: general-legacy + +Traditionally firewalls weere configured with the concept of data going in and +out of an interface. The router just listened to the data flowing through and +responding as required if it was directed at the router itself. + +To configure VyOS with the +:doc:`legacy firewall configuration ` + +As the example image below shows, the device was configured with rules blocking +inbound or outbound traffic on each interface. + +.. figure:: /_static/images/firewall-traditional.png + +Zone-based firewall +^^^^^^^^^^^^^^^^^^^ +.. toctree:: + :maxdepth: 1 + :includehidden: + zone + +With zone-based firewalls a new concept was implemented, in addtion to the +standard in and out traffic flows, a local flow was added. This local was for +traffic originating and destined to the router itself. Which means additional +rules were required to secure the firewall itself from the network, in +addition to the existing inbound and outbound rules from the traditional +concept above. + +To configure VyOS with the +:doc:`zone-based firewall configuration ` + +As the example image below shows, the device now needs rules to allow/block +traffic to or from the services running on the device that have open +connections on that interface. + +.. figure:: /_static/images/firewall-zonebased.png diff --git a/docs/configuration/firewall/ipv4.rst b/docs/configuration/firewall/ipv4.rst new file mode 100644 index 00000000..3fd365e1 --- /dev/null +++ b/docs/configuration/firewall/ipv4.rst @@ -0,0 +1,1145 @@ +:lastproofread: 2023-11-08 + +.. _firewall-ipv4-configuration: + +########################### +IPv4 Firewall Configuration +########################### + +******** +Overview +******** + +In this section there's useful information of all firewall configuration that +can be done regarding IPv4, and appropiate op-mode commands. +Configuration commands covered in this section: + +.. cfgcmd:: set firewall ipv4 ... + +From main structure defined in :doc:`Firewall Overview` +in this section you can find detailed information only for the next part +of the general structure: + +.. code-block:: none + + - set firewall + * ipv4 + - forward + + filter + - input + + filter + - output + + filter + - name + + custom_name + +For transit traffic, which is received by the router and forwarded, base chain +is **forward**. A simplified packet flow diagram for transit traffic is shown +next: + +.. figure:: /_static/images/firewall-fwd-packet-flow.png + +Where firewall base chain to configure firewall filtering rules for transit +traffic is ``set firewall ipv4 forward filter ...``, which happens in stage 5, +highlightened with red color. + +For traffic towards the router itself, base chain is **input**, while traffic +originated by the router, base chain is **output**. +A new simplified packet flow diagram is shown next, which shows the path +for traffic destinated to the router itself, and traffic generated by the +router (starting from circle number 6): + +.. figure:: /_static/images/firewall-input-packet-flow.png + +Base chain is for traffic toward the router is ``set firewall ipv4 input +filter ...`` + +And base chain for traffic generated by the router is ``set firewall ipv4 +output filter ...`` + +.. note:: **Important note about default-actions:** + If default action for any base chain is not defined, then the default + action is set to **accept** for that chain. For custom chains, if default + action is not defined, then the default-action is set to **drop** + +Custom firewall chains can be created, with commands +``set firewall ipv4 name ...``. In order to use +such custom chain, a rule with **action jump**, and the appropiate **target** +should be defined in a base chain. + +********************* +Firewall - IPv4 Rules +********************* + +For firewall filtering, firewall rules needs to be created. Each rule is +numbered, has an action to apply if the rule is matched, and the ability +to specify multiple criteria matchers. Data packets go through the rules +from 1 - 999999, so order is crucial. At the first match the action of the +rule will be executed. + +Actions +======= + +If a rule is defined, then an action must be defined for it. This tells the +firewall what to do if all criteria matchers defined for such rule do match. + +The action can be : + + * ``accept``: accept the packet. + + * ``continue``: continue parsing next rule. + + * ``drop``: drop the packet. + + * ``reject``: reject the packet. + + * ``jump``: jump to another custom chain. + + * ``return``: Return from the current chain and continue at the next rule + of the last chain. + + * ``queue``: Enqueue packet to userspace. + + * ``synproxy``: synproxy the packet. + +.. cfgcmd:: set firewall ipv4 forward filter rule <1-999999> action + [accept | continue | drop | jump | queue | reject | return | synproxy] +.. cfgcmd:: set firewall ipv4 input filter rule <1-999999> action + [accept | continue | drop | jump | queue | reject | return | synproxy] +.. cfgcmd:: set firewall ipv4 output filter rule <1-999999> action + [accept | continue | drop | jump | queue | reject | return] +.. cfgcmd:: set firewall ipv4 name rule <1-999999> action + [accept | continue | drop | jump | queue | reject | return] + + This required setting defines the action of the current rule. If action is + set to jump, then jump-target is also needed. + +.. cfgcmd:: set firewall ipv4 forward filter rule <1-999999> + jump-target +.. cfgcmd:: set firewall ipv4 input filter rule <1-999999> + jump-target +.. cfgcmd:: set firewall ipv4 output filter rule <1-999999> + jump-target +.. cfgcmd:: set firewall ipv4 name rule <1-999999> + jump-target + + To be used only when action is set to jump. Use this command to specify + jump target. + +Also, **default-action** is an action that takes place whenever a packet does +not match any rule in it's chain. For base chains, possible options for +**default-action** are **accept** or **drop**. + +.. cfgcmd:: set firewall ipv4 forward filter default-action + [accept | drop] +.. cfgcmd:: set firewall ipv4 input filter default-action + [accept | drop] +.. cfgcmd:: set firewall ipv4 output filter default-action + [accept | drop] +.. cfgcmd:: set firewall ipv4 name default-action + [accept | drop | jump | queue | reject | return] + + This set the default action of the rule-set if no rule matched a packet + criteria. If defacult-action is set to ``jump``, then + ``default-jump-target`` is also needed. Note that for base chains, default + action can only be set to ``accept`` or ``drop``, while on custom chain, + more actions are available. + +.. cfgcmd:: set firewall ipv4 name default-jump-target + + To be used only when ``defult-action`` is set to ``jump``. Use this + command to specify jump target for default rule. + +.. note:: **Important note about default-actions:** + If default action for any base chain is not defined, then the default + action is set to **accept** for that chain. For custom chains, if default + action is not defined, then the default-action is set to **drop** + +Firewall Logs +============= + +Logging can be enable for every single firewall rule. If enabled, other +log options can be defined. + +.. cfgcmd:: set firewall ipv4 forward filter rule <1-999999> log + [disable | enable] +.. cfgcmd:: set firewall ipv4 input filter rule <1-999999> log + [disable | enable] +.. cfgcmd:: set firewall ipv4 output filter rule <1-999999> log + [disable | enable] +.. cfgcmd:: set firewall ipv4 name rule <1-999999> log + [disable | enable] + + Enable or disable logging for the matched packet. + +.. cfgcmd:: set firewall ipv4 forward filter enable-default-log +.. cfgcmd:: set firewall ipv4 input filter enable-default-log +.. cfgcmd:: set firewall ipv4 output filter enable-default-log +.. cfgcmd:: set firewall ipv4 name enable-default-log + + Use this command to enable the logging of the default action on + the specified chain. + +.. cfgcmd:: set firewall ipv4 forward filter rule <1-999999> + log-options level [emerg | alert | crit | err | warn | notice + | info | debug] +.. cfgcmd:: set firewall ipv4 input filter rule <1-999999> + log-options level [emerg | alert | crit | err | warn | notice + | info | debug] +.. cfgcmd:: set firewall ipv4 output filter rule <1-999999> + log-options level [emerg | alert | crit | err | warn | notice + | info | debug] +.. cfgcmd:: set firewall ipv4 name rule <1-999999> + log-options level [emerg | alert | crit | err | warn | notice + | info | debug] + + Define log-level. Only applicable if rule log is enable. + +.. cfgcmd:: set firewall ipv4 forward filter rule <1-999999> + log-options group <0-65535> +.. cfgcmd:: set firewall ipv4 input filter rule <1-999999> + log-options group <0-65535> +.. cfgcmd:: set firewall ipv4 output filter rule <1-999999> + log-options group <0-65535> +.. cfgcmd:: set firewall ipv4 name rule <1-999999> + log-options group <0-65535> + + Define log group to send message to. Only applicable if rule log is enable. + +.. cfgcmd:: set firewall ipv4 forward filter rule <1-999999> + log-options snapshot-length <0-9000> +.. cfgcmd:: set firewall ipv4 input filter rule <1-999999> + log-options snapshot-length <0-9000> +.. cfgcmd:: set firewall ipv4 output filter rule <1-999999> + log-options snapshot-length <0-9000> +.. cfgcmd:: set firewall ipv4 name rule <1-999999> + log-options snapshot-length <0-9000> + + Define length of packet payload to include in netlink message. Only + applicable if rule log is enable and log group is defined. + +.. cfgcmd:: set firewall ipv4 forward filter rule <1-999999> + log-options queue-threshold <0-65535> +.. cfgcmd:: set firewall ipv4 input filter rule <1-999999> + log-options queue-threshold <0-65535> +.. cfgcmd:: set firewall ipv4 output filter rule <1-999999> + log-options queue-threshold <0-65535> +.. cfgcmd:: set firewall ipv4 name rule <1-999999> + log-options queue-threshold <0-65535> + + Define number of packets to queue inside the kernel before sending them to + userspace. Only applicable if rule log is enable and log group is defined. + +Firewall Description +==================== + +For reference, a description can be defined for every single rule, and for +every defined custom chain. + +.. cfgcmd:: set firewall ipv4 name description + + Provide a rule-set description to a custom firewall chain. + +.. cfgcmd:: set firewall ipv4 forward filter rule <1-999999> + description +.. cfgcmd:: set firewall ipv4 input filter rule <1-999999> + description +.. cfgcmd:: set firewall ipv4 output filter rule <1-999999> + description +.. cfgcmd:: set firewall ipv4 name rule <1-999999> description + + Provide a description for each rule. + +Rule Status +=========== + +When defining a rule, it is enable by default. In some cases, it is useful to +just disable the rule, rather than removing it. + +.. cfgcmd:: set firewall ipv4 forward filter rule <1-999999> disable +.. cfgcmd:: set firewall ipv4 input filter rule <1-999999> disable +.. cfgcmd:: set firewall ipv4 output filter rule <1-999999> disable +.. cfgcmd:: set firewall ipv4 name rule <1-999999> disable + + Command for disabling a rule but keep it in the configuration. + +Matching criteria +================= + +There are a lot of matching criteria against which the package can be tested. + +.. cfgcmd:: set firewall ipv4 forward filter rule <1-999999> + connection-status nat [destination | source] +.. cfgcmd:: set firewall ipv4 input filter rule <1-999999> + connection-status nat [destination | source] +.. cfgcmd:: set firewall ipv4 output filter rule <1-999999> + connection-status nat [destination | source] +.. cfgcmd:: set firewall ipv4 name rule <1-999999> + connection-status nat [destination | source] + + Match criteria based on nat connection status. + +.. cfgcmd:: set firewall ipv4 forward filter rule <1-999999> + connection-mark <1-2147483647> +.. cfgcmd:: set firewall ipv4 input filter rule <1-999999> + connection-mark <1-2147483647> +.. cfgcmd:: set firewall ipv4 output filter rule <1-999999> + connection-mark <1-2147483647> +.. cfgcmd:: set firewall ipv4 name rule <1-999999> + connection-mark <1-2147483647> + + Match criteria based on connection mark. + +.. cfgcmd:: set firewall ipv4 forward filter rule <1-999999> + source address [address | addressrange | CIDR] +.. cfgcmd:: set firewall ipv4 input filter rule <1-999999> + source address [address | addressrange | CIDR] +.. cfgcmd:: set firewall ipv4 output filter rule <1-999999> + source address [address | addressrange | CIDR] +.. cfgcmd:: set firewall ipv4 name rule <1-999999> + source address [address | addressrange | CIDR] + +.. cfgcmd:: set firewall ipv4 forward filter rule <1-999999> + destination address [address | addressrange | CIDR] +.. cfgcmd:: set firewall ipv4 input filter rule <1-999999> + destination address [address | addressrange | CIDR] +.. cfgcmd:: set firewall ipv4 output filter rule <1-999999> + destination address [address | addressrange | CIDR] +.. cfgcmd:: set firewall ipv4 name rule <1-999999> + destination address [address | addressrange | CIDR] + + Match criteria based on source and/or destination address. This is similar + to the network groups part, but here you are able to negate the matching + addresses. + + .. code-block:: none + + set firewall ipv4 name FOO rule 50 source address 192.0.2.10-192.0.2.11 + # with a '!' the rule match everything except the specified subnet + set firewall ipv4 input filter FOO rule 51 source address !203.0.113.0/24 + +.. cfgcmd:: set firewall ipv4 forward filter rule <1-999999> + source address-mask [address] +.. cfgcmd:: set firewall ipv4 input filter rule <1-999999> + source address-mask [address] +.. cfgcmd:: set firewall ipv4 output filter rule <1-999999> + source address-mask [address] +.. cfgcmd:: set firewall ipv4 name rule <1-999999> + source address-mask [address] + +.. cfgcmd:: set firewall ipv4 forward filter rule <1-999999> + destination address-mask [address] +.. cfgcmd:: set firewall ipv4 input filter rule <1-999999> + destination address-mask [address] +.. cfgcmd:: set firewall ipv4 output filter rule <1-999999> + destination address-mask [address] +.. cfgcmd:: set firewall ipv4 name rule <1-999999> + destination address-mask [address] + + An arbitrary netmask can be applied to mask addresses to only match against + a specific portion. + + This functions for both individual addresses and address groups. + + .. code-block:: none + + # Match any IPv4 address with `11` as the 2nd octet and `13` as the forth octet + set firewall ipv4 name FOO rule 100 destination address 0.11.0.13 + set firewall ipv4 name FOO rule 100 destination address-mask 0.255.0.255 + +.. cfgcmd:: set firewall ipv4 forward filter rule <1-999999> + source fqdn +.. cfgcmd:: set firewall ipv4 input filter rule <1-999999> + source fqdn +.. cfgcmd:: set firewall ipv4 output filter rule <1-999999> + source fqdn +.. cfgcmd:: set firewall ipv4 name rule <1-999999> + source fqdn +.. cfgcmd:: set firewall ipv4 forward filter rule <1-999999> + destination fqdn +.. cfgcmd:: set firewall ipv4 input filter rule <1-999999> + destination fqdn +.. cfgcmd:: set firewall ipv4 output filter rule <1-999999> + destination fqdn +.. cfgcmd:: set firewall ipv4 name rule <1-999999> + destination fqdn + + Specify a Fully Qualified Domain Name as source/destination matcher. Ensure + router is able to resolve such dns query. + +.. cfgcmd:: set firewall ipv4 forward filter rule <1-999999> + source geoip country-code +.. cfgcmd:: set firewall ipv4 input filter rule <1-999999> + source geoip country-code +.. cfgcmd:: set firewall ipv4 output filter rule <1-999999> + source geoip country-code +.. cfgcmd:: set firewall ipv4 name rule <1-999999> + source geoip country-code + +.. cfgcmd:: set firewall ipv4 forward filter rule <1-999999> + destination geoip country-code +.. cfgcmd:: set firewall ipv4 input filter rule <1-999999> + destination geoip country-code +.. cfgcmd:: set firewall ipv4 output filter rule <1-999999> + destination geoip country-code +.. cfgcmd:: set firewall ipv4 name rule <1-999999> + destination geoip country-code + +.. cfgcmd:: set firewall ipv4 forward filter rule <1-999999> + source geoip inverse-match +.. cfgcmd:: set firewall ipv4 input filter rule <1-999999> + source geoip inverse-match +.. cfgcmd:: set firewall ipv4 output filter rule <1-999999> + source geoip inverse-match +.. cfgcmd:: set firewall ipv4 name rule <1-999999> + source geoip inverse-match + +.. cfgcmd:: set firewall ipv4 forward filter rule <1-999999> + destination geoip inverse-match +.. cfgcmd:: set firewall ipv4 input filter rule <1-999999> + destination geoip inverse-match +.. cfgcmd:: set firewall ipv4 output filter rule <1-999999> + destination geoip inverse-match +.. cfgcmd:: set firewall ipv4 name rule <1-999999> + destination geoip inverse-match + + Match IP addresses based on its geolocation. More info: `geoip matching + `_. + Use inverse-match to match anything except the given country-codes. + +Data is provided by DB-IP.com under CC-BY-4.0 license. Attribution required, +permits redistribution so we can include a database in images(~3MB +compressed). Includes cron script (manually callable by op-mode update +geoip) to keep database and rules updated. + + +.. cfgcmd:: set firewall ipv4 forward filter rule <1-999999> + source mac-address +.. cfgcmd:: set firewall ipv4 input filter rule <1-999999> + source mac-address +.. cfgcmd:: set firewall ipv4 output filter rule <1-999999> + source mac-address +.. cfgcmd:: set firewall ipv4 name rule <1-999999> + source mac-address + + Only in the source criteria, you can specify a mac-address. + + .. code-block:: none + + set firewall ipv4 input filter rule 100 source mac-address 00:53:00:11:22:33 + set firewall ipv4 input filter rule 101 source mac-address !00:53:00:aa:12:34 + + +.. cfgcmd:: set firewall ipv4 forward filter rule <1-999999> + source port [1-65535 | portname | start-end] +.. cfgcmd:: set firewall ipv4 input filter rule <1-999999> + source port [1-65535 | portname | start-end] +.. cfgcmd:: set firewall ipv4 output filter rule <1-999999> + source port [1-65535 | portname | start-end] +.. cfgcmd:: set firewall ipv4 name rule <1-999999> + source port [1-65535 | portname | start-end] + +.. cfgcmd:: set firewall ipv4 forward filter rule <1-999999> + destination port [1-65535 | portname | start-end] +.. cfgcmd:: set firewall ipv4 input filter rule <1-999999> + destination port [1-65535 | portname | start-end] +.. cfgcmd:: set firewall ipv4 output filter rule <1-999999> + destination port [1-65535 | portname | start-end] +.. cfgcmd:: set firewall ipv4 name rule <1-999999> + destination port [1-65535 | portname | start-end] + + A port can be set with a port number or a name which is here + defined: ``/etc/services``. + + .. code-block:: none + + set firewall ipv4 forward filter rule 10 source port '22' + set firewall ipv4 forward filter rule 11 source port '!http' + set firewall ipv4 forward filter rule 12 source port 'https' + + Multiple source ports can be specified as a comma-separated list. + The whole list can also be "negated" using ``!``. For example: + +.. cfgcmd:: set firewall ipv4 forward filter rule <1-999999> + source group address-group +.. cfgcmd:: set firewall ipv4 input filter rule <1-999999> + source group address-group +.. cfgcmd:: set firewall ipv4 output filter rule <1-999999> + source group address-group +.. cfgcmd:: set firewall ipv4 name rule <1-999999> + source group address-group + +.. cfgcmd:: set firewall ipv4 forward filter rule <1-999999> + destination group address-group +.. cfgcmd:: set firewall ipv4 input filter rule <1-999999> + destination group address-group +.. cfgcmd:: set firewall ipv4 output filter rule <1-999999> + destination group address-group +.. cfgcmd:: set firewall ipv4 name rule <1-999999> + destination group address-group + + Use a specific address-group. Prepend character ``!`` for inverted matching + criteria. + +.. cfgcmd:: set firewall ipv4 forward filter rule <1-999999> + source group network-group +.. cfgcmd:: set firewall ipv4 input filter rule <1-999999> + source group network-group +.. cfgcmd:: set firewall ipv4 output filter rule <1-999999> + source group network-group +.. cfgcmd:: set firewall ipv4 name rule <1-999999> + source group network-group + +.. cfgcmd:: set firewall ipv4 forward filter rule <1-999999> + destination group network-group +.. cfgcmd:: set firewall ipv4 input filter rule <1-999999> + destination group network-group +.. cfgcmd:: set firewall ipv4 output filter rule <1-999999> + destination group network-group +.. cfgcmd:: set firewall ipv4 name rule <1-999999> + destination group network-group + + Use a specific network-group. Prepend character ``!`` for inverted matching + criteria. + +.. cfgcmd:: set firewall ipv4 forward filter rule <1-999999> + source group port-group +.. cfgcmd:: set firewall ipv4 input filter rule <1-999999> + source group port-group +.. cfgcmd:: set firewall ipv4 output filter rule <1-999999> + source group port-group +.. cfgcmd:: set firewall ipv4 name rule <1-999999> + source group port-group + +.. cfgcmd:: set firewall ipv4 forward filter rule <1-999999> + destination group port-group +.. cfgcmd:: set firewall ipv4 input filter rule <1-999999> + destination group port-group +.. cfgcmd:: set firewall ipv4 output filter rule <1-999999> + destination group port-group +.. cfgcmd:: set firewall ipv4 name rule <1-999999> + destination group port-group + + Use a specific port-group. Prepend character ``!`` for inverted matching + criteria. + +.. cfgcmd:: set firewall ipv4 forward filter rule <1-999999> + source group domain-group +.. cfgcmd:: set firewall ipv4 input filter rule <1-999999> + source group domain-group +.. cfgcmd:: set firewall ipv4 output filter rule <1-999999> + source group domain-group +.. cfgcmd:: set firewall ipv4 name rule <1-999999> + source group domain-group + +.. cfgcmd:: set firewall ipv4 forward filter rule <1-999999> + destination group domain-group +.. cfgcmd:: set firewall ipv4 input filter rule <1-999999> + destination group domain-group +.. cfgcmd:: set firewall ipv4 output filter rule <1-999999> + destination group domain-group +.. cfgcmd:: set firewall ipv4 name rule <1-999999> + destination group domain-group + + Use a specific domain-group. Prepend character ``!`` for inverted matching + criteria. + +.. cfgcmd:: set firewall ipv4 forward filter rule <1-999999> + source group mac-group +.. cfgcmd:: set firewall ipv4 input filter rule <1-999999> + source group mac-group +.. cfgcmd:: set firewall ipv4 output filter rule <1-999999> + source group mac-group +.. cfgcmd:: set firewall ipv4 name rule <1-999999> + source group mac-group + +.. cfgcmd:: set firewall ipv4 forward filter rule <1-999999> + destination group mac-group +.. cfgcmd:: set firewall ipv4 input filter rule <1-999999> + destination group mac-group +.. cfgcmd:: set firewall ipv4 output filter rule <1-999999> + destination group mac-group +.. cfgcmd:: set firewall ipv4 name rule <1-999999> + destination group mac-group + + Use a specific mac-group. Prepend character ``!`` for inverted matching + criteria. + +.. cfgcmd:: set firewall ipv4 forward filter rule <1-999999> + dscp [0-63 | start-end] +.. cfgcmd:: set firewall ipv4 input filter rule <1-999999> + dscp [0-63 | start-end] +.. cfgcmd:: set firewall ipv4 output filter rule <1-999999> + dscp [0-63 | start-end] +.. cfgcmd:: set firewall ipv4 name rule <1-999999> + dscp [0-63 | start-end] + +.. cfgcmd:: set firewall ipv4 forward filter rule <1-999999> + dscp-exclude [0-63 | start-end] +.. cfgcmd:: set firewall ipv4 input filter rule <1-999999> + dscp-exclude [0-63 | start-end] +.. cfgcmd:: set firewall ipv4 output filter rule <1-999999> + dscp-exclude [0-63 | start-end] +.. cfgcmd:: set firewall ipv4 name rule <1-999999> + dscp-exclude [0-63 | start-end] + + Match based on dscp value. + +.. cfgcmd:: set firewall ipv4 forward filter rule <1-999999> + fragment [match-frag | match-non-frag] +.. cfgcmd:: set firewall ipv4 input filter rule <1-999999> + fragment [match-frag | match-non-frag] +.. cfgcmd:: set firewall ipv4 output filter rule <1-999999> + fragment [match-frag | match-non-frag] +.. cfgcmd:: set firewall ipv4 name rule <1-999999> + fragment [match-frag | match-non-frag] + + Match based on fragment criteria. + +.. cfgcmd:: set firewall ipv4 forward filter rule <1-999999> + icmp [code | type] <0-255> +.. cfgcmd:: set firewall ipv4 input filter rule <1-999999> + icmp [code | type] <0-255> +.. cfgcmd:: set firewall ipv4 output filter rule <1-999999> + icmp [code | type] <0-255> +.. cfgcmd:: set firewall ipv4 name rule <1-999999> + icmp [code | type] <0-255> + + Match based on icmp code and type. + +.. cfgcmd:: set firewall ipv4 forward filter rule <1-999999> + icmp type-name +.. cfgcmd:: set firewall ipv4 input filter rule <1-999999> + icmp type-name +.. cfgcmd:: set firewall ipv4 output filter rule <1-999999> + icmp type-name +.. cfgcmd:: set firewall ipv4 name rule <1-999999> + icmp type-name + + Match based on icmp type-name criteria. Use tab for information + about what **type-name** criteria are supported. + +.. cfgcmd:: set firewall ipv4 forward filter rule <1-999999> + inbound-interface name +.. cfgcmd:: set firewall ipv4 input filter rule <1-999999> + inbound-interface name +.. cfgcmd:: set firewall ipv4 name rule <1-999999> + inbound-interface name + + Match based on inbound interface. Wilcard ``*`` can be used. + For example: ``eth2*``. Prepending character ``!`` for inverted matching + criteria is also supportd. For example ``!eth2`` + +.. cfgcmd:: set firewall ipv4 forward filter rule <1-999999> + inbound-interface group +.. cfgcmd:: set firewall ipv4 input filter rule <1-999999> + inbound-interface group +.. cfgcmd:: set firewall ipv4 name rule <1-999999> + inbound-interface group + + Match based on inbound interface group. Prepending character ``!`` for + inverted matching criteria is also supportd. For example ``!IFACE_GROUP`` + +.. cfgcmd:: set firewall ipv4 forward filter rule <1-999999> + outbound-interface name +.. cfgcmd:: set firewall ipv4 output filter rule <1-999999> + outbound-interface name +.. cfgcmd:: set firewall ipv4 name rule <1-999999> + outbound-interface name + + Match based on outbound interface. Wilcard ``*`` can be used. + For example: ``eth2*``. Prepending character ``!`` for inverted matching + criteria is also supportd. For example ``!eth2`` + +.. cfgcmd:: set firewall ipv4 forward filter rule <1-999999> + outbound-interface group +.. cfgcmd:: set firewall ipv4 output filter rule <1-999999> + outbound-interface group +.. cfgcmd:: set firewall ipv4 name rule <1-999999> + outbound-interface group + + Match based on outbound interface group. Prepending character ``!`` for + inverted matching criteria is also supportd. For example ``!IFACE_GROUP`` + +.. cfgcmd:: set firewall ipv4 forward filter rule <1-999999> + ipsec [match-ipsec | match-none] +.. cfgcmd:: set firewall ipv4 input filter rule <1-999999> + ipsec [match-ipsec | match-none] +.. cfgcmd:: set firewall ipv4 output filter rule <1-999999> + ipsec [match-ipsec | match-none] +.. cfgcmd:: set firewall ipv4 name rule <1-999999> + ipsec [match-ipsec | match-none] + + Match based on ipsec criteria. + +.. cfgcmd:: set firewall ipv4 forward filter rule <1-999999> + limit burst <0-4294967295> +.. cfgcmd:: set firewall ipv4 input filter rule <1-999999> + limit burst <0-4294967295> +.. cfgcmd:: set firewall ipv4 output filter rule <1-999999> + limit burst <0-4294967295> +.. cfgcmd:: set firewall ipv4 name rule <1-999999> + limit burst <0-4294967295> + + Match based on the maximum number of packets to allow in excess of rate. + +.. cfgcmd:: set firewall ipv4 forward filter rule <1-999999> + limit rate +.. cfgcmd:: set firewall ipv4 input filter rule <1-999999> + limit rate +.. cfgcmd:: set firewall ipv4 output filter rule <1-999999> + limit rate +.. cfgcmd:: set firewall ipv4 name rule <1-999999> + limit rate + + Match based on the maximum average rate, specified as **integer/unit**. + For example **5/minutes** + +.. cfgcmd:: set firewall ipv4 forward filter rule <1-999999> + packet-length +.. cfgcmd:: set firewall ipv4 input filter rule <1-999999> + packet-length +.. cfgcmd:: set firewall ipv4 output filter rule <1-999999> + packet-length +.. cfgcmd:: set firewall ipv4 name rule <1-999999> + packet-length + +.. cfgcmd:: set firewall ipv4 forward filter rule <1-999999> + packet-length-exclude +.. cfgcmd:: set firewall ipv4 input filter rule <1-999999> + packet-length-exclude +.. cfgcmd:: set firewall ipv4 output filter rule <1-999999> + packet-length-exclude +.. cfgcmd:: set firewall ipv4 name rule <1-999999> + packet-length-exclude + + Match based on packet length criteria. Multiple values from 1 to 65535 + and ranges are supported. + +.. cfgcmd:: set firewall ipv4 forward filter rule <1-999999> + packet-type [broadcast | host | multicast | other] +.. cfgcmd:: set firewall ipv4 input filter rule <1-999999> + packet-type [broadcast | host | multicast | other] +.. cfgcmd:: set firewall ipv4 output filter rule <1-999999> + packet-type [broadcast | host | multicast | other] +.. cfgcmd:: set firewall ipv4 name rule <1-999999> + packet-type [broadcast | host | multicast | other] + + Match based on packet type criteria. + +.. cfgcmd:: set firewall ipv4 forward filter rule <1-999999> + protocol [ | <0-255> | all | tcp_udp] +.. cfgcmd:: set firewall ipv4 input filter rule <1-999999> + protocol [ | <0-255> | all | tcp_udp] +.. cfgcmd:: set firewall ipv4 output filter rule <1-999999> + protocol [ | <0-255> | all | tcp_udp] +.. cfgcmd:: set firewall ipv4 name rule <1-999999> + protocol [ | <0-255> | all | tcp_udp] + + Match a protocol criteria. A protocol number or a name which is here + defined: ``/etc/protocols``. + Special names are ``all`` for all protocols and ``tcp_udp`` for tcp and udp + based packets. The ``!`` negate the selected protocol. + + .. code-block:: none + + set firewall ipv4 forward fitler rule 10 protocol tcp_udp + set firewall ipv4 forward fitler rule 11 protocol !tcp_udp + +.. cfgcmd:: set firewall ipv4 forward filter rule <1-999999> + recent count <1-255> +.. cfgcmd:: set firewall ipv4 input filter rule <1-999999> + recent count <1-255> +.. cfgcmd:: set firewall ipv4 output filter rule <1-999999> + recent count <1-255> +.. cfgcmd:: set firewall ipv4 name rule <1-999999> + recent count <1-255> + +.. cfgcmd:: set firewall ipv4 forward filter rule <1-999999> + recent time [second | minute | hour] +.. cfgcmd:: set firewall ipv4 input filter rule <1-999999> + recent time [second | minute | hour] +.. cfgcmd:: set firewall ipv4 output filter rule <1-999999> + recent time [second | minute | hour] +.. cfgcmd:: set firewall ipv4 name rule <1-999999> + recent time [second | minute | hour] + + Match bases on recently seen sources. + +.. cfgcmd:: set firewall ipv4 forward filter rule <1-999999> + tcp flags [not] +.. cfgcmd:: set firewall ipv4 input filter rule <1-999999> + tcp flags [not] +.. cfgcmd:: set firewall ipv4 output filter rule <1-999999> + tcp flags [not] +.. cfgcmd:: set firewall ipv4 name rule <1-999999> + tcp flags [not] + + Allowed values fpr TCP flags: ``ack``, ``cwr``, ``ecn``, ``fin``, ``psh``, + ``rst``, ``syn`` and ``urg``. Multiple values are supported, and for + inverted selection use ``not``, as shown in the example. + + .. code-block:: none + + set firewall ipv4 input filter rule 10 tcp flags 'ack' + set firewall ipv4 input filter rule 12 tcp flags 'syn' + set firewall ipv4 input filter rule 13 tcp flags not 'fin' + +.. cfgcmd:: set firewall ipv4 forward filter rule <1-999999> + state [established | invalid | new | related] [enable | disable] +.. cfgcmd:: set firewall ipv4 input filter rule <1-999999> + state [established | invalid | new | related] [enable | disable] +.. cfgcmd:: set firewall ipv4 output filter rule <1-999999> + state [established | invalid | new | related] [enable | disable] +.. cfgcmd:: set firewall ipv4 name rule <1-999999> + state [established | invalid | new | related] [enable | disable] + + Match against the state of a packet. + +.. cfgcmd:: set firewall ipv4 forward filter rule <1-999999> + time startdate +.. cfgcmd:: set firewall ipv4 input filter rule <1-999999> + time startdate +.. cfgcmd:: set firewall ipv4 output filter rule <1-999999> + time startdate +.. cfgcmd:: set firewall ipv4 name rule <1-999999> + time startdate +.. cfgcmd:: set firewall ipv4 forward filter rule <1-999999> + time starttime +.. cfgcmd:: set firewall ipv4 input filter rule <1-999999> + time starttime +.. cfgcmd:: set firewall ipv4 output filter rule <1-999999> + time starttime +.. cfgcmd:: set firewall ipv4 name rule <1-999999> + time starttime +.. cfgcmd:: set firewall ipv4 forward filter rule <1-999999> + time stopdate +.. cfgcmd:: set firewall ipv4 input filter rule <1-999999> + time stopdate +.. cfgcmd:: set firewall ipv4 output filter rule <1-999999> + time stopdate +.. cfgcmd:: set firewall ipv4 name rule <1-999999> + time stopdate +.. cfgcmd:: set firewall ipv4 forward filter rule <1-999999> + time stoptime +.. cfgcmd:: set firewall ipv4 input filter rule <1-999999> + time stoptime +.. cfgcmd:: set firewall ipv4 output filter rule <1-999999> + time stoptime +.. cfgcmd:: set firewall ipv4 name rule <1-999999> + time stoptime +.. cfgcmd:: set firewall ipv4 forward filter rule <1-999999> + time weekdays +.. cfgcmd:: set firewall ipv4 input filter rule <1-999999> + time weekdays +.. cfgcmd:: set firewall ipv4 output filter rule <1-999999> + time weekdays +.. cfgcmd:: set firewall ipv4 name rule <1-999999> + time weekdays + + Time to match the defined rule. + +.. cfgcmd:: set firewall ipv4 forward filter rule <1-999999> + ttl <0-255> +.. cfgcmd:: set firewall ipv4 input filter rule <1-999999> + ttl <0-255> +.. cfgcmd:: set firewall ipv4 output filter rule <1-999999> + ttl <0-255> +.. cfgcmd:: set firewall ipv4 name rule <1-999999> + ttl <0-255> + + Match time to live parameter, where 'eq' stands for 'equal'; 'gt' stands for + 'greater than', and 'lt' stands for 'less than'. + +.. cfgcmd:: set firewall ipv4 forward filter rule <1-999999> + recent count <1-255> +.. cfgcmd:: set firewall ipv4 input filter rule <1-999999> + recent count <1-255> +.. cfgcmd:: set firewall ipv4 output filter rule <1-999999> + recent count <1-255> +.. cfgcmd:: set firewall ipv4 name rule <1-999999> + recent count <1-255> + +.. cfgcmd:: set firewall ipv4 forward filter rule <1-999999> + recent time +.. cfgcmd:: set firewall ipv4 input filter rule <1-999999> + recent time +.. cfgcmd:: set firewall ipv4 output filter rule <1-999999> + recent time +.. cfgcmd:: set firewall ipv4 name rule <1-999999> + recent time + + Match when 'count' amount of connections are seen within 'time'. These + matching criteria can be used to block brute-force attempts. + +******** +Synproxy +******** +Synproxy connections + +.. cfgcmd:: set firewall ipv4 [input | forward] filter rule <1-999999> action synproxy +.. cfgcmd:: set firewall ipv4 [input | forward] filter rule <1-999999> protocol tcp +.. cfgcmd:: set firewall ipv4 [input | forward] filter rule <1-999999> synproxy tcp mss <501-65535> + + Set TCP-MSS (maximum segment size) for the connection + +.. cfgcmd:: set firewall ipv4 [input | forward] filter rule <1-999999> synproxy tcp window-scale <1-14> + + Set the window scale factor for TCP window scaling + +Example synproxy +================ +Requirements to enable synproxy: + + * Traffic must be symmetric + * Synproxy relies on syncookies and TCP timestamps, ensure these are enabled + * Disable conntrack loose track option + +.. code-block:: none + + set system sysctl parameter net.ipv4.tcp_timestamps value '1' + + set system conntrack tcp loose disable + set system conntrack ignore ipv4 rule 10 destination port '8080' + set system conntrack ignore ipv4 rule 10 protocol 'tcp' + set system conntrack ignore ipv4 rule 10 tcp flags syn + + set firewall global-options syn-cookies 'enable' + set firewall ipv4 input filter rule 10 action 'synproxy' + set firewall ipv4 input filter rule 10 destination port '8080' + set firewall ipv4 input filter rule 10 inbound-interface interface-name 'eth1' + set firewall ipv4 input filter rule 10 protocol 'tcp' + set firewall ipv4 input filter rule 10 synproxy tcp mss '1460' + set firewall ipv4 input filter rule 10 synproxy tcp window-scale '7' + set firewall ipv4 input filter rule 1000 action 'drop' + set firewall ipv4 input filter rule 1000 state invalid 'enable' + + +*********************** +Operation-mode Firewall +*********************** + +Rule-set overview +================= + +.. opcmd:: show firewall + + This will show you a basic firewall overview, for all ruleset, and not + only for ipv4 + + .. code-block:: none + + vyos@vyos:~$ show firewall + Rulesets Information + + --------------------------------- + ipv4 Firewall "forward filter" + + Rule Action Protocol Packets Bytes Conditions + ------- -------- ---------- --------- ------- ----------------------------- + 20 accept all 0 0 ip saddr @N_TRUSTEDv4 accept + 21 jump all 0 0 jump NAME_AUX + default accept all 0 0 + + --------------------------------- + ipv4 Firewall "input filter" + + Rule Action Protocol Packets Bytes Conditions + ------- -------- ---------- --------- ------- ------------------------- + 10 accept all 156 14377 iifname != @I_LAN accept + default accept all 0 0 + + --------------------------------- + ipv4 Firewall "name AUX" + + Rule Action Protocol Packets Bytes Conditions + ------ -------- ---------- --------- ------- -------------------------------------------- + 10 accept icmp 0 0 meta l4proto icmp accept + 20 accept udp 0 0 meta l4proto udp ip saddr @A_SERVERS accept + 30 drop all 0 0 ip saddr != @A_SERVERS iifname "eth2" + + --------------------------------- + ipv4 Firewall "output filter" + + Rule Action Protocol Packets Bytes Conditions + ------- -------- ---------- --------- ------- ---------------------------------------- + 10 reject all 0 0 oifname @I_LAN + 20 accept icmp 2 168 meta l4proto icmp oifname "eth0" accept + default accept all 72 9258 + + --------------------------------- + ipv6 Firewall "input filter" + + Rule Action Protocol Packets Bytes Conditions + ------- -------- ---------- --------- ------- ------------------------------- + 10 accept all 0 0 ip6 saddr @N6_TRUSTEDv6 accept + default accept all 2 112 + + vyos@vyos:~$ + +.. opcmd:: show firewall summary + + This will show you a summary of rule-sets and groups + + .. code-block:: none + + vyos@vyos:~$ show firewall summary + Ruleset Summary + + IPv6 Ruleset: + + Ruleset Hook Ruleset Priority Description + -------------- -------------------- ------------------------- + forward filter + input filter + ipv6_name IPV6-VyOS_MANAGEMENT + ipv6_name IPV6-WAN_IN PUBLIC_INTERNET + + IPv4 Ruleset: + + Ruleset Hook Ruleset Priority Description + -------------- ------------------ ------------------------- + forward filter + input filter + name VyOS_MANAGEMENT + name WAN_IN PUBLIC_INTERNET + + Firewall Groups + + Name Type References Members + ----------------------- ------------------ ----------------------- ---------------- + PBX address_group WAN_IN-100 198.51.100.77 + SERVERS address_group WAN_IN-110 192.0.2.10 + WAN_IN-111 192.0.2.11 + WAN_IN-112 192.0.2.12 + WAN_IN-120 + WAN_IN-121 + WAN_IN-122 + SUPPORT address_group VyOS_MANAGEMENT-20 192.168.1.2 + WAN_IN-20 + PHONE_VPN_SERVERS address_group WAN_IN-160 10.6.32.2 + PINGABLE_ADRESSES address_group WAN_IN-170 192.168.5.2 + WAN_IN-171 + PBX ipv6_address_group IPV6-WAN_IN-100 2001:db8::1 + SERVERS ipv6_address_group IPV6-WAN_IN-110 2001:db8::2 + IPV6-WAN_IN-111 2001:db8::3 + IPV6-WAN_IN-112 2001:db8::4 + IPV6-WAN_IN-120 + IPV6-WAN_IN-121 + IPV6-WAN_IN-122 + SUPPORT ipv6_address_group IPV6-VyOS_MANAGEMENT-20 2001:db8::5 + IPV6-WAN_IN-20 + + +.. opcmd:: show firewall ipv4 [forward | input | output] filter + +.. opcmd:: show firewall ipv4 name + + This command will give an overview of a single rule-set. + + .. code-block:: none + + vyos@vyos:~$ show firewall ipv4 input filter + Ruleset Information + + --------------------------------- + IPv4 Firewall "input filter" + + Rule Action Protocol Packets Bytes Conditions + ------- -------- ---------- --------- ------- ----------------------------------------- + 5 jump all 0 0 iifname "eth2" jump NAME_VyOS_MANAGEMENT + default accept all + +.. opcmd:: show firewall ipv4 [forward | input | output] + filter rule <1-999999> +.. opcmd:: show firewall ipv4 name rule <1-999999> + + This command will give an overview of a rule in a single rule-set, plus + information for default action. + +.. code-block:: none + + vyos@vyos:~$show firewall ipv4 output filter rule 20 + Rule Information + + --------------------------------- + ipv4 Firewall "output filter" + + Rule Action Protocol Packets Bytes Conditions + ------- -------- ---------- --------- ------- ---------------------------------------- + 20 accept icmp 2 168 meta l4proto icmp oifname "eth0" accept + default accept all 286 47614 + + vyos@vyos:~$ + + +.. opcmd:: show firewall statistics + + This will show you a statistic of all rule-sets since the last boot. + +Show Firewall log +================= + +.. opcmd:: show log firewall +.. opcmd:: show log firewall ipv4 +.. opcmd:: show log firewall ipv4 [forward | input | output | name] +.. opcmd:: show log firewall ipv4 [forward | input | output] filter +.. opcmd:: show log firewall ipv4 name +.. opcmd:: show log firewall ipv4 [forward | input | output] filter rule +.. opcmd:: show log firewall ipv4 name rule + + Show the logs of all firewall; show all ipv4 firewall logs; show all logs + for particular hook; show all logs for particular hook and priority; show all logs + for particular custom chain; show logs for specific Rule-Set. + +Example Partial Config +====================== + +.. code-block:: none + + firewall { + group { + network-group BAD-NETWORKS { + network 198.51.100.0/24 + network 203.0.113.0/24 + } + network-group GOOD-NETWORKS { + network 192.0.2.0/24 + } + port-group BAD-PORTS { + port 65535 + } + } + ipv4 { + forward { + filter { + default-action accept + rule 5 { + action accept + source { + group { + network-group GOOD-NETWORKS + } + } + } + rule 10 { + action drop + description "Bad Networks" + protocol all + source { + group { + network-group BAD-NETWORKS + } + } + } + } + } + } + } + +Update geoip database +===================== + +.. opcmd:: update geoip + + Command used to update GeoIP database and firewall sets. diff --git a/docs/configuration/firewall/ipv6.rst b/docs/configuration/firewall/ipv6.rst new file mode 100644 index 00000000..83a5f694 --- /dev/null +++ b/docs/configuration/firewall/ipv6.rst @@ -0,0 +1,1167 @@ +:lastproofread: 2023-11-08 + +.. _firewall-ipv6-configuration: + +########################### +IPv6 Firewall Configuration +########################### + +******** +Overview +******** + +In this section there's useful information of all firewall configuration that +can be done regarding IPv6, and appropiate op-mode commands. +Configuration commands covered in this section: + +.. cfgcmd:: set firewall ipv6 ... + +From main structure defined in :doc:`Firewall Overview` +in this section you can find detailed information only for the next part +of the general structure: + +.. code-block:: none + + - set firewall + * ipv6 + - forward + + filter + - input + + filter + - output + + filter + - name + + custom_name + +For transit traffic, which is received by the router and forwarded, base chain +is **forward**. A simplified packet flow diagram for transit traffic is shown +next: + +.. figure:: /_static/images/firewall-fwd-packet-flow.png + +Where firewall base chain to configure firewall filtering rules for transit +traffic is ``set firewall ipv6 forward filter ...``, which happens in stage 5, +highlightened with red color. + +For traffic towards the router itself, base chain is **input**, while traffic +originated by the router, base chain is **output**. +A new simplified packet flow diagram is shown next, which shows the path +for traffic destinated to the router itself, and traffic generated by the +router (starting from circle number 6): + +.. figure:: /_static/images/firewall-input-packet-flow.png + +Base chain is for traffic toward the router is ``set firewall ipv6 input +filter ...`` + +And base chain for traffic generated by the router is ``set firewall ipv6 +output filter ...`` + +.. note:: **Important note about default-actions:** + If default action for any base chain is not defined, then the default + action is set to **accept** for that chain. For custom chains, if default + action is not defined, then the default-action is set to **drop** + +Custom firewall chains can be created, with commands +``set firewall ipv6 name ...``. In order to use +such custom chain, a rule with **action jump**, and the appropiate **target** +should be defined in a base chain. + +****************************** +Firewall - IPv6 Rules +****************************** + +For firewall filtering, firewall rules needs to be created. Each rule is +numbered, has an action to apply if the rule is matched, and the ability +to specify multiple criteria matchers. Data packets go through the rules +from 1 - 999999, so order is crucial. At the first match the action of the +rule will be executed. + +Actions +======= + +If a rule is defined, then an action must be defined for it. This tells the +firewall what to do if all criteria matchers defined for such rule do match. + +The action can be : + + * ``accept``: accept the packet. + + * ``continue``: continue parsing next rule. + + * ``drop``: drop the packet. + + * ``reject``: reject the packet. + + * ``jump``: jump to another custom chain. + + * ``return``: Return from the current chain and continue at the next rule + of the last chain. + + * ``queue``: Enqueue packet to userspace. + + * ``synproxy``: synproxy the packet. + +.. cfgcmd:: set firewall ipv6 forward filter rule <1-999999> action + [accept | continue | drop | jump | queue | reject | return | synproxy] +.. cfgcmd:: set firewall ipv6 input filter rule <1-999999> action + [accept | continue | drop | jump | queue | reject | return | synproxy] +.. cfgcmd:: set firewall ipv6 output filter rule <1-999999> action + [accept | continue | drop | jump | queue | reject | return] +.. cfgcmd:: set firewall ipv6 name rule <1-999999> action + [accept | continue | drop | jump | queue | reject | return] + + This required setting defines the action of the current rule. If action is + set to jump, then jump-target is also needed. + +.. cfgcmd:: set firewall ipv6 forward filter rule <1-999999> + jump-target +.. cfgcmd:: set firewall ipv6 input filter rule <1-999999> + jump-target +.. cfgcmd:: set firewall ipv6 output filter rule <1-999999> + jump-target +.. cfgcmd:: set firewall ipv6 name rule <1-999999> + jump-target + + To be used only when action is set to jump. Use this command to specify + jump target. + +Also, **default-action** is an action that takes place whenever a packet does +not match any rule in it's chain. For base chains, possible options for +**default-action** are **accept** or **drop**. + +.. cfgcmd:: set firewall ipv6 forward filter default-action + [accept | drop] +.. cfgcmd:: set firewall ipv6 input filter default-action + [accept | drop] +.. cfgcmd:: set firewall ipv6 output filter default-action + [accept | drop] +.. cfgcmd:: set firewall ipv6 name default-action + [accept | drop | jump | queue | reject | return] + + This set the default action of the rule-set if no rule matched a packet + criteria. If defacult-action is set to ``jump``, then + ``default-jump-target`` is also needed. Note that for base chains, default + action can only be set to ``accept`` or ``drop``, while on custom chain, + more actions are available. + +.. cfgcmd:: set firewall ipv6 name default-jump-target + + To be used only when ``defult-action`` is set to ``jump``. Use this + command to specify jump target for default rule. + +.. note:: **Important note about default-actions:** + If default action for any base chain is not defined, then the default + action is set to **accept** for that chain. For custom chains, if default + action is not defined, then the default-action is set to **drop** + +Firewall Logs +============= + +Logging can be enable for every single firewall rule. If enabled, other +log options can be defined. + +.. cfgcmd:: set firewall ipv6 forward filter rule <1-999999> log + [disable | enable] +.. cfgcmd:: set firewall ipv6 input filter rule <1-999999> log + [disable | enable] +.. cfgcmd:: set firewall ipv6 output filter rule <1-999999> log + [disable | enable] +.. cfgcmd:: set firewall ipv6 name rule <1-999999> log + [disable | enable] + + Enable or disable logging for the matched packet. + +.. cfgcmd:: set firewall ipv6 forward filter enable-default-log +.. cfgcmd:: set firewall ipv6 input filter enable-default-log +.. cfgcmd:: set firewall ipv6 output filter enable-default-log +.. cfgcmd:: set firewall ipv6 name enable-default-log + + Use this command to enable the logging of the default action on + the specified chain. + +.. cfgcmd:: set firewall ipv6 forward filter rule <1-999999> + log-options level [emerg | alert | crit | err | warn | notice + | info | debug] +.. cfgcmd:: set firewall ipv6 input filter rule <1-999999> + log-options level [emerg | alert | crit | err | warn | notice + | info | debug] +.. cfgcmd:: set firewall ipv6 output filter rule <1-999999> + log-options level [emerg | alert | crit | err | warn | notice + | info | debug] +.. cfgcmd:: set firewall ipv6 name rule <1-999999> + log-options level [emerg | alert | crit | err | warn | notice + | info | debug] + + Define log-level. Only applicable if rule log is enable. + +.. cfgcmd:: set firewall ipv6 forward filter rule <1-999999> + log-options group <0-65535> +.. cfgcmd:: set firewall ipv6 input filter rule <1-999999> + log-options group <0-65535> +.. cfgcmd:: set firewall ipv6 output filter rule <1-999999> + log-options group <0-65535> +.. cfgcmd:: set firewall ipv6 name rule <1-999999> + log-options group <0-65535> + + Define log group to send message to. Only applicable if rule log is enable. + +.. cfgcmd:: set firewall ipv6 forward filter rule <1-999999> + log-options snapshot-length <0-9000> +.. cfgcmd:: set firewall ipv6 input filter rule <1-999999> + log-options snapshot-length <0-9000> +.. cfgcmd:: set firewall ipv6 output filter rule <1-999999> + log-options snapshot-length <0-9000> +.. cfgcmd:: set firewall ipv6 name rule <1-999999> + log-options snapshot-length <0-9000> + + Define length of packet payload to include in netlink message. Only + applicable if rule log is enable and log group is defined. + +.. cfgcmd:: set firewall ipv6 forward filter rule <1-999999> + log-options queue-threshold <0-65535> +.. cfgcmd:: set firewall ipv6 input filter rule <1-999999> + log-options queue-threshold <0-65535> +.. cfgcmd:: set firewall ipv6 output filter rule <1-999999> + log-options queue-threshold <0-65535> +.. cfgcmd:: set firewall ipv6 name rule <1-999999> + log-options queue-threshold <0-65535> + + Define number of packets to queue inside the kernel before sending them to + userspace. Only applicable if rule log is enable and log group is defined. + +Firewall Description +==================== + +For reference, a description can be defined for every single rule, and for +every defined custom chain. + +.. cfgcmd:: set firewall ipv6 name description + + Provide a rule-set description to a custom firewall chain. + +.. cfgcmd:: set firewall ipv6 forward filter rule <1-999999> + description +.. cfgcmd:: set firewall ipv6 input filter rule <1-999999> + description +.. cfgcmd:: set firewall ipv6 output filter rule <1-999999> + description +.. cfgcmd:: set firewall ipv6 name rule <1-999999> description + + Provide a description for each rule. + +Rule Status +=========== + +When defining a rule, it is enable by default. In some cases, it is useful to +just disable the rule, rather than removing it. + +.. cfgcmd:: set firewall ipv6 forward filter rule <1-999999> disable +.. cfgcmd:: set firewall ipv6 input filter rule <1-999999> disable +.. cfgcmd:: set firewall ipv6 output filter rule <1-999999> disable +.. cfgcmd:: set firewall ipv6 name rule <1-999999> disable + + Command for disabling a rule but keep it in the configuration. + +Matching criteria +================= + +There are a lot of matching criteria against which the package can be tested. + +.. cfgcmd:: set firewall ipv6 forward filter rule <1-999999> + connection-status nat [destination | source] +.. cfgcmd:: set firewall ipv6 input filter rule <1-999999> + connection-status nat [destination | source] +.. cfgcmd:: set firewall ipv6 output filter rule <1-999999> + connection-status nat [destination | source] +.. cfgcmd:: set firewall ipv6 name rule <1-999999> + connection-status nat [destination | source] + + Match criteria based on nat connection status. + +.. cfgcmd:: set firewall ipv6 forward filter rule <1-999999> + connection-mark <1-2147483647> +.. cfgcmd:: set firewall ipv6 input filter rule <1-999999> + connection-mark <1-2147483647> +.. cfgcmd:: set firewall ipv6 output filter rule <1-999999> + connection-mark <1-2147483647> +.. cfgcmd:: set firewall ipv6 name rule <1-999999> + connection-mark <1-2147483647> + + Match criteria based on connection mark. + +.. cfgcmd:: set firewall ipv6 forward filter rule <1-999999> + source address [address | addressrange | CIDR] +.. cfgcmd:: set firewall ipv6 input filter rule <1-999999> + source address [address | addressrange | CIDR] +.. cfgcmd:: set firewall ipv6 output filter rule <1-999999> + source address [address | addressrange | CIDR] +.. cfgcmd:: set firewall ipv6 name rule <1-999999> + source address [address | addressrange | CIDR] + +.. cfgcmd:: set firewall ipv6 forward filter rule <1-999999> + destination address [address | addressrange | CIDR] +.. cfgcmd:: set firewall ipv6 input filter rule <1-999999> + destination address [address | addressrange | CIDR] +.. cfgcmd:: set firewall ipv6 output filter rule <1-999999> + destination address [address | addressrange | CIDR] +.. cfgcmd:: set firewall ipv6 name rule <1-999999> + destination address [address | addressrange | CIDR] + + Match criteria based on source and/or destination address. This is similar + to the network groups part, but here you are able to negate the matching + addresses. + + .. code-block:: none + + set firewall ipv6 name FOO rule 100 source address 2001:db8::202 + +.. cfgcmd:: set firewall ipv6 forward filter rule <1-999999> + source address-mask [address] +.. cfgcmd:: set firewall ipv6 input filter rule <1-999999> + source address-mask [address] +.. cfgcmd:: set firewall ipv6 output filter rule <1-999999> + source address-mask [address] +.. cfgcmd:: set firewall ipv6 name rule <1-999999> + source address-mask [address] + +.. cfgcmd:: set firewall ipv6 forward filter rule <1-999999> + destination address-mask [address] +.. cfgcmd:: set firewall ipv6 input filter rule <1-999999> + destination address-mask [address] +.. cfgcmd:: set firewall ipv6 output filter rule <1-999999> + destination address-mask [address] +.. cfgcmd:: set firewall ipv6 name rule <1-999999> + destination address-mask [address] + + An arbitrary netmask can be applied to mask addresses to only match against + a specific portion. This is particularly useful with IPv6 as rules will + remain valid if the IPv6 prefix changes and the host + portion of systems IPv6 address is static (for example, with SLAAC or + `tokenised IPv6 addresses + `_) + + This functions for both individual addresses and address groups. + + .. code-block:: none + + # Match any IPv6 address with the suffix ::0000:0000:0000:beef + set firewall ipv6 forward filter rule 100 destination address ::beef + set firewall ipv6 forward filter rule 100 destination address-mask ::ffff:ffff:ffff:ffff + # Address groups + set firewall group ipv6-address-group WEBSERVERS address ::1000 + set firewall group ipv6-address-group WEBSERVERS address ::2000 + set firewall ipv6 forward filter rule 200 source group address-group WEBSERVERS + set firewall ipv6 forward filter rule 200 source address-mask ::ffff:ffff:ffff:ffff + +.. cfgcmd:: set firewall ipv6 forward filter rule <1-999999> + source fqdn +.. cfgcmd:: set firewall ipv6 input filter rule <1-999999> + source fqdn +.. cfgcmd:: set firewall ipv6 output filter rule <1-999999> + source fqdn +.. cfgcmd:: set firewall ipv6 name rule <1-999999> + source fqdn +.. cfgcmd:: set firewall ipv6 forward filter rule <1-999999> + destination fqdn +.. cfgcmd:: set firewall ipv6 input filter rule <1-999999> + destination fqdn +.. cfgcmd:: set firewall ipv6 output filter rule <1-999999> + destination fqdn +.. cfgcmd:: set firewall ipv6 name rule <1-999999> + destination fqdn + + Specify a Fully Qualified Domain Name as source/destination matcher. Ensure + router is able to resolve such dns query. + +.. cfgcmd:: set firewall ipv6 forward filter rule <1-999999> + source geoip country-code +.. cfgcmd:: set firewall ipv6 input filter rule <1-999999> + source geoip country-code +.. cfgcmd:: set firewall ipv6 output filter rule <1-999999> + source geoip country-code +.. cfgcmd:: set firewall ipv6 name rule <1-999999> + source geoip country-code + +.. cfgcmd:: set firewall ipv6 forward filter rule <1-999999> + destination geoip country-code +.. cfgcmd:: set firewall ipv6 input filter rule <1-999999> + destination geoip country-code +.. cfgcmd:: set firewall ipv6 output filter rule <1-999999> + destination geoip country-code +.. cfgcmd:: set firewall ipv6 name rule <1-999999> + destination geoip country-code + +.. cfgcmd:: set firewall ipv6 forward filter rule <1-999999> + source geoip inverse-match +.. cfgcmd:: set firewall ipv6 input filter rule <1-999999> + source geoip inverse-match +.. cfgcmd:: set firewall ipv6 output filter rule <1-999999> + source geoip inverse-match +.. cfgcmd:: set firewall ipv6 name rule <1-999999> + source geoip inverse-match + +.. cfgcmd:: set firewall ipv6 forward filter rule <1-999999> + destination geoip inverse-match +.. cfgcmd:: set firewall ipv6 input filter rule <1-999999> + destination geoip inverse-match +.. cfgcmd:: set firewall ipv6 output filter rule <1-999999> + destination geoip inverse-match +.. cfgcmd:: set firewall ipv6 name rule <1-999999> + destination geoip inverse-match + + Match IP addresses based on its geolocation. More info: `geoip matching + `_. + Use inverse-match to match anything except the given country-codes. + +Data is provided by DB-IP.com under CC-BY-4.0 license. Attribution required, +permits redistribution so we can include a database in images(~3MB +compressed). Includes cron script (manually callable by op-mode update +geoip) to keep database and rules updated. + + +.. cfgcmd:: set firewall ipv6 forward filter rule <1-999999> + source mac-address +.. cfgcmd:: set firewall ipv6 input filter rule <1-999999> + source mac-address +.. cfgcmd:: set firewall ipv6 output filter rule <1-999999> + source mac-address +.. cfgcmd:: set firewall ipv6 name rule <1-999999> + source mac-address + + Only in the source criteria, you can specify a mac-address. + + .. code-block:: none + + set firewall ipv6 input filter rule 100 source mac-address 00:53:00:11:22:33 + set firewall ipv6 input filter rule 101 source mac-address !00:53:00:aa:12:34 + +.. cfgcmd:: set firewall ipv6 forward filter rule <1-999999> + source port [1-65535 | portname | start-end] +.. cfgcmd:: set firewall ipv6 input filter rule <1-999999> + source port [1-65535 | portname | start-end] +.. cfgcmd:: set firewall ipv6 output filter rule <1-999999> + source port [1-65535 | portname | start-end] +.. cfgcmd:: set firewall ipv6 name rule <1-999999> + source port [1-65535 | portname | start-end] + +.. cfgcmd:: set firewall ipv6 forward filter rule <1-999999> + destination port [1-65535 | portname | start-end] +.. cfgcmd:: set firewall ipv6 input filter rule <1-999999> + destination port [1-65535 | portname | start-end] +.. cfgcmd:: set firewall ipv6 output filter rule <1-999999> + destination port [1-65535 | portname | start-end] +.. cfgcmd:: set firewall ipv6 name rule <1-999999> + destination port [1-65535 | portname | start-end] + + A port can be set with a port number or a name which is here + defined: ``/etc/services``. + + .. code-block:: none + + set firewall ipv6 forward filter rule 10 source port '22' + set firewall ipv6 forward filter rule 11 source port '!http' + set firewall ipv6 forward filter rule 12 source port 'https' + + Multiple source ports can be specified as a comma-separated list. + The whole list can also be "negated" using ``!``. For example: + + .. code-block:: none + + set firewall ipv6 forward filter rule 10 source port '!22,https,3333-3338' + +.. cfgcmd:: set firewall ipv6 forward filter rule <1-999999> + source group address-group +.. cfgcmd:: set firewall ipv6 input filter rule <1-999999> + source group address-group +.. cfgcmd:: set firewall ipv6 output filter rule <1-999999> + source group address-group +.. cfgcmd:: set firewall ipv6 name rule <1-999999> + source group address-group + +.. cfgcmd:: set firewall ipv6 forward filter rule <1-999999> + destination group address-group +.. cfgcmd:: set firewall ipv6 input filter rule <1-999999> + destination group address-group +.. cfgcmd:: set firewall ipv6 output filter rule <1-999999> + destination group address-group +.. cfgcmd:: set firewall ipv6 name rule <1-999999> + destination group address-group + + Use a specific address-group. Prepend character ``!`` for inverted matching + criteria. + +.. cfgcmd:: set firewall ipv6 forward filter rule <1-999999> + source group network-group +.. cfgcmd:: set firewall ipv6 input filter rule <1-999999> + source group network-group +.. cfgcmd:: set firewall ipv6 output filter rule <1-999999> + source group network-group +.. cfgcmd:: set firewall ipv6 name rule <1-999999> + source group network-group + +.. cfgcmd:: set firewall ipv6 forward filter rule <1-999999> + destination group network-group +.. cfgcmd:: set firewall ipv6 input filter rule <1-999999> + destination group network-group +.. cfgcmd:: set firewall ipv6 output filter rule <1-999999> + destination group network-group +.. cfgcmd:: set firewall ipv6 name rule <1-999999> + destination group network-group + + Use a specific network-group. Prepend character ``!`` for inverted matching + criteria. + +.. cfgcmd:: set firewall ipv6 forward filter rule <1-999999> + source group port-group +.. cfgcmd:: set firewall ipv6 input filter rule <1-999999> + source group port-group +.. cfgcmd:: set firewall ipv6 output filter rule <1-999999> + source group port-group +.. cfgcmd:: set firewall ipv6 name rule <1-999999> + source group port-group + +.. cfgcmd:: set firewall ipv6 forward filter rule <1-999999> + destination group port-group +.. cfgcmd:: set firewall ipv6 input filter rule <1-999999> + destination group port-group +.. cfgcmd:: set firewall ipv6 output filter rule <1-999999> + destination group port-group +.. cfgcmd:: set firewall ipv6 name rule <1-999999> + destination group port-group + + Use a specific port-group. Prepend character ``!`` for inverted matching + criteria. + +.. cfgcmd:: set firewall ipv6 forward filter rule <1-999999> + source group domain-group +.. cfgcmd:: set firewall ipv6 input filter rule <1-999999> + source group domain-group +.. cfgcmd:: set firewall ipv6 output filter rule <1-999999> + source group domain-group +.. cfgcmd:: set firewall ipv6 name rule <1-999999> + source group domain-group + +.. cfgcmd:: set firewall ipv6 forward filter rule <1-999999> + destination group domain-group +.. cfgcmd:: set firewall ipv6 input filter rule <1-999999> + destination group domain-group +.. cfgcmd:: set firewall ipv6 output filter rule <1-999999> + destination group domain-group +.. cfgcmd:: set firewall ipv6 name rule <1-999999> + destination group domain-group + + Use a specific domain-group. Prepend character ``!`` for inverted matching + criteria. + +.. cfgcmd:: set firewall ipv6 forward filter rule <1-999999> + source group mac-group +.. cfgcmd:: set firewall ipv6 input filter rule <1-999999> + source group mac-group +.. cfgcmd:: set firewall ipv6 output filter rule <1-999999> + source group mac-group +.. cfgcmd:: set firewall ipv6 name rule <1-999999> + source group mac-group + +.. cfgcmd:: set firewall ipv6 forward filter rule <1-999999> + destination group mac-group +.. cfgcmd:: set firewall ipv6 input filter rule <1-999999> + destination group mac-group +.. cfgcmd:: set firewall ipv6 output filter rule <1-999999> + destination group mac-group +.. cfgcmd:: set firewall ipv6 name rule <1-999999> + destination group mac-group + + Use a specific mac-group. Prepend character ``!`` for inverted matching + criteria. + +.. cfgcmd:: set firewall ipv6 forward filter rule <1-999999> + dscp [0-63 | start-end] +.. cfgcmd:: set firewall ipv6 input filter rule <1-999999> + dscp [0-63 | start-end] +.. cfgcmd:: set firewall ipv6 output filter rule <1-999999> + dscp [0-63 | start-end] +.. cfgcmd:: set firewall ipv6 name rule <1-999999> + dscp [0-63 | start-end] + +.. cfgcmd:: set firewall ipv6 forward filter rule <1-999999> + dscp-exclude [0-63 | start-end] +.. cfgcmd:: set firewall ipv6 input filter rule <1-999999> + dscp-exclude [0-63 | start-end] +.. cfgcmd:: set firewall ipv6 output filter rule <1-999999> + dscp-exclude [0-63 | start-end] +.. cfgcmd:: set firewall ipv6 name rule <1-999999> + dscp-exclude [0-63 | start-end] + + Match based on dscp value. + +.. cfgcmd:: set firewall ipv6 forward filter rule <1-999999> + fragment [match-frag | match-non-frag] +.. cfgcmd:: set firewall ipv6 input filter rule <1-999999> + fragment [match-frag | match-non-frag] +.. cfgcmd:: set firewall ipv6 output filter rule <1-999999> + fragment [match-frag | match-non-frag] +.. cfgcmd:: set firewall ipv6 name rule <1-999999> + fragment [match-frag | match-non-frag] + + Match based on fragment criteria. + +.. cfgcmd:: set firewall ipv6 forward filter rule <1-999999> + icmpv6 [code | type] <0-255> +.. cfgcmd:: set firewall ipv6 input filter rule <1-999999> + icmpv6 [code | type] <0-255> +.. cfgcmd:: set firewall ipv6 output filter rule <1-999999> + icmpv6 [code | type] <0-255> +.. cfgcmd:: set firewall ipv6 name rule <1-999999> + icmpv6 [code | type] <0-255> + + Match based on icmp|icmpv6 code and type. + +.. cfgcmd:: set firewall ipv6 forward filter rule <1-999999> + icmpv6 type-name +.. cfgcmd:: set firewall ipv6 input filter rule <1-999999> + icmpv6 type-name +.. cfgcmd:: set firewall ipv6 output filter rule <1-999999> + icmpv6 type-name +.. cfgcmd:: set firewall ipv6 name rule <1-999999> + icmpv6 type-name + + Match based on icmpv6 type-name criteria. Use tab for information + about what **type-name** criteria are supported. + +.. cfgcmd:: set firewall ipv6 forward filter rule <1-999999> + inbound-interface name +.. cfgcmd:: set firewall ipv6 input filter rule <1-999999> + inbound-interface name +.. cfgcmd:: set firewall ipv6 name rule <1-999999> + inbound-interface name + + Match based on inbound interface. Wilcard ``*`` can be used. + For example: ``eth2*``. Prepending character ``!`` for inverted matching + criteria is also supportd. For example ``!eth2`` + +.. cfgcmd:: set firewall ipv6 forward filter rule <1-999999> + inbound-interface group +.. cfgcmd:: set firewall ipv6 input filter rule <1-999999> + inbound-interface group +.. cfgcmd:: set firewall ipv6 name rule <1-999999> + inbound-interface group + + Match based on inbound interface group. Prepending character ``!`` for + inverted matching criteria is also supportd. For example ``!IFACE_GROUP`` + +.. cfgcmd:: set firewall ipv6 forward filter rule <1-999999> + outbound-interface name +.. cfgcmd:: set firewall ipv6 output filter rule <1-999999> + outbound-interface name +.. cfgcmd:: set firewall ipv6 name rule <1-999999> + outbound-interface name + + Match based on outbound interface. Wilcard ``*`` can be used. + For example: ``eth2*``. Prepending character ``!`` for inverted matching + criteria is also supportd. For example ``!eth2`` + +.. cfgcmd:: set firewall ipv6 forward filter rule <1-999999> + outbound-interface group +.. cfgcmd:: set firewall ipv6 output filter rule <1-999999> + outbound-interface group +.. cfgcmd:: set firewall ipv6 name rule <1-999999> + outbound-interface group + + Match based on outbound interface group. Prepending character ``!`` for + inverted matching criteria is also supportd. For example ``!IFACE_GROUP`` + +.. cfgcmd:: set firewall ipv6 forward filter rule <1-999999> + ipsec [match-ipsec | match-none] +.. cfgcmd:: set firewall ipv6 input filter rule <1-999999> + ipsec [match-ipsec | match-none] +.. cfgcmd:: set firewall ipv6 output filter rule <1-999999> + ipsec [match-ipsec | match-none] +.. cfgcmd:: set firewall ipv6 name rule <1-999999> + ipsec [match-ipsec | match-none] + + Match based on ipsec criteria. + +.. cfgcmd:: set firewall ipv6 forward filter rule <1-999999> + limit burst <0-4294967295> +.. cfgcmd:: set firewall ipv6 input filter rule <1-999999> + limit burst <0-4294967295> +.. cfgcmd:: set firewall ipv6 output filter rule <1-999999> + limit burst <0-4294967295> +.. cfgcmd:: set firewall ipv6 name rule <1-999999> + limit burst <0-4294967295> + + Match based on the maximum number of packets to allow in excess of rate. + +.. cfgcmd:: set firewall ipv6 forward filter rule <1-999999> + limit rate +.. cfgcmd:: set firewall ipv6 input filter rule <1-999999> + limit rate +.. cfgcmd:: set firewall ipv6 output filter rule <1-999999> + limit rate +.. cfgcmd:: set firewall ipv6 name rule <1-999999> + limit rate + + Match based on the maximum average rate, specified as **integer/unit**. + For example **5/minutes** + +.. cfgcmd:: set firewall ipv6 forward filter rule <1-999999> + packet-length +.. cfgcmd:: set firewall ipv6 input filter rule <1-999999> + packet-length +.. cfgcmd:: set firewall ipv6 output filter rule <1-999999> + packet-length +.. cfgcmd:: set firewall ipv6 name rule <1-999999> + packet-length + +.. cfgcmd:: set firewall ipv6 forward filter rule <1-999999> + packet-length-exclude +.. cfgcmd:: set firewall ipv6 input filter rule <1-999999> + packet-length-exclude +.. cfgcmd:: set firewall ipv6 output filter rule <1-999999> + packet-length-exclude +.. cfgcmd:: set firewall ipv6 name rule <1-999999> + packet-length-exclude + + Match based on packet length criteria. Multiple values from 1 to 65535 + and ranges are supported. + +.. cfgcmd:: set firewall ipv6 forward filter rule <1-999999> + packet-type [broadcast | host | multicast | other] +.. cfgcmd:: set firewall ipv6 input filter rule <1-999999> + packet-type [broadcast | host | multicast | other] +.. cfgcmd:: set firewall ipv6 output filter rule <1-999999> + packet-type [broadcast | host | multicast | other] +.. cfgcmd:: set firewall ipv6 name rule <1-999999> + packet-type [broadcast | host | multicast | other] + + Match based on packet type criteria. + +.. cfgcmd:: set firewall ipv6 forward filter rule <1-999999> + protocol [ | <0-255> | all | tcp_udp] +.. cfgcmd:: set firewall ipv6 input filter rule <1-999999> + protocol [ | <0-255> | all | tcp_udp] +.. cfgcmd:: set firewall ipv6 output filter rule <1-999999> + protocol [ | <0-255> | all | tcp_udp] +.. cfgcmd:: set firewall ipv6 name rule <1-999999> + protocol [ | <0-255> | all | tcp_udp] + + Match a protocol criteria. A protocol number or a name which is here + defined: ``/etc/protocols``. + Special names are ``all`` for all protocols and ``tcp_udp`` for tcp and udp + based packets. The ``!`` negate the selected protocol. + + .. code-block:: none + + set firewall ipv6 input filter rule 10 protocol tcp + +.. cfgcmd:: set firewall ipv6 forward filter rule <1-999999> + recent count <1-255> +.. cfgcmd:: set firewall ipv6 input filter rule <1-999999> + recent count <1-255> +.. cfgcmd:: set firewall ipv6 output filter rule <1-999999> + recent count <1-255> +.. cfgcmd:: set firewall ipv6 name rule <1-999999> + recent count <1-255> + +.. cfgcmd:: set firewall ipv6 forward filter rule <1-999999> + recent time [second | minute | hour] +.. cfgcmd:: set firewall ipv6 input filter rule <1-999999> + recent time [second | minute | hour] +.. cfgcmd:: set firewall ipv6 output filter rule <1-999999> + recent time [second | minute | hour] +.. cfgcmd:: set firewall ipv6 name rule <1-999999> + recent time [second | minute | hour] + + Match bases on recently seen sources. + +.. cfgcmd:: set firewall ipv6 forward filter rule <1-999999> + tcp flags [not] +.. cfgcmd:: set firewall ipv6 input filter rule <1-999999> + tcp flags [not] +.. cfgcmd:: set firewall ipv6 output filter rule <1-999999> + tcp flags [not] +.. cfgcmd:: set firewall ipv6 name rule <1-999999> + tcp flags [not] + + Allowed values fpr TCP flags: ``ack``, ``cwr``, ``ecn``, ``fin``, ``psh``, + ``rst``, ``syn`` and ``urg``. Multiple values are supported, and for + inverted selection use ``not``, as shown in the example. + + .. code-block:: none + + set firewall ipv6 input filter rule 10 tcp flags 'ack' + set firewall ipv6 input filter rule 12 tcp flags 'syn' + set firewall ipv6 input filter rule 13 tcp flags not 'fin' + +.. cfgcmd:: set firewall ipv6 forward filter rule <1-999999> + state [established | invalid | new | related] [enable | disable] +.. cfgcmd:: set firewall ipv6 input filter rule <1-999999> + state [established | invalid | new | related] [enable | disable] +.. cfgcmd:: set firewall ipv6 output filter rule <1-999999> + state [established | invalid | new | related] [enable | disable] +.. cfgcmd:: set firewall ipv6 name rule <1-999999> + state [established | invalid | new | related] [enable | disable] + + Match against the state of a packet. + +.. cfgcmd:: set firewall ipv6 forward filter rule <1-999999> + time startdate +.. cfgcmd:: set firewall ipv6 input filter rule <1-999999> + time startdate +.. cfgcmd:: set firewall ipv6 output filter rule <1-999999> + time startdate +.. cfgcmd:: set firewall ipv6 name rule <1-999999> + time startdate +.. cfgcmd:: set firewall ipv6 forward filter rule <1-999999> + time starttime +.. cfgcmd:: set firewall ipv6 input filter rule <1-999999> + time starttime +.. cfgcmd:: set firewall ipv6 output filter rule <1-999999> + time starttime +.. cfgcmd:: set firewall ipv6 name rule <1-999999> + time starttime +.. cfgcmd:: set firewall ipv6 forward filter rule <1-999999> + time stopdate +.. cfgcmd:: set firewall ipv6 input filter rule <1-999999> + time stopdate +.. cfgcmd:: set firewall ipv6 output filter rule <1-999999> + time stopdate +.. cfgcmd:: set firewall ipv6 name rule <1-999999> + time stopdate +.. cfgcmd:: set firewall ipv6 forward filter rule <1-999999> + time stoptime +.. cfgcmd:: set firewall ipv6 input filter rule <1-999999> + time stoptime +.. cfgcmd:: set firewall ipv6 output filter rule <1-999999> + time stoptime +.. cfgcmd:: set firewall ipv6 name rule <1-999999> + time stoptime +.. cfgcmd:: set firewall ipv6 forward filter rule <1-999999> + time weekdays +.. cfgcmd:: set firewall ipv6 input filter rule <1-999999> + time weekdays +.. cfgcmd:: set firewall ipv6 output filter rule <1-999999> + time weekdays +.. cfgcmd:: set firewall ipv6 name rule <1-999999> + time weekdays + + Time to match the defined rule. + +.. cfgcmd:: set firewall ipv6 forward filter rule <1-999999> + hop-limit <0-255> +.. cfgcmd:: set firewall ipv6 input filter rule <1-999999> + hop-limit <0-255> +.. cfgcmd:: set firewall ipv6 output filter rule <1-999999> + hop-limit <0-255> +.. cfgcmd:: set firewall ipv6 name rule <1-999999> + hop-limit <0-255> + + Match hop-limit parameter, where 'eq' stands for 'equal'; 'gt' stands for + 'greater than', and 'lt' stands for 'less than'. + +.. cfgcmd:: set firewall ipv6 forward filter rule <1-999999> + recent count <1-255> +.. cfgcmd:: set firewall ipv6 input filter rule <1-999999> + recent count <1-255> +.. cfgcmd:: set firewall ipv6 output filter rule <1-999999> + recent count <1-255> +.. cfgcmd:: set firewall ipv6 name rule <1-999999> + recent count <1-255> + +.. cfgcmd:: set firewall ipv6 forward filter rule <1-999999> + recent time +.. cfgcmd:: set firewall ipv6 input filter rule <1-999999> + recent time +.. cfgcmd:: set firewall ipv6 output filter rule <1-999999> + recent time +.. cfgcmd:: set firewall ipv6 name rule <1-999999> + recent time + + Match when 'count' amount of connections are seen within 'time'. These + matching criteria can be used to block brute-force attempts. + +******** +Synproxy +******** +Synproxy connections + +.. cfgcmd:: set firewall ipv6 [input | forward] filter rule <1-999999> action synproxy +.. cfgcmd:: set firewall ipv6 [input | forward] filter rule <1-999999> protocol tcp +.. cfgcmd:: set firewall ipv6 [input | forward] filter rule <1-999999> synproxy tcp mss <501-65535> + + Set TCP-MSS (maximum segment size) for the connection + +.. cfgcmd:: set firewall ipv6 [input | forward] filter rule <1-999999> synproxy tcp window-scale <1-14> + + Set the window scale factor for TCP window scaling + +Example synproxy +================ +Requirements to enable synproxy: + + * Traffic must be symmetric + * Synproxy relies on syncookies and TCP timestamps, ensure these are enabled + * Disable conntrack loose track option + +.. code-block:: none + + set system sysctl parameter net.ipv4.tcp_timestamps value '1' + + set system conntrack tcp loose disable + set system conntrack ignore ipv6 rule 10 destination port '8080' + set system conntrack ignore ipv6 rule 10 protocol 'tcp' + set system conntrack ignore ipv6 rule 10 tcp flags syn + + set firewall global-options syn-cookies 'enable' + set firewall ipv6 input filter rule 10 action 'synproxy' + set firewall ipv6 input filter rule 10 destination port '8080' + set firewall ipv6 input filter rule 10 inbound-interface interface-name 'eth1' + set firewall ipv6 input filter rule 10 protocol 'tcp' + set firewall ipv6 input filter rule 10 synproxy tcp mss '1460' + set firewall ipv6 input filter rule 10 synproxy tcp window-scale '7' + set firewall ipv6 input filter rule 1000 action 'drop' + set firewall ipv6 input filter rule 1000 state invalid 'enable' + +*********************** +Operation-mode Firewall +*********************** + +Rule-set overview +================= + +.. opcmd:: show firewall + + This will show you a basic firewall overview + + .. code-block:: none + + vyos@vyos:~$ show firewall + Rulesets Information + + --------------------------------- + IPv4 Firewall "forward filter" + + Rule Action Protocol Packets Bytes Conditions + ------- -------- ---------- --------- ------- ----------------------------------------- + 5 jump all 0 0 iifname "eth1" jump NAME_VyOS_MANAGEMENT + 10 jump all 0 0 oifname "eth1" jump NAME_WAN_IN + 15 jump all 0 0 iifname "eth3" jump NAME_WAN_IN + default accept all + + --------------------------------- + IPv4 Firewall "name VyOS_MANAGEMENT" + + Rule Action Protocol Packets Bytes Conditions + ------- -------- ---------- --------- ------- -------------------------------- + 5 accept all 0 0 ct state established accept + 10 drop all 0 0 ct state invalid + 20 accept all 0 0 ip saddr @A_GOOD_GUYS accept + 30 accept all 0 0 ip saddr @N_ENTIRE_RANGE accept + 40 accept all 0 0 ip saddr @A_VyOS_SERVERS accept + 50 accept icmp 0 0 meta l4proto icmp accept + default drop all 0 0 + + --------------------------------- + IPv6 Firewall "forward filter" + + Rule Action Protocol + ------- -------- ---------- + 5 jump all + 10 jump all + 15 jump all + default accept all + + --------------------------------- + IPv6 Firewall "input filter" + + Rule Action Protocol + ------- -------- ---------- + 5 jump all + default accept all + + --------------------------------- + IPv6 Firewall "ipv6_name IPV6-VyOS_MANAGEMENT" + + Rule Action Protocol + ------- -------- ---------- + 5 accept all + 10 drop all + 20 accept all + 30 accept all + 40 accept all + 50 accept ipv6-icmp + default drop all + +.. opcmd:: show firewall summary + + This will show you a summary of rule-sets and groups + + .. code-block:: none + + vyos@vyos:~$ show firewall summary + Ruleset Summary + + IPv6 Ruleset: + + Ruleset Hook Ruleset Priority Description + -------------- -------------------- ------------------------- + forward filter + input filter + ipv6_name IPV6-VyOS_MANAGEMENT + ipv6_name IPV6-WAN_IN PUBLIC_INTERNET + + IPv4 Ruleset: + + Ruleset Hook Ruleset Priority Description + -------------- ------------------ ------------------------- + forward filter + input filter + name VyOS_MANAGEMENT + name WAN_IN PUBLIC_INTERNET + + Firewall Groups + + Name Type References Members + ----------------------- ------------------ ----------------------- ---------------- + PBX address_group WAN_IN-100 198.51.100.77 + SERVERS address_group WAN_IN-110 192.0.2.10 + WAN_IN-111 192.0.2.11 + WAN_IN-112 192.0.2.12 + WAN_IN-120 + WAN_IN-121 + WAN_IN-122 + SUPPORT address_group VyOS_MANAGEMENT-20 192.168.1.2 + WAN_IN-20 + PHONE_VPN_SERVERS address_group WAN_IN-160 10.6.32.2 + PINGABLE_ADRESSES address_group WAN_IN-170 192.168.5.2 + WAN_IN-171 + PBX ipv6_address_group IPV6-WAN_IN-100 2001:db8::1 + SERVERS ipv6_address_group IPV6-WAN_IN-110 2001:db8::2 + IPV6-WAN_IN-111 2001:db8::3 + IPV6-WAN_IN-112 2001:db8::4 + IPV6-WAN_IN-120 + IPV6-WAN_IN-121 + IPV6-WAN_IN-122 + SUPPORT ipv6_address_group IPV6-VyOS_MANAGEMENT-20 2001:db8::5 + IPV6-WAN_IN-20 + + +.. opcmd:: show firewall ipv6 [forward | input | output] filter + +.. opcmd:: show firewall ipv4 name + +.. opcmd:: show firewall ipv6 ipv6-name + + This command will give an overview of a single rule-set. + + .. code-block:: none + + vyos@vyos:~$ show firewall ipv4 input filter + Ruleset Information + + --------------------------------- + IPv4 Firewall "input filter" + + Rule Action Protocol Packets Bytes Conditions + ------- -------- ---------- --------- ------- ----------------------------------------- + 5 jump all 0 0 iifname "eth2" jump NAME_VyOS_MANAGEMENT + default accept all + +.. opcmd:: show firewall ipv6 [forward | input | output] + filter rule <1-999999> + +.. opcmd:: show firewall ipv4 name rule <1-999999> + +.. opcmd:: show firewall ipv6 ipv6-name rule <1-999999> + + This command will give an overview of a rule in a single rule-set + +.. opcmd:: show firewall group + + Overview of defined groups. You see the type, the members, and where the + group is used. + + .. code-block:: none + + vyos@vyos:~$ show firewall group LAN + Firewall Groups + + Name Type References Members + ------------ ------------------ ----------------------- ---------------- + LAN ipv6_network_group IPV6-VyOS_MANAGEMENT-30 2001:db8::0/64 + IPV6-WAN_IN-30 + LAN network_group VyOS_MANAGEMENT-30 192.168.200.0/24 + WAN_IN-30 + + +.. opcmd:: show firewall statistics + + This will show you a statistic of all rule-sets since the last boot. + +Show Firewall log +================= + +.. opcmd:: show log firewall +.. opcmd:: show log firewall ipv6 +.. opcmd:: show log firewall ipv6 [forward | input | output | name] +.. opcmd:: show log firewall ipv6 [forward | input | output] filter +.. opcmd:: show log firewall ipv6 name +.. opcmd:: show log firewall ipv6 [forward | input | output] filter rule +.. opcmd:: show log firewall ipv6 name rule + + Show the logs of all firewall; show all ipv6 firewall logs; show all logs + for particular hook; show all logs for particular hook and priority; show all logs + for particular custom chain; show logs for specific Rule-Set. + +Example Partial Config +====================== + +.. code-block:: none + + firewall { + group { + network-group BAD-NETWORKS { + network 198.51.100.0/24 + network 203.0.113.0/24 + } + network-group GOOD-NETWORKS { + network 192.0.2.0/24 + } + port-group BAD-PORTS { + port 65535 + } + } + ipv4 { + forward { + filter { + default-action accept + rule 5 { + action accept + source { + group { + network-group GOOD-NETWORKS + } + } + } + rule 10 { + action drop + description "Bad Networks" + protocol all + source { + group { + network-group BAD-NETWORKS + } + } + } + } + } + } + } + +Update geoip database +===================== + +.. opcmd:: update geoip + + Command used to update GeoIP database and firewall sets. diff --git a/docs/configuration/firewall/zone.rst b/docs/configuration/firewall/zone.rst index 70ad7b65..1ab9c630 100644 --- a/docs/configuration/firewall/zone.rst +++ b/docs/configuration/firewall/zone.rst @@ -1,4 +1,4 @@ -:lastproofread: 2022-09-14 +:lastproofread: 2023-11-01 .. _firewall-zone: @@ -6,20 +6,39 @@ Zone Based Firewall ################### +******** +Overview +******** + .. note:: Starting from VyOS 1.4-rolling-202308040557, a new firewall - structure can be found on all vyos instalations, and zone based firewall is - no longer supported. Documentation for most of the new firewall CLI can be + structure can be found on all vyos instalations. Zone based firewall was + removed in that version, but re introduced in VyOS 1.4 and 1.5. All + versions built after 2023-10-22 has this feature. + Documentation for most of the new firewall CLI can be found in the `firewall `_ chapter. The legacy firewall is still available for versions before - 1.4-rolling-202308040557 and can be found in the :ref:`firewall-legacy` - chapter. The examples in this section use the legacy firewall configuration - commands, since this feature has been removed in earlier releases. + 1.4-rolling-202308040557 and can be found in the + :doc:`legacy firewall configuration ` + chapter. -.. note:: For latest releases, refer the `firewall - `_ - main page to configure zone based rules. New syntax was introduced here - :vytask:`T5160` +In this section there's useful information of all firewall configuration that +is needed for zone-based firewall. +Configuration commands covered in this section: + +.. cfgcmd:: set firewall zone ... + +From main structure defined in +:doc:`Firewall Overview` +in this section you can find detailed information only for the next part +of the general structure: + +.. code-block:: none + + - set firewall + * zone + - custom_zone_name + + ... In zone-based policy, interfaces are assigned to zones, and inspection policy is applied to traffic moving between the zones and acted on according to