我希望能够通过互联网访问在本地计算机上运行的服务器。我在路由器上设置了端口转发:
Public Port Range: 80-80
Target IP Address: 192.168.0.4
Target Port Range: 80-80
我检查了端口是否打开http://www.yougetsignal.com/tools/open-ports/其中说明:端口 80 已开放...
我尝试使用 Apache 服务器以及端口 3000 上的 nodeJS 服务器,但我从未能够访问该服务器。
我检查了我的机器是否正在监听这些端口netstat
netstat -ltn | grep 80
输出:
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN
我有什么选择可以彻底解决这个问题,我还可以进行其他检查吗?
如果有帮助的话这里是 Apache 配置。
<VirtualHost *:80>
ServerAdmin webmaster@localhost
ServerName lebensmittel-schulung.local
DocumentRoot /home/dominic/workspace/lebensmittel-schulung/public
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory /home/dominic/workspace/lebensmittel-schulung/public>
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
allow from all
Require all granted
</Directory>
# Redirect www to non-www
RewriteEngine on
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^(.*)$ http://%1$1 [L,R=301]
ErrorLog ${APACHE_LOG_DIR}/error.log
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel warn
CustomLog ${APACHE_LOG_DIR}/access.log combined
Alias /doc/ "/usr/share/doc/"
<Directory "/usr/share/doc/">
Options Indexes MultiViews FollowSymLinks
AllowOverride None
Order deny,allow
Deny from all
Allow from 127.0.0.0/255.0.0.0 ::1/128
</Directory>
</VirtualHost>
还恢复了路由器的出厂设置并重启,以避免配置错误
iptables 之前:
Chain INPUT (policy ACCEPT 1330K packets, 1422M bytes)
pkts bytes target prot opt in out source destination
0 0 ACCEPT udp -- virbr0 * 0.0.0.0/0 0.0.0.0/0 udp dpt:53
0 0 ACCEPT tcp -- virbr0 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:53
0 0 ACCEPT udp -- virbr0 * 0.0.0.0/0 0.0.0.0/0 udp dpt:67
0 0 ACCEPT tcp -- virbr0 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:67
手动打开 80 端口后的 iptables
Chain INPUT (policy ACCEPT 68 packets, 9825 bytes)
pkts bytes target prot opt in out source destination
0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:80
0 0 ACCEPT udp -- virbr0 * 0.0.0.0/0 0.0.0.0/0 udp dpt:53
0 0 ACCEPT tcp -- virbr0 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:53
0 0 ACCEPT udp -- virbr0 * 0.0.0.0/0 0.0.0.0/0 udp dpt:67
0 0 ACCEPT tcp -- virbr0 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:67
这是从运行服务器的同一台机器向我的公共 IP 发出请求后的 tcpdump 输出,尽管打开端口 80 不会改变任何东西。我认为这是 tcpdump 捕获的传出请求
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on wlan0, link-type EN10MB (Ethernet), capture size 65535 bytes
21:46:42.402748 IP 192.168.0.4.34870 > chello080108157035.6.12.vie.surfer.at.http: Flags [S], seq 2878976956, win 29200, options [mss 1460,sackOK,TS val 4294937394 ecr 0,nop,wscale 7], length 0
21:46:42.405078 IP chello080108157035.6.12.vie.surfer.at.http > 192.168.0.4.34870: Flags [R.], seq 0, ack 2878976957, win 0, length 0
21:46:43.473378 IP 192.168.0.4.34871 > chello080108157035.6.12.vie.surfer.at.http: Flags [S], seq 1711479299, win 29200, options [mss 1460,sackOK,TS val 4294937661 ecr 0,nop,wscale 7], length 0
21:46:43.473897 IP 192.168.0.4.34872 > chello080108157035.6.12.vie.surfer.at.http: Flags [S], seq 2157458117, win 29200, options [mss 1460,sackOK,TS val 4294937662 ecr 0,nop,wscale 7], length 0
21:46:43.475335 IP chello080108157035.6.12.vie.surfer.at.http > 192.168.0.4.34871: Flags [R.], seq 0, ack 1711479300, win 0, length 0
21:46:43.476463 IP chello080108157035.6.12.vie.surfer.at.http > 192.168.0.4.34872: Flags [R.], seq 0, ack 2157458118, win 0, length 0
答案1
假设路由器上的端口转发配置正确,您需要确保以下几点:
- 机器 192.168.0.4 有一个正在运行的 Web 服务器(OK)。
- 它正在监听 192.168.0.4:80 或 0.0.0.0:80(OK)。
- 可能正在运行的防火墙允许端口 80/tcp (未知) 上的传入连接。
关于最后一点 - 我不确定你的 iptables 规则是什么。请发布输出
sudo iptables -vL INPUT -n
如果确实允许 80/tcp 上的传入连接,但您无法从网络外部访问您的 Web 服务器,则您可能需要登录 Web 服务器并使用 tcpdump 捕获传入流量以查看是否有任何连接尝试到达它。
使用:
export ext_if=$(ip ro | awk '/^default via/ {print $5}')
sudo tcpdump -i ${ext_if} port 80
如果您尝试从网络外部连接到 Web 服务器时没有看到任何连接,则需要先修复该问题。
如果您计算机上的防火墙不允许传入连接到达端口 80/tcp,请运行以下命令修复此问题并验证:
sudo iptables -I INPUT -p tcp --dport 80 -j ACCEPT
更新:您还提到:
这是从运行服务器的同一台机器向我的公共 IP 发出请求后的 tcpdump 输出
这不太可能奏效。您的请求采用的路径是:
192.168.0.4 =>
<public_ip> (doing source and destination NAT, aka port forwarding) =>
192.168.0.4
正如您在 tcpdump 输出中看到的,无论您使用什么工具打开与 Web 服务器的连接,都会发起 3 个 HTTP 请求,路由器会通过设置了 RST(“重置”,即“离开,关闭连接”)标志的数据包进行响应来拒绝所有连接。
据我所知,许多提供 NAT 的设备不允许您从 NAT 后面的网络内部向其公共 IP 地址发起请求,然后通过端口转发(目标 NAT)返回到同一 NAT 后面的主机。
您应该尝试从网络外部发出请求。如果您没有可以登录并使用 wget/curl 发出请求的外部主机,请尝试使用许多基于 Web 的工具来执行此操作,例如http://www.infobyip.com/httpservertest.php
如果此方法有效,并且您获得的结果至少包含 HTTP 请求状态代码(即 200、302、404 等)和一些响应标头(例如 Server、Content-Type),则这将确认:
- 你的公共 IP 可以从外部访问
- 配置的端口转发有效
- 您的网络上的服务器确实接收了请求并对其做出响应。
如果您希望能够从同一网络内使用其公共 IP 访问您的 Web 服务器,您可以执行以下操作之一:
- 在您的 /etc/hosts 文件中添加适当的条目,将服务器的域名指向您的 Web 服务器的私有地址(临时破解)。
- 运行所谓的 split-dns 服务器(如果只是为了自己用的话,这是首选但不值得)
- 重新配置路由器以允许此类连接。这可以做到,但您的家用路由器(如果您有的话)不太可能做到这一点。