Category Archives: Ubuntu

Postgresql in Docker

Let’s run up the Docker image with an instance of PostgreSQL

docker run --name mypostgres -d postgres

Now, connect to the instance so we can create a database etc.

docker exec -it mypostgres bash
createdb -U postgres MyDatabase

Note: if you find this error message psql: FATAL: role “root” does not exist, you’ll need to switch to the postgres user, see below.

Switch to the postgres user (su substitute user).

su postgres
psql

At which point, we’re now in the psql application and can create databases etc.

Setting up Ubuntu Server firewall

UFW is used as the firewall on Linux and in my case on Ubuntu server. UFW comes with a UI, but we’re going to use this on a headless server (hence no UI being used).

Status and enabling/disabling the firewall

Simply run the following to check whether your firewall is active or not

sudo ufw status

To enable the firewall simply use the following

sudo ufw enable

Use disable to disable the firewall (as you probably guessed).

Once enabled run the status command again and you should see a list showing which ports we have defined rules for and these will show whether to ALLOW or REJECT connections to port. For example

To                         Action      From
--                         ------      ----
22/tcp                     ALLOW       Anywhere
80/tcp                     ALLOW       Anywhere
443/tcp                    ALLOW       Anywhere
80                         ALLOW       Anywhere

Allow and reject access

We can allow access to a port, reject access to ports and reject outgoing traffic on ports. When we allow, reject incoming or reject outgoing access we’re creating firewall rules.

To allow access to SSH, for example we do the following

sudo ufw allow 22

This will allow tcp and udp access, but we can be more precise and just allow tcp by using

sudo ufw allow 22/tcp

As you can see from the previous output from the status option, we’ve enabled 22/tcp already.

To reject access to a port we use reject.

Note: If you’re access your server using SSH you probably don’t want to reject access to port 22, for obvious reasons, i.e. port 22 is used by SSH and this will block your access via SSH.

sudo ufw reject 80

Application profiles

UFW includes application profiles which allow us to enable predefined lists of permissions

sudo ufw app list

The applications listed from this command can also be seen by listing /etc/ufw/applications.d, so for example on my system I have a file name openssh-server, if you open this with nano (or your preferred editor), you’ll see an INI file format, for example

[OpenSSH]
title=Secure shell server, an rshd replacement
description=OpenSSH is a free implementation of the Secure Shell protocol.
ports=22/tcp

We can also use

sudo ufw app info OpenSSH

Replacing OpenSSH with the name of the application profile you want to view

As you can see, if our application profiles are just INI files, then you can create your own file and place it into the aforementioned folder and make it available to UFW. Once you’ve created your file you’ll need to tell UFW to load the application definitions using

sudo ufw app update MyApp

Replace MyApp with your application name in the above.

Ofcourse once we have these profiles we can allow, reject etc. using the application name, i.e.

sudo ufw allow OpenSSH

Logging

By default logging is disabled, we can turn it on using

sudo ufw logging on

Setting up swift on Ubuntu 20.04

This is an update to Setting up swift on Ubuntu 18.04 – installing Swift on Ubuntu 20.04.

Check out Downloads for the current info. from swift.org.

  • We need to install dependencies, so start with
    apt-get install binutils git gnupg2 libc6-dev libcurl4 libedit2 libgcc-9-dev libpython2.7 libsqlite3-0 libstdc++-9-dev libxml2 libz3-dev pkg-config tzdata uuid-dev zlib1g-dev
    
  • Next we need to download the tar for the version of Swift you’re targeting, mine’s Swift 5.5.2
    wget https://download.swift.org/swift-5.5.2-release/ubuntu2004/swift-5.5.2-RELEASE/swift-5.5.2-RELEASE-ubuntu20.04.tar.gz
    

Next up we should verify this download

  • First download the signature using
    wget https://swift.org/builds/swift-5.5.2-release/ubuntu2004/swift-5.5.2-RELEASE/swift-5.5.2-RELEASE-ubuntu20.04.tar.gz.sig
    
  • Now import the key
    wget -q -O - https://swift.org/keys/all-keys.asc | gpg --import -
    
  • Now run the following
    gpg --keyserver hkp://keyserver.ubuntu.com --refresh-keys Swift
    gpg --verify swift-5.5.2-RELEASE-ubuntu20.04.tar.gz.sig
    

Assuming everything’s verified we now want to extract the download into our preferred location – in my case I am just creating a folder name ~/Swift and extracting the tar to this location, running the following from this location

tar xzf swift-5.5.2-RELEASE-ubuntu20.04.tar.gz

Finally let’s update the path – I’ve added this to the last line of my .bashrc

export PATH=~/Swift/swift-5.5.2-RELEASE-ubuntu20.04/usr/bin:"${PATH}"

Checking who last logged in and when on Ubuntu Server

You might want to see a list of who logged into your Ubuntu server last or over a time period. Or maybe you want to take a look at more than just that and see more of an audit trail…

last

We can use the command last to display a “listing of last logged in users”. For example let’s just get the tail of the list using

last | tail

or ofcourse we might simple look through all entries using

last | less

What about if we know the user we’re interested in, then we can simply use

last -x Bob

Replacing Bob with the username you wish to look for.

There’s options to specify listing data after a specific time or before a time and more see

last --help

What if we want even more information.

/var/log/auth.log

Last works well if you’re interested in users logging into the server, but what about if we just want to check who’s access a shared drive or the likes, then we can check the /var/log/auth.log like this

sudo cat /var/log/auth.log
// or 
sudo less /var/log/auth.log
// or
sudo tail /var/log/auth.log

As per standard piping of commands, I’ve included an example of using less and tail, but basically we want to list the contents of the auth.log file. Ofcourse as it’s a file we can grep it (or whatever) as required.

This auth.log file lists sessions being opened and closed, cron jobs and lots more besides.

Ubuntu server auto upgrade

I have an Ubuntu server happily living it’s life as a NAS (and more) server which every now and then (if I forget to keep track of updates) it runs out of space on /boot causing issues removing old releases or partial updates to be a bit of a problem. So how do we either turn on or off automatic upgrades?

The configuration for this is stored in the file 20auto-upgrades. So we can edit the file using

sudo nano /etc/apt/apt.conf.d/20auto-upgrades

Within the file you’ll see something like this

APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";

Note: The “1” in the above are not True/False but the minimum number of days. So we could change from “1” to run weekly by changing this value to “7”. A value of “0” will disable the feature.

You can create the file yourself or run the following command to create the file (it can be used to turn on/off by running it on an existing file but that’s all)

sudo dpkg-reconfigure -plow unattended-upgrades

If you want to change the frequency of checks for updates you’ll need to edit the 20auto-upgrades manually (as already discussed).

References

AutomaticSecurityUpdates.
UnattendedUpgrades

Mounting a USB HDD on Ubuntu server

I’m running up my latest Raspberry Pi with a connected USB SSD and forgot how to mount the thing. So this post is a little reminder. Ofcourse the instruction are not exclusive to Raspberry Pi’s or Ubuntu, but hey I just wanted a back story to this post.

So you’ve connected your USB drive and you’ve got a SSH terminal (i.e. via PuTTY) session connected to you Ubuntu server, what’s next?

Where’s my drive

The first thing you need to figure out is where your drive is, i.e. what /dev/ location it’s assigned to.

  • Try running df, which reports disk space and usage, from this you might be able to spot your drive, in my case it’s /dev/sda1 and its obvious by the size of the drive
  • If this is not conclusive then run sudo fdisk -l this may help locate the disk

Mounting the drive

Assuming we’ve located the device, and for this example it is on /dev/sda1, how do we mount this drive?

  • Create a folder that will get mapped to our mounted drive, for example mkdir /media/external or whatever you want to name it
  • To mount the drive we now use
    sudo mount -t ntfs-3g /dev/sda1 /media/external
    

    Obviously this drive I’m mounting is an NTFS formatted drive, you might be using vfat or something else instead, so check. Then we simply have the source (/dev/sda1) mapping to the destination (/media/external) that we created.

    Note: without the mount taking place, ls the destination and you’ll see no files (if they exist on your drive). After you mount the drive. ls the destination to see the files on the USB drive.

As it currently stands, when you reboot you’ll have to mount the drive again.

Auto-mounting the drive

In scenarios where we’re not removing the drive and simply want the OS to automount our drive, we need to do a couple of things.

  • Find the UUID for the drive by running sudo blkid, next to the device, i.e. /dev/sda1 should be a UUID, copy or note down the string.
  • Run sudo nano fstab
  • Add a new line to the bottom of the file along these lines
    UUID=ABCDEFGHIJK /media/external auto nosiud,nodev,nofail 0 0
    

    and save the file

  • Run sudo mount -a to check for errors

Now when you reboot the machine the USB drive should be mounted automatically.

Using the Windows Subsystem for Linux

Whilst I have Linux machines available to me, they’re not always powered up or the remoting

See Windows Subsystem for Linux Installation Guide for Windows 10 for details on installing the WSL.

For completeness here’s the steps I took.

  • Run PowerShell as Admin and then execute the following

    Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux
    
  • Go to the Microsoft Store and type Run Linux on Windows into the search text box. In the store currently, there’s the options of Ubuntu, openSUSE Leap 42, SUSE Linux Enterprise Server 12, Debian and Kali Linux.

    Install your preferred distro – I went for Ubuntu simply because that’s what I have on most of my Linux boxes.

  • Once installed you’ll need to go to the command prompt | Properties and select the Options tab. From here ensure that Use legacy console (requires relaunch) is unchecked.

Once everything is initialized you’ll be in the user’s (whatever user name you created) home folder – on Windows this folder is stored in C:\Users\{username}\AppData\Local\Packages\CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc\LocalState\rootfs\home

We can access the C drive using

cd /mnt/c

Running the Linux from Windows

When you want to run the Windows Subsystem for Linux going forward, simply execute

wsl

How to log into a Linux server without a password

Let’s assume we have two Linux systems, client and server.

On the client, carry out the following steps

  • ssh-keygen
  • By default saves to /home/username/.ssh/id_rsa
  • Enter a passphrase (if you want to add one to the key)
  • ssh-copy-id root@server (replace root@server with your user name and server IP or host name)
  • You should get prompted for the server’s password, enter this and the key will be copied

To test everything worked, execute the following

ssh root@server

(obviously, replacing root@server with your user name and server IP or host name) and if all worked you should log into the server without having to enter a password.

Now for each server that you need ssh access without a password, simple run ssh-copy-id root@server with the username and server that you want to connect to.

Ubuntu server updating

Every month (at least) I check my Ubuntu servers for updates and every month (at least) I forget how I clean old installs etc.

The following is a list of commands that I use regularly. This post is not meant to be a comprehensive description of these Linux/Ubuntu commands, more a checklist for updating my servers.

df or df /boot

When I log into my servers and see updates available the first thing I tend to do is run df and check the /boot usage/space available (obviously I could jump straight to the next command in my list, but I sort of like knowing what space I have available). I’ve tried carrying out an update in the past with next to no space available and sadly end up spending way too long trying to clear up partially installed components and/or clear disc space.

Alternatively, if you only want to view the /boot usage/space – which is really what we’re after here, just use df /boot.

sudo apt-get autoremove

apt-get is the Ubuntu based package manager (well, it’s actually originally from Debian), we’ll need to run it as the su. The options supplied will remove old packages and configurations files and all unused packages.

Why is the above useful? Well as we add updates to Ubuntu, it’s not unusual to find previous releases sat on our machine in the /boot area (I assume this is so we could roll back a release). Once you’re happy with your latest updates (or as I do, prior to the next update), run this command sudo apt-get autoremove to clear out these unused packages and free up disc space.

sudo apt-get update

The update option will retrieve a new list of packages available. This doesn’t install new versions of software but will ensure all package index files are upto date.

sudo apt-get upgrade

Now its time to upgrade we run sudo apt-get upgrade. This will look to clear out old packages if required, but doesn’t seem to do a more comprehensive removal, unlike purge and autoremove.

This command uses information from apt-get update to know about new versions of packages on the machine.

sudo apt-get dist-upgrade

If we want upgrade dependencies etc. this can be used instead of the straight upgrade.

sudo reboot now

Time to restart the server. This will obviously reboot the machine instantly (now).

uname -r

I don’t tend to use this during my “update” process, but if I want to know what version of the Linux kernel I’m running, using uname -r will tell me. This does become important if (as has happened to me) I cannot autoremove old kernels. Obviously when targeting specific kernels you need to know which one is current, or to put it another way, which one to not remove.

So for example, at the time of this post my current kernel is

4.4.0-72-generic

dpkg -l | grep linux-image

If you want to see what kernels exist on your machine, use dpkg -l | grep linux-image. This will (in conjunction with uname -r) allow us to target a purge of each kernel individually, using the following command.

sudo apt-get -y purge linux-image-?.?.?-??-generic

Obviously replace ?.?.?-?? with the version you wish to remove. This will then remove that specific package.

Redis service and client

Redis is an in memory store/cache, key/value store. Luckily there’s a Docker image for this.

Let’s run an instance of Redis via Docker on an Ubuntu server

docker run --name myredis -d -p 6379:6379 redis

Oh, how I love Docker (and ofcourse the community who create these images). This will run Redis and return immediately to your host’s command prompt (i.e. we do not go into the instance of Redis).

To run the redis client we’ll need to switch to the instance of the Docker container running Redis and then run the redis command line interface, thus

docker exec -it myredis bash
redis-cli

We’ll use this CLI later to view data in the cache.

C# client

There are several Redis client libraries available for .NET/C#, I’m going to go with ServiceStack.Redis, mainly because I’ve been using ServiceStack recently. So create a Console application, add the nuget packages for ServiceStack.Redis and now add the following code

public class Person
{
   public string FirstName { get; set; }
   public string LastName { get; set; }
}

class Program
{
   static void Main(string[] args)
   {
      var client = new RedisClient("redis://xxx.xxx.xxx.xxx:6379");
      client.Add("1234", new Person {FirstName = "Scooby", LastName = "Doo"});
      client.Save();
   }
}

Obviously change xxx.xxx.xxx.xxx to your server ip address.

This code will simply write the Person object to the store against the key 1234. If you have the redis-cli running then you can type

get 1234

this should result in the following result

"{\"FirstName\":\"Scooby\",\"LastName\":\"Doo\"}"

Ofcourse, we now need to use the ServiceStack.Redis client to read our data back. Just use this

var p = client.Get<Person>("1234");

Security

By default Redis has no security set up, hence we didn’t need to specify a user name and password. Obviously in a production environment we’d need to implement such security (or if using Redis via a cloud provider such as Azure).

For our instance we can secure Redis as a whole using the command AUTH. So from redis-cli run

CONFIG SET requirepass "password"
AUTH "password"

If you run AUTH “password” and get Err Client sent AUTH, but no password is set you’ll need the CONFIG line, otherwise the AUTH line should work fine. Our client application will need the following changes to the URL

var client = new RedisClient("redis://password@xxx.xxx.xxx.xxx:6379");

To remove the password (if you need to) simple type the following from the redis-cli

CONFIG SET requirepass ""

References

https://github.com/ServiceStack/ServiceStack.Redis