google云平台:无法启动javahttps服务器
google cloud platform: cannot start java https server
下面的简单程序:
import com.sun.net.httpserver.HttpsServer;
import java.net.InetSocketAddress;
class SimpleServer {
public static void main(String[] pArgs) {
try {
HttpsServer s = HttpsServer.create(new InetSocketAddress(443), 0);
System.out.println(" " + s);
} catch (Exception pE) {
throw new RuntimeException("Could not create HTTPS server", pE);
}
}
}
将无法在由 google 云平台(Google Compute Engine - IaaS)托管的 Debian VM 中运行:
Exception in thread "main" java.lang.RuntimeException: Could not create HTTPS server
at SimpleServer.main(SimpleServer.java:10)
Caused by: java.net.SocketException: Permission denied
at sun.nio.ch.Net.bind0(Native Method)
at sun.nio.ch.Net.bind(Net.java:433)
at sun.nio.ch.Net.bind(Net.java:425)
at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:223)
at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:74)
at sun.net.httpserver.ServerImpl.<init>(ServerImpl.java:100)
at sun.net.httpserver.HttpsServerImpl.<init>(HttpsServerImpl.java:50)
at sun.net.httpserver.DefaultHttpServerProvider.createHttpsServer(DefaultHttpServerProvider.java:39)
at com.sun.net.httpserver.HttpsServer.create(HttpsServer.java:90)
at SimpleServer.main(SimpleServer.java:7)
当 Windows 桌面上的 运行 以及我们将端口从 443 更改为其他端口时,此示例将起作用。那么我们如何强制 google 云允许 443 上的服务器呢?我试过打开防火墙,但没有用(不是说它真的应该有 :-( 因为这是一个单独的问题)。
java 版本是(尽管我怀疑这是否重要):
openjdk version "1.8.0_141"
OpenJDK Runtime Environment (build 1.8.0_141-8u141-b15-1~deb9u1-b15)
OpenJDK 64-Bit Server VM (build 25.141-b15, mixed mode)
这不是 GCP 问题,而是 linux/Unix 安全功能。
linux/Unix 上低于 1024 的端口是 "privileged ports",需要提升权限才能创建。
在 GCP 中,您有多种选择。
作为非特权用户使用 1024 以上的高端口并且:
- 连接到您 url https://foo:8443
中的那个高端口
- 使用GCP网络或HTTP/HTTPS负载均衡器将端口443转发到高端口
- 利用 IP 表将数据包从 443 转发到 VM 实例内的高端口
- 运行 使用 suid、sudo 或其他方法的服务
- 授予进程 _CAP_NET_BIND_SERVICE_ 能力(7)。
最后两个选项具有复杂的安全隐患,应尽可能避免。
下面的link将涵盖上述的一些选项,但第一个选项最简单,但比后两个选项安全得多。
https://debian-administration.org/article/386/Running_network_services_as_a_non-root_user.
下面的简单程序:
import com.sun.net.httpserver.HttpsServer;
import java.net.InetSocketAddress;
class SimpleServer {
public static void main(String[] pArgs) {
try {
HttpsServer s = HttpsServer.create(new InetSocketAddress(443), 0);
System.out.println(" " + s);
} catch (Exception pE) {
throw new RuntimeException("Could not create HTTPS server", pE);
}
}
}
将无法在由 google 云平台(Google Compute Engine - IaaS)托管的 Debian VM 中运行:
Exception in thread "main" java.lang.RuntimeException: Could not create HTTPS server
at SimpleServer.main(SimpleServer.java:10)
Caused by: java.net.SocketException: Permission denied
at sun.nio.ch.Net.bind0(Native Method)
at sun.nio.ch.Net.bind(Net.java:433)
at sun.nio.ch.Net.bind(Net.java:425)
at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:223)
at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:74)
at sun.net.httpserver.ServerImpl.<init>(ServerImpl.java:100)
at sun.net.httpserver.HttpsServerImpl.<init>(HttpsServerImpl.java:50)
at sun.net.httpserver.DefaultHttpServerProvider.createHttpsServer(DefaultHttpServerProvider.java:39)
at com.sun.net.httpserver.HttpsServer.create(HttpsServer.java:90)
at SimpleServer.main(SimpleServer.java:7)
当 Windows 桌面上的 运行 以及我们将端口从 443 更改为其他端口时,此示例将起作用。那么我们如何强制 google 云允许 443 上的服务器呢?我试过打开防火墙,但没有用(不是说它真的应该有 :-( 因为这是一个单独的问题)。
java 版本是(尽管我怀疑这是否重要):
openjdk version "1.8.0_141"
OpenJDK Runtime Environment (build 1.8.0_141-8u141-b15-1~deb9u1-b15)
OpenJDK 64-Bit Server VM (build 25.141-b15, mixed mode)
这不是 GCP 问题,而是 linux/Unix 安全功能。
linux/Unix 上低于 1024 的端口是 "privileged ports",需要提升权限才能创建。
在 GCP 中,您有多种选择。
作为非特权用户使用 1024 以上的高端口并且:
- 连接到您 url https://foo:8443 中的那个高端口
- 使用GCP网络或HTTP/HTTPS负载均衡器将端口443转发到高端口
- 利用 IP 表将数据包从 443 转发到 VM 实例内的高端口
- 运行 使用 suid、sudo 或其他方法的服务
- 授予进程 _CAP_NET_BIND_SERVICE_ 能力(7)。
最后两个选项具有复杂的安全隐患,应尽可能避免。
下面的link将涵盖上述的一些选项,但第一个选项最简单,但比后两个选项安全得多。
https://debian-administration.org/article/386/Running_network_services_as_a_non-root_user.