如何绑定并从Google云转发规则IP地址发送? [英] How to Bind and Send from Google Cloud Forwarding Rule IP Address?

查看:198
本文介绍了如何绑定并从Google云转发规则IP地址发送?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遵循了Google上使用协议转发的说明云平台。所以我现在有这样的东西:

  $ gcloud计算转发规则列表
名称区域IP_ADDRESS IP_PROTOCOL TARGET
x-fr-1 us-west1 104.198。?。?? TCP us-west1-a / targetInstances / x-target-instance
x-fr-2 us-west1 104.198。?。?? TCP us-west1 -a / targetInstances / x-target-instance
x-fr-3 us-west1 104.198。??。??? TCP us-west1 -a / targetInstances / x-target-instance
x-fr-4 us-west1 104.198。??。??? TCP us-west1-a / targetInstances / x-target-instance
x-fr-5 us-west1 104.198。?。??? TCP us-west1-a / targetInstances / x-target-instance

(注意:名称已更改和问号已被替换,我不确定保持这些隐私的重要性,但比对不起更安全。)



我的实例x位于 x-target-instance,并且通过x-fr-5具有五个转发规则x-fr-1。我在x上运行nginx,我可以从它的6个外部IP地址(1个用于实例+ 5个转发规则)访问它。到目前为止,这么好。



我现在有兴趣将服务器绑定到这些外部IP地址。为了探索,我尝试使用Python:

 导入套接字
导入时间

def serve (ip_address,port = 80):
sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sock.bind((ip_address,port))
try:
sock.listen(5)
while True:
con,_ = sock.accept()
print con.getpeername(),con.getsockname()
con.send time.ctime())
con.close()
finally:
sock.close()

现在我可以绑定0.0.0.0,并得到一些有趣的结果:

 > ;>>服务(0.0.0.0)
('173.228。???。',57288)('10 .240。?。',80)
('173.228。???。? ?',57286)('104.198。?。??',80)

服务器在其外部IP地址上,getsockname方法返回实例的内部IP地址。但是,当我使用外部IP地址与转发规则使用的服务器通信时,则getsockname方法会返回外部IP地址。



好吧,现在我绑定实例的内部IP地址:

 >>> ('10.240。?。?)
('173.228。???。',57295)('10 .240。?。?',80)

我可以再次与服务器的外部IP地址通信,getsockname方法返回实例的内部IP地址。这似乎有点奇怪。



另外,如果我尝试绑定实例的外部IP地址:

 >>> serve(104.198。?。??)
错误:[Errno 99]无法分配请求的地址

然后我得到一个错误。

但是,如果我尝试绑定转发规则使用的外部IP地址,然后发出请求:

 >>> ('104.198。??。???)
('173.228。???。',57313)('104.198。??。'',80)

它可行。



最后我看看ifconfig:

  ens4 Link encap:Ethernet HWaddr 42:01:0a:??:??:?? 
inet addr:10.240。?。? BCAST:10.240。?。? Mask:255.255.255.255
inet6 addr:fe80 :: 4001:???:????:2/64范围:链接
广播运行多播MTU:1460度量标准:1
RX数据包:37554错误:0丢弃:0超限:0帧:0
TX数据包:32286错误:0丢弃:0超限:0载波:0
冲突:0 txqueuelen:1000
RX字节:41201244(41.2 MB)TX字节:3339072(3.3 MB)

lo链接封装:本地环回
inet addr:127.0.0.1掩码:255.0.0.0
inet6 addr::: 1/128范围:主机
UP LOOPBACK RUNNING MTU:65536度量标准:1
RX包:9403错误:0丢弃:0超限:0帧:0
TX包: 9403错误:0丢弃:0超限:0载波:0
冲突:0 txqueuelen:1
RX字节:3155046(3.1 MB)TX字节:3155046(3.1 MB)

我只看到两个接口。显然,Google云平台网络的能力已经超出了我在大学的计算机网络课程中记得的。总结我的观察:


  1. 如果我想绑定实例的外部IP地址,则绑定其内部IP地址。
  2. >
  3. 绑定到实例内部IP地址的进程无法区分实例的内部或外部IP地址之间的目标IP地址。
  4. 单个网络适配器ens4 ,正在接收绑定任何实例的6个外部IP地址的数据包。

以下是我的问题:


  1. 为什么我不能绑定实例的外部IP地址?

  2. 我如何绑定使用的外部IP地址通过转发规则,当我没有关联的网络适配器?

  3. 如果我想限制SSH访问实例的外部IP地址,我应该配置SSH来绑定内部IP地址吗?

  4. 如果我在一个转发规则使用的外部IP地址之一上设置HTTP代理,那么将如何urce代理请求的IP?

  5. 最后,这可能是一个错误,为什么转发规则列表在 https://console.cloud.google.com/networking/loadbalancing/advanced/forwardingRules/list?project=我可以用gcloud compute forwarding-rules list看到它们吗?



  1. 它不在本地路由表中('ip route show table local')
    [你当然可以添加它(例如'ip address add xxxx / 32 dev ens4'),
    ,但是这样做对你来说不会有太大的好处,因为没有数据包会以
    的形式传递给你的虚拟机,并将其作为目标地址 - 请参阅$ b因为转发的地址已被添加到您的本地路由表('ip route show table local')


  2. 您可以[但请注意,这将限制ssh访问以外部IP地址为目标的外部客户端,或限制您的虚拟网络中以客户或内部IP地址为目标的客户端]。但是,正如已经指出的那样 - 限制允许的客户端地址(而不是服务器地址)可能更为重要,并且防火墙会更有效。

  3. <这取决于代理请求的目的地在哪里。如果它位于虚拟网络的内部,那么它将成为虚拟机的内部IP地址,否则它会被NAT(在您的虚拟机之外)作为虚拟机的外部IP地址。
  4. 该页面上有多个选项卡 - 其中两个列出不同类别的转发规则(全局转发规则与转发规则)。不可否认的是:P

另外一件有点混淆的事情是,当使用外部IP作为目标地址发送数据包到虚拟机时,虚拟机之外的实体(将其视为虚拟交换机/路由器/ NAT设备)在数据包到达虚拟NIC的virtio驱动程序之前自动将目标修改为内部IP - 因此,您无法修改该目标行为。然而,发送到转发规则的IP的数据包不是NAT(如你所见)。



希望有帮助!

I've followed the instructions for Using Protocol Forwarding on the Google Cloud Platform. So I now have something like this:

$ gcloud compute forwarding-rules list
NAME    REGION    IP_ADDRESS      IP_PROTOCOL  TARGET
x-fr-1  us-west1  104.198.?.??    TCP          us-west1-a/targetInstances/x-target-instance
x-fr-2  us-west1  104.198.?.??    TCP          us-west1-a/targetInstances/x-target-instance
x-fr-3  us-west1  104.198.??.???  TCP          us-west1-a/targetInstances/x-target-instance
x-fr-4  us-west1  104.198.??.???  TCP          us-west1-a/targetInstances/x-target-instance
x-fr-5  us-west1  104.198.?.???   TCP          us-west1-a/targetInstances/x-target-instance

(Note: Names have been changed and question-marks have been substituted. I'm not sure it matters to keep these private but better safe than sorry.)

My instance "x" is in the "x-target-instance" and has five forwarding rules "x-fr-1" through "x-fr-5". I'm running nginx on "x" and I can access it from any of its 6 external IP addresses (1 for the instance + 5 forwarding rules). So far, so good.

I am interested now in binding a server to these external IP addresses. To explore, I tried using Python:

import socket
import time

def serve(ip_address, port=80):
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.bind((ip_address, port))
    try:
        sock.listen(5)
        while True:
            con, _ = sock.accept()
            print con.getpeername(), con.getsockname()
            con.send(time.ctime())
            con.close()
    finally:
        sock.close()

Now I can bind "0.0.0.0" and I get some interesting results:

>>> serve("0.0.0.0")
('173.228.???.??', 57288) ('10.240.?.?', 80)
('173.228.???.??', 57286) ('104.198.?.??', 80)

When I communicate with the server on its external IP address, the "getsockname" method returns the instance's internal IP address. But when I communicate with the server on an external IP address as used by a forwarding rule, then the "getsockname" methods returns the external IP address.

Ok, now I bind the instance's internal IP address:

>>> serve("10.240.?.?")
('173.228.???.??', 57295) ('10.240.?.?', 80)

Again I can communicate with the server on its external IP address, and the "getsockname" method returns the instance's internal IP address. That seems a bit odd.

Also, if I try to bind the instance's external IP address:

>>> serve("104.198.?.??")
error: [Errno 99] Cannot assign requested address

Then I get an error.

But, if I try to bind the external IP addresses used by the forwarding rules and then make a request:

>>> serve("104.198.??.???")
('173.228.???.??', 57313) ('104.198.??.???', 80)

It works.

Finally I look at "ifconfig":

ens4      Link encap:Ethernet  HWaddr 42:01:0a:??:??:??  
          inet addr:10.240.?.?  Bcast:10.240.?.?  Mask:255.255.255.255
          inet6 addr: fe80::4001:???:????:2/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1460  Metric:1
          RX packets:37554 errors:0 dropped:0 overruns:0 frame:0
          TX packets:32286 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:41201244 (41.2 MB)  TX bytes:3339072 (3.3 MB)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:9403 errors:0 dropped:0 overruns:0 frame:0
          TX packets:9403 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1 
          RX bytes:3155046 (3.1 MB)  TX bytes:3155046 (3.1 MB)

And I see only two interfaces. Clearly, the abilities of Google Cloud Platform Networking has exceeded what I can remember from my Computer Networking class in college. To summarize my observations:

  1. If I want to bind on the instance's external IP address, then I bind its internal IP address.
  2. A process bound to the instance's internal IP address can not differentiate the destination IP between the instance's internal or external IP addresses.
  3. The single networking adapter, "ens4", is receiving packets bound for any of the instance's 6 external IP address.

And here's my questions:

  1. Why can I not bind the instance's external IP address?
  2. How is it that I can bind the external IP addresses used by forwarding rules when I have no associated network adapters?
  3. If I want to restrict SSH access to the instance's external IP address, should I configure SSH to bind the internal IP address?
  4. If I setup an HTTP proxy on one of the external IP addresses used by a forwarding rule, what will be the source IP of the proxied request?
  5. Lastly, and this may be a bug, why is the forwarding rules list empty in the web interface at https://console.cloud.google.com/networking/loadbalancing/advanced/forwardingRules/list?project=xxx when I can see them with "gcloud compute forwarding-rules list"?

解决方案

  1. it's not in the local routing table ('ip route show table local') [ you could of course add it (e.g. 'ip address add x.x.x.x/32 dev ens4'), but doing so wouldn't do you much good, since no packets will be delivered to your VM using that as the destination address - see below... ]
  2. because the forwarded addresses have been added to your local routing table ('ip route show table local')
  3. you could [ though note that this would restrict ssh access to either external clients targeting the external IP address, or to clients within your virtual network targeting either the external or internal IP address ]. However, as already noted - it might be more important to restrict the allowed client addresses (not the server address), and for that the firewall would be more effective.
  4. it depends on where the destination of the proxied request goes. If it's internal to your virtual network, then it will be the VM's internal IP address, otherwise it's NAT-ed (outside of your VM) to be the VM's external IP address.
  5. There are multiple tabs on that page - two of which list different classes of forwarding rule ("global forwarding rules" vs "forwarding rules"). Admittedly somewhat confusing :P

One other thing that's slightly confusing - when sending packets to your VM using its external IP as the destination address, an entity outside the VM (think of it as a virtual switch / router / NAT device) automatically modifies the destination to be the internal IP before the packet arrives at the virtio driver for the virtual NIC - so there's nothing you can do to modify that behavior. Packets addressed to the IP of a forwarding rule, however, are not NAT-ed (as you've seen).

Hope that helps!

这篇关于如何绑定并从Google云转发规则IP地址发送?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆