{"id":103,"date":"2020-02-06T01:54:32","date_gmt":"2020-02-06T01:54:32","guid":{"rendered":"https:\/\/www.vandervecken.com\/faucet\/?p=103"},"modified":"2020-02-06T01:54:32","modified_gmt":"2020-02-06T01:54:32","slug":"faking-services-on-an-entire-ip-subnet-controllerless-proxying","status":"publish","type":"post","link":"https:\/\/faucet.vandervecken.com\/index.php\/2020\/02\/06\/faking-services-on-an-entire-ip-subnet-controllerless-proxying\/","title":{"rendered":"Faking services on an entire IP subnet &#8211; controllerless proxying."},"content":{"rendered":"\n<p>In <a href=\"https:\/\/www.vandervecken.com\/faucet\/wp-admin\/post.php?post=97&amp;action=edit\">part II<\/a> we demonstrated faking IP services for an entire subnet. Now, let&#8217;s eliminate the need for an interactive OpenFlow control entirely, with the <a href=\"https:\/\/docs.openvswitch.org\/en\/latest\/tutorials\/ovs-advanced\/\">magic OVS learn<\/a> actions. These are almost like OVS assembly language instructions, that allow OVS rewrite packets or even add flows to itself. Once new <a href=\"https:\/\/github.com\/CyberReboot\/pipette\/blob\/15822345b18d1921d5a049251cdbf028d9612109\/pipette.py\">pipette<\/a> has programmed OVS, once, OVS can respond to ARP requests and do the L2\/L3 NAT translation entirely by itself.<\/p>\n\n\n\n<p>This means we don&#8217;t have to rely on the controller being up to handle new connections, and connection handling is fast.<\/p>\n\n\n\n<p>Here&#8217;s how OVS looks after it has just been programmed by pipette:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># ovs-ofctl -OOpenFlow13 dump-flows copro0\n cookie=0x0, duration=6.758s, table=0, n_packets=0, n_bytes=0, priority=1,in_port=enx0023565c8859,vlan_tci=0x1000\/0x1000 actions=pop_vlan,goto_table:1\n cookie=0x0, duration=6.758s, table=0, n_packets=0, n_bytes=0, priority=1,tcp,in_port=enx0023565c8859 actions=goto_table:1\n cookie=0x0, duration=6.758s, table=0, n_packets=0, n_bytes=0, priority=1,udp,in_port=enx0023565c8859 actions=goto_table:1\n cookie=0x0, duration=6.758s, table=0, n_packets=0, n_bytes=0, priority=1,tcp,in_port=ovsfake0 actions=push_vlan:0x8100,set_field:4098->vlan_vid,goto_table:2\n cookie=0x0, duration=6.758s, table=0, n_packets=0, n_bytes=0, priority=1,udp,in_port=ovsfake0 actions=push_vlan:0x8100,set_field:4098->vlan_vid,goto_table:2\n cookie=0x0, duration=6.757s, table=0, n_packets=0, n_bytes=0, priority=1,arp,in_port=ovsfake0,dl_src=0e:00:00:00:00:66 actions=goto_table:2\n cookie=0x0, duration=6.759s, table=0, n_packets=6, n_bytes=621, priority=0 actions=drop\n cookie=0x0, duration=6.758s, table=1, n_packets=0, n_bytes=0, priority=1,tcp actions=move:NXM_OF_IP_SRC&#91;]->NXM_NX_REG0&#91;],load:0xa0a->NXM_NX_REG0&#91;16..31],move:NXM_NX_REG0&#91;0..7]->NXM_NX_REG0&#91;8..15],move:NXM_OF_IP_DST&#91;0..7]->NXM_NX_REG0&#91;0..7],load:0x2->NXM_NX_REG1&#91;0..2],load:0x1->NXM_NX_REG2&#91;0..2],learn(table=1,hard_timeout=300,priority=2,eth_type=0x800,NXM_OF_IP_SRC&#91;],NXM_OF_IP_DST&#91;],load:NXM_NX_REG0&#91;]->NXM_OF_IP_SRC&#91;],load:0xa0a0001->NXM_OF_IP_DST&#91;],load:0xe0000000067->NXM_OF_ETH_SRC&#91;],load:0xe0000000066->NXM_OF_ETH_DST&#91;],output:NXM_NX_REG1&#91;0..1]),learn(table=2,idle_timeout=300,priority=2,eth_type=0x800,ip_src=10.10.0.1,NXM_OF_IP_DST&#91;]=NXM_NX_REG0&#91;],load:NXM_OF_ETH_SRC&#91;]->NXM_OF_ETH_DST&#91;],load:NXM_OF_ETH_DST&#91;]->NXM_OF_ETH_SRC&#91;],load:NXM_OF_IP_SRC&#91;]->NXM_OF_IP_DST&#91;],load:NXM_OF_IP_DST&#91;]->NXM_OF_IP_SRC&#91;],output:NXM_NX_REG2&#91;0..1]),set_field:0e:00:00:00:00:67->eth_src,set_field:0e:00:00:00:00:66->eth_dst,move:NXM_NX_REG0&#91;]->NXM_OF_IP_SRC&#91;],set_field:10.10.0.1->ip_dst,output:ovsfake0\n cookie=0x0, duration=6.758s, table=1, n_packets=0, n_bytes=0, priority=1,udp actions=move:NXM_OF_IP_SRC&#91;]->NXM_NX_REG0&#91;],load:0xa0a->NXM_NX_REG0&#91;16..31],move:NXM_NX_REG0&#91;0..7]->NXM_NX_REG0&#91;8..15],move:NXM_OF_IP_DST&#91;0..7]->NXM_NX_REG0&#91;0..7],load:0x2->NXM_NX_REG1&#91;0..2],load:0x1->NXM_NX_REG2&#91;0..2],learn(table=1,hard_timeout=300,priority=2,eth_type=0x800,NXM_OF_IP_SRC&#91;],NXM_OF_IP_DST&#91;],load:NXM_NX_REG0&#91;]->NXM_OF_IP_SRC&#91;],load:0xa0a0001->NXM_OF_IP_DST&#91;],load:0xe0000000067->NXM_OF_ETH_SRC&#91;],load:0xe0000000066->NXM_OF_ETH_DST&#91;],output:NXM_NX_REG1&#91;0..1]),learn(table=2,idle_timeout=300,priority=2,eth_type=0x800,ip_src=10.10.0.1,NXM_OF_IP_DST&#91;]=NXM_NX_REG0&#91;],load:NXM_OF_ETH_SRC&#91;]->NXM_OF_ETH_DST&#91;],load:NXM_OF_ETH_DST&#91;]->NXM_OF_ETH_SRC&#91;],load:NXM_OF_IP_SRC&#91;]->NXM_OF_IP_DST&#91;],load:NXM_OF_IP_DST&#91;]->NXM_OF_IP_SRC&#91;],output:NXM_NX_REG2&#91;0..1]),set_field:0e:00:00:00:00:67->eth_src,set_field:0e:00:00:00:00:66->eth_dst,move:NXM_NX_REG0&#91;]->NXM_OF_IP_SRC&#91;],set_field:10.10.0.1->ip_dst,output:ovsfake0\n cookie=0x0, duration=6.759s, table=1, n_packets=0, n_bytes=0, priority=0 actions=drop\n cookie=0x0, duration=6.758s, table=2, n_packets=0, n_bytes=0, priority=1,arp,arp_op=1 actions=move:NXM_OF_ARP_TPA&#91;]->NXM_NX_REG0&#91;],load:0x2->NXM_OF_ARP_OP&#91;0..2],move:NXM_OF_ETH_SRC&#91;]->NXM_OF_ETH_DST&#91;],move:NXM_NX_ARP_SHA&#91;]->NXM_NX_ARP_THA&#91;],move:NXM_OF_ARP_SPA&#91;]->NXM_OF_ARP_TPA&#91;],move:NXM_NX_REG0&#91;]->NXM_OF_ARP_SPA&#91;],set_field:0e:00:00:00:00:67->eth_src,set_field:0e:00:00:00:00:67->arp_sha,IN_PORT\n cookie=0x0, duration=6.758s, table=2, n_packets=0, n_bytes=0, priority=0 actions=drop\n<\/code><\/pre>\n\n\n\n<p>While scary looking, the flows are mostly just rearranging fields. Let&#8217;s look at the flow that responds to ARP:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code> cookie=0x0, duration=6.758s, table=2, n_packets=0, n_bytes=0, priority=1,arp,arp_op=1 actions=move:NXM_OF_ARP_TPA&#91;]->NXM_NX_REG0&#91;],load:0x2->NXM_OF_ARP_OP&#91;0..2],move:NXM_OF_ETH_SRC&#91;]->NXM_OF_ETH_DST&#91;],move:NXM_NX_ARP_SHA&#91;]->NXM_NX_ARP_THA&#91;],move:NXM_OF_ARP_SPA&#91;]->NXM_OF_ARP_TPA&#91;],move:NXM_NX_REG0&#91;]->NXM_OF_ARP_SPA&#91;],set_field:0e:00:00:00:00:67->eth_src,set_field:0e:00:00:00:00:67->arp_sha,IN_PORT<\/code><\/pre>\n\n\n\n<p>This flow matches ARP requests. Then, it turns the ARP packet into an ARP reply, rewrites source hardware addresses, and rewrites IP addresses (we temporarily store the ARP target address from the request in OVS&#8217; software register reg0, so it doesn&#8217;t get overwritten and so we can use it at the end of the rewriting process). Finally, we say to output the packet on the same port it came in on.<\/p>\n\n\n\n<p>Now let&#8217;s look at the really scary flow that implements learning:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cookie=0x0, duration=6.758s, table=1, n_packets=0, n_bytes=0, priority=1,tcp actions=move:NXM_OF_IP_SRC&#91;]->NXM_NX_REG0&#91;],load:0xa0a->NXM_NX_REG0&#91;16..31],move:NXM_NX_REG0&#91;0..7]->NXM_NX_REG0&#91;8..15],move:NXM_OF_IP_DST&#91;0..7]->NXM_NX_REG0&#91;0..7],load:0x2->NXM_NX_REG1&#91;0..2],load:0x1->NXM_NX_REG2&#91;0..2],learn(table=1,hard_timeout=300,priority=2,eth_type=0x800,NXM_OF_IP_SRC&#91;],NXM_OF_IP_DST&#91;],load:NXM_NX_REG0&#91;]->NXM_OF_IP_SRC&#91;],load:0xa0a0001->NXM_OF_IP_DST&#91;],load:0xe0000000067->NXM_OF_ETH_SRC&#91;],load:0xe0000000066->NXM_OF_ETH_DST&#91;],output:NXM_NX_REG1&#91;0..1]),learn(table=2,idle_timeout=300,priority=2,eth_type=0x800,ip_src=10.10.0.1,NXM_OF_IP_DST&#91;]=NXM_NX_REG0&#91;],load:NXM_OF_ETH_SRC&#91;]->NXM_OF_ETH_DST&#91;],load:NXM_OF_ETH_DST&#91;]->NXM_OF_ETH_SRC&#91;],load:NXM_OF_IP_SRC&#91;]->NXM_OF_IP_DST&#91;],load:NXM_OF_IP_DST&#91;]->NXM_OF_IP_SRC&#91;],output:NXM_NX_REG2&#91;0..1]),set_field:0e:00:00:00:00:67->eth_src,set_field:0e:00:00:00:00:66->eth_dst,move:NXM_NX_REG0&#91;]->NXM_OF_IP_SRC&#91;],set_field:10.10.0.1->ip_dst,output:ovsfake0<\/code><\/pre>\n\n\n\n<p>First, we calculate the source NAT address and put it in reg0. Then we have two learn() sections &#8211; one adds a flow to table 1 to implement inbound translation, and the other adds a flow to table 2 for outbound. Finally, we have to do NAT translation on the packet we just got and send it. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>In part II we demonstrated faking IP services for an entire subnet. Now, let&#8217;s eliminate the need for an interactive OpenFlow control entirely, with the magic OVS learn actions. These are almost like OVS assembly language instructions, that allow OVS rewrite packets or even add flows to itself. Once new pipette has programmed OVS, once, &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/faucet.vandervecken.com\/index.php\/2020\/02\/06\/faking-services-on-an-entire-ip-subnet-controllerless-proxying\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Faking services on an entire IP subnet &#8211; controllerless proxying.&#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-103","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\/103","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=103"}],"version-history":[{"count":1,"href":"https:\/\/faucet.vandervecken.com\/index.php\/wp-json\/wp\/v2\/posts\/103\/revisions"}],"predecessor-version":[{"id":104,"href":"https:\/\/faucet.vandervecken.com\/index.php\/wp-json\/wp\/v2\/posts\/103\/revisions\/104"}],"wp:attachment":[{"href":"https:\/\/faucet.vandervecken.com\/index.php\/wp-json\/wp\/v2\/media?parent=103"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/faucet.vandervecken.com\/index.php\/wp-json\/wp\/v2\/categories?post=103"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/faucet.vandervecken.com\/index.php\/wp-json\/wp\/v2\/tags?post=103"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}