Wednesday, August 31, 2016

Permit samba to follow symbolic links to an unshared mount

I'm posting this because if you google for the answer you end up getting out of date answers and the wrong commands.

What I wanted to do was simply make a symbolic link from my samba shared directory /storage to /home.
server:/storage# ls -l /storage/
lrwxrwxrwx  1 root    root     5 Mar 13 14:14 home -> /home
drwxr-x---  4 michael users 4096 Mar  9 00:33 music
drwxr-xr-x  5 michael users 4096 Mar  9 00:33 photos

The Solution

Samba won't let users follow a symbolic link if the link points to a place outside of (i.e. not under) the share defined in smb.conf. This kind of symbolic link is insecure because a user could set up a symbolic link to point to anywhere in the file system and attain access to it. Yep, that's pretty appalling if you have users who you don't know or trust. But this is my home network, so user level security is not a concern for me.

The smb.conf man page explains it like so:
Turning this parameter on when UNIX extensions are enabled will allow UNIX clients to create symbolic links on the share that can point to files or directories outside restricted path exported by the share definition. This can cause access to areas outside of the share. Due to this problem, this parameter will be automatically disabled (with a message in the log file) if the unix extensions option is on.
The solution didn't even require google, I should have just read the manual to start off with. Here's the amendments to the smb.conf global section:
[global]
        # default
        follow symlinks = yes
        # allow symlinks
        wide links = yes
        # Must be off for wide links
        unix extensions = no 
After restarting samba, no problem.

Samba Security

A couple of tips relating to security. I use passwords on my accounts and disable the root user. Also, I make sure that if someone does gain access to the home network (somehow getting our WPA PSK), then only the permitted (authenticated) users can mount the Samba share.

My eth1 is excluded from the bind interfaces because eth1 is attached to a cable modem, effectively connecting the machine directly to the rest of the world. I don't want the samba server to make itself available to the Internet.

Note: Setting up user passwords and authentication is not described below.

[global]
        invalid users = root
        interfaces = eth0 eth2 lo
        bind interfaces only = yes

...

[storage]
comment = Storage
path = /storage
valid users = usera userb
guest ok = No
read only = No
browseable = Yes
available = Yes

Friday, August 12, 2016

VMware Player: NAT and DHCP - Customisation and Problem Troubleshooting

If you want to change the NAT network that VMware Player uses (by default it is 192.168.5.0/24) then there are a few tasks to do. It's not straightforward and for VMware Player, some of the steps are not well documented.


NAT and DHCP should work out of the box with VMware Player, no configuration necessary. However, there may come a time that you need to change the network; there are a few good reasons and if you're reading this then you know at least one of them.

When you hunt around on the internet for answers on this, most of the responses are to just configure bridging. Actually in a corporate environment, bridging may not make your network admins happy, or actually fail, depending on how tightly controlled the network is. Bridging is just like adding another host onto the network. NAT hides the VM behind the VMware Host.

The following changes worked for me on Windows 7 with VMware Player 7.1.0. I'm not going into detail on the exact syntax of the config files because if you don't understand subnets and the concept of interface binding then this howto is not for you. 

Set Up the Interface

On your host cd to install dir (C:\Program Files (x86)\VMware\VMware Player) and run the following commands.

Alternatively, you can change adapter and services through the normal networking services control panels.

The instructions rely on vmnet8 being the adapter for NAT. By default, VM Player installs two adapters, vmnet1 for the "Host-only" interface type and vmnet8 for the "NAT" interface type.

On Windows 7 and 10 at least, the vnetlib commands have to be run with elevated privileges.
vnetlib.exe -- stop nat
vnetlib.exe -- stop dhcp
vnetlib.exe -- set vnet vmnet8 mask 255.255.255.0
vnetlib.exe -- set adapter vmnet8 addr 192.168.207.1
vnetlib.exe -- update dhcp vmnet8
vnetlib.exe -- update nat vmnet8
vnetlib.exe -- update adapter vmnet8
vnetlib.exe -- start dhcp
vnetlib.exe -- start nat
Note: These changes may lead to your config files (mentioned later) being re-written.


Configure DHCP and NAT

Note that even if you intend to only use NAT with no DHCP, you must update the DHCP settings to match the new interface subnet range. I found that if there is something incorrect in either the NAT or DHCP config file, the config files reverted to the defaults. I am not exactly sure what sequence lead to that that, but I do know that it was as a result of having mismatched subnets in the configs.

On VMware Player, there appears to be no GUI for configuring the DHCP or NAT services. VMware Workstation does seem to have a GUI.

Edit these files instead:

C:\ProgramData\VMware\vmnetdhcp.conf
C:\ProgramData\VMware\vmnetnat.conf

In the NAT file, don't mess with the vmnet1 settings unless you intend to change the Host-only interface type. I've actually disabled vmnat1 via the Windows Control Panel; you don't need vmnet1 in my experience.

Then restart DHCP and NAT via the method above, or go to the services panel in windows and do it there.

The MAC that your VM will connect to is found here:

C:\ProgramData\VMware\vmnetnat-mac.txt 

Verification

Now you should be able to reach what we call in the industry "the internet", as long as you have routing and DNS set up properly on your Host and VM.

You can use Wireshark to capture on vmnet8 and check that packets from your VM to the Host are using the destination MAC specified in vmnetnat-mac.txt. Check that your VM has resolved the .2 address to this MAC and that this is the default route.

There is a hostMAC stanza in the vmnetnat.conf file that is actually telling the NAT service what the interface MAC of the NAT vmnet device is. That MAC is actually ignored by NAT. hostMAC seems to be there so that your Host to VM communication (ssh, https etc) is excluded from NAT. You will see this in the event log:
Using configuration file: C:\ProgramData\VMware\vmnetnat.conf.
IP address: 192.168.207.2
 Subnet: 255.255.255.0
External IP address: 0.0.0.0
Device: vmnet8.
MAC address: 00:50:56:F1:77:9F.
Ignoring host MAC address: 00:50:56:C0:00:08.
The "MAC address" above is what your VM uses as the gateway:
# arp -an
? (192.168.207.2) at 00:50:56:f1:77:9f [ether] on eth0
In other words, the IP .1 is for host to VM communication and .2 is for NAT traffic.  

VMNetDHCP Errors in Event Viewer 

No subnet declaration for VMnet8 (192.168.207.2).  Please write a subnet declaration for the network segment to which interface VMnet8 is attached.
The network interface vmnet8 is in a different subnet to what you've configured in the DHCP config file.
Address range 192.168.178.128 to 192.168.207.254, netmask 255.255.255.0 spans multiple subnets!
You've written something pretty odd in the DHCP config file.
Important! Errors can lead to your config files being re-written.

VMware Player 7.1.4 Upgrade

After an install VMware Player 7.1.4 I could no longer connect from my workstation to the machines in the VM network.

Note that something weird is up with this install, after the install process WMware Player insists that the version is 6.0.7 build-2844087, yet when I run the "Help -> Software Updates" process it declares that my version is up to date (7.1.4 is the latest).

The workstation's VMnet8 adapter was statically set by the vnetlib.exe command earlier. But it is also specified in vmnetdhcp.conf. Although the adapter had a static address, it appeared to be using a "169.254.0.0" address, which generally indicates a failure to pick up a DHCP address. 

Switching the adapter setting back to DHCP immediately picked up the address defined in vmnetdhcp.conf, namely:
host VMnet8 {
    hardware ethernet 00:50:56:C0:00:08;
    fixed-address 192.168.207.1;
    option domain-name-servers 0.0.0.0;
    option domain-name "";
    option routers 0.0.0.0;
}
Things were working again after that.

Previous Upgrade Problems

On an upgrade to 7.1.3 build-3206955 I could SSH to my VMs, but they could not get out to the rest of the world, so it looked like a NAT problem.

The ARP table on the VM revealed that it was using the actual MAC of the VMnet8 interface for the .2 (NAT) address. The ARP for .2 should have had a virtual MAC for that virtual NAT IP. I call it virtual because the IP itself doesn't exist in the configuration of any interface on the Host (Windows in this case).

There were three problems. The first two were related to the upgrade and VMWare stomping over my custom config.

First, the DHCP stanza of the VMnet8 binding did not overlap the "Virtual ethernet segment 8" range. The subnet range had reverted to the default.

Second, the MAC of the NAT address had changed and may not have been represented correctly in vmnetnat-mac, I'm actually not 100% certain what happened here because I think that file is automatically updated after a VMWare NAT service restart, meaning that it's not actually configurable, just informational.

My corrected vmnetdhcp.conf:
# Virtual ethernet segment 8
# Added at 11/27/15 13:02:31
subnet 192.168.207.0 netmask 255.255.255.0 {
range 192.168.207.128 192.168.207.254; # default allows up to 125 VM's
option broadcast-address 192.168.207.255;
option domain-name-servers 192.168.207.2;
option domain-name "localdomain";
option netbios-name-servers 192.168.207.2;
option routers 192.168.207.2;
default-lease-time 1800;
max-lease-time 7200;
}
host VMnet8 {
hardware ethernet 00:50:56:C0:00:08;
fixed-address 192.168.207.1;
option domain-name-servers 0.0.0.0;
option domain-name "";
option routers 0.0.0.0;
}
# End
The third problem was that I had statically set the IP address of "VMware Virtual Ethernet Adapter for VMnet" in Windows, which is a bad idea because it should be left at DHCP and then controlled via the vmnetdhcp.conf file. Make sure that the "hardware ethernet" MAC is correct (use "ipconfig /all" to see the MAC in Windows cmd prompt).

Something a bit odd. My Wireshark doesn't see the VMnet interfaces anymore. I can't capture on them. I don't know whether that's related to Wireshark, Windows or VMPlayer though.

Thursday, August 4, 2016

Wireshark's weird ESP dissection

I recently observed Wireshark telling me obviously false information about the contents of ESP payloads. While the fix to that was trivial, the information learned in the process was worth noting down.
Wireshark was parsing many ESP payloads in the pcap and trying to make sense of the data therein. The result was columns of nonsensical frames. Antique protocols interspersed with more recognisable ones.

ESP, like AH, encapsulates the data between hosts communicating over an IPsec connection. There is no way Wireshark could have known what the contents were because the Security Associations were established to use encryption. You can tell Wireshark the keys behind SPIs as long as the ciphers matched a supported set.

The reason that this was happening was due to this setting being enabled:
Edit -> Preferences -> Protocols -> ESP -> "Attempt to detect/decode NULL encrypted ESP payloads"
It's off by default so apparently I'd enabled this long ago and completely forgotten.

The "Personal configuration" config file behind user preferences can also be easily seen by going to:
Help -> About Wireshark -> Folders
Specifically this, for the setting under discussion this should be the default setting:
# This is done only if the Decoding is not SET or the packet does not belong to a SA. Assumes a 12 byte auth (HMAC-SHA1-96/HMAC-MD5-96/AES-XCBC-MAC-96) and attempts decode based on the ethertype 13 bytes from packet end
# TRUE or FALSE (case-insensitive)
#esp.enable_null_encryption_decode_heuristic: FALSE
This is what I had:
esp.enable_null_encryption_decode_heuristic: TRUE
One fascinating aspect is, as I infer from the comment in the prefs file, that if the packet capture doesn't have the ESP negotiation (IKE phase 2) then Wireshark assumes that the ESP is using NULL encryption. If the first bytes of the ESP payload then matches a protocol, then the invoked protocol dissector will valiantly pick through an ESP stream-of-consciousness and will (often) throw up its hands, declaring the payload of the triggered protocol as invalid. Sometimes, ESP just appears as ESP because the payload matches no protocol known to Wireshark.

I think this would work much better as a Wireshark right-click option in the "packet list" pane to 'Decode ESP stream as NULL encryption'. This would reduce pointlessly attempting to decode every ESP packet in a packet capture and as a result speed up load times when opening a pcap with this user preference in place.

With Wireshark, beautiful product that it is, you get what you're given!