{"id":217,"date":"2016-05-18T13:07:44","date_gmt":"2016-05-18T18:07:44","guid":{"rendered":"https:\/\/adamkuj.net\/blog\/?p=217"},"modified":"2021-05-11T08:59:41","modified_gmt":"2021-05-11T13:59:41","slug":"pro-tip-port-mirroring-in-linux","status":"publish","type":"post","link":"https:\/\/adamkuj.net\/blog\/2016\/05\/18\/pro-tip-port-mirroring-in-linux\/","title":{"rendered":"Pro-Tip: Port Mirroring In Linux"},"content":{"rendered":"<p>Sometimes a span\/mirror port isn&#8217;t available on a switch when&nbsp;you need one. However, if you just need to monitor traffic from\/to a Linux server, you can have the Linux server mirror it&#8217;s own traffic toward a collector. You just need a spare NIC on the Linux system.<\/p>\n<p>For example, if you want to mirror all traffic going in\/out of eth0, and send it out eth1 toward a collector, you can do that with the &#8216;tc&#8217; subsystem. Some examples of this exist online. However, what they don&#8217;t tell you is that if eth1 goes down (unplugged, etc), that results in eth0 blocking all traffic &#8212; not good! I came up with a workaround for that problem using bridge and dummy interfaces. It&#8217;s kludgy, but it works!<\/p>\n<p>See below for all the required config files \/ scripts. (don&#8217;t forget to chmod the scripts so root can run them!)<\/p>\n<p>[shell title=&#8221;\/etc\/network\/interfaces&#8221; language=&#8221;true&#8221;]<br \/>\n# The loopback network interface<br \/>\nauto lo<br \/>\niface lo inet loopback<\/p>\n<p># The primary network interface<br \/>\nauto eth0<br \/>\niface eth0 inet static<br \/>\naddress 192.168.1.123<br \/>\nnetmask 255.255.255.20<br \/>\ngateway 192.168.1.254<br \/>\ndns-nameservers 8.8.8.8<\/p>\n<p># physical mirror port toward collector<br \/>\nauto eth1<br \/>\niface eth1 inet static<br \/>\naddress 127.1.1.1<br \/>\nnetmask 255.255.255.255<br \/>\nup ip addr del 127.1.1.1\/32 dev eth1;:<\/p>\n<p># always-up mirror port toward dev null<br \/>\nauto dummy0<br \/>\niface dummy0 inet static<br \/>\naddress 127.4.4.4<br \/>\nnetmask 255.255.255.255<br \/>\npre-up modprobe dummy;:<br \/>\nup ip addr del 127.4.4.4\/32 dev dummy0;:<\/p>\n<p># bridge of eth1 and dummy0<br \/>\n# this is so that it always stays up, even if eth1 is down<br \/>\nauto br0<br \/>\niface br0 inet static<br \/>\nbridge_ports eth1 dummy0<br \/>\naddress 127.5.5.5<br \/>\nnetmask 255.255.255.255<br \/>\nup ip addr del 127.5.5.5\/32 dev br0;:<br \/>\npost-up \/etc\/network\/mirror-up.sh;:<br \/>\npre-down \/etc\/network\/mirror-down.sh;:<br \/>\n[\/shell]<\/p>\n<p>[bash title=&#8221;\/etc\/network\/mirror-up.sh&#8221; language=&#8221;true&#8221;]<br \/>\n#!\/bin\/sh<\/p>\n<p># ALK 2014-10-23<br \/>\n# Send all &#8216;source_if&#8217; traffic (ingress &amp; egress) to collector box on &#8216;dest_if&#8217;<\/p>\n<p># Normally called by boot process or ifup. i.e.<br \/>\n# &#8211;\/etc\/network\/interfaces&#8211;<br \/>\n#   iface eth0 inet static<br \/>\n#     address X.X.X.X<br \/>\n#     netmask Y.Y.Y.Y<br \/>\n#     post-up \/etc\/network\/mirror-up.sh;:<\/p>\n<p>source_if=eth0<br \/>\ndest_if=br0<\/p>\n<p># enable the destination port<br \/>\nifconfig $dest_if up;:<\/p>\n<p># mirror ingress traffic<br \/>\ntc qdisc add dev $source_if ingress;:<br \/>\ntc filter add dev $source_if parent ffff: \\<br \/>\nprotocol all \\<br \/>\nu32 match u8 0 0 \\<br \/>\naction mirred egress mirror dev $dest_if;:<\/p>\n<p># mirror egress traffic<br \/>\ntc qdisc add dev $source_if handle 1: root prio;:<br \/>\ntc filter add dev $source_if parent 1: \\<br \/>\nprotocol all \\<br \/>\nu32 match u8 0 0 \\<br \/>\naction mirred egress mirror dev $dest_if;:<br \/>\n[\/bash]<\/p>\n<p>[bash title=&#8221;\/etc\/network\/mirror-down.sh&#8221; language=&#8221;true&#8221;]<br \/>\n#!\/bin\/sh<\/p>\n<p># ALK 2014-10-23<br \/>\n# De-provision mirroring config (See mirror-up.sh for provisioning)<\/p>\n<p># Normally called by boot process or ifdown. i.e.<br \/>\n# &#8211;\/etc\/network\/interfaces&#8211;<br \/>\n#   iface eth0 inet static<br \/>\n#     address X.X.X.X<br \/>\n#     netmask Y.Y.Y.Y<br \/>\n#     pre-down \/etc\/network\/mirror-down.sh;:<\/p>\n<p>source_if=eth0<\/p>\n<p># de-provision ingress mirroring<br \/>\ntc qdisc del dev $source_if ingress;:<\/p>\n<p># de-provisoin egress mirroring<br \/>\ntc qdisc del dev $source_if root;:<br \/>\n[\/bash]<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Sometimes a span\/mirror port isn&#8217;t available on a switch when&nbsp;you need one. However, if you just need to monitor traffic from\/to a Linux server, you can have the Linux server mirror it&#8217;s own traffic toward a collector. You just need a spare NIC on the Linux system. For example, if you want to mirror all [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[33,32,4,35,36,34,31],"class_list":["post-217","post","type-post","status-publish","format-standard","hentry","category-networking-tools","tag-bash","tag-ifconfig","tag-linux","tag-mirror","tag-monitor","tag-span","tag-tc"],"_links":{"self":[{"href":"https:\/\/adamkuj.net\/blog\/wp-json\/wp\/v2\/posts\/217","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/adamkuj.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/adamkuj.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/adamkuj.net\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/adamkuj.net\/blog\/wp-json\/wp\/v2\/comments?post=217"}],"version-history":[{"count":12,"href":"https:\/\/adamkuj.net\/blog\/wp-json\/wp\/v2\/posts\/217\/revisions"}],"predecessor-version":[{"id":313,"href":"https:\/\/adamkuj.net\/blog\/wp-json\/wp\/v2\/posts\/217\/revisions\/313"}],"wp:attachment":[{"href":"https:\/\/adamkuj.net\/blog\/wp-json\/wp\/v2\/media?parent=217"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/adamkuj.net\/blog\/wp-json\/wp\/v2\/categories?post=217"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/adamkuj.net\/blog\/wp-json\/wp\/v2\/tags?post=217"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}