This was a pretty fun project that I had gotten so I figured I would share the experience. There are multiple use cases for virtual desktops. In our case, it’s ephemeral – only need them for a few days for a class so that all students can share the same experience without the need for anything but a web browser. They can probably get a better experience with the PCoIP client, but it could be against some company policies. Most companies will allow HTTPs out, so we figured this would be the easiest way.
The way Amazon WorkSpaces works is that each desktop is assigned to a single user and the users sit in the directory service. The service I’m using is the Simple AD (Samba 4) as I had no need for a huge directory. To create the users, we will just need a UID (sAMAccountName in AD) and a password if using the API to create the desktops. If using the Amazon portal to create the desktops, you’ll need the first and last name and an email address as well. You can easily import a CSV file with this information, but for the sake of simplicity, I just use a generic account name and numbers.
After creating the directory and starting up a single desktop, I went to the “Programs” in the Control Panel and “Turn Windows Features on and off” and “Features” to install the “AD DS and AD LDS Tools”. More information on the RSAT tools is available here: https://wiki.samba.org/index.php/Installing_RSAT
Here’s a short video on how to do it:
Once the RSAT tools are installed, the “dsadd” command will be available to add users. This is the script I’m using that asks for the users and then creates the users:
set /p users=Number of users to create:
echo "Creating %users% students"
set /a count+=1
echo creating student%count%
dsadd user "cn=student%count%,cn=users,dc=corp,dc=amazonworkspaces,dc=com" -samid student%count% -pwd Student%count%
if "%count%"=="%users%" goto done
The script will create users with the username student# with passwords Student# – the capital “S” is just for password complexity.
After creating the users, we can go and create the desktops. To do this, I used awscli. On a Mac or Linux system, it can be easily installed running “easy_install awscli”. After installation, there will be a config and credentials file that should be configured in the .aws directory in your home directory. Once that’s set, you can check to see what workspaces you have by running “aws workspaces describe-workspaces” – that gives you an idea of what your workspaces look like. The minimal template I’m using for workspaces looks like this:
The DirectoryId is the directory service where the users are housed, I’ll be replacing the %username% with student#, and I added RunningMode just to save on costs – they’ll automatically suspend after an hour of idling. It takes about 90s to spin back up if they suspend. The BundleId is the VM that you want to provision. This one is the customized one for our classroom.
With the template in place, we’re ready to run the script:
echo "Number of Desktops to Create [20?]"
while [ $COUNTER -lt $desktops ]; do
echo Creating Desktop number $COUNTER
sed "s/%username%/student$COUNTER/g" create-workspaces.json > /tmp/student$COUNTER.json
aws workspaces create-workspaces --cli-input-json file:///tmp/student$COUNTER.json
echo Created $desktops Desktops.
You can remove the temporary files in /tmp afterwards.
You can install IPFilter from https://www-01.ibm.com/marketing/iwm/iwm/web/reg/pick.do?source=aixbp. It will require a login, but not a serial number. Just create a login and download. Installing IPFilter is a little different. It installs like an AIX package, with installp. Unzip the contents of the IPFilter_Fileset.zip and go into the IPFilter_Fileset directory and run the following commands:
If you’ve got a *Nix machine on the public Internet, you will experience this at one time or another. If you run sshd on its’ known port 22, some script kiddie out there will attack it. With that, you’ll see that you’ll have a bunch of connections that probably and hopefully will never succeed. I saw these messages in my /var/log/auth.log:
Nov 15 06:44:26 chunli sshd: Failed password for root from 184.108.40.206 port 41751 ssh2
Nov 15 06:44:26 chunli sshd: Failed password for root from 220.127.116.11 port 41921 ssh2
Nov 15 06:44:26 chunli sshd: Failed password for root from 18.104.22.168 port 42948 ssh2
Nov 15 06:44:26 chunli sshd: message repeated 2 times: [ Failed password for root from 22.214.171.124 port 27586 ssh2]
I’ve experienced this before and to alleviate this problem, I used sshdfilter in the past. I know that there are others out there like sshblack that can do blacklisting of attackers or one of the easiest ways to alleviate this problem is just to run ‘sudo ufw limit ssh’. This is a way to block them from coming back for a while.
To get started, first stop SSH:
sudo initctl stop ssh
Then move /etc/init/ssh.conf out. We’ll start SSH with sshdfilter instead.
You’ll get a message in the auth.log here:
auth.log:Nov 16 19:54:36 chunli sshd: Missing privilege separation directory: /var/run/sshd
Because of this, we’ll just add a line in the /etc/init.d/sshdfilter file like this:
Under the “Add a block rule” section, I changed some iptables commands to ufw commands. You can see the comments ones here:
#firewalladd='iptables -A $chain -p tcp -s $ip --dport 22 -j DROP'
#firewalladd='iptables -A $chain -p tcp -s $ip --dport 22 -j DROP'
firewalladd='ufw insert 1 reject proto tcp from $ip to any port 22'
# Delete a block rule:
firewalldel='ufw delete reject proto tcp from $ip to any port 22'
#firewalldel='iptables -D $chain -p tcp -s $ip --dport 22 -j DROP'
That’s about it! With that, my machine started to grow a big list of IP addresses to block from failed logins.
I ran into issues with Bind 9 on Ubuntu 16 very recently. I use an internal caching DNS server for a few reasons – try to protect myself from malware, log DNS requests on my network to have an idea of where all hosts are going – mainly searching for malware or bad websites, block some domains i.e. ad blocking and some others that I might not want to visit, even by accident, etc. Suddenly at some point, I could no longer resolve any addresses that were not in my zones. My forwarders were no longer working, etc. It turned out to be:
This line is default in Ubuntu 16’s Bind 9. Why it worked before, I don’t know. I changed it to
Then everything magically started working again. Hope this saves someone else’s time. 🙂
While we continue to see the WannaCry and other malware around, I thought I would secure my own network. Since I allow visitors onto their networks, I figured I would configure all new DHCP’d hosts to access the Internet only via HTTP and HTTPs and not allow them to use any DNS servers other than OpenDNS. Here’s how to do it:
The first thing I did was create an access restriction. I did this just to see what chain would be created and I would put subsequent rules into that chain.
The previous screenshot created this chain:
Chain rdev07 (1 references)
target prot opt source destination
DROP all -- 192.168.0.15 anywhere
With this chain, I can add additional rules. The first thing I want to do is allow only DNS access to OpenDNS servers and none other. For this, I would run the following commands:
These rules basically allow DNS queries from my network to the 2 OpenDNS servers. The last 2 rules mean that no other DNS servers outside of those 2 servers can be queried. The reason I do this is because there is some malware out there that will change the DNS servers to query on Windows, effectively overriding the DHCP setting. An alternative to this would be to configure Tomato to intercept DNS requests, but I would rather do it this way.
I added the following rules because I had noticed for some reason that some connections coming back from OpenDNS were dropped. I think they’re optional, but I put them in.