Sharing folders between Linux host and Windows guest - KVM, VirtManager (SAMBA)

I want to set up shared directory between Linux host and Windows guest in VirtManager (KVM/QEMU).
I don’t have much experience with virtual machines and with the networking. After some research I went with samba, and so far I have smbd running, and allowed by firewall. smb.conf contain:

[sambashare]
    comment = VM_Share
    path = /media/user/device_label/vm_share
    valid users = user
    public = no
    browsable = yes
    writable = yes
    printable = no

I also created samba account and password with: sudo smbpasswd -a username

As of now the guest OS in VirtManager have NIC configured with:

Network source: Virtual network 'default' : NAT
Device model: e1000e
MAC adress: xx:xx:xx:xx:xx:xx
IP address: Unknown
Link state: active

But with this config Windows dont have access to the web. Local Area Connection Status shows no IPv4 or IPv6 access.

I don’t want Windows to access the internet, except the samba share. So here goes my question, how should I set up networking between host and guest to do so?
Thank you for any help.

NAT is probably the problem, libvirt is using some networking magic to connect your guest to the hosts’ network connection.

Easiest solution involves two network cards in the host. One for the host itself, one to be shared by the guest(s). On the shared card, you setup a bridge device, and assign that using vfio to your guest. On the host card, you don’t need to change anything.

If you only have one card, you could check if it supports SR-IOV.

1 Like

I know its certainly possible to be able to access a samba share through a virtual nic.

I peronsally never used the e1000 before in the past. I’ve always used the virtio device instead. (Maybe check all drivers are working and installed on the guest if you have no other choice?)

Note going host, then bridged will almost never work.

Blocking internet to the host? Hmmm, block through router? Likely the easiest, good chance there is a way to do it through the virtual device I imagine.

1 Like

I think this one describes it well with with screenshots: Host-only Networking in KVM | Brock McElroy

1 Like

@risk unfortunately version of VirtManager in screenshots is different than the latest one. There is no Network Interfaces tab present in newest release.

@emma.concrete VirtManager is defaulting to e1000 every time I try to set it to anything else. Don’t know exactly why. Virtio doesn’t work for me with storage either - Windows 7 installer doesn’t detect .qcow2 volume connected with virtio when prompting for install location. When I change virtio to SATA the volume is detected without a problem.
As for blocking internet connection I will try the following as soon as I got connection working:
https://libvirt.org/firewall.html

@gordonthree thanks. I have two NICs on motherboard, so I assume it is a perfect fit for this?
I’ve done basic research on how to set up bridge networking on the distro im running (Debian) and found couple straight forward manuals:

https://wiki.libvirt.org/page/Networking#Altering_the_interface_config
https://jamielinux.com/docs/libvirt-networking-handbook/bridged-network.html

So supposedly I have two NICs with eth0 and eth1 interfaces. I want eth0 to be bridged to br0 for VM, and eth1 to serve as host device only. Will this setup work? I don’t use Network Manager or wicd.

/etc/network/interfaces:

# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

source /etc/network/interfaces.d/*

# The loopback network interface
auto lo
iface lo inet loopback

/etc/network/interfaces.d/br0 VM bridge:

## DHCP ip config file for br0 ##
auto br0
 
# Bridge setup
allow-hotplug br0
iface br0 inet dhcp
    bridge_ports eth0

/etc/network/interfaces.d/eth1 host:

## DHCP ip config file for eth1 ##
auto eth1
 
# Host setup
allow-hotplug eth1
iface eth1 inet dhcp

I’m not super skilled with Debian-style network configs, I admit I use NetworkManager under Fedora :grinning_face_with_smiling_eyes:

However, one observation - you don’t want to assign the bridge an IP address. It doesn’t need one to be used by the guests and you don’t want the host using it for anything.

iface br0 inet manual
1 Like

Oh. So going with manual like this?

## static ip config file for br0 ##
auto br0
allow-hotplug br0
iface br0 inet static
	address 192.168.2.23
	broadcast 192.168.2.255
	netmask 255.255.255.0
	gateway 192.168.2.254
	# If the resolvconf package is installed, you should not edit 
        # the resolv.conf configuration file manually. Set name server here
        #dns-nameservers 192.168.2.254
        # If you have muliple interfaces such as eth0 and eth1
        # bridge_ports eth0 eth1  
	bridge_ports eth0
	bridge_stp off       # disable Spanning Tree Protocol
        bridge_waitport 0    # no delay before a port becomes available
        bridge_fd 0          # no forwarding delay

this should be all you need - the idea is, this interface is for your guests to use. you don’t want the host using it too, you want your host using your other interface.

## static config file for br0 ##
auto br0
allow-hotplug br0
iface br0 inet manual
        # If you have muliple interfaces such as eth0 and eth1
        # bridge_ports eth0 eth1  
	bridge_ports eth0
	bridge_stp off       # disable Spanning Tree Protocol
        bridge_waitport 0    # no delay before a port becomes available
        bridge_fd 0          # no forwarding delay
1 Like

For virtio to work, you will need to get the virtio driver disc. virtio-win-pkg-scripts/README.md at master · virtio-win/virtio-win-pkg-scripts · GitHub

Add the virtio iso to your virtual machine as a second cd rom
When installing windows 7, when you get to the hard drive selection screen, choose load driver, and navigate to virtio storage, windows 7 folder, and install the appropriate x86/x64 drivers.
And e1000 is always the default, but once you install windows, you can change to virtio network and start windows and again use the virtio disc to find the network drivers.

2 Likes

Thanks @xavier01. I tried to make it working, but it seems that Windors 7 have problems with virtio. I get message with No signed device drivers were found. Make sure that the installation media contains the correct drivers, and then click OK. - exactly as in this thread: Windows 7 VirtIO Drivers will not install - VM Engine (KVM) - Unraid
If there is no other option, I’ll need to switch to W8 or W10.

@gordonthree - your advice was spot on. I managed to set up network with it, and now the VM have network access.

Done that I tried to connect samba share, but I done something wrong, because there is no share visible. On host machine:

smbtree:

smbc_opendir: No such file or directory

testparm smb.conf:

Load smb config files from smb.conf
Error loading services.

smbstatus:

No locked files

In /etc/smb.conf aside from adding [sambashare] record in first post I changed only interfaces = 127.0.0.0/8 eth0 to interfaces = 127.0.0.0/8 eth1 as eth0 is a bridge to br0.

If this is relavant the shared folder is on another drive mounted in /media/user/device_label/vm_share

Just to beeing sure if the daemon is running i tested smbd with echo "hello" | telnet localhost 139 and get:

Trying ::1...
Connected to localhost.
Escape character is '^]'.
Connection closed by foreign host.

Here is the testparm dump:

~$ testparm
Load smb config files from /etc/samba/smb.conf
Loaded services file OK.
Weak crypto is allowed
Server role: ROLE_STANDALONE

Press enter to see a dump of your service definitions

# Global parameters
[global]
	log file = /var/log/samba/log.%m
	logging = file
	map to guest = Bad User
	max log size = 1000
	obey pam restrictions = Yes
	pam password change = Yes
	panic action = /usr/share/samba/panic-action %d
	passwd chat = *Enter\snew\s*\spassword:* %n\n *Retype\snew\s*\spassword:* %n\n *password\supdated\ssuccessfully* .
	passwd program = /usr/bin/passwd %u
	server role = standalone server
	unix password sync = Yes
	usershare allow guests = Yes
	idmap config * : backend = tdb


[sambashare]
	comment = VM_Share
	path = /media/user/device_label/vm_share
	read only = No
	valid users = user

The smb.conf file also contains:

   workgroup = WORKGROUP
;   interfaces = 127.0.0.0/8 eth1
;   bind interfaces only = yes

Listing shares with smbclient -L 127.0.0.1 -U user gets:

session setup failed: NT_STATUS_CONNECTION_DISCONNECTED

I fixed some mistakes in my smb.conf and testparm is not showing any errors anymore.
And now I can detect at least something:

smbclient -L 127.0.0.1 returns:

Enter WORKGROUP\user's password: 

	Sharename       Type      Comment
	---------       ----      -------
	vm_share        Disk      vm_share
	IPC$            IPC       IPC Service (user server)
SMB1 disabled -- no workgroup available

nmblookup -S __SAMBA__ gives me:

192.168.88.17 *<00>
Looking up status of 192.168.88.17
	USER            <00> -         B <ACTIVE> 
	USER            <03> -         B <ACTIVE> 
	USER            <20> -         B <ACTIVE> 
	WORKGROUP       <00> - <GROUP> B <ACTIVE> 
	WORKGROUP       <1e> - <GROUP> B <ACTIVE> 

	MAC Address = 00-00-00-00-00-00

But smbstatus and smbtree are still giving me previous results.
Windows VM cannot detect either Linux host nor shared folder. I tried with navigating in File Explorer and with mapping network drive with \\192.168.88.17\vm_share but Windows shows me following network error:

The mapped network drive could not be created because the following error has occured:
The specified server cannot perform the requested operation.

Any ideas? :thinking: :thonk: :gigathink:

just make another interface.

First, create a file and filled it with this

<network>
    <name>isolated</name>
   <ip address='192.168.254.1' netmask='255.255.255.0'>
       <dhcp>
             <range start='192.168.254.2' end='192.168.254.254' />
      </dhcp>
    </ip>
</network>

Then

sudo virsh net-define /anyplace/file-isolated.xml
sudo virsh net-autostart isolated
sudo virsh net-start isolated

Now it is time to make some iptables rules.
BTW, my iptables has policy DROP by default.
The interface you can change by your VM interface’s name

INPUT IPTABLES RULES
-A INPUT -i virbr1 -s 192.168.254.0/24 -p udp --dport 137:138 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
-A INPUT -i virbr1 -s 192.168.254.0/24 -p tcp --dport 139 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
-A INPUT -i virbr1 -s 192.168.254.0/24 -p tcp --dport 445 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT

OUTPUT IPTABLES RULES
-A OUTPUT -o virbr1 -d 192.168.254.0/24 -p udp --sport 137:138 -m conntrack --ctstate ESTABLISHED -j ACCEPT
-A OUTPUT -o virbr1 -d 192.168.254.0/24 -p tcp --sport 139 -m conntrack --ctstate ESTABLISHED -j ACCEPT
-A OUTPUT -o virbr1 -d 192.168.254.0/24 -p udp --sport 445 -m conntrack --ctstate ESTABLISHED -j ACCEPT

Thats all.

You can see my posts about this on my personal blog. It is in Spanish, but you can translate them.

Don’t forget to add that virtual interface to your samba conf file.

PD: any mistake in English I’m learning that language

Hi @Mauricio , thanks for the advice.

I assume that you mean replacing br0 with this new interface?
In iptables you have virbr1 - does that mean it is neccessary to create that interface in /etc/network/interfaces?
How is network name “isolated” connected to interface name like virbr1 then?

Sorry for that kind of questions. Like I said I’m not very good with networking.

After recent update. nmblookup -S __SAMBA__ gives new record with MSBRROWSE:

192.168.88.12 __SAMBA__<00>
Looking up status of 192.168.88.12
	REX-PC          <00> -         B <ACTIVE> 
	REX-PC          <03> -         B <ACTIVE> 
	REX-PC          <20> -         B <ACTIVE> 
	..__MSBROWSE__. <01> - <GROUP> B <ACTIVE> 
	WORKGROUP       <00> - <GROUP> B <ACTIVE> 
	WORKGROUP       <1d> -         B <ACTIVE> 
	WORKGROUP       <1e> - <GROUP> B <ACTIVE> 

	MAC Address = 00-00-00-00-00-00

smbtree -d3:

lp_load_ex: refreshing parameters
Initialising global parameters
rlimit_max: increasing rlimit_max (1024) to minimum Windows limit (16384)
Processing section "[global]"
interpret_interface: using netmask value 8 from config file on interface lo
added interface lo ip=127.0.0.1 bcast=127.255.255.255 netmask=255.0.0.0
interpret_string_addr_internal: getaddrinfo failed for name br0 (flags 32) [Name or service not known]
interpret_interface: Can't find address for br0
lp_load_ex: refreshing parameters
Initialising global parameters
rlimit_max: increasing rlimit_max (1024) to minimum Windows limit (16384)
lp_load_ex: refreshing parameters
Initialising global parameters
rlimit_max: increasing rlimit_max (1024) to minimum Windows limit (16384)
Processing section "[global]"
lp_load_ex: refreshing parameters
interpret_interface: using netmask value 8 from config file on interface lo
added interface lo ip=127.0.0.1 bcast=127.255.255.255 netmask=255.0.0.0
interpret_string_addr_internal: getaddrinfo failed for name br0 (flags 32) [Name or service not known]
interpret_interface: Can't find address for br0
Using netbios name USER.
Using workgroup WORKGROUP.
name_resolve_bcast: Attempting broadcast lookup for name __MSBROWSE__<0x1>
Got a positive name query response from 127.0.0.1 ( 192.168.88.12 )
tdb(/run/samba/gencache.tdb): tdb_open_ex: could not open file /run/samba/gencache.tdb: Permission denied
resolve_lmhosts: Attempting lmhosts lookup for name WORKGROUP<0x1d>
name_resolve_bcast: Attempting broadcast lookup for name WORKGROUP<0x1d>
Got a positive name query response from 127.0.0.1 ( 192.168.88.12 )
Connecting to 192.168.88.12 at port 445
Connecting to 192.168.88.12 at port 139
Connecting to 192.168.88.12 at port 445
Connecting to 192.168.88.12 at port 139
Context 0x55c93fda65c0 successfully freed