This post describes how I created a CentOS VM on a Windows 7 host with VMware Player.
Prerequisites
- VMware Player. At the moment of this writing, the free (non-commercial) version is VMware Workstation Player, version 12. I looked after the free products / downloads and picked the 64-bit version. At installation time, I was asked to provide a valid email address, which I did.
- CentOS ISO image. At the moment of this writing, the latest version is 7.x. I prefer the “Minimal ISO” image, because I like to know what I further need to install, depending on my needs.
Create VM
The wizard is pretty straight forward. I provid the path to the ISO image, which was duly detected as “CentOS 64-bit”. I choose a name for my VM and 40 GB of maximum disk size (single file). I further customize the VM to use 4GB of RAM and keep the rest of the default settings (particularly the NAT Network Adapter). No other customization for now, so I finish the wizard (which will power on my VM after creation).
When the VM starts, I am asked to download “VMware tools for Linux” for advanced features, which I decline (I do not want to make any other dependency on the visualization solution). So the VM boots and from now on the CentOS installation process starts. I select my time zone, confirm the automatic partitioning and fire up the minimal software installation. While the installation is in progress, I choose a root password and the creation of an administrator user (I prefer to “sudo” instead of “su”). At the end, I am asked to reboot the VM, which I do.
The VM boots fine and provides a login prompt. VMware totally captures the user input at this point, so to get out of the container running the VM guest, one needs to simultaneously press “Ctrl” and “Alt” (as it is also instructed in the bottom part of the container window).
Configure VM
My goal is to achieve a “development” VM, which can be used for running different services, but also with full internet access. In other words, two network interfaces: one for testing, open to full (internal) access, and one for tasks like software update, install new software, etc.
I already got a network interface (of type NAT) which could be used for internet access. Actually let’s see what was created:
$ ip addr
The output of the above command would show two interfaces: lo and enoxxx (for example, in my case, eno16777736). And the enoxxx interface would not have any IP address assigned. But the first thing to do is to is to establish a more appropriate communication way with the VM, that is using putty. And an IP address is needed for that, so:
$ sudo ifup eno16777736
$ ip addr
Now there is an IP address and a putty connection is possible and desirable (for example for copy-paste actions). Until putty, though, let’s restart the VM and when it comes back, the IP address vanished. To make it persistent:
$ cd /etc/sysconfig/network-scripts
$ sudo vi ifcfg-eno16777736
And change ONBOOT=yes. Now the IP address would survive a VM reboot.
Connectivity
So at this point I have a NAT interface, and as I can putty to it, it means at least SSH service is running and corresponding port open. But what else is open?
$ sudo yum install socat
$ sudo yum install wget
The above commands install two programs useful for testing connectivity (socat and wget) and the fact that the installation succeeds (which it did in my case) means that the NAT interface has access to internet. How about access from outside (besides SSH)?
$ socat tcp-listen:7777,reuseaddr -
The above command starts a TCP process which listens on port 7777. From a Windows command prompt (I had the telnet client installed via “Turn Windows features on and off”) I can execute:
>telnet 192.168.182.128 1234
The connection is established.
Firewall
My goal is to have to separate interfaces, one for (outgoing) internet access and one for (incoming) local access. So first thing, I add a new network adapter, of type “Host-only”, from “Virtual Machine Settings”. After completing the action, the VM will be automatically reconfigured and the new interface will appear when running:
$ ip addr
In my case the new interface is named eno33554984 and the IP address is already assigned (192.168.85.128) and survives a VM reboot. From now on I am using this IP for my putty connection. And the next step is to install and start the firewall SW:
$ yum install firewalld
$ sudo systemctl enable firewalld
$ sudo systemctl start firewalld
To check the status of the firewall:
$ firewall-cmd --state
At this point, we have the concept of “zones”, let’s explore it:
$ firewall-cmd --get-zones
$ firewall-cmd --get-default-zone
$ firewall-cmd --zone=public --list-all
The above commands reveal that there are some pre-configured zones (block, dmz, drop, external, home, internal, public, trusted and work – read documentation for the scope of each zone), a default zone (public) and the configuration of the default zone (for example SSH service). No network interface is bound to a particular zone.
If I will start the TCP service again, with socat, telnet connection to either network interface would fail. Because only ssh service is allowed on the default, public zone which for now applies to all network interfaces.
$ socat tcp-listen:7777,reuseaddr -
>telnet 192.168.182.128 7777
>telnet 192.168.85.128 7777
So let’s dedicate the “Host-only” network interface to internal access, where I can connect to any service.
$ ip addr
$ cd /etc/sysconfig/network-scripts
$ sudo vi ifcfg-eno33554984
And the content of the newly created script is:
IPADDR=192.168.85.128
NETMASK=255.255.255.0
ZONE=trusted
DEVICE=eno33554984
BOOTPROTO=none
ONBOOT=yes
Of course, the interface name and IP address are taken from the output of the “ip addr” command. Another important thing is the assigned ZONE (trusted). This does not mean that the 33554984 device is in that zone yet. For assigning the device to a zone, I execute:
$ sudo firewall-cmd --permanent --zone=trusted --change-interface=eno33554984
$ sudo firewall-cmd --reload
$ sudo ifdown eno33554984; sudo ifup eno33554984
$ firewall-cmd --zone=public --list-all
$ firewall-cmd --zone=trusted --list-all
$ firewall-cmd --get-active-zones
Note that the interface restart was done in “one-liner”, because I am connected to that network interface! Finally, I can remove all the services from the public zone:
$ sudo firewall-cmd --remove-service=dhcpv6-client --permanent
$ sudo firewall-cmd --remove-service=ssh --permanent
$ sudo firewall-cmd --reload
$ firewall-cmd --zone=public --list-all
I can check now that I can no longer ssh to the “public” network interface. I can also run the socat program again and check that I can only connect to the “trusted” network interface.
$ socat tcp-listen:7777,reuseaddr -
>telnet 192.168.182.128 7777
>telnet 192.168.85.128 7777
Finally, I can prove that I can only access internet from our “public” network interface.
$ wget google.com
$ ip addr
$ sudo ifdown eno16777736
$ wget google.com
$ sudo ifup eno16777736
The second wget command fails because the “public” network interface is down.
Appendix
Finally, a few useful commands for the VM:
$ sudo yum update
$ sudo yum install ntp ntpdate ntp-doc
$ sudo chkconfig ntpd on
$ sudo ntpdate pool.ntp.org