Linux
為遠端桌面設置 xdmcp 強制 udp v4
我正在嘗試將遠端桌面設置為 Debian 伸展發行版,我設置了文件
/etc/gdm3/daemon.conf
.[daemon] WaylandEnable = false [security] DisallowTCP = false [xdmcp] Enable = true Port = 177 [chooser] [debug] # Uncomment the line below to turn on debugging # More verbose logs # Additionally lets the X server dump core if it crashes Enable = true
但是當我重新啟動 debian 系統時,我在 netstat 上看到以下輸出:
udp6 0 0 :::177 :::* 11059/gdm3
那是使用udp6而不是udp4。
我嘗試使用以下行將 inet6 禁用到系統中
/etc/sysctl.conf
:net.ipv6.conf.all.disable_ipv6 = 1 net.ipv6.conf.default.disable_ipv6 = 1 net.ipv6.conf.lo.disable_ipv6 = 1
我用 刷新設置
sysctl -p
,然後用 重新啟動服務sudo init 3; sudo unit 5
,但沒有任何改變。我什至重新啟動了虛擬機,但還是一樣。知道如何強制 xdcmp 監聽 UDP v4 而不是 udp6 嗎?提前致謝。
我這樣做是為了找出另一台具有相同 linux 發行版的機器所需的設置,我想在其中設置對桌面的遠端訪問(所以,我會遇到同樣的問題)。實際上我可以通過執行到另一台主機的 xvnc 訪問,但我想設置 xdmcp 以請求遠端訪問登錄。
我正在執行的確切系統:
$ lsb_release -a No LSB modules are available. Distributor ID: Debian Description: Debian GNU/Linux 9.4 (stretch) Release: 9.4 Codename: stretch $ apt-cache show gdm3 Package: gdm3 Version: 3.22.3-3+deb9u1 . . .
我想我已經找到了我的問題的答案。我已經下載了 gdm3 的原始碼,並且找到了為 xdmcp 設置套接字的位置。
static gboolean open_port (GdmXdmcpDisplayFactory *factory) { struct sockaddr_storage serv_sa = { 0 }; g_debug ("GdmXdmcpDisplayFactory: Start up on host %s, port %d", factory->priv->hostname ? factory->priv->hostname : "(null)", factory->priv->port); /* Open socket for communications */ #ifdef ENABLE_IPV6 factory->priv->socket_fd = do_bind (factory->priv->port, AF_INET6, &serv_sa); if (factory->priv->socket_fd < 0) #endif factory->priv->socket_fd = do_bind (factory->priv->port, AF_INET, &serv_sa); if G_UNLIKELY (factory->priv->socket_fd < 0) { g_warning (_("Could not create socket!")); return FALSE; } fd_set_close_on_exec (factory->priv->socket_fd); if (factory->priv->use_multicast) { setup_multicast (factory); } return TRUE; }
在這裡可以看出,如果包被建構為支持 IP6 並且綁定操作正確完成,套接字將只偵聽 UDP6,而不是 UDP4。
解決方案應該是在不支持 IP6 的情況下重建包,或修改原始碼,以便包含一個新參數以從文件中啟用/禁用 IP6
/etc/gdm3/daemon.conf
。從評論中更新了更多資訊。
static int create_socket (struct addrinfo *ai) { int sock; sock = socket (ai->ai_family, ai->ai_socktype, ai->ai_protocol); if (sock < 0) { g_warning ("socket: %s", g_strerror (errno)); return sock; } #if defined(ENABLE_IPV6) && defined(IPV6_V6ONLY) if (ai->ai_family == AF_INET6) { int zero = 0; if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &zero, sizeof(zero)) < 0) g_warning("setsockopt(IPV6_V6ONLY): %s", g_strerror(errno)); } #endif if (bind (sock, ai->ai_addr, ai->ai_addrlen) < 0) { g_warning ("bind: %s", g_strerror (errno)); close (sock); return -1; } return sock; }
我們可以在 proc 文件系統中看到以下內容:
$ cat /proc/sys/net/ipv6/bindv6only 0
因此,看起來沒有進行雙重綁定。應該是因為定義了 IPV6_V6ONLY。
在沒有 ip6 支持的情況下重建包後:
udp 0 0 0.0.0.0:177 0.0.0.0:* -