mirror of
https://github.com/microsoft/WSL.git
synced 2025-12-11 04:35:57 -06:00
Implement DNS tunelling support for WSLA (#13651)
This commit is contained in:
parent
cedbb94d36
commit
8b62d5a662
@ -16,6 +16,7 @@ Abstract:
|
|||||||
#include "hcs_schema.h"
|
#include "hcs_schema.h"
|
||||||
#include "NatNetworking.h"
|
#include "NatNetworking.h"
|
||||||
#include "WSLAUserSession.h"
|
#include "WSLAUserSession.h"
|
||||||
|
#include "DnsResolver.h"
|
||||||
|
|
||||||
using namespace wsl::windows::common;
|
using namespace wsl::windows::common;
|
||||||
using helpers::WindowsBuildNumbers;
|
using helpers::WindowsBuildNumbers;
|
||||||
@ -324,21 +325,33 @@ void WSLAVirtualMachine::ConfigureNetworking()
|
|||||||
else if (m_settings.NetworkingMode == WslNetworkingModeNAT)
|
else if (m_settings.NetworkingMode == WslNetworkingModeNAT)
|
||||||
{
|
{
|
||||||
// Launch GNS
|
// Launch GNS
|
||||||
|
// WSLA-TODO: Using fd=4 here seems to hang gns. There's probably a hardcoded file descriptor somewhere that's causing
|
||||||
|
// so using 1000 for now.
|
||||||
|
std::vector<WSLA_PROCESS_FD> fds(1);
|
||||||
|
fds[0].Fd = 1000;
|
||||||
|
fds[0].Type = WslFdType::WslFdTypeDefault;
|
||||||
|
|
||||||
WSLA_PROCESS_FD fd{};
|
std::vector<const char*> cmd{"/gns", LX_INIT_GNS_SOCKET_ARG, "1000"};
|
||||||
fd.Fd = 3;
|
|
||||||
fd.Type = WslFdType::WslFdTypeDefault;
|
// If DNS tunnelling is enabled, use an additional for its channel.
|
||||||
|
if (m_settings.EnableDnsTunneling)
|
||||||
|
{
|
||||||
|
fds.emplace_back(WSLA_PROCESS_FD{.Fd = 1001, .Type = WslFdType::WslFdTypeDefault});
|
||||||
|
cmd.emplace_back(LX_INIT_GNS_DNS_SOCKET_ARG);
|
||||||
|
cmd.emplace_back("1001");
|
||||||
|
cmd.emplace_back(LX_INIT_GNS_DNS_TUNNELING_IP);
|
||||||
|
cmd.emplace_back(LX_INIT_DNS_TUNNELING_IP_ADDRESS);
|
||||||
|
|
||||||
|
THROW_IF_FAILED(wsl::core::networking::DnsResolver::LoadDnsResolverMethods());
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<const char*> cmd{"/gns", LX_INIT_GNS_SOCKET_ARG, "3"};
|
|
||||||
WSLA_CREATE_PROCESS_OPTIONS options{};
|
WSLA_CREATE_PROCESS_OPTIONS options{};
|
||||||
options.Executable = "/init";
|
options.Executable = "/init";
|
||||||
options.CommandLine = cmd.data();
|
options.CommandLine = cmd.data();
|
||||||
options.CommandLineCount = static_cast<ULONG>(cmd.size());
|
options.CommandLineCount = static_cast<ULONG>(cmd.size());
|
||||||
|
|
||||||
std::vector<HANDLE> socketHandles(2);
|
|
||||||
|
|
||||||
WSLA_CREATE_PROCESS_RESULT result{};
|
WSLA_CREATE_PROCESS_RESULT result{};
|
||||||
auto sockets = CreateLinuxProcessImpl(&options, 1, &fd, &result);
|
auto sockets = CreateLinuxProcessImpl(&options, static_cast<DWORD>(fds.size()), fds.data(), &result);
|
||||||
|
|
||||||
THROW_HR_IF(E_FAIL, result.Errno != 0);
|
THROW_HR_IF(E_FAIL, result.Errno != 0);
|
||||||
|
|
||||||
@ -353,7 +366,11 @@ void WSLAVirtualMachine::ConfigureNetworking()
|
|||||||
|
|
||||||
// TODO: DNS Tunneling support
|
// TODO: DNS Tunneling support
|
||||||
m_networkEngine = std::make_unique<wsl::core::NatNetworking>(
|
m_networkEngine = std::make_unique<wsl::core::NatNetworking>(
|
||||||
m_computeSystem.get(), wsl::core::NatNetworking::CreateNetwork(config), std::move(sockets[0]), config, wil::unique_socket{});
|
m_computeSystem.get(),
|
||||||
|
wsl::core::NatNetworking::CreateNetwork(config),
|
||||||
|
std::move(sockets[0]),
|
||||||
|
config,
|
||||||
|
sockets.size() > 1 ? std::move(sockets[1]) : wil::unique_socket{});
|
||||||
|
|
||||||
m_networkEngine->Initialize();
|
m_networkEngine->Initialize();
|
||||||
|
|
||||||
|
|||||||
@ -99,6 +99,7 @@ struct _VIRTUAL_MACHINE_SETTINGS {
|
|||||||
BOOL EnableDebugShell;
|
BOOL EnableDebugShell;
|
||||||
BOOL EnableEarlyBootDmesg;
|
BOOL EnableEarlyBootDmesg;
|
||||||
BOOL EnableGPU;
|
BOOL EnableGPU;
|
||||||
|
BOOL EnableDnsTunnelling;
|
||||||
} VIRTUAL_MACHINE_SETTINGS;
|
} VIRTUAL_MACHINE_SETTINGS;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -520,6 +520,37 @@ class WSLATests
|
|||||||
VERIFY_ARE_EQUAL(RunCommand(vm.get(), {"/bin/grep", "-iF", "nameserver", "/etc/resolv.conf"}), 0);
|
VERIFY_ARE_EQUAL(RunCommand(vm.get(), {"/bin/grep", "-iF", "nameserver", "/etc/resolv.conf"}), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_METHOD(NATNetworkingWithDnsTunneling)
|
||||||
|
{
|
||||||
|
WSL2_TEST_ONLY();
|
||||||
|
|
||||||
|
WslVirtualMachineSettings settings{};
|
||||||
|
settings.CPU.CpuCount = 4;
|
||||||
|
settings.DisplayName = L"WSLA";
|
||||||
|
settings.Memory.MemoryMb = 2048;
|
||||||
|
settings.Options.BootTimeoutMs = 30 * 1000;
|
||||||
|
settings.Networking.Mode = WslNetworkingModeNAT;
|
||||||
|
settings.Networking.DnsTunneling = true;
|
||||||
|
|
||||||
|
auto vm = CreateVm(&settings);
|
||||||
|
|
||||||
|
// Validate that eth0 has an ip address
|
||||||
|
VERIFY_ARE_EQUAL(
|
||||||
|
RunCommand(
|
||||||
|
vm.get(),
|
||||||
|
{"/bin/bash",
|
||||||
|
"-c",
|
||||||
|
"ip a show dev eth0 | grep -iF 'inet ' | grep -E '[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}'"}),
|
||||||
|
0);
|
||||||
|
|
||||||
|
// Verify that /etc/resolv.conf is correctly configured.
|
||||||
|
auto [pid, in, out, err] = LaunchCommand(vm.get(), {"/bin/grep", "-iF", "nameserver ", "/etc/resolv.conf"});
|
||||||
|
|
||||||
|
auto output = ReadToString((SOCKET)out.get());
|
||||||
|
|
||||||
|
VERIFY_ARE_EQUAL(output, std::format("nameserver {}\n", LX_INIT_DNS_TUNNELING_IP_ADDRESS));
|
||||||
|
}
|
||||||
|
|
||||||
TEST_METHOD(OpenFiles)
|
TEST_METHOD(OpenFiles)
|
||||||
{
|
{
|
||||||
WSL2_TEST_ONLY();
|
WSL2_TEST_ONLY();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user