C.J. Scarlett

Ansible - Local Playbook Execution

Ansible Logo

Preamble

There are a several ways to run Ansible on a local system that I could find whilst searching the net. In this I’m covering three of the ones that were the most popular or the most prevalent. The first two seem great for their different contexts, and the third is not as necessary but worth considering perhaps.

Being able to do this can be very useful for setting up your own machines or workstations (dotfiles anyone?) at least in the event that you don’t want to use traditional scripting. Also when creating playbooks that involve interacting with developer API’s this is an important component - see the “more information” section at the end, for a link to an example of this.


1 – Local Play Directives

This is the easiest way I found and probably most suited for when writing one or two individual playbooks.

Simply put, using both 127.0.0.1 for the hosts: directive and setting connection: to local in a playbook ensures any tasks carried out are executed on your local machine.

This is an example playbook that prints “localhost” during execution to show local playback, then updates and upgrades Apt system packages; so it’s intended for Debian and or Ubuntu.

playbook.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
---

- name: run the playbook tasks on the localhost
hosts: 127.0.0.1
connection: local
become: yes
tasks:

- name: print out the hostname of target
command: hostname

- name: ensure aptitude is installed
command: apt-get -y install aptitude

- name: update the apt package index i.e. apt-get update
apt: update_cache=yes

- name: upgrade system packages i.e. apt-get upgrade
apt: upgrade=yes

Run it as usual like any standard playbook - inclusive of -K as it’ll need sudo privileges to complete.

1
$ ansible-playbook -K playbook.yml

2 – Repository Config and Hosts File

This second method works best in the context of a version control repository, which features multiple local playbook files and is intended to be passed around from person to person or host to host. It works by forcing Ansible to use a custom config file and in turn local hosts file.

Here are the step you’d need to carry out in order to set this up in a Git repository, after setting up the repo itself. There’s also no commands for checking in, writing, and pushing files to the remote.

In the Git repository, create the custom ansible.cfg file.

1
$ vim ansible.cfg

Add these contents to the file as they’re shown:

ansible.cfg
1
2
[defaults]
hostfile = hosts

Save and exit the new file.

Then create another file, this time the custom hosts one.

1
$ vim hosts

The contents here consist of a group named [local] and a host entry listed as localhost. The host variable for local host ansible_connection=local as expected forces a local connection whenever it is targeted in a playbook.

hosts
1
2
[local]
localhost ansible_connection=local

Again on a Debian/Ubuntu host you could use an adapted version of the earlier playbook as a test example, to ensure everything is working as intended. The difference here is the localhost value for hosts: and no requirement to mention the connection: local directive.

playbook.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
---

- name: run the playbook tasks on the localhost
hosts: localhost
become: yes
tasks:

- name: print out the hostname of target
command: hostname

- name: ensure aptitude is installed
command: apt-get -y install aptitude

- name: update the apt package index i.e. apt-get update
apt: update_cache=yes

- name: upgrade system packages i.e. apt-get upgrade
apt: upgrade=yes

You’ll need to provide your sudo password with this again, to run the playbook.

1
$ ansible-playbook -K playbook.yml

3 – Global Inventory Hosts Group

One further alternative solution (in a non version control scenario where there’s no need for portability) is to instead add the [local] host group to your global /etc/ansible/hosts file.

These would be the commands:

1
$ sudo vim /etc/ansible/hosts

Append this new host group to the file.

/etc/ansible/hosts
1
2
[local]
localhost ansible_connection=local

Write your opening lines of playbooks with the hosts: all definition. Here’s the example from before, adapted to this:

playbook.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
---

- name: run the playbook tasks on the localhost
hosts: all
become: yes
tasks:

- name: print out the hostname of target
command: hostname

- name: ensure aptitude is installed
command: apt-get -y install aptitude

- name: update the apt package index i.e. apt-get update
apt: update_cache=yes

- name: upgrade system packages i.e. apt-get upgrade
apt: upgrade=yes

Then afterwards when you want to run a playbook locally, use the -l switch and provide the local group or localhost as the target host.

1
$ ansible-playbook -K -l localhost playbook.yml

It’s still wise and maybe more convenient to keep local playbook execution isolated to one directory or Git repository however (using the method in the former step). I would probably not recommend this method over the other two, but whatever works best for your particular needs I guess.

Thanks for reading, and I hope this has helped you out with local playbook execution in some way or another.


More Information

Easily deploy an SSD cloud server on Digital Ocean in 55 seconds. Sign up using my link and receive $10.00 in free credit: https://www.digitalocean.com/?refcode=e91058dbfc7b

– Scarlz: @5car1z

Debian 8 (Jessie) VPS Basic Checklist

VPS Image

Preamble

Here are some base guidelines I follow when setting up a new VPS manually without configuration management. These steps if anything make the system more secure overall and provide a good starting point from which you can setup the services/software’s required for the purpose of the VPS.

All of these steps in this post are from the context of a droplet (VPS) hosted by Digital Ocean using the Debian 8.5 x64 kernel images they use as of the above date.


1 – Setup VPS User Account

Initial root access for this section is assumed. Adding a registered SSH public key to the droplet creation on Digital Ocean gives pass-wordless root access to the VPS.

1
$ ssh root@your.vps.ip.address

Install the sudo package manually as this is not included with Digital Ocean’s Debian 8 image.

1
$ apt-get install sudo

Add your new Linux user to the system. Whenever you see scarlz here in commands it should be replaced with your own preferred username, and substituted in from throughout.

1
$ adduser scarlz

Add the newly created user to the sudo elevation privileges group.

1
$ adduser scarlz sudo

You can also add the user to the adm group which grants read access to system log files if you think this would be useful.

1
$ adduser scarlz adm

Exit the root SSH session.

1
$ exit

2 – Copy Client Public SSH Key

Install your public key to the new user added in the previous step.

Do this by running the ssh-copy-id command, supplying it with the the username and IP address of the VPS.

1
$ ssh-copy-id scarlz@your.vps.ip.address

The public key (after authentication) will be added to the remote user’s ~/.ssh/authorized_keys file.

As long as the client has the private key tied to the public key just registered, it can be used to log into the VPS.


3 – Update and Install System Packages

SSH back into the VPS as the new user you created previously, which should work without requiring authentication details thanks to the previous step.

1
$ ssh scarlz@your.vps.ip.address

Run this command to ensure the system’s packages are up to date.

1
$ sudo apt-get update && sudo apt-get upgrade

4 – Default SSH Port and Root Access

This step removes the assumption any port scanning makes on what port number the SSH service is running on. The default is 22 so these processes will check for that first and foremost. Changing this number to an ephemeral port can help to reduce the number of attempted malicious login attempts that are made. However there are several finer points as to why you might not want to do this, so decide if this seems worthwhile or not before doing it (see the next link).

Note: Should I change the default SSH port on linux servers?

All I would say is don’t get into the habit of doing this for other service’s port numbers. If you choose not to do this then Fail2ban (which we install later) will be enough in its place.

Disabling password authentication for the root user account and relying on the registered SSH key can also put a stop to attempted root logins from unwanted hosts.

Change the VPS’s default SSH port & disable root login via passwords in the system wide SSH config file.

1
$ sudo vim /etc/ssh/sshd_config

Change the Port 22 entry to any number between 1025 and 65536 respectively, if you have decided you want to do this.

For example:

/etc/ssh/sshd_config
1
Port 3267

Change the PermitRootLogin yes entry to PermitRootLogin without-password instead,

This as mentioned before means only users with public SSH keys registered in the root authorised keys file can log in as root itself.

/etc/ssh/sshd_config
1
PermitRootLogin without-password

Restart SSH so the changes take effect.

1
$ sudo service ssh restart

When accessing the VPS via SSH in the future, you must now append the correct port number to the command e.g.

1
$ ssh scarlz@your.vps.ip.address -p 3267

5 – Automatic Security Upgrades

Using a package named unattended-upgrades it’s possible to have updates done by the package manager automatically at set intervals. It is advised to only enable security updating and not the normal package upgrading as this could potentially cause problems with conflicts or unwanted changes.

Install the package to begin with.

1
$ sudo apt-get install unattended-upgrades

Open/create the 10periodic configuration file for this package using your preferred text editor.

1
$ sudo vim /etc/apt/apt.conf.d/10periodic

Add in the lines found in the below code snippet:

/etc/apt/apt.conf.d/10periodic
1
2
3
4
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Download-Upgradeable-Packages "1";
APT::Periodic::AutocleanInterval "7";
APT::Periodic::Unattended-Upgrade "1";

Save your additions and exit the file.

Now open up another configuration file named 50unattended-upgrades for changes.

1
$ sudo vim /etc/apt/apt.conf.d/50unattended-upgrades

Enable security updates only by adding the line - "origin=Debian,codename=${distro_codename},label=Debian-Security"; to the correct location, as shown in the next code snippet on line 17:

/etc/apt/apt.conf.d/50unattended-upgrades
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Unattended-Upgrade::Origins-Pattern {
// Codename based matching:
// This will follow the migration of a release through different
// archives (e.g. from testing to stable and later oldstable).
// "o=Debian,n=jessie";
// "o=Debian,n=jessie-updates";
// "o=Debian,n=jessie-proposed-updates";
// "o=Debian,n=jessie,l=Debian-Security";

// Archive or Suite based matching:
// Note that this will silently match a different release after
// migration to the specified archive (e.g. testing becomes the
// new stable).
// "o=Debian,a=stable";
// "o=Debian,a=stable-updates";
// "o=Debian,a=proposed-updates";
"origin=Debian,codename=${distro_codename},label=Debian-Security";

};

Further down in the file add an email address thatcan receive the update reports and uncomment the line itself:

/etc/apt/apt.conf.d/50unattended-upgrades
1
2
3
4
5
// Send email to this address for problems or packages upgrades
// If empty or unset then no email is sent, make sure that you
// have a working mail setup on your system. A package that provides
// 'mailx' must be installed. E.g. "user@example.com"
Unattended-Upgrade::Mail "user@email-domain.com";

6 – Setup Dotfiles (Optional)

Most administrators or developers will have their own customised dotfiles they use to personalise the server and make tasks easier, or introduce extra functionality to the system. Here is where I would setup my own using Git and GitHub.

It is unlikely that you’ll want to carry out the commands in this step as these instructions are for my own dotfiles, so only really relevant to me.

Replace this step with installing and setting up your own equivalent dotfiles!

https://github.com/5car1z/dotfiles

Install Git via the system package manager.

1
$ sudo apt-get install git

Clone your dotfiles repository onto the system.

1
2
$ git clone https://github.com/5car1z/dotfiles.git 
$ cd ~/dotfiles

Run the two install scripts that add more packages (all the good stuff) and create the necessary symlinks using GNU Stow.

1
2
$ ./install-debian-ubuntu-dotfile-dependencies.sh
$ ./stow-dotfiles.sh

If there’s any submodule problems update them to their latest remote versions with:

1
$ update_submodules

7 – Install Software Packages

Any outstanding or super essential packages that haven’t been brought in by the “dotfiles” step should be considered before moving on. What these are will be known only to you though as everybody’s preferences and needs are different.

Here are several examples however.

1
$ sudo apt-get install git vim curl cowsay fortune-mod jq vim tmux ranger

8 – Install and Run UFW

UFW stands for “Uncomplicated Firewall” and is more concise easier to understand alternative to older firewall implementations like iptables.

Install on Debian 8 like any other package simply using:

1
$ sudo apt-get install ufw

Like with other firewalls of this elk it’s common practice to put in place a blanket set of ingress/egress rules then add the exceptions to services and ports on top afterwards.

Make the default overall action for any incoming traffic to be blocked and denied.

1
$ sudo ufw default deny incoming

Then make the default overall action for outgoing traffic to be permissible and allowed.

1
$ sudo ufw default allow outgoing

From here, any services you wish to allow that are received by the VPS can be added as an exception. See a separate post that covers the key areas of UFW in itself for information on how to do this.

Full UFW Guide

To continue here, open the SSH port number you chose earlier on by replacing the number 3267 with your own number, in the following command.

1
$ sudo ufw allow 3267/tcp

Lastly after all the extra rules you need, enable the firewall so the configuration becomes active.

1
$ sudo ufw enable

9 – Install and Run Fail2ban

This application permanently stops any excessive failed attempts (brute forcing) at connecting to the VPS - it achieves this by banning the offending source IP. This is configurable over various services on the system and not just SSH.

Install it as done before with the system package manager.

1
$ sudo apt-get install fail2ban sendmail

Sendmail can also be used by Fail2ban when sending out notification messages for bans that have occurred, so this is useful to install alongside it. Unless you want to configure it to use a different mail service.

Create a .local version of the configuration file:

1
$ sudo sed 's/^banaction = .*/banaction = ufw/' /etc/fail2ban/jail.conf > /etc/fail2ban/jail.local

Start the service and ensure it’s running by using the command:

1
$ sudo service fail2ban start

A more detailed rundown of the configuration involved with Fail2ban is covered in a separate post to this one.

Full Fail2ban Guide


This is a pretty straightforward post, all things considered. Remember that a persons needs for configuring a VPS will be tailored to their own requirements, criteria, and preferences. So these steps are good general outline but mainly the ones I personally follow - other people’s will be different, according to their needs.

More Information

Easily deploy an SSD cloud server on Digital Ocean in 55 seconds. Sign up using my link and receive $10.00 in free credit: https://www.digitalocean.com/?refcode=e91058dbfc7b

– Scarlz: @5car1z

Hosting Django Web Applications with Apache (mod_wsgi) on Debian 8

Django Logo

Preamble

This post covers one of many ways to setup and run a Django project, website, or web application. It’s probably one of the most routine methods on offer and is certainly not the “best” choice out of them all, but still a good place to start in understanding the framework and how it operates.

More popular methods of running and hosting Django are mentioned at the end of the post.


1 – Update & Install Packages

Update and upgrade the server’s system packages:

1
$ sudo apt-get update && sudo apt-get upgrade

Install Apache, mod-wsgi, and Python’s pip package manager.

1
$ sudo apt-get install apache2 libapache2-mod-wsgi python-pip

Also the virtualenv package is required for the next step.

1
$ sudo pip install virtualenv

2 – Setup Virtual Environment

Decide where you want to keep your Django project.

There are several places form which you could run the project. One that is very common is the user’s home directory. Another suitable place is the /srv/ system directory. A final place could be directly inside the system’s web server directories i.e. /var/www and down.

In my example I’ll be using a Linux user’s home directory.

1
$ mkdir ~/django-project && cd ~/django-project

Inside the new project folder create a dedicated Python virtual environment:

1
$ virtualenv django-virt-env

Activate the environment and enter into it:

1
$ source django-virt-env/bin/activate

Now you’re within the environment (prompt will change) install Django with pip into it:

1
$ pip install django

Once Django is installed, use the deactivate command to exit the environment prompt.

1
$ deactivate

3 – Create or Import Django Project

To start from scratch you can use the Django installation in the virtual environment and make a brand new Django project. Or instead import your Django project files from something like version control.

For this tutorial we’ll go down the path of importing a a pre-existing Django project from Git.

Before this though, here are the initial steps for starting a brand new Django project.

Create Project

Skip past this section to instead import an existing Django project.

1
$ source django-virt-env/bin/activate

Create the new project and give it a name, where project_name is replaced with your name you want to give it.

1
$ django-admin.py startproject project-name .

Run initial migration:

1
$ ./manage.py migrate

Create a superuser for the project:

1
$ ./manage.py createsuperuser

Open up the settings.py file for editing:

1
$ vim project-name/settings.py

Add this new line to the bottom section of the file:

~/django-project/project_name/settings.py
1
STATIC_ROOT = os.path.join(BASE_DIR, "static/")

Note: The settings.py file is often replaced with a template file in version control, as it contains user specific data, environment specific data, and sensitive credentials. More on this later.

Copy static content into the directory set in the previous STATIC_ROOT directive:

1
./manage.py collectstatic

Test the server runs correctly:

1
$ python manage.py runserver 0.0.0.0:8000

You can test the project works in a web browser at: your.vps.ip.address:8000

It Worked Django Image

CTRL + C once checked to exit the server process.

Then deactivate once again to leave the Python virtual env prompt.

1
$ deactivate

Import

This is the assumption I’m following for the rest of the post, that you already have a Django project created and want to host it. You could still however carry on with the new blank project from before.

Import the Django project into our local project’s root folder:

1
$ git clone https://github.com/username/repository-name.git ~/django-project

Note: The settings.py file is often replaced with a template file in version control, as it contains user specific data, environment specific data, and sensitive credentials. More on this later.

Then move on to setting up the virtual host.


4 – Setup Apache Virtual Host

Using your preferred text editor open the default Apache vhost for writing, or a dedicated vhost instead.

1
$ sudo vim /etc/apache2/sites-available/000-default.conf

The complete main block of the virtual host should contain the following:

/etc/apache2/sites-available/000-default.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
ServerName exampledomain.com
ServerAlias www.exampledomain.com
ServerAdmin server-administrator@emaildomain.com

Alias /static /home/username/django-project/static

<Directory /home/username/django-project/static>
Require all granted
</Directory>

<Directory /home/username/django-project>
<Files wsgi.py>
Require all granted
</Files>
</Directory>

WSGIDaemonProcess project-name python-path=/home/username/django-project:home/username/django-project/django-virt-env/lib/python2.7/site-packages
WSGIProcessGroup project-name
WSGIScriptAlias / /home/username/django-project/project-name/wsgi.py

What follows are the broken down areas of the above virtual host, and how to set them.

Static Alias

The first option to set is an alias, and needs to point to the static directory we generated when either creating or importing the Django project files.

So username needs to be your Linux username, and django-project needs to be substituted for whatever you named the very first folder we created. Back at the start of Step 3.

1
Alias /static /home/username/django-project/static

Static Directory Access

The web server must also allow access to the directory we aliased for static. Do this with a directory block that looks like this. Except again with the same values as before substituted in.

1
2
3
<Directory /home/username/django-project/static>
Require all granted
</Directory>

wsgi.py Access

The wsgi.py file inside your project-name directory should also be open for access. Add this second directory block to ensure it’s accessible.

Again project_name and the previous values need altering to your own.

1
2
3
4
5
<Directory /home/username/django-project/project-name>
<Files wsgi.py>
Require all granted
</Files>
</Directory>

WSGI Settings
The gateway interface mod for Apache uses wsgi.py to handle passing clients to the Django web app. Set it up with a daemon process path, process group name, and alias to the wsgi.py file location.

Some things to note are that the latter half of the python-path setting should point to your virtual environment’s Python site packages, and not your system wide ones. The : character delimits separate paths.

For the WSGIDaemonProcess and WSGIProcessGroup name (project-name in my example) you can set it to any suitable name.

All relevant values here once again should be replaced with your own.

1
2
3
WSGIDaemonProcess project-name python-path=/home/username/django-project:home/username/django-project/django-virt-env/lib/python2.7/site-packages
WSGIProcessGroup django-project
WSGIScriptAlias / /home/username/django-project/project-name/wsgi.py

5 – Apache Permissions

Change the system permissions so that the Linux group owner of the database file can read and write.

The database file is named db.sqlite3 by default and is in the root project directory if not moved previously.

1
$ chmod 664 ~/django-project/db.sqlite3

Apache runs under the www-data system group, give said group ownership of the database file:

1
$ sudo chown :www-data ~/django-project/db.sqlite3

In order for the www-data Apache group to properly write to the database file, we also need to give it ownership of the database file’s parent directory:

1
$ sudo chown :www-data ~/myproject

Restart Apache to implement the changes we just made:

1
$ sudo service apache2 restart

Assuming your firewall is setup correctly you should now be able to access your Django site by going to your server’s domain name or IP address in a browser.


Live Deployment Considerations

1 – Django Project Settings

The settings.py file usually contains sensitive data values such as passwords, secret keys, and user credentials. Which are at risk of being exposed when stored in the Project’s version control (at least if public version control is used).

The exact details set in settings.py are also likely to differ from user to user. As different directives and values may be required depending upon the installation context and user in question. For example DEBUG being set to TRUE on a local environment versus a live environment.

It’s for these reasons it’s advisable to instead import these values into settings.py from another local credentials file. One that the user fills out manually upon setting up the project locally for the first time.

The same “credentials” file must then be permanently ignored by the version control system, so the user specific details and passwords are kept private, but still imported into settings.py .

Here is what an example template for this credentials file might look like:

Once created the credentials.py file and it’s stored directives can all then be imported inside the main Django settings file.

Via this line of code:

~/django-project/project-name/settings.py
1
2
# Imports sensitive/user config variable values.
from credentials import *

It’s a good idea to use a template file like the one above to replace the credentials.py in version control. So new users and installs can make a copy of it, and fill in the details required.


2 – Live Specific Directives

As mentioned in the previous section, some directives will need to be set differently for different situations.

Here are some of the directives defined in credentials.py (or an equivalent user specific settings file) that are suitable for a live setup.

~/django-project/project-name/credentials.py
1
DEBUG = False

Setting this next directive is optional more than anything but provides a means of helping with debugging errors and exceptions raised while rendering the apps templates.

~/django-project/project-name/credentials.py
1
TEMPLATE_DEBUG = False

This line and directive can be kept directly in settings.py unlike the other directives, although it doesn’t hurt to place in credentials.py anyway. Once DEBUG is set to false , this allows only the specified FQDN’s access to your Django site.

It’s wise to ensure you have a valid FQDN hostname set on your server if experiencing any problems with this directive.

~/django-project/project-name/credentials.py
1
ALLOWED_HOSTS = ['127.0.0.1', 'localhost', '.leagueofyorkshire.co.uk']

Note: it is unwise to add a * symbol to the ALLOWED_HOSTS directive, as this would give access to any and all potential requests.

Django uses the STATIC_ROOT directive to tell Apache where the generated static files are located. If the ./manage.py collectstatic is run with live settings then the STATIC_ROOT directive must be set to something other than the previous static directory. In this case in the below code it’s set to generate it in a directory named assets. The other commented directives also need enabling in here for this to work:

~/django-project/project-name/credentials.py
1
2
3
4
# BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# STATIC_URL = '/static/'
# STATIC_ROOT = os.path.join(BASE_DIR, "assets/")
# STATICFILES_DIRS = (os.path.join('static'),)

These previous directives are not all the ones you will find or define in the credentials file, but are mostly the ones to consider when working with a live deployment install of the project.

See here for detailed information about more of these:

Django Official Documentation - Settings


3 – Web Server Permissions

We set some permissions on the database file and parent directory in an earlier step, however the other Django files hosted by your web server have their own permissions to consider.

The main file to take into account when setting permission is the file that holds your live environment specific directives, and user sensitive data. In our example this was the credentials.py file, created from a template that takes it’s place in version control.

Consider taking away read and write privileges to everyone else / other for this file:

1
$ sudo chmod o-rw ~/django-project/project-name/credentials.py

4 – Error Reporting & Logging

Section To Be Added


5 – .gitignore

Here is a .gitignore containing lots of potential file types and directories you likely don’t want to track for live or in general. Some are Django specific, others are Python project related.


Further Considerations

There are other alternatives to this entire procedure that have their own advantages and merits. These should be considered as an alternative or more specialised way of running Django.

Gunicorn

“Gunicorn ‘Green Unicorn’ is a Python WSGI HTTP Server for UNIX. It’s a pre-fork worker model ported from Ruby’s Unicorn project. The Gunicorn server is broadly compatible with various web frameworks, simply implemented, light on server resources, and fairly speedy.”

http://gunicorn.org/

uWSGI

“The uWSGI project aims at developing a full stack for building hosting services. Versatility, performance, low-resource usage and reliability are the strengths of the project “

Quickstart for Python/WSGI applications

Tornado

“Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed. By using non-blocking network I/O, Tornado can scale to tens of thousands of open connections, making it ideal for long polling, WebSockets, and other applications that require a long-lived connection to each user.”

tornado.wsgi — Interoperability with other Python frameworks and servers

Other Python Web Frameworks/Servers


More Information

Easily deploy an SSD cloud server on Digital Ocean in 55 seconds. Sign up using my link and receive $10.00 in free credit: https://www.digitalocean.com/?refcode=e91058dbfc7b

– Scarlz: @5car1z

Installing Minecraft Server on Debian 8

Debian Logo

Preamble

Covers the general process of setting up a basic Minecraft server from start to finish. Along with how to configure some of the server’s properties and user permissions.

  • Uses Java (OpenJDK in this case) as a dependency.
  • Requires GNU Screen to maintain a shell session.
  • The Minecraft game client is necessary to test access to the server.
  • Suitable Server Hardware specifications are addressed.

Minecraft’s Official Website


1 – Update System Packages

Ensure the packages are up to date on the system with the command:

1
$ sudo apt-get update && sudo apt-get upgrade

Confirm the action by entering y for any prompts in this step.


2 — Install Screen

Screen is used to keep the Minecraft server running in a persistent shell session, it also allows us to disconnect or re-attach to the session when needed.

1
$ sudo apt-get install screen

3 – Install Open JDK

Install the open JDK platform with Debian’s package manager:

1
$ sudo apt-get install openjdk-7-jre-headless

Note: “It is recommended that Linux users avoid using OpenJDK 6 for server hosting, as it has been known to cause issues.”


4 – Create Dedicated User

Add a user with a suitable name who’ll run and store the server software in its home directory:

1
$ sudo adduser minecraft

5 – iptables Firewall

If using iptables you’ll need to allow access on the Minecraft server’s TCP port 25565 for incoming connecting clients.

Here is one command to add this, tweak it to your own needs and firewall setup:

1
$ sudo iptables -I INPUT 3 -p tcp --dport 25565 -j ACCEPT -m comment --comment "allow connections on port 25565 Minecraft server"

Remember to re-save your updated rules (IPv4 in my case).

1
$ sudo iptables-save > /etc/iptables/rules.v4

6 – Download Minecraft Server Software

SSH to the new minecraft user (or whatever you named them).

1
$ ssh minecraft@your.vps.ip.address

Download the latest version of the Minecraft server jar file.

The current version number is 1.8.8 at the time of writing this:

1
$ wget -v https://s3.amazonaws.com/Minecraft.Download/versions/1.8.8/minecraft_server.1.8.8.jar

Note: Amend your command to include the version number that is currently in release. Previously found at https://minecraft.net/download towards the bottom of the page.


7 – Create Minecraft Executable Script

With a text editor create a shell script named something similar to the following:

1
$ vim run-minecraft-server.sh

In the newly created script add the code in the next snippet, replacing the two java parameter values with your own preferred memory usage values.

~/run-minecraft-server.sh
1
2
3
4
5
6
#!/bin/bash

BINDIR=$(dirname "$(readlink -fn "$0")")
cd "$BINDIR"

java -Xmx1024M -Xms1024M -jar minecraft_server.*.*.*.jar nogui

See the next image for recommendations on server requirements from the official Minecraft wiki, to determine your values.

Minecraft Wiki Server Requirements

-Note: Xms256M dictates the lowest amount of system memory the Minecraft server will consume, and Xmx512M specifies the upper limit of server memory it can max out at.

Save your changes to the script and exit back to the command line.

Finally in this step use chmod to make the previous script executable.

1
$ chmod +x run-minecraft-server.sh

8 – Run Executable Script

Run it from the command line by adding the ./ prefix.

1
$ ./run-minecraft-server.sh

You’ll see the following output if the script has been written correctly:

1
2
3
4
5
6
7
8
9
[09:10:50] [Server thread/INFO]: Starting minecraft server version 1.8.8
[09:10:50] [Server thread/WARN]: To start the server with more ram, launch it as "java -Xmx1024M -Xms1024M -jar minecraft_server.jar"
[09:10:50] [Server thread/INFO]: Loading properties
[09:10:50] [Server thread/WARN]: server.properties does not exist
[09:10:50] [Server thread/INFO]: Generating new properties file
[09:10:50] [Server thread/WARN]: Failed to load eula.txt
[09:10:50] [Server thread/INFO]: You need to agree to the EULA in order to run the server. Go to eula.txt for more info.
[09:10:50] [Server thread/INFO]: Stopping server
[09:10:50] [Server Shutdown Thread/INFO]: Stopping server

9 – Agree to EULA

The EULA you must agree to is located in the same user’s home directory.

Again using a text editor open it for writing:

1
$ vim eula.txt

Set the eula directive to true like in the example below:

1
2
3
#By changing the setting below to TRUE you are indicating your agreement to our EULA (https://account.mojang.com/documents/minecraft_eula).
#Mon Oct 05 09:10:50 EDT 2015
eula=true

Save changes and exit the text editor.

Back on the command line begin a screen session by providing the full path to your executable script:

1
$ screen ./run-minecraft-server.sh

The server now runs and begins to generate the in-game content.


10 – Client Connections

The server should now be running continually and Minecraft clients can connect to it.

Connect with a Minecraft client to the server IP.

Everything should be functioning as intended, and the server is ready for use!

You can leave and detach from the screen session by pressing CTRL + d then a on your keyboard, back in the terminal.


11 – Administration

Logged in once again as the Linux user minecraft or whatever you chose to call your dedicated user, re-attach to the minecraft screen session from earlier with:

1
$ screen -r

Shut down the server which saves player created progress and the in-game content.

1
/stop

Now the server has been stopped you can begin to play around with its file structure.

1
$ ls

There are several key files in in regards to maintaining the server, and two other directories to consider.

Any time you modify these files while the game is running, you will need to stop and restart the server for the changes to take effect.


ops.json

This file named ops.json contains usernames of players that have ops privileges on your server.

It is empty until you add player usernames however.

Warning: Players listed in this file can change their game mode, input certain commands, and ban or unban other players from the server.

You can either add user details directly to this .json file, if you understand the formatting involved.

Or create a completely separate ops.txt file with a list of usernames inside.

1
$ vim ~/ops.txt

The text file you create is then converted into the ops.json file from earlier once the server is next booted.

It is recommended that you follow this method if you are unfamiliar with JSON formatting.

For more information on ops or operators in Minecraft click the next link:

Minecraft Wiki Operators Page


server.properties

The bulk of in-game settings and properties are stored in the following text file.

1
$ vim ~/server.properties

There are a longer list of properties you can add to the file that are listed at this next URL:

Minecraft Wiki Server.properties Page


banned-ips.json & banned-players.json

In order to ban an IP address from connecting to the server, the full IP address must be specified; - impartial addresses or wildcards are not supported here.

Any players who are banned in this manner see “Your IP address is banned from this server!” when attempting to connect through the client.

In-game an operator can instead use “/ban-ip ipaddress”, where “ipaddress” is the IP address of the user they wish to ban. To remove and undo a ban, the operator can issue “pardon-ip ipaddress”. Or if they have access, edit the server’s banned-ips.json file.


white-list.json

This essentially can be used to make a server private to a select group of clients. To do so add their usernames to the file white-list.txt. You will need to edit the server.properties file, changing white-list=false to white-list=true .

Alongside this you can also use this file to change the public message on your Minecraft server.

1
$ vim ~/white-list.txt

Edit motd=A Minecraft Server to show the name or phrase that you want to display publicly to clients.


World Directories

This directory and its subdirectories contain map and player data for the realms in your game.

It is worth backing up these directories regularly so that you can revert to previous versions in case of in-game mishaps or unwanted trolls. These directories may be in different locations, depending on which version of the Minecraft server you installed.

Also note that the directories for the nether and the end will not be created until a player visits the area at least once on the server.


Log Directory

Anything and everything that goes on is stored in the logs directory. It’s worth reviewing it’s contents every now and then or if any technical problems arise.

1
$ less ~/logs/latest.log

Previous logs are compressed automatically as and when needed.


Console Commands

The link below contains a table that summarizes all available commands. Some of which have been mentioned here, but most of which have not.

Minecraft Wiki Commands Page


More Information

Easily deploy an SSD cloud server on Digital Ocean in 55 seconds. Sign up using my link and receive $10.00 in free credit: https://www.digitalocean.com/?refcode=e91058dbfc7b

– Scarlz: @5car1z

Installing TDSM Terraria Server Mod on Debian 8

Debian Logo

Preamble

TDSM is one of several open-source server mods available for the online action-adventure game Terraria. This modification is developed to allow the Terraria server software to be run on Linux like operating systems, and opens up many other potential benefits for players using the server.

  • External plugin support.
  • Administrative permissions system.
  • MySQL & SQLite databases.
  • New & custom in-game commands.
  • Remote console administration.

It’s also updated relatively quickly by the maintainers after a new Terraria client version is released.

TDSM Github Project Page


Requirements

  • A Terraria game client for connection to the server after installation.

  • For a small sized world, a VPS that has at least 1GB RAM.

  • For a medium sized world, a VPS that has at least 1GB RAM.

  • For a large sized world, a VPS that has at least 2GB RAM.


1 – Update System Packages

Ensure the packages are up to date on the system with the command:

1
$ sudo apt-get update && sudo apt-get upgrade

Confirm the action by entering y for any prompts in this step.


2 – Install Screen

Screen will be used to keep the TDSM server running in a persistent shell session, and allows us to disconnect or re-attach to the session when needed.

Install Screen with the command:

1
$ sudo apt-get install screen

3 – Install Mono

Mono is the open source implementation of Microsoft’s .NET Framework, and we need it to successfully run and start the TDSM server later on.

Install Mono and all its packages with the command:

1
$ sudo apt-get install mono-complete

4 – Install Unzip

The server software comes packaged in a .zip file. So install the unzip package which we’ll use in the next step, to extract the files.

1
$ sudo apt-get install unzip

5 – Add Swap Space

The server mod requires adequate swap space to be allocated by the system. Otherwise this can result in crashing and instability with TDSM whilst it is running.

Create the base swap file:

1
$ sudo fallocate -l <^>4G<^> /swapfile

Give it the correct permissions it needs:

1
$ sudo chmod 600 /swapfile

Have the system build the file:

1
$ sudo mkswap /swapfile

Then enable it with the swapon command:

1
$ sudo swapon /swapfile

To automate the mounting of the swap file on boot we need to include its details into the /etc/fstab file.

1
$ sudo nano /etc/fstab

Insert this top line show in the next code snippet into the file.

/etc/fstab
1
/swapfile   none    swap    sw    0   0

6 – Download the TDSM Server Software

The TDSM server software that we’ll download in this step will be stored and run from your user’s home directory.

Make sure this is your current working directory by entering:

1
$ cd ~

As of writing this tutorial the current TDSM server build release is number: 005

For newer versions than the current 005 release, and to download the most up to date version.
You’ll need to change the URL passed to wget in the next code snippet.

1
$ wget https://github.com/DeathCradle/Terraria-s-Dedicated-Server-Mod/releases/download/Build-5/tdsm-b5.zip

The TDSM server releases and their file URL’s can be found on the project’s GitHub page:

TDSM Releases on Github


7 – Run the Terraria Server Binary

Next unzip the downloaded archive file and extract the contents into a new folder named tdsm-terraria-server using the -d option:

Note: The downloaded .zip file name will differ for future release downloads.

1
$ unzip tdsm-b5.zip -d tdsm-terraria-server

Change into the unpacked tdsm-terraria-server directory with:

1
$ cd tdsm-terraria-server

Now to run the server software in it’s most basic form without any arguments or parameters, enter the following command:

1
$ screen mono tdsm.exe

Note the inclusion of Screen in the last command. This runs the Mono program and server in a separate shell session to our original one.


8 – Create a New World

The below output (or similar) is seen upon successfully running the server binary in “Step 7 – Run the Terraria Server Binary“.

Type n and press ENTER to create a new world.

1
2
3
4
5
6
7
8
9
10
11
12
10/2/2015 2:05:20 PM Run> TDSM Rebind API build 5lr running on Mono                                                                                                                                                                            10/2/2015 2:05:20 PM Run> Logging started to file "/home/<username>/src/tdsm-terraria-server/Data/server_20151002_1405.log".
10/2/2015 2:05:20 PM Run> Loading plugin from TDSM.Core.dll.
10/2/2015 2:05:20 PM Run> TDSM Rebind core build 5lr
10/2/2015 2:05:20 PM Run> TDSM Rebind core enabled
10/2/2015 2:05:21 PM Run> Server state changed to: Initialising
10/2/2015 2:05:23 PM Run> Server state changed to: Starting
Terraria Server v1.3.0.8

n New World
d <number> Delete World

Choose World:

Enter 1 , 2 , or 3 depending upon your preference and suitability of world size.

The requirements section at the start of this article indicates what world size is suitable for your VPS.

Here it is again:

  • For a small sized world, a VPS that has at least 1GB RAM.

  • For a medium sized world, a VPS that has at least 1GB RAM.

  • For a large sized world, a VPS that has at least 2GB RAM.

Warning: Be aware that the larger the world the more memory and CPU your server will need to consume whilst the server is up and running, so be sure to select a suitable world size.

1
2
3
4
5
6
7
Terraria Server v1.3.0.8

1 Small
2 Medium
3 Large

Choose size:

Enter 1 , 2 , or 3 again once more depending upon your desired level of in-game difficulty.

1
2
3
4
5
6
Terraria Server v1.3.0.8

1 Normal
2 Expert

Choose difficulty:

Now give the new world a suitable name.

For example purposes we’re calling ours test-tdsm-server in this guide.

1
2
3
Terraria Server v1.3.0.8

Enter world name:

Wait for the new world to be generated as it outputs its progress and percentage completion.


9 – Set World Details

Once the world is created and has finished generating, choose your previously created world by entering 1 into the prompt:

1
2
3
4
5
6
1   test-tdsm-server      norm, crim, exp   Last used: 10/02/2015 10:27 AM

n New World
d <number> Delete World

Choose World:

Provide the world with a max number of players that can join the server at any one time. If you are unsure on a value, the default of 8 is a sensible choice.

Warning: Once again be aware that the more players the world has connected the more memory and CPU your server will need to consume whilst running.

1
2
3
Terraria Server v1.3.0.8

Max players (press enter for 8):

Enter a suitable port the server can transmit on, go for the default choice of 7777 if you don’t have a specific port you want to use:

1
2
3
Terraria Server v1.3.0.8

Server port (press enter for 7777):

The final two questions are up to you (forwarding and password). Forwarding with iptables is covered in this next section however.

Wait for the server to load as it outputs its progress.


10 – iptables Firewall

Now the server is up running you’ll need to de-attach from the currently active screen session with:

CTRL + a then c

If using iptables (or you intend to use it) as a firewall solution on the VPS, then open up the port number you chose in “ 9 – Set World Details”

To do this use:

1
$ sudo iptables -A INPUT -p tcp --dport 7777 -j ACCEPT -m comment --comment "allow connections on port 7777 Terraria server"

Replacing 7777 for your own chosen port number.

For any other firewall program you may use in its place perform the equivalent port forwarding/opening actions.

To now connect back to the previous screen session press:

CTRL + a then n


Conclusion

The server itself is now ready and should be open for connections via the Terraria client.

To learn how to administer, run, and configure the server properly alongside what configuration files it uses, see the Github wiki:

TDSM Project Github Wiki


More Information

Easily deploy an SSD cloud server on Digital Ocean in 55 seconds. Sign up using my link and receive $10.00 in free credit: https://www.digitalocean.com/?refcode=e91058dbfc7b

– Scarlz: @5car1z