Howto – Install Docker on Debian

Set-Up docker on Debian:

Install packages to allow apt to use a repository over HTTPS:

$ sudo apt-get install apt-transport-https ca-certificates curl gnupg2 software-properties-common 

Add Docker’s official GPG key:

$ curl -fsSL | sudo apt-key add - 

Verify that you now have the key with the fingerprint9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88, by searching for the last 8 characters of the fingerprint.

$ sudo apt-key fingerprint 0EBFCD88
pub 4096R/0EBFCD88 2017-02-22 Key fingerprint = 9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88
uid Docker Release (CE deb) <>
sub 4096R/F273FCD8 2017-02-22 

Use the following command to set up the stable repository. You always need the stable repository, even if you want to install builds from the edge or test repositories as well. To add the edge or test repository, add the word edge or test (or both) after the word stable in the commands below.

$ sudo add-apt-repository "deb [arch=amd64] $(lsb_release -cs) stable" 
$ sudo apt-get update
$ sudo apt-get install docker-ce

To install a specific version of Docker CE, list the available versions in the repo, then select and install:

 List the versions available in your repo:

$ apt-cache madison docker-ce docker-ce | 18.03.0~ce-0~debian | jessie/stable amd64 Packages 

Install a specific version by its fully qualified package name, which is the package name (docker-ce) plus the version string (2nd column) up to the first hyphen, separated by a an equals sign (=), for example, docker-ce=18.03.0.ce.

$ sudo apt-get install docker-ce=<VERSION_STRING> 

The Docker daemon starts automatically.

Verify that Docker CE is installed correctly by running the hello-world image.

$ sudo docker run hello-world 


Howto – Install self-signed CA Root certificate on Linux


If you are running your own x509 certificate authority with a self signed root certificate, and want to use this to sign your own server certificates for usage on Linux servers, then this article is for you.

This article will explain to you how to install the root certificate of your self signed certificate authority on your Linux server.


(not required for java / Active Directory Plugin)

If not yet installed, install wget or curl you will use these tools to download the root certificate.

$ sudo apt-get install curl
$ sudo apt-get install wget 

Global per-server installation

Install the ca-certificates package, this downloads the root certificates of all public certificate authorities, so these will be trusted. It also creates a certificate store on your Linux server to which we can add our own, self signed, root certificate.

$ sudo apt-get install ca-certificates  

If you need the CA certificate in Java too, you will probably want to install the hook scripts for updating the trusted CA certificates for the JRE store:

$ sudo apt-get install ca-certificates-java 

Create a separate folder to store our on ca certificate

$ sudo mkdir /usr/share/ca-certificates/ 

Download your self signed CA Root certificate to your server-specific directory (in this case from Microsoft Certificate Services)

NOTE: replace ‘myusername’ with your AD username, and enter your AD password when asked for.

$ sudo wget -nv --no-check-certificate --http-user myusername --ask-password '' -O /usr/share/ca-certificates/ 

Alternatively using curl:

$ sudo curl -k --ntlm -u myusername '' -o /usr/share/ca-certificates/  

Now reconfigure the ca-certificates package to trust the new certificate.

$ sudo dpkg-reconfigure ca-certificates

#-- Trust new certicates from certicate authorities? yes
#-- select  

Or automated:

$ sed -e '/[!#[:space:]]*mydomain\.com\/myca\.mydomain\.com\.crt/d' -i /etc/ca-certificates.conf 

$ echo '' >> /etc/ca-certificates.conf 

$ dpkg-reconfigure -f noninteractive ca-certificates 

Java Note

If it’s not working for Java applications, you can try to restart the Java application or install the CA certificate manually:

$ ( cd ${JAVA_HOME}/jre/lib/security/ && sudo keytool -keystore cacerts -storepass changeit -alias '' -importcert -file /etc/ssl/certs/ -noprompt ) 

You can check if the certificate is trusted now as follows:

$ ( cd ${JAVA_HOME}/jre/lib/security && keytool -list -keystore cacerts -storepass changeit ) | grep -i myca 

Python Notes

Python has yet another special case. You might get following error:

   <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:590)>

In this case try following steps:

$ sudo update-ca-certificates
$ disable the myca certificate 

And enable it again.

User-Specific installation

Create a directory to store the certificates:

$ mkdir -p ~/.ssl/certs 

Download the self signed CA Root certificate to your user-specific directory:

NOTE: replace ‘myusername’ with your AD username, and enter your AD password when asked for.

$ curl -k --ntlm -u myusername '' -o ~/.ssl/certs/ 

Create symbolic link to the hash file for compatibility reasons :

$ ln -s ~/.ssl/certs/ $(openssl x509 -in ~/.ssl/certs/ -hash -noout).0 ) 

Once this has been done we need to set the correct permissions on the folder:

$ chmod -R go-rwx ~/.ssl
$ chmod 0400 ~/.ssl/certs/
$ chmod 0400 ~/.ssl/certs/*.0 

Howto – cURL the kubernetes API server

Kubernetes management is abstracted via a rest API, which is served over a self signed secure connection. Frequently people run into issues when accessing this rest API because of TLS issues, in this case it can be useful to debug your connection with curl, as it will provide a detailed explanation of what is going wrong with your connection.

To have a grasp understanding on how authentication is taking place in kubernetes we will be creating a new service account with the required permission to perform our test with kubernetes.

Kubernetes is using a role based access system

Role Based Access – The Theory

Before we dive too deep, lets first understand the three pieces in a Kubernetes cluster that are needed to make role based access work. These are Subjects, Resources, and Verbs.

  • Subjects – Users or processes that need access to the Kubernetes API.
  • Resources – The k8s API objects that you’d grant access to
  • Verbs – List of actions that can be taken on a resource

These three items listed above are used in concert to grant permissions such that a user (Subject) is allowed access to take an action (verb) on an object (Resource).

Now we need to look at how we tie these three items together in Kubernetes. The first step will be to create a Role or a ClusterRole. Now both of these roles will be used to tie the Resources together with a Verb, the difference between them is that a Role is used at a namespace level whereas a ClusterRole is for the entire cluster.

Once you’ve created your Role or your Cluster Role, you’ve tied the Resource and Verb together and are only missing the Subject now. To tie the Subject to the Role, a RoleBinding or ClusterRoleBinding is needed. As you can guess the difference between a RoleBinding or a ClusterRoleBinding is whether or not its done at the namespace or for the entire Cluster, much like the Role/ClusterRole described above.

It should be noted that you can tie a ClusterRole with a RoleBinding that lives within a namespace. This enables administrators to use a common set of roles for the entire cluster and then bind them to a specific namespace for use.

So for the creation of our user account, we will create a ServiceAccount, ClusterRole and RoleBinding .

$ kubectl create serviceaccount my-service-account

Now we need to create a ClusterRole which will grant us the necessary permissions on our kubernetes cluster.

kind: ClusterRole
  name: log-reader
- apiGroups: [""] # "" indicates the core API group
  resources: ["pods", "pods/log"]
  verbs: ["get", "watch", "list"]

Bind the ClusterRole to the ServiceAccount in the current namespace (eg. ‘default’).

$ kubectl create rolebinding my-service-account:log-reader --clusterrole log-reader --serviceaccount default:my-service-account

Get the Bearer Token, Certificate and API Server URL

Get the token and certificate from the ServiceAccount’s token secret for use in your API requests. This script relies on the swiss army knife of JSON parsing on the command line, jq. Start by setting the SERVICE_ACCOUNTvariable.

$ SERVICE_ACCOUNT=my-service-account

#-- Get the ServiceAccount's token Secret's name
$ SECRET=$(kubectl get serviceaccount ${SERVICE_ACCOUNT} -o json | jq -Mr '.secrets[].name | select(contains("token"))')

#-- Extract the Bearer token from the Secret and decode
$ TOKEN=$(kubectl get secret ${SECRET} -o json | jq -Mr '.data.token' | base64 -d)

#-- Extract, decode and write the ca.crt to a temporary location
$ kubectl get secret ${SECRET} -o json | jq -Mr '.data["ca.crt"]' | base64 -d > /tmp/ca.crt

#-- Get the API Server location
$ APISERVER=https://$(kubectl -n default get endpoints kubernetes --no-headers | awk '{ print $2 }')

Explore the API

You can see the API documentation at /openapi/v2

$ curl -s $APISERVER/openapi/v2  --header "Authorization: Bearer $TOKEN" --cacert /tmp/ca.crt | less

Use case: Get pod logs

To get the logs of a pod, first list all the pods. Select only the names with the JsonPath .items[]

$ curl -s $APISERVER/api/v1/namespaces/default/pods/ --header "Authorization: Bearer $TOKEN" --cacert /tmp/ca.crt | jq -rM '.items[]'

Insert the desired pod name into the request path.

$ curl -s $APISERVER/api/v1/namespaces/default/pods/nginx-5dc7fbd98-hvv6s/log  --header "Authorization: Bearer $TOKEN" --cacert /tmp/ca.crt

That’s it! You can now explore the API using your favourite tool without proxying the server or any other tricks. Remember to assign roles as needed to access various resources.

Howto – Resize linux partition and move swap space

Most of the time when you install a linux system, and when not making usage of LVM, the default parition layout will consist of something like a large main partition, and an extended partition with a swap volume on it.

If you want to extend a disk of a linux virtual machine, you will have to reconfigure your disk on the hypervisor, and afterwards, re-arrange your partition lay-out on your linux virtual machine. This howto serves as a working procdure to resize your virtual disk in the right way.

First disable your swap space.

$ swapoff /dev/sda5

Comment out the swap partition out in /etc/fstab

Now edit your partition table, delete the swap partitions:

$ fdisk /dev/sda 

#-- delete partition 5, then 2 and write changes
#-- shutdown the vm
#-- resize vm disk in hypervisor
#-- boot up the vm 

Now edit your partition table to resize your main partition, and re-create the swap partition:

$ fdisk /dev/sda 

#-- delete partition 1, and recreate it with new size leaving room for swap partition
#-- create extended partition 2
#-- create logical partition 5
#-- change type of logical partition to 82
#-- write changes
#-- reboot 

$ mkswap /dev/sda5
$ blkid /dev/sda5

#-- enter uuid in /etc/fstab
#-- enter uuid in /etc/initramfs-tools/conf.d/resume

$ update-initramfs -u
$ reboot
$ resize2fs /dev/sda1 

Howto – Set static network interface names in Linux with Systemd

Sometimes Linux admins have the need to write startup scripts for which they require static network interface names. On systems where systemd is used this can be accomplished by below procedure.

To change the names of the network interfaces, we need to create a configuration file for each network interface.


Each network interface configuration file needs to contain the mac address and interface name.



After creating the configuration files, and modifying the interfaces file to bring up the correct interfaces, we need to make this change persistent by updating the initial ramdisk.

$ update-initramfs -u

The network interfaces will now be renamed the next reboot.

Wiki – Exchange online Powershell examples

Welkom at the Exchange online Powershell examples Wiki.

Before you are able to perform any of the below powershell examples, you will need to connect to Exchange online using powershell.   

Steps on how to do this can be found on the: Howto – Install and Connect to Exchange online remote powershell with 2FA

Add calender permissions in a mailbox:

View the current permissions:

  • Get-MailboxFolderPermission\calendar

View the permissions for a specific user:

  • Get-MailboxFolderPermission -Identity\Calendar -User

Add permissions to the calendar:

  • Add-MailboxFolderPermission\Calendar -User -AccessRights Author

Note: AccessRights can be: Owner, PublishingEditor, Editor, PublishingAuthor, Author, NonEditingAuthor, Reviewer, Contributor, AvailabilityOnly, LimitedDetails

Remove permissions for a specific user

  • Remove-MailboxFolderPermission -Identity calendar@company:\calendar -user

What if you need to change the calendar permissions for all users within your organization?!

$allmailbox = Get-Mailbox -Resultsize Unlimited
Foreach ($Mailbox in $allmailbox)
    $path = $Mailbox.alias + “:\” + (Get-MailboxFolderStatistics $Mailbox.alias | Where-Object { $_.Foldertype -eq “Calendar” } | Select-Object -First 1).Name
    Set-mailboxfolderpermission –identity ($path) –user Default –Accessrights AvailabilityOnly

List all folders in a mailbox

Get-MailboxFolderStatistics -Identity username.e | select-object identity

Enable out of office message for a mailbox via powershell

Set-MailboxAutoReplyConfiguration -Identity <username> -AutoReplyState Enabled -InternalMessage “Internal auto-reply message.” -ExternalMessage “External auto-reply message.”

Export distribution group members to csv file

Get-DistributionGroupMember -identity “mydistributionlist” | export-csv -NoTypeInformation -path.\mydocument.csv -encoding utf8

Insert a mailbox rule to silently discard auto-reply messages

New-InboxRule -mailbox -Name NoAutoReplyMessages -SubjectContainsWords “Automatic reply” -DeleteMessage $true

Howto – Manually enable changed block tracking on a vSphere VM

How can I enable CBT manually?


Changed Block Tracking speeds up incremental backup and replication. 
Due to technical limitations, CBT cannot be enabled in Free ESXi automatically.

ESXi 5.1 and earlier

CBT can be enabled manually by editing the VM settings.
To enable CBT in a virtual machine on Free ESXi 5.1 and earlier, follow the steps below:

  1. Power off the virtual machine. 
  2. Right-click the virtual machine and click Edit Settings.
  3. Click the Options tab.
  4. Click General under the Advanced section and then click Configuration Parameters. The Configuration Parameters dialog opens.
  5. Click Add Row.
  6. Add the “ctkEnabled” parameter and then set its value to “true”.
  7. Click Add Row, add “scsi0:0.ctkEnabled”, and set its value to “true”.
    NOTE: The “scsi0:0” parameter in the “scsi0:0.ctkEnabled” value indicates the SCSI device assigned to the hard disk that is added to the virtual machine. Every hard disk added to the virtual machine is given a SCSI device that appears similar to scsi0:0, scsi0:1, or scsi 1:1.  
  8. Power on the virtual machine.

ESXi 5.5

CBT cannot be enabled without removing the VM from Inventory. 
To enable CBT in a virtual machine on Free ESXi 5.5, follow the steps below:

  1. Power off the virtual machine.
  2. Right-click the virtual machine and click Remove from Inventory.
  3. Open Datastore Browser and browse the datastore where the virtual machine configuration file <VM name>.vmx is located.
  4. Open the virtual machine folder on the datastore and download the <VM name>.vmx file.
  5. Open the downloaded file using a text editor.
  6. Manually add the ctkEnabled = “true” attribute.
  7. Manually add the scsi0:0.ctkEnabled = “true” attribute.
    NOTE: The “scsi0:0” parameter in the “scsi0:0.ctkEnabled” value indicates the SCSI device assigned to the hard disk that is added to the virtual machine. Every hard disk added to the virtual machine is given a SCSI device that appears similar to scsi0:0, scsi0:1, or scsi 1:1.
  8. Save the modified file.
  9. Upload the modified <VM name>.vmx file back to the datastore.
  10. Right-click the uploaded file and click Add to Inventory. The wizard for adding to inventory opens.
  11. Follow the wizard and complete adding the virtual machine to Inventory.
  12. Power on the virtual machine.

More information on Enabling CBT in VMware VMs can be found in VMware KB 1031873.

HOWTO – Linux Active Directory Integration with SSSD


Integrating Open Source Operating Systems into a centralized Accounting and Authorization system Active Directory from Microsoft.

To facilitate this integration, we are making use of the System Security Services Daemon (SSSD) package, which provides us with access to local or remote identity and authentication resources through a common framework that can provide caching and offline support to the system.

It provides several interfaces, including NSS and PAM modules or a D-Bus interface.

Installation and configuration.

Check DNS resolving.

Verify if your OS can resolve the domain’s ldap SRV records:

$ dig -t SRV

Verify if your OS can resolve the domain’s AD SRV records:

$  dig -t SRV 

NOTE: Verify if you can ping all displayed IPv4 and IPv6 addresses to check if there are no routing or firewall issues.

Check your hostname configuration. 

Before you will be able to join the domain successfully without any error messages you need to verify your hosts file configuration. NOTE: the order in which you specify your hostnames is important, make sure that you FQDN of your computername is in the first position.

$ cat /etc/hosts       localhost myhost
# The following lines are desirable for IPv6 capable hosts
::1     localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

Software Installation

Install the required packages for SSSD.

$ apt-get update
$ apt-get install realmd sssd sssd-tools samba-common samba-common-bin samba-libs krb5-user adcli ntp sssd-tools sssd libnss-sss libpam-sss adcli policykit-1 packagekit 

Software Configuration

Configure your time service to syncronise with your domain controllers.

Stop your NTP server.

$ systemctl stop ntp 

Edit your ntp.conf file.

$ vi /etc/ntp.conf 

Modify the ntp.conf contents to reflect below configuration.

#-- replace below lines:
pool iburst
pool iburst
pool iburst
pool iburst

#-- replace with

Now save your config file.

Synchronize one time manually for initial time sync.

$ apt install ntpdate 
$ ntpdate 

Now restart your NTP daemon for automatic operation.

$ systemctl start ntp 

Verify that your service is running correctly.

$ systemctl status ntp 

Configure sssd

Join the server to the Active Directory, this will create an initial sssd.conf file for us.

$ realm join -U Administrator --verbose 

Check the permissions of the /etc/sssd/sssd.conf file, it should be 0600 Correct if necessary.

$ chown root:root /etc/sssd/sssd.conf
$ chmod 0600 /etc/sssd/sssd.conf 

Modify your /etc/sssd/sssd.conf file:

filter_groups = root,adm
filter_users = root,adm
reconnection_retries = 3

reconnection_retries = 3

domains =
config_file_version = 2
services = nss, pam

ad_domain =
krb5_realm = MYDOMAIN.COM
realmd_tags = manages-system joined-with-adcli
cache_credentials = True
id_provider = ad
krb5_store_password_if_offline = True
default_shell = /bin/bash
ldap_id_mapping = True
use_fully_qualified_names = False
override_homedir = /home/%u@%d
enumerate = False
ad_gpo_access_control = permissive

# Note: below two configuration lines are only required when u want to restrict ssh access based on AD groups.

access_provider = simple
simple_allow_groups = myadgroup

The server should create a home directory for the user logging in:

$ vi /etc/pam.d/common-account 

add to the bottom of the file

session required skel=/etc/skel/ umask=0077

We will assign an AD group for sudo access to the server:

$ vi /etc/sudoers.d/10-adsudo-grant-all 
%myadsudogroup ALL=(ALL) ALL
$ chmod 0440 /etc/sudoers.d/10-adsudo-grant-all 

Now that we have set up and configured sssd lets restart the service to activate this.

$ sudo systemctl restart sssd 

Set-up the Samba server.

$ apt-get install samba 

Stop your samba server

$ systemctl stop smbd 

Edit your smb.conf file, and add any shares you need in the configuration

$ vi /etc/samba/smb.conf 
# Global parameters
        realm = MYDOMAIN.COM
        server string = %h server (Samba, Ubuntu)
        workgroup = MYDOMAIN
        log file = /var/log/samba/log.%m
        max log size = 1000
        syslog = 0
        panic action = /usr/share/samba/panic-action %d
        load printers = No
        client signing = if_required
        kerberos method = secrets and keytab
        security = ADS
        idmap config * : backend = tdb

        comment = MyShare
        path = /srv/share
        create mask = 0664
        directory mask = 02775
        force create mode = 0664
        force directory mode = 02775
        valid users = localuser @adsmbaccessgroup

Now join your Samba server to AD

$ net ads join -U myusername 

Howto – Disable IPV6 on Linux

On a Debian system:

$ sudo nano /etc/sysctl.conf 

Add the following at the bottom of the file:

net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1 

Save and close the file.

Reboot the machine.

To re-enable IPv6, remove the above lines from /etc/sysctl.conf and reboot the machine.

On a RedHat system:

Here’s how to disable the protocol on a Red Hat-based system:

Open a terminal window.

Change to the root user.

$ sysctl -w net.ipv6.conf.all.disable_ipv6=1 
$ sysctl -w net.ipv6.conf.default.disable_ipv6=1 

To re-enable IPv6, issue the following commands:

$ sysctl -w net.ipv6.conf.all.disable_ipv6=0 
$ sysctl -w net.ipv6.conf.default.disable_ipv6=0 

Howto – Install Apt-Cacher-Server


Suppose that you are on a network, a lot of Linux machines are installed, each with their own distribution version and set of packages.  It happens frequently that  packages are needed on the network.   It’s a security risk to let old, unpatched operating systems connect to the internet.  Therefore we can set up an apt-cacher server.

Server Installation:

NOTE: this caching server was implemented on a debian 9.3 Operating system.

Install apt-cacher and apache2 webserver:

$ apt-get install apt-cacher apache2 

Enable apt-cacher:

Edit /etc/default/apt-cacher and change autostart to 1 

Note: You may have problems doing this on a machine with apache already installed.

Restart apache:

$ sudo systemctl restart apache2 

Server Configuration:

Edit /etc/apt-cacher/apt-cacher.conf and uncomment the following line:

# allowed_hosts = * Or set allowed_hosts to something appropriate. 

Apt Cacher now uses IPv6 addressing so you may find you need something like: allowed_hosts=::ffff:, for example, if you want to restrict hosts to a common home subnet.

Change the admin_email email address to something meaningful.

If you want to cache multiple distributions, uncomment the line and set distinct_namespaces value to 1:

 distinct_namespaces = 1 

By default apt-cacher may have problems with upgrades of ubuntu from one version to another when running do-release-upgrade -d 

This can be fixed by uncommenting the line beginning with installer_files_regexp and modifying it from:

installer_files_regexp = ^(?:vmlinuz|linux|initrd\.gz|changelog|NEWS.Debian|UBUNTU_RELEASE_NAMES\.tar\.gz(?:\.gpg)?|(?:Devel|EOL)?ReleaseAnnouncement(?:\.html)?|meta-release(?:-lts)?(?:-(?:development|proposed))?)$ 


installer_files_regexp = ^(?:vmlinuz|linux|initrd\.gz|changelog|NEWS.Debian|[a-z]+\.tar\.gz(?:\.gpg)?|UBUNTU_RELEASE_NAMES\.tar\.gz(?:\.gpg)?|(?:Devel|EOL)?ReleaseAnnouncement(?:\.html)?|meta-release(?:-lts)?(?:-(?:development|proposed))?)$ 

Restart apt-cacher: 

$ sudo systemctl restart apt-cacher 

Client Configuration:

To configure a client to utilize the apt cacher, edit below file:

$ sudo nano /etc/apt/apt.conf.d/01proxy 

And populate it with the below line:

Acquire::http::Proxy "http://<IP address or hostname of the apt-cacher server>:3142";