如何绑定和发送Google Cloud Forwarding规则IP地址?

Gra*_*ntJ 11 python networking google-compute-engine google-cloud-platform

我已按照Google云端平台上的使用协议转发的说明进行操作.所以我现在有这样的事情:

$ 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
Run Code Online (Sandbox Code Playgroud)

(注意:名称已被更改,问号已被替换.我不确定保持这些私密但更安全而不是遗憾.)

我的实例"x"在"x-target-instance"中,并且具有五个转发规则"x-fr-1"到"x-fr-5".我在"x"上运行nginx,我可以从它的6个外部IP地址中的任何一个访问它(1个用于实例+ 5个转发规则).到现在为止还挺好.

我现在感兴趣的是将服务器绑定到这些外部IP地址.为了探索,我尝试使用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()
Run Code Online (Sandbox Code Playgroud)

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

>>> serve("0.0.0.0")
('173.228.???.??', 57288) ('10.240.?.?', 80)
('173.228.???.??', 57286) ('104.198.?.??', 80)
Run Code Online (Sandbox Code Playgroud)

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

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

>>> serve("10.240.?.?")
('173.228.???.??', 57295) ('10.240.?.?', 80)
Run Code Online (Sandbox Code Playgroud)

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

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

>>> serve("104.198.?.??")
error: [Errno 99] Cannot assign requested address
Run Code Online (Sandbox Code Playgroud)

然后我收到一个错误.

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

>>> serve("104.198.??.???")
('173.228.???.??', 57313) ('104.198.??.???', 80)
Run Code Online (Sandbox Code Playgroud)

有用.

最后我看看"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)
Run Code Online (Sandbox Code Playgroud)

我只看到两个接口.显然,Google Cloud Platform Networking的功能已经超出了我在大学的计算机网络课程中的记忆.总结一下我的观察:

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

这是我的问题:

  1. 为什么我不能绑定实例的外部IP地址?
  2. 当我没有关联的网络适配器时,如何绑定转发规则使用的外部IP地址?
  3. 如果我想限制SSH访问实例的外部IP地址,我应该配置SSH来绑定内部IP地址吗?
  4. 如果我在转发规则使用的其中一个外部IP地址上设置HTTP代理,那么代理请求的源IP是什么?
  5. 最后,这可能是一个错误,为什么在我看到https://console.cloud.google.com/networking/loadbalancing/advanced/forwardingRules/list?project=xxx的网络界面中的转发规则列表为空他们用"gcloud计算转发规则列表"?

Kev*_*vin 6

  1. 它不在本地路由表中('ip route show table local')[你当然可以添加它(例如'ip address add xxxx/32 dev ens4'),但这样做对你来说不会太好,因为没有数据包将作为目标地址传送到您的VM - 请参阅下面的...]
  2. 因为已转发的地址已添加到您的本地路由表('ip route show table local')
  3. 你可以[虽然注意到这会限制ssh访问针对外部IP地址的外部客户端,或限制虚拟网络中针对外部或内部IP地址的客户端].但是,正如已经指出的那样 - 限制允许的客户端地址(而不是服务器地址)可能更为重要,因此防火墙会更有效.
  4. 它取决于代理请求的目的地的去向.如果它在您的虚拟网络内部,那么它将是VM的内部IP地址,否则它是NAT(在您的VM之外)作为VM的外部IP地址.
  5. 该页面上有多个选项卡 - 其中两个列出了不同类别的转发规则("全局转发规则"与"转发规则").不可否认有点令人困惑:P

另一件令人困惑的事情 - 当使用外部IP作为目标地址向VM发送数据包时,VM外部的实体(将其视为虚拟交换机/路由器/ NAT设备)会自动将目标修改为内部IP在数据包到达虚拟网卡的virtio驱动程序之前 - 因此您无法修改该行为.但是,寻址到转发规则的IP的数据包不是NAT(正如您所见).

希望有所帮助!