{"id":89,"date":"2020-01-24T04:20:17","date_gmt":"2020-01-24T04:20:17","guid":{"rendered":"https:\/\/www.vandervecken.com\/faucet\/?p=89"},"modified":"2020-01-27T01:45:56","modified_gmt":"2020-01-27T01:45:56","slug":"faking-services-on-an-entire-ip-subnet","status":"publish","type":"post","link":"https:\/\/faucet.vandervecken.com\/index.php\/2020\/01\/24\/faking-services-on-an-entire-ip-subnet\/","title":{"rendered":"faking services on an entire IP subnet"},"content":{"rendered":"\n<p>In a previous <a href=\"https:\/\/www.vandervecken.com\/faucet\/index.php\/2019\/10\/31\/injecting-services-into-the-dataplane-with-coprocessing\/\">post<\/a>, we introduced coprocessing and faking a TCP service on a single IP. The FAUCET coprocessor feature allows an external host to inject packets to a given VLAN (or even port). FAUCET ACLs are used to select traffic to be sent to the coprocessor (by default nothing is sent for coprocessing).<\/p>\n\n\n\n<p>In this post we will develop the idea further &#8211; we will fake a TCP service on all hosts in a subnet, and we will do away with the need to deal with ARP.<\/p>\n\n\n\n<p>Consider this topology. The two real hosts are at the bottom. We want to cause, from 192.168.2.5&#8217;s point of view, 192.168.2.1 to have an SMTP service it doesn&#8217;t really have. Further, from 192.168.2.5&#8217;s point of view, we want any host within 192.168.2.0\/24 to appear to have that service.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"768\" src=\"https:\/\/www.vandervecken.com\/faucet\/wp-content\/uploads\/2020\/01\/pipette-1024x768.jpg\" alt=\"\" class=\"wp-image-90\" srcset=\"https:\/\/faucet.vandervecken.com\/wp-content\/uploads\/2020\/01\/pipette-1024x768.jpg 1024w, https:\/\/faucet.vandervecken.com\/wp-content\/uploads\/2020\/01\/pipette-300x225.jpg 300w, https:\/\/faucet.vandervecken.com\/wp-content\/uploads\/2020\/01\/pipette-768x576.jpg 768w, https:\/\/faucet.vandervecken.com\/wp-content\/uploads\/2020\/01\/pipette-1536x1152.jpg 1536w, https:\/\/faucet.vandervecken.com\/wp-content\/uploads\/2020\/01\/pipette-2048x1536.jpg 2048w, https:\/\/faucet.vandervecken.com\/wp-content\/uploads\/2020\/01\/pipette-1568x1176.jpg 1568w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>The first step is to have FAUCET apply a port ACL to 192.168.2.5&#8217;s port, saying we want TCP port 25 (we&#8217;re faking SMTP) for all of 192.168.2.0\/24 to be coprocessed. We could also use a VLAN ACL (pipette would need a small modification to allow it to receive tagged VLAN packets in that case).<\/p>\n\n\n\n<p>Port 13 will have the host with 192.168.2.5 &#8211; port 18 is where the coprocessor is connected.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>vlans:\n  trusted:\n    vid: 2\ninterfaces:\n  13:\n    acls_in:\n      - coprocessssh\n    description: 802.1x Pi\n    native_vlan: trusted\n  18:\n    coprocessor:\n      strategy: vlan_vid\n    description: coprocessor NFV\nacls:\n  coprocessssh:\n  - rule:\n      dl_type: 0x800\n      ip_proto: 6\n      ipv4_src: 192.168.2.0\/24\n      tcp_dst: 25\n      actions:\n        output:\n          ports: [18]\n  - rule:\n      actions:\n        allow: 1<\/code><\/pre>\n\n\n\n<p>Now, on the coprocessor, we&#8217;ll need OVS and Ryu installed, and <a href=\"https:\/\/github.com\/anarkiwi\/pipette\/blob\/e008b3db8021a689514f98e39e167c2650aea3a7\/pipette.py\">pipette<\/a>. pipette patches TCP traffic in and out of a namespace where the fake service will run while maintaining the L2 illusion that the fake service is running on the real host.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># interface connected to FAUCET switch\nNFVINT=enx0023565c8859\n# used privately by the fake service.\nFAKEHW=0e:00:00:00:00:66\nFAKECLIENTHW=0e:00:00:00:00:67\n# all 192.168.2.0\/24 port 25 will be redirected to this fake IP.\nFAKEIP=192.168.2.1\/24\nNS=copro\n\nip netns add $NS\nifconfig $NFVINT up\nip link add dev fake0 type veth peer name fakeovs0\nifconfig fakeovs0 up\nip link set fake0 netns $NS\nip netns exec $NS ifconfig fake0 hw ether $FAKEHW $FAKEIP up\nfor i in $NFVINT fakeovs0 ovs-system ; do\n  echo 1 > \/proc\/sys\/net\/ipv6\/conf\/$i\/disable_ipv6\ndone\nifconfig ovs-system 0.0.0.0\n\novs-vsctl del-br br0\novs-vsctl add-br br0\novs-ofctl del-flows br0\n\nfor i in $NFVINT fakeovs0 ; do\n  ovs-vsctl add-port br0 $i\ndone\n\novs-vsctl set-controller br0 tcp:127.0.0.1:6653\nryu-manager pipette.py --verbose<\/code><\/pre>\n\n\n\n<p>Now we can run the fake SMTP service in the fake namespace. Note, even though the fake service is only running on 192.168.2.1, pipette is arranging for TCP traffic for the entire subnet to be mapped to that IP address as below.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># while \/bin\/true ; do echo completely legit SMTP service| ip netns exec copro nc -l 192.168.2.1 25 ; done<\/code><\/pre>\n\n\n\n<p>With everything ready, let&#8217;s try to connect to the fake SMTP server, apparently on 192.168.2.1, but in reality inside the coprocessor:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>pi@pi8021x:~ $ telnet 192.168.2.1 25\nTrying 192.168.2.1...\nConnected to 192.168.2.1.\nEscape character is '^]'.\ncompletely legit SMTP service\n<\/code><\/pre>\n\n\n\n<p>How odd! What about 192.168.2.2?<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>pi@pi8021x:~ $ telnet 192.168.2.2 25\nTrying 192.168.2.2...\nConnected to 192.168.2.2.\nEscape character is '^]'.\ncompletely legit SMTP service<\/code><\/pre>\n\n\n\n<p>It appears there too! What&#8217;s going on? pipette is doing some TCP MAC and IP translation and mapping that into an isolated namespace, while also proxying the real host&#8217;s MAC address dynamically.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\nroot@coprocessor:\/home\/pi# ovs-ofctl -OOpenFlow13 dump-flows br0\n cookie=0x0, duration=178.489s, table=0, n_packets=6, n_bytes=428, priority=1,in_port=enx0023565c8859 actions=goto_table:1\n cookie=0x0, duration=178.489s, table=0, n_packets=9, n_bytes=600, priority=1,in_port=fakeovs0 actions=goto_table:2\n cookie=0x0, duration=178.490s, table=0, n_packets=0, n_bytes=0, priority=0 actions=drop\n cookie=0x0, duration=14.819s, table=1, n_packets=1, n_bytes=70, idle_timeout=30, priority=2,tcp,dl_src=b8:27:eb:d6:31:ca,nw_dst=192.168.2.1,tp_dst=25 actions=set_field:0e:00:00:00:00:67->eth_src,set_field:0e:00:00:00:00:66->eth_dst,set_field:192.168.2.1->ip_dst,output:fakeovs0\n cookie=0x0, duration=178.490s, table=1, n_packets=2, n_bytes=146, priority=1,tcp actions=CONTROLLER:65509\n cookie=0x0, duration=178.490s, table=1, n_packets=0, n_bytes=0, priority=0 actions=drop\n cookie=0x0, duration=14.819s, table=2, n_packets=1, n_bytes=66, idle_timeout=30, priority=2,tcp,nw_dst=192.168.2.5,tp_src=25 actions=set_field:aa:56:63:87:9e:e9->eth_src,set_field:b8:27:eb:d6:31:ca->eth_dst,set_field:192.168.2.1->ip_src,push_vlan:0x8100,set_field:4098->vlan_vid,output:enx0023565c8859\n cookie=0x0, duration=178.490s, table=2, n_packets=2, n_bytes=84, priority=1,arp actions=CONTROLLER:65509\n cookie=0x0, duration=178.490s, table=2, n_packets=4, n_bytes=280, priority=0 actions=drop\n<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>In a previous post, we introduced coprocessing and faking a TCP service on a single IP. The FAUCET coprocessor feature allows an external host to inject packets to a given VLAN (or even port). FAUCET ACLs are used to select traffic to be sent to the coprocessor (by default nothing is sent for coprocessing). In &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/faucet.vandervecken.com\/index.php\/2020\/01\/24\/faking-services-on-an-entire-ip-subnet\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;faking services on an entire IP subnet&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-89","post","type-post","status-publish","format-standard","hentry","category-uncategorised","entry"],"_links":{"self":[{"href":"https:\/\/faucet.vandervecken.com\/index.php\/wp-json\/wp\/v2\/posts\/89","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/faucet.vandervecken.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/faucet.vandervecken.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/faucet.vandervecken.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/faucet.vandervecken.com\/index.php\/wp-json\/wp\/v2\/comments?post=89"}],"version-history":[{"count":6,"href":"https:\/\/faucet.vandervecken.com\/index.php\/wp-json\/wp\/v2\/posts\/89\/revisions"}],"predecessor-version":[{"id":96,"href":"https:\/\/faucet.vandervecken.com\/index.php\/wp-json\/wp\/v2\/posts\/89\/revisions\/96"}],"wp:attachment":[{"href":"https:\/\/faucet.vandervecken.com\/index.php\/wp-json\/wp\/v2\/media?parent=89"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/faucet.vandervecken.com\/index.php\/wp-json\/wp\/v2\/categories?post=89"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/faucet.vandervecken.com\/index.php\/wp-json\/wp\/v2\/tags?post=89"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}