总而言之,虽然我设置了允许 tcp:80 的防火墙规则,但位于“默认”网络上的 GCE 实例不接受到端口 80 的连接。看来我的实例上只打开了端口 22。我可以 ping 它,但无法在 64 跳以下追踪到它。
接下来是我的调查,使我得出这些结论。
gcloud beta compute firewall-rules list
NAME NETWORK DIRECTION PRIORITY ALLOW DENY
default-allow-http default INGRESS 1000 tcp:80
default-allow-https default INGRESS 1000 tcp:443
default-allow-icmp default INGRESS 65534 icmp
default-allow-internal default INGRESS 65534 tcp:0-65535,udp:0-65535,icmp
default-allow-rdp default INGRESS 65534 tcp:3389
default-allow-ssh default INGRESS 65534 tcp:22
temp default INGRESS 1000 tcp:8888
gcloud compute instances list
NAME ZONE MACHINE_TYPE PREEMPTIBLE INTERNAL_IP EXTERNAL_IP STATUS
ssrf3 us-west1-c f1-micro true 10.138.0.4 35.197.33.182 RUNNING
gcloud compute instances describe ssrf3
...
name: ssrf3
networkInterfaces:
- accessConfigs:
- kind: compute#accessConfig
name: external-nat
natIP: 35.197.33.182
type: ONE_TO_ONE_NAT
kind: compute#networkInterface
name: nic0
network: https://www.googleapis.com/compute/v1/projects/hack-170416/global/networks/default
networkIP: 10.138.0.4
subnetwork: https://www.googleapis.com/compute/v1/projects/hack-170416/regions/us-west1/subnetworks/default
...
tags:
fingerprint: 6smc4R4d39I=
items:
- http-server
- https-server
我通过 ssh 进入 35.197.33.182(这是 ssrf3 实例)并运行:
sudo nc -l -vv -p 80
在我的本地计算机上,我运行:
nc 35.197.33.182 80 -vv
hey
但什么也没发生。 所以我尝试 ping 主机。看起来很健康:
ping 35.197.33.182
PING 35.197.33.182 (35.197.33.182): 56 data bytes
64 bytes from 35.197.33.182: icmp_seq=0 ttl=57 time=69.172 ms
64 bytes from 35.197.33.182: icmp_seq=1 ttl=57 time=21.509 ms
Traceroute 在 64 跳后退出,未到达 35.197.33.182 目的地。
所以我用 nmap 检查哪些端口打开了:
nmap 35.197.33.182
Starting Nmap 7.12 ( https://nmap.org ) at 2017-06-18 16:39 PDT
Note: Host seems down. If it is really up, but blocking our ping probes, try -Pn
Nmap done: 1 IP address (0 hosts up) scanned in 3.06 seconds
nmap 35.197.33.182 -Pn
Starting Nmap 7.12 ( https://nmap.org ) at 2017-06-18 16:39 PDT
Nmap scan report for 182.33.197.35.bc.googleusercontent.com (35.197.33.182)
Host is up (0.022s latency).
Not shown: 999 filtered ports
PORT STATE SERVICE
22/tcp open ssh
Nmap done: 1 IP address (1 host up) scanned in 6.84 seconds
…即使我在 35.197.33.182 上运行
nc -l -p 80
。
确保虚拟机级防火墙不会干预。例如,与所有其他默认映像相比,容器优化操作系统有点特殊:
默认情况下,Container-Optimized OS 主机防火墙仅允许传出连接,并且仅接受通过 SSH 服务的传入连接。要接受 Container-Optimized OS 实例上的传入连接,您必须打开您的服务正在侦听的端口。
https://cloud.google.com/container-optimized-os/docs/how-to/firewall
选中“允许 HTTP 流量”和“允许 HTTPS 流量”两个复选框就可以了。这创建了两个防火墙规则,打开端口 80 和 443。 由于某种原因,为这些端口手动添加规则不起作用,但它可以通过选中复选框来实现。
乍一看,您的设置似乎是正确的。
tcp:80
。当您在云提供商上运行虚拟机时,Traceroute 不会给出良好的指示,因为不幸的是,由于使用了 SDN、虚拟网络和大量中间网络基础设施。
我注意到的一件事是您的实例有 2 个标签
http-server
和 https-server
。这些可能被其他一些防火墙规则使用,这些规则可能以某种方式阻止到虚拟机 tcp:80 端口的流量。
您的设置中还有其他变量,如果需要进一步调试,我很乐意进行调试。
您可以尝试基于标记的防火墙规则,该规则将仅将防火墙规则应用于具有指定目标标记的实例。
网络使用网络标签来识别哪些实例 受某些防火墙规则和网络路由的约束。例如,如果 您有多个虚拟机实例为大型网站提供服务,标记 这些实例具有共享单词或术语,然后使用该标签 应用允许 HTTP 访问这些实例的防火墙规则。标签 也反映在元数据服务器中,因此您可以将它们用于 在您的实例上运行的应用程序。当您创建防火墙时 规则,您可以提供
或sourceRanges
,但不能同时提供两者。sourceTags
# Add a new tag based firewall rule to allow ingress tcp:80
gcloud compute firewall-rules create rule-allow-tcp-80 --source-ranges 0.0.0.0/0 --target-tags allow-tcp-80 --allow tcp:80
# Add the allow-tcp-80 target tag to the VM ssrf3
gcloud compute instances add-tags ssrf3 --tags allow-tcp-80
更改可能需要几秒钟到几分钟才能生效。
注意: 由于您要向互联网开放虚拟机的外部 IP 端口,请注意根据在这些端口上运行的应用程序的需求相应地限制访问。
经过大量的尝试和错误,以下内容对我有用 ubuntu-1404-trusty-v20190514 ,使用 Nodejs 应用程序侦听端口 8080。接受端口 80 和 8080,然后将 80 重定向到 8080。
sudo iptables -A INPUT -i eth0 -p tcp --dport 80 -j ACCEPT
sudo iptables -A INPUT -i eth0 -p tcp --dport 8080 -j ACCEPT
sudo iptables -t nat -A OUTPUT -o lo -p tcp --dport 80 -j REDIRECT --to-port 8080
sudo iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8080
如果您是 Windows 服务器实例,您可以尝试关闭 Windows Defender 并检查它是否阻止传入连接。
我在尝试使用
terraform
创建 CE 实例时遇到了这个问题。防火墙规则部分如下:
resource "google_compute_firewall" "test" {
name = "allow-http"
network = "default"
source_ranges = ["0.0.0.0"]
allow {
protocol = "tcp"
ports = ["80", "443"]
}
}
使用
terraform
source_ranges
、source_tags
或 source_service_accounts
之一是必需。我的错误是指定 0.0.0.0
代替 0.0.0.0/0
。
使用
gcloud
创建防火墙规则时 --source-ranges
默认为 0.0.0.0/0
。因此,对于 gcloud
,你遇到它的机会会更小。
无论如何,你最有可能想跑步:
$ gcloud compute firewall-rules describe default-allow-http
$ gcloud compute firewall-rules describe default-allow-https
并查看谁获得了访问权限。