As part of the Lanfest UK project I have been setting up Game servers running as virtual machines (Post coming soon). So to save time I set up 4 templates for deploying VM’s
- Server 2012 R2
- Server 2008 R2
- Windows 7
- Ubuntu 14.04 lts
Today I will be focusing on the Ubuntu Template. Upon making the template I realised that I still had to configure a lot on the VM before it was production ready. This takes time and if I need to spin a new VM up at the Event then we may be in a little trouble.
I created the Template with the following settings :
1* 60GB Disk
1* VMNEXT3 NIC
servername : CHANGEME
IP : DHCP
SNMP : Not configured
to set up the VM I would have to deploy from the template, change the above settings manually , reboot and install the rest of the tools that I need such as SteamCMD. Doing all of this manually can take a lot of time and gives room for error.
So at a crazy hour of the morning I decided I was going to write a bash script that does all this for me.
First of all I had to think what I wanted it to do, the changes it makes and how to implement them. I soon worked out that the script would need to do the following:
- Check to see if running as root
- Make a log directory
- Change the server name
- Update package lists
- update packages
- Install the standard packages
- Set static IP
- Configure SNMP
- Add Device on the SNMP server
- Install SteamCMD
I was thinking about getting it to call a powershell script that adds the device into Veeam for me but I haven’t got the veeam server running yet. I will add it in the future though.
The next thing that I decided was that I wanted it to run all the commands silently, especially with the package updates and upgrades. It just gets messy. So I took great advantage of the > feature in bash, any output from the command goes into a file that you specify.
for example :
robert@ubuntu: ls /var/test > /var/log/dirlist.txt robert@ubuntu: cat /var/log/dirlist.txt test1 test2 test3 test4
As you can see, it redirected all the output into the dirlist.txt file. My script does a similar thing. Just to a different directory and with different commands.
Here is the first part of the script:
#introduction echo "Welcome to the Lanfest Linux server setup wizard" echo "This script was created by Robert Ainsworth (Ainsey11)" echo echo
The above part displays on the screen the text in the quotation marks. To do this you can use the command “echo” you can try it on your terminal now, just type :
Press enter to run the command and it will display what you entered in between the quote marks.
The next part will be the bit that determines if it has been run as root or not. For the changes that the script makes it needs root access.
FILE="/tmp/out.$$" GREP="/bin/grep" #.... # Make sure only root can run our script if [[ $EUID -ne 0 ]]; then echo "This script must be run as root" 1>&2 exit 1 fi
If the command returns the EUID not as root then the script echoes that it needs to be ran as root and exits, if it returns true then it continues with the script.
The next part of it creates the log directires and sets a $logdir variable for use later in the script
#make log directory mkdir /var/log/setup-script/ #set logdir var logdir=/var/log/setup-script
The mdkdir command makes the directory, and the logdir part is setting the $logdir variable.
This next part of the script changes the server name :
#find old server name oldservername=$(cat /etc/hostname) #display old server name echo "The server name is currently : $oldservername" #ask for new server name echo "What should the server name be?" read newservername #set server name in the correct dirs echo "changing hostname to : $newservername" hostname $newservername sed -i "s/$oldservername/$newservername/g" /etc/hosts sed -i "s/$oldservername/$newservername/g" /etc/hostname #display new server name echo "congrats, your server name is now : $newservername" echo "" echo "Press any key to continue" read -n 1
This part finds the existing hostname of the server by looking in the /etc/hostname file, then sets it as the $oldservername variable.
It then prints on the screen the old server name, by using the variable I set just before. After this it asks what do I want to call the server name?
Then using the “read” command I capture whatever is entered and it sets it as the “newservername” variable.
Once it has obtained this it then echoes that it is changing the old server name to the new server name and changes it in the background with the “sed -i “s/$oldservername/$newservername/g” /etc/hostname” command.
Once that is done it then displays that the new servername has been set. and asks for “any” key to be pressed to continue
After this the script then runs updates on the server :
#perform server updates echo "Now updating : $newservername's package lists" apt-get update -qy >>$logdir/packagelist.txt echo "Now updating $newservername's packages" echo "Finished!" apt-get upgrade -y >>$logdir/packageupdate.txt echo "Finished!" echo "$newservername has now been fully updated" echo "press any key to continue" read -n 1 echo""
This uses the standard ubuntu package management commands,
to update the packages. You can see in the code snippet that I use the >> redirect to export any output to the log directory.Meaning there is no output that the end user sees until there is an echo line.
Once it has finished it will ask for any key to be pressed again.
I added this in as it allow people to read the echo lines at a comfortable rate and allows you to progress at a comfortable rate.
next up is installing our most used packages:
#install basic packages echo "Now installing standard packages" apt-get install -y vim screen htop iftop iotop iperf openssh-server snmpd curl whois >> $logdir/packageinstallation.txt echo "Finished!" echo"" echo "Press any key to continue" read -n 1
This does a similar thing to the updates. It uses the apt-get install command and redirects all the output into the log directory. No horrible output on the screen.
After this it sets the network information up, as the servers and clients are going to be on a 220.127.116.11/16 address space (servers on 18.104.22.168 – .254 and clients 22.214.171.124 – 254) we can set the subnet, gateway and other config up. The only thing that needs to change is the IP itself.
#set static IP configuration echo "Setting up networking" oldnetwork=$(ifconfig | grep "inet addr:") echo "$newservername's network settings are $oldnetwork " echo "What IP do you wish to set?" read newip #backup old network config and remove cp /etc/network/interfaces /etc/network/interfaces.old rm /etc/network/interfaces #create empty conf file touch /etc/network/interfaces #add new IP settings to config file echo "auto lo iface lo inet loopback auto eth0 iface eth0 inet static address $newip netmask 255.255.0.0 gateway 126.96.36.199" >> /etc/network/interfaces echo "Finished!" echo "Press any key to continue" read -n 1
It starts by finding the old network information and adding it as a variable. It then displays the current settings to the user. It then asks the user what IP address they would like to add to the servers interface. (our servers are vm’s so one nic will suffice) The user input is set as the $newip” var and used later. To prevent any network configuration issues I have set the script to it backs up the existing configuration to interfaces.old in case I need to revert the change. It then removes the existing config and creates an empty file to replace it.
then using the $newip var set earlier it adds the remaining configuration into the config files. Notice the way I used the echo command and then the >> redirect to create the file. Exactly like I have don with the log directory.
Then the usual any key to continue.
Next up is the best part (in my opinion). We have observium deployed on the lanfest network to help us monitor and keep track of the network information and bandwidth. This part of the script sets up an ssl key and copies it onto the observium server, then it adds itself onto the monitored devices.
#configure snmpd for observium echo "Downloading SNMP config" curl http://lanfest.co.uk/scripts/snmpd.conf > /etc/snmp/snmpd.conf echo "Finished!" echo "press any key to continue" read -n 1 echo "" echo " Please ensure that lanfest-observer-1 is running before continuing and that a DNS record has been created on lanfest-inf-1" echo "press any key to continue" read -n 1 #create ssh keys and copy to lanfest-observer-1 for passwordless auth ssh-keygen -t rsa -b 2048 ssh-copy-id "lanfest@lanfest-observer-1" #ssh to lanfest-observer-1 and add device observerserver=$"lanfest-irc-1" observeraccount=$"lanfest" "ssh $observeraccount@$observerserver 'cd /var/opt/observium; sudo ./addevice.php -h $newservername ; sudo ./poller.php -h $newservername ; sudo ./discover.php -h $newservername'" echo "finished!" echo "Press any key to continue" read -n 1
As you can see it creates the ssh keys and copies it over to “lanfest-observer-1” so no passwords are stored in the script. After it has done this it ssh’s to the server and runs the commands required to add a device onto the monitoring. To make the script universal I have used the $newservername variable. Once it has finished it asks for any key to continue.
The second to last part of the script sets up the steamcmd tool for us. SteamCMD is a Valve owned software that allows us to install game servers and tools without having to install the fully blown steam client thus saving on server resources so we can ultimately run more servers.
The last part just echoes all the settings that were set and reboots the server when enter is pressed for the final time.
echo " $newservername is now configured with the below settings:" echo " The server name is now $newservername" echo " The New IP is $newip" echo " This server has been added onto observium and has passwordless ssh enabled" echo " This server has also been updated and is fully secure against threats" echo " Thanks for using this script, logs are in $logdir" echo " The server is now going to reboot to apply the final settings" echo " Press any key to continue and reboot" read -n 1 reboot -n exit
See how the use of the variables helped? It is a great use for scripts that need to be ran on multiple servers.
You can get a copy of the script here