Module: Dcmgr::NodeModules::Nat
- Includes:
- Helpers::NicHelper, Logger
- Included in:
- ServiceNetfilter
- Defined in:
- lib/dcmgr/node_modules/service_netfilter.rb
Instance Method Summary collapse
-
#arp_respond(ip) ⇒ Object
Returns ebtables command to respond to ARP requests for the address ip.
- #is_natted_ip?(ip) ⇒ Boolean
- #nat_exceptions(inst_map) ⇒ Object
-
#nat_instance(inst_map) ⇒ Object
Takes an instance and nats it.
Methods included from Logger
create, default_logdev, included
Methods included from Helpers::NicHelper
#find_nic, #nic_state, #valid_nic?
Instance Method Details
#arp_respond(ip) ⇒ Object
Returns ebtables command to respond to ARP requests for the address ip.
125 126 127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/dcmgr/node_modules/service_netfilter.rb', line 125 def arp_respond(ip) ip = IPAddress(ip) if ip.is_a?(String) raise "Invalid IP address: #{ip}" unless ip.is_a?(IPAddress) #Get the mac address for our physical nic nic = find_nic(@node.manifest.config.hv_ifindex) #TODO: Find a prettier way to get the mac address mac_addr = %x{ifconfig | grep '#{nic}' | tr -s ' ' | cut -d ' ' -f5}.chomp logger.debug "Replying ARP requests for address: #{ip.address}" "ebtables -t nat -A PREROUTING -p arp --arp-ip-dst #{ip.address} --arp-opcode REQUEST -j arpreply --arpreply-mac #{mac_addr}" end |
#is_natted_ip?(ip) ⇒ Boolean
139 140 141 142 143 144 145 |
# File 'lib/dcmgr/node_modules/service_netfilter.rb', line 139 def is_natted_ip?(ip) ip = IPAddress(ip) if ip.is_a?(String) #TODO: put in a proper argumenterror here raise "Invalid IP address: #{ip}" unless ip.is_a?(IPAddress) rpc.request('hva-collector', 'is_natted_ip?', ip.address) end |
#nat_exceptions(inst_map) ⇒ Object
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/dcmgr/node_modules/service_netfilter.rb', line 106 def nat_exceptions(inst_map) inside_exception_ips = rpc.request('hva-collector','get_group_instance_ipv4s',inst_map[:uuid]).map {|ip| IPAddress(ip)} outside_exception_ips = rpc.request('hva-collector','get_group_instance_ipv4s',inst_map[:uuid],:outside).map {|ip| IPAddress(ip)} cmds = [] inst_map[:instance_nics].each { |nic| internal_ip = IPAddress(rpc.request('hva-collector', 'get_iplease_for_nic', nic[:uuid])) inside_exception_ips.each { |ex_ip| cmds << "iptables -t nat -A POSTROUTING -s #{internal_ip.address} -d #{ex_ip.address}/#{ex_ip.prefix} -j ACCEPT" } outside_exception_ips.each { |ex_ip| cmds << "iptables -t nat -A PREROUTING -s #{internal_ip.address} -d #{ex_ip.address}/#{ex_ip.prefix} -j ACCEPT" } } cmds end |
#nat_instance(inst_map) ⇒ Object
Takes an instance and nats it. If the instance is in a network that has a nat_network mapped to it, it will receive a second ip lease for that network. This lease will then be natted to the ip the instance already had in its own network. For example if 192.168.0.0/24 is natted to 172.16.0.0/16, then an instance with ip 192.168.0.10 might be natted to ip 172.16.46.23.
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/dcmgr/node_modules/service_netfilter.rb', line 57 def nat_instance(inst_map) nat_cmd = [] raise ArgumentError unless inst_map.is_a?(Hash) inst_map[:instance_nics].each { |nic| nat_ips = rpc.request('hva-collector', 'get_nat_leases', nic[:uuid]).map {|ip| IPAddress(ip)} #Get the internal ip for this nic internal_ip = IPAddress rpc.request('hva-collector', 'get_iplease_for_nic', nic[:uuid]) inside_exception_ips = rpc.request('hva-collector','get_group_instance_ipv4s',inst_map[:uuid]).map {|ip| IPAddress(ip)} outside_exception_ips = rpc.request('hva-collector','get_group_instance_ipv4s',inst_map[:uuid],:outside).map {|ip| IPAddress(ip)} #output the commands to nat this nic and answer arp requests for its outside ip friend_ipset = inst_map[:uuid] + "_friend_ips" nat_ips.each { |external_ip| if @node.manifest.config.use_ipset nat_cmd << "ipset -N #{friend_ipset} iphash" inside_exception_ips.each { |ex_ip| nat_cmd << "ipset -A #{friend_ipset} #{ex_ip.address}" } # The good rules that use ipset postrouting_command = "iptables -t nat -A POSTROUTING -s #{internal_ip.address} -m set ! --match-set #{friend_ipset} dst" prerouting_command = "iptables -t nat -A PREROUTING -d #{external_ip.address} -m set ! --match-set #{friend_ipset} src" else # The ugly rules to use in case ipset is not installed postrouting_command = "iptables -t nat -A POSTROUTING -s #{internal_ip.address}" prerouting_command = "iptables -t nat -A PREROUTING -d #{external_ip.address}" end # Build the final nat rules and log any packets that traverse them nat_cmd << postrouting_command + " -j LOG --log-prefix 'Snat '" nat_cmd << postrouting_command + " -j SNAT --to #{external_ip.address}" nat_cmd << prerouting_command + " -j LOG --log-prefix 'Dnat '" nat_cmd << prerouting_command + " -j DNAT --to #{internal_ip.address}" logger.debug "Natting #{internal_ip.address} to #{external_ip.address}" nat_cmd << arp_respond(external_ip) } } nat_cmd end |